Rework split pane

This commit is contained in:
crschnick
2026-06-02 00:25:00 +00:00
parent 351dbea6c2
commit c96aa2ac6b
9 changed files with 66 additions and 25 deletions

View File

@@ -80,7 +80,6 @@ public class BrowserFullSessionComp extends SimpleRegionBuilder {
loadingStack.apply(struc -> struc.setPickOnBounds(false));
var delayedStack = new DelayedInitComp(
left, () -> StoreViewState.get() != null && StoreViewState.get().isInitialized());
delayedStack.hide(AppSizeBreakpoints.compactMode());
var splitPane = new LeftSplitPaneComp(delayedStack, loadingStack)
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
.withOnDividerChange(d -> {

View File

@@ -8,6 +8,7 @@ import io.xpipe.app.comp.base.PrettyImageHelper;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.core.AppFontSizes;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.AppSizeBreakpoints;
import io.xpipe.app.platform.LabelGraphic;
import io.xpipe.app.platform.MenuHelper;
@@ -269,24 +270,24 @@ public class BrowserSessionTabsComp extends SimpleRegionBuilder {
.paddingProperty()
.bind(Bindings.createObjectBinding(
() -> {
if (!AppSizeBreakpoints.compactMode().get()) {
if (!AppLayoutModel.get().getPortraitLayoutCollapsed().get()) {
return new Insets(2, 0, 4, -leftPadding.get() + 3);
} else {
return new Insets(2, 0, 4, -leftPadding.get() - 4);
}
},
AppSizeBreakpoints.compactMode(),
AppLayoutModel.get().getPortraitLayoutCollapsed(),
leftPadding));
tabs.paddingProperty()
.bind(Bindings.createObjectBinding(
() -> {
if (!AppSizeBreakpoints.compactMode().get()) {
if (!AppLayoutModel.get().getPortraitLayoutCollapsed().get()) {
return new Insets(0, 0, 0, -5);
} else {
return new Insets(0, 0, 0, 5);
}
},
AppSizeBreakpoints.compactMode()));
AppLayoutModel.get().getPortraitLayoutCollapsed()));
headerHeight.bind(headerArea.heightProperty());
});
}

View File

@@ -3,12 +3,16 @@ package io.xpipe.app.comp.base;
import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.comp.RegionStructure;
import io.xpipe.app.comp.RegionStructureBuilder;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.core.AppSizeBreakpoints;
import io.xpipe.app.issue.TrackEvent;
import io.xpipe.app.platform.LabelGraphic;
import io.xpipe.app.platform.PlatformThread;
import io.xpipe.app.terminal.TerminalDockHubManager;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.Parent;

View File

@@ -4,6 +4,7 @@ import io.xpipe.app.comp.BaseRegionBuilder;
import io.xpipe.app.comp.RegionStructure;
import io.xpipe.app.comp.RegionStructureBuilder;
import io.xpipe.app.core.AppLayoutModel;
import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
@@ -30,7 +31,7 @@ public class LeftSplitPaneComp extends RegionStructureBuilder<SplitPane, LeftSpl
@Override
public Structure createBase() {
var c = center.build();
var sidebar = left.build();
var sidebar = left.hide(AppLayoutModel.get().getPortraitLayoutCollapsed()).build();
if (initialWidth != null) {
sidebar.setPrefWidth(initialWidth);
}

View File

@@ -19,10 +19,8 @@ import io.xpipe.app.util.*;
import io.xpipe.app.webtop.WebtopAppListDialog;
import io.xpipe.app.webtop.WebtopAppListManager;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.binding.Bindings;
import javafx.beans.property.*;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@@ -54,6 +52,8 @@ public class AppLayoutModel {
private final BooleanProperty ptbAvailable = new SimpleBooleanProperty();
private final BooleanProperty portraitLayoutCollapsed = new SimpleBooleanProperty();
public AppLayoutModel(SavedState savedState) {
this.savedState = savedState;
this.entries = createEntryList();
@@ -112,6 +112,27 @@ public class AppLayoutModel {
}
}
});
var portraitExpanded = new SimpleBooleanProperty(true);
var toggleExpand = new AppLayoutModel.QueueEntry(AppI18n.observable("expand"), Bindings.createObjectBinding(() -> {
return new LabelGraphic.IconGraphic("mdi2a-arrow-expand-horizontal");
}, portraitExpanded), () -> {
portraitExpanded.set(!portraitExpanded.get());
return false;
});
AppSizeBreakpoints.portraitMode().subscribe(v -> {
if (v) {
AppLayoutModel.get().getQueueEntries().add(toggleExpand);
portraitExpanded.set(false);
} else {
AppLayoutModel.get().getQueueEntries().remove(toggleExpand);
portraitExpanded.set(true);
}
});
portraitLayoutCollapsed.bind(Bindings.createBooleanBinding(() -> {
return AppSizeBreakpoints.portraitMode().get() && !portraitExpanded.get();
}, portraitExpanded, AppSizeBreakpoints.portraitMode()));
}
public static void reset() {
@@ -263,6 +284,13 @@ public class AppLayoutModel {
}
public QueueEntry(ObservableValue<String> name, LabelGraphic icon, Supplier<Boolean> action) {
this.name = name;
this.icon = new ReadOnlyObjectWrapper<>(icon);
this.action = action;
this.top = false;
}
public QueueEntry(ObservableValue<String> name, ObservableValue<LabelGraphic> icon, Supplier<Boolean> action) {
this.name = name;
this.icon = icon;
this.action = action;
@@ -270,7 +298,7 @@ public class AppLayoutModel {
}
ObservableValue<String> name;
LabelGraphic icon;
ObservableValue<LabelGraphic> icon;
Supplier<Boolean> action;
boolean top;

View File

@@ -30,7 +30,6 @@ public class StoreLayoutComp extends SimpleRegionBuilder {
private Region createContent() {
var filterTrigger = new ObservableSubscriber();
var left = new StoreSidebarComp(filterTrigger);
left.hide(AppSizeBreakpoints.compactMode());
left.minWidth(285);
left.maxWidth(500);
left.minHeight(0);

View File

@@ -1,6 +1,9 @@
package io.xpipe.app.prefs;
import io.xpipe.app.comp.RegionBuilder;
import io.xpipe.app.comp.SimpleRegionBuilder;
import io.xpipe.app.comp.base.LeftSplitPaneComp;
import io.xpipe.app.comp.base.StackComp;
import io.xpipe.app.comp.base.VerticalComp;
import io.xpipe.app.platform.PlatformThread;
import io.xpipe.app.util.BooleanScope;
@@ -12,6 +15,8 @@ import javafx.scene.layout.*;
import net.synedra.validatorfx.GraphicDecorationStackPane;
import java.util.List;
public class AppPrefsComp extends SimpleRegionBuilder {
@Override
@@ -83,17 +88,16 @@ public class AppPrefsComp extends SimpleRegionBuilder {
scrollPane.setFitToWidth(true);
HBox.setHgrow(scrollPane, Priority.ALWAYS);
var sidebar = new AppPrefsSidebarComp().build();
sidebar.setMinWidth(260);
sidebar.setPrefWidth(260);
sidebar.setMaxWidth(260);
sidebar.setMinHeight(0);
var sidebar = new AppPrefsSidebarComp();
var sidebarWrapper = new StackComp(List.of(sidebar));
sidebarWrapper.padding(new Insets(4));
sidebarWrapper.minWidth(150);
sidebarWrapper.maxWidth(350);
var split = new HBox(sidebar, scrollPane);
HBox.setMargin(sidebar, new Insets(4));
split.setFillHeight(true);
split.getStyleClass().add("prefs");
return split;
var split = new LeftSplitPaneComp(sidebarWrapper, RegionBuilder.of(() -> scrollPane));
split.withInitialWidth(265);
split.style("prefs");
return split.build();
}
private double computeCategoryOffset(Region box, ScrollPane scrollPane, AppPrefsCategory val) {

View File

@@ -19,6 +19,7 @@ import io.xpipe.app.util.OsType;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.ListChangeListener;
import javafx.scene.input.KeyCode;
@@ -138,7 +139,7 @@ public class TerminalDockHubManager {
AppI18n.observable(
"toggleTerminalDock",
new KeyCodeCombination(KeyCode.T, KeyCombination.SHORTCUT_DOWN).getDisplayText()),
new LabelGraphic.NodeGraphic(() -> {
new ReadOnlyObjectWrapper<>(new LabelGraphic.NodeGraphic(() -> {
var inner = new FontIcon();
inner.iconCodeProperty()
.bind(PlatformThread.sync(Bindings.createObjectBinding(
@@ -153,7 +154,7 @@ public class TerminalDockHubManager {
inner.getStyleClass().add("graphic");
inner.getStyleClass().add("terminal-dock-button");
return inner;
}),
})),
() -> {
refreshDockStatus();

View File

@@ -89,7 +89,11 @@
-fx-effect: NONE;
}
.root:seamless-frame .prefs .scroll-bar:vertical {
-fx-padding: 9 1 5 1;
}
.prefs .split-pane-divider {
-fx-padding: 0 2 0 3;
-fx-background-color: transparent;
}