in-sideFX / Undecorator

Decorate "Undecorated" JavaFX windows
118 stars 30 forks source link

No resize possible when padding is set to 0 [with fix] #5

Closed arwinvdv closed 2 years ago

arwinvdv commented 10 years ago

Hi, First of all, many thanks for this great project! I found 1 little bug, if you set the padding to 0, you cannot resize the windows anymore. If you overwrite the following rules, you can resize the window without the padding:

Undecorator.java line 241:

undecoratorController.setStageResizableWith(stage, clientArea, RESIZE_PADDING, SHADOW_WIDTH);

Undecorator.java line 266:

super.getChildren().addAll(shadowRectangle, clientArea, stageDecoration, glassPane);

I don't know if this is a good solution, but it works for me..

in-sideFX commented 10 years ago

Hi, First, thank you for your support. Regarding the "bug", I wouldn't say that putting 0 as "ResizePadding" and having the resize feature no longer available, is a bug :-). Anyway, I've tested your code, and the resize feature works, but it introduces an issue in the demo app, I no longer can move the window use mouse drag. Do you? Thanks.

arwinvdv commented 10 years ago

Hi, No, i have noticed that too so i made some changes: i have deleted (commented out) this call in Undecorator.java (on 2 places)

        undecoratorController.setAsStageDraggable(stage, node);

