feat: decorator shadow

This commit is contained in:
huanghongxun 2020-06-21 18:18:20 +08:00
parent 63082f5a5e
commit 1208d6dabc
5 changed files with 78 additions and 60 deletions

View File

@ -22,7 +22,9 @@ import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.layout.Region; import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.jackhuang.hmcl.Launcher; import org.jackhuang.hmcl.Launcher;
import org.jackhuang.hmcl.Metadata; import org.jackhuang.hmcl.Metadata;
import org.jackhuang.hmcl.setting.EnumCommonDirectory; import org.jackhuang.hmcl.setting.EnumCommonDirectory;
@ -123,15 +125,17 @@ public final class Controllers {
Task.runAsync(JavaVersion::initialize).start(); Task.runAsync(JavaVersion::initialize).start();
scene = new Scene(decorator.getDecorator(), 802, 482); scene = new Scene(decorator.getDecorator());
stage.setMinHeight(482); scene.setFill(Color.TRANSPARENT);
stage.setMinWidth(802); stage.setMinHeight(482 + 32);
stage.setMinWidth(802 + 32);
decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty()); decorator.getDecorator().prefWidthProperty().bind(scene.widthProperty());
decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty()); decorator.getDecorator().prefHeightProperty().bind(scene.heightProperty());
scene.getStylesheets().setAll(config().getTheme().getStylesheets()); scene.getStylesheets().setAll(config().getTheme().getStylesheets());
stage.getIcons().add(newImage("/assets/img/icon.png")); stage.getIcons().add(newImage("/assets/img/icon.png"));
stage.setTitle(Metadata.TITLE); stage.setTitle(Metadata.TITLE);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene); stage.setScene(scene);
} }

View File

@ -22,12 +22,16 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Control; import javafx.scene.control.Control;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background; import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage; import javafx.stage.Stage;
import javafx.stage.StageStyle; import javafx.stage.StageStyle;
@ -55,6 +59,8 @@ public class Decorator extends Control {
public Decorator(Stage primaryStage) { public Decorator(Stage primaryStage) {
this.primaryStage = primaryStage; this.primaryStage = primaryStage;
setBackground(new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)));
primaryStage.initStyle(StageStyle.UNDECORATED); primaryStage.initStyle(StageStyle.UNDECORATED);
} }

View File

