From 6caf132cfb1fdef4759505aba38dd4c50b25fe58 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Thu, 10 Nov 2022 18:18:34 +0100 Subject: [PATCH 1/3] fixes #2512 --- .../ChooseExistingVaultController.java | 82 +++++++++++++++++-- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 432007c99..50cbb73e0 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,10 +2,15 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import org.apache.commons.lang3.SystemUtils; +import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.UiTheme; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; +import org.cryptomator.integrations.uiappearance.Theme; +import org.cryptomator.integrations.uiappearance.UiAppearanceException; +import org.cryptomator.integrations.uiappearance.UiAppearanceListener; +import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; @@ -15,6 +20,8 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; import javafx.scene.image.Image; @@ -23,6 +30,7 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.Optional; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -41,11 +49,14 @@ public class ChooseExistingVaultController implements FxController { private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; private final Settings settings; + private final Optional appearanceProvider; + private final LicenseHolder licenseHolder; + private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; - private Image screenshot; + private final ObjectProperty screenshot = new SimpleObjectProperty<>(); @Inject - ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings) { + ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { this.window = window; this.welcomeScene = welcomeScene; this.successScene = successScene; @@ -55,17 +66,73 @@ public class ChooseExistingVaultController implements FxController { this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; this.settings = settings; + this.appearanceProvider = appearanceProvider; + this.licenseHolder = licenseHolder; } @FXML public void initialize() { if (SystemUtils.IS_OS_MAC) { - this.screenshot = new Image(getClass().getResource("/img/select-masterkey-mac"+(UiTheme.LIGHT == settings.theme().get()? "":"-dark")+".png").toString()); + settings.theme().addListener(this::appThemeChanged); + setSelectedMacScreenshot(settings.theme().get()); } else { - this.screenshot = new Image(getClass().getResource("/img/select-masterkey-win.png").toString()); + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); } } + private void appThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) { + if (appearanceProvider.isPresent() && oldValue == UiTheme.AUTOMATIC && newValue != UiTheme.AUTOMATIC) { + try { + appearanceProvider.get().removeListener(systemInterfaceThemeListener); + } catch (UiAppearanceException e) { + LOG.error("Failed to disable automatic theme switching."); + } + } + setSelectedMacScreenshot(newValue); + } + + private void setSelectedMacScreenshot(UiTheme desiredTheme) { + UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT; + switch (theme) { + case LIGHT -> setLightMacScreenshot(); + case DARK -> setDarkMacScreenshot(); + case AUTOMATIC -> { + appearanceProvider.ifPresent(provider -> { + try { + provider.addListener(systemInterfaceThemeListener); + } catch (UiAppearanceException e) { + LOG.error("Failed to enable automatic theme switching."); + } + }); + setSystemMacScreenshot(); + } + } + } + + private void systemInterfaceThemeChanged(Theme theme) { + switch (theme) { + case LIGHT -> setLightMacScreenshot(); + case DARK -> setDarkMacScreenshot(); + } + } + + private void setSystemMacScreenshot() { + if (appearanceProvider.isPresent()) { + systemInterfaceThemeChanged(appearanceProvider.get().getSystemTheme()); + } else { + LOG.warn("No UiAppearanceProvider present, assuming LIGHT theme..."); + setLightMacScreenshot(); + } + } + + private void setLightMacScreenshot() { + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); + } + + private void setDarkMacScreenshot() { + this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); + } + @FXML public void back() { window.setScene(welcomeScene.get()); @@ -92,8 +159,13 @@ public class ChooseExistingVaultController implements FxController { /* Getter */ - public Image getScreenshot() { + public ObjectProperty screenshotProperty() { return screenshot; } + public Image getScreenshot() { + return screenshot.get(); + } + + } From dda7255d8e2f303c05660fd844aab488dff8e994 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Thu, 10 Nov 2022 18:36:14 +0100 Subject: [PATCH 2/3] deduplicated code --- .../ChooseExistingVaultController.java | 75 +++---------------- .../ui/fxapp/FxApplicationStyle.java | 11 ++- 2 files changed, 21 insertions(+), 65 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 50cbb73e0..0a0dc3d2e 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -2,18 +2,13 @@ package org.cryptomator.ui.addvaultwizard; import dagger.Lazy; import org.apache.commons.lang3.SystemUtils; -import org.cryptomator.common.LicenseHolder; -import org.cryptomator.common.settings.Settings; -import org.cryptomator.common.settings.UiTheme; import org.cryptomator.common.vaults.Vault; import org.cryptomator.common.vaults.VaultListManager; import org.cryptomator.integrations.uiappearance.Theme; -import org.cryptomator.integrations.uiappearance.UiAppearanceException; -import org.cryptomator.integrations.uiappearance.UiAppearanceListener; -import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.ui.common.FxController; import org.cryptomator.ui.common.FxmlFile; import org.cryptomator.ui.common.FxmlScene; +import org.cryptomator.ui.fxapp.FxApplicationStyle; import org.cryptomator.ui.fxapp.FxApplicationWindows; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +25,6 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; -import java.util.Optional; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -48,15 +42,12 @@ public class ChooseExistingVaultController implements FxController { private final ObjectProperty vault; private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; - private final Settings settings; - private final Optional appearanceProvider; - private final LicenseHolder licenseHolder; - private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; + private final FxApplicationStyle applicationStyle; private final ObjectProperty screenshot = new SimpleObjectProperty<>(); @Inject - ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { + ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, FxApplicationStyle applicationStyle) { this.window = window; this.welcomeScene = welcomeScene; this.successScene = successScene; @@ -65,74 +56,30 @@ public class ChooseExistingVaultController implements FxController { this.vault = vault; this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; - this.settings = settings; - this.appearanceProvider = appearanceProvider; - this.licenseHolder = licenseHolder; + this.applicationStyle = applicationStyle; } @FXML public void initialize() { if (SystemUtils.IS_OS_MAC) { - settings.theme().addListener(this::appThemeChanged); - setSelectedMacScreenshot(settings.theme().get()); + applicationStyle.appliedThemeProperty().addListener(this::appliedThemeChanged); + setMacScreenshot(applicationStyle.appliedThemeProperty().get()); } else { this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); } } - private void appThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) { - if (appearanceProvider.isPresent() && oldValue == UiTheme.AUTOMATIC && newValue != UiTheme.AUTOMATIC) { - try { - appearanceProvider.get().removeListener(systemInterfaceThemeListener); - } catch (UiAppearanceException e) { - LOG.error("Failed to disable automatic theme switching."); - } - } - setSelectedMacScreenshot(newValue); + private void appliedThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Theme oldValue, Theme newValue) { + setMacScreenshot(newValue); } - private void setSelectedMacScreenshot(UiTheme desiredTheme) { - UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT; + private void setMacScreenshot(Theme theme) { switch (theme) { - case LIGHT -> setLightMacScreenshot(); - case DARK -> setDarkMacScreenshot(); - case AUTOMATIC -> { - appearanceProvider.ifPresent(provider -> { - try { - provider.addListener(systemInterfaceThemeListener); - } catch (UiAppearanceException e) { - LOG.error("Failed to enable automatic theme switching."); - } - }); - setSystemMacScreenshot(); - } + case LIGHT -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); + case DARK -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); } } - private void systemInterfaceThemeChanged(Theme theme) { - switch (theme) { - case LIGHT -> setLightMacScreenshot(); - case DARK -> setDarkMacScreenshot(); - } - } - - private void setSystemMacScreenshot() { - if (appearanceProvider.isPresent()) { - systemInterfaceThemeChanged(appearanceProvider.get().getSystemTheme()); - } else { - LOG.warn("No UiAppearanceProvider present, assuming LIGHT theme..."); - setLightMacScreenshot(); - } - } - - private void setLightMacScreenshot() { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); - } - - private void setDarkMacScreenshot() { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); - } - @FXML public void back() { window.setScene(welcomeScene.get()); diff --git a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java index 711da7948..b6681f728 100644 --- a/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java +++ b/src/main/java/org/cryptomator/ui/fxapp/FxApplicationStyle.java @@ -12,6 +12,8 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.application.Application; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import java.util.Optional; @@ -24,9 +26,10 @@ public class FxApplicationStyle { private final Optional appearanceProvider; private final LicenseHolder licenseHolder; private final UiAppearanceListener systemInterfaceThemeListener = this::systemInterfaceThemeChanged; + private final ObjectProperty appliedTheme = new SimpleObjectProperty<>(Theme.LIGHT); @Inject - public FxApplicationStyle(Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder){ + public FxApplicationStyle(Settings settings, Optional appearanceProvider, LicenseHolder licenseHolder) { this.settings = settings; this.appearanceProvider = appearanceProvider; this.licenseHolder = licenseHolder; @@ -91,6 +94,7 @@ public class FxApplicationStyle { } else { Application.setUserAgentStylesheet(stylesheet.toString()); appearanceProvider.ifPresent(provider -> provider.adjustToTheme(Theme.LIGHT)); + appliedTheme.set(Theme.LIGHT); } } @@ -103,6 +107,11 @@ public class FxApplicationStyle { } else { Application.setUserAgentStylesheet(stylesheet.toString()); appearanceProvider.ifPresent(provider -> provider.adjustToTheme(Theme.DARK)); + appliedTheme.set(Theme.DARK); } } + + public ObjectProperty appliedThemeProperty() { + return appliedTheme; + } } From 2f9818aadec270b3ac0df9a5a1204e100e40226f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 29 Nov 2022 17:07:43 +0100 Subject: [PATCH 3/3] use new JavaFX 19 API --- .../ChooseExistingVaultController.java | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java index 0a0dc3d2e..fe4ac3bd1 100644 --- a/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java +++ b/src/main/java/org/cryptomator/ui/addvaultwizard/ChooseExistingVaultController.java @@ -15,7 +15,6 @@ import org.slf4j.LoggerFactory; import javax.inject.Inject; import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.fxml.FXML; import javafx.scene.Scene; @@ -25,6 +24,7 @@ import javafx.stage.Stage; import java.io.File; import java.io.IOException; import java.nio.file.Path; +import java.util.Objects; import java.util.ResourceBundle; import static org.cryptomator.common.Constants.CRYPTOMATOR_FILENAME_GLOB; @@ -42,9 +42,7 @@ public class ChooseExistingVaultController implements FxController { private final ObjectProperty vault; private final VaultListManager vaultListManager; private final ResourceBundle resourceBundle; - private final FxApplicationStyle applicationStyle; - - private final ObjectProperty screenshot = new SimpleObjectProperty<>(); + private final ObservableValue screenshot; @Inject ChooseExistingVaultController(@AddVaultWizardWindow Stage window, @FxmlScene(FxmlFile.ADDVAULT_WELCOME) Lazy welcomeScene, @FxmlScene(FxmlFile.ADDVAULT_SUCCESS) Lazy successScene, FxApplicationWindows appWindows, ObjectProperty vaultPath, @AddVaultWizardWindow ObjectProperty vault, VaultListManager vaultListManager, ResourceBundle resourceBundle, FxApplicationStyle applicationStyle) { @@ -56,28 +54,20 @@ public class ChooseExistingVaultController implements FxController { this.vault = vault; this.vaultListManager = vaultListManager; this.resourceBundle = resourceBundle; - this.applicationStyle = applicationStyle; + this.screenshot = applicationStyle.appliedThemeProperty().map(this::selectScreenshot); } - @FXML - public void initialize() { + private Image selectScreenshot(Theme theme) { + String imageResourcePath; if (SystemUtils.IS_OS_MAC) { - applicationStyle.appliedThemeProperty().addListener(this::appliedThemeChanged); - setMacScreenshot(applicationStyle.appliedThemeProperty().get()); + imageResourcePath = switch (theme) { + case LIGHT -> "/img/select-masterkey-mac.png"; + case DARK -> "/img/select-masterkey-mac-dark.png"; + }; } else { - this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-win.png").toString())); - } - } - - private void appliedThemeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") Theme oldValue, Theme newValue) { - setMacScreenshot(newValue); - } - - private void setMacScreenshot(Theme theme) { - switch (theme) { - case LIGHT -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac.png").toString())); - case DARK -> this.screenshot.set(new Image(getClass().getResource("/img/select-masterkey-mac-dark.png").toString())); + imageResourcePath = "/img/select-masterkey-win.png"; } + return new Image((Objects.requireNonNull(getClass().getResource(imageResourcePath)).toString())); } @FXML @@ -106,12 +96,12 @@ public class ChooseExistingVaultController implements FxController { /* Getter */ - public ObjectProperty screenshotProperty() { + public ObservableValue screenshotProperty() { return screenshot; } public Image getScreenshot() { - return screenshot.get(); + return screenshot.getValue(); }