From 1208d6dabc73d33b6c0730321c99eceb8ce63247 Mon Sep 17 00:00:00 2001 From: huanghongxun Date: Sun, 21 Jun 2020 18:18:20 +0800 Subject: [PATCH] feat: decorator shadow --- .../org/jackhuang/hmcl/ui/Controllers.java | 10 +- .../hmcl/ui/decorator/Decorator.java | 6 + .../ui/decorator/DecoratorController.java | 2 +- .../hmcl/ui/decorator/DecoratorSkin.java | 111 +++++++++--------- HMCL/src/main/resources/assets/css/root.css | 9 +- 5 files changed, 78 insertions(+), 60 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java index 92c92ef2e..8407b8128 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -22,7 +22,9 @@ import javafx.beans.property.SimpleDoubleProperty; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.Region; +import javafx.scene.paint.Color; import javafx.stage.Stage; +import javafx.stage.StageStyle; import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.setting.EnumCommonDirectory; @@ -123,15 +125,17 @@ public final class Controllers { Task.runAsync(JavaVersion::initialize).start(); - scene = new Scene(decorator.getDecorator(), 802, 482); - stage.setMinHeight(482); - stage.setMinWidth(802); + scene = new Scene(decorator.getDecorator()); + scene.setFill(Color.TRANSPARENT); + stage.setMinHeight(482 + 32); + stage.setMinWidth(802 + 32); decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty()); decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty()); scene.getStylesheets().setAll(config().getTheme().getStylesheets()); stage.getIcons().add(newImage("/assets/img/icon.png")); stage.setTitle(Metadata.TITLE); + stage.initStyle(StageStyle.TRANSPARENT); stage.setScene(scene); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java index e33d7ba83..eecb72e60 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/Decorator.java @@ -22,12 +22,16 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; +import javafx.geometry.Insets; import javafx.scene.Node; import javafx.scene.control.Control; import javafx.scene.control.Skin; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.CornerRadii; import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; import javafx.stage.Stage; import javafx.stage.StageStyle; @@ -55,6 +59,8 @@ public class Decorator extends Control { public Decorator(Stage primaryStage) { this.primaryStage = primaryStage; + setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY))); + primaryStage.initStyle(StageStyle.UNDECORATED); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java index 7a50d4c55..a6db83839 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorController.java @@ -133,7 +133,7 @@ public class DecoratorController { // ==== Background ==== private void setupBackground() { - decorator.backgroundProperty().bind( + decorator.contentBackgroundProperty().bind( Bindings.createObjectBinding( () -> { Image image = null; diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java index 651fb74d5..99116b16d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/decorator/DecoratorSkin.java @@ -50,7 +50,7 @@ public class DecoratorSkin extends SkinBase { private static final SVGGlyph minus = Lang.apply(new SVGGlyph(0, "MINUS", "M804.571 420.571v109.714q0 22.857-16 38.857t-38.857 16h-694.857q-22.857 0-38.857-16t-16-38.857v-109.714q0-22.857 16-38.857t38.857-16h694.857q22.857 0 38.857 16t16 38.857z", Color.WHITE), glyph -> { glyph.setSize(12, 2); glyph.setTranslateY(4); }); - private final StackPane parent; + private final StackPane root, parent; private final StackPane titleContainer; private final Stage primaryStage; private final TransitionPane navBarPane; @@ -72,15 +72,20 @@ public class DecoratorSkin extends SkinBase { minus.fillProperty().bind(Theme.foregroundFillBinding()); Decorator skinnable = getSkinnable(); + root = new StackPane(); + root.getStyleClass().add("window"); + parent = new StackPane(); - parent.getStyleClass().add("window"); - parent.backgroundProperty().bind(skinnable.backgroundProperty()); + parent.getStyleClass().add("body"); + parent.backgroundProperty().bind(skinnable.contentBackgroundProperty()); parent.setPickOnBounds(false); parent.prefHeightProperty().bind(control.prefHeightProperty()); parent.prefWidthProperty().bind(control.prefWidthProperty()); - parent.setOnMouseReleased(this::onMouseReleased); - parent.setOnMouseDragged(this::onMouseDragged); - parent.setOnMouseMoved(this::onMouseMoved); + root.setOnMouseReleased(this::onMouseReleased); + root.setOnMouseDragged(this::onMouseDragged); + root.setOnMouseMoved(this::onMouseMoved); + + root.getChildren().setAll(parent); // animation layer at bottom { @@ -93,9 +98,9 @@ public class DecoratorSkin extends SkinBase { } StackPane wrapper = new StackPane(); - BorderPane root = new BorderPane(); - root.getStyleClass().addAll("jfx-decorator"); - wrapper.getChildren().setAll(root); + BorderPane frame = new BorderPane(); + frame.getStyleClass().addAll("jfx-decorator"); + wrapper.getChildren().setAll(frame); skinnable.setDrawerWrapper(wrapper); parent.getChildren().add(wrapper); @@ -132,7 +137,7 @@ public class DecoratorSkin extends SkinBase { container.getChildren().add(floatLayer); } - root.setCenter(container); + frame.setCenter(container); titleContainer = new StackPane(); titleContainer.setPickOnBounds(false); @@ -174,7 +179,7 @@ public class DecoratorSkin extends SkinBase { titleBar.setCenter(navBarPane); titleBar.setRight(buttonsContainerPlaceHolder); } - root.setTop(titleContainer); + frame.setTop(titleContainer); { HBox buttonsContainer = new HBox(); @@ -204,7 +209,7 @@ public class DecoratorSkin extends SkinBase { parent.getChildren().add(layer); } - getChildren().add(parent); + getChildren().add(root); } private Node createNavBar(Decorator skinnable, boolean titleBarTransparent, double leftPaneWidth, boolean canBack, boolean canClose, boolean showCloseAsHome, boolean canRefresh, String title, Node titleNode) { @@ -293,19 +298,19 @@ public class DecoratorSkin extends SkinBase { } private boolean isRightEdge(double x, double y, Bounds boundsInParent) { - return x < parent.getWidth() && x >= parent.getWidth() - parent.snappedLeftInset(); + return x < root.getWidth() && x >= root.getWidth() - root.snappedLeftInset(); } private boolean isTopEdge(double x, double y, Bounds boundsInParent) { - return y >= 0 && y <= parent.snappedTopInset(); + return y >= 0 && y <= root.snappedTopInset(); } private boolean isBottomEdge(double x, double y, Bounds boundsInParent) { - return y < parent.getHeight() && y >= parent.getHeight() - parent.snappedLeftInset(); + return y < root.getHeight() && y >= root.getHeight() - root.snappedLeftInset(); } private boolean isLeftEdge(double x, double y, Bounds boundsInParent) { - return x >= 0 && x <= parent.snappedLeftInset(); + return x >= 0 && x <= root.snappedLeftInset(); } private boolean setStageWidth(double width) { @@ -341,48 +346,46 @@ public class DecoratorSkin extends SkinBase { updateInitMouseValues(mouseEvent); if (primaryStage.isResizable()) { double x = mouseEvent.getX(), y = mouseEvent.getY(); - Bounds boundsInParent = parent.getBoundsInParent(); - if (parent.getBorder() != null && parent.getBorder().getStrokes().size() > 0) { - double diagonalSize = parent.snappedLeftInset() + 10; - if (this.isRightEdge(x, y, boundsInParent)) { - if (y < diagonalSize) { - parent.setCursor(Cursor.NE_RESIZE); - } else if (y > parent.getHeight() - diagonalSize) { - parent.setCursor(Cursor.SE_RESIZE); - } else { - parent.setCursor(Cursor.E_RESIZE); - } - } else if (this.isLeftEdge(x, y, boundsInParent)) { - if (y < diagonalSize) { - parent.setCursor(Cursor.NW_RESIZE); - } else if (y > parent.getHeight() - diagonalSize) { - parent.setCursor(Cursor.SW_RESIZE); - } else { - parent.setCursor(Cursor.W_RESIZE); - } - } else if (this.isTopEdge(x, y, boundsInParent)) { - if (x < diagonalSize) { - parent.setCursor(Cursor.NW_RESIZE); - } else if (x > parent.getWidth() - diagonalSize) { - parent.setCursor(Cursor.NE_RESIZE); - } else { - parent.setCursor(Cursor.N_RESIZE); - } - } else if (this.isBottomEdge(x, y, boundsInParent)) { - if (x < diagonalSize) { - parent.setCursor(Cursor.SW_RESIZE); - } else if (x > parent.getWidth() - diagonalSize) { - parent.setCursor(Cursor.SE_RESIZE); - } else { - parent.setCursor(Cursor.S_RESIZE); - } + Bounds boundsInParent = root.getBoundsInParent(); + double diagonalSize = root.snappedLeftInset() + 10; + if (this.isRightEdge(x, y, boundsInParent)) { + if (y < diagonalSize) { + root.setCursor(Cursor.NE_RESIZE); + } else if (y > root.getHeight() - diagonalSize) { + root.setCursor(Cursor.SE_RESIZE); } else { - parent.setCursor(Cursor.DEFAULT); + root.setCursor(Cursor.E_RESIZE); } + } else if (this.isLeftEdge(x, y, boundsInParent)) { + if (y < diagonalSize) { + root.setCursor(Cursor.NW_RESIZE); + } else if (y > root.getHeight() - diagonalSize) { + root.setCursor(Cursor.SW_RESIZE); + } else { + root.setCursor(Cursor.W_RESIZE); + } + } else if (this.isTopEdge(x, y, boundsInParent)) { + if (x < diagonalSize) { + root.setCursor(Cursor.NW_RESIZE); + } else if (x > root.getWidth() - diagonalSize) { + root.setCursor(Cursor.NE_RESIZE); + } else { + root.setCursor(Cursor.N_RESIZE); + } + } else if (this.isBottomEdge(x, y, boundsInParent)) { + if (x < diagonalSize) { + root.setCursor(Cursor.SW_RESIZE); + } else if (x > root.getWidth() - diagonalSize) { + root.setCursor(Cursor.SE_RESIZE); + } else { + root.setCursor(Cursor.S_RESIZE); + } + } else { + root.setCursor(Cursor.DEFAULT); } } } else { - parent.setCursor(Cursor.DEFAULT); + root.setCursor(Cursor.DEFAULT); } } @@ -398,7 +401,7 @@ public class DecoratorSkin extends SkinBase { this.newY = mouseEvent.getScreenY(); double deltaX = this.newX - this.initX; double deltaY = this.newY - this.initY; - Cursor cursor = parent.getCursor(); + Cursor cursor = root.getCursor(); if (Cursor.E_RESIZE == cursor) { this.setStageWidth(this.primaryStage.getWidth() + deltaX); mouseEvent.consume(); diff --git a/HMCL/src/main/resources/assets/css/root.css b/HMCL/src/main/resources/assets/css/root.css index 0dc99cd84..c3fe72dd2 100644 --- a/HMCL/src/main/resources/assets/css/root.css +++ b/HMCL/src/main/resources/assets/css/root.css @@ -1146,8 +1146,13 @@ } .window { - -fx-border-color: black; - -fx-border-width: 1; + -fx-background-color: transparent; + -fx-padding: 16; +} + +.body { + -fx-border-radius: 5; + -fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.4), 20, 0.3, 0.0, 0.0); } .debug-border {