And i have replace the following method in UndecoratorController.java:

 public void setStageResizableWith(final Stage stage, final Node node, int PADDING, int SHADOW) {

        RESIZE_PADDING = PADDING;
        SHADOW_WIDTH = SHADOW;
        //node.toFront();
        node.setOnMouseClicked(new EventHandler<MouseEvent>() {
            // Maximize on double click
            @Override
            public void handle(MouseEvent mouseEvent) {
                if (undecorator.getStageStyle() != StageStyle.UTILITY && !stage.isFullScreen() && mouseEvent.getClickCount() > 1) {
                    if (mouseEvent.getSceneY() - SHADOW_WIDTH < MAXIMIZE_BORDER) {
                        undecorator.maximizeProperty().set(!undecorator.maximizeProperty().get());
                        mouseEvent.consume();
                    }
                }
            }
        });

        node.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                if (mouseEvent.isPrimaryButtonDown()) {
                    initX = mouseEvent.getScreenX();
                    initY = mouseEvent.getScreenY();
                    mouseEvent.consume();
                } else {
                    initX = -1;
                    initY = -1;
                }
            }
        });
        node.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {

                if (!mouseEvent.isPrimaryButtonDown() || (initX == -1 && initY == -1)) {
                    return;
                }
                if (stage.isFullScreen()) {
                    return;
                }
                /*
                 * Long press generates drag event!
                 */
                if (mouseEvent.isStillSincePress()) {
                    return;
                }
                if (maximized) {
                    // Remove maximized state
                    undecorator.maximizeProperty.set(false);
                    // Center 
                    stage.setX(mouseEvent.getScreenX() - stage.getWidth() / 2);
                    stage.setY(mouseEvent.getScreenY() - SHADOW_WIDTH);
                    return;
                } // Docked then moved, so restore state
                else if (savedBounds != null) {
                    restoreSavedBounds(stage, false);
                    undecorator.setShadow(true);
                    // Center
                    stage.setX(mouseEvent.getScreenX() - stage.getWidth() / 2);
                    stage.setY(mouseEvent.getScreenY() - SHADOW_WIDTH);
                }

                newX = mouseEvent.getScreenX();
                newY = mouseEvent.getScreenY();
                double deltax = newX - initX;
                double deltay = newY - initY;

                initX = newX;
                initY = newY;

                Cursor cursor = node.getCursor();
                if (Cursor.E_RESIZE.equals(cursor)) {
                    setStageWidth(stage, stage.getWidth() + deltax);
                    mouseEvent.consume();
                } else if (Cursor.NE_RESIZE.equals(cursor)) {
                    if (setStageHeight(stage, stage.getHeight() - deltay)) {
                        setStageY(stage, stage.getY() + deltay);
                    }
                    setStageWidth(stage, stage.getWidth() + deltax);
                    mouseEvent.consume();
                } else if (Cursor.SE_RESIZE.equals(cursor)) {
                    setStageWidth(stage, stage.getWidth() + deltax);
                    setStageHeight(stage, stage.getHeight() + deltay);
                    mouseEvent.consume();
                } else if (Cursor.S_RESIZE.equals(cursor)) {
                    setStageHeight(stage, stage.getHeight() + deltay);
                    mouseEvent.consume();
                } else if (Cursor.W_RESIZE.equals(cursor)) {
                    if (setStageWidth(stage, stage.getWidth() - deltax)) {
                        stage.setX(stage.getX() + deltax);
                    }
                    mouseEvent.consume();
                } else if (Cursor.SW_RESIZE.equals(cursor)) {
                    if (setStageWidth(stage, stage.getWidth() - deltax)) {
                        stage.setX(stage.getX() + deltax);
                    }
                    setStageHeight(stage, stage.getHeight() + deltay);
                    mouseEvent.consume();
                } else if (Cursor.NW_RESIZE.equals(cursor)) {
                    if (setStageWidth(stage, stage.getWidth() - deltax)) {
                        stage.setX(stage.getX() + deltax);
                    }
                    if (setStageHeight(stage, stage.getHeight() - deltay)) {
                        setStageY(stage, stage.getY() + deltay);
                    }
                    mouseEvent.consume();
                } else if (Cursor.N_RESIZE.equals(cursor)) {
                    if (setStageHeight(stage, stage.getHeight() - deltay)) {
                        setStageY(stage, stage.getY() + deltay);
                    }
                    mouseEvent.consume();
                } else {
                    setCursor(node, Cursor.HAND);
                    stage.setX(stage.getX() + deltax);
                    setStageY(stage, stage.getY() + deltay);

                    testDock(stage, mouseEvent);
                    mouseEvent.consume();
                }

            }
        });
        node.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent mouseEvent) {
                if (maximized) {
                    setCursor(node, Cursor.DEFAULT);
                    return; // maximized mode does not support resize
                }
                if (stage.isFullScreen()) {
                    return;
                }
                if (!stage.isResizable()) {
                    return;
                }

                double x = mouseEvent.getX();
                double y = mouseEvent.getY();
                Bounds boundsInParent = node.getBoundsInParent();
                if (isRightEdge(x, y, boundsInParent)) {
                    if (y < RESIZE_PADDING + SHADOW_WIDTH) {
                        setCursor(node, Cursor.NE_RESIZE);
                    } else if (y > boundsInParent.getHeight() - (double) (RESIZE_PADDING + SHADOW_WIDTH)) {
                        setCursor(node, Cursor.SE_RESIZE);
                    } else {
                        setCursor(node, Cursor.E_RESIZE);
                    }

                } else if (isLeftEdge(x, y, boundsInParent)) {
                    if (y < RESIZE_PADDING + SHADOW_WIDTH) {
                        setCursor(node, Cursor.NW_RESIZE);
                    } else if (y > boundsInParent.getHeight() - (double) (RESIZE_PADDING + SHADOW_WIDTH)) {
                        setCursor(node, Cursor.SW_RESIZE);
                    } else {
                        setCursor(node, Cursor.W_RESIZE);
                    }
                } else if (isTopEdge(x, y, boundsInParent)) {
                    setCursor(node, Cursor.N_RESIZE);
                } else if (isBottomEdge(x, y, boundsInParent)) {
                    setCursor(node, Cursor.S_RESIZE);
                } else {
                    setCursor(node, Cursor.DEFAULT);
                }
            }
        });
        node.setOnMouseReleased(new EventHandler<MouseEvent>() { //By Arwin
            @Override
            public void handle(MouseEvent t) {
                if (stage.isResizable()) {
                    undecorator.setDockFeedbackInvisible();
                    setCursor(node, Cursor.DEFAULT);
                    initX = -1;
                    initY = -1;
                    dockActions(stage, t);
                }
            }
        });
    }

Now it works well with 1 display, with multiple displays it wil automaticly grab another screen.. But its now good enough for me.