Script intro rework

This commit is contained in:
crschnick 2024-10-25 20:01:54 +00:00
parent 2678ade3c3
commit b9b3f7907f
5 changed files with 212 additions and 4 deletions

View file

@ -2,11 +2,13 @@ package io.xpipe.app.comp.store;
import io.xpipe.app.comp.base.ListBoxViewComp;
import io.xpipe.app.comp.base.MultiContentComp;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppLayoutModel;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.layout.Region;
@ -46,6 +48,7 @@ public class StoreEntryListComp extends SimpleComp {
@Override
protected Region createSimple() {
var scriptsIntroShowing = new SimpleBooleanProperty(!AppCache.get("scriptsIntroCompleted", Boolean.class,() -> false));
var initialCount = 1;
var showIntro = Bindings.createBooleanBinding(
() -> {
@ -63,6 +66,20 @@ public class StoreEntryListComp extends SimpleComp {
},
StoreViewState.get().getAllEntries().getList(),
StoreViewState.get().getActiveCategory());
var showList = Bindings.createBooleanBinding(() -> {
if (StoreViewState.get().getActiveCategory().getValue().getRoot().equals(StoreViewState.get().getAllScriptsCategory())) {
return !scriptsIntroShowing.get();
}
if (StoreViewState.get()
.getCurrentTopLevelSection()
.getShownChildren()
.getList().isEmpty()) {
return false;
}
return true;
}, StoreViewState.get().getActiveCategory(), scriptsIntroShowing, StoreViewState.get().getCurrentTopLevelSection().getShownChildren().getList());
var map = new LinkedHashMap<Comp<?>, ObservableValue<Boolean>>();
map.put(
new StoreNotFoundComp(),
@ -75,11 +92,9 @@ public class StoreEntryListComp extends SimpleComp {
.getList())));
map.put(
createList(),
Bindings.not(Bindings.isEmpty(StoreViewState.get()
.getCurrentTopLevelSection()
.getShownChildren()
.getList())));
showList);
map.put(new StoreIntroComp(), showIntro);
map.put(new StoreScriptsIntroComp(scriptsIntroShowing), scriptsIntroShowing);
return new MultiContentComp(map).createRegion();
}

View file

@ -0,0 +1,122 @@
package io.xpipe.app.comp.store;
import atlantafx.base.theme.Styles;
import io.xpipe.app.core.AppCache;
import io.xpipe.app.core.AppFont;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.core.process.OsType;
import javafx.beans.property.BooleanProperty;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import org.kordamp.ikonli.javafx.FontIcon;
public class StoreScriptsIntroComp extends SimpleComp {
private final BooleanProperty show;
public StoreScriptsIntroComp(BooleanProperty show) {this.show = show;}
private Region createIntro() {
var title = new Label();
title.textProperty().bind(AppI18n.observable("scriptsIntroTitle"));
if (OsType.getLocal() != OsType.MACOS) {
title.getStyleClass().add(Styles.TEXT_BOLD);
}
AppFont.setSize(title, 7);
var introDesc = new Label();
introDesc.textProperty().bind(AppI18n.observable("scriptsIntroText"));
introDesc.setWrapText(true);
introDesc.setMaxWidth(470);
var img = new FontIcon("mdi2s-script-text");
img.setIconSize(80);
var text = new VBox(title, introDesc);
text.setSpacing(5);
text.setAlignment(Pos.CENTER_LEFT);
var hbox = new HBox(img, text);
hbox.setSpacing(55);
hbox.setAlignment(Pos.CENTER);
var v = new VBox(hbox);
v.setMinWidth(Region.USE_PREF_SIZE);
v.setMaxWidth(Region.USE_PREF_SIZE);
v.setMinHeight(Region.USE_PREF_SIZE);
v.setMaxHeight(Region.USE_PREF_SIZE);
v.setSpacing(10);
v.getStyleClass().add("intro");
return v;
}
private Region createBottom() {
var title = new Label();
title.textProperty().bind(AppI18n.observable("scriptsIntroBottomTitle"));
if (OsType.getLocal() != OsType.MACOS) {
title.getStyleClass().add(Styles.TEXT_BOLD);
}
AppFont.setSize(title, 7);
var importDesc = new Label();
importDesc.textProperty().bind(AppI18n.observable("scriptsIntroBottomText"));
importDesc.setWrapText(true);
importDesc.setMaxWidth(470);
var importButton = new Button(null, new FontIcon("mdi2p-play-circle"));
importButton.setDefaultButton(true);
importButton.textProperty().bind(AppI18n.observable("scriptsIntroStart"));
importButton.setOnAction(event -> {
AppCache.update("scriptsIntroCompleted", true);
show.set(false);
});
var importPane = new StackPane(importButton);
importPane.setAlignment(Pos.CENTER);
var fi = new FontIcon("mdi2t-tooltip-edit");
fi.setIconSize(80);
var img = new StackPane(fi);
img.setPrefWidth(100);
img.setPrefHeight(150);
var text = new VBox(title, importDesc);
text.setSpacing(5);
text.setAlignment(Pos.CENTER_LEFT);
var hbox = new HBox(img, text);
hbox.setSpacing(35);
hbox.setAlignment(Pos.CENTER);
var v = new VBox(hbox, importPane);
v.setMinWidth(Region.USE_PREF_SIZE);
v.setMaxWidth(Region.USE_PREF_SIZE);
v.setMinHeight(Region.USE_PREF_SIZE);
v.setMaxHeight(Region.USE_PREF_SIZE);
v.setSpacing(20);
v.getStyleClass().add("intro");
return v;
}
@Override
public Region createSimple() {
var intro = createIntro();
var introImport = createBottom();
var v = new VBox(intro, introImport);
v.setSpacing(80);
v.setMinWidth(Region.USE_PREF_SIZE);
v.setMaxWidth(Region.USE_PREF_SIZE);
v.setMinHeight(Region.USE_PREF_SIZE);
v.setMaxHeight(Region.USE_PREF_SIZE);
var sp = new StackPane(v);
sp.setPadding(new Insets(40, 0, 0, 0));
sp.setAlignment(Pos.CENTER);
sp.setPickOnBounds(false);
return sp;
}
}

