基于 HBox 重新实现 LineComponent (#5416)
This commit is contained in:
@@ -45,9 +45,11 @@ final class ComponentSublistWrapper extends VBox implements NoPaddingComponent {
|
|||||||
ComponentSublistWrapper(ComponentSublist sublist) {
|
ComponentSublistWrapper(ComponentSublist sublist) {
|
||||||
boolean noPadding = !sublist.hasComponentPadding();
|
boolean noPadding = !sublist.hasComponentPadding();
|
||||||
|
|
||||||
|
this.getStyleClass().add("options-sublist-wrapper");
|
||||||
|
|
||||||
Node expandIcon = SVG.KEYBOARD_ARROW_DOWN.createIcon(20);
|
Node expandIcon = SVG.KEYBOARD_ARROW_DOWN.createIcon(20);
|
||||||
|
expandIcon.getStyleClass().add("expand-icon");
|
||||||
expandIcon.setMouseTransparent(true);
|
expandIcon.setMouseTransparent(true);
|
||||||
HBox.setMargin(expandIcon, new Insets(0, 8, 0, 8));
|
|
||||||
|
|
||||||
VBox labelVBox = new VBox();
|
VBox labelVBox = new VBox();
|
||||||
labelVBox.setMouseTransparent(true);
|
labelVBox.setMouseTransparent(true);
|
||||||
@@ -72,7 +74,7 @@ final class ComponentSublistWrapper extends VBox implements NoPaddingComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
HBox header = new HBox();
|
HBox header = new HBox();
|
||||||
header.setSpacing(16);
|
header.setSpacing(12);
|
||||||
header.getChildren().add(labelVBox);
|
header.getChildren().add(labelVBox);
|
||||||
header.setPadding(new Insets(10, 16, 10, 16));
|
header.setPadding(new Insets(10, 16, 10, 16));
|
||||||
header.setAlignment(Pos.CENTER_LEFT);
|
header.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|||||||
@@ -20,34 +20,27 @@ package org.jackhuang.hmcl.ui.construct;
|
|||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.control.OverrunStyle;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public final class LineButton extends LineButtonBase {
|
public class LineButton extends LineButtonBase {
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-button";
|
private static final String DEFAULT_STYLE_CLASS = "line-button";
|
||||||
|
|
||||||
|
private static final int IDX_TRAILING_TEXT = IDX_TRAILING;
|
||||||
|
private static final int IDX_TRAILING_ICON = IDX_TRAILING + 1;
|
||||||
|
|
||||||
public static LineButton createNavigationButton() {
|
public static LineButton createNavigationButton() {
|
||||||
var button = new LineButton();
|
var button = new LineButton();
|
||||||
button.setRightIcon(SVG.ARROW_FORWARD);
|
button.setTrailingIcon(SVG.ARROW_FORWARD);
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LineButton() {
|
public LineButton() {
|
||||||
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
container.setMouseTransparent(true);
|
||||||
root.setMouseTransparent(true);
|
|
||||||
|
|
||||||
FXUtils.onClicked(container, this::fire);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fire() {
|
|
||||||
fireEvent(new ActionEvent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ObjectProperty<EventHandler<ActionEvent>> onAction;
|
private ObjectProperty<EventHandler<ActionEvent>> onAction;
|
||||||
@@ -55,12 +48,6 @@ public final class LineButton extends LineButtonBase {
|
|||||||
public ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {
|
public ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {
|
||||||
if (onAction == null) {
|
if (onAction == null) {
|
||||||
onAction = new ObjectPropertyBase<>() {
|
onAction = new ObjectPropertyBase<>() {
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void invalidated() {
|
|
||||||
setEventHandler(ActionEvent.ACTION, get());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getBean() {
|
public Object getBean() {
|
||||||
return LineButton.this;
|
return LineButton.this;
|
||||||
@@ -70,6 +57,11 @@ public final class LineButton extends LineButtonBase {
|
|||||||
public String getName() {
|
public String getName() {
|
||||||
return "onAction";
|
return "onAction";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidated() {
|
||||||
|
setEventHandler(ActionEvent.ACTION, get());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return onAction;
|
return onAction;
|
||||||
@@ -83,11 +75,13 @@ public final class LineButton extends LineButtonBase {
|
|||||||
onActionProperty().set(value);
|
onActionProperty().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringProperty message;
|
private StringProperty trailingText;
|
||||||
|
|
||||||
|
public StringProperty trailingTextProperty() {
|
||||||
|
if (trailingText == null) {
|
||||||
|
trailingText = new StringPropertyBase() {
|
||||||
|
private Label trailingTextLabel;
|
||||||
|
|
||||||
public StringProperty messageProperty() {
|
|
||||||
if (message == null) {
|
|
||||||
message = new StringPropertyBase() {
|
|
||||||
@Override
|
@Override
|
||||||
public Object getBean() {
|
public Object getBean() {
|
||||||
return LineButton.this;
|
return LineButton.this;
|
||||||
@@ -95,85 +89,78 @@ public final class LineButton extends LineButtonBase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "message";
|
return "trailingText";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invalidated() {
|
protected void invalidated() {
|
||||||
updateRight();
|
String message = get();
|
||||||
|
if (message != null && !message.isEmpty()) {
|
||||||
|
if (trailingTextLabel == null) {
|
||||||
|
trailingTextLabel = new Label();
|
||||||
|
trailingTextLabel.getStyleClass().add("trailing-label");
|
||||||
|
trailingTextLabel.setTextOverrun(OverrunStyle.CENTER_ELLIPSIS);
|
||||||
|
}
|
||||||
|
trailingTextLabel.setText(message);
|
||||||
|
setNode(IDX_TRAILING_TEXT, trailingTextLabel);
|
||||||
|
} else if (trailingTextLabel != null) {
|
||||||
|
trailingTextLabel.setText("");
|
||||||
|
setNode(IDX_TRAILING_TEXT, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return trailingText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
public String getTrailingText() {
|
||||||
return message == null ? "" : message.get();
|
return trailingText != null ? trailingText.get() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(String message) {
|
public void setTrailingText(String trailingText) {
|
||||||
messageProperty().set(message);
|
trailingTextProperty().set(trailingText);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SVG rightIcon;
|
private ObjectProperty<Node> trailingIcon;
|
||||||
private double rightIconSize;
|
|
||||||
|
|
||||||
public void setRightIcon(SVG rightIcon) {
|
public ObjectProperty<Node> trailingIconProperty() {
|
||||||
setRightIcon(rightIcon, SVG.DEFAULT_SIZE);
|
if (trailingIcon == null)
|
||||||
|
trailingIcon = new ObjectPropertyBase<>() {
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return LineButton.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "trailingIcon";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidated() {
|
||||||
|
setNode(IDX_TRAILING_ICON, get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return trailingIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRightIcon(SVG rightIcon, double size) {
|
public Node getTrailingIcon() {
|
||||||
this.rightIcon = rightIcon;
|
return trailingIcon != null ? trailingIcon.get() : null;
|
||||||
this.rightIconSize = size;
|
|
||||||
updateRight();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//region Right
|
public void setTrailingIcon(Node trailingIcon) {
|
||||||
|
trailingIconProperty().set(trailingIcon);
|
||||||
private Label messageLabel;
|
|
||||||
private Node rightIconNode;
|
|
||||||
private SVG currentRightIcon;
|
|
||||||
private double currentRightIconSize;
|
|
||||||
|
|
||||||
private void updateRight() {
|
|
||||||
HBox right;
|
|
||||||
if (root.getRight() instanceof HBox box) {
|
|
||||||
right = box;
|
|
||||||
} else {
|
|
||||||
right = new HBox();
|
|
||||||
right.setAlignment(Pos.CENTER_RIGHT);
|
|
||||||
root.setRight(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
right.getChildren().clear();
|
|
||||||
|
|
||||||
String message = getMessage();
|
|
||||||
if (message != null && !message.isEmpty()) {
|
|
||||||
if (messageLabel == null) {
|
|
||||||
messageLabel = new Label();
|
|
||||||
messageLabel.getStyleClass().add("subtitle");
|
|
||||||
}
|
|
||||||
messageLabel.setText(message);
|
|
||||||
right.getChildren().add(messageLabel);
|
|
||||||
} else if (messageLabel != null) {
|
|
||||||
messageLabel.setText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rightIcon != currentRightIcon || rightIconSize != currentRightIconSize) {
|
|
||||||
if (rightIcon != null) {
|
|
||||||
rightIconNode = rightIcon.createIcon(rightIconSize);
|
|
||||||
HBox.setMargin(rightIconNode, new Insets(0, 8, 0, 8));
|
|
||||||
} else {
|
|
||||||
rightIconNode = null;
|
|
||||||
}
|
|
||||||
currentRightIcon = rightIcon;
|
|
||||||
currentRightIconSize = rightIconSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rightIconNode != null)
|
|
||||||
right.getChildren().add(rightIconNode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
public void setTrailingIcon(SVG rightIcon) {
|
||||||
|
setTrailingIcon(rightIcon, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTrailingIcon(SVG rightIcon, double size) {
|
||||||
|
Node rightIconNode = rightIcon.createIcon(size);
|
||||||
|
rightIconNode.getStyleClass().add("trailing-icon");
|
||||||
|
setTrailingIcon(rightIconNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,71 +17,25 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.construct;
|
package org.jackhuang.hmcl.ui.construct;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.beans.property.StringProperty;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import javafx.scene.layout.StackPane;
|
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public abstract class LineButtonBase extends StackPane implements LineComponent {
|
public abstract class LineButtonBase extends LineComponent {
|
||||||
|
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-button-base";
|
private static final String DEFAULT_STYLE_CLASS = "line-button-base";
|
||||||
|
|
||||||
protected final BorderPane root;
|
protected final RipplerContainer ripplerContainer;
|
||||||
protected final RipplerContainer container;
|
|
||||||
|
|
||||||
private final Label titleLabel;
|
|
||||||
|
|
||||||
public LineButtonBase() {
|
public LineButtonBase() {
|
||||||
this.getStyleClass().addAll(LineComponent.DEFAULT_STYLE_CLASS, LineButtonBase.DEFAULT_STYLE_CLASS);
|
this.getStyleClass().addAll(LineButtonBase.DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
this.root = new BorderPane();
|
this.ripplerContainer = new RipplerContainer(container);
|
||||||
root.setPadding(LineComponent.PADDING);
|
FXUtils.onClicked(this, this::fire);
|
||||||
root.setMinHeight(LineComponent.MIN_HEIGHT);
|
|
||||||
|
|
||||||
this.container = new RipplerContainer(root);
|
this.getChildren().setAll(ripplerContainer);
|
||||||
this.getChildren().setAll(container);
|
|
||||||
|
|
||||||
this.titleLabel = new Label();
|
|
||||||
root.setCenter(titleLabel);
|
|
||||||
BorderPane.setAlignment(titleLabel, Pos.CENTER_LEFT);
|
|
||||||
titleLabel.textProperty().bind(titleProperty());
|
|
||||||
titleLabel.getStyleClass().add("title");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void fire() {
|
||||||
public BorderPane getRoot() {
|
fireEvent(new ActionEvent());
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title");
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StringProperty titleProperty() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
private StringProperty subtitle;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StringProperty subtitleProperty() {
|
|
||||||
if (subtitle == null) {
|
|
||||||
subtitle = new LineComponent.SubtitleProperty() {
|
|
||||||
@Override
|
|
||||||
public LineButtonBase getBean() {
|
|
||||||
return LineButtonBase.this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Label getTitleLabel() {
|
|
||||||
return titleLabel;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return subtitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,101 +17,203 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.construct;
|
package org.jackhuang.hmcl.ui.construct;
|
||||||
|
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.ObjectPropertyBase;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.property.StringPropertyBase;
|
import javafx.beans.property.StringPropertyBase;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.BorderPane;
|
import javafx.scene.layout.*;
|
||||||
import javafx.scene.layout.Region;
|
|
||||||
import javafx.scene.layout.VBox;
|
|
||||||
import org.jackhuang.hmcl.ui.SVG;
|
import org.jackhuang.hmcl.ui.SVG;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public interface LineComponent extends NoPaddingComponent {
|
public abstract class LineComponent extends StackPane implements NoPaddingComponent {
|
||||||
String DEFAULT_STYLE_CLASS = "line-component";
|
private static final String DEFAULT_STYLE_CLASS = "line-component";
|
||||||
|
private static final double MIN_HEIGHT = 48.0;
|
||||||
|
private static final PseudoClass PSEUDO_LARGER_TITLE = PseudoClass.getPseudoClass("large-title");
|
||||||
|
|
||||||
PseudoClass PSEUDO_LARGER_TITLE = PseudoClass.getPseudoClass("large-title");
|
protected static final int IDX_LEADING = 0;
|
||||||
|
protected static final int IDX_TITLE = 1;
|
||||||
|
protected static final int IDX_TRAILING = 2;
|
||||||
|
|
||||||
Insets PADDING = new Insets(8, 8, 8, 16);
|
public static final double SPACING = 12;
|
||||||
Insets ICON_MARGIN = new Insets(0, 16, 0, 0);
|
public static final double DEFAULT_ICON_SIZE = 20;
|
||||||
double MIN_HEIGHT = 48.0;
|
|
||||||
|
|
||||||
private Node self() {
|
public static void setMargin(Node child, Insets value) {
|
||||||
return (Node) this;
|
HBox.setMargin(child, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
BorderPane getRoot();
|
protected final HBox container;
|
||||||
|
|
||||||
StringProperty titleProperty();
|
private final Label titleLabel;
|
||||||
|
private final VBox titleContainer;
|
||||||
|
|
||||||
default String getTitle() {
|
public LineComponent() {
|
||||||
return titleProperty().get();
|
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
|
this.setMinHeight(MIN_HEIGHT);
|
||||||
|
|
||||||
|
this.container = new HBox(SPACING);
|
||||||
|
container.getStyleClass().add("line-component-container");
|
||||||
|
container.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
|
||||||
|
this.titleLabel = new Label();
|
||||||
|
titleLabel.getStyleClass().add("title-label");
|
||||||
|
titleLabel.setMinWidth(Region.USE_PREF_SIZE);
|
||||||
|
|
||||||
|
this.titleContainer = new VBox(titleLabel);
|
||||||
|
titleContainer.getStyleClass().add("title-container");
|
||||||
|
titleContainer.setMouseTransparent(true);
|
||||||
|
titleContainer.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
titleContainer.minWidthProperty().bind(titleLabel.prefWidthProperty());
|
||||||
|
HBox.setHgrow(titleContainer, Priority.ALWAYS);
|
||||||
|
|
||||||
|
this.setNode(IDX_TITLE, titleContainer);
|
||||||
|
|
||||||
|
this.getChildren().setAll(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setTitle(String title) {
|
private Node[] nodes = new Node[2];
|
||||||
titleProperty().set(title);
|
|
||||||
|
protected void setNode(int idx, Node node) {
|
||||||
|
if (nodes.length <= idx)
|
||||||
|
nodes = Arrays.copyOf(nodes, idx + 1);
|
||||||
|
|
||||||
|
if (nodes[idx] != node) {
|
||||||
|
nodes[idx] = node;
|
||||||
|
container.getChildren().setAll(Arrays.stream(nodes).filter(Objects::nonNull).toArray(Node[]::new));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SubtitleProperty extends StringPropertyBase {
|
public void setLargeTitle(boolean largeTitle) {
|
||||||
private VBox left;
|
pseudoClassStateChanged(PSEUDO_LARGER_TITLE, largeTitle);
|
||||||
private Label subtitleLabel;
|
}
|
||||||
|
|
||||||
|
private final StringProperty title = new StringPropertyBase() {
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return LineComponent.this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "subtitle";
|
return "title";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public abstract LineComponent getBean();
|
|
||||||
|
|
||||||
public abstract Label getTitleLabel();
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invalidated() {
|
protected void invalidated() {
|
||||||
String subtitle = get();
|
titleLabel.setText(get());
|
||||||
if (subtitle != null && !subtitle.isEmpty()) {
|
|
||||||
if (left == null) {
|
|
||||||
left = new VBox();
|
|
||||||
left.setMouseTransparent(true);
|
|
||||||
left.setAlignment(Pos.CENTER_LEFT);
|
|
||||||
|
|
||||||
subtitleLabel = new Label();
|
|
||||||
subtitleLabel.setWrapText(true);
|
|
||||||
subtitleLabel.setMinHeight(Region.USE_PREF_SIZE);
|
|
||||||
subtitleLabel.getStyleClass().add("subtitle");
|
|
||||||
}
|
|
||||||
subtitleLabel.setText(subtitle);
|
|
||||||
left.getChildren().setAll(getTitleLabel(), subtitleLabel);
|
|
||||||
getBean().getRoot().setCenter(left);
|
|
||||||
} else if (left != null) {
|
|
||||||
subtitleLabel.setText(null);
|
|
||||||
getBean().getRoot().setCenter(getTitleLabel());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public final StringProperty titleProperty() {
|
||||||
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringProperty subtitleProperty();
|
public String getTitle() {
|
||||||
|
return titleProperty().get();
|
||||||
default String getSubtitle() {
|
|
||||||
return subtitleProperty().get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setSubtitle(String subtitle) {
|
public void setTitle(String title) {
|
||||||
|
titleProperty().set(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringProperty subtitle;
|
||||||
|
|
||||||
|
public final StringProperty subtitleProperty() {
|
||||||
|
if (subtitle == null) {
|
||||||
|
subtitle = new StringPropertyBase() {
|
||||||
|
private Label subtitleLabel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "subtitle";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return LineComponent.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidated() {
|
||||||
|
String subtitle = get();
|
||||||
|
if (subtitle != null && !subtitle.isEmpty()) {
|
||||||
|
if (subtitleLabel == null) {
|
||||||
|
subtitleLabel = new Label();
|
||||||
|
subtitleLabel.setWrapText(true);
|
||||||
|
subtitleLabel.setMinHeight(Region.USE_PREF_SIZE);
|
||||||
|
subtitleLabel.getStyleClass().add("subtitle-label");
|
||||||
|
}
|
||||||
|
subtitleLabel.setText(subtitle);
|
||||||
|
if (titleContainer.getChildren().size() == 1)
|
||||||
|
titleContainer.getChildren().add(subtitleLabel);
|
||||||
|
} else if (subtitleLabel != null) {
|
||||||
|
subtitleLabel.setText(null);
|
||||||
|
if (titleContainer.getChildren().size() == 2)
|
||||||
|
titleContainer.getChildren().remove(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return subtitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getSubtitle() {
|
||||||
|
return subtitle != null ? subtitle.get() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setSubtitle(String subtitle) {
|
||||||
subtitleProperty().set(subtitle);
|
subtitleProperty().set(subtitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setLeftIcon(Image icon) {
|
private ObjectProperty<Node> leading;
|
||||||
setLeftIcon(icon, -1.0);
|
|
||||||
|
public final ObjectProperty<Node> leadingProperty() {
|
||||||
|
if (leading == null) {
|
||||||
|
leading = new ObjectPropertyBase<>() {
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return LineComponent.this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "leading";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidated() {
|
||||||
|
setNode(IDX_LEADING, get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return leading;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setLeftIcon(Image icon, double size) {
|
public final Node getLeading() {
|
||||||
ImageView imageView = new ImageView(icon);
|
return leadingProperty().get();
|
||||||
imageView.getStyleClass().add("left-icon");
|
}
|
||||||
|
|
||||||
|
public final void setLeading(Node node) {
|
||||||
|
leadingProperty().set(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeading(Image icon) {
|
||||||
|
setLeading(icon, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeading(Image icon, double size) {
|
||||||
|
var imageView = new ImageView(icon);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
imageView.setFitWidth(size);
|
imageView.setFitWidth(size);
|
||||||
imageView.setFitHeight(size);
|
imageView.setFitHeight(size);
|
||||||
@@ -119,25 +221,18 @@ public interface LineComponent extends NoPaddingComponent {
|
|||||||
imageView.setSmooth(true);
|
imageView.setSmooth(true);
|
||||||
}
|
}
|
||||||
imageView.setMouseTransparent(true);
|
imageView.setMouseTransparent(true);
|
||||||
BorderPane.setAlignment(imageView, Pos.CENTER);
|
|
||||||
BorderPane.setMargin(imageView, ICON_MARGIN);
|
setNode(IDX_LEADING, imageView);
|
||||||
getRoot().setLeft(imageView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setLeftIcon(SVG svg) {
|
public void setLeading(SVG svg) {
|
||||||
setLeftIcon(svg, SVG.DEFAULT_SIZE);
|
setLeading(svg, DEFAULT_ICON_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setLeftIcon(SVG svg, double size) {
|
public void setLeading(SVG svg, double size) {
|
||||||
Node node = svg.createIcon(size);
|
Node node = svg.createIcon(size);
|
||||||
node.getStyleClass().add("left-icon");
|
|
||||||
node.setMouseTransparent(true);
|
node.setMouseTransparent(true);
|
||||||
BorderPane.setAlignment(node, Pos.CENTER);
|
setNode(IDX_LEADING, node);
|
||||||
BorderPane.setMargin(node, ICON_MARGIN);
|
|
||||||
getRoot().setLeft(node);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default void setLargeTitle(boolean largeTitle) {
|
|
||||||
self().pseudoClassStateChanged(PSEUDO_LARGER_TITLE, largeTitle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,61 +17,47 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.ui.construct;
|
package org.jackhuang.hmcl.ui.construct;
|
||||||
|
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.ObjectProperty;
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.ObjectPropertyBase;
|
||||||
import javafx.geometry.Pos;
|
import javafx.scene.Node;
|
||||||
import javafx.scene.control.Label;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public class LinePane extends BorderPane implements LineComponent {
|
public class LinePane extends LineComponent {
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-pane";
|
private static final String DEFAULT_STYLE_CLASS = "line-pane";
|
||||||
|
|
||||||
private final Label titleLabel;
|
|
||||||
|
|
||||||
public LinePane() {
|
public LinePane() {
|
||||||
this.getStyleClass().addAll(LineComponent.DEFAULT_STYLE_CLASS, LinePane.DEFAULT_STYLE_CLASS);
|
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
this.setPadding(LineComponent.PADDING);
|
|
||||||
this.setMinHeight(LineComponent.MIN_HEIGHT);
|
|
||||||
|
|
||||||
this.titleLabel = new Label();
|
|
||||||
this.setCenter(titleLabel);
|
|
||||||
BorderPane.setAlignment(titleLabel, Pos.CENTER_LEFT);
|
|
||||||
titleLabel.textProperty().bind(titleProperty());
|
|
||||||
titleLabel.getStyleClass().add("title");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private ObjectProperty<Node> right;
|
||||||
public BorderPane getRoot() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final StringProperty title = new SimpleStringProperty(this, "title");
|
public ObjectProperty<Node> rightProperty() {
|
||||||
|
if (right == null) {
|
||||||
@Override
|
right = new ObjectPropertyBase<>() {
|
||||||
public StringProperty titleProperty() {
|
|
||||||
return title;
|
|
||||||
}
|
|
||||||
|
|
||||||
private StringProperty subtitle;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StringProperty subtitleProperty() {
|
|
||||||
if (subtitle == null) {
|
|
||||||
subtitle = new LineComponent.SubtitleProperty() {
|
|
||||||
@Override
|
@Override
|
||||||
public LinePane getBean() {
|
public Object getBean() {
|
||||||
return LinePane.this;
|
return LinePane.this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Label getTitleLabel() {
|
public String getName() {
|
||||||
return titleLabel;
|
return "right";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidated() {
|
||||||
|
setNode(IDX_TRAILING, get());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
return subtitle;
|
public Node getRight() {
|
||||||
|
return rightProperty().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRight(Node right) {
|
||||||
|
rightProperty().set(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,7 @@ import javafx.beans.property.*;
|
|||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.css.PseudoClass;
|
import javafx.css.PseudoClass;
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Pos;
|
import javafx.geometry.Pos;
|
||||||
import javafx.scene.Node;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.input.MouseButton;
|
import javafx.scene.input.MouseButton;
|
||||||
import javafx.scene.input.MouseEvent;
|
import javafx.scene.input.MouseEvent;
|
||||||
@@ -43,7 +41,7 @@ import java.util.function.Function;
|
|||||||
import static org.jackhuang.hmcl.ui.FXUtils.determineOptimalPopupPosition;
|
import static org.jackhuang.hmcl.ui.FXUtils.determineOptimalPopupPosition;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public final class LineSelectButton<T> extends LineButtonBase {
|
public final class LineSelectButton<T> extends LineButton {
|
||||||
|
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-select-button";
|
private static final String DEFAULT_STYLE_CLASS = "line-select-button";
|
||||||
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");
|
private static final PseudoClass SELECTED_PSEUDO_CLASS = PseudoClass.getPseudoClass("selected");
|
||||||
@@ -53,109 +51,96 @@ public final class LineSelectButton<T> extends LineButtonBase {
|
|||||||
public LineSelectButton() {
|
public LineSelectButton() {
|
||||||
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
root.setMouseTransparent(true);
|
InvalidationListener updateTrailingText = observable -> {
|
||||||
|
T value = getValue();
|
||||||
|
if (value != null) {
|
||||||
|
Function<T, String> converter = getConverter();
|
||||||
|
setTrailingText(converter != null ? converter.apply(value) : value.toString());
|
||||||
|
} else {
|
||||||
|
setTrailingText(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
converterProperty().addListener(updateTrailingText);
|
||||||
|
valueProperty().addListener(updateTrailingText);
|
||||||
|
|
||||||
HBox right = new HBox();
|
setTrailingIcon(SVG.UNFOLD_MORE);
|
||||||
root.setRight(right);
|
|
||||||
{
|
|
||||||
right.setAlignment(Pos.CENTER_RIGHT);
|
|
||||||
|
|
||||||
Label valueLabel = new Label();
|
ripplerContainer.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
||||||
valueLabel.getStyleClass().add("subtitle");
|
if (event.getButton() == MouseButton.SECONDARY) {
|
||||||
|
|
||||||
InvalidationListener updateValue = observable -> {
|
|
||||||
T value = getValue();
|
|
||||||
if (value == null)
|
|
||||||
valueLabel.setText("");
|
|
||||||
else {
|
|
||||||
Function<T, String> converter = getConverter();
|
|
||||||
valueLabel.setText(converter != null ? converter.apply(value) : value.toString());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
converterProperty().addListener(updateValue);
|
|
||||||
valueProperty().addListener(updateValue);
|
|
||||||
|
|
||||||
Node arrowIcon = SVG.UNFOLD_MORE.createIcon(24);
|
|
||||||
HBox.setMargin(arrowIcon, new Insets(0, 8, 0, 8));
|
|
||||||
|
|
||||||
right.getChildren().setAll(valueLabel, arrowIcon);
|
|
||||||
}
|
|
||||||
|
|
||||||
container.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
|
|
||||||
if (event.getButton() == MouseButton.PRIMARY) {
|
|
||||||
if (popup == null) {
|
|
||||||
PopupMenu popupMenu = new PopupMenu();
|
|
||||||
this.popup = new JFXPopup(popupMenu);
|
|
||||||
|
|
||||||
container.addEventFilter(ScrollEvent.ANY, ignored -> popup.hide());
|
|
||||||
|
|
||||||
Bindings.bindContent(popupMenu.getContent(), MappedObservableList.create(itemsProperty(), item -> {
|
|
||||||
VBox vbox = new VBox();
|
|
||||||
|
|
||||||
var itemTitleLabel = new Label();
|
|
||||||
itemTitleLabel.getStyleClass().add("title");
|
|
||||||
itemTitleLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
|
||||||
if (item == null)
|
|
||||||
return "";
|
|
||||||
|
|
||||||
Function<T, String> converter = getConverter();
|
|
||||||
return converter != null ? converter.apply(item) : Objects.toString(item, "");
|
|
||||||
}, converterProperty()));
|
|
||||||
|
|
||||||
var itemSubtitleLabel = new Label();
|
|
||||||
itemSubtitleLabel.getStyleClass().add("subtitle");
|
|
||||||
itemSubtitleLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
|
||||||
Function<T, String> descriptionConverter = getDescriptionConverter();
|
|
||||||
return descriptionConverter != null ? descriptionConverter.apply(item) : "";
|
|
||||||
}, descriptionConverterProperty()));
|
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(itemSubtitleLabel.textProperty(), text -> {
|
|
||||||
if (text == null || text.isEmpty()) {
|
|
||||||
vbox.getChildren().setAll(itemTitleLabel);
|
|
||||||
} else {
|
|
||||||
vbox.getChildren().setAll(itemTitleLabel, itemSubtitleLabel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var wrapper = new StackPane(vbox);
|
|
||||||
wrapper.setAlignment(Pos.CENTER_LEFT);
|
|
||||||
wrapper.getStyleClass().add("menu-container");
|
|
||||||
wrapper.setMouseTransparent(true);
|
|
||||||
RipplerContainer ripplerContainer = new RipplerContainer(wrapper);
|
|
||||||
FXUtils.onClicked(ripplerContainer, () -> {
|
|
||||||
setValue(item);
|
|
||||||
popup.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
FXUtils.onChangeAndOperate(valueProperty(),
|
|
||||||
value -> wrapper.pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, Objects.equals(value, item)));
|
|
||||||
|
|
||||||
return ripplerContainer;
|
|
||||||
}));
|
|
||||||
|
|
||||||
popup.showingProperty().addListener((observable, oldValue, newValue) ->
|
|
||||||
container.getRippler().setRipplerDisabled(newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (popup.isShowing()) {
|
|
||||||
popup.hide();
|
|
||||||
} else {
|
|
||||||
JFXPopup.PopupVPosition vPosition = determineOptimalPopupPosition(this, popup);
|
|
||||||
popup.show(this, vPosition, JFXPopup.PopupHPosition.RIGHT,
|
|
||||||
0,
|
|
||||||
vPosition == JFXPopup.PopupVPosition.TOP ? this.getHeight() : -this.getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
event.consume();
|
|
||||||
} else if (event.getButton() == MouseButton.SECONDARY) {
|
|
||||||
if (popup != null)
|
if (popup != null)
|
||||||
popup.hide();
|
popup.hide();
|
||||||
|
|
||||||
event.consume();
|
event.consume();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fire() {
|
||||||
|
super.fire();
|
||||||
|
if (popup == null) {
|
||||||
|
PopupMenu popupMenu = new PopupMenu();
|
||||||
|
this.popup = new JFXPopup(popupMenu);
|
||||||
|
|
||||||
|
ripplerContainer.addEventFilter(ScrollEvent.ANY, ignored -> popup.hide());
|
||||||
|
|
||||||
|
Bindings.bindContent(popupMenu.getContent(), MappedObservableList.create(itemsProperty(), item -> {
|
||||||
|
VBox vbox = new VBox();
|
||||||
|
|
||||||
|
var itemTitleLabel = new Label();
|
||||||
|
itemTitleLabel.getStyleClass().add("title-label");
|
||||||
|
itemTitleLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||||
|
if (item == null)
|
||||||
|
return "";
|
||||||
|
|
||||||
|
Function<T, String> converter = getConverter();
|
||||||
|
return converter != null ? converter.apply(item) : Objects.toString(item, "");
|
||||||
|
}, converterProperty()));
|
||||||
|
|
||||||
|
var itemSubtitleLabel = new Label();
|
||||||
|
itemSubtitleLabel.getStyleClass().add("subtitle-label");
|
||||||
|
itemSubtitleLabel.textProperty().bind(Bindings.createStringBinding(() -> {
|
||||||
|
Function<T, String> descriptionConverter = getDescriptionConverter();
|
||||||
|
return descriptionConverter != null ? descriptionConverter.apply(item) : "";
|
||||||
|
}, descriptionConverterProperty()));
|
||||||
|
|
||||||
|
FXUtils.onChangeAndOperate(itemSubtitleLabel.textProperty(), text -> {
|
||||||
|
if (text == null || text.isEmpty()) {
|
||||||
|
vbox.getChildren().setAll(itemTitleLabel);
|
||||||
|
} else {
|
||||||
|
vbox.getChildren().setAll(itemTitleLabel, itemSubtitleLabel);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var wrapper = new StackPane(vbox);
|
||||||
|
wrapper.setAlignment(Pos.CENTER_LEFT);
|
||||||
|
wrapper.getStyleClass().add("menu-container");
|
||||||
|
wrapper.setMouseTransparent(true);
|
||||||
|
RipplerContainer ripplerContainer = new RipplerContainer(wrapper);
|
||||||
|
FXUtils.onClicked(ripplerContainer, () -> {
|
||||||
|
setValue(item);
|
||||||
|
popup.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
FXUtils.onChangeAndOperate(valueProperty(),
|
||||||
|
value -> wrapper.pseudoClassStateChanged(SELECTED_PSEUDO_CLASS, Objects.equals(value, item)));
|
||||||
|
|
||||||
|
return ripplerContainer;
|
||||||
|
}));
|
||||||
|
|
||||||
|
popup.showingProperty().addListener((observable, oldValue, newValue) ->
|
||||||
|
ripplerContainer.getRippler().setRipplerDisabled(newValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popup.isShowing()) {
|
||||||
|
popup.hide();
|
||||||
|
} else {
|
||||||
|
JFXPopup.PopupVPosition vPosition = determineOptimalPopupPosition(this, popup);
|
||||||
|
popup.show(this, vPosition, JFXPopup.PopupHPosition.RIGHT,
|
||||||
|
0,
|
||||||
|
vPosition == JFXPopup.PopupVPosition.TOP ? this.getHeight() : -this.getHeight());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final ObjectProperty<T> value = new SimpleObjectProperty<>(this, "value");
|
private final ObjectProperty<T> value = new SimpleObjectProperty<>(this, "value");
|
||||||
|
|
||||||
public ObjectProperty<T> valueProperty() {
|
public ObjectProperty<T> valueProperty() {
|
||||||
@@ -187,9 +172,8 @@ public final class LineSelectButton<T> extends LineButtonBase {
|
|||||||
private ObjectProperty<Function<T, String>> descriptionConverter;
|
private ObjectProperty<Function<T, String>> descriptionConverter;
|
||||||
|
|
||||||
public ObjectProperty<Function<T, String>> descriptionConverterProperty() {
|
public ObjectProperty<Function<T, String>> descriptionConverterProperty() {
|
||||||
if (descriptionConverter == null) {
|
if (descriptionConverter == null)
|
||||||
descriptionConverter = new SimpleObjectProperty<>(this, "descriptionConverter");
|
descriptionConverter = new SimpleObjectProperty<>(this, "descriptionConverter");
|
||||||
}
|
|
||||||
return descriptionConverter;
|
return descriptionConverter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,19 +19,16 @@ package org.jackhuang.hmcl.ui.construct;
|
|||||||
|
|
||||||
import javafx.beans.property.StringProperty;
|
import javafx.beans.property.StringProperty;
|
||||||
import javafx.beans.property.StringPropertyBase;
|
import javafx.beans.property.StringPropertyBase;
|
||||||
import javafx.geometry.Insets;
|
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.control.Label;
|
import javafx.scene.control.Label;
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
|
||||||
/// @author Glavo
|
/// @author Glavo
|
||||||
public final class LineTextPane extends LinePane {
|
public final class LineTextPane extends LineComponent {
|
||||||
|
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-label-pane";
|
private static final String DEFAULT_STYLE_CLASS = "line-text-pane";
|
||||||
|
|
||||||
public LineTextPane() {
|
public LineTextPane() {
|
||||||
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
this.getStyleClass().addAll(DEFAULT_STYLE_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringProperty text;
|
private StringProperty text;
|
||||||
@@ -39,8 +36,6 @@ public final class LineTextPane extends LinePane {
|
|||||||
public StringProperty textProperty() {
|
public StringProperty textProperty() {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
text = new StringPropertyBase() {
|
text = new StringPropertyBase() {
|
||||||
private static final Insets LABEL_MARGIN = new Insets(0, 8, 0, 16);
|
|
||||||
|
|
||||||
private Label rightLabel;
|
private Label rightLabel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -56,19 +51,18 @@ public final class LineTextPane extends LinePane {
|
|||||||
@Override
|
@Override
|
||||||
protected void invalidated() {
|
protected void invalidated() {
|
||||||
String text = get();
|
String text = get();
|
||||||
if (text == null || text.isEmpty()) {
|
if (text != null && !text.isEmpty()) {
|
||||||
if (rightLabel != null)
|
|
||||||
rightLabel.setText(null);
|
|
||||||
LineTextPane.this.setRight(null);
|
|
||||||
} else {
|
|
||||||
if (rightLabel == null) {
|
if (rightLabel == null) {
|
||||||
rightLabel = FXUtils.newSafeTruncatedLabel();
|
rightLabel = FXUtils.newSafeTruncatedLabel();
|
||||||
FXUtils.copyOnDoubleClick(rightLabel);
|
FXUtils.copyOnDoubleClick(rightLabel);
|
||||||
BorderPane.setMargin(rightLabel, LABEL_MARGIN);
|
|
||||||
BorderPane.setAlignment(rightLabel, Pos.CENTER_RIGHT);
|
|
||||||
}
|
}
|
||||||
rightLabel.setText(text);
|
rightLabel.setText(text);
|
||||||
LineTextPane.this.setRight(rightLabel);
|
setNode(IDX_TRAILING, rightLabel);
|
||||||
|
} else {
|
||||||
|
if (rightLabel != null)
|
||||||
|
rightLabel.setText(null);
|
||||||
|
|
||||||
|
setNode(IDX_TRAILING, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,25 +20,27 @@ package org.jackhuang.hmcl.ui.construct;
|
|||||||
import com.jfoenix.controls.JFXToggleButton;
|
import com.jfoenix.controls.JFXToggleButton;
|
||||||
import javafx.beans.property.BooleanProperty;
|
import javafx.beans.property.BooleanProperty;
|
||||||
import javafx.beans.property.SimpleBooleanProperty;
|
import javafx.beans.property.SimpleBooleanProperty;
|
||||||
import javafx.geometry.Pos;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
|
|
||||||
public final class LineToggleButton extends LineButtonBase {
|
public final class LineToggleButton extends LineButtonBase {
|
||||||
private static final String DEFAULT_STYLE_CLASS = "line-toggle-button";
|
private static final String DEFAULT_STYLE_CLASS = "line-toggle-button";
|
||||||
|
|
||||||
|
private final JFXToggleButton toggleButton;
|
||||||
|
|
||||||
public LineToggleButton() {
|
public LineToggleButton() {
|
||||||
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
this.getStyleClass().add(DEFAULT_STYLE_CLASS);
|
||||||
|
|
||||||
JFXToggleButton toggleButton = new JFXToggleButton();
|
this.toggleButton = new JFXToggleButton();
|
||||||
toggleButton.selectedProperty().bindBidirectional(selectedProperty());
|
toggleButton.selectedProperty().bindBidirectional(selectedProperty());
|
||||||
toggleButton.setSize(8);
|
toggleButton.setSize(8);
|
||||||
FXUtils.setLimitHeight(toggleButton, 30);
|
FXUtils.setLimitHeight(toggleButton, 30);
|
||||||
|
setNode(IDX_TRAILING, toggleButton);
|
||||||
|
}
|
||||||
|
|
||||||
BorderPane.setAlignment(toggleButton, Pos.CENTER);
|
@Override
|
||||||
root.setRight(toggleButton);
|
public void fire() {
|
||||||
|
toggleButton.fire();
|
||||||
FXUtils.onClicked(container, toggleButton::fire);
|
super.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected");
|
private final BooleanProperty selected = new SimpleBooleanProperty(this, "selected");
|
||||||
|
|||||||
@@ -115,7 +115,6 @@ public final class JavaInstallPage extends WizardSinglePage {
|
|||||||
nameField = new JFXTextField();
|
nameField = new JFXTextField();
|
||||||
nameField.textProperty().bindBidirectional(control.nameProperty);
|
nameField.textProperty().bindBidirectional(control.nameProperty);
|
||||||
FXUtils.setLimitWidth(nameField, 200);
|
FXUtils.setLimitWidth(nameField, 200);
|
||||||
BorderPane.setAlignment(nameField, Pos.CENTER_RIGHT);
|
|
||||||
namePane.setRight(nameField);
|
namePane.setRight(nameField);
|
||||||
nameField.setValidators(
|
nameField.setValidators(
|
||||||
new RequiredValidator(),
|
new RequiredValidator(),
|
||||||
|
|||||||
@@ -151,10 +151,10 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
body.setLineSpacing(4);
|
body.setLineSpacing(4);
|
||||||
|
|
||||||
var download = createLargeTitleLineButton();
|
var download = createLargeTitleLineButton();
|
||||||
download.setLeftIcon(FXUtils.newBuiltinImage("/assets/img/terracotta.png"));
|
download.setLeading(FXUtils.newBuiltinImage("/assets/img/terracotta.png"));
|
||||||
download.setTitle(i18n(String.format("terracotta.status.uninitialized.%s.title", fork)));
|
download.setTitle(i18n(String.format("terracotta.status.uninitialized.%s.title", fork)));
|
||||||
download.setSubtitle(i18n("terracotta.status.uninitialized.desc"));
|
download.setSubtitle(i18n("terracotta.status.uninitialized.desc"));
|
||||||
download.setRightIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
download.setTrailingIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
||||||
download.setOnAction(event -> {
|
download.setOnAction(event -> {
|
||||||
TerracottaState.Preparing s = TerracottaManager.download();
|
TerracottaState.Preparing s = TerracottaManager.download();
|
||||||
if (s != null) {
|
if (s != null) {
|
||||||
@@ -195,10 +195,10 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
flow.setLineSpacing(4);
|
flow.setLineSpacing(4);
|
||||||
|
|
||||||
var host = createLargeTitleLineButton();
|
var host = createLargeTitleLineButton();
|
||||||
host.setLeftIcon(SVG.HOST, ICON_SIZE);
|
host.setLeading(SVG.HOST, ICON_SIZE);
|
||||||
host.setTitle(i18n("terracotta.status.waiting.host.title"));
|
host.setTitle(i18n("terracotta.status.waiting.host.title"));
|
||||||
host.setSubtitle(i18n("terracotta.status.waiting.host.desc"));
|
host.setSubtitle(i18n("terracotta.status.waiting.host.desc"));
|
||||||
host.setRightIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
host.setTrailingIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
||||||
host.setOnAction(event -> {
|
host.setOnAction(event -> {
|
||||||
if (LauncherHelper.countMangedProcesses() >= 1) {
|
if (LauncherHelper.countMangedProcesses() >= 1) {
|
||||||
TerracottaState.HostScanning s1 = TerracottaManager.setScanning();
|
TerracottaState.HostScanning s1 = TerracottaManager.setScanning();
|
||||||
@@ -227,10 +227,10 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var guest = createLargeTitleLineButton();
|
var guest = createLargeTitleLineButton();
|
||||||
guest.setLeftIcon(SVG.ADD_CIRCLE, ICON_SIZE);
|
guest.setLeading(SVG.ADD_CIRCLE, ICON_SIZE);
|
||||||
guest.setTitle(i18n("terracotta.status.waiting.guest.title"));
|
guest.setTitle(i18n("terracotta.status.waiting.guest.title"));
|
||||||
guest.setSubtitle(i18n("terracotta.status.waiting.guest.desc"));
|
guest.setSubtitle(i18n("terracotta.status.waiting.guest.desc"));
|
||||||
guest.setRightIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
guest.setTrailingIcon(SVG.ARROW_FORWARD, ICON_SIZE);
|
||||||
guest.setOnAction(event -> {
|
guest.setOnAction(event -> {
|
||||||
Controllers.prompt(i18n("terracotta.status.waiting.guest.prompt.title"), (code, handler) -> {
|
Controllers.prompt(i18n("terracotta.status.waiting.guest.prompt.title"), (code, handler) -> {
|
||||||
Task<TerracottaState.GuestConnecting> task = TerracottaManager.setGuesting(code);
|
Task<TerracottaState.GuestConnecting> task = TerracottaManager.setGuesting(code);
|
||||||
@@ -251,10 +251,10 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
|
|
||||||
if (ThreadLocalRandom.current().nextDouble() < 0.02D) {
|
if (ThreadLocalRandom.current().nextDouble() < 0.02D) {
|
||||||
var feedback = createLargeTitleLineButton();
|
var feedback = createLargeTitleLineButton();
|
||||||
feedback.setLeftIcon(SVG.FEEDBACK, ICON_SIZE);
|
feedback.setLeading(SVG.FEEDBACK, ICON_SIZE);
|
||||||
feedback.setTitle(i18n("terracotta.feedback.title"));
|
feedback.setTitle(i18n("terracotta.feedback.title"));
|
||||||
feedback.setSubtitle(i18n("terracotta.feedback.desc"));
|
feedback.setSubtitle(i18n("terracotta.feedback.desc"));
|
||||||
feedback.setRightIcon(SVG.OPEN_IN_NEW, ICON_SIZE);
|
feedback.setTrailingIcon(SVG.OPEN_IN_NEW, ICON_SIZE);
|
||||||
FXUtils.onClicked(feedback, () -> FXUtils.openLink(TerracottaMetadata.FEEDBACK_LINK));
|
FXUtils.onClicked(feedback, () -> FXUtils.openLink(TerracottaMetadata.FEEDBACK_LINK));
|
||||||
|
|
||||||
nodesProperty.setAll(flow, host, guest, feedback);
|
nodesProperty.setAll(flow, host, guest, feedback);
|
||||||
@@ -270,7 +270,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
body.setLineSpacing(4);
|
body.setLineSpacing(4);
|
||||||
|
|
||||||
var room = createLargeTitleLineButton();
|
var room = createLargeTitleLineButton();
|
||||||
room.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
room.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
room.setTitle(i18n("terracotta.back"));
|
room.setTitle(i18n("terracotta.back"));
|
||||||
room.setSubtitle(i18n("terracotta.status.scanning.back"));
|
room.setSubtitle(i18n("terracotta.status.scanning.back"));
|
||||||
room.setOnAction(event -> {
|
room.setOnAction(event -> {
|
||||||
@@ -286,7 +286,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
progressProperty.set(-1);
|
progressProperty.set(-1);
|
||||||
|
|
||||||
var room = createLargeTitleLineButton();
|
var room = createLargeTitleLineButton();
|
||||||
room.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
room.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
room.setTitle(i18n("terracotta.back"));
|
room.setTitle(i18n("terracotta.back"));
|
||||||
room.setSubtitle(i18n("terracotta.status.host_starting.back"));
|
room.setSubtitle(i18n("terracotta.status.host_starting.back"));
|
||||||
room.setOnAction(event -> {
|
room.setOnAction(event -> {
|
||||||
@@ -330,13 +330,13 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
FXUtils.onClicked(code, () -> copyCode(cs));
|
FXUtils.onClicked(code, () -> copyCode(cs));
|
||||||
|
|
||||||
var copy = createLargeTitleLineButton();
|
var copy = createLargeTitleLineButton();
|
||||||
copy.setLeftIcon(SVG.CONTENT_COPY, ICON_SIZE);
|
copy.setLeading(SVG.CONTENT_COPY, ICON_SIZE);
|
||||||
copy.setTitle(i18n("terracotta.status.host_ok.code.copy"));
|
copy.setTitle(i18n("terracotta.status.host_ok.code.copy"));
|
||||||
copy.setSubtitle(i18n("terracotta.status.host_ok.code.desc"));
|
copy.setSubtitle(i18n("terracotta.status.host_ok.code.desc"));
|
||||||
FXUtils.onClicked(copy, () -> copyCode(cs));
|
FXUtils.onClicked(copy, () -> copyCode(cs));
|
||||||
|
|
||||||
var back = createLargeTitleLineButton();
|
var back = createLargeTitleLineButton();
|
||||||
back.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
back.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
back.setTitle(i18n("terracotta.back"));
|
back.setTitle(i18n("terracotta.back"));
|
||||||
back.setSubtitle(i18n("terracotta.status.host_ok.back"));
|
back.setSubtitle(i18n("terracotta.status.host_ok.back"));
|
||||||
back.setOnAction(event -> {
|
back.setOnAction(event -> {
|
||||||
@@ -357,7 +357,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
progressProperty.set(-1);
|
progressProperty.set(-1);
|
||||||
|
|
||||||
var room = createLargeTitleLineButton();
|
var room = createLargeTitleLineButton();
|
||||||
room.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
room.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
room.setTitle(i18n("terracotta.back"));
|
room.setTitle(i18n("terracotta.back"));
|
||||||
room.setSubtitle(i18n("terracotta.status.guest_starting.back"));
|
room.setSubtitle(i18n("terracotta.status.guest_starting.back"));
|
||||||
room.setOnAction(event -> {
|
room.setOnAction(event -> {
|
||||||
@@ -372,7 +372,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
TerracottaState.GuestStarting.Difficulty difficulty = ((TerracottaState.GuestStarting) state).getDifficulty();
|
TerracottaState.GuestStarting.Difficulty difficulty = ((TerracottaState.GuestStarting) state).getDifficulty();
|
||||||
if (difficulty != null && difficulty != TerracottaState.GuestStarting.Difficulty.UNKNOWN) {
|
if (difficulty != null && difficulty != TerracottaState.GuestStarting.Difficulty.UNKNOWN) {
|
||||||
var info = createLargeTitleLineButton();
|
var info = createLargeTitleLineButton();
|
||||||
info.setLeftIcon(switch (difficulty) {
|
info.setLeading(switch (difficulty) {
|
||||||
case UNKNOWN -> throw new AssertionError();
|
case UNKNOWN -> throw new AssertionError();
|
||||||
case EASIEST, SIMPLE -> SVG.INFO;
|
case EASIEST, SIMPLE -> SVG.INFO;
|
||||||
case MEDIUM, TOUGH -> SVG.WARNING;
|
case MEDIUM, TOUGH -> SVG.WARNING;
|
||||||
@@ -404,7 +404,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
tutorial.setSubtitle(i18n("terracotta.status.guest_ok.desc", guestOK.getUrl()));
|
tutorial.setSubtitle(i18n("terracotta.status.guest_ok.desc", guestOK.getUrl()));
|
||||||
|
|
||||||
var back = createLargeTitleLineButton();
|
var back = createLargeTitleLineButton();
|
||||||
back.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
back.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
back.setTitle(i18n("terracotta.back"));
|
back.setTitle(i18n("terracotta.back"));
|
||||||
back.setSubtitle(i18n("terracotta.status.guest_ok.back"));
|
back.setSubtitle(i18n("terracotta.status.guest_ok.back"));
|
||||||
back.setOnAction(event -> {
|
back.setOnAction(event -> {
|
||||||
@@ -426,7 +426,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
nodesProperty.setAll();
|
nodesProperty.setAll();
|
||||||
|
|
||||||
var back = createLargeTitleLineButton();
|
var back = createLargeTitleLineButton();
|
||||||
back.setLeftIcon(SVG.ARROW_BACK, ICON_SIZE);
|
back.setLeading(SVG.ARROW_BACK, ICON_SIZE);
|
||||||
back.setTitle(i18n("terracotta.back"));
|
back.setTitle(i18n("terracotta.back"));
|
||||||
back.setSubtitle(i18n("terracotta.status.exception.back"));
|
back.setSubtitle(i18n("terracotta.status.exception.back"));
|
||||||
back.setOnAction(event -> {
|
back.setOnAction(event -> {
|
||||||
@@ -438,7 +438,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
|
|
||||||
SpinnerPane exportLog = new SpinnerPane();
|
SpinnerPane exportLog = new SpinnerPane();
|
||||||
var exportLogInner = createLargeTitleLineButton();
|
var exportLogInner = createLargeTitleLineButton();
|
||||||
exportLogInner.setLeftIcon(SVG.OUTPUT, ICON_SIZE);
|
exportLogInner.setLeading(SVG.OUTPUT, ICON_SIZE);
|
||||||
exportLogInner.setTitle(i18n("terracotta.export_log"));
|
exportLogInner.setTitle(i18n("terracotta.export_log"));
|
||||||
exportLogInner.setSubtitle(i18n("terracotta.export_log.desc"));
|
exportLogInner.setSubtitle(i18n("terracotta.export_log.desc"));
|
||||||
exportLog.setContent(exportLogInner);
|
exportLog.setContent(exportLogInner);
|
||||||
@@ -481,7 +481,7 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
|
|
||||||
if (fatal.isRecoverable()) {
|
if (fatal.isRecoverable()) {
|
||||||
var retry = createLargeTitleLineButton();
|
var retry = createLargeTitleLineButton();
|
||||||
retry.setLeftIcon(SVG.RESTORE, ICON_SIZE);
|
retry.setLeading(SVG.RESTORE, ICON_SIZE);
|
||||||
retry.setTitle(i18n("terracotta.status.fatal.retry"));
|
retry.setTitle(i18n("terracotta.status.fatal.retry"));
|
||||||
retry.setSubtitle(message);
|
retry.setSubtitle(message);
|
||||||
retry.setOnAction(event -> {
|
retry.setOnAction(event -> {
|
||||||
@@ -552,17 +552,16 @@ public class TerracottaControllerPage extends StackPane {
|
|||||||
|
|
||||||
var header = new LinePane();
|
var header = new LinePane();
|
||||||
header.setLargeTitle(true);
|
header.setLargeTitle(true);
|
||||||
header.setPadding(Insets.EMPTY);
|
|
||||||
header.setMinHeight(LinePane.USE_COMPUTED_SIZE);
|
header.setMinHeight(LinePane.USE_COMPUTED_SIZE);
|
||||||
header.setMouseTransparent(true);
|
header.setMouseTransparent(true);
|
||||||
header.setLeftIcon(FXUtils.newBuiltinImage("/assets/img/terracotta.png"));
|
header.setLeading(FXUtils.newBuiltinImage("/assets/img/terracotta.png"));
|
||||||
header.setTitle(i18n("terracotta.from_local.title"));
|
header.setTitle(i18n("terracotta.from_local.title"));
|
||||||
header.setSubtitle(i18n("terracotta.from_local.desc"));
|
header.setSubtitle(i18n("terracotta.from_local.desc"));
|
||||||
locals.setHeaderLeft(header);
|
locals.setHeaderLeft(header);
|
||||||
|
|
||||||
for (TerracottaMetadata.Link link : TerracottaMetadata.PACKAGE_LINKS) {
|
for (TerracottaMetadata.Link link : TerracottaMetadata.PACKAGE_LINKS) {
|
||||||
LineButton item = new LineButton();
|
LineButton item = new LineButton();
|
||||||
item.setRightIcon(SVG.OPEN_IN_NEW);
|
item.setTrailingIcon(SVG.OPEN_IN_NEW);
|
||||||
item.setTitle(link.description().getText(I18n.getLocale().getCandidateLocales()));
|
item.setTitle(link.description().getText(I18n.getLocale().getCandidateLocales()));
|
||||||
item.setOnAction(event -> Controllers.dialog(
|
item.setOnAction(event -> Controllers.dialog(
|
||||||
i18n("terracotta.from_local.guide", TerracottaMetadata.PACKAGE_NAME),
|
i18n("terracotta.from_local.guide", TerracottaMetadata.PACKAGE_NAME),
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import javafx.scene.control.ScrollPane;
|
|||||||
import javafx.scene.effect.BoxBlur;
|
import javafx.scene.effect.BoxBlur;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
import javafx.scene.layout.HBox;
|
import javafx.scene.layout.HBox;
|
||||||
import javafx.scene.layout.StackPane;
|
import javafx.scene.layout.StackPane;
|
||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
@@ -202,7 +201,6 @@ public final class WorldInfoPage extends SpinnerPane implements WorldManagePage.
|
|||||||
HBox right = new HBox(8);
|
HBox right = new HBox(8);
|
||||||
{
|
{
|
||||||
right.setAlignment(Pos.CENTER_RIGHT);
|
right.setAlignment(Pos.CENTER_RIGHT);
|
||||||
BorderPane.setAlignment(right, Pos.CENTER_RIGHT);
|
|
||||||
right.getChildren().setAll(visibilityButton, seedLabel);
|
right.getChildren().setAll(visibilityButton, seedLabel);
|
||||||
seedPane.setRight(right);
|
seedPane.setRight(right);
|
||||||
}
|
}
|
||||||
@@ -410,9 +408,9 @@ public final class WorldInfoPage extends SpinnerPane implements WorldManagePage.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRightTextField(BorderPane borderPane, int perfWidth, Tag tag) {
|
private void setRightTextField(LinePane linePane, int perfWidth, Tag tag) {
|
||||||
JFXTextField textField = new JFXTextField();
|
JFXTextField textField = new JFXTextField();
|
||||||
setRightTextField(borderPane, textField, perfWidth);
|
setRightTextField(linePane, textField, perfWidth);
|
||||||
if (tag instanceof IntTag intTag) {
|
if (tag instanceof IntTag intTag) {
|
||||||
bindTagAndTextField(intTag, textField);
|
bindTagAndTextField(intTag, textField);
|
||||||
} else if (tag instanceof FloatTag floatTag) {
|
} else if (tag instanceof FloatTag floatTag) {
|
||||||
@@ -422,11 +420,10 @@ public final class WorldInfoPage extends SpinnerPane implements WorldManagePage.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRightTextField(BorderPane borderPane, JFXTextField textField, int perfWidth) {
|
private void setRightTextField(LinePane linePane, JFXTextField textField, int perfWidth) {
|
||||||
textField.setDisable(isReadOnly);
|
textField.setDisable(isReadOnly);
|
||||||
textField.setPrefWidth(perfWidth);
|
textField.setPrefWidth(perfWidth);
|
||||||
BorderPane.setAlignment(textField, Pos.CENTER_RIGHT);
|
linePane.setRight(textField);
|
||||||
borderPane.setRight(textField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindTagAndToggleButton(Tag tag, LineToggleButton toggleButton) {
|
private void bindTagAndToggleButton(Tag tag, LineToggleButton toggleButton) {
|
||||||
|
|||||||
@@ -1041,6 +1041,10 @@
|
|||||||
-fx-font-size: 12;
|
-fx-font-size: 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.options-list-item > .line-component .line-component-container {
|
||||||
|
-fx-padding: 10 16 10 16;
|
||||||
|
}
|
||||||
|
|
||||||
.options-list-item .svg {
|
.options-list-item .svg {
|
||||||
-fx-fill: -monet-on-surface;
|
-fx-fill: -monet-on-surface;
|
||||||
-fx-border-color: -monet-outline-variant;
|
-fx-border-color: -monet-outline-variant;
|
||||||
@@ -1076,6 +1080,10 @@
|
|||||||
-fx-border-width: 0;
|
-fx-border-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.options-sublist-wrapper .expand-icon .svg {
|
||||||
|
-fx-fill: -monet-on-surface-variant;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* *
|
* *
|
||||||
* JFX Toggle Button *
|
* JFX Toggle Button *
|
||||||
@@ -1103,15 +1111,16 @@
|
|||||||
.jfx-toggle-button Line {
|
.jfx-toggle-button Line {
|
||||||
-fx-stroke: -jfx-untoggle-line-color;
|
-fx-stroke: -jfx-untoggle-line-color;
|
||||||
}
|
}
|
||||||
.jfx-toggle-button:selected Line{
|
|
||||||
|
.jfx-toggle-button:selected Line {
|
||||||
-fx-stroke: -jfx-toggle-line-color;
|
-fx-stroke: -jfx-toggle-line-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jfx-toggle-button Circle{
|
.jfx-toggle-button Circle {
|
||||||
-fx-fill: -jfx-untoggle-color;
|
-fx-fill: -jfx-untoggle-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.jfx-toggle-button:selected Circle{
|
.jfx-toggle-button:selected Circle {
|
||||||
-fx-fill: -jfx-toggle-color;
|
-fx-fill: -jfx-toggle-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1864,47 +1873,39 @@
|
|||||||
* *
|
* *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
.line-component .title {
|
.line-component:large-title .title-label {
|
||||||
-fx-text-fill: -monet-on-surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-component:large-title .title {
|
|
||||||
-fx-font-size: 15px;
|
-fx-font-size: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-component .subtitle {
|
|
||||||
-fx-text-fill: -monet-on-surface-variant;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-button .svg {
|
|
||||||
-fx-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-button .svg:disabled {
|
.line-button .svg:disabled {
|
||||||
-fx-opacity: 0.4;
|
-fx-opacity: 0.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-select-button .svg {
|
.line-button .trailing-label {
|
||||||
-fx-opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-select-button .svg:disabled {
|
|
||||||
-fx-opacity: 0.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-select-button .menu-container .title {
|
|
||||||
-fx-font-size: 13px;
|
|
||||||
-fx-text-fill: -monet-on-surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-select-button .menu-container:selected .title {
|
|
||||||
-fx-text-fill: -monet-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.line-select-button .menu-container .subtitle {
|
|
||||||
-fx-text-fill: -monet-on-surface-variant;
|
-fx-text-fill: -monet-on-surface-variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-select-button .menu-container:selected .subtitle {
|
.line-button .trailing-icon .svg {
|
||||||
|
-fx-fill: -monet-on-surface-variant;
|
||||||
|
-fx-opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-button .trailing-icon .svg:disabled {
|
||||||
|
-fx-opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-select-button .menu-container .title-label {
|
||||||
|
-fx-font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-select-button .menu-container:selected .title-label {
|
||||||
-fx-text-fill: -monet-primary;
|
-fx-text-fill: -monet-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-select-button .menu-container:selected .subtitle-label {
|
||||||
|
-fx-text-fill: -monet-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-toggle-button .jfx-toggle-button {
|
||||||
|
-fx-padding: 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user