From a02c61ec7eaebdaedb50419530b3e2b1290e0139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Genov=C3=A9s?= Date: Tue, 25 Feb 2020 13:32:10 +0100 Subject: [PATCH] Implement theme switcher auth.: @Exalm --- data/media/css/gtk/base.css | 41 ++++- data/media/css/web/adwaita.css | 20 ++- data/media/css/web/adwaita_dark.css | 18 --- data/media/css/web/arc.css | 21 ++- data/media/css/web/arc_dark.css | 18 --- data/media/css/web/arc_darker.css | 1 - data/uberwriter.gresource.xml | 1 + data/ui/Menu2.ui | 229 ++++++++++++++++++++++++++++ uberwriter/application.py | 21 ++- uberwriter/headerbars.py | 23 ++- uberwriter/main_window.py | 1 - uberwriter/styled_window.py | 33 +--- uberwriter/theme.py | 6 +- 13 files changed, 359 insertions(+), 74 deletions(-) delete mode 100644 data/media/css/web/adwaita_dark.css delete mode 100644 data/media/css/web/arc_dark.css delete mode 100644 data/media/css/web/arc_darker.css create mode 100644 data/ui/Menu2.ui diff --git a/data/media/css/gtk/base.css b/data/media/css/gtk/base.css index 543da99..8d4bffa 100644 --- a/data/media/css/gtk/base.css +++ b/data/media/css/gtk/base.css @@ -171,9 +171,48 @@ } .quick-preview-popup label { - color: @theme_fg_color; + color: @theme_fg_color; } .plain-listview { background-color: @fg-color; +} + +/* theme selector */ + +.color-button { + padding: 12px; + border-radius: 999px; + -gtk-outline-radius: 999px; + outline-offset: 1px; + border: none; + -gtk-icon-shadow: none; + min-width: 0px; + min-height: 0px; + color: transparent; + transition: all 200ms ease-out; +} + +.color-light { + background: #ffffff; + box-shadow: inset 0 0 0 1px #2e3436; +} + +.color-light:checked { + color: #2e3436; + box-shadow: inset 0 0 0 2px @theme_selected_bg_color; +} + +.color-dark { + background: #2d2d2d; + box-shadow: inset 0 0 0 1px alpha(black, .35); +} +.color-dark:checked { + color: #eeeeec; + box-shadow: inset 0 0 0 2px @theme_selected_bg_color; +} + +.color-button:disabled { + background: #929292; + box-shadow: inset 0 0 0 1px #2e3436; } \ No newline at end of file diff --git a/data/media/css/web/adwaita.css b/data/media/css/web/adwaita.css index e784b20..f37b57e 100644 --- a/data/media/css/web/adwaita.css +++ b/data/media/css/web/adwaita.css @@ -15,5 +15,23 @@ --kbd-background-color: #f1f1f1; --kbd-border-color: #bdc1c6; --kbd-shadow-color: #8c939a; +} -} \ No newline at end of file +@media (prefers-color-scheme: dark) { + :root { + --text-color: #eeeeec; + --background-color: #353535; + --alt-background-color: #3a3a3a; + --link-color: #b5daff; + --blockquote-text-color: #a8a8a6; + --blockquote-border-color: #525252; + --header-border-color: #474747; + --hr-background-color: #505050; + --table-tr-border-color: #696969; + --table-td-border-color: #525252; + --kbd-text-color: #cececc; + --kbd-background-color: #3c3c3c; + --kbd-border-color: #696969; + --kbd-shadow-color: #979797; + } +} diff --git a/data/media/css/web/adwaita_dark.css b/data/media/css/web/adwaita_dark.css deleted file mode 100644 index afedc5c..0000000 --- a/data/media/css/web/adwaita_dark.css +++ /dev/null @@ -1,18 +0,0 @@ -@import url("base.css"); - -:root { - --text-color: #eeeeec; - --background-color: #353535; - --alt-background-color: #3a3a3a; - --link-color: #b5daff; - --blockquote-text-color: #a8a8a6; - --blockquote-border-color: #525252; - --header-border-color: #474747; - --hr-background-color: #505050; - --table-tr-border-color: #696969; - --table-td-border-color: #525252; - --kbd-text-color: #cececc; - --kbd-background-color: #3c3c3c; - --kbd-border-color: #696969; - --kbd-shadow-color: #979797; -} \ No newline at end of file diff --git a/data/media/css/web/arc.css b/data/media/css/web/arc.css index 7ee62ac..ea0d3c4 100644 --- a/data/media/css/web/arc.css +++ b/data/media/css/web/arc.css @@ -15,4 +15,23 @@ --kbd-background-color: #f0f2f4; --kbd-border-color: #bcc2c9; --kbd-shadow-color: #8b949d; -} \ No newline at end of file +} + +@media (prefers-color-scheme: dark) { + :root { + --text-color: #d3dae3; + --background-color: #383c4a; + --alt-background-color: #3d414f; + --link-color: #9ac6ff; + --blockquote-text-color: #8d949d; + --blockquote-border-color: #555967; + --header-border-color: #4a4e5c; + --hr-background-color: #535765; + --table-tr-border-color: #6c707e; + --table-td-border-color: #555967; + --kbd-text-color: #b3bac3; + --kbd-background-color: #3f4351; + --kbd-border-color: #6c707e; + --kbd-shadow-color: #9a9eac; + } +} diff --git a/data/media/css/web/arc_dark.css b/data/media/css/web/arc_dark.css deleted file mode 100644 index f421845..0000000 --- a/data/media/css/web/arc_dark.css +++ /dev/null @@ -1,18 +0,0 @@ -@import url("base.css"); - -:root { - --text-color: #d3dae3; - --background-color: #383c4a; - --alt-background-color: #3d414f; - --link-color: #9ac6ff; - --blockquote-text-color: #8d949d; - --blockquote-border-color: #555967; - --header-border-color: #4a4e5c; - --hr-background-color: #535765; - --table-tr-border-color: #6c707e; - --table-td-border-color: #555967; - --kbd-text-color: #b3bac3; - --kbd-background-color: #3f4351; - --kbd-border-color: #6c707e; - --kbd-shadow-color: #9a9eac; -} \ No newline at end of file diff --git a/data/media/css/web/arc_darker.css b/data/media/css/web/arc_darker.css deleted file mode 100644 index a2b855f..0000000 --- a/data/media/css/web/arc_darker.css +++ /dev/null @@ -1 +0,0 @@ -@import url("arc.css"); diff --git a/data/uberwriter.gresource.xml b/data/uberwriter.gresource.xml index c875ef3..b129813 100644 --- a/data/uberwriter.gresource.xml +++ b/data/uberwriter.gresource.xml @@ -8,6 +8,7 @@ media/css/gtk/base.css ui/Export.ui ui/Menu.ui + ui/Menu2.ui ui/Preferences.ui ui/Preview.ui ui/Recents.ui diff --git a/data/ui/Menu2.ui b/data/ui/Menu2.ui new file mode 100644 index 0000000..2cc2ade --- /dev/null +++ b/data/ui/Menu2.ui @@ -0,0 +1,229 @@ + + + + + + False + + + True + False + 12 + 12 + 12 + 12 + vertical + + + True + False + center + 12 + 12 + 6 + 24 + + + True + True + False + center + app.dark_mode + False + + + True + False + emblem-ok-symbolic + + + + + + False + True + 0 + + + + + True + True + False + center + False + light_mode_button + + + True + False + emblem-ok-symbolic + + + + + + False + True + 1 + + + + + False + True + 0 + + + + + True + False + + + False + True + 1 + + + + + True + True + True + app.hemingway_mode + Hemingway mode + + + False + True + 2 + + + + + True + True + True + app.focus_mode + Focus Mode + + + False + True + 3 + + + + + True + False + + + False + True + 4 + + + + + True + True + True + app.search_replace + Find and Replace + + + False + True + 5 + + + + + True + False + + + False + True + 6 + + + + + True + True + True + app.preferences + Preferences + + + False + True + 7 + + + + + True + False + + + False + True + 8 + + + + + True + True + True + app.open_tutorial + Open Tutorial + + + False + True + 9 + + + + + True + True + True + app.shortcuts + Keyboard Shortcuts + + + False + True + 10 + + + + + True + True + True + app.about + About Uberwriter + + + False + True + 11 + + + + + + diff --git a/uberwriter/application.py b/uberwriter/application.py index 5fc8ebf..badcc9d 100644 --- a/uberwriter/application.py +++ b/uberwriter/application.py @@ -41,6 +41,7 @@ class Application(Gtk.Application): Gtk.Application.do_startup(self) self.settings.connect("changed", self.on_settings_changed) + self._set_dark_mode () # Header bar @@ -65,6 +66,10 @@ class Application(Gtk.Application): self.add_action(action) # App Menu + action = Gio.SimpleAction.new_stateful( + "dark_mode", None, GLib.Variant.new_boolean(False)) + action.connect("change-state", self.on_dark_mode) + self.add_action(action) action = Gio.SimpleAction.new_stateful( "focus_mode", None, GLib.Variant.new_boolean(False)) @@ -184,9 +189,20 @@ class Application(Gtk.Application): self.activate() return 0 + def _set_dark_mode (self): + dark = self.settings.get_value("dark-mode") + settings = Gtk.Settings.get_default() + + settings.props.gtk_application_prefer_dark_theme = dark + + if settings.props.gtk_theme_name == "HighContrast" and dark: + settings.props.gtk_theme_name = "HighContrastInverse" + elif settings.props.gtk_theme_name == "HighContrastInverse" and not dark: + settings.props.gtk_theme_name = "HighContrast" + def on_settings_changed(self, settings, key): if key == "dark-mode-auto" or key == "dark-mode": - self.window.apply_current_theme() + self._set_dark_mode () elif key == "spellcheck": self.window.toggle_spellcheck(settings.get_value(key)) elif key == "gradient-overlay": @@ -203,6 +219,9 @@ class Application(Gtk.Application): def on_new(self, _action, _value): self.window.new_document() + def on_dark_mode(self, action, value): + print(action, value) + def on_open(self, _action, _value): self.window.open_document() diff --git a/uberwriter/headerbars.py b/uberwriter/headerbars.py index b3d0f35..45fd18d 100644 --- a/uberwriter/headerbars.py +++ b/uberwriter/headerbars.py @@ -63,6 +63,17 @@ class BaseHeaderbar: self.menu_button = self.builder.get_object("menu_button") self.recents_button = self.builder.get_object("recents_button") + add_menus(self, app) + + settings = Gtk.Settings.get_default() + if global_dark:= settings.props.gtk_theme_name.endswith("-dark"): + self.light_button.set_sensitive(False) + self.light_button.set_tooltip_text(_("Light mode isn't available while using a dark global theme")) + + self.dark_button.set_active(self.settings.get_boolean("dark-mode") or global_dark) + + self.light_button.connect("toggled", self.__on_dark_mode) + def update_preview_layout_icon(self): mode = self.settings.get_enum("preview-mode") self.preview_switcher_icon.set_from_icon_name( @@ -118,6 +129,8 @@ class BaseHeaderbar: self.settings.set_boolean("sync-scroll", state) return False + def __on_dark_mode(self, _): + self.settings.set_boolean("dark-mode", self.dark_button.get_active()) class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods """Sets up the main application headerbar @@ -129,7 +142,7 @@ class MainHeaderbar(BaseHeaderbar): # pylint: disable=too-few-public-methods self.hb.set_show_close_button(True) - add_menus(self, app) + #add_menus(self, app) self.hb_revealer.props.transition_duration = 0 @@ -147,7 +160,7 @@ class FullscreenHeaderbar(BaseHeaderbar): self.exit_fs_button = self.builder.get_object("exit_fs_button") self.exit_fs_button.set_visible(True) - add_menus(self, app) + #add_menus(self, app) self.events = fs_builder.get_object("FullscreenEventbox") self.events.add(self.hb_revealer) @@ -248,10 +261,12 @@ def add_menus(headerbar, app): builder_window_menu = Gtk.Builder() builder_window_menu.add_from_resource( - "/de/wolfvollprecht/UberWriter/ui/Menu.ui") + "/de/wolfvollprecht/UberWriter/ui/Menu2.ui") model = builder_window_menu.get_object("Menu") + headerbar.light_button = builder_window_menu.get_object("light_mode_button") + headerbar.dark_button = builder_window_menu.get_object("dark_mode_button") - headerbar.menu_button.set_menu_model(model) + headerbar.menu_button.set_popover(model) # Add recents menu to the open recents button diff --git a/uberwriter/main_window.py b/uberwriter/main_window.py index 2880793..20dfa97 100644 --- a/uberwriter/main_window.py +++ b/uberwriter/main_window.py @@ -35,7 +35,6 @@ from gi.repository import Gtk, Gdk, GObject, GLib, Gio import cairo from uberwriter import helpers -from uberwriter.theme import Theme from uberwriter.sidebar import Sidebar from uberwriter.search_and_replace import SearchAndReplace diff --git a/uberwriter/styled_window.py b/uberwriter/styled_window.py index b95ad03..9e0fed6 100644 --- a/uberwriter/styled_window.py +++ b/uberwriter/styled_window.py @@ -1,7 +1,6 @@ import gi from uberwriter import helpers -from uberwriter.theme import Theme gi.require_version('Gtk', '3.0') from gi.repository import Gtk, GLib, Gio @@ -13,27 +12,11 @@ class StyledWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.connect("style-updated", self.apply_current_theme) - self.apply_current_theme() - - def apply_current_theme(self, *_): - """Adjusts the window, CSD and preview for the current theme.""" - # Get current theme - theme, changed = Theme.get_current_changed() - if changed: - # Set theme variant (dark/light) - Gtk.Settings.get_default().set_property( - "gtk-application-prefer-dark-theme", - GLib.Variant("b", theme.is_dark)) - - # Set theme css - css_provider_file = Gio.File.new_for_uri( - "resource:///de/wolfvollprecht/UberWriter/media/css/gtk/base.css") - style_provider = Gtk.CssProvider() - style_provider.load_from_file(css_provider_file) - Gtk.StyleContext.add_provider_for_screen( - self.get_screen(), style_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) - - # Redraw contents of window - self.queue_draw() \ No newline at end of file + # Set theme css + css_provider_file = Gio.File.new_for_uri( + "resource:///de/wolfvollprecht/UberWriter/media/css/gtk/base.css") + style_provider = Gtk.CssProvider() + style_provider.load_from_file(css_provider_file) + Gtk.StyleContext.add_provider_for_screen( + self.get_screen(), style_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) diff --git a/uberwriter/theme.py b/uberwriter/theme.py index 2c11e2f..732c774 100644 --- a/uberwriter/theme.py +++ b/uberwriter/theme.py @@ -56,11 +56,11 @@ class Theme: defaultThemes = [ # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/Adwaita Theme('Adwaita', get_css_path('web/adwaita.css'), False, 'Adwaita-dark'), - Theme('Adwaita-dark', get_css_path('web/adwaita_dark.css'), True, 'Adwaita'), + Theme('Adwaita-dark', get_css_path('web/adwaita.css'), True, 'Adwaita'), # https://github.com/NicoHood/arc-theme/tree/master/common/gtk-3.0/3.20/sass Theme('Arc', get_css_path('web/arc.css'), False, 'Arc-Dark'), - Theme('Arc-Darker', get_css_path('web/arc_darker.css'), False, 'Arc-Dark'), - Theme('Arc-Dark', get_css_path('web/arc_dark.css'), True, 'Arc'), + Theme('Arc-Darker', get_css_path('web/arc.css'), False, 'Arc-Dark'), + Theme('Arc-Dark', get_css_path('web/arc.css'), True, 'Arc'), # https://gitlab.gnome.org/GNOME/gtk/tree/master/gtk/theme/HighContrast Theme('HighContrast', get_css_path('web/highcontrast.css'), False, 'HighContrastInverse'), Theme('HighContrastInverse', get_css_path('web/highcontrast_inverse.css'), True, 'HighContrast')