Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further improvements in offer list payments filter #2691

Merged
merged 5 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* This file is part of Bisq.
*
* Bisq is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bisq is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bisq. If not, see <http://www.gnu.org/licenses/>.
*/

package bisq.desktop.components.controls;

import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.scene.control.CustomMenuItem;
import lombok.Getter;

@Getter
public class DropdownBisqMenuItem extends CustomMenuItem {
private final BisqMenuItem bisqMenuItem;

public DropdownBisqMenuItem(String defaultIconId, String activeIconId, String text) {
bisqMenuItem = new BisqMenuItem(defaultIconId, activeIconId, text);
bisqMenuItem.getStyleClass().add("dropdown-menu-item-content");
setContent(bisqMenuItem);

// Using DropdownMenuItem.setOnAction leads to duplicate execution of the handler on MacOS 14.5 / M3.
// Might be a bug in the MacOS specific JavaFX libraries as other devs could not reproduce the issue.
// Using an eventFilter and consuming the event solves the issue.
// This happens only when bisqMenuItem is used inside the DropdownMenuItem
bisqMenuItem.addEventFilter(ActionEvent.ANY, Event::consume);
}

public DropdownBisqMenuItem(String text) {
this(null, null, text);
}

public DropdownBisqMenuItem(String defaultIconId, String activeIconId) {
this(defaultIconId, activeIconId, "");
}

public void setLabelText(String text) {
bisqMenuItem.setText(text);
}

public Double getWidth() {
return bisqMenuItem.getWidth();
}

public void updateWidth(Double width) {
bisqMenuItem.setPrefWidth(width);
}

public String getLabelText() {
return bisqMenuItem.getText();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class DropdownMenu extends HBox {
private boolean openUpwards = false;
@Setter
private boolean openToTheRight = false;
private Double prefWidth = null;

public DropdownMenu(String defaultIconId, String activeIconId, boolean useIconOnly) {
defaultIcon = ImageUtil.getImageViewById(defaultIconId);
Expand Down Expand Up @@ -151,6 +152,10 @@ private void attachListeners() {
getStyleClass().add("dropdown-menu-active");
updateIcon(activeIcon);
isMenuShowing.setValue(true);
if (prefWidth != null && !contextMenu.getItems().isEmpty()
&& contextMenu.getItems().getFirst() instanceof DropdownMenuItem) {
updateMenuItemWidth();
}
});
contextMenu.setOnHidden(e -> {
getStyleClass().remove("dropdown-menu-active");
Expand All @@ -163,16 +168,24 @@ private void attachListeners() {
isFirstRun = true;
// Once the contextMenu has calculated the width on the first render time we update the items
// so that they all have the same size.
for (MenuItem item : contextMenu.getItems()) {
if (item instanceof DropdownMenuItem dropdownMenuItem) {
dropdownMenuItem.updateWidth(contextMenu.getWidth() - 18); // Remove margins
}
}
prefWidth = contextMenu.getWidth() - 18; // Remove margins
updateMenuItemWidth();
}
};
contextMenu.widthProperty().addListener(new WeakChangeListener<>(widthPropertyChangeListener));
}

private void updateMenuItemWidth() {
for (MenuItem item : contextMenu.getItems()) {
if (item instanceof DropdownBisqMenuItem dropdownBisqMenuItem) {
dropdownBisqMenuItem.updateWidth(prefWidth);
}
if (item instanceof DropdownMenuItem dropdownMenuItem) {
dropdownMenuItem.updateWidth(prefWidth);
}
}
}

private void updateIcon(ImageView newIcon) {
if (buttonIcon != newIcon) {
getChildren().remove(buttonIcon);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,61 @@

package bisq.desktop.components.controls;

import bisq.desktop.common.utils.ImageUtil;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.CustomMenuItem;
import lombok.Getter;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;

@Getter
public class DropdownMenuItem extends CustomMenuItem {
private final BisqMenuItem bisqMenuItem;
public static final String ICON_CSS_STYLE = "menu-item-icon";

public DropdownMenuItem(String defaultIconId, String activeIconId, String text) {
bisqMenuItem = new BisqMenuItem(defaultIconId, activeIconId, text);
bisqMenuItem.getStyleClass().add("dropdown-menu-item-content");
setContent(bisqMenuItem);
private final HBox hBox;
private ImageView defaultIcon, activeIcon, buttonIcon;

// Using DropdownMenuItem.setOnAction leads to duplicate execution of the handler on MacOS 14.5 / M3.
// Might be a bug in the MacOS specific JavaFX libraries as other devs could not reproduce the issue.
// Using an eventFilter and consuming the event solves the issue.
// This happens only when bisqMenuItem is used inside the DropdownMenuItem
bisqMenuItem.addEventFilter(ActionEvent.ANY, Event::consume);
}
public DropdownMenuItem(String defaultIconId, String activeIconId, Node node) {
hBox = new HBox(10);
hBox.getStyleClass().add("dropdown-menu-item-content");

public DropdownMenuItem(String text) {
this(null, null, text);
}
if (defaultIconId != null && activeIconId != null) {
defaultIcon = ImageUtil.getImageViewById(defaultIconId);
activeIcon = ImageUtil.getImageViewById(activeIconId);
defaultIcon.getStyleClass().add(ICON_CSS_STYLE);
activeIcon.getStyleClass().add(ICON_CSS_STYLE);
buttonIcon = defaultIcon;
hBox.getChildren().add(buttonIcon);
attachListeners();
}

public DropdownMenuItem(String defaultIconId, String activeIconId) {
this(defaultIconId, activeIconId, "");
}
if (node != null) {
hBox.getChildren().add(node);
}

public void setLabelText(String text) {
bisqMenuItem.setText(text);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.getStyleClass().add("bisq-menu-item");
hBox.addEventFilter(ActionEvent.ANY, Event::consume);
setContent(hBox);
setHideOnClick(false);
}

public Double getWidth() {
return bisqMenuItem.getWidth();
public void updateWidth(Double width) {
hBox.setPrefWidth(width);
}

public void updateWidth(Double width) {
bisqMenuItem.setPrefWidth(width);
private void attachListeners() {
hBox.setOnMouseEntered(e -> updateIcon(activeIcon));
hBox.setOnMouseExited(e -> updateIcon(defaultIcon));
hBox.setOnMouseClicked(e -> updateIcon(defaultIcon));
}

public String getLabelText() {
return bisqMenuItem.getText();
private void updateIcon(ImageView newIcon) {
if (buttonIcon != newIcon) {
buttonIcon = newIcon;
hBox.getChildren().removeFirst();
hBox.getChildren().addFirst(buttonIcon);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import bisq.desktop.components.containers.Spacer;
import bisq.desktop.components.controls.BisqTooltip;
import bisq.desktop.components.controls.DropdownMenu;
import bisq.desktop.components.controls.DropdownMenuItem;
import bisq.desktop.components.controls.DropdownBisqMenuItem;
import bisq.desktop.components.controls.SearchBox;
import bisq.desktop.components.overlay.Popup;
import bisq.desktop.main.content.user.reputation.list.ReputationListView;
Expand Down Expand Up @@ -286,7 +286,7 @@ private void listItemsChanged() {

@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
public static final class FilterMenuItem<T> extends DropdownMenuItem implements Toggle {
public static final class FilterMenuItem<T> extends DropdownBisqMenuItem implements Toggle {
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");

public static FilterMenuItem<ReputationListView.ListItem> getShowAllFilterMenuItem(ToggleGroup toggleGroup) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ private void updateAppliedFiltersSectionStyles(boolean shouldShowAppliedFilters)
}

@Getter
private static final class SortAndFilterMarketsDropdownMenuItem<T> extends DropdownMenuItem {
private static final class SortAndFilterMarketsDropdownMenuItem<T> extends DropdownBisqMenuItem {
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");

private final T menuItem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import bisq.desktop.common.utils.ImageUtil;
import bisq.desktop.components.controls.BisqTooltip;
import bisq.desktop.components.controls.DropdownMenu;
import bisq.desktop.components.controls.DropdownBisqMenuItem;
import bisq.desktop.components.controls.DropdownMenuItem;
import bisq.desktop.components.table.BisqTableColumn;
import bisq.desktop.components.table.BisqTableView;
Expand All @@ -49,6 +50,7 @@
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -63,6 +65,7 @@ public class OfferbookListView extends bisq.desktop.common.view.View<VBox, Offer
private static final double COLLAPSED_LIST_WIDTH = BisqEasyOfferbookView.COLLAPSED_LIST_WIDTH;
private static final double HEADER_HEIGHT = BaseChatView.HEADER_HEIGHT;
private static final double LIST_CELL_HEIGHT = BisqEasyOfferbookView.LIST_CELL_HEIGHT;
private static final String ACTIVE_PAYMENT_FILTER_CLASS = "active-payment-filter";

private final Label title;
private final BisqTableView<OfferbookListItem> tableView;
Expand All @@ -71,9 +74,10 @@ public class OfferbookListView extends bisq.desktop.common.view.View<VBox, Offer
private final ImageView offerListWhiteIcon, offerListGreyIcon, offerListGreenIcon;
private final DropdownMenu offerDirectionFilterMenu, paymentsFilterMenu;
private final ListChangeListener<FiatPaymentMethod> listChangeListener;
private DropdownMenuItem buyFromOffers, sellToOffers;
private DropdownBisqMenuItem buyFromOffers, sellToOffers;
private Label offerDirectionFilterLabel, paymentsFilterLabel;
private Subscription showOfferListExpandedPin, showBuyFromOffersPin, offerListTableViewSelectionPin;
private Subscription showOfferListExpandedPin, showBuyFromOffersPin,
offerListTableViewSelectionPin, activeMarketPaymentsCountPin;

OfferbookListView(OfferbookListModel model, OfferbookListController controller) {
super(new VBox(), model, controller);
Expand Down Expand Up @@ -174,6 +178,16 @@ protected void onViewAttached() {
}
});

activeMarketPaymentsCountPin = EasyBind.subscribe(model.getActiveMarketPaymentsCount(), count -> {
if (count.intValue() != 0) {
if (!paymentsFilterLabel.getStyleClass().contains(ACTIVE_PAYMENT_FILTER_CLASS)) {
paymentsFilterLabel.getStyleClass().add(ACTIVE_PAYMENT_FILTER_CLASS);
}
} else {
paymentsFilterLabel.getStyleClass().remove(ACTIVE_PAYMENT_FILTER_CLASS);
}
});

model.getAvailableMarketPayments().addListener(listChangeListener);
updateMarketPaymentFilters();

Expand All @@ -192,6 +206,7 @@ protected void onViewDetached() {
showOfferListExpandedPin.unsubscribe();
offerListTableViewSelectionPin.unsubscribe();
showBuyFromOffersPin.unsubscribe();
activeMarketPaymentsCountPin.unsubscribe();

model.getAvailableMarketPayments().removeListener(listChangeListener);

Expand All @@ -212,8 +227,8 @@ private DropdownMenu createAndGetOffersDirectionFilterMenu() {
menu.setOpenToTheRight(true);
offerDirectionFilterLabel = new Label();
menu.setLabel(offerDirectionFilterLabel);
buyFromOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom"));
sellToOffers = new DropdownMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo"));
buyFromOffers = new DropdownBisqMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.buyFrom"));
sellToOffers = new DropdownBisqMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.offerDirection.sellTo"));
menu.addMenuItems(buyFromOffers, sellToOffers);
return menu;
}
Expand All @@ -231,15 +246,22 @@ private void updateMarketPaymentFilters() {
cleanUpPaymentsFilterMenu();

model.getAvailableMarketPayments().forEach(payment -> {
PaymentMenuItem item = new PaymentMenuItem(payment.getDisplayString());
ImageView paymentIcon = ImageUtil.getImageViewById(payment.getName());
Label paymentLabel = new Label(payment.getDisplayString(), paymentIcon);
paymentLabel.setGraphicTextGap(10);
PaymentMenuItem item = new PaymentMenuItem(paymentLabel);
item.setOnAction(e -> {
item.updateSelection(!item.isSelected());
controller.toggleMethodFilter(payment, item.isSelected());
});
paymentsFilterMenu.addMenuItems(item);
});

PaymentMenuItem customItem = new PaymentMenuItem(Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.customMethod"));
StackPane customPaymentIcon = BisqEasyViewUtils.getCustomPaymentMethodIcon("C");
Label customPaymentLabel = new Label(
Res.get("bisqEasy.offerbook.offerList.table.filters.paymentMethods.customPayments"), customPaymentIcon);
customPaymentLabel.setGraphicTextGap(10);
PaymentMenuItem customItem = new PaymentMenuItem(customPaymentLabel);
customItem.setOnAction(e -> {
customItem.updateSelection(!customItem.isSelected());
controller.toggleCustomMethodFilter(customItem.isSelected());
Expand Down Expand Up @@ -469,9 +491,8 @@ protected void updateItem(OfferbookListItem item, boolean empty) {
private static final class PaymentMenuItem extends DropdownMenuItem {
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");

PaymentMenuItem(String displayName) {
// TODO: Update code so that we can pass label instead of text
super("check-white", "check-white", displayName);
private PaymentMenuItem(Label displayLabel) {
super("check-white", "check-white", displayLabel);

getStyleClass().add("dropdown-menu-item");
updateSelection(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import bisq.desktop.common.utils.ImageUtil;
import bisq.desktop.common.view.NavigationView;
import bisq.desktop.components.controls.DropdownMenu;
import bisq.desktop.components.controls.DropdownMenuItem;
import bisq.desktop.components.controls.DropdownBisqMenuItem;
import bisq.desktop.components.controls.SearchBox;
import bisq.i18n.Res;
import javafx.scene.control.Label;
Expand All @@ -40,7 +40,7 @@ public abstract class BaseChatView extends NavigationView<ScrollPane, BaseChatMo
protected final Label channelTitle = new Label();
protected final Label channelDescription = new Label();
protected Label channelIcon = new Label();
protected DropdownMenuItem helpButton, infoButton;
protected DropdownBisqMenuItem helpButton, infoButton;
protected final VBox sideBar = new VBox();
protected final VBox centerVBox = new VBox();
protected final HBox titleHBox = new HBox(10);
Expand Down Expand Up @@ -72,8 +72,8 @@ public BaseChatView(BaseChatModel model,
}

private void setUpHeaderDropdownMenu() {
helpButton = new DropdownMenuItem("icon-help-grey", "icon-help-white");
infoButton = new DropdownMenuItem("icon-info-grey", "icon-info-white",
helpButton = new DropdownBisqMenuItem("icon-help-grey", "icon-help-white");
infoButton = new DropdownBisqMenuItem("icon-info-grey", "icon-info-white",
Res.get("chat.dropdownMenu.channelInfo"));
headerDropdownMenu.addMenuItems(helpButton, infoButton);
headerDropdownMenu.setTooltip(Res.get("chat.dropdownMenu.tooltip"));
Expand Down
Loading
Loading