removed MainWindowTitleController and ResizeController and the corresponding fxml

This commit is contained in:
Jan-Peter Klein
2024-07-01 12:25:48 +02:00
parent cb7d0ade47
commit e677a0beaa
6 changed files with 6 additions and 475 deletions

View File

@@ -6,7 +6,6 @@ import dagger.Provides;
import dagger.multibindings.IntoMap;
import org.cryptomator.common.vaults.Vault;
import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.common.FxControllerKey;
import org.cryptomator.ui.common.FxmlFile;
@@ -14,6 +13,7 @@ import org.cryptomator.ui.common.FxmlLoaderFactory;
import org.cryptomator.ui.common.FxmlScene;
import org.cryptomator.ui.common.StageFactory;
import org.cryptomator.ui.common.StageInitializer;
import org.cryptomator.ui.error.ErrorComponent;
import org.cryptomator.ui.fxapp.PrimaryStage;
import org.cryptomator.ui.migration.MigrationComponent;
import org.cryptomator.ui.removevault.RemoveVaultComponent;
@@ -82,16 +82,6 @@ abstract class MainWindowModule {
@FxControllerKey(MainWindowController.class)
abstract FxController bindMainWindowController(MainWindowController controller);
@Binds
@IntoMap
@FxControllerKey(MainWindowTitleController.class)
abstract FxController bindMainWindowTitleController(MainWindowTitleController controller);
@Binds
@IntoMap
@FxControllerKey(ResizeController.class)
abstract FxController bindResizeController(ResizeController controller);
@Binds
@IntoMap
@FxControllerKey(VaultListController.class)

View File

@@ -18,22 +18,22 @@ public class MainWindowSceneFactory extends DefaultSceneFactory {
protected static final KeyCodeCombination SHORTCUT_N = new KeyCodeCombination(KeyCode.N, KeyCombination.SHORTCUT_DOWN);
protected static final KeyCodeCombination SHORTCUT_O = new KeyCodeCombination(KeyCode.O, KeyCombination.SHORTCUT_DOWN);
private final Lazy<MainWindowTitleController> mainWindowTitleController;
private final Stage window;
private final Lazy<VaultListController> vaultListController;
@Inject
public MainWindowSceneFactory(Settings settings, Lazy<MainWindowTitleController> mainWindowTitleController, Lazy<VaultListController> vaultListController) {
public MainWindowSceneFactory(Settings settings, @MainWindow Stage window, Lazy<VaultListController> vaultListController) {
super(settings);
this.mainWindowTitleController = mainWindowTitleController;
this.window = window;
this.vaultListController = vaultListController;
}
@Override
protected void setupDefaultAccelerators(Scene scene, Stage stage) {
if (SystemUtils.IS_OS_WINDOWS) {
scene.getAccelerators().put(ALT_F4, mainWindowTitleController.get()::close);
scene.getAccelerators().put(ALT_F4, window::close);
} else {
scene.getAccelerators().put(SHORTCUT_W, mainWindowTitleController.get()::close);
scene.getAccelerators().put(SHORTCUT_W, window::close);
}
scene.getAccelerators().put(SHORTCUT_N, vaultListController.get()::didClickAddNewVault);
scene.getAccelerators().put(SHORTCUT_O, vaultListController.get()::didClickAddExistingVault);

View File

@@ -1,157 +0,0 @@
package org.cryptomator.ui.mainwindow;
import org.cryptomator.common.LicenseHolder;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController;
import org.cryptomator.ui.fxapp.FxApplicationTerminator;
import org.cryptomator.ui.fxapp.FxApplicationWindows;
import org.cryptomator.ui.fxapp.UpdateChecker;
import org.cryptomator.ui.preferences.SelectedPreferencesTab;
import org.cryptomator.ui.traymenu.TrayMenuComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.fxml.FXML;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
@MainWindowScoped
public class MainWindowTitleController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(MainWindowTitleController.class);
private final Stage window;
private final FxApplicationTerminator terminator;
private final FxApplicationWindows appWindows;
private final boolean trayMenuInitialized;
private final UpdateChecker updateChecker;
private final BooleanBinding updateAvailable;
private final LicenseHolder licenseHolder;
private final Settings settings;
private final BooleanBinding showMinimizeButton;
public HBox titleBar;
private double xOffset;
private double yOffset;
@Inject
MainWindowTitleController(@MainWindow Stage window, FxApplicationTerminator terminator, FxApplicationWindows appWindows, TrayMenuComponent trayMenu, UpdateChecker updateChecker, LicenseHolder licenseHolder, Settings settings) {
this.window = window;
this.terminator = terminator;
this.appWindows = appWindows;
this.trayMenuInitialized = trayMenu.isInitialized();
this.updateChecker = updateChecker;
this.updateAvailable = updateChecker.updateAvailableProperty();
this.licenseHolder = licenseHolder;
this.settings = settings;
this.showMinimizeButton = Bindings.createBooleanBinding(this::isShowMinimizeButton, settings.showMinimizeButton, settings.showTrayIcon);
}
@FXML
public void initialize() {
LOG.trace("init MainWindowTitleController");
updateChecker.automaticallyCheckForUpdatesIfEnabled();
titleBar.setOnMousePressed(event -> {
xOffset = event.getSceneX();
yOffset = event.getSceneY();
});
titleBar.setOnMouseClicked(event -> {
if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2) {
window.setFullScreen(!window.isFullScreen());
}
});
titleBar.setOnMouseDragged(event -> {
if (window.isFullScreen()) return;
window.setX(event.getScreenX() - xOffset);
window.setY(event.getScreenY() - yOffset);
});
titleBar.setOnDragDetected(mouseDragEvent -> {
titleBar.startFullDrag();
});
titleBar.setOnMouseDragReleased(mouseDragEvent -> {
saveWindowSettings();
});
window.setOnCloseRequest(event -> {
close();
event.consume();
});
}
private void saveWindowSettings() {
settings.windowXPosition.setValue(window.getX());
settings.windowYPosition.setValue(window.getY());
settings.windowWidth.setValue(window.getWidth());
settings.windowHeight.setValue(window.getHeight());
}
@FXML
public void close() {
if (trayMenuInitialized) {
window.close();
} else {
terminator.terminate();
}
}
@FXML
public void minimize() {
window.setIconified(true);
}
@FXML
public void showPreferences() {
appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY);
}
@FXML
public void showGeneralPreferences() {
appWindows.showPreferencesWindow(SelectedPreferencesTab.GENERAL);
}
@FXML
public void showContributePreferences() {
appWindows.showPreferencesWindow(SelectedPreferencesTab.CONTRIBUTE);
}
/* Getter/Setter */
public LicenseHolder getLicenseHolder() {
return licenseHolder;
}
public BooleanBinding updateAvailableProperty() {
return updateAvailable;
}
public boolean isUpdateAvailable() {
return updateAvailable.get();
}
public boolean isTrayIconPresent() {
return trayMenuInitialized;
}
public ReadOnlyBooleanProperty debugModeEnabledProperty() {
return settings.debugMode;
}
public boolean isDebugModeEnabled() {
return debugModeEnabledProperty().get();
}
public BooleanBinding showMinimizeButtonProperty() {
return showMinimizeButton;
}
public boolean isShowMinimizeButton() {
// always show the minimize button if no tray icon is present OR it is explicitly enabled
return !trayMenuInitialized || settings.showMinimizeButton.get();
}
}

View File

@@ -1,194 +0,0 @@
package org.cryptomator.ui.mainwindow;
import org.cryptomator.common.settings.Settings;
import org.cryptomator.ui.common.FxController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import javafx.beans.binding.BooleanBinding;
import javafx.fxml.FXML;
import javafx.geometry.Rectangle2D;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
@MainWindow
public class ResizeController implements FxController {
private static final Logger LOG = LoggerFactory.getLogger(ResizeController.class);
private final Stage window;
public Region tlResizer;
public Region trResizer;
public Region blResizer;
public Region brResizer;
public Region tResizer;
public Region rResizer;
public Region bResizer;
public Region lResizer;
public Region lDefaultRegion;
public Region tDefaultRegion;
public Region rDefaultRegion;
public Region bDefaultRegion;
private double origX, origY, origW, origH;
private final Settings settings;
private final BooleanBinding showResizingArrows;
@Inject
ResizeController(@MainWindow Stage window, Settings settings) {
this.window = window;
this.settings = settings;
this.showResizingArrows = window.fullScreenProperty().not();
}
@FXML
public void initialize() {
LOG.trace("init ResizeController");
if (!neverTouched()) {
window.setHeight(settings.windowHeight.get() > window.getMinHeight() ? settings.windowHeight.get() : window.getMinHeight());
window.setWidth(settings.windowWidth.get() > window.getMinWidth() ? settings.windowWidth.get() : window.getMinWidth());
window.setX(settings.windowXPosition.get());
window.setY(settings.windowYPosition.get());
}
window.setOnShowing(this::checkDisplayBounds);
}
private boolean neverTouched() {
return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0);
}
private void checkDisplayBounds(WindowEvent evt) {
// Minimizing a window in Windows and closing it could result in an out of bounds position at (x, y) = (-32000, -32000)
// See https://devblogs.microsoft.com/oldnewthing/20041028-00/?p=37453
// If the position is (-32000, -32000), restore to the last saved position
if (window.getX() == -32000 && window.getY() == -32000) {
window.setX(settings.windowXPosition.get());
window.setY(settings.windowYPosition.get());
window.setWidth(settings.windowWidth.get());
window.setHeight(settings.windowHeight.get());
}
if (isOutOfDisplayBounds()) {
// If the position is illegal, then the window appears on the main screen in the middle of the window.
LOG.debug("Resetting window position due to insufficient screen overlap");
Rectangle2D primaryScreenBounds = Screen.getPrimary().getBounds();
window.setX((primaryScreenBounds.getWidth() - window.getMinWidth()) / 2);
window.setY((primaryScreenBounds.getHeight() - window.getMinHeight()) / 2);
window.setWidth(window.getMinWidth());
window.setHeight(window.getMinHeight());
savePositionalSettings();
}
}
private boolean isOutOfDisplayBounds() {
// define a rect which is inset on all sides from the window's rect:
final double x = window.getX() + 20; // 20px left
final double y = window.getY() + 5; // 5px top
final double w = window.getWidth() - 40; // 20px left + 20px right
final double h = window.getHeight() - 25; // 5px top + 20px bottom
return isRectangleOutOfScreen(x, y, 0, h) // Left pixel column
|| isRectangleOutOfScreen(x + w, y, 0, h) // Right pixel column
|| isRectangleOutOfScreen(x, y, w, 0) // Top pixel row
|| isRectangleOutOfScreen(x, y + h, w, 0); // Bottom pixel row
}
private boolean isRectangleOutOfScreen(double x, double y, double width, double height) {
return Screen.getScreensForRectangle(x, y, width, height).isEmpty();
}
private void startResize(MouseEvent evt) {
origX = window.getX();
origY = window.getY();
origW = window.getWidth();
origH = window.getHeight();
}
@FXML
private void resizeTopLeft(MouseEvent evt) {
resizeTop(evt);
resizeLeft(evt);
}
@FXML
private void resizeTopRight(MouseEvent evt) {
resizeTop(evt);
resizeRight(evt);
}
@FXML
private void resizeBottomLeft(MouseEvent evt) {
resizeBottom(evt);
resizeLeft(evt);
}
@FXML
private void resizeBottomRight(MouseEvent evt) {
resizeBottom(evt);
resizeRight(evt);
}
@FXML
private void resizeTop(MouseEvent evt) {
startResize(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);
}
}
@FXML
private void resizeLeft(MouseEvent evt) {
startResize(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);
}
}
@FXML
private void resizeBottom(MouseEvent evt) {
double newH = evt.getSceneY();
if (newH < window.getMaxHeight() && newH > window.getMinHeight()) {
window.setHeight(newH);
}
}
@FXML
private void resizeRight(MouseEvent evt) {
double newW = evt.getSceneX();
if (newW < window.getMaxWidth() && newW > window.getMinWidth()) {
window.setWidth(newW);
}
}
@FXML
public void savePositionalSettings() {
settings.windowWidth.setValue(window.getWidth());
settings.windowHeight.setValue(window.getHeight());
settings.windowXPosition.setValue(window.getX());
settings.windowYPosition.setValue(window.getY());
}
public BooleanBinding showResizingArrowsProperty() {
return showResizingArrows;
}
public boolean isShowResizingArrows() {
return showResizingArrows.get();
}
}

