allow resizing main window on all four corners

fixes #995
This commit is contained in:
Sebastian Stenzel
2020-01-09 12:06:12 +01:00
parent 62cc454367
commit 35d0ccfe89
7 changed files with 191 additions and 101 deletions

View File

@@ -7,8 +7,7 @@ import javafx.fxml.FXML;
import javafx.scene.input.DragEvent;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.cryptomator.common.LicenseHolder;
import org.cryptomator.common.vaults.VaultListManager;
@@ -46,8 +45,7 @@ public class MainWindowController implements FxController {
private final BooleanProperty draggingOver = new SimpleBooleanProperty();
private final BooleanProperty draggingVaultOver = new SimpleBooleanProperty();
public HBox titleBar;
public VBox root;
public Region resizer;
public StackPane root;
private double xOffset;
private double yOffset;
@@ -74,11 +72,6 @@ public class MainWindowController implements FxController {
window.setX(event.getScreenX() - xOffset);
window.setY(event.getScreenY() - yOffset);
});
resizer.setOnMouseDragged(event -> {
// we know for a fact that window is borderless. i.e. the scene starts at 0/0 of the window.
window.setWidth(event.getSceneX());
window.setHeight(event.getSceneY());
});
updateChecker.automaticallyCheckForUpdatesIfEnabled();
root.setOnDragEntered(this::handleDragEvent);
root.setOnDragOver(this::handleDragEvent);

View File

