From 1d52d3bdc39fa768ef8d2f210f92a791dae24c16 Mon Sep 17 00:00:00 2001 From: crschnick Date: Tue, 24 Dec 2024 17:15:11 +0000 Subject: [PATCH] Rework --- .../xpipe/app/comp/base/InputGroupComp.java | 33 +++++++++++++++++++ .../xpipe/app/comp/base/TileButtonComp.java | 16 ++++++++- .../io/xpipe/app/core/check/AppPtbCheck.java | 3 +- .../io/xpipe/app/core/mode/OperationMode.java | 14 +++++--- .../io/xpipe/app/core/window/AppDialog.java | 30 +++++++++++++++++ .../app/core/window/AppWindowHelper.java | 11 ------- .../app/prefs/ExternalApplicationType.java | 2 +- lang/app/strings/translations_en.properties | 2 ++ 8 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java diff --git a/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java b/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java new file mode 100644 index 000000000..135f0d36b --- /dev/null +++ b/app/src/main/java/io/xpipe/app/comp/base/InputGroupComp.java @@ -0,0 +1,33 @@ +package io.xpipe.app.comp.base; + +import atlantafx.base.layout.InputGroup; +import io.xpipe.app.comp.Comp; +import io.xpipe.app.comp.CompStructure; +import io.xpipe.app.comp.SimpleCompStructure; +import javafx.geometry.Pos; + +import java.util.List; + +public class InputGroupComp extends Comp> { + + private final List> entries; + + public InputGroupComp(List> comps) { + entries = List.copyOf(comps); + } + + public Comp> spacing(double spacing) { + return apply(struc -> struc.get().setSpacing(spacing)); + } + + @Override + public CompStructure createBase() { + InputGroup b = new InputGroup(); + b.getStyleClass().add("input-group-comp"); + for (var entry : entries) { + b.getChildren().add(entry.createRegion()); + } + b.setAlignment(Pos.CENTER); + return new SimpleCompStructure<>(b); + } +} diff --git a/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java b/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java index d1457e267..fc876d0b4 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/TileButtonComp.java @@ -1,5 +1,6 @@ package io.xpipe.app.comp.base; +import atlantafx.base.controls.Spacer; import io.xpipe.app.comp.Comp; import io.xpipe.app.comp.CompStructure; import io.xpipe.app.core.AppFont; @@ -13,6 +14,7 @@ import javafx.event.ActionEvent; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.HBox; +import javafx.scene.layout.Region; import javafx.scene.layout.VBox; import lombok.*; @@ -31,6 +33,9 @@ public class TileButtonComp extends Comp { @Setter private double iconSize = 0.55; + @Setter + private Comp right; + public TileButtonComp(String nameKey, String descriptionKey, String icon, Consumer action) { this.name = AppI18n.observable(nameKey); this.description = AppI18n.observable(descriptionKey); @@ -54,7 +59,9 @@ public class TileButtonComp extends Comp { var bt = new Button(); bt.getStyleClass().add("tile-button-comp"); bt.setOnAction(e -> { - action.accept(e); + if (action != null) { + action.accept(e); + } }); var header = new Label(); @@ -69,6 +76,11 @@ public class TileButtonComp extends Comp { var fi = new FontIconComp(icon).createStructure(); var pane = fi.getPane(); var hbox = new HBox(pane, text); + Region rightRegion = right != null ? right.createRegion() : null; + if (rightRegion != null) { + hbox.getChildren().add(new Spacer()); + hbox.getChildren().add(rightRegion); + } hbox.setSpacing(8); pane.prefWidthProperty() .bind(Bindings.createDoubleBinding( @@ -91,6 +103,7 @@ public class TileButtonComp extends Comp { .content(hbox) .name(header) .description(desc) + .right(rightRegion) .build(); } @@ -102,6 +115,7 @@ public class TileButtonComp extends Comp { FontIcon graphic; Label name; Label description; + Region right; @Override public Button get() { diff --git a/app/src/main/java/io/xpipe/app/core/check/AppPtbCheck.java b/app/src/main/java/io/xpipe/app/core/check/AppPtbCheck.java index fa285cebb..78ba291ac 100644 --- a/app/src/main/java/io/xpipe/app/core/check/AppPtbCheck.java +++ b/app/src/main/java/io/xpipe/app/core/check/AppPtbCheck.java @@ -17,12 +17,11 @@ public class AppPtbCheck { return; } - var content = AppWindowHelper.dialogText("You are running a PTB build of XPipe." + var content = AppDialog.dialogText("You are running a PTB build of XPipe." + " This version is unstable and might contain bugs." + " You should not use it as a daily driver." + " It will also not receive regular updates after its testing period." + " You will have to install and launch the normal XPipe release for that."); - ; var modal = ModalOverlay.of("ptbNotice", content); modal.persist(); modal.addButton(ModalButton.ok()); diff --git a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java index 44983179b..752b116d0 100644 --- a/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java +++ b/app/src/main/java/io/xpipe/app/core/mode/OperationMode.java @@ -226,13 +226,17 @@ public abstract class OperationMode { return ALL; } + public static void startNewInstance() throws Exception { + var loc = AppProperties.get().isDevelopmentEnvironment() + ? XPipeInstallation.getLocalDefaultInstallationBasePath() + : XPipeInstallation.getCurrentInstallationBasePath().toString(); + var exec = XPipeInstallation.createExternalAsyncLaunchCommand(loc, XPipeDaemonMode.GUI, "", true); + LocalShell.getShell().executeSimpleCommand(exec); + } + public static void restart() { OperationMode.executeAfterShutdown(() -> { - var loc = AppProperties.get().isDevelopmentEnvironment() - ? XPipeInstallation.getLocalDefaultInstallationBasePath() - : XPipeInstallation.getCurrentInstallationBasePath().toString(); - var exec = XPipeInstallation.createExternalAsyncLaunchCommand(loc, XPipeDaemonMode.GUI, "", true); - LocalShell.getShell().executeSimpleCommand(exec); + startNewInstance(); }); } diff --git a/app/src/main/java/io/xpipe/app/core/window/AppDialog.java b/app/src/main/java/io/xpipe/app/core/window/AppDialog.java index 7e260e06a..64ada447e 100644 --- a/app/src/main/java/io/xpipe/app/core/window/AppDialog.java +++ b/app/src/main/java/io/xpipe/app/core/window/AppDialog.java @@ -1,6 +1,11 @@ package io.xpipe.app.core.window; +import atlantafx.base.layout.ModalBox; +import io.xpipe.app.comp.Comp; +import io.xpipe.app.comp.base.ModalButton; import io.xpipe.app.comp.base.ModalOverlay; +import io.xpipe.app.core.AppFont; +import io.xpipe.app.core.AppI18n; import io.xpipe.app.util.PlatformInit; import io.xpipe.app.util.PlatformThread; import io.xpipe.app.util.ThreadHelper; @@ -9,10 +14,14 @@ import javafx.animation.PauseTransition; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.layout.StackPane; +import javafx.scene.text.Text; import javafx.util.Duration; import lombok.Getter; +import java.util.concurrent.atomic.AtomicBoolean; + public class AppDialog { @Getter @@ -63,4 +72,25 @@ public class AppDialog { waitForClose(); } } + + public static Comp dialogText(String s) { + return Comp.of(() -> { + var text = new Text(s); + text.setWrappingWidth(450); + AppFont.medium(text); + var sp = new StackPane(text); + return sp; + }) + .prefWidth(450); + } + + public static boolean confirm(String translationKey) { + var confirmed = new AtomicBoolean(false); + var content = dialogText(AppI18n.get(translationKey + "Content")); + var modal = ModalOverlay.of(translationKey + "Title", content); + modal.addButton(ModalButton.cancel()); + modal.addButton(ModalButton.ok(() -> confirmed.set(true))); + showAndWait(modal); + return confirmed.get(); + } } diff --git a/app/src/main/java/io/xpipe/app/core/window/AppWindowHelper.java b/app/src/main/java/io/xpipe/app/core/window/AppWindowHelper.java index 03048edc5..2dc6cb305 100644 --- a/app/src/main/java/io/xpipe/app/core/window/AppWindowHelper.java +++ b/app/src/main/java/io/xpipe/app/core/window/AppWindowHelper.java @@ -47,17 +47,6 @@ public class AppWindowHelper { return alertContentText(s, 450); } - public static Comp dialogText(String s) { - return Comp.of(() -> { - var text = new Text(s); - text.setWrappingWidth(450); - AppFont.medium(text); - var sp = new StackPane(text); - return sp; - }) - .prefWidth(450); - } - public static Region alertContentText(String s, int width) { var text = new Text(s); text.setWrappingWidth(width); diff --git a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java index d4a5693a6..92586eca7 100644 --- a/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java +++ b/app/src/main/java/io/xpipe/app/prefs/ExternalApplicationType.java @@ -49,7 +49,7 @@ public abstract class ExternalApplicationType implements PrefsChoiceValue { "mdfind -literal 'kMDItemFSName = \"%s.app\"' -onlyin /Applications -onlyin ~/Applications -onlyin /System/Applications", applicationName)) .readStdoutIfPossible(); - return out.isPresent() && !out.get().isBlank(); + return out.isPresent() && !out.get().isBlank() && out.get().contains(applicationName + ".app"); } catch (Exception e) { ErrorEvent.fromThrowable(e).handle(); return false; diff --git a/lang/app/strings/translations_en.properties b/lang/app/strings/translations_en.properties index 98d6c1ade..ebf442918 100644 --- a/lang/app/strings/translations_en.properties +++ b/lang/app/strings/translations_en.properties @@ -599,3 +599,5 @@ loadingSettings=Loading settings ... loadingConnections=Loading connections ... renderingContent=Rendering content ... ptbNotice=Notice for the public test build +userDeletionTitle=User deletion +userDeletionContent=Do you want to delete this user? This will also remove all personal identities and connections of this user. XPipe will restart to apply the user changes.