diff --git a/app/src/main/java/io/xpipe/app/comp/base/TextFieldComp.java b/app/src/main/java/io/xpipe/app/comp/base/TextFieldComp.java index 6e32c7624..66592bbd6 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/TextFieldComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/TextFieldComp.java @@ -57,12 +57,13 @@ public class TextFieldComp extends Comp> { text.setOnKeyPressed(ke -> { if (ke.getCode().equals(KeyCode.ENTER)) { text.getScene().getRoot().requestFocus(); + ke.consume(); } if (lazy && ke.getCode().equals(KeyCode.ENTER)) { lastAppliedValue.setValue(currentValue.getValue()); + ke.consume(); } - ke.consume(); }); text.focusedProperty().addListener((observable, oldValue, newValue) -> { diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java index 3f4807079..e70430382 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationComp.java @@ -5,11 +5,14 @@ import io.xpipe.app.comp.augment.GrowAugment; import io.xpipe.app.comp.base.*; import io.xpipe.app.util.*; +import javafx.application.Platform; import javafx.beans.property.*; import javafx.beans.value.ObservableValue; import javafx.geometry.Insets; import javafx.scene.control.*; import javafx.scene.control.skin.ScrollPaneSkin; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import javafx.scene.layout.BorderPane; import javafx.scene.layout.Priority; import javafx.scene.layout.Region; @@ -41,11 +44,6 @@ public class StoreCreationComp extends ModalOverlayContentComp { .addString(model.getName(), false) .nonNull(propVal) .buildComp() - .onSceneAssign(struc -> { - if (model.isStaticDisplay()) { - struc.get().requestFocus(); - } - }) .styleClass("store-creator-options") .createRegion(); } @@ -54,6 +52,7 @@ public class StoreCreationComp extends ModalOverlayContentComp { var layout = new BorderPane(); layout.getStyleClass().add("store-creator"); var providerChoice = new StoreProviderChoiceComp(model.getFilter(), model.getProvider()); + providerChoice.grow(true, false); var provider = model.getProvider().getValue() != null ? model.getProvider().getValue() : providerChoice.getProviders().getFirst(); @@ -62,16 +61,13 @@ public class StoreCreationComp extends ModalOverlayContentComp { if (model.isStaticDisplay()) { providerChoice.apply(struc -> struc.get().setDisable(true)); } - if (showProviders) { - providerChoice.onSceneAssign(struc -> struc.get().requestFocus()); - } - providerChoice.apply(GrowAugment.create(true, false)); model.getProvider().subscribe(n -> { if (n != null) { var d = n.guiDialog(model.getExistingEntry(), model.getStore()); var propVal = new SimpleValidator(); var propR = createStoreProperties(d == null || d.getComp() == null ? null : d.getComp(), propVal); + model.getInitialStore().setValue(model.getStore().getValue()); var valSp = new GraphicDecorationStackPane(); valSp.getChildren().add(propR); @@ -92,6 +88,10 @@ public class StoreCreationComp extends ModalOverlayContentComp { var vbox = new VBox(topSep, sp, bottomSep); VBox.setVgrow(sp, Priority.ALWAYS); + Platform.runLater(() -> { + propR.requestFocus(); + }); + layout.setCenter(vbox); model.getValidator() diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationDialog.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationDialog.java index 7ce7771c7..cd56185ad 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationDialog.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationDialog.java @@ -18,6 +18,8 @@ import io.xpipe.core.store.DataStore; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; import java.util.function.Consumer; import java.util.function.Predicate; @@ -127,12 +129,12 @@ public class StoreCreationDialog { } private static boolean showInvalidConfirmAlert() { - var skipped = new SimpleBooleanProperty(); + var retry = new SimpleBooleanProperty(); var modal = ModalOverlay.of("confirmInvalidStoreTitle", AppDialog.dialogTextKey("confirmInvalidStoreContent")); - modal.addButton(new ModalButton("retry", null, true, false)); - modal.addButton(new ModalButton("skip", () -> skipped.set(true), true, true)); + modal.addButton(new ModalButton("retry", () -> retry.set(true), true, false)); + modal.addButton(new ModalButton("skip", null, true, true)); modal.showAndWait(); - return skipped.get(); + return !retry.get(); } private static ModalOverlay createModalOverlay(StoreCreationModel model) { @@ -146,6 +148,17 @@ public class StoreCreationDialog { ? new LabelGraphic.ImageGraphic( provider.getDisplayIconFileName(model.getStore().get()), 20) : new LabelGraphic.IconGraphic("mdi2b-beaker-plus-outline"); + comp.apply(struc -> { + struc.get().addEventHandler(KeyEvent.KEY_PRESSED, e -> { + if (e.getCode() == KeyCode.ESCAPE) { + var changed = model.hasBeenModified(); + if (!changed) { + modal.close(); + e.consume(); + } + } + }); + }); modal.hideable(AppI18n.observable(model.storeTypeNameKey() + "Add"), graphic, () -> { modal.show(); }); diff --git a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java index 60a0a9f9a..c76f08784 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java +++ b/app/src/main/java/io/xpipe/app/comp/store/StoreCreationModel.java @@ -29,6 +29,7 @@ import java.util.function.Predicate; @Getter public class StoreCreationModel { + ObjectProperty initialStore = new SimpleObjectProperty<>(); Property provider; ObjectProperty store; Predicate filter; @@ -171,6 +172,15 @@ public class StoreCreationModel { }); } + boolean hasBeenModified() { + if (initialStore.getValue() == null) { + return true; + } + + var eq = initialStore.getValue().equals(store.getValue()); + return !eq; + } + void finish() { if (finished.get()) { return;