From e038348dcadcdbe10b4bceb261e5d21faea406b8 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Tue, 28 May 2024 21:56:03 +0200 Subject: [PATCH 01/28] changed mainWindow StageStyle to UNDECORATED removed main_window_title area moved main_window_resize functions to MainWindowController put add vault button under the vault list and wrapped both in a ScrollPane bound vault list height properties to amount of entries and width to scroll pane width add listener to scroll down after adding a vault moved preferences button under vault list new style classes for new elements changed wording --- .../ui/mainwindow/MainWindowController.java | 28 +++++++++- .../ui/mainwindow/MainWindowModule.java | 1 - .../ui/mainwindow/VaultListController.java | 29 +++++++++- src/main/resources/css/dark_theme.css | 21 ++++++++ src/main/resources/css/light_theme.css | 20 +++++++ src/main/resources/fxml/main_window.fxml | 2 - src/main/resources/fxml/vault_list.fxml | 54 ++++++++++++------- src/main/resources/i18n/strings.properties | 2 +- 8 files changed, 132 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java index b2c912834..a09c3afba 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java @@ -1,6 +1,7 @@ package org.cryptomator.ui.mainwindow; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.common.settings.Settings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.common.FxController; @@ -22,13 +23,15 @@ public class MainWindowController implements FxController { private final Stage window; private final ReadOnlyObjectProperty selectedVault; + private final Settings settings; public StackPane root; @Inject - public MainWindowController(@MainWindow Stage window, ObjectProperty selectedVault) { + public MainWindowController(@MainWindow Stage window, ObjectProperty selectedVault, Settings settings) { this.window = window; this.selectedVault = selectedVault; + this.settings = settings; } @FXML @@ -38,6 +41,29 @@ public class MainWindowController implements FxController { root.getStyleClass().add("os-windows"); } window.focusedProperty().addListener(this::mainWindowFocusChanged); + + 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.widthProperty().addListener((_,_,_) -> savePositionalSettings()); + window.heightProperty().addListener((_,_,_) -> savePositionalSettings()); + window.xProperty().addListener((_,_,_) -> savePositionalSettings()); + window.yProperty().addListener((_,_,_) -> savePositionalSettings()); + } + + private boolean neverTouched() { + return (settings.windowHeight.get() == 0) && (settings.windowWidth.get() == 0) && (settings.windowXPosition.get() == 0) && (settings.windowYPosition.get() == 0); + } + + @FXML + public void savePositionalSettings() { + settings.windowWidth.setValue(window.getWidth()); + settings.windowHeight.setValue(window.getHeight()); + settings.windowXPosition.setValue(window.getX()); + settings.windowYPosition.setValue(window.getY()); } private void mainWindowFocusChanged(Observable observable) { diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java index 0b403bb47..bfddabf46 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java @@ -41,7 +41,6 @@ abstract class MainWindowModule { static Stage provideMainWindow(@PrimaryStage Stage stage, StageInitializer initializer) { initializer.accept(stage); stage.setTitle("Cryptomator"); - stage.initStyle(StageStyle.UNDECORATED); stage.setMinWidth(650); stage.setMinHeight(440); return stage; diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index e8ea21fe4..76a69ad14 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -9,6 +9,7 @@ import org.cryptomator.ui.addvaultwizard.AddVaultWizardComponent; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.VaultService; import org.cryptomator.ui.fxapp.FxApplicationWindows; +import org.cryptomator.ui.preferences.SelectedPreferencesTab; import org.cryptomator.ui.removevault.RemoveVaultComponent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,13 +28,16 @@ import javafx.geometry.Side; import javafx.scene.control.Button; import javafx.scene.control.ContextMenu; import javafx.scene.control.ListView; +import javafx.scene.control.ScrollPane; import javafx.scene.input.ContextMenuEvent; import javafx.scene.input.DragEvent; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.input.TransferMode; +import javafx.scene.layout.HBox; import javafx.scene.layout.StackPane; +import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.io.File; import java.io.IOException; @@ -71,8 +75,11 @@ public class VaultListController implements FxController { private final FxApplicationWindows appWindows; public ListView vaultList; + public ScrollPane scrollPane; + public VBox vbox; public StackPane root; public Button addVaultBtn; + public HBox addVaultArea; @FXML private ContextMenu addVaultContextMenu; @@ -106,6 +113,21 @@ public class VaultListController implements FxController { public void initialize() { vaultList.setItems(vaults); vaultList.setCellFactory(cellFactory); + + vaultList.prefHeightProperty().bind(vaultList.fixedCellSizeProperty().multiply(vaultList.getItems().size())); + vaultList.maxHeightProperty().bind(vaultList.prefHeightProperty()); + vaultList.prefWidthProperty().bind(scrollPane.widthProperty()); + + vbox.heightProperty().addListener((_, oldValue, newValue) -> { + if(newValue.doubleValue()>oldValue.doubleValue()){ + scrollPane.setVvalue(1.0); + } + }); + + vaults.addListener((ListChangeListener) c -> { + vaultList.prefHeightProperty().bind(vaultList.fixedCellSizeProperty().multiply(vaultList.getItems().size())); + }); + selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty()); vaults.addListener((ListChangeListener.Change c) -> { while (c.next()) { @@ -171,7 +193,7 @@ public class VaultListController implements FxController { if (addVaultContextMenu.isShowing()) { addVaultContextMenu.hide(); } else { - addVaultContextMenu.show(addVaultBtn, Side.BOTTOM, 0.0, 0.0); + addVaultContextMenu.show(addVaultArea, Side.BOTTOM, 0.0, 0.0); } } @@ -247,6 +269,11 @@ public class VaultListController implements FxController { } } + @FXML + public void showPreferences() { + appWindows.showPreferencesWindow(SelectedPreferencesTab.ANY); + } + // Getter and Setter public BooleanBinding emptyVaultListProperty() { diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css index 86d9aaa71..bba91cb11 100644 --- a/src/main/resources/css/dark_theme.css +++ b/src/main/resources/css/dark_theme.css @@ -341,6 +341,27 @@ -fx-background-color: CONTROL_BG_ARMED; } +.vault-list-box { + -fx-background-color: CONTROL_BG_NORMAL; +} + +.add-vault-btn { + -fx-background-color: CONTROL_BG_NORMAL; +} +.add-vault-btn .icon { + -fx-fill: TEXT_FILL_MUTED; +} +.add-vault-btn-label { + -fx-font-family: 'Open Sans SemiBold'; + -fx-font-size: 1.0em; +} + +.preferences-btn { + -fx-background-color: MAIN_BG; + -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent; + -fx-border-width: 1px 0 0 0; +} + /******************************************************************************* * * * ScrollBar * diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css index 88cf6d970..d000c0464 100644 --- a/src/main/resources/css/light_theme.css +++ b/src/main/resources/css/light_theme.css @@ -340,6 +340,26 @@ -fx-background-color: CONTROL_BG_ARMED; } +.vault-list-box { + -fx-background-color: CONTROL_BG_NORMAL; +} + +.add-vault-btn { + -fx-background-color: CONTROL_BG_NORMAL; +} +.add-vault-btn .icon { + -fx-fill: GRAY_4; +} +.add-vault-btn-label { + -fx-font-family: 'Open Sans SemiBold'; + -fx-font-size: 1.0em; +} + +.preferences-btn { + -fx-border-color: CONTROL_BORDER_NORMAL transparent transparent transparent; + -fx-border-width: 1px 0 0 0; +} + /******************************************************************************* * * * ScrollBar * diff --git a/src/main/resources/fxml/main_window.fxml b/src/main/resources/fxml/main_window.fxml index 2796455d3..cefa18e58 100644 --- a/src/main/resources/fxml/main_window.fxml +++ b/src/main/resources/fxml/main_window.fxml @@ -9,11 +9,9 @@ fx:controller="org.cryptomator.ui.mainwindow.MainWindowController" styleClass="main-window"> - - diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml index f9cb29258..a1fe141db 100644 --- a/src/main/resources/fxml/vault_list.fxml +++ b/src/main/resources/fxml/vault_list.fxml @@ -1,38 +1,54 @@ - - + + + - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index acdac613b..4309351b5 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -389,7 +389,7 @@ main.vaultlist.contextMenu.unlock=Unlock… main.vaultlist.contextMenu.unlockNow=Unlock Now main.vaultlist.contextMenu.vaultoptions=Show Vault Options main.vaultlist.contextMenu.reveal=Reveal Drive -main.vaultlist.addVaultBtn=Add +main.vaultlist.addVaultBtn=Add Vault main.vaultlist.addVaultBtn.menuItemNew=New Vault... main.vaultlist.addVaultBtn.menuItemExisting=Existing Vault... ## Vault Detail From cb7d0ade47289e4bf22011bdc61f982fda28b5dd Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Wed, 26 Jun 2024 13:43:21 +0200 Subject: [PATCH 02/28] fixed some SonarCloud mentioned issues --- .../java/org/cryptomator/ui/mainwindow/MainWindowModule.java | 2 -- .../org/cryptomator/ui/mainwindow/VaultListController.java | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java index bfddabf46..ff0b4421a 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java @@ -15,7 +15,6 @@ import org.cryptomator.ui.common.FxmlScene; import org.cryptomator.ui.common.StageFactory; import org.cryptomator.ui.common.StageInitializer; import org.cryptomator.ui.fxapp.PrimaryStage; -import org.cryptomator.ui.health.HealthCheckComponent; import org.cryptomator.ui.migration.MigrationComponent; import org.cryptomator.ui.removevault.RemoveVaultComponent; import org.cryptomator.ui.stats.VaultStatisticsComponent; @@ -28,7 +27,6 @@ import javafx.beans.property.SimpleObjectProperty; import javafx.scene.Scene; import javafx.stage.Modality; import javafx.stage.Stage; -import javafx.stage.StageStyle; import java.util.Map; import java.util.ResourceBundle; diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 76a69ad14..92817d321 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -124,9 +124,7 @@ public class VaultListController implements FxController { } }); - vaults.addListener((ListChangeListener) c -> { - vaultList.prefHeightProperty().bind(vaultList.fixedCellSizeProperty().multiply(vaultList.getItems().size())); - }); + vaults.addListener((ListChangeListener) _ -> vaultList.prefHeightProperty().bind(vaultList.fixedCellSizeProperty().multiply(vaultList.getItems().size()))); selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty()); vaults.addListener((ListChangeListener.Change c) -> { From d379ada10074bd114a1e0e540af53b2886567521 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Wed, 26 Jun 2024 15:13:28 +0200 Subject: [PATCH 03/28] addded debug, update and support notification bar --- .../ui/mainwindow/MainWindowController.java | 62 +++++++++++++++++-- src/main/resources/css/dark_theme.css | 29 +++++++++ src/main/resources/css/light_theme.css | 29 +++++++++ src/main/resources/fxml/main_window.fxml | 11 ++++ src/main/resources/i18n/strings.properties | 4 ++ 5 files changed, 130 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java index a09c3afba..3b73b4338 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java @@ -1,16 +1,22 @@ package org.cryptomator.ui.mainwindow; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.ui.common.FxController; +import org.cryptomator.ui.fxapp.FxApplicationWindows; +import org.cryptomator.ui.fxapp.UpdateChecker; +import org.cryptomator.ui.preferences.SelectedPreferencesTab; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.Observable; +import javafx.beans.binding.BooleanBinding; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyObjectProperty; import javafx.fxml.FXML; import javafx.scene.layout.StackPane; @@ -24,14 +30,25 @@ public class MainWindowController implements FxController { private final Stage window; private final ReadOnlyObjectProperty selectedVault; private final Settings settings; + private final FxApplicationWindows appWindows; + private final BooleanBinding updateAvailable; + private final LicenseHolder licenseHolder; public StackPane root; @Inject - public MainWindowController(@MainWindow Stage window, ObjectProperty selectedVault, Settings settings) { + public MainWindowController(@MainWindow Stage window, // + ObjectProperty selectedVault, // + Settings settings, // + FxApplicationWindows appWindows, // + UpdateChecker updateChecker, // + LicenseHolder licenseHolder) { this.window = window; this.selectedVault = selectedVault; this.settings = settings; + this.appWindows = appWindows; + this.updateAvailable = updateChecker.updateAvailableProperty(); + this.licenseHolder = licenseHolder; } @FXML @@ -48,10 +65,10 @@ public class MainWindowController implements FxController { window.setX(settings.windowXPosition.get()); window.setY(settings.windowYPosition.get()); } - window.widthProperty().addListener((_,_,_) -> savePositionalSettings()); - window.heightProperty().addListener((_,_,_) -> savePositionalSettings()); - window.xProperty().addListener((_,_,_) -> savePositionalSettings()); - window.yProperty().addListener((_,_,_) -> savePositionalSettings()); + window.widthProperty().addListener((_, _, _) -> savePositionalSettings()); + window.heightProperty().addListener((_, _, _) -> savePositionalSettings()); + window.xProperty().addListener((_, _, _) -> savePositionalSettings()); + window.yProperty().addListener((_, _, _) -> savePositionalSettings()); } private boolean neverTouched() { @@ -73,4 +90,39 @@ public class MainWindowController implements FxController { } } + @FXML + public void showGeneralPreferences() { + appWindows.showPreferencesWindow(SelectedPreferencesTab.GENERAL); + } + + @FXML + public void showContributePreferences() { + appWindows.showPreferencesWindow(SelectedPreferencesTab.CONTRIBUTE); + } + + @FXML + public void showUpdatePreferences() { + appWindows.showPreferencesWindow(SelectedPreferencesTab.UPDATES); + } + + public LicenseHolder getLicenseHolder() { + return licenseHolder; + } + + public ReadOnlyBooleanProperty debugModeEnabledProperty() { + return settings.debugMode; + } + + public boolean isDebugModeEnabled() { + return debugModeEnabledProperty().get(); + } + + public BooleanBinding updateAvailableProperty() { + return updateAvailable; + } + + public boolean isUpdateAvailable() { + return updateAvailable.get(); + } + } diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css index bba91cb11..61270eeab 100644 --- a/src/main/resources/css/dark_theme.css +++ b/src/main/resources/css/dark_theme.css @@ -362,6 +362,35 @@ -fx-border-width: 1px 0 0 0; } +/******************************************************************************* + * * + * NotificationBar * + * * + ******************************************************************************/ + +.notification-label { + -fx-text-fill: white; + -fx-font-weight: bold; +} + +.notification-debug { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: RED_5; +} + +.notification-update { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: YELLOW_5; +} + +.notification-support { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: PRIMARY; +} + /******************************************************************************* * * * ScrollBar * diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css index d000c0464..c8b7eaf79 100644 --- a/src/main/resources/css/light_theme.css +++ b/src/main/resources/css/light_theme.css @@ -360,6 +360,35 @@ -fx-border-width: 1px 0 0 0; } +/******************************************************************************* + * * + * NotificationBar * + * * + ******************************************************************************/ + +.notification-label { + -fx-text-fill: white; + -fx-font-weight: bold; +} + +.notification-debug { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: RED_5; +} + +.notification-update { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: YELLOW_5; +} + +.notification-support { + -fx-min-height:24px; + -fx-max-height:24px; + -fx-background-color: PRIMARY; +} + /******************************************************************************* * * * ScrollBar * diff --git a/src/main/resources/fxml/main_window.fxml b/src/main/resources/fxml/main_window.fxml index cefa18e58..eed8fc695 100644 --- a/src/main/resources/fxml/main_window.fxml +++ b/src/main/resources/fxml/main_window.fxml @@ -3,15 +3,26 @@ + + + + + + + + diff --git a/src/main/resources/i18n/strings.properties b/src/main/resources/i18n/strings.properties index 4309351b5..5e79550b5 100644 --- a/src/main/resources/i18n/strings.properties +++ b/src/main/resources/i18n/strings.properties @@ -392,6 +392,10 @@ main.vaultlist.contextMenu.reveal=Reveal Drive main.vaultlist.addVaultBtn=Add Vault main.vaultlist.addVaultBtn.menuItemNew=New Vault... main.vaultlist.addVaultBtn.menuItemExisting=Existing Vault... +##Notificaition +main.notification.updateAvailable=Update is available. +main.notification.support=Support Cryptomator. +main.notification.debugMode=DEBUG MODE ## Vault Detail ### Welcome main.vaultDetail.welcomeOnboarding=Thanks for choosing Cryptomator to protect your files. If you need any assistance, check out our getting started guides: From e677a0beaa8db52f36b600d036baed1bc0cee57a Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 1 Jul 2024 12:25:48 +0200 Subject: [PATCH 04/28] removed MainWindowTitleController and ResizeController and the corresponding fxml --- .../ui/mainwindow/MainWindowModule.java | 12 +- .../ui/mainwindow/MainWindowSceneFactory.java | 10 +- .../mainwindow/MainWindowTitleController.java | 157 -------------- .../ui/mainwindow/ResizeController.java | 194 ------------------ .../resources/fxml/main_window_resize.fxml | 30 --- .../resources/fxml/main_window_title.fxml | 78 ------- 6 files changed, 6 insertions(+), 475 deletions(-) delete mode 100644 src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java delete mode 100644 src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java delete mode 100644 src/main/resources/fxml/main_window_resize.fxml delete mode 100644 src/main/resources/fxml/main_window_title.fxml diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java index ff0b4421a..14bc84fd2 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowModule.java @@ -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) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java index d78192186..c297b8f0f 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowSceneFactory.java @@ -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; + private final Stage window; private final Lazy vaultListController; @Inject - public MainWindowSceneFactory(Settings settings, Lazy mainWindowTitleController, Lazy vaultListController) { + public MainWindowSceneFactory(Settings settings, @MainWindow Stage window, Lazy 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); diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java deleted file mode 100644 index f3c92790d..000000000 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowTitleController.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java b/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java deleted file mode 100644 index 2c3838ea0..000000000 --- a/src/main/java/org/cryptomator/ui/mainwindow/ResizeController.java +++ /dev/null @@ -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(); - } -} \ No newline at end of file diff --git a/src/main/resources/fxml/main_window_resize.fxml b/src/main/resources/fxml/main_window_resize.fxml deleted file mode 100644 index 7d5fb9437..000000000 --- a/src/main/resources/fxml/main_window_resize.fxml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/fxml/main_window_title.fxml b/src/main/resources/fxml/main_window_title.fxml deleted file mode 100644 index bd60aa25d..000000000 --- a/src/main/resources/fxml/main_window_title.fxml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file From 3e6204a657e032a37a1211d1643c3aa4e6f12eed Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 1 Jul 2024 12:32:50 +0200 Subject: [PATCH 05/28] remove showMinimizeButton setting --- src/main/java/org/cryptomator/common/settings/Settings.java | 4 ---- .../java/org/cryptomator/common/settings/SettingsJson.java | 3 --- .../ui/preferences/InterfacePreferencesController.java | 3 --- src/main/resources/fxml/preferences_interface.fxml | 3 --- 4 files changed, 13 deletions(-) diff --git a/src/main/java/org/cryptomator/common/settings/Settings.java b/src/main/java/org/cryptomator/common/settings/Settings.java index a54e71a4f..04facdcd0 100644 --- a/src/main/java/org/cryptomator/common/settings/Settings.java +++ b/src/main/java/org/cryptomator/common/settings/Settings.java @@ -59,7 +59,6 @@ public class Settings { public final StringProperty keychainProvider; public final ObjectProperty userInterfaceOrientation; public final StringProperty licenseKey; - public final BooleanProperty showMinimizeButton; public final BooleanProperty showTrayIcon; public final IntegerProperty windowXPosition; public final IntegerProperty windowYPosition; @@ -96,7 +95,6 @@ public class Settings { this.keychainProvider = new SimpleStringProperty(this, "keychainProvider", json.keychainProvider); this.userInterfaceOrientation = new SimpleObjectProperty<>(this, "userInterfaceOrientation", parseEnum(json.uiOrientation, NodeOrientation.class, NodeOrientation.LEFT_TO_RIGHT)); this.licenseKey = new SimpleStringProperty(this, "licenseKey", json.licenseKey); - this.showMinimizeButton = new SimpleBooleanProperty(this, "showMinimizeButton", json.showMinimizeButton); this.showTrayIcon = new SimpleBooleanProperty(this, "showTrayIcon", json.showTrayIcon); this.windowXPosition = new SimpleIntegerProperty(this, "windowXPosition", json.windowXPosition); this.windowYPosition = new SimpleIntegerProperty(this, "windowYPosition", json.windowYPosition); @@ -123,7 +121,6 @@ public class Settings { keychainProvider.addListener(this::somethingChanged); userInterfaceOrientation.addListener(this::somethingChanged); licenseKey.addListener(this::somethingChanged); - showMinimizeButton.addListener(this::somethingChanged); showTrayIcon.addListener(this::somethingChanged); windowXPosition.addListener(this::somethingChanged); windowYPosition.addListener(this::somethingChanged); @@ -177,7 +174,6 @@ public class Settings { json.keychainProvider = keychainProvider.get(); json.uiOrientation = userInterfaceOrientation.get().name(); json.licenseKey = licenseKey.get(); - json.showMinimizeButton = showMinimizeButton.get(); json.showTrayIcon = showTrayIcon.get(); json.windowXPosition = windowXPosition.get(); json.windowYPosition = windowYPosition.get(); diff --git a/src/main/java/org/cryptomator/common/settings/SettingsJson.java b/src/main/java/org/cryptomator/common/settings/SettingsJson.java index 2ded82885..1dd68e02a 100644 --- a/src/main/java/org/cryptomator/common/settings/SettingsJson.java +++ b/src/main/java/org/cryptomator/common/settings/SettingsJson.java @@ -51,9 +51,6 @@ class SettingsJson { @JsonProperty("port") int port = Settings.DEFAULT_PORT; - @JsonProperty("showMinimizeButton") - boolean showMinimizeButton = Settings.DEFAULT_SHOW_MINIMIZE_BUTTON; - @JsonProperty("showTrayIcon") boolean showTrayIcon; diff --git a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java index 40983c3f0..937431571 100644 --- a/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java +++ b/src/main/java/org/cryptomator/ui/preferences/InterfacePreferencesController.java @@ -36,7 +36,6 @@ public class InterfacePreferencesController implements FxController { private final ResourceBundle resourceBundle; private final SupportedLanguages supportedLanguages; public ChoiceBox themeChoiceBox; - public CheckBox showMinimizeButtonCheckbox; public CheckBox showTrayIconCheckbox; public ChoiceBox preferredLanguageChoiceBox; public ToggleGroup nodeOrientation; @@ -63,8 +62,6 @@ public class InterfacePreferencesController implements FxController { themeChoiceBox.valueProperty().bindBidirectional(settings.theme); themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle)); - showMinimizeButtonCheckbox.selectedProperty().bindBidirectional(settings.showMinimizeButton); - showTrayIconCheckbox.selectedProperty().bindBidirectional(settings.showTrayIcon); preferredLanguageChoiceBox.getItems().addAll(supportedLanguages.getLanguageTags()); diff --git a/src/main/resources/fxml/preferences_interface.fxml b/src/main/resources/fxml/preferences_interface.fxml index 6cb9b7d73..990b66c8c 100644 --- a/src/main/resources/fxml/preferences_interface.fxml +++ b/src/main/resources/fxml/preferences_interface.fxml @@ -37,9 +37,6 @@ - - - From d58307d1d65fd9734f9dd54e22604129c76c8b1b Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 1 Jul 2024 13:09:53 +0200 Subject: [PATCH 06/28] optimize vaultList height update to avoid repeated bindings --- .../java/org/cryptomator/ui/mainwindow/VaultListController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index 92817d321..db615061e 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -124,7 +124,7 @@ public class VaultListController implements FxController { } }); - vaults.addListener((ListChangeListener) _ -> vaultList.prefHeightProperty().bind(vaultList.fixedCellSizeProperty().multiply(vaultList.getItems().size()))); + vaultList.prefHeightProperty().bind(Bindings.size(vaultList.getItems()).multiply(vaultList.fixedCellSizeProperty())); selectedVault.bind(vaultList.getSelectionModel().selectedItemProperty()); vaults.addListener((ListChangeListener.Change c) -> { From 902c66cf1e8121578372c54503c2daed62654b67 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Mon, 1 Jul 2024 18:19:30 +0200 Subject: [PATCH 07/28] removed vbox id and renamed style --- .../org/cryptomator/ui/mainwindow/VaultListController.java | 2 +- src/main/resources/css/dark_theme.css | 2 +- src/main/resources/css/light_theme.css | 2 +- src/main/resources/fxml/vault_list.fxml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java index db615061e..dbe81bcc8 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/VaultListController.java @@ -118,7 +118,7 @@ public class VaultListController implements FxController { vaultList.maxHeightProperty().bind(vaultList.prefHeightProperty()); vaultList.prefWidthProperty().bind(scrollPane.widthProperty()); - vbox.heightProperty().addListener((_, oldValue, newValue) -> { + scrollPane.heightProperty().addListener((_, oldValue, newValue) -> { if(newValue.doubleValue()>oldValue.doubleValue()){ scrollPane.setVvalue(1.0); } diff --git a/src/main/resources/css/dark_theme.css b/src/main/resources/css/dark_theme.css index bba91cb11..d01230f09 100644 --- a/src/main/resources/css/dark_theme.css +++ b/src/main/resources/css/dark_theme.css @@ -341,7 +341,7 @@ -fx-background-color: CONTROL_BG_ARMED; } -.vault-list-box { +.left-side-panel { -fx-background-color: CONTROL_BG_NORMAL; } diff --git a/src/main/resources/css/light_theme.css b/src/main/resources/css/light_theme.css index d000c0464..7d7d53645 100644 --- a/src/main/resources/css/light_theme.css +++ b/src/main/resources/css/light_theme.css @@ -340,7 +340,7 @@ -fx-background-color: CONTROL_BG_ARMED; } -.vault-list-box { +.left-side-panel { -fx-background-color: CONTROL_BG_NORMAL; } diff --git a/src/main/resources/fxml/vault_list.fxml b/src/main/resources/fxml/vault_list.fxml index a1fe141db..ad80c9a2c 100644 --- a/src/main/resources/fxml/vault_list.fxml +++ b/src/main/resources/fxml/vault_list.fxml @@ -16,9 +16,9 @@ fx:id="root" fx:controller="org.cryptomator.ui.mainwindow.VaultListController" minWidth="206"> - + - + From 8ff06a3efd5eeceb6cac54a45422e0b53558b7d7 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Tue, 2 Jul 2024 12:43:27 +0200 Subject: [PATCH 08/28] implement hideable notification bars --- .../ui/mainwindow/MainWindowController.java | 52 +++++++++++++++++++ src/main/resources/fxml/main_window.fxml | 18 +++++-- src/main/resources/i18n/strings.properties | 1 - 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java index 3b73b4338..ee16205f3 100644 --- a/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java +++ b/src/main/java/org/cryptomator/ui/mainwindow/MainWindowController.java @@ -14,10 +14,13 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.Observable; +import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.ReadOnlyBooleanProperty; import javafx.beans.property.ReadOnlyObjectProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.fxml.FXML; import javafx.scene.layout.StackPane; import javafx.stage.Stage; @@ -33,6 +36,10 @@ public class MainWindowController implements FxController { private final FxApplicationWindows appWindows; private final BooleanBinding updateAvailable; private final LicenseHolder licenseHolder; + private final BooleanProperty hideSupportNotificationClicked = new SimpleBooleanProperty(false); + private final BooleanProperty supportNotificationHidden = new SimpleBooleanProperty(); + private final BooleanProperty hideUpdateNotificationClicked = new SimpleBooleanProperty(false); + private final BooleanProperty updateNotificationHidden = new SimpleBooleanProperty(); public StackPane root; @@ -69,6 +76,9 @@ public class MainWindowController implements FxController { window.heightProperty().addListener((_, _, _) -> savePositionalSettings()); window.xProperty().addListener((_, _, _) -> savePositionalSettings()); window.yProperty().addListener((_, _, _) -> savePositionalSettings()); + + supportNotificationHidden.bind(Bindings.createBooleanBinding(() -> !licenseHolder.isValidLicense() && !hideSupportNotificationClicked.get(), hideSupportNotificationClicked)); + updateNotificationHidden.bind(Bindings.createBooleanBinding(() -> updateAvailable.get() && !hideUpdateNotificationClicked.get(), hideUpdateNotificationClicked)); } private boolean neverTouched() { @@ -105,6 +115,16 @@ public class MainWindowController implements FxController { appWindows.showPreferencesWindow(SelectedPreferencesTab.UPDATES); } + @FXML + public void hideSupportNotification() { + this.hideSupportNotificationClicked.setValue(true); + } + + @FXML + public void hideUpdateNotification() { + this.hideUpdateNotificationClicked.setValue(true); + } + public LicenseHolder getLicenseHolder() { return licenseHolder; } @@ -125,4 +145,36 @@ public class MainWindowController implements FxController { return updateAvailable.get(); } + public BooleanProperty hideSupportNotificationClickedProperty() { + return hideSupportNotificationClicked; + } + + public boolean isHideSupportNotificationClicked() { + return hideSupportNotificationClicked.get(); + } + + public BooleanProperty supportNotificationHiddenProperty() { + return supportNotificationHidden; + } + + public boolean isSupportNotificationHidden() { + return supportNotificationHidden.get(); + } + + public BooleanProperty hideUpdateNotificationClickedProperty() { + return hideUpdateNotificationClicked; + } + + public boolean isHideUpdateNotificationClicked() { + return hideUpdateNotificationClicked.get(); + } + + public BooleanProperty updateNotificationHiddenProperty() { + return updateNotificationHidden; + } + + public boolean isUpdateNotificationHidden() { + return updateNotificationHidden.get(); + } + } diff --git a/src/main/resources/fxml/main_window.fxml b/src/main/resources/fxml/main_window.fxml index eed8fc695..29e9ea36a 100644 --- a/src/main/resources/fxml/main_window.fxml +++ b/src/main/resources/fxml/main_window.fxml @@ -5,24 +5,34 @@ + + - + + +