diff --git a/app/src/main/java/io/xpipe/app/browser/BrowserFilterComp.java b/app/src/main/java/io/xpipe/app/browser/BrowserFilterComp.java index 88d1a3b80..a205021b5 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserFilterComp.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserFilterComp.java @@ -39,7 +39,7 @@ public class BrowserFilterComp extends Comp { button.fire(); keyEvent.consume(); }); - new TooltipAugment<>("app.search", new KeyCodeCombination(KeyCode.F, KeyCombination.CONTROL_DOWN)).augment(button); + new TooltipAugment<>("app.search", new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN)).augment(button); text.focusedProperty().addListener((observable, oldValue, newValue) -> { if (!newValue && filterString.getValue() == null) { if (button.isFocused()) { 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 9339513da..e54899e8d 100644 --- a/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java +++ b/app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java @@ -10,6 +10,7 @@ import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.augment.ContextMenuAugment; import io.xpipe.app.fxcomps.impl.PrettyImageHelper; import io.xpipe.app.fxcomps.impl.TextFieldComp; +import io.xpipe.app.fxcomps.impl.TooltipAugment; import io.xpipe.app.util.BooleanScope; import io.xpipe.app.util.ThreadHelper; import javafx.application.Platform; @@ -75,9 +76,6 @@ public class BrowserNavBar extends Comp { struc.get().setPromptText("Overview of " + model.getName()); }) - .shortcut(new KeyCodeCombination(KeyCode.P, KeyCombination.SHORTCUT_DOWN), s -> { - s.get().requestFocus(); - }) .accessibleText("Current path"); var graphic = Bindings.createStringBinding( @@ -105,6 +103,7 @@ public class BrowserNavBar extends Comp { historyButton.getStyleClass().add(Styles.RIGHT_PILL); new ContextMenuAugment<>(event -> event.getButton() == MouseButton.PRIMARY, null, this::createContextMenu) .augment(new SimpleCompStructure<>(historyButton)); + new TooltipAugment<>("history", new KeyCodeCombination(KeyCode.H, KeyCombination.ALT_DOWN)).augment(historyButton); var breadcrumbs = new BrowserBreadcrumbBar(model).grow(false, true); @@ -114,6 +113,7 @@ public class BrowserNavBar extends Comp { pathRegion.requestFocus(); event.consume(); }); + breadcrumbsRegion.setFocusTraversable(false); breadcrumbsRegion.visibleProperty() .bind(Bindings.createBooleanBinding( () -> { diff --git a/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemComp.java b/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemComp.java index 3a59da1fa..22cadb094 100644 --- a/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemComp.java +++ b/app/src/main/java/io/xpipe/app/browser/fs/OpenFileSystemComp.java @@ -101,15 +101,26 @@ public class OpenFileSystemComp extends SimpleComp { root.getChildren().addAll(topBar, content); VBox.setVgrow(content, Priority.ALWAYS); root.setPadding(Insets.EMPTY); - InputHelper.onCtrlKeyCode(root, KeyCode.F, true, keyEvent -> { + InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.F, KeyCombination.CONTROL_DOWN), true, keyEvent -> { filter.toggleButton().fire(); filter.textField().requestFocus(); keyEvent.consume(); }); - InputHelper.onCtrlKeyCode(root, KeyCode.L, true, keyEvent -> { + InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.L, KeyCombination.CONTROL_DOWN), true, keyEvent -> { navBar.textField().requestFocus(); keyEvent.consume(); }); + InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.H, KeyCombination.ALT_DOWN), true, keyEvent -> { + navBar.historyButton().fire(); + keyEvent.consume(); + }); + InputHelper.onKeyCombination(root, new KeyCodeCombination(KeyCode.UP, KeyCombination.ALT_DOWN), true, keyEvent -> { + var p = model.getCurrentParentDirectory(); + if (p != null) { + model.cdAsync(p.getPath()); + } + keyEvent.consume(); + }); return root; } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java index 31e1a5390..ac750efc6 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreEntryListStatusComp.java @@ -19,9 +19,6 @@ import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.control.Label; import javafx.scene.control.MenuButton; -import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyCodeCombination; -import javafx.scene.input.KeyCombination; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; @@ -102,9 +99,6 @@ public class StoreEntryListStatusComp extends SimpleComp { }); }); var filter = new FilterComp(StoreViewState.get().getFilterString()); - filter.shortcut(new KeyCodeCombination(KeyCode.F, KeyCombination.SHORTCUT_DOWN), s -> { - s.getText().requestFocus(); - }); filter.apply(struc -> struc.get().sceneProperty().addListener((observable, oldValue, newValue) -> { if (newValue != null) { struc.getText().requestFocus(); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java index 921825e65..7ddbc96bc 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreLayoutComp.java @@ -5,6 +5,7 @@ import io.xpipe.app.core.AppActionLinkDetector; import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.fxcomps.SimpleComp; +import io.xpipe.app.util.InputHelper; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; @@ -12,12 +13,6 @@ import javafx.scene.layout.Region; public class StoreLayoutComp extends SimpleComp { - public StoreLayoutComp() { - shortcut(new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN), structure -> { - AppActionLinkDetector.detectOnPaste(); - }); - } - @Override protected Region createSimple() { var struc = new SideSplitPaneComp(new StoreSidebarComp(), new StoreEntryListComp()) @@ -29,6 +24,10 @@ public class StoreLayoutComp extends SimpleComp { struc.getLeft().setMinWidth(260); struc.getLeft().setMaxWidth(500); struc.get().getStyleClass().add("store-layout"); + InputHelper.onKeyCombination(struc.get(),new KeyCodeCombination(KeyCode.V, KeyCombination.SHORTCUT_DOWN), true, keyEvent -> { + AppActionLinkDetector.detectOnPaste(); + keyEvent.consume(); + }); return struc.get(); } } diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java index 346a658d0..db79e5151 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreSectionComp.java @@ -63,8 +63,7 @@ public class StoreSectionComp extends Comp> { section.getWrapper().getName())) .disable(quickAccessDisabled) .focusTraversableForAccessibility() - .displayOnlyShortcut(new KeyCodeCombination(KeyCode.RIGHT)) - .tooltipKey("accessSubConnections"); + .tooltipKey("accessSubConnections", new KeyCodeCombination(KeyCode.RIGHT)); return quickAccessButton; } @@ -84,8 +83,7 @@ public class StoreSectionComp extends Comp> { .apply(struc -> struc.get().setMinWidth(30)) .apply(struc -> struc.get().setPrefWidth(30)) .focusTraversableForAccessibility() - .displayOnlyShortcut(new KeyCodeCombination(KeyCode.SPACE)) - .tooltipKey("expand") + .tooltipKey("expand", new KeyCodeCombination(KeyCode.SPACE)) .accessibleText(Bindings.createStringBinding( () -> { return "Expand " + section.getWrapper().getName().getValue(); diff --git a/app/src/main/java/io/xpipe/app/fxcomps/Comp.java b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java index fb2b79dc5..9407d4646 100644 --- a/app/src/main/java/io/xpipe/app/fxcomps/Comp.java +++ b/app/src/main/java/io/xpipe/app/fxcomps/Comp.java @@ -7,7 +7,6 @@ import io.xpipe.app.fxcomps.augment.GrowAugment; import io.xpipe.app.fxcomps.impl.TooltipAugment; import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.PlatformThread; -import io.xpipe.app.fxcomps.util.Shortcuts; import javafx.application.Platform; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; @@ -21,7 +20,6 @@ import javafx.scene.layout.VBox; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -179,14 +177,6 @@ public abstract class Comp> { return apply(GrowAugment.create(width, height)); } - public Comp shortcut(KeyCombination shortcut, Consumer con) { - return apply(struc -> Shortcuts.addShortcut(struc.get(), shortcut, r -> con.accept(struc))); - } - - public Comp displayOnlyShortcut(KeyCombination shortcut) { - return apply(struc -> Shortcuts.addDisplayShortcut(struc.get(), shortcut)); - } - public Comp tooltip(ObservableValue text) { return apply(new TooltipAugment<>(text, null)); } diff --git a/app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java b/app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java deleted file mode 100644 index ca27f6dca..000000000 --- a/app/src/main/java/io/xpipe/app/fxcomps/util/Shortcuts.java +++ /dev/null @@ -1,66 +0,0 @@ -package io.xpipe.app.fxcomps.util; - -import javafx.event.EventHandler; -import javafx.scene.Scene; -import javafx.scene.control.ButtonBase; -import javafx.scene.input.KeyCombination; -import javafx.scene.input.KeyEvent; -import javafx.scene.layout.Region; - -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -public class Shortcuts { - - private static final Map DISPLAY_SHORTCUTS = new HashMap<>(); - - public static void addDisplayShortcut(Region region, KeyCombination comb) { - DISPLAY_SHORTCUTS.put(region, comb); - } - - public static void addShortcut(T region, KeyCombination comb) { - addShortcut(region, comb, ButtonBase::fire); - } - - public static void addShortcut(T region, KeyCombination comb, Consumer exec) { - var filter = new EventHandler() { - public void handle(KeyEvent ke) { - if (!region.isVisible() || !region.isManaged() || region.isDisabled()) { - return; - } - - if (comb.match(ke)) { - exec.accept(region); - ke.consume(); - } - } - }; - - DISPLAY_SHORTCUTS.put(region, comb); - AtomicReference scene = new AtomicReference<>(); - region.sceneProperty().subscribe(s -> { - if (Objects.equals(s, scene.get())) { - return; - } - - if (scene.get() != null) { - scene.get().removeEventHandler(KeyEvent.KEY_PRESSED, filter); - DISPLAY_SHORTCUTS.remove(region); - scene.set(null); - } - - if (s != null) { - scene.set(s); - DISPLAY_SHORTCUTS.put(region, comb); - s.addEventHandler(KeyEvent.KEY_PRESSED, filter); - } - }); - } - - public static KeyCombination getDisplayShortcut(Region region) { - return DISPLAY_SHORTCUTS.get(region); - } -} diff --git a/app/src/main/java/io/xpipe/app/util/InputHelper.java b/app/src/main/java/io/xpipe/app/util/InputHelper.java index da6390410..10296b43d 100644 --- a/app/src/main/java/io/xpipe/app/util/InputHelper.java +++ b/app/src/main/java/io/xpipe/app/util/InputHelper.java @@ -12,27 +12,6 @@ import java.util.function.Consumer; public class InputHelper { - public static void onCtrlKeyCode(EventTarget target, KeyCode code, boolean filter, Consumer r) { - EventHandler keyEventEventHandler = event -> { - if (event.isAltDown() || event.isShiftDown()) { - return; - } - - if (!event.isShortcutDown()) { - return; - } - - if (code == event.getCode()) { - r.accept(event); - } - }; - if (filter) { - target.addEventFilter(KeyEvent.KEY_PRESSED, keyEventEventHandler); - } else { - target.addEventHandler(KeyEvent.KEY_PRESSED, keyEventEventHandler); - } - } - public static void onKeyCombination(EventTarget target, KeyCombination c, boolean filter, Consumer r) { EventHandler keyEventEventHandler = event -> { if (c.match(event)) { diff --git a/app/src/main/resources/io/xpipe/app/resources/style/browser.css b/app/src/main/resources/io/xpipe/app/resources/style/browser.css index cb3957d11..3e17ee8a6 100644 --- a/app/src/main/resources/io/xpipe/app/resources/style/browser.css +++ b/app/src/main/resources/io/xpipe/app/resources/style/browser.css @@ -79,7 +79,11 @@ -fx-background-color: transparent; } -.browser .top-bar > .button:hover { +.browser .top-bar .button:hover, .root:key-navigation .browser .top-bar .button:focused { + -fx-background-color: -color-accent-subtle; +} + +.browser .top-bar .menu-button:hover, .root:key-navigation .browser .top-bar .menu-button:focused { -fx-background-color: -color-accent-subtle; } diff --git a/ext/base/src/main/java/io/xpipe/ext/base/browser/EditFileAction.java b/ext/base/src/main/java/io/xpipe/ext/base/browser/EditFileAction.java index dfe276ae5..797dec80e 100644 --- a/ext/base/src/main/java/io/xpipe/ext/base/browser/EditFileAction.java +++ b/ext/base/src/main/java/io/xpipe/ext/base/browser/EditFileAction.java @@ -11,12 +11,20 @@ import io.xpipe.core.store.FileKind; import javafx.beans.value.ObservableValue; import javafx.scene.Node; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyCodeCombination; +import javafx.scene.input.KeyCombination; import org.kordamp.ikonli.javafx.FontIcon; import java.util.List; public class EditFileAction implements LeafAction { + @Override + public KeyCombination getShortcut() { + return new KeyCodeCombination(KeyCode.E, KeyCombination.SHORTCUT_DOWN); + } + @Override public void execute(OpenFileSystemModel model, List entries) { for (BrowserEntry entry : entries) {