View file

@ -0,0 +1,65 @@
package io.xpipe.ext.base.action;
import io.xpipe.app.comp.store.StoreCreationComp;
import io.xpipe.app.core.AppI18n;
import io.xpipe.app.ext.ActionProvider;
import io.xpipe.app.storage.DataStoreEntry;
import io.xpipe.app.storage.DataStoreEntryRef;
import io.xpipe.ext.base.script.SimpleScriptStore;
import javafx.beans.value.ObservableValue;
import lombok.Value;
public class EditScriptStoreAction implements ActionProvider {
@Override
public LeafDataStoreCallSite<?> getLeafDataStoreCallSite() {
return new LeafDataStoreCallSite<SimpleScriptStore>() {
@Override
public boolean isSystemAction() {
return true;
}
@Override
public boolean isMajor(DataStoreEntryRef<SimpleScriptStore> o) {
return true;
}
@Override
public ActionProvider.Action createAction(DataStoreEntryRef<SimpleScriptStore> store) {
return new Action(store.get());
}
@Override
public Class<SimpleScriptStore> getApplicableClass() {
return SimpleScriptStore.class;
}
@Override
public ObservableValue<String> getName(DataStoreEntryRef<SimpleScriptStore> store) {
return AppI18n.observable("base.edit");
}
@Override
public String getIcon(DataStoreEntryRef<SimpleScriptStore> store) {
return "mdal-edit";
}
@Override
public boolean requiresValidStore() {
return false;
}
};
}
@Value
static class Action implements ActionProvider.Action {
DataStoreEntry store;
@Override
public void execute() {
StoreCreationComp.showEdit(store);
}
}
}

View file

@ -86,6 +86,7 @@ open module io.xpipe.ext.base {
LaunchStoreAction,
XPipeUrlAction,
EditStoreAction,
EditScriptStoreAction,
BrowseStoreAction,
ScanStoreAction,
ChangeStoreIconAction;

View file

@ -540,3 +540,8 @@ openSessionLogs=Open session logs
sessionLogging=Session logging
sessionActive=A background session is running for this connection.\n\nTo stop this session manually, click on the status indicator.
skipValidation=Skip validation
scriptsIntroTitle=About scripts
scriptsIntroText=You can run scripts on any system on shell init, in the file browser, and on demand. With scripts, you can bring your custom prompts, aliases, and other custom functionality to all your systems without having to set up scripts on remote systems yourself, XPipe will handle everything for you.
scriptsIntroBottomTitle=Using scripts
scriptsIntroBottomText=There are a variety of sample scripts to start out. You can click on the edit button of the individual scripts to see how they are designed and enable them to try them out. Scripts have to be enabled to run and show up in menus, there is a toggle on every script for that.
scriptsIntroStart=Get started