Improve styling of navigation bar

This commit is contained in:
crschnick 2023-05-27 22:29:25 +00:00
parent ff99506d3a
commit 40a5c6a306
6 changed files with 100 additions and 29 deletions

View file

@ -1,16 +1,27 @@
package io.xpipe.app.browser; package io.xpipe.app.browser;
import atlantafx.base.theme.Styles;
import io.xpipe.app.browser.icon.FileIconManager;
import io.xpipe.app.fxcomps.Comp;
import io.xpipe.app.fxcomps.SimpleComp; import io.xpipe.app.fxcomps.SimpleComp;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import io.xpipe.app.fxcomps.augment.ContextMenuAugment;
import io.xpipe.app.fxcomps.augment.GrowAugment;
import io.xpipe.app.fxcomps.impl.HorizontalComp;
import io.xpipe.app.fxcomps.impl.PrettyImageComp;
import io.xpipe.app.fxcomps.impl.StackComp;
import io.xpipe.app.fxcomps.impl.TextFieldComp; import io.xpipe.app.fxcomps.impl.TextFieldComp;
import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.application.Platform; import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.layout.HBox; import javafx.scene.control.Button;
import javafx.scene.layout.Priority; import javafx.scene.input.MouseButton;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import java.util.List;
public class BrowserNavBar extends SimpleComp { public class BrowserNavBar extends SimpleComp {
@ -25,34 +36,73 @@ public class BrowserNavBar extends SimpleComp {
@Override @Override
protected Region createSimple() { protected Region createSimple() {
var path = new SimpleStringProperty(model.getCurrentPath().get()); var path = new SimpleStringProperty(model.getCurrentPath().get());
model.getCurrentPath().addListener((observable, oldValue, newValue) -> {
path.set(newValue);
});
path.addListener((observable, oldValue, newValue) -> { path.addListener((observable, oldValue, newValue) -> {
var changed = model.cd(newValue); var changed = model.cd(newValue);
changed.ifPresent(path::set); changed.ifPresent(path::set);
}); });
var pathBar = new TextFieldComp(path, true).createStructure().get();
pathBar.getStyleClass().add("path-text"); var pathBar = new TextFieldComp(path, true)
model.getCurrentPath().addListener((observable, oldValue, newValue) -> { .styleClass(Styles.RIGHT_PILL)
path.set(newValue); .styleClass("path-text")
}); .apply(struc -> {
SimpleChangeListener.apply(pathBar.focusedProperty(), val -> { SimpleChangeListener.apply(struc.get().focusedProperty(), val -> {
pathBar.pseudoClassStateChanged(INVISIBLE, !val); struc.get().pseudoClassStateChanged(INVISIBLE, !val);
if (val) {
Platform.runLater(() -> {
pathBar.end();
pathBar.selectBackward();
});
}
}); });
var breadcrumbs = new BrowserBreadcrumbBar(model) struc.get().setOnMouseClicked(event -> {
.hide(pathBar.focusedProperty()) if (struc.get().isFocused()) {
return;
}
struc.get().end();
struc.get().selectAll();
struc.get().requestFocus();
});
});
var graphic = Bindings.createStringBinding(
() -> {
var icon = model.getCurrentDirectory() != null
? FileIconManager.getFileIcon(model.getCurrentDirectory(), false)
: null;
return icon;
},
model.getCurrentPath());
var breadcrumbsGraphic = new PrettyImageComp(graphic, 22, 22)
.padding(new Insets(0, 0, 1, 0))
.styleClass("path-graphic")
.createRegion(); .createRegion();
var stack = new StackPane(pathBar, breadcrumbs); var graphicButton = new Button(null, breadcrumbsGraphic);
breadcrumbs.prefHeightProperty().bind(pathBar.heightProperty()); graphicButton.getStyleClass().add(Styles.LEFT_PILL);
HBox.setHgrow(stack, Priority.ALWAYS); graphicButton.getStyleClass().add("path-graphic-button");
stack.setAlignment(Pos.CENTER_LEFT); new ContextMenuAugment<>(
event -> event.getButton() == MouseButton.PRIMARY, () -> new BrowserContextMenu(model, null))
.augment(new SimpleCompStructure<>(graphicButton));
GrowAugment.create(false, true).augment(graphicButton);
return stack; var breadcrumbs = new BrowserBreadcrumbBar(model).grow(false, true);
var stack = new StackComp(List.of(pathBar, breadcrumbs))
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT))
.hgrow()
.apply(struc -> {
var t = struc.get().getChildren().get(0);
var b = struc.get().getChildren().get(1);
b.visibleProperty().bind(t.focusedProperty().not());
})
.grow(false, true);
var topBox = new HorizontalComp(List.of(Comp.of(() -> graphicButton), stack))
.apply(struc -> struc.get().setAlignment(Pos.CENTER_LEFT))
.apply(struc -> {
struc.get().setPickOnBounds(false);
})
.hgrow();
return topBox.createRegion();
} }
} }

