Browser fixes

This commit is contained in:
crschnick 2024-07-20 16:04:04 +00:00
parent 68e29efd1a
commit 1061d407e5
8 changed files with 95 additions and 33 deletions

View file

@ -1,9 +1,10 @@
package io.xpipe.app.browser; package io.xpipe.app.browser;
import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.session.BrowserSessionModel; import io.xpipe.app.browser.session.BrowserSessionModel;
import io.xpipe.app.comp.base.ButtonComp; import io.xpipe.app.comp.base.ButtonComp;
import io.xpipe.app.comp.base.ListBoxViewComp; import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.comp.base.TileButtonComp; import io.xpipe.app.comp.base.TileButtonComp;
import io.xpipe.app.core.AppFont; import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n; import io.xpipe.app.core.AppI18n;
@ -17,7 +18,6 @@ import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.fxcomps.util.DerivedObservableList; import io.xpipe.app.fxcomps.util.DerivedObservableList;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
@ -31,9 +31,6 @@ import javafx.scene.layout.Priority;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles;
import java.util.List; import java.util.List;
public class BrowserWelcomeComp extends SimpleComp { public class BrowserWelcomeComp extends SimpleComp {
@ -57,8 +54,7 @@ public class BrowserWelcomeComp extends SimpleComp {
.padding(new Insets(5, 0, 0, 0)) .padding(new Insets(5, 0, 0, 0))
.createRegion(); .createRegion();
var loading = LoadingOverlayComp.noProgress(Comp.empty(),model.getBusy()).createRegion(); var hbox = new HBox(img, vbox);
var hbox = new HBox(img, vbox, new Spacer(), loading);
hbox.setAlignment(Pos.CENTER_LEFT); hbox.setAlignment(Pos.CENTER_LEFT);
hbox.setSpacing(15); hbox.setSpacing(15);

View file

@ -3,21 +3,24 @@ package io.xpipe.app.browser.session;
import io.xpipe.app.browser.BrowserBookmarkComp; import io.xpipe.app.browser.BrowserBookmarkComp;
import io.xpipe.app.browser.BrowserBookmarkHeaderComp; import io.xpipe.app.browser.BrowserBookmarkHeaderComp;
import io.xpipe.app.browser.BrowserTransferComp; import io.xpipe.app.browser.BrowserTransferComp;
import io.xpipe.app.comp.base.LoadingOverlayComp;
import io.xpipe.app.comp.base.SideSplitPaneComp; import io.xpipe.app.comp.base.SideSplitPaneComp;
import io.xpipe.app.comp.store.StoreEntryWrapper; import io.xpipe.app.comp.store.StoreEntryWrapper;
import io.xpipe.app.core.AppLayoutModel; import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.AnchorComp;
import io.xpipe.app.fxcomps.impl.StackComp; import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.app.fxcomps.impl.VerticalComp; import io.xpipe.app.fxcomps.impl.VerticalComp;
import io.xpipe.app.fxcomps.util.BindingsHelper; import io.xpipe.app.fxcomps.util.BindingsHelper;
import io.xpipe.app.fxcomps.util.PlatformThread; import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.util.ThreadHelper; import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.ShellStore;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle; import javafx.scene.shape.Rectangle;
@ -101,9 +104,22 @@ public class BrowserSessionComp extends SimpleComp {
var split = new SimpleDoubleProperty(); var split = new SimpleDoubleProperty();
var tabs = new BrowserSessionTabsComp(model, split) var tabs = new BrowserSessionTabsComp(model, split)
.apply(struc -> struc.get().setViewOrder(1)) .apply(struc -> {
.apply(struc -> struc.get().setPickOnBounds(false)); struc.get().setViewOrder(1);
var splitPane = new SideSplitPaneComp(vertical, tabs) struc.get().setPickOnBounds(false);
AnchorPane.setTopAnchor(struc.get(), 0.0);
AnchorPane.setBottomAnchor(struc.get(), 0.0);
AnchorPane.setLeftAnchor(struc.get(), 0.0);
AnchorPane.setRightAnchor(struc.get(), 0.0);
});
var loadingIndicator = LoadingOverlayComp.noProgress(Comp.empty(),model.getBusy())
.apply(struc -> {
AnchorPane.setTopAnchor(struc.get(), 0.0);
AnchorPane.setRightAnchor(struc.get(), 0.0);
})
.styleClass("tab-loading-indicator");
var loadingStack = new AnchorComp(List.of(tabs, loadingIndicator));
var splitPane = new SideSplitPaneComp(vertical, loadingStack)
.withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth()) .withInitialWidth(AppLayoutModel.get().getSavedState().getBrowserConnectionsWidth())
.withOnDividerChange(d -> { .withOnDividerChange(d -> {
AppLayoutModel.get().getSavedState().setBrowserConnectionsWidth(d); AppLayoutModel.get().getSavedState().setBrowserConnectionsWidth(d);

View file

@ -26,6 +26,8 @@ import javafx.scene.control.Tab;
import javafx.scene.control.TabPane; import javafx.scene.control.TabPane;
import javafx.scene.input.DragEvent; import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
@ -207,12 +209,39 @@ public class BrowserSessionTabsComp extends SimpleComp {
if (keyEvent.getCode() == KeyCode.W && keyEvent.isShortcutDown()) { if (keyEvent.getCode() == KeyCode.W && keyEvent.isShortcutDown()) {
tabs.getTabs().remove(current); tabs.getTabs().remove(current);
keyEvent.consume(); keyEvent.consume();
return;
} }
if (keyEvent.getCode() == KeyCode.W && keyEvent.isShortcutDown() && keyEvent.isShiftDown()) { if (keyEvent.getCode() == KeyCode.W && keyEvent.isShortcutDown() && keyEvent.isShiftDown()) {
tabs.getTabs().clear(); tabs.getTabs().clear();
keyEvent.consume(); keyEvent.consume();
} }
if (keyEvent.getCode().isFunctionKey()) {
var start = KeyCode.F1.getCode();
var index = keyEvent.getCode().getCode() - start;
if (index < tabs.getTabs().size()) {
tabs.getSelectionModel().select(index);
keyEvent.consume();
return;
}
}
var forward = new KeyCodeCombination(KeyCode.TAB, KeyCombination.CONTROL_DOWN);
if (forward.match(keyEvent)) {
var next = (tabs.getSelectionModel().getSelectedIndex() + 1) % tabs.getTabs().size();
tabs.getSelectionModel().select(next);
keyEvent.consume();
return;
}
var back = new KeyCodeCombination(KeyCode.TAB, KeyCombination.CONTROL_DOWN, KeyCombination.SHIFT_DOWN);
if (back.match(keyEvent)) {
var previous = (tabs.getTabs().size() + tabs.getSelectionModel().getSelectedIndex() - 1) % tabs.getTabs().size();
tabs.getSelectionModel().select(previous);
keyEvent.consume();
return;
}
}); });
return tabs; return tabs;

View file

@ -10,13 +10,10 @@ import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.prefs.AppPrefs; import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.scene.control.ButtonBase; import javafx.scene.control.ButtonBase;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.KeyEvent; import javafx.scene.input.KeyEvent;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane; import javafx.scene.layout.Pane;
@ -68,23 +65,6 @@ public class AppLayoutComp extends Comp<CompStructure<Pane>> {
return; return;
} }
}); });
if (event.isConsumed()) {
return;
}
var forward = new KeyCodeCombination(KeyCode.TAB, KeyCombination.CONTROL_DOWN);
if (forward.match(event)) {
var next = (model.getEntries().indexOf(model.getSelected().getValue()) + 1) % 3;
model.getSelected().setValue(model.getEntries().get(next));
return;
}
var back = new KeyCodeCombination(KeyCode.TAB, KeyCombination.CONTROL_DOWN, KeyCombination.SHIFT_DOWN);
if (back.match(event)) {
var next = (model.getEntries().indexOf(model.getSelected().getValue()) + 2) % 3;
model.getSelected().setValue(model.getEntries().get(next));
return;
}
}); });
AppFont.normal(pane); AppFont.normal(pane);
pane.getStyleClass().add("layout"); pane.getStyleClass().add("layout");

