feat: platform-style window buttons, 21px dialog radius, thin round progress bar, title mark
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0269e54b95
commit
07ff244cd2
3 files changed
+138
-5
No files matched your search
@@ -27,6 +27,7 @@ import javafx.util.Duration;
|
||||
import org.glavo.monetfx.ColorRole;
|
||||
import org.glavo.monetfx.ColorScheme;
|
||||
import org.jackhuang.hmcl.theme.Themes;
|
||||
import org.jackhuang.hmcl.util.platform.OperatingSystem;
|
||||
import org.jackhuang.hmcl.theme.WarmPalette;
|
||||
import org.jackhuang.hmcl.ui.*;
|
||||
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
|
||||
@@ -102,7 +103,11 @@ final class MainWindowPane extends StackPane {
|
||||
titleBar = new BorderPane();
|
||||
titleBar.setPickOnBounds(false);
|
||||
titleBar.getStyleClass().add("jfx-tool-bar");
|
||||
titleBar.setRight(windowButtons);
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
|
||||
titleBar.setLeft(windowButtons);
|
||||
} else {
|
||||
titleBar.setRight(windowButtons);
|
||||
}
|
||||
|
||||
navBarPane = new TransitionPane();
|
||||
titleBar.setCenter(navBarPane);
|
||||
@@ -163,21 +168,39 @@ final class MainWindowPane extends StackPane {
|
||||
/// @return a size-limited top-right button row
|
||||
private HBox createWindowButtons() {
|
||||
HBox buttons = new HBox();
|
||||
buttons.setAlignment(Pos.TOP_RIGHT);
|
||||
decorator.capableDraggingWindow(buttons);
|
||||
|
||||
if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS) {
|
||||
// macOS style: round close/minimize buttons on the left. Zoom is shown but disabled.
|
||||
buttons.setAlignment(Pos.CENTER_LEFT);
|
||||
buttons.setSpacing(8);
|
||||
buttons.setPadding(new Insets(0, 0, 0, 20));
|
||||
buttons.setMaxSize(Region.USE_PREF_SIZE, 40);
|
||||
|
||||
JFXButton closeButton = macButton("mac-close", decorator::closeWindow);
|
||||
JFXButton minimizeButton = macButton("mac-minimize", decorator::minimizeWindow);
|
||||
JFXButton zoomButton = macButton("mac-zoom", () -> {
|
||||
});
|
||||
zoomButton.setDisable(true);
|
||||
buttons.getChildren().setAll(closeButton, minimizeButton, zoomButton);
|
||||
return buttons;
|
||||
}
|
||||
|
||||
// Windows and Linux style: flat rectangular buttons on the right.
|
||||
buttons.setAlignment(Pos.TOP_RIGHT);
|
||||
buttons.setMaxSize(Region.USE_PREF_SIZE, 40);
|
||||
|
||||
JFXButton minimizeButton = new JFXButton();
|
||||
minimizeButton.setFocusTraversable(false);
|
||||
minimizeButton.setGraphic(SVG.MINIMIZE_CENTER.createIcon(Themes.titleFillProperty()));
|
||||
minimizeButton.getStyleClass().add("jfx-decorator-button");
|
||||
minimizeButton.getStyleClass().add("window-button");
|
||||
minimizeButton.setOnAction(event -> decorator.minimizeWindow());
|
||||
decorator.forbidDraggingWindow(minimizeButton);
|
||||
|
||||
JFXButton closeButton = new JFXButton();
|
||||
closeButton.setFocusTraversable(false);
|
||||
closeButton.setGraphic(SVG.CLOSE.createIcon(Themes.titleFillProperty()));
|
||||
closeButton.getStyleClass().add("jfx-decorator-button");
|
||||
closeButton.getStyleClass().addAll("window-button", "window-close-button");
|
||||
closeButton.setOnAction(event -> decorator.closeWindow());
|
||||
decorator.forbidDraggingWindow(closeButton);
|
||||
|
||||
@@ -185,6 +208,19 @@ final class MainWindowPane extends StackPane {
|
||||
return buttons;
|
||||
}
|
||||
|
||||
/// Creates one round macOS-style window button.
|
||||
///
|
||||
/// @param styleClass the class that selects the button color
|
||||
/// @param action the action to run when the button is pressed
|
||||
private JFXButton macButton(String styleClass, Runnable action) {
|
||||
JFXButton button = new JFXButton();
|
||||
button.setFocusTraversable(false);
|
||||
button.getStyleClass().addAll("mac-window-button", styleClass);
|
||||
button.setOnAction(event -> action.run());
|
||||
decorator.forbidDraggingWindow(button);
|
||||
return button;
|
||||
}
|
||||
|
||||
/// Recomputes the title-bar background for the current theme and transparency preference.
|
||||
private void updateTitleBarBackground() {
|
||||
titleBar.setBackground(new Background(new BackgroundFill(
|
||||
|
||||
@@ -71,7 +71,8 @@ public final class MainPage extends StackPane implements DecoratorPage {
|
||||
titleNode.setPadding(new Insets(0, 0, 0, 2));
|
||||
titleNode.setAlignment(Pos.CENTER_LEFT);
|
||||
|
||||
ImageView titleIcon = new ImageView(FXUtils.newBuiltinImage("/assets/img/icon-title.png"));
|
||||
Region titleIcon = new Region();
|
||||
titleIcon.getStyleClass().add("title-mark");
|
||||
Label titleLabel = new Label();
|
||||
titleLabel.textProperty().bind(Controllers.launcherTitleProperty());
|
||||
if (I18n.isUpsideDown()) {
|
||||
|
||||
@@ -2253,3 +2253,99 @@
|
||||
-fx-border-color: transparent -monet-outline-variant transparent transparent;
|
||||
-fx-border-width: 0 1px 0 0;
|
||||
}
|
||||
|
||||
/* ---- Window buttons ---- */
|
||||
.window-button {
|
||||
-fx-min-width: 46px;
|
||||
-fx-pref-width: 46px;
|
||||
-fx-max-width: 46px;
|
||||
-fx-min-height: 40px;
|
||||
-fx-pref-height: 40px;
|
||||
-fx-max-height: 40px;
|
||||
-fx-background-color: transparent;
|
||||
-fx-background-radius: 0;
|
||||
-fx-cursor: default;
|
||||
}
|
||||
|
||||
.window-button:hover {
|
||||
-fx-background-color: -monet-surface-container;
|
||||
}
|
||||
|
||||
.window-close-button:hover {
|
||||
-fx-background-color: #C42B1C;
|
||||
}
|
||||
|
||||
.window-close-button:hover .svg {
|
||||
-fx-fill: white;
|
||||
}
|
||||
|
||||
.mac-window-button {
|
||||
-fx-min-width: 12px;
|
||||
-fx-pref-width: 12px;
|
||||
-fx-max-width: 12px;
|
||||
-fx-min-height: 12px;
|
||||
-fx-pref-height: 12px;
|
||||
-fx-max-height: 12px;
|
||||
-fx-padding: 0;
|
||||
-fx-background-radius: 6px;
|
||||
-fx-border-radius: 6px;
|
||||
-fx-border-width: 0.5px;
|
||||
-fx-cursor: default;
|
||||
}
|
||||
|
||||
.mac-close { -fx-background-color: #FF5F57; -fx-border-color: #E0443E; }
|
||||
.mac-minimize { -fx-background-color: #FEBC2E; -fx-border-color: #DEA123; }
|
||||
.mac-zoom { -fx-background-color: #28C840; -fx-border-color: #1AAB29; }
|
||||
.mac-zoom:disabled { -fx-opacity: 1; -fx-background-color: #D5CEC1; -fx-border-color: #C2BAAB; }
|
||||
.mac-close:hover, .mac-minimize:hover { -fx-effect: innershadow(gaussian, rgba(0, 0, 0, 0.25), 3, 0.2, 0, 0); }
|
||||
|
||||
/* ---- Dialogs: one corner radius family (8 / 13 / 21) ---- */
|
||||
.jfx-dialog-layout, .task-executor-dialog-layout {
|
||||
-fx-background-color: -monet-surface-bright;
|
||||
-fx-background-radius: 21px;
|
||||
-fx-border-color: -monet-outline-variant;
|
||||
-fx-border-radius: 21px;
|
||||
-fx-border-width: 1px;
|
||||
-fx-effect: dropshadow(gaussian, rgba(60, 40, 20, 0.18), 34, 0.1, 0, 8);
|
||||
}
|
||||
|
||||
.dialog-accept, .dialog-cancel, .dialog-error {
|
||||
-fx-background-radius: 8px;
|
||||
}
|
||||
|
||||
/* ---- Progress bar: thin, round-ended ---- */
|
||||
.jfx-progress-bar > .track {
|
||||
-fx-background-color: -monet-surface-container-highest;
|
||||
-fx-pref-height: 6px;
|
||||
-fx-min-height: 6px;
|
||||
-fx-max-height: 6px;
|
||||
}
|
||||
|
||||
.jfx-progress-bar > .bar {
|
||||
-fx-background-color: -monet-primary;
|
||||
-fx-padding: 0;
|
||||
-fx-pref-height: 6px;
|
||||
-fx-min-height: 6px;
|
||||
-fx-max-height: 6px;
|
||||
}
|
||||
|
||||
.jfx-progress-bar > .track,
|
||||
.jfx-progress-bar > .bar {
|
||||
-fx-background-radius: 999px;
|
||||
}
|
||||
|
||||
.card, .card-no-padding, .card-non-transparent {
|
||||
-fx-background-radius: 13px;
|
||||
}
|
||||
|
||||
/* The small accent mark that stands in for a logo in the title bar. */
|
||||
.title-mark {
|
||||
-fx-background-color: -monet-primary;
|
||||
-fx-background-radius: 5px;
|
||||
-fx-min-width: 18px;
|
||||
-fx-pref-width: 18px;
|
||||
-fx-max-width: 18px;
|
||||
-fx-min-height: 18px;
|
||||
-fx-pref-height: 18px;
|
||||
-fx-max-height: 18px;
|
||||
}
|
||||
Reference in new issue
Block a user