diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java index 0dde9d04..f26090f4 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFileListComp.java @@ -268,6 +268,7 @@ final class BrowserFileListComp extends SimpleComp { return false; }, + null, () -> { if (row.getItem() != null && row.getItem().isSynthetic()) { return null; diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java index 3daa2a7e..3fffcc61 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java @@ -103,7 +103,7 @@ public class BrowserNavBar extends SimpleComp { homeButton.setAccessibleText("Directory options"); homeButton.getStyleClass().add(Styles.LEFT_PILL); homeButton.getStyleClass().add("path-graphic-button"); - new ContextMenuAugment<>(event -> event.getButton() == MouseButton.PRIMARY, () -> { + new ContextMenuAugment<>(event -> event.getButton() == MouseButton.PRIMARY, null, () -> { return model.getInOverview().get() ? null : new BrowserContextMenu(model, null); }) .augment(new SimpleCompStructure<>(homeButton)); @@ -112,7 +112,7 @@ public class BrowserNavBar extends SimpleComp { historyButton.setAccessibleText("History"); historyButton.getStyleClass().add(Styles.RIGHT_PILL); // historyButton.getStyleClass().add("path-graphic-button"); - new ContextMenuAugment<>(event -> event.getButton() == MouseButton.PRIMARY, this::createContextMenu) + new ContextMenuAugment<>(event -> event.getButton() == MouseButton.PRIMARY, null, this::createContextMenu) .augment(new SimpleCompStructure<>(historyButton)); var breadcrumbs = new BrowserBreadcrumbBar(model).grow(false, true); diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserQuickAccessContextMenu.java b/app/src/main/java/io/xpipe/app/browser/BrowserQuickAccessContextMenu.java index 5d9e1ec6..d56216e5 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserQuickAccessContextMenu.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserQuickAccessContextMenu.java @@ -79,9 +79,6 @@ public class BrowserQuickAccessContextMenu extends ContextMenu { var empty = new MenuItem("..."); empty.setDisable(true); menu.getItems().add(empty); - InputHelper.onRight(empty, true, keyEvent -> { - keyEvent.consume(); - }); } private void createDirectoryMenu() { diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java index 148e089e..96333477 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserStatusBarComp.java @@ -124,6 +124,6 @@ public class BrowserStatusBarComp extends SimpleComp { }); // Use status bar as an extension of file list - new ContextMenuAugment<>(() -> new BrowserContextMenu(model, null)).augment(new SimpleCompStructure<>(r)); + new ContextMenuAugment<>(mouseEvent -> mouseEvent.isSecondaryButtonDown(), null, () -> new BrowserContextMenu(model, null)).augment(new SimpleCompStructure<>(r)); } } diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java index f9fe4910..3700cbf3 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserWelcomeComp.java @@ -7,14 +7,15 @@ import io.xpipe.app.comp.base.TileButtonComp; import io.xpipe.app.core.AppFont; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.fxcomps.impl.HorizontalComp; import io.xpipe.app.fxcomps.impl.LabelComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.PrettySvgComp; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.storage.DataStorage; -import io.xpipe.app.util.JfxHelper; import io.xpipe.app.util.ThreadHelper; import javafx.beans.binding.Bindings; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; import javafx.geometry.Insets; @@ -26,6 +27,8 @@ import javafx.scene.layout.Priority; import javafx.scene.layout.Region; import javafx.scene.layout.VBox; +import java.util.List; + public class BrowserWelcomeComp extends SimpleComp { private final BrowserModel model; @@ -86,25 +89,10 @@ public class BrowserWelcomeComp extends SimpleComp { storeList.setSpacing(8); var listBox = new ListBoxViewComp<>(list, list, e -> { - var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid()); - var graphic = entry.get() - .getProvider() - .getDisplayIconFileName(entry.get().getStore()); - var view = PrettyImageHelper.ofFixedSize(graphic, 50, 40); - view.padding(new Insets(2, 8, 2, 8)); - var content = JfxHelper.createNamedEntry( - DataStorage.get().getStoreDisplayName(entry.get()), e.getPath(), graphic); - var disable = new SimpleBooleanProperty(); - return new ButtonComp(null, content, () -> { - ThreadHelper.runAsync(() -> { - model.restoreStateAsync(e, disable); - }); - }) - .accessibleText(DataStorage.get().getStoreDisplayName(entry.get())) - .disable(disable) - .styleClass("color-listBox") - .apply(struc -> struc.get().setMaxWidth(2000)) - .grow(true, false); + var disable = new SimpleBooleanProperty(); + var entryButton = entryButton(e, disable); + var dirButton = dirButton(e, disable); + return new HorizontalComp(List.of(entryButton, dirButton)); }) .apply(struc -> { VBox vBox = (VBox) struc.get().getContent(); @@ -134,4 +122,37 @@ public class BrowserWelcomeComp extends SimpleComp { return layout; } + + private Comp entryButton(BrowserSavedState.Entry e, BooleanProperty disable) { + var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid()); + var graphic = entry.get() + .getProvider() + .getDisplayIconFileName(entry.get().getStore()); + var view = PrettyImageHelper.ofFixedSize(graphic, 30, 24); + return new ButtonComp(new SimpleStringProperty(DataStorage.get().getStoreDisplayName(entry.get())), view.createRegion(), () -> { + ThreadHelper.runAsync(() -> { + model.restoreStateAsync(e, disable); + }); + }) + .minWidth(250) + .accessibleText(DataStorage.get().getStoreDisplayName(entry.get())) + .disable(disable) + .styleClass("entry-button") + .apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT)); + } + + private Comp dirButton(BrowserSavedState.Entry e, BooleanProperty disable) { + var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid()); + return new ButtonComp(new SimpleStringProperty(e.getPath()), null, () -> { + ThreadHelper.runAsync(() -> { + model.restoreStateAsync(e, disable); + }); + }) + .accessibleText(e.getPath()) + .disable(disable) + .styleClass("directory-button") + .apply(struc -> struc.get().setMaxWidth(2000)) + .grow(true, false) + .apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT)); + } } diff --git a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java index 080f8b75..b2b15698 100644 --- a/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java +++ b/app/src/main/java/io/xpipe/app/browser/OpenFileSystemComp.java @@ -55,7 +55,7 @@ public class OpenFileSystemComp extends SimpleComp { var menuButton = new MenuButton(null, new FontIcon("mdral-folder_open")); new ContextMenuAugment<>( - event -> event.getButton() == MouseButton.PRIMARY, () -> new BrowserContextMenu(model, null)) + event -> event.getButton() == MouseButton.PRIMARY, null, () -> new BrowserContextMenu(model, null)) .augment(new SimpleCompStructure<>(menuButton)); menuButton.disableProperty().bind(model.getInOverview()); menuButton.setAccessibleText("Directory options"); diff --git a/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java b/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java index 1ad47764..183088c1 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/DropdownComp.java @@ -32,7 +32,7 @@ public class DropdownComp extends Comp> { .toArray(MenuItem[]::new)); Button button = (Button) new ButtonComp(null, () -> {}) - .apply(new ContextMenuAugment<>(e -> true, () -> { + .apply(new ContextMenuAugment<>(e -> true, null, () -> { return cm; })) .createRegion(); diff --git a/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java b/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java index b688b567..836e2d45 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java @@ -1,6 +1,5 @@ package io.xpipe.app.comp.base; -import atlantafx.base.theme.Styles; import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppI18n; import io.xpipe.app.fxcomps.Comp; @@ -43,7 +42,7 @@ public class TileButtonComp extends Comp { @Override public Structure createBase() { var bt = new Button(); - Styles.toggleStyleClass(bt, Styles.FLAT); + bt.getStyleClass().add("tile-button-comp"); bt.setOnAction(e -> { action.accept(e); }); diff --git a/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java b/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java index 07b9c1ba..69bfb379 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/ToggleSwitchComp.java @@ -5,6 +5,8 @@ import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.util.PlatformThread; import javafx.beans.property.Property; import javafx.beans.value.ObservableValue; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.Region; public class ToggleSwitchComp extends SimpleComp { @@ -20,6 +22,13 @@ public class ToggleSwitchComp extends SimpleComp { @Override protected Region createSimple() { var s = new ToggleSwitch(); + s.addEventFilter(KeyEvent.KEY_PRESSED,event -> { + if (event.getCode() == KeyCode.SPACE || event.getCode() == KeyCode.ENTER) { + s.setSelected(!s.isSelected()); + event.consume(); + } + }); + s.getStyleClass().add("toggle-switch-comp"); s.setSelected(selected.getValue()); s.selectedProperty().addListener((observable, oldValue, newValue) -> { selected.setValue(newValue); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java index 47c843d9..9f66920d 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryComp.java @@ -97,7 +97,7 @@ public abstract class StoreEntryComp extends SimpleComp { wrapper.executeDefaultAction(); }); }); - new ContextMenuAugment<>(() -> this.createContextMenu()).augment(new SimpleCompStructure<>(button)); + new ContextMenuAugment<>(mouseEvent -> mouseEvent.isSecondaryButtonDown(), null, () -> this.createContextMenu()).augment(new SimpleCompStructure<>(button)); var loading = LoadingOverlayComp.noProgress( Comp.of(() -> button), @@ -247,7 +247,7 @@ public abstract class StoreEntryComp extends SimpleComp { settingsButton.styleClass("settings"); settingsButton.accessibleText("More"); settingsButton.apply(new ContextMenuAugment<>( - event -> event.getButton() == MouseButton.PRIMARY, () -> StoreEntryComp.this.createContextMenu())); + event -> event.getButton() == MouseButton.PRIMARY, null, () -> StoreEntryComp.this.createContextMenu())); settingsButton.apply(new FancyTooltipAugment<>("more")); return settingsButton; } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreQuickAccessButtonComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreQuickAccessButtonComp.java index 4a937f5c..77a81cbf 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreQuickAccessButtonComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreQuickAccessButtonComp.java @@ -4,8 +4,8 @@ import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.CompStructure; import io.xpipe.app.fxcomps.impl.IconButtonComp; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; +import io.xpipe.app.util.ContextMenuHelper; import javafx.geometry.Side; -import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ContextMenu; import javafx.scene.control.Menu; @@ -24,22 +24,12 @@ public class StoreQuickAccessButtonComp extends Comp> { this.action = action; } - private void showMenu(Node anchor) { - var cm = createMenu(); - if (cm == null) { - return; - } - - cm.show(anchor, Side.RIGHT, 0, 0); - } - private ContextMenu createMenu() { if (section.getShownChildren().isEmpty()) { return null; } - var cm = new ContextMenu(); - cm.setAutoHide(true); + var cm = ContextMenuHelper.create(); cm.getStyleClass().add("condensed"); Menu menu = (Menu) recurse(cm, section); cm.getItems().addAll(menu.getItems()); @@ -52,9 +42,7 @@ public class StoreQuickAccessButtonComp extends Comp> { var graphic = w.getEntry().getProvider().getDisplayIconFileName(w.getEntry().getStore()); if (c.isEmpty()) { - var item = new MenuItem( - w.getName().getValue(), - PrettyImageHelper.ofFixedSizeSquare(graphic, 16).createRegion()); + var item = ContextMenuHelper.item(PrettyImageHelper.ofFixedSizeSquare(graphic, 16), w.getName().getValue()); item.setOnAction(event -> { action.accept(w); contextMenu.hide(); @@ -89,8 +77,14 @@ public class StoreQuickAccessButtonComp extends Comp> { public CompStructure