From a975df6f8cab2dfb6e289670fd27364def9182a0 Mon Sep 17 00:00:00 2001 From: Tobias Hagemann Date: Thu, 6 Aug 2020 18:30:34 +0200 Subject: [PATCH] added "Automatic" theme on macOS --- .../cryptomator/common/settings/UiTheme.java | 20 +++++++--- main/pom.xml | 2 +- .../cryptomator/ui/fxapp/FxApplication.java | 40 +++++++++++++++---- .../GeneralPreferencesController.java | 11 +++-- .../ui/traymenu/TrayIconController.java | 2 +- .../main/resources/i18n/strings.properties | 1 + 6 files changed, 57 insertions(+), 19 deletions(-) diff --git a/main/commons/src/main/java/org/cryptomator/common/settings/UiTheme.java b/main/commons/src/main/java/org/cryptomator/common/settings/UiTheme.java index a8b66c65c..8df1e7f89 100644 --- a/main/commons/src/main/java/org/cryptomator/common/settings/UiTheme.java +++ b/main/commons/src/main/java/org/cryptomator/common/settings/UiTheme.java @@ -1,11 +1,21 @@ package org.cryptomator.common.settings; -public enum UiTheme { - LIGHT("preferences.general.theme.light"), - DARK("preferences.general.theme.dark"); - // CUSTOM("Custom (%s)"); +import org.apache.commons.lang3.SystemUtils; - private String displayName; +public enum UiTheme { + LIGHT("preferences.general.theme.light"), // + DARK("preferences.general.theme.dark"), // + AUTOMATIC("preferences.general.theme.automatic"); + + public static UiTheme[] applicableValues() { + if (SystemUtils.IS_OS_MAC) { + return values(); + } else { + return new UiTheme[]{LIGHT, DARK}; + } + } + + private final String displayName; UiTheme(String displayName) { this.displayName = displayName; diff --git a/main/pom.xml b/main/pom.xml index 5f0d7e5ea..618793f93 100644 --- a/main/pom.xml +++ b/main/pom.xml @@ -25,7 +25,7 @@ 1.9.12 - 2.2.2 + 2.2.3 1.2.3 1.1.15 1.0.11 diff --git a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java index 3172b6288..4d80a3451 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java +++ b/main/ui/src/main/java/org/cryptomator/ui/fxapp/FxApplication.java @@ -6,7 +6,6 @@ import javafx.application.Platform; import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; import javafx.beans.value.ObservableValue; -import javafx.collections.FXCollections; import javafx.collections.ObservableSet; import javafx.stage.Stage; import org.cryptomator.common.LicenseHolder; @@ -46,6 +45,8 @@ public class FxApplication extends Application { private final LicenseHolder licenseHolder; private final BooleanBinding hasVisibleStages; + private Optional macApperanceObserverIdentifier = Optional.empty(); + @Inject FxApplication(Settings settings, Lazy mainWindow, Lazy preferencesWindow, Provider unlockWindowBuilderProvider, Provider quitWindowBuilderProvider, Optional macFunctions, VaultService vaultService, LicenseHolder licenseHolder, ObservableSet visibleStages) { this.settings = settings; @@ -115,21 +116,44 @@ public class FxApplication extends Application { } private void themeChanged(@SuppressWarnings("unused") ObservableValue observable, @SuppressWarnings("unused") UiTheme oldValue, UiTheme newValue) { + if (macApperanceObserverIdentifier.isPresent()) { + macFunctions.map(MacFunctions::uiAppearance).ifPresent(uiAppearance -> uiAppearance.removeListener(macApperanceObserverIdentifier.get())); + macApperanceObserverIdentifier = Optional.empty(); + } loadSelectedStyleSheet(newValue); } private void loadSelectedStyleSheet(UiTheme desiredTheme) { UiTheme theme = licenseHolder.isValidLicense() ? desiredTheme : UiTheme.LIGHT; switch (theme) { - case DARK -> { - Application.setUserAgentStylesheet(getClass().getResource("/css/dark_theme.css").toString()); - macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToDarkAqua)); - } - case LIGHT -> { - Application.setUserAgentStylesheet(getClass().getResource("/css/light_theme.css").toString()); - macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToAqua)); + case LIGHT -> setToLightTheme(); + case DARK -> setToDarkTheme(); + case AUTOMATIC -> { + macFunctions.map(MacFunctions::uiAppearance).ifPresent(uiAppearance -> { + macApperanceObserverIdentifier = Optional.of(uiAppearance.addListener(this::macInterfaceThemeChanged)); + }); + macInterfaceThemeChanged(); } } } + private void macInterfaceThemeChanged() { + macFunctions.map(MacFunctions::uiAppearance).ifPresent(uiAppearance -> { + switch (uiAppearance.getCurrentInterfaceStyle()) { + case LIGHT -> setToLightTheme(); + case DARK -> setToDarkTheme(); + } + }); + } + + private void setToLightTheme() { + Application.setUserAgentStylesheet(getClass().getResource("/css/light_theme.css").toString()); + macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToAqua)); + } + + private void setToDarkTheme() { + Application.setUserAgentStylesheet(getClass().getResource("/css/dark_theme.css").toString()); + macFunctions.map(MacFunctions::uiAppearance).ifPresent(JniException.ignore(MacApplicationUiAppearance::setToDarkAqua)); + } + } diff --git a/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java b/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java index 30f06b166..fdec00d62 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/preferences/GeneralPreferencesController.java @@ -1,5 +1,6 @@ package org.cryptomator.ui.preferences; +import javafx.application.Application; import javafx.application.Platform; import javafx.beans.property.ObjectProperty; import javafx.beans.value.ObservableValue; @@ -12,11 +13,10 @@ import javafx.scene.control.RadioButton; import javafx.scene.control.Toggle; import javafx.scene.control.ToggleGroup; import javafx.util.StringConverter; -import javafx.application.Application; +import org.cryptomator.common.Environment; import org.cryptomator.common.LicenseHolder; import org.cryptomator.common.settings.Settings; import org.cryptomator.common.settings.UiTheme; -import org.cryptomator.common.Environment; import org.cryptomator.ui.common.FxController; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +64,10 @@ public class GeneralPreferencesController implements FxController { @FXML public void initialize() { - themeChoiceBox.getItems().addAll(UiTheme.values()); + themeChoiceBox.getItems().addAll(UiTheme.applicableValues()); + if (!themeChoiceBox.getItems().contains(settings.theme().get())) { + settings.theme().set(UiTheme.LIGHT); + } themeChoiceBox.valueProperty().bindBidirectional(settings.theme()); themeChoiceBox.setConverter(new UiThemeConverter(resourceBundle)); @@ -122,7 +125,7 @@ public class GeneralPreferencesController implements FxController { } @FXML - public void showLogfileDirectory(){ + public void showLogfileDirectory() { environment.getLogDir().ifPresent(logDirPath -> application.getHostServices().showDocument(logDirPath.toUri().toString())); } diff --git a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java index 78c5cfe62..13183a36e 100644 --- a/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java +++ b/main/ui/src/main/java/org/cryptomator/ui/traymenu/TrayIconController.java @@ -47,7 +47,7 @@ public class TrayIconController { trayMenuController.initTrayMenu(); } - public void macInterfaceThemeChanged() { + private void macInterfaceThemeChanged() { trayIcon.setImage(imageFactory.loadImage()); } diff --git a/main/ui/src/main/resources/i18n/strings.properties b/main/ui/src/main/resources/i18n/strings.properties index cd6a2d625..6b1a89136 100644 --- a/main/ui/src/main/resources/i18n/strings.properties +++ b/main/ui/src/main/resources/i18n/strings.properties @@ -131,6 +131,7 @@ preferences.title=Preferences ## General preferences.general=General preferences.general.theme=Look & Feel +preferences.general.theme.automatic=Automatic preferences.general.theme.light=Light preferences.general.theme.dark=Dark preferences.general.unlockThemes=Unlock dark mode