mirror of
https://github.com/GradienceTeam/Gradience.git
synced 2024-09-29 23:17:53 +00:00
backend/theming: move apply, restore and reset preset functions to backend
This commit is contained in:
parent
22f476f766
commit
e1e244db72
3 changed files with 172 additions and 110 deletions
|
@ -23,3 +23,19 @@ presets_dir = os.path.join(
|
||||||
os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"),
|
os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"),
|
||||||
"presets",
|
"presets",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_gtk_theme_dir(app_type):
|
||||||
|
if app_type == "gtk4":
|
||||||
|
theme_dir = os.path.join(
|
||||||
|
os.environ.get("XDG_CONFIG_HOME",
|
||||||
|
os.environ["HOME"] + "/.config"),
|
||||||
|
"gtk-4.0",
|
||||||
|
)
|
||||||
|
elif app_type == "gtk3":
|
||||||
|
theme_dir = os.path.join(
|
||||||
|
os.environ.get("XDG_CONFIG_HOME",
|
||||||
|
os.environ["HOME"] + "/.config"),
|
||||||
|
"gtk-3.0",
|
||||||
|
)
|
||||||
|
|
||||||
|
return theme_dir
|
||||||
|
|
|
@ -16,13 +16,17 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import os
|
||||||
import json
|
import json
|
||||||
import material_color_utilities_python as monet
|
|
||||||
|
from gi.repository import GLib, Gio
|
||||||
|
|
||||||
from gradience.backend.theming.monet import Monet
|
from gradience.backend.theming.monet import Monet
|
||||||
from gradience.backend.models.preset import Preset
|
from gradience.backend.models.preset import Preset
|
||||||
from gradience.backend.utils.colors import rgba_from_argb
|
from gradience.backend.utils.colors import rgba_from_argb
|
||||||
|
|
||||||
|
from gradience.backend.globals import get_gtk_theme_dir
|
||||||
|
|
||||||
from gradience.backend.logger import Logger
|
from gradience.backend.logger import Logger
|
||||||
|
|
||||||
logging = Logger()
|
logging = Logger()
|
||||||
|
@ -32,6 +36,24 @@ class PresetUtils:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.preset = Preset()
|
self.preset = Preset()
|
||||||
|
|
||||||
|
def generate_gtk_css(self, app_type: str, preset: Preset) -> str:
|
||||||
|
variables = preset.variables
|
||||||
|
palette = preset.palette
|
||||||
|
custom_css = preset.custom_css
|
||||||
|
|
||||||
|
final_css = ""
|
||||||
|
|
||||||
|
for key in variables.keys():
|
||||||
|
final_css += f"@define-color {key} {variables[key]};\n"
|
||||||
|
|
||||||
|
for prefix_key in palette.keys():
|
||||||
|
for key in palette[prefix_key].keys():
|
||||||
|
final_css += f"@define-color {prefix_key + key} {palette[prefix_key][key]};\n"
|
||||||
|
|
||||||
|
final_css += custom_css.get(app_type, "")
|
||||||
|
|
||||||
|
return final_css
|
||||||
|
|
||||||
def new_preset_from_monet(self, name=None, monet_palette=None, props=None, vars_only=False) -> dict or bool:
|
def new_preset_from_monet(self, name=None, monet_palette=None, props=None, vars_only=False) -> dict or bool:
|
||||||
if props:
|
if props:
|
||||||
tone = props[0]
|
tone = props[0]
|
||||||
|
@ -160,11 +182,131 @@ class PresetUtils:
|
||||||
self.preset.save_to_file(name=name)
|
self.preset.save_to_file(name=name)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# TODO: Move exception handling to model/preset module
|
# TODO: Move exception handling to model/preset module
|
||||||
logging.error(f"Unexpected file error while trying to generate preset from generated Monet palette. Exc: {e}")
|
logging.error(f"Unexpected file error while trying to generate preset from Monet palette. Exc: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def apply_preset(self, app_type: str, preset: Preset) -> None:
|
||||||
|
if app_type == "gtk4":
|
||||||
|
theme_dir = get_gtk_theme_dir(app_type)
|
||||||
|
|
||||||
|
if not os.path.exists(theme_dir):
|
||||||
|
os.makedirs(theme_dir)
|
||||||
|
|
||||||
|
gtk4_css = self.generate_gtk_css("gtk4", preset)
|
||||||
|
contents = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css"), "r", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
contents = file.read()
|
||||||
|
except FileNotFoundError: # first run
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css.bak"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(contents)
|
||||||
|
finally:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(gtk4_css)
|
||||||
|
elif app_type == "gtk3":
|
||||||
|
theme_dir = get_gtk_theme_dir(app_type)
|
||||||
|
|
||||||
|
if not os.path.exists(theme_dir):
|
||||||
|
os.makedirs(theme_dir)
|
||||||
|
|
||||||
|
gtk3_css = self.generate_gtk_css("gtk3", preset)
|
||||||
|
contents = ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css"), "r", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
contents = file.read()
|
||||||
|
except FileNotFoundError: # first run
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css.bak"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(contents)
|
||||||
|
finally:
|
||||||
|
with open(
|
||||||
|
os.path.join(theme_dir, "gtk.css"), "w", encoding="utf-8"
|
||||||
|
) as file:
|
||||||
|
file.write(gtk3_css)
|
||||||
|
|
||||||
|
def restore_gtk4_preset(self):
|
||||||
|
try:
|
||||||
|
with open(
|
||||||
|
os.path.join(
|
||||||
|
os.environ.get(
|
||||||
|
"XDG_CONFIG_HOME", os.environ["HOME"] +
|
||||||
|
"/.config"
|
||||||
|
),
|
||||||
|
"gtk-4.0/gtk.css.bak",
|
||||||
|
),
|
||||||
|
"r",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as backup:
|
||||||
|
contents = backup.read()
|
||||||
|
backup.close()
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(
|
||||||
|
os.environ.get(
|
||||||
|
"XDG_CONFIG_HOME", os.environ["HOME"] +
|
||||||
|
"/.config"
|
||||||
|
),
|
||||||
|
"gtk-4.0/gtk.css",
|
||||||
|
),
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as gtk4css:
|
||||||
|
gtk4css.write(contents)
|
||||||
|
gtk4css.close()
|
||||||
|
except OSError as e:
|
||||||
|
logging.error(f"Unable to restore Gtk4 backup. Exc: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
def reset_preset(self, app_type: str) -> None:
|
||||||
|
if app_type == "gtk4":
|
||||||
|
file = Gio.File.new_for_path(
|
||||||
|
os.path.join(
|
||||||
|
os.environ.get(
|
||||||
|
"XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"
|
||||||
|
),
|
||||||
|
"gtk-4.0/gtk.css",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file.delete()
|
||||||
|
except GLib.GError as e:
|
||||||
|
logging.error(f"Unable to delete current preset. Exc: {e}")
|
||||||
|
raise
|
||||||
|
elif app_type == "gtk3":
|
||||||
|
file = Gio.File.new_for_path(
|
||||||
|
os.path.join(
|
||||||
|
os.environ.get(
|
||||||
|
"XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"
|
||||||
|
),
|
||||||
|
"gtk-3.0/gtk.css",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
file.delete()
|
||||||
|
except GLib.GError as e:
|
||||||
|
logging.error(f"Unable to delete current preset. Exc: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
preset_utils = PresetUtils()
|
preset_utils = PresetUtils()
|
||||||
|
|
||||||
|
|
|
@ -514,6 +514,7 @@ class GradienceApplication(Adw.Application):
|
||||||
Adw.ResponseAppearance.DESTRUCTIVE,
|
Adw.ResponseAppearance.DESTRUCTIVE,
|
||||||
transient_for=self.props.active_window,
|
transient_for=self.props.active_window,
|
||||||
)
|
)
|
||||||
|
dialog.gtk3_app_type.set_sensitive(False)
|
||||||
dialog.connect("response", self.restore_color_scheme)
|
dialog.connect("response", self.restore_color_scheme)
|
||||||
dialog.present()
|
dialog.present()
|
||||||
|
|
||||||
|
@ -691,60 +692,10 @@ class GradienceApplication(Adw.Application):
|
||||||
def apply_color_scheme(self, widget, response):
|
def apply_color_scheme(self, widget, response):
|
||||||
if response == "apply":
|
if response == "apply":
|
||||||
if widget.get_app_types()["gtk4"]:
|
if widget.get_app_types()["gtk4"]:
|
||||||
gtk4_dir = os.path.join(
|
PresetUtils().apply_preset("gtk4", self.preset)
|
||||||
os.environ.get("XDG_CONFIG_HOME",
|
|
||||||
os.environ["HOME"] + "/.config"),
|
|
||||||
"gtk-4.0",
|
|
||||||
)
|
|
||||||
if not os.path.exists(gtk4_dir):
|
|
||||||
os.makedirs(gtk4_dir)
|
|
||||||
gtk4_css = self.generate_gtk_css("gtk4")
|
|
||||||
contents = ""
|
|
||||||
try:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk4_dir, "gtk.css"), "r", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
contents = file.read()
|
|
||||||
except FileNotFoundError: # first run
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk4_dir, "gtk.css.bak"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(contents)
|
|
||||||
finally:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk4_dir, "gtk.css"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(gtk4_css)
|
|
||||||
|
|
||||||
if widget.get_app_types()["gtk3"]:
|
if widget.get_app_types()["gtk3"]:
|
||||||
gtk3_dir = os.path.join(
|
PresetUtils().apply_preset("gtk3", self.preset)
|
||||||
os.environ.get("XDG_CONFIG_HOME",
|
|
||||||
os.environ["HOME"] + "/.config"),
|
|
||||||
"gtk-3.0",
|
|
||||||
)
|
|
||||||
if not os.path.exists(gtk3_dir):
|
|
||||||
os.makedirs(gtk3_dir)
|
|
||||||
gtk3_css = self.generate_gtk_css("gtk3")
|
|
||||||
contents = ""
|
|
||||||
try:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk3_dir, "gtk.css"), "r", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
contents = file.read()
|
|
||||||
except FileNotFoundError: # first run
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk3_dir, "gtk.css.bak"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(contents)
|
|
||||||
finally:
|
|
||||||
with open(
|
|
||||||
os.path.join(gtk3_dir, "gtk.css"), "w", encoding="utf-8"
|
|
||||||
) as file:
|
|
||||||
file.write(gtk3_css)
|
|
||||||
|
|
||||||
self.reload_plugins()
|
self.reload_plugins()
|
||||||
self.plugins_list.apply()
|
self.plugins_list.apply()
|
||||||
|
@ -753,11 +704,12 @@ class GradienceApplication(Adw.Application):
|
||||||
Adw.Toast(title=_("Preset set successfully"))
|
Adw.Toast(title=_("Preset set successfully"))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: Make it as a seperate widget
|
||||||
dialog = Adw.MessageDialog(
|
dialog = Adw.MessageDialog(
|
||||||
transient_for=self.props.active_window,
|
transient_for=self.props.active_window,
|
||||||
heading=_("Log out"),
|
heading=_("Log out"),
|
||||||
body=_(
|
body=_(
|
||||||
"For the changes to take effect, you need to log out. "
|
"For the changes to take full effect, you need to log out."
|
||||||
),
|
),
|
||||||
body_use_markup=True,
|
body_use_markup=True,
|
||||||
)
|
)
|
||||||
|
@ -776,42 +728,9 @@ class GradienceApplication(Adw.Application):
|
||||||
def restore_color_scheme(self, widget, response):
|
def restore_color_scheme(self, widget, response):
|
||||||
if response == "restore":
|
if response == "restore":
|
||||||
if widget.get_app_types()["gtk4"]:
|
if widget.get_app_types()["gtk4"]:
|
||||||
file = Gio.File.new_for_path(
|
|
||||||
os.path.join(
|
|
||||||
os.environ.get(
|
|
||||||
"XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"
|
|
||||||
),
|
|
||||||
"gtk-4.0/gtk.css.bak",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
backup = open(
|
PresetUtils().restore_gtk4_preset()
|
||||||
os.path.join(
|
except Exception:
|
||||||
os.environ.get(
|
|
||||||
"XDG_CONFIG_HOME", os.environ["HOME"] +
|
|
||||||
"/.config"
|
|
||||||
),
|
|
||||||
"gtk-4.0/gtk.css.bak",
|
|
||||||
),
|
|
||||||
"r",
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
contents = backup.read()
|
|
||||||
backup.close()
|
|
||||||
gtk4css = open(
|
|
||||||
os.path.join(
|
|
||||||
os.environ.get(
|
|
||||||
"XDG_CONFIG_HOME", os.environ["HOME"] +
|
|
||||||
"/.config"
|
|
||||||
),
|
|
||||||
"gtk-4.0/gtk.css",
|
|
||||||
),
|
|
||||||
"w",
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
||||||
gtk4css.write(contents)
|
|
||||||
gtk4css.close()
|
|
||||||
except FileNotFoundError:
|
|
||||||
self.win.toast_overlay.add_toast(
|
self.win.toast_overlay.add_toast(
|
||||||
Adw.Toast(title=_("Unable to restore GTK 4 backup"))
|
Adw.Toast(title=_("Unable to restore GTK 4 backup"))
|
||||||
)
|
)
|
||||||
|
@ -820,7 +739,7 @@ class GradienceApplication(Adw.Application):
|
||||||
transient_for=self.props.active_window,
|
transient_for=self.props.active_window,
|
||||||
heading=_("Log out"),
|
heading=_("Log out"),
|
||||||
body=_(
|
body=_(
|
||||||
"For the changes to take effect, you need to log out. "
|
"For the changes to take full effect, you need to log out."
|
||||||
),
|
),
|
||||||
body_use_markup=True,
|
body_use_markup=True,
|
||||||
)
|
)
|
||||||
|
@ -839,32 +758,16 @@ class GradienceApplication(Adw.Application):
|
||||||
def reset_color_scheme(self, widget, response):
|
def reset_color_scheme(self, widget, response):
|
||||||
if response == "reset":
|
if response == "reset":
|
||||||
if widget.get_app_types()["gtk4"]:
|
if widget.get_app_types()["gtk4"]:
|
||||||
file = Gio.File.new_for_path(
|
|
||||||
os.path.join(
|
|
||||||
os.environ.get(
|
|
||||||
"XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"
|
|
||||||
),
|
|
||||||
"gtk-4.0/gtk.css",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
file.delete()
|
PresetUtils().reset_preset("gtk4")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.win.toast_overlay.add_toast(
|
self.win.toast_overlay.add_toast(
|
||||||
Adw.Toast(title=_("Unable to delete current preset"))
|
Adw.Toast(title=_("Unable to delete current preset"))
|
||||||
)
|
)
|
||||||
|
|
||||||
if widget.get_app_types()["gtk3"]:
|
if widget.get_app_types()["gtk3"]:
|
||||||
file = Gio.File.new_for_path(
|
|
||||||
os.path.join(
|
|
||||||
os.environ.get(
|
|
||||||
"XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"
|
|
||||||
),
|
|
||||||
"gtk-3.0/gtk.css",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
file.delete()
|
PresetUtils().reset_preset("gtk3")
|
||||||
except Exception:
|
except Exception:
|
||||||
self.win.toast_overlay.add_toast(
|
self.win.toast_overlay.add_toast(
|
||||||
Adw.Toast(title=_("Unable to delete current preset"))
|
Adw.Toast(title=_("Unable to delete current preset"))
|
||||||
|
@ -874,7 +777,7 @@ class GradienceApplication(Adw.Application):
|
||||||
transient_for=self.props.active_window,
|
transient_for=self.props.active_window,
|
||||||
heading=_("Log out"),
|
heading=_("Log out"),
|
||||||
body=_(
|
body=_(
|
||||||
"For the changes to take effect, you need to log out. "
|
"For the changes to take full effect, you need to log out."
|
||||||
),
|
),
|
||||||
body_use_markup=True,
|
body_use_markup=True,
|
||||||
)
|
)
|
||||||
|
@ -895,6 +798,7 @@ class GradienceApplication(Adw.Application):
|
||||||
prefs.set_transient_for(self.win)
|
prefs.set_transient_for(self.win)
|
||||||
prefs.present()
|
prefs.present()
|
||||||
|
|
||||||
|
# TODO: Move it to seperate frontend module
|
||||||
def show_about_window(self, *_args):
|
def show_about_window(self, *_args):
|
||||||
about = Adw.AboutWindow(
|
about = Adw.AboutWindow(
|
||||||
transient_for=self.props.active_window,
|
transient_for=self.props.active_window,
|
||||||
|
|
Loading…
Reference in a new issue