@ -133,7 +133,7 @@ public class DecoratorController {
// ==== Background ==== // ==== Background ====
private void setupBackground() { private void setupBackground() {
decorator.backgroundProperty().bind( decorator.contentBackgroundProperty().bind(
Bindings.createObjectBinding( Bindings.createObjectBinding(
() -> { () -> {
Image image = null; Image image = null;

View File

@ -50,7 +50,7 @@ public class DecoratorSkin extends SkinBase<Decorator> {
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), 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); }); glyph -> { glyph.setSize(12, 2); glyph.setTranslateY(4); });
private final StackPane parent; private final StackPane root, parent;
private final StackPane titleContainer; private final StackPane titleContainer;
private final Stage primaryStage; private final Stage primaryStage;
private final TransitionPane navBarPane; private final TransitionPane navBarPane;
@ -72,15 +72,20 @@ public class DecoratorSkin extends SkinBase<Decorator> {
minus.fillProperty().bind(Theme.foregroundFillBinding()); minus.fillProperty().bind(Theme.foregroundFillBinding());
Decorator skinnable = getSkinnable(); Decorator skinnable = getSkinnable();
root = new StackPane();
root.getStyleClass().add("window");
parent = new StackPane(); parent = new StackPane();
parent.getStyleClass().add("window"); parent.getStyleClass().add("body");
parent.backgroundProperty().bind(skinnable.backgroundProperty()); parent.backgroundProperty().bind(skinnable.contentBackgroundProperty());
parent.setPickOnBounds(false); parent.setPickOnBounds(false);
parent.prefHeightProperty().bind(control.prefHeightProperty()); parent.prefHeightProperty().bind(control.prefHeightProperty());
parent.prefWidthProperty().bind(control.prefWidthProperty()); parent.prefWidthProperty().bind(control.prefWidthProperty());
parent.setOnMouseReleased(this::onMouseReleased); root.setOnMouseReleased(this::onMouseReleased);
parent.setOnMouseDragged(this::onMouseDragged); root.setOnMouseDragged(this::onMouseDragged);
parent.setOnMouseMoved(this::onMouseMoved); root.setOnMouseMoved(this::onMouseMoved);
root.getChildren().setAll(parent);
// animation layer at bottom // animation layer at bottom
{ {
@ -93,9 +98,9 @@ public class DecoratorSkin extends SkinBase<Decorator> {
} }
StackPane wrapper = new StackPane(); StackPane wrapper = new StackPane();
BorderPane root = new BorderPane(); BorderPane frame = new BorderPane();
root.getStyleClass().addAll("jfx-decorator"); frame.getStyleClass().addAll("jfx-decorator");
wrapper.getChildren().setAll(root); wrapper.getChildren().setAll(frame);
skinnable.setDrawerWrapper(wrapper); skinnable.setDrawerWrapper(wrapper);
parent.getChildren().add(wrapper); parent.getChildren().add(wrapper);
@ -132,7 +137,7 @@ public class DecoratorSkin extends SkinBase<Decorator> {
container.getChildren().add(floatLayer); container.getChildren().add(floatLayer);
} }
root.setCenter(container); frame.setCenter(container);
titleContainer = new StackPane(); titleContainer = new StackPane();
titleContainer.setPickOnBounds(false); titleContainer.setPickOnBounds(false);
@ -174,7 +179,7 @@ public class DecoratorSkin extends SkinBase<Decorator> {
titleBar.setCenter(navBarPane); titleBar.setCenter(navBarPane);
titleBar.setRight(buttonsContainerPlaceHolder); titleBar.setRight(buttonsContainerPlaceHolder);
} }
root.setTop(titleContainer); frame.setTop(titleContainer);
{ {
HBox buttonsContainer = new HBox(); HBox buttonsContainer = new HBox();
@ -204,7 +209,7 @@ public class DecoratorSkin extends SkinBase<Decorator> {
parent.getChildren().add(layer); 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) { 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<Decorator> {
} }
private boolean isRightEdge(double x, double y, Bounds boundsInParent) { 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) { 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) { 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) { 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) { private boolean setStageWidth(double width) {
@ -341,48 +346,46 @@ public class DecoratorSkin extends SkinBase<Decorator> {
updateInitMouseValues(mouseEvent); updateInitMouseValues(mouseEvent);
if (primaryStage.isResizable()) { if (primaryStage.isResizable()) {
double x = mouseEvent.getX(), y = mouseEvent.getY(); double x = mouseEvent.getX(), y = mouseEvent.getY();
Bounds boundsInParent = parent.getBoundsInParent(); Bounds boundsInParent = root.getBoundsInParent();
if (parent.getBorder() != null && parent.getBorder().getStrokes().size() > 0) { double diagonalSize = root.snappedLeftInset() + 10;
double diagonalSize = parent.snappedLeftInset() + 10; if (this.isRightEdge(x, y, boundsInParent)) {
if (this.isRightEdge(x, y, boundsInParent)) { if (y < diagonalSize) {
if (y < diagonalSize) { root.setCursor(Cursor.NE_RESIZE);
parent.setCursor(Cursor.NE_RESIZE); } else if (y > root.getHeight() - diagonalSize) {
} else if (y > parent.getHeight() - diagonalSize) { root.setCursor(Cursor.SE_RESIZE);
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);
}
} else { } 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 { } else {
parent.setCursor(Cursor.DEFAULT); root.setCursor(Cursor.DEFAULT);
} }
} }
@ -398,7 +401,7 @@ public class DecoratorSkin extends SkinBase<Decorator> {
this.newY = mouseEvent.getScreenY(); this.newY = mouseEvent.getScreenY();
double deltaX = this.newX - this.initX; double deltaX = this.newX - this.initX;
double deltaY = this.newY - this.initY; double deltaY = this.newY - this.initY;
Cursor cursor = parent.getCursor(); Cursor cursor = root.getCursor();
if (Cursor.E_RESIZE == cursor) { if (Cursor.E_RESIZE == cursor) {
this.setStageWidth(this.primaryStage.getWidth() + deltaX); this.setStageWidth(this.primaryStage.getWidth() + deltaX);
mouseEvent.consume(); mouseEvent.consume();

View File

@ -1146,8 +1146,13 @@
} }
.window { .window {
-fx-border-color: black; -fx-background-color: transparent;
-fx-border-width: 1; -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 { .debug-border {