Make categories expendable

This commit is contained in:
crschnick 2024-08-21 15:20:58 +00:00
parent 417115c527
commit d92b870908
7 changed files with 49 additions and 29 deletions

View file

@ -6,9 +6,7 @@ import io.xpipe.app.prefs.AppPrefs;
import io.xpipe.app.storage.DataStorage; import io.xpipe.app.storage.DataStorage;
import io.xpipe.app.storage.DataStoreCategory; import io.xpipe.app.storage.DataStoreCategory;
import javafx.beans.property.Property; import javafx.beans.property.*;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
@ -30,6 +28,7 @@ public class StoreCategoryWrapper {
private final Property<Boolean> share; private final Property<Boolean> share;
private final ObservableList<StoreCategoryWrapper> children; private final ObservableList<StoreCategoryWrapper> children;
private final ObservableList<StoreEntryWrapper> containedEntries; private final ObservableList<StoreEntryWrapper> containedEntries;
private final BooleanProperty expanded = new SimpleBooleanProperty();
public StoreCategoryWrapper(DataStoreCategory category) { public StoreCategoryWrapper(DataStoreCategory category) {
var d = 0; var d = 0;
@ -111,6 +110,10 @@ public class StoreCategoryWrapper {
}); });
} }
public void toggleExpanded() {
this.expanded.set(!expanded.getValue());
}
public void update() { public void update() {
// We are probably in shutdown then // We are probably in shutdown then
if (StoreViewState.get() == null) { if (StoreViewState.get() == null) {
@ -126,6 +129,7 @@ public class StoreCategoryWrapper {
lastAccess.setValue(category.getLastAccess().minus(Duration.ofMillis(500))); lastAccess.setValue(category.getLastAccess().minus(Duration.ofMillis(500)));
sortMode.setValue(category.getSortMode()); sortMode.setValue(category.getSortMode());
share.setValue(category.isShare()); share.setValue(category.isShare());
expanded.setValue(category.isExpanded());
containedEntries.setAll(StoreViewState.get().getAllEntries().getList().stream() containedEntries.setAll(StoreViewState.get().getAllEntries().getList().stream()
.filter(entry -> { .filter(entry -> {

View file

@ -49,13 +49,16 @@ public class StoreCategoryComp extends SimpleComp {
() -> { () -> {
if (!DataStorage.get().supportsSharing() if (!DataStorage.get().supportsSharing()
|| !category.getCategory().canShare()) { || !category.getCategory().canShare()) {
return "mdal-keyboard_arrow_right"; var exp = category.getExpanded().get() && category.getChildren().size() > 0;
return exp ? "mdal-keyboard_arrow_down" : "mdal-keyboard_arrow_right";
} }
return category.getShare().getValue() ? "mdi2g-git" : "mdi2a-account-cancel"; return category.getShare().getValue() ? "mdi2g-git" : "mdi2a-account-cancel";
}, },
category.getShare()); category.getShare(), category.getExpanded(), category.getChildren());
var icon = new IconButtonComp(i) var icon = new IconButtonComp(i, () -> {
category.toggleExpanded();
})
.apply(struc -> AppFont.small(struc.get())) .apply(struc -> AppFont.small(struc.get()))
.apply(struc -> { .apply(struc -> {
struc.get().setAlignment(Pos.CENTER); struc.get().setAlignment(Pos.CENTER);
@ -116,8 +119,10 @@ public class StoreCategoryComp extends SimpleComp {
var children = var children =
new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper), false); new ListBoxViewComp<>(l, l, storeCategoryWrapper -> new StoreCategoryComp(storeCategoryWrapper), false);
var emptyBinding = Bindings.isEmpty(category.getChildren()); var hide = Bindings.createBooleanBinding(() -> {
var v = new VerticalComp(List.of(categoryButton, children.hide(emptyBinding))); return !category.getExpanded().get() || category.getChildren().isEmpty();
}, category.getChildren(), category.getExpanded());
var v = new VerticalComp(List.of(categoryButton, children.hide(hide)));
v.styleClass("category"); v.styleClass("category");
v.apply(struc -> { v.apply(struc -> {
StoreViewState.get().getActiveCategory().subscribe(val -> { StoreViewState.get().getActiveCategory().subscribe(val -> {

View file

@ -175,7 +175,8 @@ public abstract class DataStorage {
true, true,
ALL_CONNECTIONS_CATEGORY_UUID, ALL_CONNECTIONS_CATEGORY_UUID,
StoreSortMode.getDefault(), StoreSortMode.getDefault(),
false)); false,
true));
} }
storeCategories.forEach(dataStoreCategory -> { storeCategories.forEach(dataStoreCategory -> {

View file

@ -41,8 +41,9 @@ public class DataStoreCategory extends StorageElement {
boolean dirty, boolean dirty,
UUID parentCategory, UUID parentCategory,
StoreSortMode sortMode, StoreSortMode sortMode,
boolean share) { boolean share,
super(directory, uuid, name, lastUsed, lastModified, dirty); boolean expanded) {
super(directory, uuid, name, lastUsed, lastModified, expanded, dirty);
this.parentCategory = parentCategory; this.parentCategory = parentCategory;
this.sortMode = sortMode; this.sortMode = sortMode;
this.share = share; this.share = share;
@ -58,7 +59,8 @@ public class DataStoreCategory extends StorageElement {
true, true,
parentCategory, parentCategory,
StoreSortMode.getDefault(), StoreSortMode.getDefault(),
false); false,
true);
} }
public static DataStoreCategory createNew(UUID parentCategory, @NonNull UUID uuid, @NonNull String name) { public static DataStoreCategory createNew(UUID parentCategory, @NonNull UUID uuid, @NonNull String name) {
@ -71,7 +73,8 @@ public class DataStoreCategory extends StorageElement {
true, true,
parentCategory, parentCategory,
StoreSortMode.getDefault(), StoreSortMode.getDefault(),
false); false,
true);
} }
public static Optional<DataStoreCategory> fromDirectory(Path dir) throws Exception { public static Optional<DataStoreCategory> fromDirectory(Path dir) throws Exception {
@ -108,9 +111,12 @@ public class DataStoreCategory extends StorageElement {
.map(jsonNode -> jsonNode.textValue()) .map(jsonNode -> jsonNode.textValue())
.map(Instant::parse) .map(Instant::parse)
.orElse(Instant.now()); .orElse(Instant.now());
var expanded = Optional.ofNullable(stateJson.get("expanded"))
.map(jsonNode -> jsonNode.booleanValue())
.orElse(true);
return Optional.of( return Optional.of(
new DataStoreCategory(dir, uuid, name, lastUsed, lastModified, false, parentUuid, sortMode, share)); new DataStoreCategory(dir, uuid, name, lastUsed, lastModified, false, parentUuid, sortMode, share, expanded));
} }
public void setSortMode(StoreSortMode sortMode) { public void setSortMode(StoreSortMode sortMode) {
@ -177,6 +183,7 @@ public class DataStoreCategory extends StorageElement {
stateObj.put("lastUsed", lastUsed.toString()); stateObj.put("lastUsed", lastUsed.toString());
stateObj.put("lastModified", lastModified.toString()); stateObj.put("lastModified", lastModified.toString());
stateObj.put("sortMode", sortMode.getId()); stateObj.put("sortMode", sortMode.getId());
stateObj.put("expanded", expanded);
obj.put("parentUuid", parentCategory != null ? parentCategory.toString() : null); obj.put("parentUuid", parentCategory != null ? parentCategory.toString() : null);
var entryString = mapper.writeValueAsString(obj); var entryString = mapper.writeValueAsString(obj);

View file

@ -44,9 +44,6 @@ public class DataStoreEntry extends StorageElement {
@NonFinal @NonFinal
Configuration configuration; Configuration configuration;
@NonFinal
boolean expanded;
AtomicInteger busyCounter = new AtomicInteger(); AtomicInteger busyCounter = new AtomicInteger();
@Getter @Getter
@ -92,13 +89,12 @@ public class DataStoreEntry extends StorageElement {
DataStoreColor color, DataStoreColor color,
String notes, String notes,
Order explicitOrder) { Order explicitOrder) {
super(directory, uuid, name, lastUsed, lastModified, dirty); super(directory, uuid, name, lastUsed, lastModified, expanded, dirty);
this.categoryUuid = categoryUuid; this.categoryUuid = categoryUuid;
this.store = store; this.store = store;
this.storeNode = storeNode; this.storeNode = storeNode;
this.validity = validity; this.validity = validity;
this.configuration = configuration; this.configuration = configuration;
this.expanded = expanded;
this.color = color; this.color = color;
this.explicitOrder = explicitOrder; this.explicitOrder = explicitOrder;
this.provider = store != null ? DataStoreProviders.byStore(store) : null; this.provider = store != null ? DataStoreProviders.byStore(store) : null;
@ -115,7 +111,7 @@ public class DataStoreEntry extends StorageElement {
Instant lastModified, Instant lastModified,
DataStore store, DataStore store,
Order explicitOrder) { Order explicitOrder) {
super(directory, uuid, name, lastUsed, lastModified, false); super(directory, uuid, name, lastUsed, lastModified, false,false);
this.categoryUuid = categoryUuid; this.categoryUuid = categoryUuid;
this.store = store; this.store = store;
this.explicitOrder = explicitOrder; this.explicitOrder = explicitOrder;
@ -401,14 +397,6 @@ public class DataStoreEntry extends StorageElement {
dirty = false; dirty = false;
} }
public void setExpanded(boolean expanded) {
var changed = expanded != this.expanded;
this.expanded = expanded;
if (changed) {
notifyUpdate(false, true);
}
}
public void setNotes(String newNotes) { public void setNotes(String newNotes) {
var changed = !Objects.equals(notes, newNotes); var changed = !Objects.equals(notes, newNotes);
this.notes = newNotes; this.notes = newNotes;

View file

@ -33,6 +33,7 @@ public class ImpersistentStorage extends DataStorage {
true, true,
ALL_CONNECTIONS_CATEGORY_UUID, ALL_CONNECTIONS_CATEGORY_UUID,
StoreSortMode.getDefault(), StoreSortMode.getDefault(),
true,
true); true);
storeCategories.add(cat); storeCategories.add(cat);
selectedCategory = getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID).orElseThrow(); selectedCategory = getStoreCategoryIfPresent(DEFAULT_CATEGORY_UUID).orElseThrow();

View file

@ -4,6 +4,7 @@ import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.Value; import lombok.Value;
import lombok.experimental.NonFinal;
import lombok.extern.jackson.Jacksonized; import lombok.extern.jackson.Jacksonized;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
@ -37,16 +38,29 @@ public abstract class StorageElement {
@Getter @Getter
protected Instant lastModified; protected Instant lastModified;
@NonFinal
@Getter
protected boolean expanded;
public StorageElement( public StorageElement(
Path directory, UUID uuid, String name, Instant lastUsed, Instant lastModified, boolean dirty) { Path directory, UUID uuid, String name, Instant lastUsed, Instant lastModified, boolean expanded, boolean dirty) {
this.directory = directory; this.directory = directory;
this.uuid = uuid; this.uuid = uuid;
this.name = name; this.name = name;
this.lastUsed = lastUsed; this.lastUsed = lastUsed;
this.lastModified = lastModified; this.lastModified = lastModified;
this.expanded = expanded;
this.dirty = dirty; this.dirty = dirty;
} }
public void setExpanded(boolean expanded) {
var changed = expanded != this.expanded;
this.expanded = expanded;
if (changed) {
notifyUpdate(false, true);
}
}
public abstract Path[] getShareableFiles(); public abstract Path[] getShareableFiles();
public void notifyUpdate(boolean used, boolean modified) { public void notifyUpdate(boolean used, boolean modified) {