Skip to content

Commit

Permalink
Various small fixes [release]
Browse files Browse the repository at this point in the history
  • Loading branch information
crschnick committed Feb 26, 2023
1 parent 26a7592 commit 417aa16
Show file tree
Hide file tree
Showing 40 changed files with 393 additions and 230 deletions.
122 changes: 84 additions & 38 deletions app/src/main/java/io/xpipe/app/browser/FileBrowserComp.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
package io.xpipe.app.browser;

import atlantafx.base.controls.RingProgressIndicator;
import atlantafx.base.controls.Spacer;
import atlantafx.base.theme.Styles;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.util.PlatformThread;
import io.xpipe.app.storage.DataStorage;
import io.xpipe.core.store.FileSystem;
import javafx.beans.binding.Bindings;
import javafx.collections.ListChangeListener;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.*;
import javafx.scene.input.DragEvent;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.*;

import java.util.HashMap;

Expand All @@ -26,8 +27,6 @@

public class FileBrowserComp extends SimpleComp {

private static final double TAB_MIN_HEIGHT = 60;

private final FileBrowserModel model;

public FileBrowserComp(FileBrowserModel model) {
Expand All @@ -44,7 +43,40 @@ protected Region createSimple() {
// set sidebar width in pixels depending on split pane width
(obs, old, val) -> splitPane.setDividerPosition(0, 230 / splitPane.getWidth()));

return splitPane;
return addBottomBar(splitPane);
}

private Region addBottomBar(Region r) {
if (model.getMode().equals(FileBrowserModel.Mode.BROWSER)) {
return r;
}

var selectedLabel = new Label("Selected: ");
selectedLabel.setAlignment(Pos.CENTER);
var selected = new HBox();
selected.setAlignment(Pos.CENTER_LEFT);
selected.setSpacing(10);
model.getSelectedFiles().addListener((ListChangeListener<? super FileSystem.FileEntry>) c -> {
selected.getChildren().setAll(c.getList().stream().map(s -> {
var field = new TextField(s.getPath());
field.setEditable(false);
field.setPrefWidth(400);
return field;
}).toList());
});
var spacer = new Spacer(Orientation.HORIZONTAL);
var button = new Button("Select");
button.setOnAction(event -> model.finishChooser());
button.setDefaultButton(true);
var bottomBar = new HBox(selectedLabel, selected, spacer, button);
HBox.setHgrow(selected, Priority.ALWAYS);
bottomBar.setAlignment(Pos.CENTER);
bottomBar.setPadding(new Insets(15));
bottomBar.getStyleClass().add("chooser-bar");

var layout = new VBox(r, bottomBar);
VBox.setVgrow(r, Priority.ALWAYS);
return layout;
}

private Node createTabs() {
Expand All @@ -54,6 +86,15 @@ private Node createTabs() {

var map = new HashMap<OpenFileSystemModel, Tab>();

// Restore state
model.getOpenFileSystems().forEach(v -> {
var t = createTab(tabs, v);
map.put(v, t);
tabs.getTabs().add(t);
});
tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(model.getSelected().getValue()));

// Handle selection from platform
tabs.getSelectionModel().selectedIndexProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.intValue() == -1) {
model.getSelected().setValue(null);
Expand All @@ -63,34 +104,29 @@ private Node createTabs() {
model.getSelected().setValue(model.getOpenFileSystems().get(newValue.intValue()));
});

model.getOpenFileSystems().forEach(v -> {
var t = createTab(tabs, v);
map.put(v, t);
tabs.getTabs().add(t);
});
if (model.getOpenFileSystems().size() > 0) {
tabs.getSelectionModel().select(0);
}

model.getOpenFileSystems().addListener((ListChangeListener<? super OpenFileSystemModel>) c -> {
PlatformThread.runLaterIfNeededBlocking(() -> {
while (c.next()) {
for (var r : c.getRemoved()) {
while (c.next()) {
for (var r : c.getRemoved()) {
PlatformThread.runLaterIfNeeded(() -> {
var t = map.remove(r);
tabs.getTabs().remove(t);
}
});
}

for (var a : c.getAddedSubList()) {
for (var a : c.getAddedSubList()) {
PlatformThread.runLaterIfNeeded(() -> {
var t = createTab(tabs, a);
map.put(a, t);
tabs.getTabs().add(t);
}
});
}
});
}
});

model.getSelected().addListener((observable, oldValue, newValue) -> {
tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(newValue));
PlatformThread.runLaterIfNeeded(() -> {
tabs.getSelectionModel().select(model.getOpenFileSystems().indexOf(newValue));
});
});

tabs.getTabs().addListener((ListChangeListener<? super Tab>) c -> {
Expand All @@ -100,7 +136,13 @@ private Node createTabs() {
.filter(openFileSystemModelTabEntry ->
openFileSystemModelTabEntry.getValue().equals(r))
.findAny()
.orElseThrow();
.orElse(null);

// Only handle close events that are triggered from the platform
if (source == null) {
continue;
}

model.closeFileSystem(source.getKey());
}
}
Expand All @@ -110,22 +152,20 @@ private Node createTabs() {
return stack;
}

private Node createSingular() {
var stack =
new StackPane(new OpenFileSystemComp(model.getOpenFileSystems().get(0)).createSimple());
return stack;
}

private TabPane createTabPane() {
var tabs = new TabPane();
tabs.setTabDragPolicy(TabPane.TabDragPolicy.REORDER);
tabs.setTabClosingPolicy(ALL_TABS);
Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING);
// tabs.setStyle("-fx-open-tab-animation:none;-fx-close-tab-animation:none;");
toggleStyleClass(tabs, DENSE);
tabs.setMinHeight(TAB_MIN_HEIGHT);
tabs.setTabMinWidth(Region.USE_COMPUTED_SIZE);

if (!model.getMode().equals(FileBrowserModel.Mode.BROWSER)) {
tabs.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE);
tabs.getStyleClass().add("singular");
} else {
tabs.setTabClosingPolicy(ALL_TABS);
Styles.toggleStyleClass(tabs, TabPane.STYLE_CLASS_FLOATING);
toggleStyleClass(tabs, DENSE);
}

return tabs;
}

Expand Down Expand Up @@ -180,6 +220,12 @@ public void handle(DragEvent mouseEvent) {
PlatformThread.sync(model.getBusy())));

tab.setGraphic(label);

if (!this.model.getMode().equals(FileBrowserModel.Mode.BROWSER)) {
label.setManaged(false);
label.setVisible(false);
}

tab.setContent(new OpenFileSystemComp(model).createSimple());
return tab;
}
Expand Down
63 changes: 61 additions & 2 deletions app/src/main/java/io/xpipe/app/browser/FileBrowserModel.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,88 @@
package io.xpipe.app.browser;

import io.xpipe.app.util.ThreadHelper;
import io.xpipe.core.impl.FileStore;
import io.xpipe.core.store.FileSystem;
import io.xpipe.core.store.ShellStore;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

@Getter
public class FileBrowserModel {

public static final FileBrowserModel DEFAULT = new FileBrowserModel();
public FileBrowserModel(Mode mode) {
this.mode = mode;
}

public static enum Mode {
BROWSER,
SINGLE_FILE_CHOOSER,
SINGLE_FILE_SAVE,
MULTIPLE_FILE_CHOOSER,
DIRECTORY_CHOOSER
}

public static final FileBrowserModel DEFAULT = new FileBrowserModel(Mode.BROWSER);

private final Mode mode;
private final ObservableList<FileSystem.FileEntry> selectedFiles = FXCollections.observableArrayList();

@Setter
private Consumer<List<FileStore>> onFinish;

private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();

public void finishChooser() {
if (getMode().equals(Mode.BROWSER)) {
throw new IllegalStateException();
}

closeFileSystem(openFileSystems.get(0));

if (selectedFiles.size() == 0) {
return;
}
var stores = selectedFiles.stream().map(entry -> new FileStore(entry.getFileSystem().getStore(), entry.getPath())).toList();
onFinish.accept(stores);
}

public void closeFileSystem(OpenFileSystemModel open) {
ThreadHelper.runAsync(() -> {
if (Objects.equals(selected.getValue(), open)) {
selected.setValue(null);
}
open.closeSync();
openFileSystems.remove(open);
});
}

public void openFileSystem(ShellStore store) {
// Prevent multiple tabs in non browser modes
if (!mode.equals(Mode.BROWSER)) {
ThreadHelper.runAsync(() -> {
var open = openFileSystems.size() > 0 ? openFileSystems.get(0) : null;
if (open != null) {
open.closeSync();
openFileSystems.remove(open);
}

var model = new OpenFileSystemModel(this);
openFileSystems.add(model);
selected.setValue(model);
model.switchAsync(store);
});
return;
}

var found = openFileSystems.stream()
.filter(fileSystemModel -> fileSystemModel.getStore().getValue().equals(store))
.findFirst();
Expand All @@ -32,7 +91,7 @@ public void openFileSystem(ShellStore store) {
return;
}

var model = new OpenFileSystemModel();
var model = new OpenFileSystemModel(this);
openFileSystems.add(model);
selected.setValue(model);
model.switchAsync(store);
Expand Down
11 changes: 11 additions & 0 deletions app/src/main/java/io/xpipe/app/browser/FileContextMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

package io.xpipe.app.browser;

import io.xpipe.app.comp.source.GuiDsCreatorMultiStep;
import io.xpipe.app.ext.DataSourceProvider;
import io.xpipe.app.util.*;
import io.xpipe.core.impl.FileStore;
import io.xpipe.core.process.OsType;
import io.xpipe.core.process.ShellProcessControl;
import io.xpipe.core.store.FileSystem;
Expand Down Expand Up @@ -103,6 +106,14 @@ private void createMenu() {
getItems().add(open);
}

var pipe = new MenuItem("Pipe");
pipe.setOnAction(event -> {
var store = new FileStore(model.getFileSystem().getStore(), entry.getPath());
GuiDsCreatorMultiStep.showForStore(DataSourceProvider.Category.STREAM, store, null);
event.consume();
});
getItems().add(pipe);

var edit = new MenuItem("Edit");
edit.setOnAction(event -> {
FileOpener.openInTextEditor(entry);
Expand Down
14 changes: 12 additions & 2 deletions app/src/main/java/io/xpipe/app/browser/FileListComp.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.xpipe.core.store.FileSystem;
import javafx.beans.property.*;
import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
Expand Down Expand Up @@ -85,10 +86,19 @@ private TableView<FileSystem.FileEntry> createTable() {
table.getColumns().setAll(filenameCol, sizeCol, mtimeCol);
table.getSortOrder().add(filenameCol);
table.setSortPolicy(param -> true);
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
filenameCol.minWidthProperty().bind(table.widthProperty().multiply(0.5));

if (fileList.getMode().equals(FileBrowserModel.Mode.SINGLE_FILE_CHOOSER) || fileList.getMode().equals(FileBrowserModel.Mode.DIRECTORY_CHOOSER)) {
table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
} else {
table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
}

table.getSelectionModel().getSelectedItems().addListener((ListChangeListener<? super FileSystem.FileEntry>) c -> {
fileList.getModel().getBrowserModel().getSelectedFiles().setAll(c.getList());
});

var draggedOverDirectory = new SimpleBooleanProperty();

table.setOnKeyPressed(event -> {
Expand Down Expand Up @@ -127,7 +137,7 @@ private TableView<FileSystem.FileEntry> createTable() {

row.setOnMouseClicked(e -> {
if (e.getClickCount() == 2 && !row.isEmpty()) {
fileList.onClick(row.getItem());
fileList.onDoubleClick(row.getItem());
}
});

Expand Down
11 changes: 10 additions & 1 deletion app/src/main/java/io/xpipe/app/browser/FileListModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public FileListModel(OpenFileSystemModel model) {
});
}

public FileBrowserModel.Mode getMode() {
return model.getBrowserModel().getMode();
}

public void setAll(List<FileSystem.FileEntry> newFiles) {
all.setValue(newFiles);
refreshShown();
Expand Down Expand Up @@ -80,7 +84,12 @@ public boolean rename(String filename, String newName) {
}
}

public void onClick(FileSystem.FileEntry entry) {
public void onDoubleClick(FileSystem.FileEntry entry) {
if (!entry.isDirectory() && getMode().equals(FileBrowserModel.Mode.SINGLE_FILE_CHOOSER)) {
getModel().getBrowserModel().finishChooser();
return;
}

if (entry.isDirectory()) {
model.navigate(entry.getPath(), true);
} else {
Expand Down
Loading

0 comments on commit 417aa16

Please sign in to comment.