From 574ac44ffae32269c521a1e2eff316a572a5c1d2 Mon Sep 17 00:00:00 2001 From: Phillipus Date: Sat, 14 Sep 2024 19:06:12 +0100 Subject: [PATCH] [Themes] Automatic theme for light/dark - Eclipse's ThemeEngine will try to automatically set the light or dark theme on startup if the themeid setting is not present in the org.eclipse.e4.ui.css.swt.theme.prefs file or that file doesn't exist (fresh workspace) - We'll expose this in Preferences as a new automatic pseudo theme. This will delete the themeid setting so that the auto theming occurs on startup --- .../preferences/AppearancePreferencePage.java | 58 ++++++++++++++++--- .../editor/preferences/Messages.java | 2 + .../editor/preferences/messages.properties | 1 + .../archimatetool/editor/ui/ThemeUtils.java | 5 ++ .../help/Text/prefs_appearance.html | 2 + 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/AppearancePreferencePage.java b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/AppearancePreferencePage.java index 6d300378d..7b1c1f485 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/AppearancePreferencePage.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/AppearancePreferencePage.java @@ -5,6 +5,9 @@ */ package com.archimatetool.editor.preferences; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.e4.ui.css.swt.theme.ITheme; import org.eclipse.e4.ui.css.swt.theme.IThemeEngine; @@ -24,6 +27,7 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -58,6 +62,22 @@ public class AppearancePreferencePage private IThemeEngine themeEngine; private ITheme lastActiveTheme; + /** + * Pseudo theme to set automatic light/dark on startup + */ + private static ITheme AUTOMATIC_THEME = new ITheme() { + @Override + public String getId() { + return Display.isSystemDarkTheme() ? ThemeUtils.E4_DARK_THEME_ID : ThemeUtils.E4_DEFAULT_THEME_ID; + } + + @Override + public String getLabel() { + return Messages.AppearancePreferencePage_7; + } + }; + + public AppearancePreferencePage() { setPreferenceStore(ArchiPlugin.PREFERENCES); setDescription(Messages.AppearancePreferencePage_0); @@ -135,7 +155,7 @@ public String getText(Object element) { @Override public void selectionChanged(SelectionChangedEvent event) { ITheme theme = (ITheme)((IStructuredSelection)fThemeComboViewer.getSelection()).getFirstElement(); - themeEngine.setTheme(theme, false); + themeEngine.setTheme(theme.getId(), false); // set theme id, not theme in case of automatic theme } }); } @@ -146,11 +166,20 @@ public void selectionChanged(SelectionChangedEvent event) { private void setValues() { // Themes list if(themeEngine != null) { - fThemeComboViewer.setInput(themeEngine.getThemes().toArray()); + List themes = new ArrayList<>((themeEngine.getThemes())); + themes.add(0, AUTOMATIC_THEME); - ITheme activeTheme = themeEngine.getActiveTheme(); - if(activeTheme != null) { - fThemeComboViewer.setSelection(new StructuredSelection(activeTheme)); + fThemeComboViewer.setInput(themes.toArray()); + + // If themeid is not present the ThemeEngine will try to set light/dark theme based on OS theme + if(ThemeUtils.getThemePreferences().get(ThemeUtils.THEMEID_KEY, null) == null) { + fThemeComboViewer.setSelection(new StructuredSelection(AUTOMATIC_THEME)); + } + else { + ITheme activeTheme = themeEngine.getActiveTheme(); + if(activeTheme != null) { + fThemeComboViewer.setSelection(new StructuredSelection(activeTheme)); + } } } @@ -170,10 +199,24 @@ public boolean performOk() { // Theme if(themeEngine != null) { ITheme theme = (ITheme)((IStructuredSelection)fThemeComboViewer.getSelection()).getFirstElement(); - if(!theme.equals(lastActiveTheme)) { + + if(theme == AUTOMATIC_THEME) { + // Just remove the "themeid" key and then the ThemeEngine will use dark/light depending on OS theme on startup + IEclipsePreferences themePrefs = ThemeUtils.getThemePreferences(); + themePrefs.remove(ThemeUtils.THEMEID_KEY); + try { + themePrefs.flush(); + } + catch(BackingStoreException ex) { + ex.printStackTrace(); + } + } + else { themeEngine.setTheme(theme, true); - lastActiveTheme = theme; } + + // Store this in both cases + lastActiveTheme = themeEngine.getActiveTheme(); } // Status line @@ -192,6 +235,7 @@ public boolean performOk() { swtPrefs.flush(); } catch(BackingStoreException ex) { + ex.printStackTrace(); } // Mac native item heights diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/Messages.java b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/Messages.java index 71d2f5056..412f95b19 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/Messages.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/Messages.java @@ -25,6 +25,8 @@ public class Messages extends NLS { public static String AppearancePreferencePage_6; + public static String AppearancePreferencePage_7; + public static String ColoursPreferencePage_0; public static String ColoursPreferencePage_1; diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/messages.properties b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/messages.properties index 73d854dd4..d2a6e255f 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/preferences/messages.properties +++ b/com.archimatetool.editor/src/com/archimatetool/editor/preferences/messages.properties @@ -5,6 +5,7 @@ AppearancePreferencePage_3=Use round tabs AppearancePreferencePage_4=Enable Theming AppearancePreferencePage_5=Use larger (Mac native) row heights AppearancePreferencePage_6=Requires a restart +AppearancePreferencePage_7=Automatically select Light/Dark ColoursPreferencePage_0=Default colours for objects: ColoursPreferencePage_1=Strategy elements diff --git a/com.archimatetool.editor/src/com/archimatetool/editor/ui/ThemeUtils.java b/com.archimatetool.editor/src/com/archimatetool/editor/ui/ThemeUtils.java index 4251990a0..d6408a874 100644 --- a/com.archimatetool.editor/src/com/archimatetool/editor/ui/ThemeUtils.java +++ b/com.archimatetool.editor/src/com/archimatetool/editor/ui/ThemeUtils.java @@ -56,6 +56,11 @@ public final class ThemeUtils { */ public static final String THEME_ENABLED = "themeEnabled"; + /** + * Used in .metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.e4.ui.css.swt.theme.prefs to store current theme id + */ + public static final String THEMEID_KEY = "themeid"; + private static IThemeEngine engine; /** diff --git a/com.archimatetool.help/help/Text/prefs_appearance.html b/com.archimatetool.help/help/Text/prefs_appearance.html index 8451d6fe0..082c8c735 100644 --- a/com.archimatetool.help/help/Text/prefs_appearance.html +++ b/com.archimatetool.help/help/Text/prefs_appearance.html @@ -20,6 +20,8 @@

Appearance

Theme
Choose the theme to use for Archi. A restart will be required for this change to fully take effect.

+ +

If the theme is set to "Automatically select Light/Dark" the theme will be set according to the current operating system theme of light or dark when starting Archi. Some system dark themes are not supported and so this setting might not work. If this is the case, select another theme to suit the host system theme.

Use round tabs
Whether to use round or square tabs.