mirror of
https://github.com/xpipe-io/xpipe.git
synced 2024-11-25 09:00:26 +00:00
Rework filter field
This commit is contained in:
parent
3ef26d0b0b
commit
c1b2086e90
6 changed files with 42 additions and 87 deletions
|
@ -27,11 +27,11 @@ import javafx.scene.text.TextAlignment;
|
||||||
|
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
public class StoreEntryListStatusComp extends SimpleComp {
|
public class StoreEntryListOverviewComp extends SimpleComp {
|
||||||
|
|
||||||
private final Property<StoreSortMode> sortMode;
|
private final Property<StoreSortMode> sortMode;
|
||||||
|
|
||||||
public StoreEntryListStatusComp() {
|
public StoreEntryListOverviewComp() {
|
||||||
this.sortMode = new SimpleObjectProperty<>();
|
this.sortMode = new SimpleObjectProperty<>();
|
||||||
StoreViewState.get().getActiveCategory().subscribe(val -> {
|
StoreViewState.get().getActiveCategory().subscribe(val -> {
|
||||||
sortMode.setValue(val.getSortMode().getValue());
|
sortMode.setValue(val.getSortMode().getValue());
|
||||||
|
@ -110,30 +110,20 @@ public class StoreEntryListStatusComp extends SimpleComp {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
var filter = new FilterComp(StoreViewState.get().getFilterString());
|
var filter = new FilterComp(StoreViewState.get().getFilterString());
|
||||||
filter.apply(struc -> struc.get().sceneProperty().addListener((observable, oldValue, newValue) -> {
|
|
||||||
if (newValue != null) {
|
|
||||||
struc.getText().requestFocus();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
var f = filter.createRegion();
|
var f = filter.createRegion();
|
||||||
var hbox = new HBox(createButtons(), f);
|
var buttons = createAddButton();
|
||||||
|
var hbox = new HBox(buttons, f);
|
||||||
|
f.prefHeightProperty().bind(buttons.heightProperty());
|
||||||
hbox.setSpacing(8);
|
hbox.setSpacing(8);
|
||||||
hbox.setAlignment(Pos.CENTER);
|
hbox.setAlignment(Pos.CENTER);
|
||||||
HBox.setHgrow(f, Priority.ALWAYS);
|
HBox.setHgrow(f, Priority.ALWAYS);
|
||||||
|
|
||||||
f.getStyleClass().add("filter-bar");
|
f.getStyleClass().add("filter-bar");
|
||||||
if (OsType.getLocal().equals(OsType.MACOS)) {
|
|
||||||
f.setPadding(new Insets(-2, 0, -2, 0));
|
|
||||||
} else {
|
|
||||||
f.setPadding(new Insets(-3, 0, -3, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
AppFont.medium(hbox);
|
AppFont.medium(hbox);
|
||||||
return hbox;
|
return hbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Region createButtons() {
|
private Region createAddButton() {
|
||||||
var menu = new MenuButton(null, new FontIcon("mdi2p-plus-thick"));
|
var menu = new MenuButton(null, new FontIcon("mdi2p-plus-thick"));
|
||||||
menu.textProperty().bind(AppI18n.observable("addConnections"));
|
menu.textProperty().bind(AppI18n.observable("addConnections"));
|
||||||
menu.setAlignment(Pos.CENTER);
|
menu.setAlignment(Pos.CENTER);
|
|
@ -14,7 +14,7 @@ public class StoreSidebarComp extends SimpleComp {
|
||||||
@Override
|
@Override
|
||||||
protected Region createSimple() {
|
protected Region createSimple() {
|
||||||
var sideBar = new VerticalComp(List.of(
|
var sideBar = new VerticalComp(List.of(
|
||||||
new StoreEntryListStatusComp()
|
new StoreEntryListOverviewComp()
|
||||||
.styleClass("color-box")
|
.styleClass("color-box")
|
||||||
.styleClass("gray")
|
.styleClass("gray")
|
||||||
.styleClass("bar"),
|
.styleClass("bar"),
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package io.xpipe.app.fxcomps.impl;
|
package io.xpipe.app.fxcomps.impl;
|
||||||
|
|
||||||
|
import atlantafx.base.controls.Popover;
|
||||||
|
import atlantafx.base.theme.Styles;
|
||||||
import io.xpipe.app.comp.base.ButtonComp;
|
import io.xpipe.app.comp.base.ButtonComp;
|
||||||
import io.xpipe.app.comp.store.*;
|
import io.xpipe.app.comp.store.*;
|
||||||
import io.xpipe.app.core.AppFont;
|
import io.xpipe.app.core.AppFont;
|
||||||
|
@ -13,7 +15,6 @@ import io.xpipe.app.util.DataStoreCategoryChoiceComp;
|
||||||
import io.xpipe.core.store.DataStore;
|
import io.xpipe.core.store.DataStore;
|
||||||
import io.xpipe.core.store.LocalStore;
|
import io.xpipe.core.store.LocalStore;
|
||||||
import io.xpipe.core.store.ShellStore;
|
import io.xpipe.core.store.ShellStore;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
|
@ -25,9 +26,6 @@ import javafx.scene.control.MenuButton;
|
||||||
import javafx.scene.layout.Region;
|
import javafx.scene.layout.Region;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
import atlantafx.base.controls.Popover;
|
|
||||||
import atlantafx.base.theme.Styles;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
|
@ -139,10 +137,7 @@ public class DataStoreChoiceComp<T extends DataStore> extends SimpleComp {
|
||||||
.focusedProperty()
|
.focusedProperty()
|
||||||
.addListener((observable, oldValue, newValue) -> {
|
.addListener((observable, oldValue, newValue) -> {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
((StackPane) struc.get().getChildren().get(1))
|
struc.get().getChildren().get(1).requestFocus();
|
||||||
.getChildren()
|
|
||||||
.get(1)
|
|
||||||
.requestFocus();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
package io.xpipe.app.fxcomps.impl;
|
package io.xpipe.app.fxcomps.impl;
|
||||||
|
|
||||||
|
import atlantafx.base.controls.CustomTextField;
|
||||||
import io.xpipe.app.core.AppActionLinkDetector;
|
import io.xpipe.app.core.AppActionLinkDetector;
|
||||||
import io.xpipe.app.core.AppI18n;
|
import io.xpipe.app.core.AppI18n;
|
||||||
import io.xpipe.app.fxcomps.Comp;
|
import io.xpipe.app.fxcomps.Comp;
|
||||||
import io.xpipe.app.fxcomps.CompStructure;
|
import io.xpipe.app.fxcomps.CompStructure;
|
||||||
|
import io.xpipe.app.fxcomps.SimpleCompStructure;
|
||||||
import io.xpipe.app.fxcomps.util.PlatformThread;
|
import io.xpipe.app.fxcomps.util.PlatformThread;
|
||||||
|
|
||||||
import javafx.beans.binding.Bindings;
|
import javafx.beans.binding.Bindings;
|
||||||
import javafx.beans.property.Property;
|
import javafx.beans.property.Property;
|
||||||
import javafx.scene.Node;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.Cursor;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
|
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Value;
|
|
||||||
import org.kordamp.ikonli.javafx.FontIcon;
|
import org.kordamp.ikonli.javafx.FontIcon;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class FilterComp extends Comp<FilterComp.Structure> {
|
public class FilterComp extends Comp<CompStructure<CustomTextField>> {
|
||||||
|
|
||||||
private final Property<String> filterText;
|
private final Property<String> filterText;
|
||||||
|
|
||||||
|
@ -28,61 +25,47 @@ public class FilterComp extends Comp<FilterComp.Structure> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Structure createBase() {
|
public CompStructure<CustomTextField> createBase() {
|
||||||
var fi = new FontIcon("mdi2m-magnify");
|
var fi = new FontIcon("mdi2m-magnify");
|
||||||
var bgLabel = new Label(null, fi);
|
var clear = new FontIcon("mdi2c-close");
|
||||||
bgLabel.textProperty().bind(AppI18n.observable("searchFilter"));
|
clear.setCursor(Cursor.DEFAULT);
|
||||||
bgLabel.getStyleClass().add("filter-background");
|
clear.setOnMousePressed(event -> {
|
||||||
var filter = new TextField();
|
if (event.getButton() == MouseButton.PRIMARY) {
|
||||||
|
filterText.setValue(null);
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var filter = new CustomTextField();
|
||||||
|
filter.alignmentProperty().bind(Bindings.createObjectBinding(() -> {
|
||||||
|
return filter.isFocused() || (filter.getText() != null && !filter.getText().isEmpty()) ? Pos.CENTER_LEFT : Pos.CENTER;
|
||||||
|
}, filter.textProperty(), filter.focusedProperty()));
|
||||||
|
filter.setMaxHeight(2000);
|
||||||
|
filter.getStyleClass().add("filter-comp");
|
||||||
|
filter.promptTextProperty().bind(AppI18n.observable("searchFilter"));
|
||||||
|
filter.setLeft(fi);
|
||||||
|
filter.setRight(clear);
|
||||||
filter.setAccessibleText("Filter");
|
filter.setAccessibleText("Filter");
|
||||||
|
|
||||||
filterText.subscribe(val -> {
|
filterText.subscribe(val -> {
|
||||||
PlatformThread.runLaterIfNeeded(() -> {
|
PlatformThread.runLaterIfNeeded(() -> {
|
||||||
|
clear.setVisible(val != null);
|
||||||
if (!Objects.equals(filter.getText(), val)) {
|
if (!Objects.equals(filter.getText(), val)) {
|
||||||
filter.setText(val);
|
filter.setText(val);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
filter.textProperty().addListener((observable, oldValue, newValue) -> {
|
|
||||||
|
filter.textProperty().addListener((observable, oldValue, n) -> {
|
||||||
// Handle pasted xpipe URLs
|
// Handle pasted xpipe URLs
|
||||||
if (newValue != null && newValue.startsWith("xpipe://")) {
|
if (n != null && n.startsWith("xpipe://")) {
|
||||||
AppActionLinkDetector.handle(newValue, false);
|
AppActionLinkDetector.handle(n, false);
|
||||||
filter.setText(null);
|
filter.setText(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
filterText.setValue(newValue);
|
filterText.setValue(n != null && n.length() > 0 ? n : null);
|
||||||
});
|
});
|
||||||
|
|
||||||
bgLabel.visibleProperty()
|
return new SimpleCompStructure<>(filter);
|
||||||
.bind(Bindings.createBooleanBinding(
|
|
||||||
() -> (filter.getText() == null || filter.getText().isEmpty()),
|
|
||||||
filter.textProperty(),
|
|
||||||
filter.focusedProperty()));
|
|
||||||
|
|
||||||
var stack = new StackPane(bgLabel, filter);
|
|
||||||
stack.getStyleClass().add("filter-comp");
|
|
||||||
stack.minWidthProperty().bind(bgLabel.prefWidthProperty());
|
|
||||||
|
|
||||||
return Structure.builder()
|
|
||||||
.inactiveIcon(fi)
|
|
||||||
.inactiveText(bgLabel)
|
|
||||||
.text(filter)
|
|
||||||
.pane(stack)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
|
||||||
@Builder
|
|
||||||
public static class Structure implements CompStructure<StackPane> {
|
|
||||||
StackPane pane;
|
|
||||||
Node inactiveIcon;
|
|
||||||
Label inactiveText;
|
|
||||||
TextField text;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StackPane get() {
|
|
||||||
return pane;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
.filter-comp .text-field {
|
.filter-comp {
|
||||||
-fx-padding: 0.15em 0.3em 0.15em 0.3em;
|
-fx-padding: 0.15em 0.3em 0.15em 0.3em;
|
||||||
-fx-background-color: transparent;
|
-fx-background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter-comp .input-line {
|
|
||||||
-fx-opacity: 0.2;
|
|
||||||
}
|
|
|
@ -136,12 +136,3 @@
|
||||||
-fx-border-width: 0.05em;
|
-fx-border-width: 0.05em;
|
||||||
-fx-border-radius: 3px;
|
-fx-border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.store-header-bar .filter-bar .filter-background {
|
|
||||||
-fx-opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-bar .input-line {
|
|
||||||
-fx-opacity: 0.2;
|
|
||||||
}
|
|
Loading…
Reference in a new issue