@@ -68,6 +68,11 @@ abstract class MainWindowModule {
@FxControllerKey(MainWindowController.class)
abstract FxController bindMainWindowController(MainWindowController controller);
@Binds
@IntoMap
@FxControllerKey(ResizeController.class)
abstract FxController bindResizeController(ResizeController controller);
@Binds
@IntoMap
@FxControllerKey(VaultListController.class)

View File

@@ -0,0 +1,102 @@
package org.cryptomator.ui.mainwindow;
import javafx.fxml.FXML;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.stage.Stage;
import org.cryptomator.ui.common.FxController;
import javax.inject.Inject;
@MainWindow
public class ResizeController implements FxController {
private final Stage window;
public Region tlResizer;
public Region trResizer;
public Region blResizer;
public Region brResizer;
private double origX, origY, origW, origH;
@Inject
ResizeController(@MainWindow Stage window) {
this.window = window;
// TODO inject settings and save current position and size
}
@FXML
public void initialize() {
tlResizer.setOnMousePressed(this::startResize);
trResizer.setOnMousePressed(this::startResize);
blResizer.setOnMousePressed(this::startResize);
brResizer.setOnMousePressed(this::startResize);
tlResizer.setOnMouseDragged(this::resizeTopLeft);
trResizer.setOnMouseDragged(this::resizeTopRight);
blResizer.setOnMouseDragged(this::resizeBottomLeft);
brResizer.setOnMouseDragged(this::resizeBottomRight);
}
private void startResize(MouseEvent evt) {
origX = window.getX();
origY = window.getY();
origW = window.getWidth();
origH = window.getHeight();
}
private void resizeTopLeft(MouseEvent evt) {
resizeTop(evt);
resizeLeft(evt);
}
private void resizeTopRight(MouseEvent evt) {
resizeTop(evt);
resizeRight(evt);
}
private void resizeBottomLeft(MouseEvent evt) {
resizeBottom(evt);
resizeLeft(evt);
}
private void resizeBottomRight(MouseEvent evt) {
resizeBottom(evt);
resizeRight(evt);
}
private void resizeTop(MouseEvent evt) {
double newY = evt.getScreenY();
double dy = newY - origY;
double newH = origH - dy;
if (newH < window.getMaxHeight() && newH > window.getMinHeight()) {
window.setY(newY);
window.setHeight(newH);
}
}
private void resizeLeft(MouseEvent evt) {
double newX = evt.getScreenX();
double dx = newX - origX;
double newW = origW - dx;
if (newW < window.getMaxWidth() && newW > window.getMinWidth()) {
window.setX(newX);
window.setWidth(newW);
}
}
private void resizeBottom(MouseEvent evt) {
double newH = evt.getSceneY();
if (newH < window.getMaxHeight() && newH > window.getMinHeight()) {
window.setHeight(newH);
}
}
private void resizeRight(MouseEvent evt) {
double newW = evt.getSceneX();
if (newW < window.getMaxWidth() && newW > window.getMinWidth()) {
window.setWidth(newW);
}
}
}

View File

@@ -184,20 +184,6 @@
-fx-fill: CONTROL_WHITE_BG_ARMED;
}
.main-window .resizer {
-fx-background-color: linear-gradient(to bottom right,
transparent 50%,
CONTROL_BORDER_NORMAL 51%,
CONTROL_BORDER_NORMAL 60%,
transparent 61%,
transparent 70%,
CONTROL_BORDER_NORMAL 71%,
CONTROL_BORDER_NORMAL 80%,
transparent 81%
);
-fx-cursor: nw_resize;
}
.main-window .update-indicator {
-fx-background-color: PRIMARY_BG, white, INDICATOR_BG;
-fx-background-insets: 0, 1px, 2px;

View File

@@ -184,20 +184,6 @@
-fx-fill: CONTROL_WHITE_BG_ARMED;
}
.main-window .resizer {
-fx-background-color: linear-gradient(to bottom right,
transparent 50%,
CONTROL_BORDER_NORMAL 51%,
CONTROL_BORDER_NORMAL 60%,
transparent 61%,
transparent 70%,
CONTROL_BORDER_NORMAL 71%,
CONTROL_BORDER_NORMAL 80%,
transparent 81%
);
-fx-cursor: nw_resize;
}
.main-window .update-indicator {
-fx-background-color: PRIMARY_BG, white, INDICATOR_BG;
-fx-background-insets: 0, 1px, 2px;

View File

@@ -10,68 +10,69 @@
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<VBox xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:id="root"
fx:controller="org.cryptomator.ui.mainwindow.MainWindowController"
styleClass="main-window">
<HBox styleClass="title" fx:id="titleBar" alignment="CENTER" minHeight="50" maxHeight="50" VBox.vgrow="NEVER" spacing="6">
<padding>
<Insets bottom="6" left="12" right="12" top="6"/>
</padding>
<children>
<Label text="Cryptomator"/>
<Region HBox.hgrow="ALWAYS"/>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#showDonationKeyPreferences" focusTraversable="false" visible="${!controller.licenseHolder.validLicense}">
<graphic>
<StackPane>
<FontAwesome5IconView glyph="EXCLAMATION_CIRCLE" glyphSize="16"/>
<Region styleClass="update-indicator" StackPane.alignment="TOP_RIGHT" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.donationKeyMissing.tooltip"/>
</tooltip>
</Button>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#showPreferences" focusTraversable="false">
<graphic>
<StackPane>
<FontAwesome5IconView glyph="COGS" glyphSize="16"/>
<Region styleClass="update-indicator" visible="${controller.updateAvailable}" StackPane.alignment="TOP_RIGHT" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.preferencesBtn.tooltip"/>
</tooltip>
</Button>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#close" focusTraversable="false">
<graphic>
<FontAwesome5IconView glyph="TIMES" glyphSize="16"/>
</graphic>
<tooltip>
<Tooltip text="%main.closeBtn.tooltip"/>
</tooltip>
</Button>
</children>
</HBox>
<StackPane VBox.vgrow="ALWAYS">
<SplitPane dividerPositions="0.33" orientation="HORIZONTAL">
<fx:include source="/fxml/vault_list.fxml" SplitPane.resizableWithParent="false"/>
<fx:include source="/fxml/vault_detail.fxml" SplitPane.resizableWithParent="true"/>
</SplitPane>
<StackPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:id="root"
fx:controller="org.cryptomator.ui.mainwindow.MainWindowController"
styleClass="main-window">
<VBox>
<HBox styleClass="title" fx:id="titleBar" alignment="CENTER" minHeight="50" maxHeight="50" VBox.vgrow="NEVER" spacing="6">
<padding>
<Insets bottom="6" left="12" right="12" top="6"/>
</padding>
<children>
<Label text="Cryptomator"/>
<Region HBox.hgrow="ALWAYS"/>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#showDonationKeyPreferences" focusTraversable="false" visible="${!controller.licenseHolder.validLicense}">
<graphic>
<StackPane>
<FontAwesome5IconView glyph="EXCLAMATION_CIRCLE" glyphSize="16"/>
<Region styleClass="update-indicator" StackPane.alignment="TOP_RIGHT" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.donationKeyMissing.tooltip"/>
</tooltip>
</Button>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#showPreferences" focusTraversable="false">
<graphic>
<StackPane>
<FontAwesome5IconView glyph="COGS" glyphSize="16"/>
<Region styleClass="update-indicator" visible="${controller.updateAvailable}" StackPane.alignment="TOP_RIGHT" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.preferencesBtn.tooltip"/>
</tooltip>
</Button>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#close" focusTraversable="false">
<graphic>
<FontAwesome5IconView glyph="TIMES" glyphSize="16"/>
</graphic>
<tooltip>
<Tooltip text="%main.closeBtn.tooltip"/>
</tooltip>
</Button>
</children>
</HBox>
<StackPane VBox.vgrow="ALWAYS">
<SplitPane dividerPositions="0.33" orientation="HORIZONTAL">
<fx:include source="/fxml/vault_list.fxml" SplitPane.resizableWithParent="false"/>
<fx:include source="/fxml/vault_detail.fxml" SplitPane.resizableWithParent="true"/>
</SplitPane>
<Region styleClass="resizer" StackPane.alignment="BOTTOM_RIGHT" fx:id="resizer" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity"/>
<VBox styleClass="drag-n-drop-indicator" visible="${controller.draggingOver}" alignment="TOP_CENTER">
<HBox visible="${!controller.draggingVaultOver}" managed="${!controller.draggingVaultOver}" spacing="6" styleClass="drag-n-drop-header" alignment="CENTER" VBox.vgrow="NEVER">
<FontAwesome5IconView glyph="EXCLAMATION_TRIANGLE"/>
<Label text="%main.dropZone.unknownDragboardContent"/>
</HBox>
<HBox visible="${controller.draggingVaultOver}" managed="${controller.draggingVaultOver}" spacing="6" styleClass="drag-n-drop-header" alignment="CENTER" VBox.vgrow="NEVER">
<FontAwesome5IconView glyph="CHECK"/>
<Label text="%main.dropZone.dropVault"/>
</HBox>
<Region VBox.vgrow="ALWAYS"/>
</VBox>
</StackPane>
</VBox>
<VBox styleClass="drag-n-drop-indicator" visible="${controller.draggingOver}" alignment="TOP_CENTER">
<HBox visible="${!controller.draggingVaultOver}" managed="${!controller.draggingVaultOver}" spacing="6" styleClass="drag-n-drop-header" alignment="CENTER" VBox.vgrow="NEVER">
<FontAwesome5IconView glyph="EXCLAMATION_TRIANGLE"/>
<Label text="%main.dropZone.unknownDragboardContent"/>
</HBox>
<HBox visible="${controller.draggingVaultOver}" managed="${controller.draggingVaultOver}" spacing="6" styleClass="drag-n-drop-header" alignment="CENTER" VBox.vgrow="NEVER">
<FontAwesome5IconView glyph="CHECK"/>
<Label text="%main.dropZone.dropVault"/>
</HBox>
<Region VBox.vgrow="ALWAYS"/>
</VBox>
</StackPane>
</VBox>
<fx:include source="/fxml/main_window_resize.fxml"/>
</StackPane>

View File

@@ -0,0 +1,17 @@
<?import javafx.scene.Cursor?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Region?>
<AnchorPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="org.cryptomator.ui.mainwindow.ResizeController"
nodeOrientation="LEFT_TO_RIGHT"
pickOnBounds="false">
<fx:define>
<Cursor fx:id="nwResize" fx:constant="NW_RESIZE"/>
<Cursor fx:id="neResize" fx:constant="NE_RESIZE"/>
</fx:define>
<Region fx:id="tlResizer" cursor="${nwResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.topAnchor="0" AnchorPane.leftAnchor="0"/>
<Region fx:id="trResizer" cursor="${neResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0"/>
<Region fx:id="blResizer" cursor="${neResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
<Region fx:id="brResizer" cursor="${nwResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.bottomAnchor="0" AnchorPane.rightAnchor="0"/>
</AnchorPane>