mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-21 23:20:23 +00:00
Improve store styling
This commit is contained in:
parent
1e714e2c4a
commit
1ba5f7cf2a
9 changed files with 90 additions and 59 deletions
|
@ -36,23 +36,25 @@ public class ListBoxViewComp<T> extends Comp<CompStructure<ScrollPane>> {
|
|||
public CompStructure<ScrollPane> createBase() {
|
||||
Map<T, Region> cache = new HashMap<>();
|
||||
|
||||
VBox listView = new VBox();
|
||||
listView.setFocusTraversable(false);
|
||||
VBox vbox = new VBox();
|
||||
vbox.getStyleClass().add("content");
|
||||
vbox.setFocusTraversable(false);
|
||||
|
||||
refresh(listView, shown, all, cache, false);
|
||||
listView.requestLayout();
|
||||
refresh(vbox, shown, all, cache, false);
|
||||
vbox.requestLayout();
|
||||
|
||||
shown.addListener((ListChangeListener<? super T>) (c) -> {
|
||||
refresh(listView, c.getList(), all, cache, true);
|
||||
refresh(vbox, c.getList(), all, cache, true);
|
||||
});
|
||||
|
||||
all.addListener((ListChangeListener<? super T>) c -> {
|
||||
cache.keySet().retainAll(c.getList());
|
||||
});
|
||||
|
||||
var scroll = new ScrollPane(listView);
|
||||
var scroll = new ScrollPane(vbox);
|
||||
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
|
||||
scroll.setFitToWidth(true);
|
||||
scroll.getStyleClass().add("list-box-view-comp");
|
||||
|
||||
return new SimpleCompStructure<>(scroll);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,12 @@ import java.util.ArrayList;
|
|||
|
||||
public abstract class StoreEntryComp extends SimpleComp {
|
||||
|
||||
public static Comp<?> customSection(StoreEntryWrapper e) {
|
||||
var prov = e.getEntry().getProvider();
|
||||
public static Comp<?> customSection(StoreSection e) {
|
||||
var prov = e.getWrapper().getEntry().getProvider();
|
||||
if (prov != null) {
|
||||
return prov.customDisplay(e);
|
||||
} else {
|
||||
return new StandardStoreEntryComp(e, null);
|
||||
return new StandardStoreEntryComp(e.getWrapper(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ public class StoreEntryListComp extends SimpleComp {
|
|||
.map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
||||
var content = new ListBoxViewComp<>(filtered, topLevel.getChildren(), (StoreSection e) -> {
|
||||
var custom = StoreSection.customSection(e).hgrow();
|
||||
return new HorizontalComp(List.of(Comp.spacer(20), custom, Comp.spacer(20))).styleClass("top");
|
||||
}).apply(struc -> ((Region) struc.get().getContent()).setPadding(new Insets(20, 0, 20, 0)));
|
||||
return new HorizontalComp(List.of(Comp.spacer(10), custom, Comp.spacer(10))).styleClass("top");
|
||||
}).apply(struc -> ((Region) struc.get().getContent()).setPadding(new Insets(10, 0, 10, 0)));
|
||||
return content.styleClass("store-list-comp");
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@ import io.xpipe.app.comp.storage.StorageFilter;
|
|||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||
import io.xpipe.app.storage.DataStorage;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.value.ObservableBooleanValue;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import lombok.Value;
|
||||
|
@ -19,12 +22,30 @@ public class StoreSection implements StorageFilter.Filterable {
|
|||
if (prov != null) {
|
||||
return prov.customContainer(e);
|
||||
} else {
|
||||
return new StoreEntrySectionComp(e);
|
||||
return new StoreSectionComp(e);
|
||||
}
|
||||
}
|
||||
|
||||
StoreEntryWrapper wrapper;
|
||||
ObservableList<StoreSection> children;
|
||||
int depth;
|
||||
ObservableBooleanValue showDetails;
|
||||
|
||||
public StoreSection(StoreEntryWrapper wrapper, ObservableList<StoreSection> children, int depth) {
|
||||
this.wrapper = wrapper;
|
||||
this.children = children;
|
||||
this.depth = depth;
|
||||
if (wrapper != null) {
|
||||
this.showDetails = Bindings.createBooleanBinding(
|
||||
() -> {
|
||||
return wrapper.getExpanded().get() || children.size() == 0;
|
||||
},
|
||||
wrapper.getExpanded(),
|
||||
children);
|
||||
} else {
|
||||
this.showDetails = new SimpleBooleanProperty(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Comparator<StoreSection> COMPARATOR = Comparator.<StoreSection, Instant>comparing(
|
||||
o -> o.wrapper.getEntry().getState().isUsable()
|
||||
|
@ -36,19 +57,19 @@ public class StoreSection implements StorageFilter.Filterable {
|
|||
|
||||
public static StoreSection createTopLevel() {
|
||||
var topLevel = BindingsHelper.mappedContentBinding(
|
||||
StoreViewState.get().getAllEntries(), storeEntryWrapper -> create(storeEntryWrapper));
|
||||
StoreViewState.get().getAllEntries(), storeEntryWrapper -> create(storeEntryWrapper, 1));
|
||||
var filtered = BindingsHelper.filteredContentBinding(topLevel, section -> {
|
||||
return DataStorage.get()
|
||||
.getParent(section.getWrapper().getEntry(), true)
|
||||
.isEmpty();
|
||||
});
|
||||
var ordered = BindingsHelper.orderedContentBinding(filtered, COMPARATOR);
|
||||
return new StoreSection(null, ordered);
|
||||
return new StoreSection(null, ordered, 0);
|
||||
}
|
||||
|
||||
private static StoreSection create(StoreEntryWrapper e) {
|
||||
private static StoreSection create(StoreEntryWrapper e, int depth) {
|
||||
if (!e.getEntry().getState().isUsable()) {
|
||||
return new StoreSection(e, FXCollections.observableArrayList());
|
||||
return new StoreSection(e, FXCollections.observableArrayList(), depth);
|
||||
}
|
||||
|
||||
var filtered =
|
||||
|
@ -58,9 +79,9 @@ public class StoreSection implements StorageFilter.Filterable {
|
|||
.map(found -> found.equals(e.getEntry()))
|
||||
.orElse(false);
|
||||
});
|
||||
var children = BindingsHelper.mappedContentBinding(filtered, entry1 -> create(entry1));
|
||||
var children = BindingsHelper.mappedContentBinding(filtered, entry1 -> create(entry1, depth + 1));
|
||||
var ordered = BindingsHelper.orderedContentBinding(children, COMPARATOR);
|
||||
return new StoreSection(e, ordered);
|
||||
return new StoreSection(e, ordered, depth);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.comp.storage.store;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.comp.base.ListBoxViewComp;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.CompStructure;
|
||||
|
@ -12,24 +11,27 @@ import io.xpipe.app.fxcomps.util.BindingsHelper;
|
|||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.css.PseudoClass;
|
||||
import javafx.scene.layout.*;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Priority;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StoreEntrySectionComp extends Comp<CompStructure<VBox>> {
|
||||
public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||
|
||||
private static final PseudoClass ODD = PseudoClass.getPseudoClass("odd-depth");
|
||||
private static final PseudoClass EVEN = PseudoClass.getPseudoClass("even-depth");
|
||||
public static final PseudoClass EXPANDED = PseudoClass.getPseudoClass("expanded");
|
||||
|
||||
private final StoreSection section;
|
||||
|
||||
public StoreEntrySectionComp(StoreSection section) {
|
||||
public StoreSectionComp(StoreSection section) {
|
||||
this.section = section;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompStructure<VBox> createBase() {
|
||||
var root = StandardStoreEntryComp.customSection(section.getWrapper()).apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS));
|
||||
var root = StandardStoreEntryComp.customSection(section).apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS));
|
||||
var button = new IconButtonComp(
|
||||
Bindings.createStringBinding(
|
||||
() -> section.getWrapper().getExpanded().get()
|
||||
|
@ -57,15 +59,7 @@ public class StoreEntrySectionComp extends Comp<CompStructure<VBox>> {
|
|||
.map(s -> (storeEntrySection -> storeEntrySection.shouldShow(s))));
|
||||
var content = new ListBoxViewComp<>(shown, all, (StoreSection e) -> {
|
||||
return StoreSection.customSection(e).apply(GrowAugment.create(true, false));
|
||||
})
|
||||
.apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS))
|
||||
.apply(struc -> struc.get().backgroundProperty().set(Background.fill(Color.color(0, 0, 0, 0.01))));
|
||||
var spacer = Comp.of(() -> {
|
||||
var padding = new Region();
|
||||
padding.setMinWidth(25);
|
||||
padding.setMaxWidth(25);
|
||||
return padding;
|
||||
});
|
||||
}).hgrow();
|
||||
|
||||
var expanded = Bindings.createBooleanBinding(() -> {
|
||||
return section.getWrapper().getExpanded().get() && section.getChildren().size() > 0;
|
||||
|
@ -75,18 +69,20 @@ public class StoreEntrySectionComp extends Comp<CompStructure<VBox>> {
|
|||
new HorizontalComp(topEntryList)
|
||||
.apply(struc -> struc.get().setFillHeight(true)),
|
||||
Comp.separator().visible(expanded),
|
||||
new HorizontalComp(List.of(spacer, content))
|
||||
new HorizontalComp(List.of(content))
|
||||
.styleClass("content")
|
||||
.apply(struc -> struc.get().setFillHeight(true))
|
||||
.hide(BindingsHelper.persist(Bindings.or(
|
||||
Bindings.not(section.getWrapper().getExpanded()),
|
||||
Bindings.size(section.getChildren()).isEqualTo(0))))))
|
||||
.styleClass("store-entry-section-comp")
|
||||
.styleClass(Styles.ELEVATED_1)
|
||||
.apply(struc -> {
|
||||
struc.get().setFillWidth(true);
|
||||
SimpleChangeListener.apply(expanded, val -> {
|
||||
struc.get().pseudoClassStateChanged(EXPANDED, val);
|
||||
});
|
||||
struc.get().pseudoClassStateChanged(EVEN, section.getDepth() % 2 == 0);
|
||||
struc.get().pseudoClassStateChanged(ODD, section.getDepth() % 2 != 0);
|
||||
})
|
||||
.createStructure();
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package io.xpipe.app.comp.storage.store;
|
||||
|
||||
import atlantafx.base.theme.Styles;
|
||||
import io.xpipe.app.fxcomps.Comp;
|
||||
import io.xpipe.app.fxcomps.SimpleComp;
|
||||
import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||
|
@ -14,8 +13,8 @@ public class StoreSidebarComp extends SimpleComp {
|
|||
@Override
|
||||
protected Region createSimple() {
|
||||
var sideBar = new VerticalComp(List.of(
|
||||
new StoreEntryListHeaderComp().styleClass(Styles.ELEVATED_1),
|
||||
new StoreCreationBarComp().styleClass(Styles.ELEVATED_1),
|
||||
new StoreEntryListHeaderComp(),
|
||||
new StoreCreationBarComp(),
|
||||
Comp.of(() -> new Region()).styleClass("bar").styleClass("filler-bar")));
|
||||
sideBar.apply(s -> VBox.setVgrow(s.get().getChildren().get(2), Priority.ALWAYS));
|
||||
sideBar.styleClass("sidebar");
|
||||
|
|
|
@ -3,7 +3,7 @@ package io.xpipe.app.ext;
|
|||
import io.xpipe.app.comp.base.MarkdownComp;
|
||||
import io.xpipe.app.comp.base.SystemStateComp;
|
||||
import io.xpipe.app.comp.storage.store.StandardStoreEntryComp;
|
||||
import io.xpipe.app.comp.storage.store.StoreEntrySectionComp;
|
||||
import io.xpipe.app.comp.storage.store.StoreSectionComp;
|
||||
import io.xpipe.app.comp.storage.store.StoreEntryWrapper;
|
||||
import io.xpipe.app.comp.storage.store.StoreSection;
|
||||
import io.xpipe.app.core.AppI18n;
|
||||
|
@ -34,12 +34,12 @@ public interface DataStoreProvider {
|
|||
}
|
||||
}
|
||||
|
||||
default Comp<?> customDisplay(StoreEntryWrapper w) {
|
||||
return new StandardStoreEntryComp(w, null);
|
||||
default Comp<?> customDisplay(StoreSection s) {
|
||||
return new StandardStoreEntryComp(s.getWrapper(), null);
|
||||
}
|
||||
|
||||
default Comp<?> customContainer(StoreSection section) {
|
||||
return new StoreEntrySectionComp(section);
|
||||
return new StoreSectionComp(section);
|
||||
}
|
||||
|
||||
default String failureInfo() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
.bar {
|
||||
-fx-padding: 0.8em 1.0em 0.8em 1.0em;
|
||||
-fx-background-color: -color-bg-subtle;
|
||||
-fx-border-color: -color-neutral-emphasis;
|
||||
-fx-border-color: -color-border-default;
|
||||
-fx-effect: dropshadow(three-pass-box, -color-shadow-default, 8px, 0.5, 0, 1);
|
||||
}
|
||||
|
||||
.store-header-bar {
|
||||
|
@ -25,7 +26,7 @@
|
|||
}
|
||||
|
||||
.sidebar {
|
||||
-fx-spacing: 5px;
|
||||
-fx-spacing: 0.75em;
|
||||
}
|
||||
|
||||
.bar .button-comp {
|
||||
|
|
|
@ -32,21 +32,19 @@
|
|||
}
|
||||
|
||||
.store-list-comp .top {
|
||||
-fx-border-width: 0 0 1em 0;
|
||||
-fx-background-insets: 0 0 1em 0;
|
||||
-fx-border-width: 0 0 0.7em 0;
|
||||
-fx-background-insets: 0 0 0.7em 0;
|
||||
-fx-border-color: transparent;
|
||||
}
|
||||
|
||||
.store-list-comp .top:odd .store-entry-section-comp {
|
||||
-fx-background-color: -color-bg-subtle;
|
||||
}
|
||||
|
||||
.store-list-comp .top:even .store-entry-section-comp {
|
||||
-fx-background-color: -color-bg-overlay;
|
||||
}
|
||||
|
||||
.store-list-comp .store-entry-section-comp {
|
||||
.store-entry-section-comp:expanded:odd-depth {
|
||||
-fx-background-color: -color-bg-default;
|
||||
-fx-background-radius: 4px;
|
||||
}
|
||||
|
||||
.store-entry-section-comp:expanded:even-depth {
|
||||
-fx-background-color: -color-bg-subtle;
|
||||
-fx-background-radius: 4px;
|
||||
}
|
||||
|
||||
.store-entry-comp:hover {
|
||||
|
@ -62,21 +60,35 @@
|
|||
}
|
||||
|
||||
.store-entry-section-comp .separator {
|
||||
-fx-padding: 0 0.5em 0 0.5em;
|
||||
-fx-padding: 0 0.75em 0 0.75em;
|
||||
-fx-border-insets: 0px;
|
||||
}
|
||||
|
||||
.store-entry-section-comp > .content {
|
||||
-fx-padding: 5px 0 5px 25px;
|
||||
}
|
||||
|
||||
.store-entry-section-comp .separator .line {
|
||||
-fx-padding: 0;
|
||||
-fx-border-insets: 0px;
|
||||
-fx-background-color: -color-border-subtle;
|
||||
-fx-pref-height: 1;
|
||||
}
|
||||
|
||||
.store-entry-section-comp * {
|
||||
-fx-spacing: 0.5em;
|
||||
.top > .store-entry-section-comp {
|
||||
-fx-effect: dropshadow(three-pass-box, -color-shadow-default, 6px, 0.5, 0, 1);
|
||||
-fx-background-color: -color-bg-default;
|
||||
-fx-background-radius: 4px;
|
||||
}
|
||||
|
||||
.store-entry-section-comp:expanded {
|
||||
-fx-background-color: -color-bg-default;
|
||||
-fx-border-radius: 4px;
|
||||
-fx-border-width: 1px;
|
||||
-fx-border-color: -color-border-default;
|
||||
}
|
||||
|
||||
.store-entry-section-comp .list-box-view-comp .content {
|
||||
-fx-spacing: 0.2em;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue