diff --git a/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java b/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java index 47aa0c775..7fe6a68ce 100644 --- a/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java +++ b/app/src/main/java/io/xpipe/app/comp/base/LoadingOverlayComp.java @@ -1,23 +1,30 @@ package io.xpipe.app.comp.base; -import atlantafx.base.controls.RingProgressIndicator; import io.xpipe.app.fxcomps.Comp; import io.xpipe.app.fxcomps.CompStructure; import io.xpipe.app.fxcomps.SimpleCompStructure; import io.xpipe.app.fxcomps.util.PlatformThread; -import io.xpipe.app.prefs.AppPrefs; +import io.xpipe.app.util.Indicator; import io.xpipe.app.util.ThreadHelper; import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.geometry.Pos; +import javafx.scene.Parent; import javafx.scene.layout.StackPane; +import org.reactfx.EventStream; +import org.reactfx.EventStreams; + +import java.time.Duration; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; public class LoadingOverlayComp extends Comp> { public static LoadingOverlayComp noProgress(Comp comp, ObservableValue loading) { - return new LoadingOverlayComp(comp, loading, new SimpleDoubleProperty(-1)); + return new LoadingOverlayComp(comp, loading, new SimpleDoubleProperty(50)); } private final Comp comp; @@ -30,16 +37,24 @@ public class LoadingOverlayComp extends Comp> { this.progress = PlatformThread.sync(progress); } + private static final double FPS = 30.0; + private static final double cycleDurationSeconds = 4.0; + @Override public CompStructure createBase() { var compStruc = comp.createStructure(); var r = compStruc.get(); - var loading = new RingProgressIndicator(0, false); - loading.progressProperty().bind(progress); - loading.visibleProperty().bind(Bindings.not(AppPrefs.get().performanceMode())); + ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor(); + EventStream ticks = EventStreams.ticks(Duration.ofMillis((long) (1000 / FPS)), scheduler, Platform::runLater); - var loadingOverlay = new StackPane(loading); + + var pane = new StackPane(); + Parent node = new Indicator(ticks, (int) (FPS * cycleDurationSeconds)).getNode(); + pane.getChildren().add(node); + pane.setAlignment(Pos.CENTER); + + var loadingOverlay = new StackPane(pane); loadingOverlay.getStyleClass().add("loading-comp"); loadingOverlay.setVisible(showLoading.getValue()); @@ -76,13 +91,13 @@ public class LoadingOverlayComp extends Comp> { var stack = new StackPane(r, loadingOverlay); - loading.prefWidthProperty() + pane.prefWidthProperty() .bind(Bindings.createDoubleBinding( () -> { return Math.min(r.getHeight() - 20, 50); }, r.heightProperty())); - loading.prefHeightProperty().bind(loading.prefWidthProperty()); + pane.prefHeightProperty().bind(pane.prefWidthProperty()); return new SimpleCompStructure<>(stack); } diff --git a/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java b/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java index 4058cf8e4..9545a9ce7 100644 --- a/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java +++ b/app/src/main/java/io/xpipe/app/comp/store/GuiDsStoreCreator.java @@ -110,13 +110,22 @@ public class GuiDsStoreCreator extends MultiStepComp.Step> { name.getValue(), store.getValue()); var p = provider.getValue().getDisplayParent(testE); + + var targetCategory = p != null + ? p.getCategoryUuid() + : DataStorage.get() + .getSelectedCategory() + .getUuid(); + var rootCategory = DataStorage.get().getRootCategory(DataStorage.get().getStoreCategoryIfPresent(targetCategory).orElseThrow()); + // Don't put connections in the scripts category ever + if (!provider.getValue().getCreationCategory().equals(DataStoreProvider.CreationCategory.SCRIPT) && + rootCategory.equals(DataStorage.get().getAllScriptsCategory())) { + targetCategory = DataStorage.get().getDefaultCategory().getUuid(); + } + return DataStoreEntry.createNew( UUID.randomUUID(), - p != null - ? p.getCategoryUuid() - : DataStorage.get() - .getSelectedCategory() - .getUuid(), + targetCategory, name.getValue(), store.getValue()); }, name, store); diff --git a/app/src/main/java/io/xpipe/app/util/Indicator.java b/app/src/main/java/io/xpipe/app/util/Indicator.java new file mode 100644 index 000000000..a2f3d184c --- /dev/null +++ b/app/src/main/java/io/xpipe/app/util/Indicator.java @@ -0,0 +1,98 @@ +package io.xpipe.app.util; + +import javafx.scene.Group; +import javafx.scene.Parent; +import javafx.scene.paint.Color; +import javafx.scene.shape.*; +import org.reactfx.EventStream; + +public class Indicator { + + private static final Color lColor = Color.rgb(0x66, 0x66, 0x66); + private static final Color rColor = Color.rgb(0x0f, 0x87, 0xc3); + + private static final PathElement[] ELEMS = new PathElement[] { + new MoveTo(9.2362945,19.934046), + new CubicCurveTo(-1.3360939,-0.28065, -1.9963146,-1.69366, -1.9796182,-2.95487), + new CubicCurveTo(-0.1152909,-1.41268, -0.5046634,-3.07081, -1.920768,-3.72287), + new CubicCurveTo(-1.4711631,-0.77284, -3.4574873,-0.11153, -4.69154031,-1.40244), + new CubicCurveTo(-1.30616123,-1.40422, -0.5308003,-4.1855799, 1.46313121,-4.4219799), + new CubicCurveTo(1.4290018,-0.25469, 3.1669517,-0.0875, 4.1676818,-1.36207), + new CubicCurveTo(0.9172241,-1.12206, 0.9594176,-2.63766, 1.0685793,-4.01259), + new CubicCurveTo(0.4020299,-1.95732999, 3.2823027,-2.72818999, 4.5638567,-1.15760999), + new CubicCurveTo(1.215789,1.31824999, 0.738899,3.90740999, -1.103778,4.37267999), + new CubicCurveTo(-1.3972543,0.40868, -3.0929979,0.0413, -4.2208253,1.16215), + new CubicCurveTo(-1.3524806,1.26423, -1.3178578,3.29187, -1.1086673,4.9895199), + new CubicCurveTo(0.167826,1.28946, 1.0091133,2.5347, 2.3196964,2.86608), + new CubicCurveTo(1.6253079,0.53477, 3.4876372,0.45004, 5.0294052,-0.30121), + new CubicCurveTo(1.335829,-0.81654, 1.666839,-2.49408, 1.717756,-3.9432), + new CubicCurveTo(0.08759,-1.1232899, 0.704887,-2.3061299, 1.871843,-2.5951699), + new CubicCurveTo(1.534558,-0.50726, 3.390804,0.62784, 3.467269,2.28631), + new CubicCurveTo(0.183147,1.4285099, -0.949563,2.9179999, -2.431156,2.9383699), + new CubicCurveTo(-1.390597,0.17337, -3.074035,0.18128, -3.971365,1.45069), + new CubicCurveTo(-0.99314,1.271, -0.676157,2.98683, -1.1715,4.43018), + new CubicCurveTo(-0.518248,1.11436, -1.909118,1.63902, -3.0700005,1.37803), + new ClosePath() + }; + + static { + for(int i = 1; i < ELEMS.length; ++i) { + ELEMS[i].setAbsolute(false); + } + } + + private final Path left; + private final Path right; + private final Group g; + private final int steps; + + private boolean fw = true; + private int step = 0; + + public Indicator(EventStream ticks, int ticksPerCycle) { + this.steps = ticksPerCycle; + + left = new Path(ELEMS); + right = new Path(ELEMS); + + right.setScaleX(-1); + right.setScaleY(-1); + right.setTranslateX(7.266); + right.setOpacity(0.0); + + left.setStroke(null); + right.setStroke(null); + left.setFill(lColor); + right.setFill(rColor); + + g = new Group(left, right); + + ticks.conditionOnShowing(g).subscribe(tick -> step()); + } + + public Parent getNode() { + return g; + } + + private void step() { + double lOpacity, rOpacity; + + step += fw ? 1 : -1; + + if(step == steps) { + fw = false; + lOpacity = 0.0; + rOpacity = 1.0; + } else if(step == 0) { + fw = true; + lOpacity = 1.0; + rOpacity = 0.0; + } else { + lOpacity = 1.0 * (steps - step) / steps; + rOpacity = 1.0 * step / steps; + } + + left.setOpacity(lOpacity); + right.setOpacity(rOpacity); + } +} diff --git a/dist/changelogs/1.7.13.md b/dist/changelogs/1.7.13.md new file mode 100644 index 000000000..cb20946ca --- /dev/null +++ b/dist/changelogs/1.7.13.md @@ -0,0 +1,16 @@ +## New professional features + +- Add ability to open files and directories in VSCode SSH remote environment in file browser +- Added support for fully offline licenses. You can obtain them via email request + in case you're running it on a system without internet connectivity or restricted proxy settings + +## Changes + + +## Additions + + +## Fixes + +- Fix connections being accidentally listed under scripts category + if they were added while scripts category was selected