diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java index a97351ca2..430d2f1ea 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/Config.java @@ -112,6 +112,12 @@ public final class Config implements Cloneable, Observable { @SerializedName("proxyPassword") private StringProperty proxyPass = new SimpleStringProperty(); + @SerializedName("x") + private DoubleProperty x = new SimpleDoubleProperty(); + + @SerializedName("y") + private DoubleProperty y = new SimpleDoubleProperty(); + @SerializedName("width") private DoubleProperty width = new SimpleDoubleProperty(); @@ -379,6 +385,30 @@ public final class Config implements Cloneable, Observable { return proxyPass; } + public double getX() { + return x.get(); + } + + public DoubleProperty xProperty() { + return x; + } + + public void setX(double height) { + this.x.set(height); + } + + public double getY() { + return y.get(); + } + + public DoubleProperty yProperty() { + return y; + } + + public void setY(double height) { + this.y.set(height); + } + public double getWidth() { return width.get(); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java index 8176575c0..be202785f 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/setting/ConfigUpgrader.java @@ -18,6 +18,7 @@ package org.jackhuang.hmcl.setting; import com.google.gson.Gson; +import org.jackhuang.hmcl.ui.Controllers; import org.jackhuang.hmcl.util.Lang; import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.StringUtils; @@ -36,7 +37,7 @@ final class ConfigUpgrader { private ConfigUpgrader() { } - private static final int CURRENT_VERSION = 1; + private static final int CURRENT_VERSION = 2; /** * This method is for the compatibility with old HMCL versions. @@ -122,6 +123,10 @@ final class ConfigUpgrader { } }); } + }), + Pair.pair(2, (deserialized, rawJson) -> { + deserialized.setX(0.5D - deserialized.getWidth() / Controllers.SCREEN.getBounds().getWidth() / 2); + deserialized.setY(0.5D - deserialized.getHeight() / Controllers.SCREEN.getBounds().getHeight() / 2); }) ); 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 352da31ed..acedb629c 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/ui/Controllers.java @@ -24,12 +24,14 @@ import javafx.beans.WeakInvalidationListener; import javafx.beans.property.DoubleProperty; import javafx.beans.property.ReadOnlyDoubleProperty; import javafx.beans.property.SimpleDoubleProperty; +import javafx.geometry.Rectangle2D; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.control.ButtonBase; import javafx.scene.control.Label; import javafx.scene.layout.Region; import javafx.scene.paint.Color; +import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.StageStyle; import org.jackhuang.hmcl.Launcher; @@ -66,7 +68,10 @@ import static org.jackhuang.hmcl.ui.FXUtils.newBuiltinImage; import static org.jackhuang.hmcl.util.i18n.I18n.i18n; public final class Controllers { + public static final Screen SCREEN = Screen.getPrimary(); private static InvalidationListener stageSizeChangeListener; + private static DoubleProperty stageX = new SimpleDoubleProperty(); + private static DoubleProperty stageY = new SimpleDoubleProperty(); private static DoubleProperty stageWidth = new SimpleDoubleProperty(); private static DoubleProperty stageHeight = new SimpleDoubleProperty(); @@ -143,6 +148,14 @@ public final class Controllers { public static void onApplicationStop() { stageSizeChangeListener = null; + if (stageX != null) { + config().setX(stageX.get() / SCREEN.getBounds().getWidth()); + stageX = null; + } + if (stageY != null) { + config().setY(stageY.get() / SCREEN.getBounds().getHeight()); + stageY = null; + } if (stageHeight != null) { config().setHeight(stageHeight.get()); stageHeight = null; @@ -160,7 +173,28 @@ public final class Controllers { stageSizeChangeListener = o -> { ReadOnlyDoubleProperty sourceProperty = (ReadOnlyDoubleProperty) o; - DoubleProperty targetProperty = "width".equals(sourceProperty.getName()) ? stageWidth : stageHeight; + DoubleProperty targetProperty; + switch (sourceProperty.getName()) { + case "x": { + targetProperty = stageX; + break; + } + case "y": { + targetProperty = stageY; + break; + } + case "width": { + targetProperty = stageWidth; + break; + } + case "height": { + targetProperty = stageHeight; + break; + } + default: { + targetProperty = null; + } + } if (targetProperty != null && Controllers.stage != null @@ -173,11 +207,37 @@ public final class Controllers { double initHeight = config().getHeight(); double initWidth = config().getWidth(); + double initX = config().getX() * SCREEN.getBounds().getWidth(); + double initY = config().getY() * SCREEN.getBounds().getHeight(); + { + boolean invalid = true; + double border = 20D; + for (Screen screen : Screen.getScreens()) { + Rectangle2D bound = screen.getBounds(); + + if (bound.getMinX() + border <= initX + initWidth && initX <= bound.getMaxX() - border && bound.getMinY() + border <= initY + initHeight && initY <= bound.getMaxY() - border) { + invalid = false; + break; + } + } + + if (invalid) { + initX = (0.5D - initWidth / Controllers.SCREEN.getBounds().getWidth() / 2) * SCREEN.getBounds().getWidth(); + initY = (0.5D - initHeight / Controllers.SCREEN.getBounds().getHeight() / 2) * SCREEN.getBounds().getHeight(); + } + } + + stage.setX(initX); + stage.setY(initY); stage.setHeight(initHeight); stage.setWidth(initWidth); + stageX.set(initX); + stageY.set(initY); stageHeight.set(initHeight); stageWidth.set(initWidth); + stage.xProperty().addListener(weakListener); + stage.yProperty().addListener(weakListener); stage.heightProperty().addListener(weakListener); stage.widthProperty().addListener(weakListener);