alt: allow dragging window when a dialog is shown

This commit is contained in:
huanghongxun
2020-04-17 00:16:17 +08:00
parent 1eeba344f7
commit 02ce950020
3 changed files with 35 additions and 28 deletions

View File

@@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.ui.decorator;
import com.jfoenix.controls.JFXDialog;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@@ -46,7 +47,7 @@ public class Decorator extends Control {
private final BooleanProperty canClose = new SimpleBooleanProperty(false);
private final BooleanProperty showCloseAsHome = new SimpleBooleanProperty(false);
private final Stage primaryStage;
private StackPane drawerWrapper;
private JFXDialog dialog;
public Decorator(Stage primaryStage) {
this.primaryStage = primaryStage;
@@ -58,12 +59,12 @@ public class Decorator extends Control {
return primaryStage;
}
public StackPane getDrawerWrapper() {
return drawerWrapper;
public JFXDialog getDialog() {
return dialog;
}
void setDrawerWrapper(StackPane drawerWrapper) {
this.drawerWrapper = drawerWrapper;
void setDialog(JFXDialog dialog) {
this.dialog = dialog;
}
public ObservableList<Node> getDrawer() {

View File

@@ -72,7 +72,6 @@ public class DecoratorController {
private final ImageView welcomeView;
private final Navigator navigator;
private JFXDialog dialog;
private StackContainerPane dialogPane;
public DecoratorController(Stage stage, Node mainPage) {
@@ -294,23 +293,21 @@ public class DecoratorController {
public void showDialog(Node node) {
FXUtils.checkFxUserThread();
if (dialog == null) {
if (decorator.getDrawerWrapper() == null) {
// Sometimes showDialog will be invoked before decorator was initialized.
// Keep trying again.
Platform.runLater(() -> showDialog(node));
return;
}
dialog = new JFXDialog();
dialogPane = new StackContainerPane();
dialog.setContent(dialogPane);
dialog.setDialogContainer(decorator.getDrawerWrapper());
dialog.setOverlayClose(false);
dialog.show();
if (decorator.getDialog() == null) {
// Sometimes showDialog will be invoked before decorator was initialized.
// Keep trying again.
Platform.runLater(() -> showDialog(node));
return;
}
if (dialogPane == null) {
dialogPane = new StackContainerPane();
decorator.getDialog().setContent(dialogPane);
}
if (dialogPane.isEmpty())
decorator.getDialog().show();
dialogPane.push(node);
EventHandler<DialogCloseEvent> handler = event -> closeDialog(node);
@@ -319,10 +316,10 @@ public class DecoratorController {
if (node instanceof DialogAware) {
DialogAware dialogAware = (DialogAware) node;
if (dialog.isVisible()) {
if (decorator.getDialog().isVisible()) {
dialogAware.onDialogShown();
} else {
dialog.visibleProperty().addListener(new ChangeListener<Boolean>() {
decorator.getDialog().visibleProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
@@ -342,13 +339,11 @@ public class DecoratorController {
Optional.ofNullable(node.getProperties().get(PROPERTY_DIALOG_CLOSE_HANDLER))
.ifPresent(handler -> node.removeEventHandler(DialogCloseEvent.CLOSE, (EventHandler<DialogCloseEvent>) handler));
if (dialog != null) {
if (decorator.getDialog() != null) {
dialogPane.pop(node);
if (dialogPane.getChildren().isEmpty()) {
dialog.close();
dialog = null;
dialogPane = null;
decorator.getDialog().close();
}
}
}

View File

@@ -18,6 +18,7 @@
package org.jackhuang.hmcl.ui.decorator;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialog;
import com.jfoenix.svg.SVGGlyph;
import javafx.beans.binding.Bindings;
import javafx.collections.ListChangeListener;
@@ -97,7 +98,17 @@ public class DecoratorSkin extends SkinBase<Decorator> {
BorderPane root = new BorderPane();
root.getStyleClass().addAll("jfx-decorator");
wrapper.getChildren().setAll(root);
skinnable.setDrawerWrapper(wrapper);
JFXDialog dialog = new JFXDialog();
dialog.setDialogContainer(wrapper);
dialog.setOverlayClose(false);
dialog.addEventHandler(MouseEvent.MOUSE_ENTERED, e -> allowMove = true);
dialog.addEventHandler(MouseEvent.MOUSE_EXITED, e -> {
if (!isDragging) allowMove = false;
});
skinnable.setDialog(dialog);
parent.getChildren().add(wrapper);
// center node with a animation layer at bottom, a container layer at middle and a "welcome" layer at top.