mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 17:10:27 +00:00
Add quick access button
This commit is contained in:
parent
9abd19483f
commit
c4f0797960
15 changed files with 260 additions and 90 deletions
|
@ -6,6 +6,8 @@ import io.xpipe.app.comp.store.StoreSection;
|
||||||
import io.xpipe.app.comp.store.StoreSectionMiniComp;
|
import io.xpipe.app.comp.store.StoreSectionMiniComp;
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
import io.xpipe.app.comp.store.StoreViewState;
|
||||||
import io.xpipe.app.core.AppFont;
|
import io.xpipe.app.core.AppFont;
|
||||||
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
import io.xpipe.app.fxcomps.SimpleComp;
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
import io.xpipe.app.fxcomps.impl.FilterComp;
|
import io.xpipe.app.fxcomps.impl.FilterComp;
|
||||||
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
import io.xpipe.app.fxcomps.impl.HorizontalComp;
|
||||||
|
@ -23,6 +25,7 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.geometry.Point2D;
|
import javafx.geometry.Point2D;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.input.DragEvent;
|
import javafx.scene.input.DragEvent;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
@ -30,6 +33,8 @@ import javafx.scene.layout.VBox;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
final class BrowserBookmarkComp extends SimpleComp {
|
final class BrowserBookmarkComp extends SimpleComp {
|
||||||
|
@ -55,30 +60,11 @@ final class BrowserBookmarkComp extends SimpleComp {
|
||||||
};
|
};
|
||||||
var selectedCategory = new SimpleObjectProperty<>(
|
var selectedCategory = new SimpleObjectProperty<>(
|
||||||
StoreViewState.get().getActiveCategory().getValue());
|
StoreViewState.get().getActiveCategory().getValue());
|
||||||
var section = StoreSectionMiniComp.createList(
|
|
||||||
StoreSection.createTopLevel(
|
|
||||||
StoreViewState.get().getAllEntries(), storeEntryWrapper -> true, filterText, selectedCategory),
|
|
||||||
(s, comp) -> {
|
|
||||||
BooleanProperty busy = new SimpleBooleanProperty(false);
|
BooleanProperty busy = new SimpleBooleanProperty(false);
|
||||||
comp.disable(Bindings.createBooleanBinding(
|
Consumer<StoreEntryWrapper> action = w -> {
|
||||||
() -> {
|
|
||||||
return busy.get() || !applicable.test(s.getWrapper());
|
|
||||||
},
|
|
||||||
busy));
|
|
||||||
comp.apply(struc -> {
|
|
||||||
open.addListener((observable, oldValue, newValue) -> {
|
|
||||||
struc.get()
|
|
||||||
.pseudoClassStateChanged(
|
|
||||||
SELECTED,
|
|
||||||
newValue != null
|
|
||||||
&& newValue.getEntry()
|
|
||||||
.get()
|
|
||||||
.equals(s.getWrapper()
|
|
||||||
.getEntry()));
|
|
||||||
});
|
|
||||||
struc.get().setOnAction(event -> {
|
|
||||||
ThreadHelper.runFailableAsync(() -> {
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
var entry = s.getWrapper().getEntry();
|
var entry = w.getEntry();
|
||||||
if (!entry.getValidity().isUsable()) {
|
if (!entry.getValidity().isUsable()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -87,14 +73,27 @@ final class BrowserBookmarkComp extends SimpleComp {
|
||||||
model.openFileSystemAsync(entry.ref(), null, busy);
|
model.openFileSystemAsync(entry.ref(), null, busy);
|
||||||
} else if (entry.getStore() instanceof FixedHierarchyStore) {
|
} else if (entry.getStore() instanceof FixedHierarchyStore) {
|
||||||
BooleanScope.execute(busy, () -> {
|
BooleanScope.execute(busy, () -> {
|
||||||
s.getWrapper().refreshChildren();
|
w.refreshChildren();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
event.consume();
|
};
|
||||||
|
BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment = (s, comp) -> {
|
||||||
|
comp.disable(Bindings.createBooleanBinding(() -> {
|
||||||
|
return busy.get() || !applicable.test(s.getWrapper());
|
||||||
|
}, busy));
|
||||||
|
comp.apply(struc -> {
|
||||||
|
open.addListener((observable, oldValue, newValue) -> {
|
||||||
|
struc.get().pseudoClassStateChanged(SELECTED, newValue != null && newValue.getEntry().get().equals(s.getWrapper().getEntry()));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
|
var section = new StoreSectionMiniComp(
|
||||||
|
StoreSection.createTopLevel(
|
||||||
|
StoreViewState.get().getAllEntries(), storeEntryWrapper -> true, filterText, selectedCategory),
|
||||||
|
augment,
|
||||||
|
action,
|
||||||
true);
|
true);
|
||||||
var category = new DataStoreCategoryChoiceComp(
|
var category = new DataStoreCategoryChoiceComp(
|
||||||
StoreViewState.get().getAllConnectionsCategory(),
|
StoreViewState.get().getAllConnectionsCategory(),
|
||||||
|
|
|
@ -55,6 +55,11 @@ public class DenseStoreEntryComp extends StoreEntryComp {
|
||||||
return information;
|
return information;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFullSize() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
protected Region createContent() {
|
protected Region createContent() {
|
||||||
var grid = new GridPane();
|
var grid = new GridPane();
|
||||||
grid.setHgap(8);
|
grid.setHgap(8);
|
||||||
|
|
|
@ -12,6 +12,11 @@ public class StandardStoreEntryComp extends StoreEntryComp {
|
||||||
super(entry, content);
|
super(entry, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFullSize() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
protected Region createContent() {
|
protected Region createContent() {
|
||||||
var name = createName().createRegion();
|
var name = createName().createRegion();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,8 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract boolean isFullSize();
|
||||||
|
|
||||||
public static StoreEntryComp create(StoreEntryWrapper entry, Comp<?> content, boolean preferLarge) {
|
public static StoreEntryComp create(StoreEntryWrapper entry, Comp<?> content, boolean preferLarge) {
|
||||||
var forceCondensed = AppPrefs.get() != null
|
var forceCondensed = AppPrefs.get() != null
|
||||||
&& AppPrefs.get().condenseConnectionDisplay().get();
|
&& AppPrefs.get().condenseConnectionDisplay().get();
|
||||||
|
@ -64,7 +66,7 @@ public abstract class StoreEntryComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Comp<?> customSection(StoreSection e, boolean topLevel) {
|
public static StoreEntryComp customSection(StoreSection e, boolean topLevel) {
|
||||||
var prov = e.getWrapper().getEntry().getProvider();
|
var prov = e.getWrapper().getEntry().getProvider();
|
||||||
if (prov != null) {
|
if (prov != null) {
|
||||||
return prov.customEntryComp(e, topLevel);
|
return prov.customEntryComp(e, topLevel);
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package io.xpipe.app.comp.store;
|
||||||
|
|
||||||
|
import io.xpipe.app.fxcomps.SimpleComp;
|
||||||
|
import io.xpipe.app.fxcomps.impl.IconButtonComp;
|
||||||
|
import io.xpipe.app.fxcomps.impl.PrettyImageHelper;
|
||||||
|
import javafx.geometry.Side;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.ContextMenu;
|
||||||
|
import javafx.scene.control.Menu;
|
||||||
|
import javafx.scene.control.MenuItem;
|
||||||
|
import javafx.scene.layout.Region;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class StoreQuickAccessButtonComp extends SimpleComp {
|
||||||
|
|
||||||
|
private final StoreSection section;
|
||||||
|
private final Consumer<StoreEntryWrapper> action;
|
||||||
|
|
||||||
|
public StoreQuickAccessButtonComp(StoreSection section, Consumer<StoreEntryWrapper> action) {this.section = section;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Region createSimple() {
|
||||||
|
var button = new IconButtonComp("mdi2p-play-speed");
|
||||||
|
button.apply(struc -> {
|
||||||
|
struc.get().setOnAction(event -> {
|
||||||
|
showMenu(struc.get());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return button.createRegion();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMenu(Node anchor) {
|
||||||
|
var cm = createMenu();
|
||||||
|
if (cm == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cm.show(anchor, Side.RIGHT, 0, 0);
|
||||||
|
|
||||||
|
// App.getApp().getStage().getScene().addEventFilter(MouseEvent.MOUSE_MOVED, event -> {
|
||||||
|
// var stages = Stage.getWindows().stream().filter(window -> window instanceof ContextMenu).toList();
|
||||||
|
// var hovered = stages.stream().anyMatch(window -> window.getScene().getRoot().hoverProperty().get());
|
||||||
|
// if (!hovered) {
|
||||||
|
// stages.forEach(window -> window.hide());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
private ContextMenu createMenu() {
|
||||||
|
if (section.getShownChildren().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cm = new ContextMenu();
|
||||||
|
cm.setAutoHide(true);
|
||||||
|
cm.getStyleClass().add("condensed");
|
||||||
|
Menu menu = (Menu) recurse(cm, section);
|
||||||
|
cm.getItems().addAll(menu.getItems());
|
||||||
|
return cm;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MenuItem recurse(ContextMenu contextMenu, StoreSection section) {
|
||||||
|
var c = section.getShownChildren();
|
||||||
|
var w = section.getWrapper();
|
||||||
|
var graphic = w.getEntry()
|
||||||
|
.getProvider()
|
||||||
|
.getDisplayIconFileName(w.getEntry().getStore());
|
||||||
|
if (c.isEmpty()) {
|
||||||
|
var item = new MenuItem(w.getName().getValue(), PrettyImageHelper.ofFixedSquare(graphic, 16).createRegion());
|
||||||
|
item.setOnAction(event -> {
|
||||||
|
action.accept(w);
|
||||||
|
contextMenu.hide();
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new ArrayList<MenuItem>();
|
||||||
|
for (StoreSection sub : c) {
|
||||||
|
if (!sub.getWrapper().getValidity().getValue().isUsable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
items.add(recurse(contextMenu, sub));
|
||||||
|
}
|
||||||
|
var m = new Menu(w.getName().getValue(), PrettyImageHelper.ofFixedSquare(graphic, 16).createRegion());
|
||||||
|
m.getItems().setAll(items);
|
||||||
|
m.setOnAction(event -> {
|
||||||
|
if (event.getTarget() == m) {
|
||||||
|
action.accept(w);
|
||||||
|
contextMenu.hide();
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,15 +10,15 @@ import io.xpipe.app.fxcomps.impl.VerticalComp;
|
||||||
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
import io.xpipe.app.fxcomps.util.BindingsHelper;
|
||||||
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
import io.xpipe.app.fxcomps.util.SimpleChangeListener;
|
||||||
import io.xpipe.app.storage.DataStoreColor;
|
import io.xpipe.app.storage.DataStoreColor;
|
||||||
|
import io.xpipe.app.util.ThreadHelper;
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.scene.layout.HBox;
|
|
||||||
import javafx.scene.layout.Priority;
|
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||||
|
|
||||||
|
@ -37,9 +37,32 @@ public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompStructure<VBox> createBase() {
|
public CompStructure<VBox> createBase() {
|
||||||
var root = StoreEntryComp.customSection(section, topLevel)
|
var expanded = BindingsHelper.persist(Bindings.createBooleanBinding(
|
||||||
.apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS));
|
() -> {
|
||||||
var button = new IconButtonComp(
|
return section.getWrapper().getExpanded().get()
|
||||||
|
&& section.getShownChildren().size() > 0;
|
||||||
|
},
|
||||||
|
section.getWrapper().getExpanded(),
|
||||||
|
section.getShownChildren()));
|
||||||
|
var root = StoreEntryComp.customSection(section, topLevel);
|
||||||
|
|
||||||
|
var quickAccessDisabled = BindingsHelper.persist(Bindings.createBooleanBinding(
|
||||||
|
() -> {
|
||||||
|
return section.getShownChildren().isEmpty();
|
||||||
|
},
|
||||||
|
section.getShownChildren()));
|
||||||
|
Consumer<StoreEntryWrapper> quickAccessAction = w -> {
|
||||||
|
ThreadHelper.runFailableAsync(() -> {
|
||||||
|
w.executeDefaultAction();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var quickAccessButton = new StoreQuickAccessButtonComp(section, quickAccessAction).vgrow()
|
||||||
|
.styleClass("quick-access-button")
|
||||||
|
.apply(struc -> struc.get().setMinWidth(30))
|
||||||
|
.apply(struc -> struc.get().setPrefWidth(30))
|
||||||
|
.maxHeight(100)
|
||||||
|
.disable(quickAccessDisabled);
|
||||||
|
var expandButton = new IconButtonComp(
|
||||||
Bindings.createStringBinding(
|
Bindings.createStringBinding(
|
||||||
() -> section.getWrapper().getExpanded().get()
|
() -> section.getWrapper().getExpanded().get()
|
||||||
&& section.getShownChildren().size() > 0
|
&& section.getShownChildren().size() > 0
|
||||||
|
@ -60,9 +83,16 @@ public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||||
section.getWrapper().getName()))
|
section.getWrapper().getName()))
|
||||||
.disable(BindingsHelper.persist(
|
.disable(BindingsHelper.persist(
|
||||||
Bindings.size(section.getShownChildren()).isEqualTo(0)))
|
Bindings.size(section.getShownChildren()).isEqualTo(0)))
|
||||||
.grow(false, true)
|
.styleClass("expand-button")
|
||||||
.styleClass("expand-button");
|
.maxHeight(100)
|
||||||
List<Comp<?>> topEntryList = List.of(button, root);
|
.vgrow();
|
||||||
|
var buttonList = new ArrayList<Comp<?>>();
|
||||||
|
if (root.isFullSize()) {
|
||||||
|
buttonList.add(quickAccessButton);
|
||||||
|
}
|
||||||
|
buttonList.add(expandButton);
|
||||||
|
var buttons = new VerticalComp(buttonList);
|
||||||
|
List<Comp<?>> topEntryList = List.of(buttons, root.hgrow());
|
||||||
|
|
||||||
// Optimization for large sections. If there are more than 20 children, only add the nodes to the scene if the
|
// Optimization for large sections. If there are more than 20 children, only add the nodes to the scene if the
|
||||||
// section is actually expanded
|
// section is actually expanded
|
||||||
|
@ -78,14 +108,6 @@ public class StoreSectionComp extends Comp<CompStructure<VBox>> {
|
||||||
.minHeight(0)
|
.minHeight(0)
|
||||||
.hgrow();
|
.hgrow();
|
||||||
|
|
||||||
var expanded = Bindings.createBooleanBinding(
|
|
||||||
() -> {
|
|
||||||
return section.getWrapper().getExpanded().get()
|
|
||||||
&& section.getShownChildren().size() > 0;
|
|
||||||
},
|
|
||||||
section.getWrapper().getExpanded(),
|
|
||||||
section.getShownChildren());
|
|
||||||
|
|
||||||
return new VerticalComp(List.of(
|
return new VerticalComp(List.of(
|
||||||
new HorizontalComp(topEntryList)
|
new HorizontalComp(topEntryList)
|
||||||
.apply(struc -> struc.get().setFillHeight(true)),
|
.apply(struc -> struc.get().setFillHeight(true)),
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
||||||
|
|
||||||
|
@ -35,22 +36,19 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
||||||
|
|
||||||
private final StoreSection section;
|
private final StoreSection section;
|
||||||
private final BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment;
|
private final BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment;
|
||||||
|
private final Consumer<StoreEntryWrapper> action;
|
||||||
private final boolean condensedStyle;
|
private final boolean condensedStyle;
|
||||||
|
|
||||||
public StoreSectionMiniComp(
|
public StoreSectionMiniComp(
|
||||||
StoreSection section,
|
StoreSection section,
|
||||||
BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment,
|
BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment, Consumer<StoreEntryWrapper> action,
|
||||||
boolean condensedStyle) {
|
boolean condensedStyle) {
|
||||||
this.section = section;
|
this.section = section;
|
||||||
this.augment = augment;
|
this.augment = augment;
|
||||||
|
this.action = action;
|
||||||
this.condensedStyle = condensedStyle;
|
this.condensedStyle = condensedStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Comp<?> createList(
|
|
||||||
StoreSection top, BiConsumer<StoreSection, Comp<CompStructure<Button>>> augment, boolean condensedStyle) {
|
|
||||||
return new StoreSectionMiniComp(top, augment, condensedStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompStructure<VBox> createBase() {
|
public CompStructure<VBox> createBase() {
|
||||||
var list = new ArrayList<Comp<?>>();
|
var list = new ArrayList<Comp<?>>();
|
||||||
|
@ -71,6 +69,12 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
||||||
.apply(struc -> {
|
.apply(struc -> {
|
||||||
struc.get().setAlignment(Pos.CENTER_LEFT);
|
struc.get().setAlignment(Pos.CENTER_LEFT);
|
||||||
})
|
})
|
||||||
|
.apply(struc -> {
|
||||||
|
struc.get().setOnAction(event -> {
|
||||||
|
action.accept(section.getWrapper());
|
||||||
|
event.consume();
|
||||||
|
});
|
||||||
|
})
|
||||||
.grow(true, false)
|
.grow(true, false)
|
||||||
.apply(struc -> struc.get().setMnemonicParsing(false))
|
.apply(struc -> struc.get().setMnemonicParsing(false))
|
||||||
.styleClass("item");
|
.styleClass("item");
|
||||||
|
@ -99,8 +103,27 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
||||||
Bindings.size(section.getAllChildren()).isEqualTo(0)))
|
Bindings.size(section.getAllChildren()).isEqualTo(0)))
|
||||||
.grow(false, true)
|
.grow(false, true)
|
||||||
.styleClass("expand-button");
|
.styleClass("expand-button");
|
||||||
List<Comp<?>> topEntryList = List.of(button, root);
|
|
||||||
list.add(new HorizontalComp(topEntryList).apply(struc -> struc.get().setFillHeight(true)));
|
var quickAccessDisabled = BindingsHelper.persist(Bindings.createBooleanBinding(
|
||||||
|
() -> {
|
||||||
|
return section.getShownChildren().isEmpty();
|
||||||
|
},
|
||||||
|
section.getShownChildren()));
|
||||||
|
Consumer<StoreEntryWrapper> quickAccessAction = w -> {
|
||||||
|
action.accept(w);
|
||||||
|
};
|
||||||
|
var quickAccessButton = new StoreQuickAccessButtonComp(section, quickAccessAction).vgrow()
|
||||||
|
.styleClass("quick-access-button")
|
||||||
|
.maxHeight(100)
|
||||||
|
.disable(quickAccessDisabled);
|
||||||
|
|
||||||
|
var buttonList = new ArrayList<Comp<?>>();
|
||||||
|
buttonList.add(button);
|
||||||
|
buttonList.add(root);
|
||||||
|
if (section.getDepth() == 1) {
|
||||||
|
buttonList.add(quickAccessButton);
|
||||||
|
}
|
||||||
|
list.add(new HorizontalComp(buttonList).apply(struc -> struc.get().setFillHeight(true)));
|
||||||
} else {
|
} else {
|
||||||
expanded = new SimpleBooleanProperty(true);
|
expanded = new SimpleBooleanProperty(true);
|
||||||
}
|
}
|
||||||
|
@ -115,7 +138,7 @@ public class StoreSectionMiniComp extends Comp<CompStructure<VBox>> {
|
||||||
section.getAllChildren())
|
section.getAllChildren())
|
||||||
: section.getShownChildren();
|
: section.getShownChildren();
|
||||||
var content = new ListBoxViewComp<>(listSections, section.getAllChildren(), (StoreSection e) -> {
|
var content = new ListBoxViewComp<>(listSections, section.getAllChildren(), (StoreSection e) -> {
|
||||||
return new StoreSectionMiniComp(e, this.augment, this.condensedStyle);
|
return new StoreSectionMiniComp(e, this.augment, this.action, this.condensedStyle);
|
||||||
})
|
})
|
||||||
.minHeight(0)
|
.minHeight(0)
|
||||||
.hgrow();
|
.hgrow();
|
||||||
|
|
|
@ -57,11 +57,11 @@ public interface DataStoreProvider {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
default Comp<?> customEntryComp(StoreSection s, boolean preferLarge) {
|
default StoreEntryComp customEntryComp(StoreSection s, boolean preferLarge) {
|
||||||
return StoreEntryComp.create(s.getWrapper(), null, preferLarge);
|
return StoreEntryComp.create(s.getWrapper(), null, preferLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
default Comp<?> customSectionComp(StoreSection section, boolean topLevel) {
|
default StoreSectionComp customSectionComp(StoreSection section, boolean topLevel) {
|
||||||
return new StoreSectionComp(section, topLevel);
|
return new StoreSectionComp(section, topLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,20 +87,18 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
|
||||||
&& e.getValidity().isUsable()
|
&& e.getValidity().isUsable()
|
||||||
&& (applicableCheck == null || applicableCheck.test(e.ref()));
|
&& (applicableCheck == null || applicableCheck.test(e.ref()));
|
||||||
};
|
};
|
||||||
var section = StoreSectionMiniComp.createList(
|
var section = new StoreSectionMiniComp(
|
||||||
StoreSection.createTopLevel(
|
StoreSection.createTopLevel(
|
||||||
StoreViewState.get().getAllEntries(), applicable, filterText, selectedCategory),
|
StoreViewState.get().getAllEntries(), applicable, filterText, selectedCategory),
|
||||||
(s, comp) -> {
|
(s, comp) -> {
|
||||||
comp.apply(struc -> struc.get().setOnAction(event -> {
|
|
||||||
selected.setValue(s.getWrapper().getEntry().ref());
|
|
||||||
popover.hide();
|
|
||||||
event.consume();
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (!applicable.test(s.getWrapper())) {
|
if (!applicable.test(s.getWrapper())) {
|
||||||
comp.disable(new SimpleBooleanProperty(true));
|
comp.disable(new SimpleBooleanProperty(true));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
storeEntryWrapper -> {
|
||||||
|
selected.setValue(storeEntryWrapper.getEntry().ref());
|
||||||
|
popover.hide();
|
||||||
|
},
|
||||||
false);
|
false);
|
||||||
var category = new DataStoreCategoryChoiceComp(
|
var category = new DataStoreCategoryChoiceComp(
|
||||||
initialCategory != null ? initialCategory.getRoot() : null,
|
initialCategory != null ? initialCategory.getRoot() : null,
|
||||||
|
|
|
@ -54,10 +54,11 @@ public class ErrorHandlerComp extends SimpleComp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unhandled platform exceptions usually means that we will have trouble displaying another window
|
// Unhandled platform exceptions usually means that we will have trouble displaying another window
|
||||||
if (event.isUnhandled() && Platform.isFxApplicationThread()) {
|
// Let's just hope that this is not the case
|
||||||
ErrorAction.ignore().handle(event);
|
// if (event.isUnhandled() && Platform.isFxApplicationThread()) {
|
||||||
return;
|
// ErrorAction.ignore().handle(event);
|
||||||
}
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
if (Platform.isFxApplicationThread()) {
|
if (Platform.isFxApplicationThread()) {
|
||||||
showAndWaitWithPlatformThread(event, forceWait);
|
showAndWaitWithPlatformThread(event, forceWait);
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
-fx-border-color: -color-border-default;
|
-fx-border-color: -color-border-default;
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-menu * .context-menu {
|
.context-menu * .context-menu, .context-menu.condensed {
|
||||||
-fx-padding: 0;
|
-fx-padding: 0;
|
||||||
-fx-background-radius: 0;
|
-fx-background-radius: 0;
|
||||||
-fx-border-radius: 0;
|
-fx-border-radius: 0;
|
||||||
|
|
|
@ -76,11 +76,11 @@
|
||||||
-fx-opacity: 1.0;
|
-fx-opacity: 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expand-button:hover, .expand-button:focused {
|
.expand-button:hover, .expand-button:focused, .quick-access-button:hover, .quick-access-button:focused {
|
||||||
-fx-background-color: -color-neutral-muted;
|
-fx-background-color: -color-neutral-muted;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expand-button:disabled {
|
.expand-button:disabled, .quick-access-button:disabled {
|
||||||
-fx-opacity: 0.2;
|
-fx-opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
-fx-padding: 0.25em 0.4em 0.25em 0.4em;
|
-fx-padding: 0.25em 0.4em 0.25em 0.4em;
|
||||||
-fx-border-color: transparent;
|
-fx-border-color: transparent;
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
|
-fx-background-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.store-section-mini-comp .item:hover, .store-section-mini-comp .item:focused {
|
.store-section-mini-comp .item:hover, .store-section-mini-comp .item:focused {
|
||||||
|
@ -44,6 +45,25 @@
|
||||||
-fx-opacity: 0.2;
|
-fx-opacity: 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.store-section-mini-comp.condensed .expand-button {
|
||||||
|
-fx-background-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-section-mini-comp .expand-button {
|
||||||
|
-fx-background-radius: 4 0 0 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-section-mini-comp .quick-access-button:hover, .store-section-mini-comp .quick-access-button:focused {
|
||||||
|
-fx-background-color: -color-neutral-muted;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-section-mini-comp .quick-access-button:disabled {
|
||||||
|
-fx-opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-section-mini-comp .quick-access-button {
|
||||||
|
-fx-background-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.store-section-mini-comp .separator {
|
.store-section-mini-comp .separator {
|
||||||
-fx-padding: 0 0.75em 0 0.75em;
|
-fx-padding: 0 0.75em 0 0.75em;
|
||||||
|
|
|
@ -3,10 +3,7 @@ package io.xpipe.ext.base.script;
|
||||||
import io.xpipe.app.comp.base.DropdownComp;
|
import io.xpipe.app.comp.base.DropdownComp;
|
||||||
import io.xpipe.app.comp.base.StoreToggleComp;
|
import io.xpipe.app.comp.base.StoreToggleComp;
|
||||||
import io.xpipe.app.comp.base.SystemStateComp;
|
import io.xpipe.app.comp.base.SystemStateComp;
|
||||||
import io.xpipe.app.comp.store.DenseStoreEntryComp;
|
import io.xpipe.app.comp.store.*;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
|
||||||
import io.xpipe.app.ext.DataStoreProvider;
|
import io.xpipe.app.ext.DataStoreProvider;
|
||||||
import io.xpipe.app.ext.GuiDialog;
|
import io.xpipe.app.ext.GuiDialog;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
|
@ -25,7 +22,7 @@ import java.util.List;
|
||||||
public class ScriptGroupStoreProvider implements DataStoreProvider {
|
public class ScriptGroupStoreProvider implements DataStoreProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
ScriptGroupStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
||||||
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
||||||
return new DenseStoreEntryComp(sec.getWrapper(), true, null);
|
return new DenseStoreEntryComp(sec.getWrapper(), true, null);
|
||||||
|
|
|
@ -4,10 +4,7 @@ import io.xpipe.app.comp.base.DropdownComp;
|
||||||
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
import io.xpipe.app.comp.base.IntegratedTextAreaComp;
|
||||||
import io.xpipe.app.comp.base.StoreToggleComp;
|
import io.xpipe.app.comp.base.StoreToggleComp;
|
||||||
import io.xpipe.app.comp.base.SystemStateComp;
|
import io.xpipe.app.comp.base.SystemStateComp;
|
||||||
import io.xpipe.app.comp.store.DenseStoreEntryComp;
|
import io.xpipe.app.comp.store.*;
|
||||||
import io.xpipe.app.comp.store.StoreEntryWrapper;
|
|
||||||
import io.xpipe.app.comp.store.StoreSection;
|
|
||||||
import io.xpipe.app.comp.store.StoreViewState;
|
|
||||||
import io.xpipe.app.core.AppExtensionManager;
|
import io.xpipe.app.core.AppExtensionManager;
|
||||||
import io.xpipe.app.ext.DataStoreProvider;
|
import io.xpipe.app.ext.DataStoreProvider;
|
||||||
import io.xpipe.app.ext.GuiDialog;
|
import io.xpipe.app.ext.GuiDialog;
|
||||||
|
@ -55,7 +52,7 @@ public class SimpleScriptStoreProvider implements DataStoreProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Comp<?> customEntryComp(StoreSection sec, boolean preferLarge) {
|
public StoreEntryComp customEntryComp(StoreSection sec, boolean preferLarge) {
|
||||||
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
SimpleScriptStore s = sec.getWrapper().getEntry().getStore().asNeeded();
|
||||||
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
if (sec.getWrapper().getValidity().getValue() != DataStoreEntry.Validity.COMPLETE) {
|
||||||
return new DenseStoreEntryComp(sec.getWrapper(), true, null);
|
return new DenseStoreEntryComp(sec.getWrapper(), true, null);
|
||||||
|
|
Loading…
Reference in a new issue