Small browser fixes [release]

This commit is contained in:
crschnick 2023-03-20 13:49:28 +00:00
parent 4bb7627488
commit 1f9d5ab2e6
6 changed files with 64 additions and 23 deletions

View file

@ -17,10 +17,14 @@ import javafx.beans.property.*;
import javafx.beans.value.ChangeListener; import javafx.beans.value.ChangeListener;
import javafx.collections.ListChangeListener; import javafx.collections.ListChangeListener;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;
import javafx.geometry.Bounds;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.control.skin.TableViewSkin;
import javafx.scene.control.skin.VirtualFlow;
import javafx.scene.input.DragEvent;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*; import javafx.scene.layout.*;
@ -29,6 +33,7 @@ import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.Comparator;
import java.util.Objects;
import static io.xpipe.app.util.HumanReadableFormat.byteCount; import static io.xpipe.app.util.HumanReadableFormat.byteCount;
import static javafx.scene.control.TableColumn.SortType.ASCENDING; import static javafx.scene.control.TableColumn.SortType.ASCENDING;
@ -125,7 +130,7 @@ final class FileListComp extends AnchorPane {
} }
}); });
var emptyEntry = new FileListEntry(table, null, fileList); var emptyEntry = new FileListCompEntry(table, null, fileList);
table.setOnDragOver(event -> { table.setOnDragOver(event -> {
emptyEntry.onDragOver(event); emptyEntry.onDragOver(event);
}); });
@ -145,7 +150,7 @@ final class FileListComp extends AnchorPane {
table.setRowFactory(param -> { table.setRowFactory(param -> {
TableRow<FileSystem.FileEntry> row = new TableRow<>(); TableRow<FileSystem.FileEntry> row = new TableRow<>();
var listEntry = Bindings.createObjectBinding( var listEntry = Bindings.createObjectBinding(
() -> new FileListEntry(row, row.getItem(), fileList), row.itemProperty()); () -> new FileListCompEntry(row, row.getItem(), fileList), row.itemProperty());
row.selectedProperty().addListener((observable, oldValue, newValue) -> { row.selectedProperty().addListener((observable, oldValue, newValue) -> {
if (newValue && listEntry.get().isSynthetic()) { if (newValue && listEntry.get().isSynthetic()) {
@ -180,6 +185,7 @@ final class FileListComp extends AnchorPane {
listEntry.get().onDragEntered(event); listEntry.get().onDragEntered(event);
}); });
row.setOnDragOver(event -> { row.setOnDragOver(event -> {
borderScroll(table, event);
listEntry.get().onDragOver(event); listEntry.get().onDragOver(event);
}); });
row.setOnDragDetected(event -> { row.setOnDragDetected(event -> {
@ -195,6 +201,7 @@ final class FileListComp extends AnchorPane {
return row; return row;
}); });
var lastDir = new SimpleObjectProperty<FileSystem.FileEntry>();
SimpleChangeListener.apply(fileList.getShown(), (newValue) -> { SimpleChangeListener.apply(fileList.getShown(), (newValue) -> {
PlatformThread.runLaterIfNeeded(() -> { PlatformThread.runLaterIfNeeded(() -> {
var newItems = new ArrayList<FileSystem.FileEntry>(); var newItems = new ArrayList<FileSystem.FileEntry>();
@ -204,16 +211,36 @@ final class FileListComp extends AnchorPane {
} }
newItems.addAll(newValue); newItems.addAll(newValue);
table.getItems().setAll(newItems); table.getItems().setAll(newItems);
// if (newValue.size() > 0) {
// table.scrollTo(0); var currentDirectory = fileList.getFileSystemModel().getCurrentDirectory();
// } if (!Objects.equals(lastDir.get(), currentDirectory)) {
table.scrollTo(0);
}
lastDir.setValue(currentDirectory);
}); });
}); });
return table; return table;
} }
/////////////////////////////////////////////////////////////////////////// private void borderScroll(TableView<?> tableView, DragEvent event) {
TableViewSkin<?> skin = (TableViewSkin<?>) tableView.getSkin();
VirtualFlow<?> flow = (VirtualFlow<?>) skin.getChildren().get(1);
ScrollBar vbar = (ScrollBar) flow.getChildrenUnmodifiable().get(2);
double proximity = 100;
Bounds tableBounds = tableView.localToScene(tableView.getBoundsInParent());
double dragY = event.getSceneY();
double topYProximity = tableBounds.getMinY() + proximity;
double bottomYProximity = tableBounds.getMaxY() - proximity;
if (dragY < topYProximity) {
var scrollValue = Math.min(topYProximity - dragY, 100) / 10000.0;
vbar.setValue(vbar.getValue() - scrollValue);
} else if (dragY > bottomYProximity) {
var scrollValue = Math.min(dragY - bottomYProximity, 100) / 10000.0;
vbar.setValue(vbar.getValue() + scrollValue);
}
}
private class FilenameCell extends TableCell<FileSystem.FileEntry, String> { private class FilenameCell extends TableCell<FileSystem.FileEntry, String> {
@ -265,7 +292,11 @@ final class FileListComp extends AnchorPane {
pseudoClassStateChanged(FOLDER, isDirectory); pseudoClassStateChanged(FOLDER, isDirectory);
var fileName = getTableRow().getItem().equals(fileList.getFileSystemModel().getCurrentParentDirectory()) ? ".." : FileNames.getFileName(fullPath); var fileName = getTableRow()
.getItem()
.equals(fileList.getFileSystemModel().getCurrentParentDirectory())
? ".."
: FileNames.getFileName(fullPath);
var hidden = getTableRow().getItem().isHidden() || fileName.startsWith("."); var hidden = getTableRow().getItem().isHidden() || fileName.startsWith(".");
getTableRow().pseudoClassStateChanged(HIDDEN, hidden); getTableRow().pseudoClassStateChanged(HIDDEN, hidden);
text.set(fileName); text.set(fileName);

View file

@ -13,7 +13,7 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@Getter @Getter
public class FileListEntry { public class FileListCompEntry {
public static final Timer DROP_TIMER = new Timer("dnd", true); public static final Timer DROP_TIMER = new Timer("dnd", true);
@ -24,7 +24,7 @@ public class FileListEntry {
private Point2D lastOver = new Point2D(-1, -1); private Point2D lastOver = new Point2D(-1, -1);
private TimerTask activeTask; private TimerTask activeTask;
public FileListEntry(Node row, FileSystem.FileEntry item, FileListModel model) { public FileListCompEntry(Node row, FileSystem.FileEntry item, FileListModel model) {
this.row = row; this.row = row;
this.item = item; this.item = item;
this.model = model; this.model = model;
@ -47,6 +47,11 @@ public class FileListEntry {
} }
private boolean acceptsDrop(DragEvent event) { private boolean acceptsDrop(DragEvent event) {
// Accept drops from outside the app window
if (event.getGestureSource() == null) {
return true;
}
if (FileBrowserClipboard.currentDragClipboard == null) { if (FileBrowserClipboard.currentDragClipboard == null) {
return false; return false;
} }

View file

@ -7,11 +7,9 @@ import io.xpipe.app.core.mode.OperationMode;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.issue.ErrorEvent; import io.xpipe.app.issue.ErrorEvent;
import io.xpipe.app.issue.UserReportComp; import io.xpipe.app.issue.UserReportComp;
import io.xpipe.app.util.DesktopHelper; import io.xpipe.app.util.*;
import io.xpipe.app.util.DynamicOptionsBuilder;
import io.xpipe.app.util.FileOpener;
import io.xpipe.app.util.ScriptHelper;
import io.xpipe.core.impl.FileNames; import io.xpipe.core.impl.FileNames;
import io.xpipe.core.process.OsType;
import io.xpipe.core.store.ShellStore; import io.xpipe.core.store.ShellStore;
import io.xpipe.core.util.XPipeInstallation; import io.xpipe.core.util.XPipeInstallation;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
@ -35,9 +33,9 @@ public class BrowseDirectoryComp extends SimpleComp {
"logFile", "logFile",
new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> { new ButtonComp(AppI18n.observable("openCurrentLogFile"), () -> {
FileOpener.openInTextEditor(AppLogs.get() FileOpener.openInTextEditor(AppLogs.get()
.getSessionLogsDirectory() .getSessionLogsDirectory()
.resolve("xpipe.log") .resolve("xpipe.log")
.toString()); .toString());
}), }),
null) null)
.addComp( .addComp(
@ -45,8 +43,15 @@ public class BrowseDirectoryComp extends SimpleComp {
new ButtonComp(AppI18n.observable("launchDebugMode"), () -> { new ButtonComp(AppI18n.observable("launchDebugMode"), () -> {
OperationMode.executeAfterShutdown(() -> { OperationMode.executeAfterShutdown(() -> {
try (var sc = ShellStore.createLocal().create().start()) { try (var sc = ShellStore.createLocal().create().start()) {
var script = FileNames.join(XPipeInstallation.getCurrentInstallationBasePath().toString(), XPipeInstallation.getDaemonDebugScriptPath(sc.getOsType())); var script = FileNames.join(
sc.executeSimpleCommand(ScriptHelper.createDetachCommand(sc, script)); XPipeInstallation.getCurrentInstallationBasePath()
.toString(),
XPipeInstallation.getDaemonDebugScriptPath(sc.getOsType()));
if (sc.getOsType().equals(OsType.WINDOWS)) {
sc.executeSimpleCommand(ScriptHelper.createDetachCommand(sc, "\"" + script + "\""));
} else {
TerminalHelper.open("X-Pipe Debug", "\"" + script + "\"");
}
} }
}); });
DesktopHelper.browsePath(AppLogs.get().getSessionLogsDirectory()); DesktopHelper.browsePath(AppLogs.get().getSessionLogsDirectory());

View file

@ -9,7 +9,7 @@ import java.util.stream.Stream;
public abstract class TestModule<V> { public abstract class TestModule<V> {
private static final Map<Class<?>, Map<String, ?>> values = new HashMap<>(); private static final Map<Class<?>, Map<String, ?>> values = new LinkedHashMap<>();
@SuppressWarnings({"unchecked"}) @SuppressWarnings({"unchecked"})
public static <T> Map<String, T> get(Class<T> c, String... classes) { public static <T> Map<String, T> get(Class<T> c, String... classes) {

View file

@ -71,7 +71,7 @@ public class ConnectionFileSystem implements FileSystem {
@Override @Override
public boolean exists(String file) throws Exception { public boolean exists(String file) throws Exception {
try (var pc = shellControl.command(proc -> proc.getShellDialect() try (var pc = shellControl.command(proc -> proc.getShellDialect()
.getFileExistsCommand(proc.getOsType().normalizeFileName(file))) .getFileExistsCommand(proc.getOsType().normalizeFileName(file))).complex()
.start()) { .start()) {
return pc.discardAndCheckExit(); return pc.discardAndCheckExit();
} }
@ -80,7 +80,7 @@ public class ConnectionFileSystem implements FileSystem {
@Override @Override
public void delete(String file) throws Exception { public void delete(String file) throws Exception {
try (var pc = shellControl.command(proc -> proc.getShellDialect() try (var pc = shellControl.command(proc -> proc.getShellDialect()
.getFileDeleteCommand(proc.getOsType().normalizeFileName(file))) .getFileDeleteCommand(proc.getOsType().normalizeFileName(file))).complex()
.start()) { .start()) {
pc.discardOrThrow(); pc.discardOrThrow();
} }
@ -107,7 +107,7 @@ public class ConnectionFileSystem implements FileSystem {
@Override @Override
public boolean mkdirs(String file) throws Exception { public boolean mkdirs(String file) throws Exception {
try (var pc = shellControl.command(proc -> proc.getShellDialect() try (var pc = shellControl.command(proc -> proc.getShellDialect()
.getMkdirsCommand(proc.getOsType().normalizeFileName(file))) .getMkdirsCommand(proc.getOsType().normalizeFileName(file))).complex()
.start()) { .start()) {
return pc.discardAndCheckExit(); return pc.discardAndCheckExit();
} }

View file

@ -1 +1 @@
0.5.15 0.5.16