View file

@ -6,9 +6,12 @@ import io.xpipe.app.fxcomps.impl.WrapperComp;
import io.xpipe.app.fxcomps.util.Shortcuts; import io.xpipe.app.fxcomps.util.Shortcuts;
import io.xpipe.app.fxcomps.util.SimpleChangeListener; import io.xpipe.app.fxcomps.util.SimpleChangeListener;
import javafx.beans.value.ObservableValue; import javafx.beans.value.ObservableValue;
import javafx.geometry.Insets;
import javafx.scene.control.ButtonBase; import javafx.scene.control.ButtonBase;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.input.KeyCombination; import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import java.util.ArrayList; import java.util.ArrayList;
@ -47,6 +50,10 @@ public abstract class Comp<S extends CompStructure<?>> {
return (T) this; return (T) this;
} }
public Comp<S> hgrow() {
return apply(struc -> HBox.setHgrow(struc.get(), Priority.ALWAYS));
}
public Comp<S> visible(ObservableValue<Boolean> o) { public Comp<S> visible(ObservableValue<Boolean> o) {
return apply(struc -> struc.get().visibleProperty().bind(o)); return apply(struc -> struc.get().visibleProperty().bind(o));
} }
@ -55,6 +62,10 @@ public abstract class Comp<S extends CompStructure<?>> {
return apply(struc -> struc.get().disableProperty().bind(o)); return apply(struc -> struc.get().disableProperty().bind(o));
} }
public Comp<S> padding(Insets insets) {
return apply(struc -> struc.get().setPadding(insets));
}
public Comp<S> hide(ObservableValue<Boolean> o) { public Comp<S> hide(ObservableValue<Boolean> o) {
return apply(struc -> { return apply(struc -> {
var region = struc.get(); var region = struc.get();

View file

@ -1,8 +1,16 @@
package io.xpipe.app.fxcomps.augment; package io.xpipe.app.fxcomps.augment;
import io.xpipe.app.fxcomps.CompStructure; import io.xpipe.app.fxcomps.CompStructure;
import io.xpipe.app.fxcomps.SimpleCompStructure;
import javafx.scene.Node;
import javafx.scene.layout.Region;
public interface Augment<S extends CompStructure<?>> { public interface Augment<S extends CompStructure<?>> {
@SuppressWarnings("unchecked")
default void augment(Node r) {
augment((S) new SimpleCompStructure<>((Region) r));
}
void augment(S struc); void augment(S struc);
} }

View file

@ -35,10 +35,7 @@ public class FancyTooltipAugment<S extends CompStructure<?>> implements Augment<
@Override @Override
public void augment(S struc) { public void augment(S struc) {
augment(struc.get()); var region = struc.get();
}
public void augment(Node region) {
var tt = new JFXTooltip(); var tt = new JFXTooltip();
var toDisplay = text.getValue(); var toDisplay = text.getValue();
if (Shortcuts.getShortcut((Region) region) != null) { if (Shortcuts.getShortcut((Region) region) != null) {

View file

@ -94,6 +94,7 @@ public class SvgView {
var wv = new WebView(); var wv = new WebView();
wv.setPageFill(Color.TRANSPARENT); wv.setPageFill(Color.TRANSPARENT);
wv.getEngine().setJavaScriptEnabled(false); wv.getEngine().setJavaScriptEnabled(false);
wv.setContextMenuEnabled(false);
wv.getEngine().loadContent(getHtml(svgContent.getValue())); wv.getEngine().loadContent(getHtml(svgContent.getValue()));
svgContent.addListener((c, o, n) -> { svgContent.addListener((c, o, n) -> {

View file

@ -105,6 +105,10 @@
.browser .path-text:invisible { .browser .path-text:invisible {
-fx-text-fill: transparent; -fx-text-fill: transparent;
} }
.browser .path-graphic-button {
-fx-padding: 0 2px 0 7px;
}
.browser .context-menu .accelerator-text { .browser .context-menu .accelerator-text {
-fx-padding: 3px 0px 3px 50px; -fx-padding: 3px 0px 3px 50px;