Package org.ugate.gui.components

Source Code of org.ugate.gui.components.AppFrame$WindowReziseButton

package org.ugate.gui.components;

import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

import org.ugate.resources.RS;

import com.sun.javafx.Utils;

/**
* Application frame that takes place of the typical native window look and feel.
* The content will be sized to fit in the frame.
*/
public class AppFrame extends StackPane {
 
  public static final double TOP_LEFT_WIDTH = 90;
  public static final double TOP_RIGHT_WIDTH = 140;
  public static final double TOP_BORDER_HEIGHT = 80;
  public static final double TOP_BORDER_CONTENT_ADJUSTMENT = 11;
  public static final double BOTTOM_LEFT_WIDTH = 70;
  public static final double BOTTOM_RIGHT_WIDTH = 70;
  public static final double BOTTOM_BORDER_HEIGHT = 40;
  public static final double BOTTOM_BORDER_CONTENT_ADJUSTMENT = 11;
  public static final double LEFT_BORDER_WIDTH = 1;
  public static final double RIGHT_BORDER_WIDTH = 1;
  public static final double TOP_MIN_MAX_CLOSE_ADJUSTMENT = 5;
  // Icon frame is 5 pixels from the left edge of the title bar
  public static final double LOGO_X_OFFSET = 3d;
  // Icon frame has a diameter of 64 pixels. Therefore, offset is 64/4
  public static final double LOGO_Y_OFFSET = -16d;
  private final HBox titleBarCenter;
  private Rectangle2D backupWindowBounds;
    private double mouseDragOffsetX = 0;
    private double mouseDragOffsetY = 0;

