mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-09-19 02:39:01 +12:00
Improve browser navigation bar
This commit is contained in:
parent
441226855f
commit
0eea4f3e3f
5 changed files with 85 additions and 15 deletions
50
app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java
Normal file
50
app/src/main/java/io/xpipe/app/browser/BrowserNavBar.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
|
import io.xpipe.app.fxcomps.impl.TextFieldComp;
|
||||||
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
import javafx.css.PseudoClass;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Priority;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
import javafx.scene.layout.StackPane;
|
||||||
|
|
||||||
|
public class BrowserNavBar extends SimpleComp {
|
||||||
|
|
||||||
|
private static final PseudoClass INVISIBLE = PseudoClass.getPseudoClass("invisible");
|
||||||
|
|
||||||
|
private final OpenFileSystemModel model;
|
||||||
|
|
||||||
|
public BrowserNavBar(OpenFileSystemModel model) {
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Region createSimple() {
|
||||||
|
var path = new SimpleStringProperty(model.getCurrentPath().get());
|
||||||
|
path.addListener((observable, oldValue, newValue) -> {
|
||||||
|
var changed = model.cd(newValue);
|
||||||
|
changed.ifPresent(path::set);
|
||||||
|
});
|
||||||
|
var pathBar = new TextFieldComp(path, true).createRegion();
|
||||||
|
pathBar.getStyleClass().add("path-text");
|
||||||
|
model.getCurrentPath().addListener((observable, oldValue, newValue) -> {
|
||||||
|
path.set(newValue);
|
||||||
|
});
|
||||||
|
SimpleChangeListener.apply(pathBar.focusedProperty(), val -> {
|
||||||
|
pathBar.pseudoClassStateChanged(INVISIBLE, !val);
|
||||||
|
});
|
||||||
|
|
||||||
|
var breadcrumbs = new FileBrowserBreadcrumbBar(model)
|
||||||
|
.hide(pathBar.focusedProperty())
|
||||||
|
.createRegion();
|
||||||
|
|
||||||
|
var stack = new StackPane(pathBar, breadcrumbs);
|
||||||
|
HBox.setHgrow(stack, Priority.ALWAYS);
|
||||||
|
stack.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import atlantafx.base.controls.Breadcrumbs;
|
import atlantafx.base.controls.Breadcrumbs;
|
||||||
import atlantafx.base.theme.Styles;
|
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
|
@ -9,6 +8,7 @@ import io.xpipe.core.impl.FileNames;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ButtonBase;
|
import javafx.scene.control.ButtonBase;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@ public class FileBrowserBreadcrumbBar extends SimpleComp {
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
Callback<Breadcrumbs.BreadCrumbItem<String>, ButtonBase> crumbFactory = crumb -> {
|
Callback<Breadcrumbs.BreadCrumbItem<String>, ButtonBase> crumbFactory = crumb -> {
|
||||||
var btn = new Button(FileNames.getFileName(crumb.getValue()), null);
|
var btn = new Button(FileNames.getFileName(crumb.getValue()), null);
|
||||||
btn.getStyleClass().add(Styles.FLAT);
|
|
||||||
btn.setFocusTraversable(false);
|
btn.setFocusTraversable(false);
|
||||||
return btn;
|
return btn;
|
||||||
};
|
};
|
||||||
|
@ -42,6 +41,13 @@ public class FileBrowserBreadcrumbBar extends SimpleComp {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sc = model.getFileSystem().getShell();
|
||||||
|
if (sc.isEmpty()) {
|
||||||
|
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label("/") : null);
|
||||||
|
} else {
|
||||||
|
breadcrumbs.setDividerFactory(item -> item != null && !item.isLast() ? new Label(sc.get().getOsType().getFileSystemSeparator()) : null);
|
||||||
|
}
|
||||||
|
|
||||||
var elements = FileNames.splitHierarchy(val);
|
var elements = FileNames.splitHierarchy(val);
|
||||||
Breadcrumbs.BreadCrumbItem<String> items = Breadcrumbs.buildTreeModel(elements.toArray(String[]::new));
|
Breadcrumbs.BreadCrumbItem<String> items = Breadcrumbs.buildTreeModel(elements.toArray(String[]::new));
|
||||||
breadcrumbs.setSelectedCrumb(items);
|
breadcrumbs.setSelectedCrumb(items);
|
||||||
|
|
|
@ -54,17 +54,6 @@ public class OpenFileSystemComp extends SimpleComp {
|
||||||
forthBtn.setOnAction(e -> model.forth());
|
forthBtn.setOnAction(e -> model.forth());
|
||||||
forthBtn.disableProperty().bind(model.getHistory().canGoForthProperty().not());
|
forthBtn.disableProperty().bind(model.getHistory().canGoForthProperty().not());
|
||||||
|
|
||||||
var path = new SimpleStringProperty(model.getCurrentPath().get());
|
|
||||||
var pathBar = new TextFieldComp(path, true).createRegion();
|
|
||||||
path.addListener((observable, oldValue, newValue) -> {
|
|
||||||
var changed = model.cd(newValue);
|
|
||||||
changed.ifPresent(path::set);
|
|
||||||
});
|
|
||||||
model.getCurrentPath().addListener((observable, oldValue, newValue) -> {
|
|
||||||
path.set(newValue);
|
|
||||||
});
|
|
||||||
HBox.setHgrow(pathBar, Priority.ALWAYS);
|
|
||||||
|
|
||||||
var refreshBtn = new Button(null, new FontIcon("mdmz-refresh"));
|
var refreshBtn = new Button(null, new FontIcon("mdmz-refresh"));
|
||||||
refreshBtn.setOnAction(e -> model.refresh());
|
refreshBtn.setOnAction(e -> model.refresh());
|
||||||
Shortcuts.addShortcut(refreshBtn, new KeyCodeCombination(KeyCode.F5));
|
Shortcuts.addShortcut(refreshBtn, new KeyCodeCombination(KeyCode.F5));
|
||||||
|
@ -86,7 +75,7 @@ public class OpenFileSystemComp extends SimpleComp {
|
||||||
|
|
||||||
var topBar = new ToolBar();
|
var topBar = new ToolBar();
|
||||||
topBar.getItems()
|
topBar.getItems()
|
||||||
.setAll(backBtn, forthBtn, new Spacer(10), new FileBrowserBreadcrumbBar(model).createRegion(), filter.get(), refreshBtn, terminalBtn, addBtn);
|
.setAll(backBtn, forthBtn, new Spacer(10), new BrowserNavBar(model).createRegion(), filter.get(), refreshBtn, terminalBtn, addBtn);
|
||||||
|
|
||||||
// ~
|
// ~
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser .breadcrumbs .button {
|
.browser .breadcrumbs .button {
|
||||||
-fx-padding: 0;
|
-fx-padding: 3px 1px 3px 1px;
|
||||||
|
-fx-background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.browser .breadcrumbs .button:hover {
|
||||||
|
-fx-background-color: -color-neutral-muted;
|
||||||
|
}
|
||||||
|
.browser .path-text:invisible {
|
||||||
|
-fx-text-fill: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.browser .context-menu .accelerator-text {
|
.browser .context-menu .accelerator-text {
|
||||||
|
|
|
@ -25,6 +25,8 @@ public sealed interface OsType permits OsType.Windows, OsType.Linux, OsType.MacO
|
||||||
|
|
||||||
String getHomeDirectory(ShellControl pc) throws Exception;
|
String getHomeDirectory(ShellControl pc) throws Exception;
|
||||||
|
|
||||||
|
String getFileSystemSeparator();
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
String getTempDirectory(ShellControl pc) throws Exception;
|
String getTempDirectory(ShellControl pc) throws Exception;
|
||||||
|
@ -41,6 +43,11 @@ public sealed interface OsType permits OsType.Windows, OsType.Linux, OsType.MacO
|
||||||
pc.getShellDialect().getPrintEnvironmentVariableCommand("USERPROFILE"));
|
pc.getShellDialect().getPrintEnvironmentVariableCommand("USERPROFILE"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileSystemSeparator() {
|
||||||
|
return "\\";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Windows";
|
return "Windows";
|
||||||
|
@ -87,6 +94,11 @@ public sealed interface OsType permits OsType.Windows, OsType.Linux, OsType.MacO
|
||||||
return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME"));
|
return pc.executeSimpleStringCommand(pc.getShellDialect().getPrintEnvironmentVariableCommand("HOME"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileSystemSeparator() {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTempDirectory(ShellControl pc) throws Exception {
|
public String getTempDirectory(ShellControl pc) throws Exception {
|
||||||
return "/tmp/";
|
return "/tmp/";
|
||||||
|
@ -157,6 +169,11 @@ public sealed interface OsType permits OsType.Windows, OsType.Linux, OsType.MacO
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFileSystemSeparator() {
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Mac";
|
return "Mac";
|
||||||
|
|
Loading…
Reference in a new issue