From 7ba01f9504bd825aa328bf0b75c0e4adcec89b16 Mon Sep 17 00:00:00 2001 From: Radek Davidek Date: Mon, 19 Jan 2026 13:15:16 +0100 Subject: [PATCH] UI updates --- .../cz/kamma/kfmanager/config/AppConfig.java | 12 ++++++ .../cz/kamma/kfmanager/ui/FilePanelTab.java | 32 ++++++++++++--- .../cz/kamma/kfmanager/ui/MainWindow.java | 16 +++++--- .../cz/kamma/kfmanager/ui/SettingsDialog.java | 40 +++++++++++++++++++ 4 files changed, 89 insertions(+), 11 deletions(-) diff --git a/src/main/java/cz/kamma/kfmanager/config/AppConfig.java b/src/main/java/cz/kamma/kfmanager/config/AppConfig.java index 6d7419e..34a9bb5 100644 --- a/src/main/java/cz/kamma/kfmanager/config/AppConfig.java +++ b/src/main/java/cz/kamma/kfmanager/config/AppConfig.java @@ -101,6 +101,18 @@ public class AppConfig { public void setActivePanel(String panel) { properties.setProperty("active.panel", panel); } + + public int getBriefMouseWheelSteps() { + try { + return Integer.parseInt(properties.getProperty("brief.mousewheel.steps", "10")); + } catch (NumberFormatException e) { + return 10; + } + } + + public void setBriefMouseWheelSteps(int steps) { + properties.setProperty("brief.mousewheel.steps", String.valueOf(steps)); + } public String getLeftPanelPath() { return properties.getProperty("leftPanel.path", System.getProperty("user.home")); diff --git a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java index 75c0863..7039a1f 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java +++ b/src/main/java/cz/kamma/kfmanager/ui/FilePanelTab.java @@ -535,7 +535,26 @@ public class FilePanelTab extends JPanel { JScrollPane scrollPane = new JScrollPane(fileTable); // Enable horizontal scrollbar when needed so BRIEF mode can scroll left-right scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); - add(scrollPane, BorderLayout.CENTER); + + // Implement mouse wheel navigation in BRIEF mode to match arrow key behavior + fileTable.addMouseWheelListener(new java.awt.event.MouseWheelListener() { + @Override + public void mouseWheelMoved(java.awt.event.MouseWheelEvent e) { + if (viewMode == ViewMode.BRIEF) { + int rotation = e.getWheelRotation(); + if (rotation != 0) { + int steps = 10; + if (persistedConfig != null) { + steps = persistedConfig.getBriefMouseWheelSteps(); + } + handleBriefNavigation(rotation > 0, steps); + e.consume(); + } + } + } + }); + + add(scrollPane, BorderLayout.CENTER); // Status bar statusLabel = new JLabel(" "); @@ -683,15 +702,18 @@ public class FilePanelTab extends JPanel { } private void handleBriefNavigation(boolean down) { + handleBriefNavigation(down, 1); + } + + private void handleBriefNavigation(boolean down, int amount) { int currentRow = fileTable.getSelectedRow(); if (currentRow < 0) return; int currentIndex = briefCurrentColumn * tableModel.briefRowsPerColumn + currentRow; - int newIndex = down ? currentIndex + 1 : currentIndex - 1; + int newIndex = down ? currentIndex + amount : currentIndex - amount; - if (newIndex < 0 || newIndex >= tableModel.items.size()) { - return; - } + if (newIndex < 0) newIndex = 0; + if (newIndex >= tableModel.items.size()) newIndex = tableModel.items.size() - 1; int newColumn = newIndex / tableModel.briefRowsPerColumn; int newRow = newIndex % tableModel.briefRowsPerColumn; diff --git a/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java b/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java index 5580e64..34748af 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java +++ b/src/main/java/cz/kamma/kfmanager/ui/MainWindow.java @@ -95,7 +95,6 @@ public class MainWindow extends JFrame { String leftPath = config.getLeftPanelPath(); leftPanel = new FilePanel(leftPath); leftPanel.setAppConfig(config); - leftPanel.setBorder(BorderFactory.createTitledBorder("Left panel")); // Provide a callback so tabs inside the panel can request switching panels with TAB leftPanel.setSwitchPanelCallback(() -> switchPanelsFromChild()); leftPanel.setOnDirectoryChangedAll(() -> updateCommandLinePrompt()); @@ -112,7 +111,6 @@ public class MainWindow extends JFrame { String rightPath = config.getRightPanelPath(); rightPanel = new FilePanel(rightPath); rightPanel.setAppConfig(config); - rightPanel.setBorder(BorderFactory.createTitledBorder("Right panel")); // Provide a callback so tabs inside the panel can request switching panels with TAB rightPanel.setSwitchPanelCallback(() -> switchPanelsFromChild()); rightPanel.setOnDirectoryChangedAll(() -> updateCommandLinePrompt()); @@ -724,6 +722,8 @@ public class MainWindow extends JFrame { if (sel != null) { if (leftPanel != null) leftPanel.applySelectionColor(sel); if (rightPanel != null) rightPanel.applySelectionColor(sel); + // Ensure the active panel border uses the updated configuration color immediately + SwingUtilities.invokeLater(() -> updateActivePanelBorder()); } Color mark = config.getMarkedColor(); @@ -957,10 +957,14 @@ public class MainWindow extends JFrame { * Update panel borders according to active panel */ private void updateActivePanelBorder() { - leftPanel.setBorder(BorderFactory.createTitledBorder( - activePanel == leftPanel ? "Left panel [ACTIVE]" : "Left panel")); - rightPanel.setBorder(BorderFactory.createTitledBorder( - activePanel == rightPanel ? "Right panel [ACTIVE]" : "Right panel")); + Color selColor = config.getSelectionColor(); + if (selColor == null) selColor = new Color(184, 207, 229); + + // Active panel uses selection color, inactive panel uses a very dark gray border + Color inactiveColor = new Color(45, 45, 45); + + leftPanel.setBorder(BorderFactory.createLineBorder(activePanel == leftPanel ? selColor : inactiveColor, 2)); + rightPanel.setBorder(BorderFactory.createLineBorder(activePanel == rightPanel ? selColor : inactiveColor, 2)); } /** diff --git a/src/main/java/cz/kamma/kfmanager/ui/SettingsDialog.java b/src/main/java/cz/kamma/kfmanager/ui/SettingsDialog.java index b18d513..43ab52e 100644 --- a/src/main/java/cz/kamma/kfmanager/ui/SettingsDialog.java +++ b/src/main/java/cz/kamma/kfmanager/ui/SettingsDialog.java @@ -25,6 +25,7 @@ public class SettingsDialog extends JDialog { private final Color originalSel; private final Color originalMark; private final Color originalFolder; + private final int originalBriefMouseWheelSteps; private final Font originalGlobalFont; private final Font originalEditorFont; private final String originalExternalEditorPath; @@ -55,6 +56,7 @@ public class SettingsDialog extends JDialog { this.originalSel = config.getSelectionColor(); this.originalMark = config.getMarkedColor(); this.originalFolder = config.getFolderColor(); + this.originalBriefMouseWheelSteps = config.getBriefMouseWheelSteps(); this.originalGlobalFont = config.getGlobalFont(); this.originalEditorFont = config.getEditorFont(); this.originalExternalEditorPath = config.getExternalEditorPath(); @@ -70,6 +72,7 @@ public class SettingsDialog extends JDialog { DefaultListModel model = new DefaultListModel<>(); model.addElement("Appearance"); model.addElement("Editor"); + model.addElement("Behavior"); model.addElement("Sorting"); model.addElement("Toolbar"); model.addElement("Associations"); @@ -83,6 +86,7 @@ public class SettingsDialog extends JDialog { // Build category panels cards.add(buildAppearancePanel(), "Appearance"); cards.add(buildEditorPanel(), "Editor"); + cards.add(buildBehaviorPanel(), "Behavior"); cards.add(buildSortingPanel(), "Sorting"); cards.add(buildToolbarPanel(), "Toolbar"); cards.add(buildAssociationsPanel(), "Associations"); @@ -199,6 +203,15 @@ public class SettingsDialog extends JDialog { config.setExternalEditorPath(externalEditorField.getText()); } + // Collect Behavior settings + JPanel behaviorHolder = (JPanel) panels.get("Behavior"); + if (behaviorHolder != null) { + try { + JSpinner mws = (JSpinner) behaviorHolder.getClientProperty("mouseWheelSteps"); + if (mws != null) config.setBriefMouseWheelSteps((Integer) mws.getValue()); + } catch (Exception ignore) {} + } + // Persist config and notify caller config.saveConfig(); if (onChange != null) onChange.run(); @@ -211,6 +224,7 @@ public class SettingsDialog extends JDialog { config.setSelectionColor(originalSel); config.setMarkedColor(originalMark); config.setFolderColor(originalFolder); + config.setBriefMouseWheelSteps(originalBriefMouseWheelSteps); config.setGlobalFont(originalGlobalFont); config.setEditorFont(originalEditorFont); config.setExternalEditorPath(originalExternalEditorPath); @@ -402,6 +416,32 @@ public class SettingsDialog extends JDialog { return p; } + private JPanel buildBehaviorPanel() { + JPanel p = new JPanel(new BorderLayout(8, 8)); + JPanel grid = new JPanel(new GridBagLayout()); + grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(4, 4, 4, 4); + gbc.weightx = 1.0; + + int row = 0; + + // Mouse wheel steps in brief mode + gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0; + grid.add(new JLabel("Mouse wheel steps (Brief mode):"), gbc); + + JSpinner mwSteps = new JSpinner(new SpinnerNumberModel(config.getBriefMouseWheelSteps(), 1, 100, 1)); + gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0; + grid.add(mwSteps, gbc); + + p.add(grid, BorderLayout.NORTH); + p.putClientProperty("mouseWheelSteps", mwSteps); + panels.put("Behavior", p); + return p; + } + private JPanel buildSortingPanel() { JPanel p = new JPanel(new BorderLayout(8, 8)); JPanel grid = new JPanel();