diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/BisqPopupMenuItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/BisqPopupMenuItem.java
deleted file mode 100644
index bedd3111f2..0000000000
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/BisqPopupMenuItem.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package bisq.desktop.components.controls;
-
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.ToString;
-
-@Getter
-@ToString
-@EqualsAndHashCode
-public final class BisqPopupMenuItem {
- private final String title;
- private final Runnable action;
-
- public BisqPopupMenuItem(String title, Runnable action) {
- this.title = title;
- this.action = action;
- }
-}
\ No newline at end of file
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownBisqMenuItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownBisqMenuItem.java
new file mode 100644
index 0000000000..579e7fdaf1
--- /dev/null
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownBisqMenuItem.java
@@ -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 .
+ */
+
+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();
+ }
+}
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java
index a4c54e037c..256817245e 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenu.java
@@ -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);
@@ -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");
@@ -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);
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java
index 6bf0e3eabf..af7c5c5440 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/controls/DropdownMenuItem.java
@@ -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);
+ }
}
}
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/components/table/RichTableView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/components/table/RichTableView.java
index 5b5c2b5e5b..7e3bf668a3 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/components/table/RichTableView.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/components/table/RichTableView.java
@@ -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;
@@ -286,7 +286,7 @@ private void listItemsChanged() {
@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = false)
- public static final class FilterMenuItem extends DropdownMenuItem implements Toggle {
+ public static final class FilterMenuItem extends DropdownBisqMenuItem implements Toggle {
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");
public static FilterMenuItem getShowAllFilterMenuItem(ToggleGroup toggleGroup) {
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/BisqEasyOfferbookView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/BisqEasyOfferbookView.java
index 3945bc1cfd..86ad74f415 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/BisqEasyOfferbookView.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/BisqEasyOfferbookView.java
@@ -518,7 +518,7 @@ private void updateAppliedFiltersSectionStyles(boolean shouldShowAppliedFilters)
}
@Getter
- private static final class SortAndFilterMarketsDropdownMenuItem extends DropdownMenuItem {
+ private static final class SortAndFilterMarketsDropdownMenuItem extends DropdownBisqMenuItem {
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");
private final T menuItem;
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java
index b7f21e5f8d..83d38639b4 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/bisq_easy/offerbook/offerbook_list/OfferbookListView.java
@@ -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;
@@ -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;
@@ -63,6 +65,7 @@ public class OfferbookListView extends bisq.desktop.common.view.View tableView;
@@ -71,9 +74,10 @@ public class OfferbookListView extends bisq.desktop.common.view.View 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);
@@ -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();
@@ -192,6 +206,7 @@ protected void onViewDetached() {
showOfferListExpandedPin.unsubscribe();
offerListTableViewSelectionPin.unsubscribe();
showBuyFromOffersPin.unsubscribe();
+ activeMarketPaymentsCountPin.unsubscribe();
model.getAvailableMarketPayments().removeListener(listChangeListener);
@@ -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;
}
@@ -231,7 +246,10 @@ 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());
@@ -239,7 +257,11 @@ private void updateMarketPaymentFilters() {
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());
@@ -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);
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/BaseChatView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/BaseChatView.java
index 9e1ce32ac1..74db5e693d 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/BaseChatView.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/BaseChatView.java
@@ -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;
@@ -40,7 +40,7 @@ public abstract class BaseChatView extends NavigationView> item,
ListView>> list,
@@ -74,9 +74,9 @@ protected void setUpActions() {
openPrivateChatAction.setTooltip(Res.get("chat.message.privateMessage"));
// More actions dropdown menu
- ignoreUserMenuItem = new DropdownMenuItem("ignore-grey", "ignore-white",
+ ignoreUserMenuItem = new DropdownBisqMenuItem("ignore-grey", "ignore-white",
Res.get("chat.message.contextMenu.ignoreUser"));
- reportUserMenuItem = new DropdownMenuItem("report-grey", "report-white",
+ reportUserMenuItem = new DropdownBisqMenuItem("report-grey", "report-white",
Res.get("chat.message.contextMenu.reportUser"));
moreActionsMenu = new DropdownMenu("more-actions-grey", "more-actions-white", true);
moreActionsMenu.setTooltip(Res.get("chat.message.moreOptions"));
diff --git a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/priv/PrivateChatsView.java b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/priv/PrivateChatsView.java
index 93708069cc..e17587672b 100644
--- a/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/priv/PrivateChatsView.java
+++ b/apps/desktop/desktop/src/main/java/bisq/desktop/main/content/chat/priv/PrivateChatsView.java
@@ -22,7 +22,7 @@
import bisq.desktop.common.utils.ImageUtil;
import bisq.desktop.components.containers.Spacer;
import bisq.desktop.components.controls.Badge;
-import bisq.desktop.components.controls.DropdownMenuItem;
+import bisq.desktop.components.controls.DropdownBisqMenuItem;
import bisq.desktop.components.table.BisqTableColumn;
import bisq.desktop.components.table.BisqTableView;
import bisq.desktop.main.content.chat.ChatView;
@@ -63,7 +63,7 @@ public abstract class PrivateChatsView extends ChatView