  public AppFrame(final Stage stage, final Region content, final double sceneWidth, final double sceneHeight,
      final double minResizableWidth, final double minResizableHeight, final boolean isResizable,
      final String[] cssPaths, final Region... titleBarItems) {
    // when showing/hiding the width/height end up skewed
    stage.setOnShown(new EventHandler<WindowEvent>() {
      @Override
      public void handle(final WindowEvent event) {
        Platform.runLater(new Runnable() {
          @Override
          public void run() {
            stage.setIconified(false);
            stage.setWidth(minResizableWidth);
            stage.setHeight(minResizableHeight);
            stage.toFront();
            stage.centerOnScreen();
          }
        });
      }
    });
    // stage/scene adjustment for transparency/size
    this.setMinSize(minResizableWidth, minResizableHeight);
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.setScene(new Scene(this, sceneWidth, sceneHeight, Color.TRANSPARENT));
    setAlignment(Pos.TOP_LEFT);
    if (cssPaths != null) {
      for (final String cssPath : cssPaths) {
        stage.getScene().getStylesheets().add(cssPath);
      }
    }

//      final ImageView logoView = RS.imgView(RS.IMG_LOGO_48);
//      logoView.setTranslateX(LOGO_X_OFFSET + logoView.getImage().getWidth() / 2d);
//      logoView.setTranslateY(LOGO_Y_OFFSET + logoView.getImage().getHeight() / 2d);
      final ImageView logoView = RS.imgView(RS.IMG_LOGO_128, 64d, 64d, true, true);
      logoView.setTranslateX(LOGO_X_OFFSET + logoView.getImage().getRequestedWidth() / 4d);
      logoView.setTranslateY(LOGO_Y_OFFSET + logoView.getImage().getRequestedHeight() / 4d);
//      final ScaleTransition logoViewEffect = new ScaleTransition(Duration.seconds(4), logoView);
//      logoViewEffect.setByX(0.5f);
//      logoViewEffect.setByY(0.5f);
//      logoViewEffect.setCycleCount(1);
//      logoView.setOnMouseEntered(new EventHandler<MouseEvent>() {
//      @Override
//      public void handle(MouseEvent event) {
//        if (logoViewEffect.getStatus() != javafx.animation.Animation.Status.RUNNING) {
//          logoViewEffect.stop();
//        }
//        logoViewEffect.setRate(1);
//        logoViewEffect.play();
//      }
//    });
//      logoView.setOnMouseExited(new EventHandler<MouseEvent>() {
//      @Override
//      public void handle(MouseEvent event) {
//        if (logoViewEffect.getStatus() == javafx.animation.Animation.Status.RUNNING) {
//          logoViewEffect.stop();
//          logoViewEffect.setRate(-1);
//          logoViewEffect.play();
//        }
//      }
//    });
     
      // title bar
      final HBox titleBar = new HBox();
      //titleBar.setStyle("-fx-background-color: black;");
      titleBar.setPrefHeight(TOP_BORDER_HEIGHT);
      titleBar.setMaxHeight(TOP_BORDER_HEIGHT);
      titleBar.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent event) {
                mouseDragOffsetX = event.getSceneX();
                mouseDragOffsetY = event.getSceneY();
            }
        });
      titleBar.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override public void handle(MouseEvent event) {
              if (!(event.getTarget() instanceof ImageView)) {
                    stage.setX(event.getScreenX() - mouseDragOffsetX);
                    stage.setY(event.getScreenY() - mouseDragOffsetY);
              }
            }
        });
        final Region titleBarLeft = new Region();
        titleBarLeft.setId("title-bar-left");
        titleBarLeft.setPrefWidth(TOP_LEFT_WIDTH);
        titleBarLeft.setMaxWidth(TOP_LEFT_WIDTH);
      titleBarCenter = new HBox(0);
      titleBarCenter.setId("title-bar");
      titleBarCenter.setAlignment(Pos.TOP_LEFT);
      updateTitleBarItems(titleBarItems);
        HBox.setHgrow(titleBarCenter, Priority.ALWAYS);
      final HBox titleBarRight = newMinMaxClose(stage);
      titleBarRight.setId("title-bar-right");
      titleBarRight.setPrefWidth(TOP_RIGHT_WIDTH);
        titleBarRight.setMaxWidth(TOP_RIGHT_WIDTH);
      //titleBarRight.getChildren().add(newMinMaxClose(stage, 0, TOP_BORDER_HEIGHT / 2 + TOP_MIN_MAX_CLOSE_Y));
        titleBar.getChildren().addAll(titleBarLeft, titleBarCenter, titleBarRight);
     
      final VBox leftBar = new VBox();
      leftBar.setId("border-left");
      leftBar.setPrefWidth(LEFT_BORDER_WIDTH);
      leftBar.setMaxWidth(LEFT_BORDER_WIDTH);
      leftBar.setTranslateX(1);
      Bindings.bindBidirectional(leftBar.translateYProperty(), content.translateYProperty());
      Bindings.bindBidirectional(leftBar.maxHeightProperty(), content.maxHeightProperty());
     
      final VBox rightBar = new VBox();
      rightBar.setId("border-right");
      rightBar.setPrefWidth(RIGHT_BORDER_WIDTH);
      rightBar.setMaxWidth(RIGHT_BORDER_WIDTH);
      Bindings.bindBidirectional(rightBar.translateYProperty(), content.translateYProperty());
      Bindings.bindBidirectional(rightBar.maxHeightProperty(), content.maxHeightProperty());
     
      final HBox statusBar = new HBox();
      //statusBar.setStyle("-fx-background-color: black;");
      statusBar.setPrefHeight(BOTTOM_BORDER_HEIGHT);
      statusBar.setMaxHeight(BOTTOM_BORDER_HEIGHT);
        final Region statusBarLeft = new Region();
        statusBarLeft.setId("status-bar-left");
        statusBarLeft.setPrefWidth(BOTTOM_LEFT_WIDTH);
        statusBarLeft.setMaxWidth(BOTTOM_LEFT_WIDTH);
      final Region statusBarCenter = new Region();
      statusBarCenter.setId("status-bar");
        HBox.setHgrow(statusBarCenter, Priority.ALWAYS);
      final HBox statusBarRight = new HBox();
      statusBarRight.setAlignment(Pos.BOTTOM_RIGHT);
      statusBarRight.setId("status-bar-right");
      statusBarRight.setPrefWidth(BOTTOM_RIGHT_WIDTH);
      statusBarRight.setMaxWidth(BOTTOM_RIGHT_WIDTH);
      if (isResizable) {
        final WindowReziseButton windowResizeButton = new WindowReziseButton(stage, this.getMinWidth(), this.getMinHeight());
        HBox.setMargin(windowResizeButton, new Insets(BOTTOM_BORDER_HEIGHT - 11, 0, 0, 0));
        statusBarRight.getChildren().addAll(windowResizeButton);
      }
        statusBar.getChildren().addAll(statusBarLeft, statusBarCenter, statusBarRight);
     
      // content adjustment
      stage.widthProperty().addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        content.setMaxWidth(stage.getWidth() - content.getTranslateX() - RIGHT_BORDER_WIDTH);
        rightBar.setTranslateX(content.getMaxWidth() - RIGHT_BORDER_WIDTH);
      }
    });
      stage.heightProperty().addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
        statusBar.setTranslateY(stage.getHeight() - BOTTOM_BORDER_HEIGHT);
        content.setMaxHeight(stage.getHeight() - content.getTranslateY() - statusBar.getMaxHeight() + BOTTOM_BORDER_CONTENT_ADJUSTMENT);
      }
    });
      content.setTranslateX(LEFT_BORDER_WIDTH);
      content.setTranslateY(TOP_BORDER_HEIGHT - TOP_BORDER_CONTENT_ADJUSTMENT);
      getChildren().addAll(content, leftBar, rightBar, titleBar, statusBar, logoView);
  }
 
  public void updateTitleBarItems(final Region... titleBarItems) {
      if (titleBarItems != null) {
        for (final Region tbi : titleBarItems) {
          tbi.setMaxHeight(USE_PREF_SIZE);
          tbi.setPrefHeight(TOP_BORDER_HEIGHT / 1.8d);
        }
        titleBarCenter.getChildren().setAll(titleBarItems);
      }
  }

  private HBox newMinMaxClose(final Stage stage) {
    final HBox box = new HBox(4);
    final ImageView minBtn = newTitleBarButton(RS.IMG_SKIN_MIN, 0.9, 0);
    minBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override
      public void handle(final MouseEvent event) {
        stage.setIconified(true);
      }
    });
    final ImageView maxBtn = newTitleBarButton(RS.IMG_SKIN_MAX, 0.9, 0);
    final Image maxImage = maxBtn.getImage();
    final Image resImage = RS.img(RS.IMG_SKIN_RESTORE);
    maxBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
                final double stageY = Utils.isMac() ? stage.getY() - 22 : stage.getY(); // TODO Workaround for RT-13980
                final Screen screen = Screen.getScreensForRectangle(stage.getX(), stageY, 1, 1).get(0);
                Rectangle2D bounds = screen.getVisualBounds();
                if (bounds.getMinX() == stage.getX() && bounds.getMinY() == stageY &&
                        bounds.getWidth() == stage.getWidth() && bounds.getHeight() == stage.getHeight()) {
                    if (backupWindowBounds != null) {
                        stage.setX(backupWindowBounds.getMinX());
                        stage.setY(backupWindowBounds.getMinY());
                        stage.setWidth(backupWindowBounds.getWidth());
                        stage.setHeight(backupWindowBounds.getHeight());
                        maxBtn.setImage(maxImage);
                    }
                } else {
                    backupWindowBounds = new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
                    final double newStageY = Utils.isMac() ? screen.getVisualBounds().getMinY() + 22 : screen.getVisualBounds().getMinY(); // TODO Workaround for RT-13980
                    stage.setX(screen.getVisualBounds().getMinX());
                    stage.setY(newStageY);
                    stage.setWidth(screen.getVisualBounds().getWidth());
                    stage.setHeight(screen.getVisualBounds().getHeight());
                    maxBtn.setImage(resImage);
                }
      }
    });
    final ImageView closeBtn = newTitleBarButton(RS.IMG_SKIN_CLOSE, 0.7, 0);
    closeBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
        Platform.exit();
      }
    });
    box.getChildren().addAll(minBtn, maxBtn, closeBtn);
    return box;
  }
 
  private ImageView newTitleBarButton(final String imageName, final double enterBrightness, final double exitedBrightness) {
      final ImageView btn = RS.imgView(imageName);
      btn.setId("title-menu");
      HBox.setMargin(btn, new Insets(TOP_BORDER_HEIGHT / 2 + TOP_MIN_MAX_CLOSE_ADJUSTMENT, 0, 0, 0));
        final ColorAdjust btnEffect = new ColorAdjust();
        //btnEffect.setContrast(enterBrightness);
        btnEffect.setBrightness(exitedBrightness);
        btn.setEffect(btnEffect);
      btn.setOnMouseEntered(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
            btnEffect.setBrightness(enterBrightness);
            //btnEffect.setContrast(exitedBrightness);
      }
    });
      btn.setOnMouseExited(new EventHandler<MouseEvent>() {
      @Override
      public void handle(MouseEvent event) {
            btnEffect.setBrightness(exitedBrightness);
            //btnEffect.setContrast(enterBrightness);
      }
    });
      return btn;
  }
 
  public class WindowReziseButton extends Region {
    private double dragOffsetX, dragOffsetY;
   
    public WindowReziseButton(final Stage stage, final double stageMinimumWidth, final double stageMinimumHeight) {
          setId("window-resize-button");
          setPrefSize(11, 11);
          setOnMousePressed(new EventHandler<MouseEvent>() {
              @Override public void handle(MouseEvent e) {
                  final double stageY = Utils.isMac() ? stage.getY() + 22 : stage.getY(); // TODO Workaround for RT-13980
                  dragOffsetX = (stage.getX() + stage.getWidth()) - e.getScreenX();
                  dragOffsetY = (stageY + stage.getHeight()) - e.getScreenY();
                  e.consume();
              }
          });
          setOnMouseDragged(new EventHandler<MouseEvent>() {
              @Override public void handle(MouseEvent e) {
                  final double stageY = Utils.isMac() ? stage.getY() + 22 : stage.getY(); // TODO Workaround for RT-13980
                  final Screen screen = Screen.getScreensForRectangle(stage.getX(), stageY, 1, 1).get(0);
                  Rectangle2D visualBounds = screen.getVisualBounds();
                  if (Utils.isMac()) visualBounds = new Rectangle2D(visualBounds.getMinX(), visualBounds.getMinY() + 22,
                          visualBounds.getWidth(), visualBounds.getHeight()); // TODO Workaround for RT-13980
                  double maxX = Math.min(visualBounds.getMaxX(), e.getScreenX() + dragOffsetX);
                  double maxY = Math.min(visualBounds.getMaxY(), e.getScreenY() - dragOffsetY);
                  stage.setWidth(Math.max(stageMinimumWidth, maxX - stage.getX()));
                  stage.setHeight(Math.max(stageMinimumHeight, maxY - stageY));
                  e.consume();
              }
          });
    }
  }
}
TOP

Related Classes of org.ugate.gui.components.AppFrame$WindowReziseButton

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.