Add browser quick access

This commit is contained in:
crschnick 2024-03-26 13:53:51 +00:00
parent 7784757393
commit 07472cad9a
4 changed files with 148 additions and 16 deletions

View file

@ -1,5 +1,6 @@
package io.xpipe.app.browser;
import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.action.BrowserAction;
import io.xpipe.app.browser.icon.FileIconManager;
@ -36,7 +37,6 @@ import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import java.time.Instant;
import java.time.ZoneId;
@ -485,8 +485,6 @@ final class BrowserFileListComp extends SimpleComp {
private final StringProperty img = new SimpleStringProperty();
private final StringProperty text = new SimpleStringProperty();
private final StackPane textField =
new LazyTextFieldComp(text).createStructure().get();
private final BooleanProperty updating = new SimpleBooleanProperty();
@ -499,6 +497,17 @@ final class BrowserFileListComp extends SimpleComp {
itemProperty()));
setAccessibleRole(AccessibleRole.TEXT);
var textField = new LazyTextFieldComp(text).minWidth(USE_PREF_SIZE).createStructure().get();
var quickAccess = new BrowserQuickAccessButtonComp(() -> getTableRow().getItem().getRawFileEntry(), fileList.getFileSystemModel(), fileEntry -> {})
.hide(Bindings.createBooleanBinding(() -> {
var notDir = getTableRow().getItem().getRawFileEntry().getKind() != FileKind.DIRECTORY;
var isParentLink = getTableRow()
.getItem()
.getRawFileEntry()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory());
return notDir || isParentLink;
}, itemProperty())).createRegion();
editing.addListener((observable, oldValue, newValue) -> {
if (getTableRow().getItem() != null && getTableRow().getItem().equals(newValue)) {
PlatformThread.runLaterIfNeeded(() -> textField.requestFocus());
@ -518,10 +527,13 @@ final class BrowserFileListComp extends SimpleComp {
text.addListener(listener);
Node imageView = new PrettySvgComp(img, 24, 24).createRegion();
HBox graphic = new HBox(imageView, textField);
graphic.setSpacing(10);
graphic.setAlignment(Pos.CENTER_LEFT);
HBox graphic = new HBox(imageView,
new Spacer(7),
quickAccess,
new Spacer(3),
textField);
HBox.setHgrow(textField, Priority.ALWAYS);
graphic.setAlignment(Pos.CENTER_LEFT);
setGraphic(graphic);
}

View file

@ -72,7 +72,7 @@ public class BrowserOverviewComp extends SimpleComp {
var recentOverview = new BrowserFileOverviewComp(model, recent, true);
var recentPane = new SimpleTitledPaneComp(AppI18n.observable("recent"), recentOverview);
var vbox = new VerticalComp(List.of(commonPane, rootsPane, recentPane)).styleClass("overview");
var vbox = new VerticalComp(List.of(recentPane, commonPane, rootsPane)).styleClass("overview");
return vbox.createRegion();
}
}

View file

@ -0,0 +1,129 @@
package io.xpipe.app.browser;
import io.xpipe.app.browser.icon.FileIconManager;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.IconButtonComp;
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.store.FileKind;
import io.xpipe.core.store.FileSystem;
import javafx.application.Platform;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.Region;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Supplier;
public class BrowserQuickAccessButtonComp extends SimpleComp {
private final Supplier<FileSystem.FileEntry> base;
private final OpenFileSystemModel model;
private final Consumer<FileSystem.FileEntry> action;
public BrowserQuickAccessButtonComp(Supplier<FileSystem.FileEntry> base, OpenFileSystemModel model, Consumer<FileSystem.FileEntry> action) {
this.base = base;
this.model = model;
this.action = action;
}
@Override
protected Region createSimple() {
var button = new IconButtonComp("mdi2c-chevron-double-right");
button.apply(struc -> {
struc.get().setOnAction(event -> {
showMenu(struc.get());
});
});
return button.createRegion();
}
private void showMenu(Node anchor) {
ThreadHelper.runFailableAsync(() -> {
var children = model.getFileSystem().listFiles(base.get().getPath());
try (var s = children) {
var list = s.toList();
if (list.isEmpty()) {
return;
}
Platform.runLater(() -> {
var cm = new ContextMenu();
cm.addEventHandler(Menu.ON_SHOWING, e -> {
Node content = cm.getSkin().getNode();
if (content instanceof Region r) {
r.setMaxWidth(500);
r.setMaxHeight(600);
}
});
cm.setAutoHide(true);
cm.getStyleClass().add("condensed");
cm.getItems().addAll(list.stream().map(e -> recurse(cm, e)).toList());
cm.show(anchor, Side.RIGHT, 0, 0);
});
}
});
}
private MenuItem recurse(ContextMenu contextMenu, FileSystem.FileEntry fileEntry) {
if (fileEntry.getKind() != FileKind.DIRECTORY) {
var m = new MenuItem(
fileEntry.getName(),
PrettyImageHelper.ofFixedSquare(FileIconManager.getFileIcon(fileEntry,false), 16).createRegion());
m.setMnemonicParsing(false);
m.setOnAction(event -> {
action.accept(fileEntry);
event.consume();
});
return m;
}
var m = new Menu(
fileEntry.getName(),
PrettyImageHelper.ofFixedSquare(FileIconManager.getFileIcon(fileEntry,false), 16).createRegion());
m.setMnemonicParsing(false);
m.setOnAction(event -> {
if (event.getTarget() == m) {
if (m.isShowing()) {
event.consume();
return;
}
ThreadHelper.runFailableAsync(() -> {
updateMenuItems(m, fileEntry);
});
action.accept(fileEntry);
event.consume();
}
});
return m;
}
private void updateMenuItems(Menu m, FileSystem.FileEntry fileEntry) throws Exception {
var newFiles = model.getFileSystem().listFiles(fileEntry.getPath());
try (var s = newFiles) {
var list = s.toList();
var newItems = new ArrayList<MenuItem>();
if (list.isEmpty()) {
newItems.add(new MenuItem("<empty>"));
} else if (list.size() == 1 && list.getFirst().getKind() == FileKind.DIRECTORY) {
var subMenu = recurse(m.getParentPopup(),list.getFirst());
updateMenuItems(m, list.getFirst());
newItems.add(subMenu);
} else {
newItems.addAll(list.stream().map(e -> recurse(m.getParentPopup(), e)).toList());
}
Platform.runLater(() -> {
m.getItems().setAll(newItems);
m.hide();
m.show();
});
}
}
}

View file

@ -41,15 +41,6 @@ public class StoreQuickAccessButtonComp extends SimpleComp {
}
cm.show(anchor, Side.RIGHT, 0, 0);
// App.getApp().getStage().getScene().addEventFilter(MouseEvent.MOUSE_MOVED, event -> {
// var stages = Stage.getWindows().stream().filter(window -> window instanceof ContextMenu).toList();
// var hovered = stages.stream().anyMatch(window ->
// window.getScene().getRoot().hoverProperty().get());
// if (!hovered) {
// stages.forEach(window -> window.hide());
// }
// });
}
private ContextMenu createMenu() {