mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Add browser quick access
This commit is contained in:
parent
7784757393
commit
07472cad9a
4 changed files with 148 additions and 16 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue