new UI updates

This commit is contained in:
rdavidek 2026-01-14 21:31:56 +01:00
parent 30502d6136
commit 0f0b073cf2
5 changed files with 119 additions and 20 deletions

View File

@ -305,6 +305,20 @@ public class AppConfig {
}
}
public Color getFolderColor() {
String v = properties.getProperty("appearance.folder", null);
if (v == null) return new Color(255, 200, 0); // Default yellow/gold
try { return Color.decode(v); } catch (Exception ex) { return new Color(255, 200, 0); }
}
public void setFolderColor(Color c) {
if (c == null) {
properties.remove("appearance.folder");
} else {
properties.setProperty("appearance.folder", String.format("#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue()));
}
}
// -- Sorting persistence (global default)
public int getDefaultSortColumn() {
return Integer.parseInt(properties.getProperty("global.sort.column", "-1"));

View File

@ -439,10 +439,6 @@ public class FileEditor extends JDialog {
updateStatus();
}
private void buildHexViewText() {
buildHexViewText(0L);
}
private void buildHexViewText(long baseOffset) {
byteTextOffsets.clear();
if (fileBytes == null) fileBytes = new byte[0];

View File

@ -5,7 +5,6 @@ import com.kfmanager.model.FileItem;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.List;
@ -443,13 +442,6 @@ public class FilePanel extends JPanel {
double gb = bytes / 1024.0 / 1024.0 / 1024.0;
return String.format("%.1f", gb);
}
private static String humanReadableByteCount(long bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String pre = "KMGTPE".charAt(exp-1) + "";
return String.format("%.1f %sB", bytes / Math.pow(1024, exp), pre);
}
/**
* Request focus on the table in the current tab

View File

@ -31,12 +31,10 @@ public class FilePanelTab extends JPanel {
private JLabel statusLabel;
private ViewMode viewMode = ViewMode.FULL;
private int briefCurrentColumn = 0;
private int briefColumnBeforeEnter = 0;
private Runnable onDirectoryChanged;
private Runnable onSwitchPanelRequested;
// Appearance customization
private Color selectionColor = new Color(184, 207, 229);
private Color selectionInactiveColor = new Color(220, 220, 220);
private Color markedColor = new Color(204, 153, 0);
// Sorting state for FULL mode header clicks
private int sortColumn = -1; // 0=name,1=size,2=date
@ -155,8 +153,6 @@ public class FilePanelTab extends JPanel {
public void applySelectionColor(Color sel) {
if (sel == null) return;
this.selectionColor = sel;
// Derive an inactive variant
this.selectionInactiveColor = sel.brighter();
fileTable.repaint();
}
@ -828,7 +824,6 @@ public class FilePanelTab extends JPanel {
loadDirectory(temp.toFile());
}
} else if (item.isDirectory()) {
briefColumnBeforeEnter = briefCurrentColumn;
loadDirectory(item.getFile());
}
}
@ -869,7 +864,6 @@ public class FilePanelTab extends JPanel {
loadDirectory(temp.toFile());
}
} else if (item.isDirectory()) {
briefColumnBeforeEnter = briefCurrentColumn;
loadDirectory(item.getFile());
}
}
@ -1006,11 +1000,15 @@ public class FilePanelTab extends JPanel {
if (cur.equals(currentArchiveTempDir)) {
File parent = currentArchiveSourceFile.getParentFile();
if (parent != null) {
String archiveName = currentArchiveSourceFile.getName();
// cleanup temp dir before switching back
deleteTempDirRecursively(currentArchiveTempDir);
currentArchiveTempDir = null;
currentArchiveSourceFile = null;
loadDirectory(parent, true);
loadDirectory(parent, false);
// Select the archive file we just left
SwingUtilities.invokeLater(() -> selectItemByName(archiveName));
}
return;
}
@ -1019,7 +1017,11 @@ public class FilePanelTab extends JPanel {
File parent = currentDirectory.getParentFile();
if (parent != null) {
loadDirectory(parent, true);
String previousDirName = currentDirectory.getName();
loadDirectory(parent, false);
// Select the directory we just left
SwingUtilities.invokeLater(() -> selectItemByName(previousDirName));
}
}
@ -1036,6 +1038,7 @@ public class FilePanelTab extends JPanel {
fileTable.setRowSelectionInterval(row, row);
fileTable.scrollRectToVisible(fileTable.getCellRect(row, column, true));
fileTable.repaint();
fileTable.requestFocusInWindow();
updateStatus();
}
return;
@ -1047,6 +1050,7 @@ public class FilePanelTab extends JPanel {
if (item != null && item.getName().equals(name)) {
fileTable.setRowSelectionInterval(i, i);
fileTable.scrollRectToVisible(fileTable.getCellRect(i, 0, true));
fileTable.requestFocusInWindow();
updateStatus();
return;
}
@ -1258,6 +1262,12 @@ public class FilePanelTab extends JPanel {
// Zobrazit ikonu pro názvy souborů
Icon icon = item.getIcon();
if (item.getName().equals("..")) {
icon = new UpArrowIcon(getForeground());
} else if (item.isDirectory() && persistedConfig != null) {
icon = new ColoredFolderIcon(persistedConfig.getFolderColor());
}
if (viewMode == ViewMode.BRIEF) {
// V BRIEF módu jsou všechny sloupce názvy
setIcon(icon);
@ -1913,4 +1923,80 @@ public class FilePanelTab extends JPanel {
return null;
}
}
/**
* Custom icon for directories that uses a configurable color.
*/
private static class ColoredFolderIcon implements Icon {
private final Color color;
public ColoredFolderIcon(Color color) {
this.color = color;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
// Draw a simple folder shape
// Main body
g2.fillRect(x + 2, y + 4, 12, 8);
// Tab
g2.fillRect(x + 2, y + 2, 5, 2);
// Optional: outline for depth
g2.setColor(color.darker());
g2.drawRect(x + 2, y + 4, 12, 8);
g2.dispose();
}
@Override
public int getIconWidth() {
return 16;
}
@Override
public int getIconHeight() {
return 16;
}
}
/**
* Custom icon for ".." that shows an upward arrow.
*/
private static class UpArrowIcon implements Icon {
private final Color color;
public UpArrowIcon(Color color) {
this.color = color;
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(color);
// Draw a simple upward arrow
int[] xPoints = {x + 8, x + 3, x + 13};
int[] yPoints = {y + 3, y + 10, y + 10};
g2.fillPolygon(xPoints, yPoints, 3);
g2.fillRect(x + 7, y + 10, 2, 4);
g2.dispose();
}
@Override
public int getIconWidth() {
return 16;
}
@Override
public int getIconHeight() {
return 16;
}
}
}

View File

@ -23,6 +23,7 @@ public class SettingsDialog extends JDialog {
private final Color originalBg;
private final Color originalSel;
private final Color originalMark;
private final Color originalFolder;
private final Font originalGlobalFont;
private final Font originalEditorFont;
@ -31,6 +32,7 @@ public class SettingsDialog extends JDialog {
private JButton appearanceBgBtn;
private JButton appearanceSelBtn;
private JButton appearanceMarkBtn;
private JButton appearanceFolderBtn;
// Editor controls
private JButton editorFontBtn;
@ -47,6 +49,7 @@ public class SettingsDialog extends JDialog {
this.originalBg = config.getBackgroundColor();
this.originalSel = config.getSelectionColor();
this.originalMark = config.getMarkedColor();
this.originalFolder = config.getFolderColor();
this.originalGlobalFont = config.getGlobalFont();
this.originalEditorFont = config.getEditorFont();
@ -159,6 +162,7 @@ public class SettingsDialog extends JDialog {
config.setBackgroundColor(originalBg);
config.setSelectionColor(originalSel);
config.setMarkedColor(originalMark);
config.setFolderColor(originalFolder);
config.setGlobalFont(originalGlobalFont);
config.setEditorFont(originalEditorFont);
@ -212,6 +216,13 @@ public class SettingsDialog extends JDialog {
});
grid.add(appearanceMarkBtn);
grid.add(new JLabel("Folder icon color:"));
appearanceFolderBtn = createColorButton(config.getFolderColor(), "Choose folder icon color", c -> {
config.setFolderColor(c);
if (onChange != null) onChange.run();
});
grid.add(appearanceFolderBtn);
p.add(grid, BorderLayout.NORTH);
panels.put("Appearance", p);
return p;