diff --git a/ts3-client/core/src/main/java/com/ts3client/config/Settings.java b/ts3-client/core/src/main/java/com/ts3client/config/Settings.java index c8ba187..88fc1dc 100644 --- a/ts3-client/core/src/main/java/com/ts3client/config/Settings.java +++ b/ts3-client/core/src/main/java/com/ts3client/config/Settings.java @@ -139,6 +139,8 @@ public final class Settings { public boolean showStatusBar = true; /** Whether the Master Volume slider is shown on the toolbar. */ public boolean showMasterVolumeSlider = true; + /** Share of the tree/info column the tree takes, i.e. where their divider sits. */ + public double infoSplitRatio = 0.68; /** Which actions make a sound, and which ones are important enough to survive muting. */ public final NotificationSettings notifications = new NotificationSettings(); @@ -230,6 +232,7 @@ public final class Settings { appearance = parseAppearance(props.getProperty("appearance"), appearance); showStatusBar = parseB(props.getProperty("showStatusBar"), showStatusBar); showMasterVolumeSlider = parseB(props.getProperty("showMasterVolumeSlider"), showMasterVolumeSlider); + infoSplitRatio = parseD(props.getProperty("infoSplitRatio"), infoSplitRatio); notifications.load(props); } @@ -272,6 +275,7 @@ public final class Settings { props.setProperty("appearance", appearance.name()); props.setProperty("showStatusBar", Boolean.toString(showStatusBar)); props.setProperty("showMasterVolumeSlider", Boolean.toString(showMasterVolumeSlider)); + props.setProperty("infoSplitRatio", Double.toString(infoSplitRatio)); notifications.store(props); } diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java b/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java index fcdb41c..5bd66c4 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/MainFrame.java @@ -723,6 +723,7 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener { private void shutdown() { if (!shuttingDown.compareAndSet(false, true)) return; if (statusTimer != null) statusTimer.stop(); + settings.save(); // keeps the layout the user left behind (info panel height, …) try { Runtime.getRuntime().removeShutdownHook(shutdownHook); } catch (IllegalStateException ignored) { diff --git a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java index abdb0a0..f9149c6 100644 --- a/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java +++ b/ts3-client/swing/src/main/java/com/ts3client/ui/ServerTab.java @@ -16,6 +16,8 @@ import javax.swing.SwingUtilities; import java.util.ArrayList; import java.util.List; import java.awt.Component; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; /** * One server connection and the views bound to it (tree, info and chat). The @@ -45,6 +47,8 @@ final class ServerTab implements ServerTabConnectionEvents.Listener { private JSplitPane leftColumn; private int normalDividerSize; private int savedDividerLocation = -1; + /** Whether the saved divider share has been applied; before that, layout is not the user's doing. */ + private boolean splitRestored; /** Label shown in the tab bar: the server name once known, the address before that. */ private String title = "New connection"; @@ -109,6 +113,16 @@ final class ServerTab implements ServerTabConnectionEvents.Listener { leftColumn.setResizeWeight(0.68); leftColumn.setContinuousLayout(true); normalDividerSize = leftColumn.getDividerSize(); + // The info panel keeps the height the user gave it, in this tab and the next session. + leftColumn.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + if (splitRestored) return; + splitRestored = true; + leftColumn.setDividerLocation(settings.infoSplitRatio); + } + }); + leftColumn.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, e -> rememberSplit()); JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftColumn, chatPanel); split.setResizeWeight(0.55); @@ -377,6 +391,19 @@ final class ServerTab implements ServerTabConnectionEvents.Listener { treeActions.browseFiles(channel); } + /** + * Records where the user put the divider, as a share of the column. Collapsed and + * pre-layout positions are not the user's choice, so they are left out. + */ + private void rememberSplit() { + if (!splitRestored || !infoPanel.isVisible()) return; + int span = leftColumn.getHeight() - leftColumn.getDividerSize(); + if (span <= 0) return; + double ratio = leftColumn.getDividerLocation() / (double) span; + if (ratio <= 0.05 || ratio >= 0.98) return; + settings.infoSplitRatio = ratio; + } + /** Collapses the info panel to nothing while its content lives in the chat tab, or restores it. */ private void setInfoPanelHidden(boolean hidden) { if (hidden == !infoPanel.isVisible()) return;