Remember how tall the user made the info panel
Kept as a share of the tree/info column, so it survives new tabs, a resized window and the next session. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -139,6 +139,8 @@ public final class Settings {
|
|||||||
public boolean showStatusBar = true;
|
public boolean showStatusBar = true;
|
||||||
/** Whether the Master Volume slider is shown on the toolbar. */
|
/** Whether the Master Volume slider is shown on the toolbar. */
|
||||||
public boolean showMasterVolumeSlider = true;
|
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. */
|
/** Which actions make a sound, and which ones are important enough to survive muting. */
|
||||||
public final NotificationSettings notifications = new NotificationSettings();
|
public final NotificationSettings notifications = new NotificationSettings();
|
||||||
@@ -230,6 +232,7 @@ public final class Settings {
|
|||||||
appearance = parseAppearance(props.getProperty("appearance"), appearance);
|
appearance = parseAppearance(props.getProperty("appearance"), appearance);
|
||||||
showStatusBar = parseB(props.getProperty("showStatusBar"), showStatusBar);
|
showStatusBar = parseB(props.getProperty("showStatusBar"), showStatusBar);
|
||||||
showMasterVolumeSlider = parseB(props.getProperty("showMasterVolumeSlider"), showMasterVolumeSlider);
|
showMasterVolumeSlider = parseB(props.getProperty("showMasterVolumeSlider"), showMasterVolumeSlider);
|
||||||
|
infoSplitRatio = parseD(props.getProperty("infoSplitRatio"), infoSplitRatio);
|
||||||
notifications.load(props);
|
notifications.load(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -272,6 +275,7 @@ public final class Settings {
|
|||||||
props.setProperty("appearance", appearance.name());
|
props.setProperty("appearance", appearance.name());
|
||||||
props.setProperty("showStatusBar", Boolean.toString(showStatusBar));
|
props.setProperty("showStatusBar", Boolean.toString(showStatusBar));
|
||||||
props.setProperty("showMasterVolumeSlider", Boolean.toString(showMasterVolumeSlider));
|
props.setProperty("showMasterVolumeSlider", Boolean.toString(showMasterVolumeSlider));
|
||||||
|
props.setProperty("infoSplitRatio", Double.toString(infoSplitRatio));
|
||||||
notifications.store(props);
|
notifications.store(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -723,6 +723,7 @@ public final class MainFrame extends JFrame implements ServerTabPane.Listener {
|
|||||||
private void shutdown() {
|
private void shutdown() {
|
||||||
if (!shuttingDown.compareAndSet(false, true)) return;
|
if (!shuttingDown.compareAndSet(false, true)) return;
|
||||||
if (statusTimer != null) statusTimer.stop();
|
if (statusTimer != null) statusTimer.stop();
|
||||||
|
settings.save(); // keeps the layout the user left behind (info panel height, …)
|
||||||
try {
|
try {
|
||||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||||
} catch (IllegalStateException ignored) {
|
} catch (IllegalStateException ignored) {
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import javax.swing.SwingUtilities;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.awt.Component;
|
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
|
* 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 JSplitPane leftColumn;
|
||||||
private int normalDividerSize;
|
private int normalDividerSize;
|
||||||
private int savedDividerLocation = -1;
|
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. */
|
/** Label shown in the tab bar: the server name once known, the address before that. */
|
||||||
private String title = "New connection";
|
private String title = "New connection";
|
||||||
@@ -109,6 +113,16 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
|||||||
leftColumn.setResizeWeight(0.68);
|
leftColumn.setResizeWeight(0.68);
|
||||||
leftColumn.setContinuousLayout(true);
|
leftColumn.setContinuousLayout(true);
|
||||||
normalDividerSize = leftColumn.getDividerSize();
|
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);
|
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftColumn, chatPanel);
|
||||||
split.setResizeWeight(0.55);
|
split.setResizeWeight(0.55);
|
||||||
@@ -377,6 +391,19 @@ final class ServerTab implements ServerTabConnectionEvents.Listener {
|
|||||||
treeActions.browseFiles(channel);
|
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. */
|
/** Collapses the info panel to nothing while its content lives in the chat tab, or restores it. */
|
||||||
private void setInfoPanelHidden(boolean hidden) {
|
private void setInfoPanelHidden(boolean hidden) {
|
||||||
if (hidden == !infoPanel.isVisible()) return;
|
if (hidden == !infoPanel.isVisible()) return;
|
||||||
|
|||||||
Reference in New Issue
Block a user