mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-10-02 18:17:27 +13:00
Rework browser welcome screen
This commit is contained in:
parent
2bc508d448
commit
f67e9ad247
10 changed files with 136 additions and 94 deletions
|
@ -84,7 +84,7 @@ final class BrowserBookmarkList extends SimpleComp {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var category = new DataStoreCategoryChoiceComp(StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(),
|
var category = new DataStoreCategoryChoiceComp(StoreViewState.get().getAllConnectionsCategory(), StoreViewState.get().getActiveCategory(),
|
||||||
selectedCategory).styleClass(Styles.LEFT_PILL).grow(false, true);
|
selectedCategory).styleClass(Styles.LEFT_PILL);
|
||||||
var filter = new FilterComp(filterText).styleClass(Styles.RIGHT_PILL).hgrow().apply(struc -> {});
|
var filter = new FilterComp(filterText).styleClass(Styles.RIGHT_PILL).hgrow().apply(struc -> {});
|
||||||
|
|
||||||
var top = new HorizontalComp(List.of(category, filter.hgrow())).styleClass("categories").apply(struc -> {
|
var top = new HorizontalComp(List.of(category, filter.hgrow())).styleClass("categories").apply(struc -> {
|
||||||
|
|
|
@ -22,7 +22,7 @@ public class BrowserGreetingComp extends SimpleComp {
|
||||||
text = "Good afternoon";
|
text = "Good afternoon";
|
||||||
}
|
}
|
||||||
var r = new Label(text);
|
var r = new Label(text);
|
||||||
AppFont.setSize(r, 12);
|
AppFont.setSize(r, 7);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,17 +25,20 @@ import java.util.function.Function;
|
||||||
@Getter
|
@Getter
|
||||||
public class BrowserModel {
|
public class BrowserModel {
|
||||||
|
|
||||||
public static final BrowserModel DEFAULT = new BrowserModel(Mode.BROWSER);
|
public static final BrowserModel DEFAULT = new BrowserModel(Mode.BROWSER, BrowserSavedStateImpl.load());
|
||||||
|
|
||||||
private final Mode mode;
|
private final Mode mode;
|
||||||
private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
|
private final ObservableList<OpenFileSystemModel> openFileSystems = FXCollections.observableArrayList();
|
||||||
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();
|
private final Property<OpenFileSystemModel> selected = new SimpleObjectProperty<>();
|
||||||
private final BrowserTransferModel localTransfersStage = new BrowserTransferModel(this);
|
private final BrowserTransferModel localTransfersStage = new BrowserTransferModel(this);
|
||||||
private final ObservableList<BrowserEntry> selection = FXCollections.observableArrayList();
|
private final ObservableList<BrowserEntry> selection = FXCollections.observableArrayList();
|
||||||
|
private final BrowserSavedState savedState;
|
||||||
@Setter
|
@Setter
|
||||||
private Consumer<List<FileReference>> onFinish;
|
private Consumer<List<FileReference>> onFinish;
|
||||||
|
|
||||||
public BrowserModel(Mode mode) {
|
public BrowserModel(Mode mode, BrowserSavedState savedState) {
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
|
this.savedState = savedState;
|
||||||
|
|
||||||
selected.addListener((observable, oldValue, newValue) -> {
|
selected.addListener((observable, oldValue, newValue) -> {
|
||||||
if (newValue == null) {
|
if (newValue == null) {
|
||||||
|
@ -48,7 +51,7 @@ public class BrowserModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void restoreState(BrowserSavedState state) {
|
public void restoreState(BrowserSavedState state) {
|
||||||
state.getLastSystems().forEach(e -> {
|
state.getEntries().forEach(e -> {
|
||||||
restoreState(e, null);
|
restoreState(e, null);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,27 +64,14 @@ public class BrowserModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
var list = new ArrayList<BrowserSavedState.Entry>();
|
|
||||||
synchronized (BrowserModel.this) {
|
synchronized (BrowserModel.this) {
|
||||||
openFileSystems.forEach(model -> {
|
openFileSystems.forEach(model -> {
|
||||||
if (DataStorage.get().getStoreEntries().contains(model.getEntry().get())) {
|
closeFileSystemSync(model);
|
||||||
list.add(new BrowserSavedState.Entry(model.getEntry().get().getUuid(), model.getCurrentPath().get()));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
if (savedState != null) {
|
||||||
|
savedState.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't override state if it is empty
|
|
||||||
if (list.size() == 0) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var meaningful = list.size() > 1 || list.stream().allMatch(s -> s.getPath() != null);
|
|
||||||
if (!meaningful) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var state = BrowserSavedState.builder().lastSystems(list).build();
|
|
||||||
state.save();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishChooser() {
|
public void finishChooser() {
|
||||||
|
@ -108,11 +98,18 @@ public class BrowserModel {
|
||||||
|
|
||||||
public void closeFileSystemAsync(OpenFileSystemModel open) {
|
public void closeFileSystemAsync(OpenFileSystemModel open) {
|
||||||
ThreadHelper.runAsync(() -> {
|
ThreadHelper.runAsync(() -> {
|
||||||
|
closeFileSystemSync(open);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeFileSystemSync(OpenFileSystemModel open) {
|
||||||
|
if (DataStorage.get().getStoreEntries().contains(open.getEntry().get()) && savedState != null && open.getCurrentPath().get() != null) {
|
||||||
|
savedState.add(new BrowserSavedState.Entry(open.getEntry().get().getUuid(), open.getCurrentPath().get()));
|
||||||
|
}
|
||||||
open.closeSync();
|
open.closeSync();
|
||||||
synchronized (BrowserModel.this) {
|
synchronized (BrowserModel.this) {
|
||||||
openFileSystems.remove(open);
|
openFileSystems.remove(open);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void openFileSystemAsync(DataStoreEntryRef<? extends FileSystemStore> store, Function<OpenFileSystemModel, String> path, BooleanProperty externalBusy) {
|
public void openFileSystemAsync(DataStoreEntryRef<? extends FileSystemStore> store, Function<OpenFileSystemModel, String> path, BooleanProperty externalBusy) {
|
||||||
|
|
|
@ -1,27 +1,40 @@
|
||||||
package io.xpipe.app.browser;
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
import io.xpipe.app.core.AppCache;
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import lombok.extern.jackson.Jacksonized;
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Value
|
public interface BrowserSavedState {
|
||||||
@Jacksonized
|
|
||||||
@Builder
|
static BrowserSavedState none() {
|
||||||
@Getter
|
return new BrowserSavedState() {
|
||||||
public class BrowserSavedState {
|
@Override
|
||||||
|
public void add(Entry entry) {
|
||||||
|
|
||||||
static BrowserSavedState load() {
|
|
||||||
return AppCache.get("browser-state", BrowserSavedState.class, () -> {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableList<Entry> getEntries() {
|
||||||
|
return FXCollections.observableArrayList();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Entry entry);
|
||||||
|
|
||||||
|
void save();
|
||||||
|
|
||||||
|
ObservableList<Entry> getEntries();
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
@Jacksonized
|
@Jacksonized
|
||||||
@Builder
|
@Builder
|
||||||
|
@ -30,10 +43,4 @@ public class BrowserSavedState {
|
||||||
UUID uuid;
|
UUID uuid;
|
||||||
String path;
|
String path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull List<Entry> lastSystems;
|
|
||||||
|
|
||||||
public void save() {
|
|
||||||
AppCache.update("browser-state", this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package io.xpipe.app.browser;
|
||||||
|
|
||||||
|
import io.xpipe.app.core.AppCache;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Value;
|
||||||
|
import lombok.extern.jackson.Jacksonized;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
@Jacksonized
|
||||||
|
@Builder
|
||||||
|
@Getter
|
||||||
|
public class BrowserSavedStateImpl implements BrowserSavedState {
|
||||||
|
|
||||||
|
static BrowserSavedStateImpl load() {
|
||||||
|
return AppCache.get("browser-state", BrowserSavedStateImpl.class, () -> {
|
||||||
|
return new BrowserSavedStateImpl(FXCollections.observableArrayList());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ObservableList<Entry> lastSystems;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void add(BrowserSavedState.Entry entry) {
|
||||||
|
lastSystems.removeIf(s -> s.getUuid().equals(entry.getUuid()));
|
||||||
|
lastSystems.addFirst(entry);
|
||||||
|
if (lastSystems.size() > 10) {
|
||||||
|
lastSystems.removeLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() {
|
||||||
|
AppCache.update("browser-state", this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObservableList<Entry> getEntries() {
|
||||||
|
return lastSystems;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,19 +5,21 @@ import atlantafx.base.theme.Styles;
|
||||||
import io.xpipe.app.comp.base.ButtonComp;
|
import io.xpipe.app.comp.base.ButtonComp;
|
||||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||||
import io.xpipe.app.comp.base.TileButtonComp;
|
import io.xpipe.app.comp.base.TileButtonComp;
|
||||||
import io.xpipe.app.core.AppFont;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
|
import io.xpipe.app.fxcomps.impl.LabelComp;
|
||||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||||
|
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.util.JfxHelper;
|
import io.xpipe.app.util.JfxHelper;
|
||||||
import io.xpipe.app.util.ThreadHelper;
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.collections.FXCollections;
|
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Separator;
|
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.Priority;
|
import javafx.scene.layout.Priority;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
|
@ -33,33 +35,26 @@ public class BrowserWelcomeComp extends SimpleComp {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var state = BrowserSavedState.load();
|
var state = model.getSavedState();
|
||||||
|
|
||||||
var welcome = new BrowserGreetingComp().createSimple();
|
var welcome = new BrowserGreetingComp().createSimple();
|
||||||
|
|
||||||
var vbox = new VBox(welcome, new Spacer(Orientation.VERTICAL));
|
var vbox = new VBox(welcome, new Spacer(4, Orientation.VERTICAL));
|
||||||
|
vbox.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Hips.svg"), 50, 75).padding(new Insets(5, 0, 0, 0)).createRegion();
|
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Hips.svg"), 50, 75).padding(new Insets(5, 0, 0, 0)).createRegion();
|
||||||
var hbox = new HBox(img, vbox);
|
var hbox = new HBox(img, vbox);
|
||||||
|
hbox.setAlignment(Pos.CENTER_LEFT);
|
||||||
hbox.setSpacing(15);
|
hbox.setSpacing(15);
|
||||||
|
|
||||||
if (state == null) {
|
if (state == null) {
|
||||||
var header = new Label("Here you will be able to see where you left off last time you exited XPipe.");
|
var header = new Label("Here you will be able to see where you left off last time you exited XPipe.");
|
||||||
AppFont.header(header);
|
|
||||||
vbox.getChildren().add(header);
|
vbox.getChildren().add(header);
|
||||||
hbox.setPadding(new Insets(40, 40, 40, 50));
|
hbox.setPadding(new Insets(40, 40, 40, 50));
|
||||||
return new VBox(hbox);
|
return new VBox(hbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
var header = new Label("Last time you were connected to the following systems:");
|
var list = BindingsHelper.filteredContentBinding(state.getEntries(), e -> {
|
||||||
header.getStyleClass().add(Styles.TEXT_MUTED);
|
|
||||||
AppFont.header(header);
|
|
||||||
vbox.getChildren().add(header);
|
|
||||||
|
|
||||||
var storeList = new VBox();
|
|
||||||
storeList.setSpacing(8);
|
|
||||||
|
|
||||||
var list = FXCollections.observableList(state.getLastSystems().stream().filter(e -> {
|
|
||||||
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
||||||
if (entry.isEmpty()) {
|
if (entry.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -70,8 +65,20 @@ public class BrowserWelcomeComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}).toList());
|
});
|
||||||
var box = new ListBoxViewComp<>(list, list, e -> {
|
var empty = Bindings.createBooleanBinding(() -> list.isEmpty(), list);
|
||||||
|
|
||||||
|
var header = new LabelComp(Bindings.createStringBinding(() -> {
|
||||||
|
return !empty.get() ? "Last time you were connected to the following systems:" :
|
||||||
|
"Here you will be able to see where you left off last time you exited XPipe.";
|
||||||
|
}, empty)).createRegion();
|
||||||
|
header.getStyleClass().add(Styles.TEXT_MUTED);
|
||||||
|
vbox.getChildren().add(header);
|
||||||
|
|
||||||
|
var storeList = new VBox();
|
||||||
|
storeList.setSpacing(8);
|
||||||
|
|
||||||
|
var listBox = new ListBoxViewComp<>(list, list, e -> {
|
||||||
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
var entry = DataStorage.get().getStoreEntryIfPresent(e.getUuid());
|
||||||
var graphic = entry.get().getProvider().getDisplayIconFileName(entry.get().getStore());
|
var graphic = entry.get().getProvider().getDisplayIconFileName(entry.get().getStore());
|
||||||
var view = PrettyImageHelper.ofFixedSquare(graphic, 45);
|
var view = PrettyImageHelper.ofFixedSquare(graphic, 45);
|
||||||
|
@ -83,26 +90,26 @@ public class BrowserWelcomeComp extends SimpleComp {
|
||||||
ThreadHelper.runAsync(() -> {
|
ThreadHelper.runAsync(() -> {
|
||||||
model.restoreState(e, disable);
|
model.restoreState(e, disable);
|
||||||
});
|
});
|
||||||
}).accessibleText(DataStorage.get().getStoreDisplayName(entry.get())).disable(disable).styleClass("color-box").apply(struc -> struc.get().setMaxWidth(2000)).grow(true, false);
|
}).accessibleText(DataStorage.get().getStoreDisplayName(entry.get())).disable(disable).styleClass("color-listBox").apply(struc -> struc.get().setMaxWidth(2000)).grow(true, false);
|
||||||
}).apply(struc -> {
|
}).apply(struc -> {
|
||||||
VBox vBox = (VBox) struc.get().getContent();
|
VBox vBox = (VBox) struc.get().getContent();
|
||||||
vBox.setSpacing(10);
|
vBox.setSpacing(10);
|
||||||
}).createRegion();
|
}).hide(empty).createRegion();
|
||||||
|
|
||||||
var layout = new VBox();
|
var layout = new VBox();
|
||||||
layout.getStyleClass().add("welcome");
|
layout.getStyleClass().add("welcome");
|
||||||
layout.setPadding(new Insets(40, 40, 40, 50));
|
layout.setPadding(new Insets(40, 40, 40, 50));
|
||||||
layout.setSpacing(18);
|
layout.setSpacing(18);
|
||||||
layout.getChildren().add(hbox);
|
layout.getChildren().add(hbox);
|
||||||
layout.getChildren().add(new Separator(Orientation.HORIZONTAL));
|
layout.getChildren().add(Comp.separator().hide(empty).createRegion());
|
||||||
layout.getChildren().add(box);
|
layout.getChildren().add(listBox);
|
||||||
VBox.setVgrow(layout.getChildren().get(2), Priority.NEVER);
|
VBox.setVgrow(layout.getChildren().get(2), Priority.NEVER);
|
||||||
layout.getChildren().add(new Separator(Orientation.HORIZONTAL));
|
layout.getChildren().add(Comp.separator().hide(empty).createRegion());
|
||||||
|
|
||||||
var tile = new TileButtonComp("restore", "restoreAllSessions", "mdmz-restore", actionEvent -> {
|
var tile = new TileButtonComp("restore", "restoreAllSessions", "mdmz-restore", actionEvent -> {
|
||||||
model.restoreState(state);
|
model.restoreState(state);
|
||||||
actionEvent.consume();
|
actionEvent.consume();
|
||||||
}).grow(true, false).accessibleTextKey("restoreAllSessions");
|
}).grow(true, false).hide(empty).accessibleTextKey("restoreAllSessions");
|
||||||
layout.getChildren().add(tile.createRegion());
|
layout.getChildren().add(tile.createRegion());
|
||||||
|
|
||||||
return layout;
|
return layout;
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class StandaloneFileBrowser {
|
||||||
|
|
||||||
public static void openSingleFile(Supplier<DataStoreEntryRef<? extends FileSystemStore>> store, Consumer<FileReference> file) {
|
public static void openSingleFile(Supplier<DataStoreEntryRef<? extends FileSystemStore>> store, Consumer<FileReference> file) {
|
||||||
PlatformThread.runLaterIfNeeded(() -> {
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
var model = new BrowserModel(BrowserModel.Mode.SINGLE_FILE_CHOOSER);
|
var model = new BrowserModel(BrowserModel.Mode.SINGLE_FILE_CHOOSER, null);
|
||||||
var comp = new BrowserComp(model)
|
var comp = new BrowserComp(model)
|
||||||
.apply(struc -> struc.get().setPrefSize(1200, 700))
|
.apply(struc -> struc.get().setPrefSize(1200, 700))
|
||||||
.apply(struc -> AppFont.normal(struc.get()));
|
.apply(struc -> AppFont.normal(struc.get()));
|
||||||
|
@ -57,7 +57,7 @@ public class StandaloneFileBrowser {
|
||||||
|
|
||||||
public static void saveSingleFile(Property<FileReference> file) {
|
public static void saveSingleFile(Property<FileReference> file) {
|
||||||
PlatformThread.runLaterIfNeeded(() -> {
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
var model = new BrowserModel(BrowserModel.Mode.SINGLE_FILE_SAVE);
|
var model = new BrowserModel(BrowserModel.Mode.SINGLE_FILE_SAVE, null);
|
||||||
var comp = new BrowserComp(model)
|
var comp = new BrowserComp(model)
|
||||||
.apply(struc -> struc.get().setPrefSize(1200, 700))
|
.apply(struc -> struc.get().setPrefSize(1200, 700))
|
||||||
.apply(struc -> AppFont.normal(struc.get()));
|
.apply(struc -> AppFont.normal(struc.get()));
|
||||||
|
|
|
@ -5,13 +5,11 @@ import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||||
import io.xpipe.app.storage.DataStorage;
|
import io.xpipe.app.storage.DataStorage;
|
||||||
import io.xpipe.app.util.Hyperlinks;
|
|
||||||
import io.xpipe.app.util.ScanAlert;
|
import io.xpipe.app.util.ScanAlert;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.geometry.Orientation;
|
import javafx.geometry.Orientation;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.Hyperlink;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.control.Separator;
|
import javafx.scene.control.Separator;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
|
@ -26,7 +24,6 @@ public class StoreIntroComp extends SimpleComp {
|
||||||
public Region createSimple() {
|
public Region createSimple() {
|
||||||
var title = new Label(AppI18n.get("storeIntroTitle"));
|
var title = new Label(AppI18n.get("storeIntroTitle"));
|
||||||
AppFont.setSize(title, 7);
|
AppFont.setSize(title, 7);
|
||||||
title.getStyleClass().add("title-header");
|
|
||||||
|
|
||||||
var introDesc = new Label(AppI18n.get("storeIntroDescription"));
|
var introDesc = new Label(AppI18n.get("storeIntroDescription"));
|
||||||
|
|
||||||
|
@ -41,22 +38,10 @@ public class StoreIntroComp extends SimpleComp {
|
||||||
var scanPane = new StackPane(scanButton);
|
var scanPane = new StackPane(scanButton);
|
||||||
scanPane.setAlignment(Pos.CENTER);
|
scanPane.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
var dofi = new FontIcon("mdi2b-book-open-variant");
|
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Wave.svg"), 80, 150).createRegion();
|
||||||
var documentation = new Label(AppI18n.get("introDocumentation"), dofi);
|
var text = new VBox(title, introDesc, new Separator(Orientation.HORIZONTAL), machine);
|
||||||
documentation.heightProperty().addListener((c, o, n) -> {
|
text.setAlignment(Pos.CENTER_LEFT);
|
||||||
dofi.iconSizeProperty().set(n.intValue());
|
var hbox = new HBox(img, text);
|
||||||
});
|
|
||||||
var docLink = new Hyperlink(Hyperlinks.DOCUMENTATION);
|
|
||||||
docLink.setOnAction(e -> {
|
|
||||||
Hyperlinks.open(Hyperlinks.DOCUMENTATION);
|
|
||||||
});
|
|
||||||
var docLinkPane = new StackPane(docLink);
|
|
||||||
docLinkPane.setAlignment(Pos.CENTER);
|
|
||||||
|
|
||||||
var img = PrettyImageHelper.ofSvg(new SimpleStringProperty("Wave.svg"), 80, 180).createRegion();
|
|
||||||
var hbox = new HBox(img, new VBox(
|
|
||||||
title, introDesc, new Separator(Orientation.HORIZONTAL), machine
|
|
||||||
));
|
|
||||||
hbox.setSpacing(35);
|
hbox.setSpacing(35);
|
||||||
hbox.setAlignment(Pos.CENTER);
|
hbox.setAlignment(Pos.CENTER);
|
||||||
|
|
||||||
|
|
|
@ -289,14 +289,16 @@ public class BindingsHelper {
|
||||||
var newSet = new HashSet<>(newList);
|
var newSet = new HashSet<>(newList);
|
||||||
|
|
||||||
// Only add missing element
|
// Only add missing element
|
||||||
if (targetSet.size() + 1 == newList.size() && newSet.containsAll(targetSet)) {
|
if (target.size() + 1 == newList.size() && newSet.containsAll(targetSet)) {
|
||||||
var l = new HashSet<>(newSet);
|
var l = new HashSet<>(newSet);
|
||||||
l.removeAll(targetSet);
|
l.removeAll(targetSet);
|
||||||
|
if (l.size() > 0) {
|
||||||
var found = l.iterator().next();
|
var found = l.iterator().next();
|
||||||
var index = newList.indexOf(found);
|
var index = newList.indexOf(found);
|
||||||
target.add(index, found);
|
target.add(index, found);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Only remove not needed element
|
// Only remove not needed element
|
||||||
if (target.size() - 1 == newList.size() && targetSet.containsAll(newSet)) {
|
if (target.size() - 1 == newList.size() && targetSet.containsAll(newSet)) {
|
||||||
|
|
|
@ -58,6 +58,7 @@ public class JfxHelper {
|
||||||
var desc = new Label(descString);
|
var desc = new Label(descString);
|
||||||
AppFont.small(desc);
|
AppFont.small(desc);
|
||||||
var text = new VBox(header, new Spacer(), desc);
|
var text = new VBox(header, new Spacer(), desc);
|
||||||
|
text.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
if (image == null) {
|
if (image == null) {
|
||||||
return text;
|
return text;
|
||||||
|
|
Loading…
Reference in a new issue