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