View file

@ -0,0 +1,27 @@
package io.xpipe.app.fxcomps.impl;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import javafx.scene.layout.AnchorPane;
import java.util.List;
public class AnchorComp extends Comp<CompStructure<AnchorPane>> {
private final List<Comp<?>> comps;
public AnchorComp(List<Comp<?>> comps) {
this.comps = List.copyOf(comps);
}
@Override
public CompStructure<AnchorPane> createBase() {
var pane = new AnchorPane();
for (var c : comps) {
pane.getChildren().add(c.createRegion());
}
pane.setPickOnBounds(false);
return new SimpleCompStructure<>(pane);
}
}

View file

@ -208,6 +208,20 @@
} }
.browser .tab-header-area .control-buttons-tab {
-fx-opacity: 0;
}
.browser .tab-loading-indicator {
-fx-min-width: 2.5em;
-fx-pref-width: 2.5em;
-fx-max-width: 2.5em;
-fx-min-height: 2.5em;
-fx-pref-height: 2.5em;
-fx-max-height: 2.5em;
-fx-background-color: transparent;
}
.browser .tab-pane.floating > .tab-header-area { .browser .tab-pane.floating > .tab-header-area {
-fx-border-width: 0 0 0.05em 0; -fx-border-width: 0 0 0.05em 0;
-fx-border-color: -color-border-default; -fx-border-color: -color-border-default;

View file

@ -27,7 +27,7 @@ public interface ShellOpenFunction {
@Override @Override
public CommandBuilder prepareWithInitCommand(@NonNull String command) { public CommandBuilder prepareWithInitCommand(@NonNull String command) {
throw new UnsupportedOperationException(); return CommandBuilder.of().add(command);
} }
}; };
} }

View file

@ -48,6 +48,6 @@ public class OpenFileDefaultAction implements LeafAction {
@Override @Override
public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) { public boolean isApplicable(OpenFileSystemModel model, List<BrowserEntry> entries) {
return entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.FILE); return model.getFileList().getEditing().getValue() == null && entries.stream().allMatch(entry -> entry.getRawFileEntry().getKind() == FileKind.FILE);
} }
} }