View File

@@ -1,30 +0,0 @@
<?import javafx.scene.Cursor?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Region?>
<AnchorPane xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
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"/>
<Cursor fx:id="nsResize" fx:constant="N_RESIZE"/>
<Cursor fx:id="ewResize" fx:constant="E_RESIZE"/>
<Cursor fx:id="default" fx:constant="DEFAULT"/>
</fx:define>
<Region fx:id="tlResizer" cursor="${nwResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeTopLeft" onMouseReleased="#savePositionalSettings" AnchorPane.topAnchor="0" AnchorPane.leftAnchor="0"/>
<Region fx:id="trResizer" cursor="${neResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeTopRight" onMouseReleased="#savePositionalSettings" AnchorPane.topAnchor="0" AnchorPane.rightAnchor="0"/>
<Region fx:id="blResizer" cursor="${neResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeBottomLeft" onMouseReleased="#savePositionalSettings" AnchorPane.bottomAnchor="0" AnchorPane.leftAnchor="0"/>
<Region fx:id="brResizer" cursor="${nwResize}" prefWidth="10" prefHeight="10" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeBottomRight" onMouseReleased="#savePositionalSettings" AnchorPane.bottomAnchor="0" AnchorPane.rightAnchor="0"/>
<Region fx:id="tResizer" cursor="${nsResize}" prefWidth="0" prefHeight="6" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeTop" onMouseReleased="#savePositionalSettings" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="0.0"/>
<Region fx:id="rResizer" cursor="${ewResize}" prefWidth="6" prefHeight="0" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeRight" onMouseReleased="#savePositionalSettings" AnchorPane.bottomAnchor="10.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="10.0"/>
<Region fx:id="bResizer" cursor="${nsResize}" prefWidth="6" prefHeight="6" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeBottom" onMouseReleased="#savePositionalSettings" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0"/>
<Region fx:id="lResizer" cursor="${ewResize}" prefWidth="6" prefHeight="6" maxWidth="-Infinity" maxHeight="-Infinity" visible="${controller.showResizingArrows}" managed="${controller.showResizingArrows}" onMouseDragged="#resizeLeft" onMouseReleased="#savePositionalSettings" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="0.0" AnchorPane.topAnchor="10.0"/>
<Region fx:id="lDefaultRegion" cursor="${default}" prefWidth="1" prefHeight="1" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.bottomAnchor="-1" AnchorPane.leftAnchor="-1" AnchorPane.topAnchor="-1"/>
<Region fx:id="tDefaultRegion" cursor="${default}" prefWidth="1" prefHeight="1" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.leftAnchor="-1" AnchorPane.topAnchor="-1" AnchorPane.rightAnchor="-1"/>
<Region fx:id="rDefaultRegion" cursor="${default}" prefWidth="1" prefHeight="1" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.topAnchor="-1" AnchorPane.rightAnchor="-1" AnchorPane.bottomAnchor="-1"/>
<Region fx:id="bDefaultRegion" cursor="${default}" prefWidth="1" prefHeight="1" maxWidth="-Infinity" maxHeight="-Infinity" AnchorPane.rightAnchor="-1" AnchorPane.bottomAnchor="-1" AnchorPane.leftAnchor="-1"/>
</AnchorPane>

View File

@@ -1,78 +0,0 @@
<?import org.cryptomator.ui.controls.FontAwesome5IconView?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tooltip?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.Region?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<HBox xmlns:fx="http://javafx.com/fxml"
xmlns="http://javafx.com/javafx"
fx:id="titleBar"
fx:controller="org.cryptomator.ui.mainwindow.MainWindowTitleController"
styleClass="title"
alignment="CENTER"
minHeight="50"
maxHeight="50"
spacing="6">
<padding>
<Insets bottom="6" left="12" right="12" top="6"/>
</padding>
<children>
<ImageView HBox.hgrow="ALWAYS" fitHeight="14" preserveRatio="true" cache="true">
<Image url="@../img/title-logo.png"/>
</ImageView>
<Region HBox.hgrow="ALWAYS"/>
<Hyperlink onAction="#showGeneralPreferences" focusTraversable="false" visible="${controller.debugModeEnabled}" styleClass="badge-debug" text="DEBUG MODE" textFill="white">
<tooltip>
<Tooltip text="%main.debugModeEnabled.tooltip"/>
</tooltip>
</Hyperlink>
<Region HBox.hgrow="ALWAYS"/>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#showContributePreferences" focusTraversable="false" visible="${!controller.licenseHolder.validLicense}">
<graphic>
<StackPane>
<FontAwesome5IconView glyph="EXCLAMATION_CIRCLE" glyphSize="16"/>
<Region styleClass="update-indicator" StackPane.alignment="TOP_RIGHT" prefWidth="12" prefHeight="12" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.supporterCertificateMissing.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="12" prefHeight="12" maxWidth="-Infinity" maxHeight="-Infinity"/>
</StackPane>
</graphic>
<tooltip>
<Tooltip text="%main.preferencesBtn.tooltip"/>
</tooltip>
</Button>
<Button contentDisplay="GRAPHIC_ONLY" mnemonicParsing="false" onAction="#minimize" focusTraversable="false" visible="${controller.showMinimizeButton}" managed="${controller.showMinimizeButton}">
<graphic>
<FontAwesome5IconView glyph="WINDOW_MINIMIZE" glyphSize="12"/>
</graphic>
<tooltip>
<Tooltip text="%main.minimizeBtn.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>