Merge branch 'main' into pypi-deps

This commit is contained in:
0xMRTT 2022-09-13 23:23:36 +02:00 committed by GitHub
commit b224d17237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 245 additions and 35 deletions

View file

@ -81,7 +81,7 @@ yay -S gradience # or gradience-git
- GTK4 `gtk4`
- libadwaita (>= 1.2.alpha) `libadwaita`
- Meson `meson`
- Ninja `ninja`
- Ninja `ninja-build`
Install required Python libraries:
@ -104,7 +104,7 @@ sudo ninja -C builddir install
git clone https://github.com/GradienceTeam/Gradience.git
cd Gradience
meson builddir
meson configure builddir -Dprefix="$(pwd)/builddir/testdir"
meson configure builddir -Dprefix="$(pwd)/builddir"
ninja -C builddir install
ninja -C builddir run
```

View file

@ -1,12 +0,0 @@
#!/usr/bin/env python3
import os
import subprocess
build_root = os.environ.get("MESON_BUILD_ROOT")
source_root = os.environ.get("MESON_SOURCE_ROOT")
subprocess.call(
["mv", build_root, "gradience/constants.py",
source_root, "gradience/constants.py"]
)

View file

@ -42,11 +42,10 @@ template GradienceMainWindow : Adw.ApplicationWindow {
}
[end]
Button presets_button {
MenuButton presets-dropdown {
menu-model: presets-menu;
label: _("Presets");
tooltip-text: _("Presets");
icon-name: "palette-symbolic";
clicked => on_presets_button_clicked();
}
[end]
@ -66,7 +65,7 @@ template GradienceMainWindow : Adw.ApplicationWindow {
popover: errors-popover;
}
}
@ -81,9 +80,9 @@ template GradienceMainWindow : Adw.ApplicationWindow {
name: "colors";
title: _("Colors");
icon-name: "larger-brush-symbolic";
child: Adw.PreferencesPage content { };
}
Adw.ViewStackPage {
@ -156,6 +155,32 @@ menu preview-menu {
}
}
menu presets-menu {
section {
label: _("Built-in Presets");
item {
label: "Adwaita";
action: "app.load_preset";
target: "adwaita";
}
item {
label: "Adwaita Dark";
action: "app.load_preset";
target: "adwaita-dark";
}
item {
label: "Pretty purple";
action: "app.load_preset";
target: "pretty-purple";
}
item {
label: "Manage Presets";
action: "app.manage_presets";
}
}
}
Popover errors-popover {
ListBox errors-list {
selection-mode: none;

View file

@ -22,6 +22,7 @@ import os
import sys
import signal
import locale
import shutil
import gettext
is_local = @local_build@
@ -33,6 +34,11 @@ if is_local:
# In the local use case the installed schemas go in <builddir>/data
os.environ["XDG_DATA_DIRS"] = '@SCHEMAS_DIR@:' + os.environ.get("XDG_DATA_DIRS", "")
shutil.copyfile(
os.path.join('@BUILD_DIR@', "gradience", "constants.py"),
os.path.join('@SOURCE_DIR@', "gradience", "constants.py")
)
pkgdatadir = '@PKGDATA_DIR@'
localedir = '@LOCALE_DIR@'

View file

@ -19,6 +19,7 @@
import sys
import json
import os
import traceback
from gi.repository import Gtk, Gdk, Gio, Adw, GLib, Xdp, XdpGtk4
from material_color_utilities_python import *
@ -40,7 +41,8 @@ from .welcome import GradienceWelcomeWindow
from .preferences import GradiencePreferencesWindow
from .modules.utils import to_slug_case, buglog
from .plugins_list import GradiencePluginsList
from .presets_manager_window import GradiencePresetWindow
from pathlib import Path
class GradienceApplication(Adw.Application):
"""The main application singleton class."""
@ -110,6 +112,7 @@ class GradienceApplication(Adw.Application):
self.create_action(
"restore_color_scheme", self.show_restore_color_scheme_dialog
)
self.create_action("manage_presets", self.manage_presets)
self.create_action("reset_color_scheme",
self.show_reset_color_scheme_dialog)
@ -118,6 +121,8 @@ class GradienceApplication(Adw.Application):
self.create_action("about", self.show_about_window)
self.load_preset_from_css()
self.reload_user_defined_presets()
if self.first_run:
buglog("first run")
welcome = GradienceWelcomeWindow(self.win)
@ -126,6 +131,111 @@ class GradienceApplication(Adw.Application):
buglog("normal run")
self.win.present()
def reload_user_defined_presets(self):
print("reload")
if self.props.active_window.presets_menu.get_n_items() > 1:
self.props.active_window.presets_menu.remove(1)
preset_directory = os.path.join(
os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"),
"presets",
)
if not os.path.exists(preset_directory):
os.makedirs(preset_directory)
self.custom_presets = {"user": {}}
for repo in Path(preset_directory).iterdir():
if repo.is_dir(): # repo
presets_list = {}
for file_name in repo.iterdir():
file_name = str(file_name)
if file_name.endswith(".json"):
try:
with open(
os.path.join(preset_directory, file_name),
"r",
encoding="utf-8",
) as file:
preset_text = file.read()
preset = json.loads(preset_text)
if preset.get("variables") is None:
raise KeyError("variables")
if preset.get("palette") is None:
raise KeyError("palette")
presets_list[file_name.replace(".json", "")] = preset[
"name"
]
except Exception:
self.win.toast_overlay.add_toast(
Adw.Toast(title=_("Failed to load preset"))
)
self.custom_presets[repo.name] = presets_list
elif repo.is_file():
buglog("file")
# keep compatiblity with old presets
if repo.name.endswith(".json"):
os.rename(repo, os.path.join(
preset_directory, "user", repo.name))
try:
with open(
os.path.join(preset_directory, "user", repo),
"r",
encoding="utf-8",
) as file:
preset_text = file.read()
preset = json.loads(preset_text)
if preset.get("variables") is None:
raise KeyError("variables")
if preset.get("palette") is None:
raise KeyError("palette")
presets_list["user"][file_name.replace(".json", "")] = preset[
"name"
]
except Exception:
self.win.toast_overlay.add_toast(
Adw.Toast(title=_("Failed to load preset"))
)
buglog(self.custom_presets)
custom_menu_section = Gio.Menu()
if self.custom_presets["user"] or self.custom_presets["curated"] or self.custom_presets["official"]:
for repo, content in self.custom_presets.items():
for preset, preset_name in content.items():
menu_item = Gio.MenuItem()
menu_item.set_label(preset_name)
if not preset.startswith("error"):
menu_item.set_action_and_target_value(
"app.load_preset", GLib.Variant("s", "custom-" + preset)
)
else:
menu_item.set_action_and_target_value("")
custom_menu_section.append_item(menu_item)
else:
menu_item = Gio.MenuItem()
menu_item.set_label("No presets found")
custom_menu_section.append_item(menu_item)
open_in_file_manager_item = Gio.MenuItem()
open_in_file_manager_item.set_label(_("Open in File Manager"))
open_in_file_manager_item.set_action_and_target_value(
"app.open_preset_directory"
)
# custom_menu_section.append_item(open_in_file_manager_item)
self.props.active_window.presets_menu.append_section(
_("Installed Presets"), custom_menu_section
)
def manage_presets(self, *args):
presets = GradiencePresetWindow(self)
presets.set_transient_for(self.win)
presets.set_modal(True)
presets.present()
def load_preset_from_css(self):
try:
variables, palette, custom_css = load_preset_from_css(
@ -523,6 +633,79 @@ class GradienceApplication(Adw.Application):
dialog.present()
def show_exit_dialog(self, *_args):
dialog = Adw.MessageDialog(
transient_for=self.props.active_window,
heading=_("You have unsaved changes!"),
body=_(
"Saving preset to <tt>{0}</tt>. If that preset already exists, it will be overwritten!"
).format(
os.path.join(
os.environ.get("XDG_CONFIG_HOME",
os.environ["HOME"] + "/.config"),
"presets",
"user",
to_slug_case(self.preset_name) + ".json",
)
),
body_use_markup=True,
)
dialog.add_response("cancel", _("Cancel"))
dialog.add_response("discard", _("Discard"))
dialog.add_response("save", _("Save"))
dialog.set_response_appearance(
"save", Adw.ResponseAppearance.SUGGESTED)
dialog.set_response_appearance(
"discard", Adw.ResponseAppearance.DESTRUCTIVE)
dialog.set_default_response("cancel")
dialog.set_close_response("cancel")
preset_entry = Gtk.Entry(placeholder_text="Preset Name")
preset_entry.set_text(self.preset_name)
def on_preset_entry_change(*_args):
if len(preset_entry.get_text()) == 0:
dialog.set_body(
_(
"Saving preset to <tt>{0}</tt>. If that preset already exists, it will be overwritten!"
).format(
os.path.join(
os.environ.get(
"XDG_CONFIG_HOME", os.environ["HOME"] +
"/.config"
),
"presets",
"user",
)
)
)
dialog.set_response_enabled("save", False)
else:
dialog.set_body(
_(
"Saving preset to <tt>{0}</tt>. If that preset already exists, it will be overwritten!"
).format(
os.path.join(
os.environ.get(
"XDG_CONFIG_HOME", os.environ["HOME"] +
"/.config"
),
"presets",
"user",
to_slug_case(preset_entry.get_text()) + ".json",
)
)
)
dialog.set_response_enabled("save", True)
preset_entry.connect("changed", on_preset_entry_change)
dialog.set_extra_child(preset_entry)
dialog.connect("response", self.save_preset, preset_entry)
dialog.present()
def save_preset(self, _unused, response, entry):
if response == "save":
if not os.path.exists(
@ -565,7 +748,9 @@ class GradienceApplication(Adw.Application):
self.clear_dirty()
self.win.toast_overlay.add_toast(
Adw.Toast(title=_("Preset saved")))
elif response == "discard":
self.clear_dirty()
self.win.close()
def apply_color_scheme(self, widget, response):
if response == "apply":
if widget.get_app_types()["gtk4"]:

View file

@ -34,7 +34,6 @@ def load_preset_from_css(path):
break
else:
variables[name] = color[:-1]
print(f"{name} = {color}")
elif rule.type == rule.STYLE_RULE:
css += f"\n{rule.cssText}"
return variables, palette, css

View file

@ -144,7 +144,7 @@ class GradiencePresetRow(Adw.ActionRow):
"custom_css": custom_css,
}
file.write(json.dumps(object_to_write, indent=4))
self.toast_overlay.add_toast(Adw.Toast(title=_("Preset renamed")))
# self.toast_overlay.add_toast(Adw.Toast(title=_("Preset renamed")))
os.remove(
os.path.join(
os.environ.get("XDG_CONFIG_HOME",

View file

@ -72,6 +72,8 @@ class GradiencePresetWindow(Adw.Window):
self.app = Gtk.Application.get_default()
self.parent = parent
self.settings = parent.settings
self.user_repositories = self.settings.get_value("repos").unpack()

View file

@ -46,10 +46,13 @@ class GradienceMainWindow(Adw.ApplicationWindow):
main_menu = Gtk.Template.Child("main-menu")
errors_button = Gtk.Template.Child("errors-button")
errors_list = Gtk.Template.Child("errors-list")
presets_dropdown = Gtk.Template.Child("presets-dropdown")
presets_menu = Gtk.Template.Child("presets-menu")
monet_image_file = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.presets_dropdown.get_popover().connect("show", self.on_presets_dropdown_activate)
# Set devel style
if build_type == "debug":
@ -75,7 +78,7 @@ class GradienceMainWindow(Adw.ApplicationWindow):
"window-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT
)
self.connect("close-request", self.close_window)
self.connect("close-request", self.on_close_request)
self.style_manager = self.get_application().style_manager
self.first_apply = True
@ -106,9 +109,13 @@ class GradienceMainWindow(Adw.ApplicationWindow):
def on_file_picker_button_clicked(self, *args):
self.monet_file_chooser_dialog.show()
def close_window(self, *args):
def on_close_request(self, *args):
if self.get_application().is_dirty:
buglog("app is dirty")
buglog("Window close request")
self.get_application().show_exit_dialog()
return True
else:
self.close()
def on_monet_file_chooser_response(self, widget, response):
if response == Gtk.ResponseType.ACCEPT:
@ -288,9 +295,5 @@ class GradienceMainWindow(Adw.ApplicationWindow):
GradienceError(error["error"], error["element"], error["line"])
)
@Gtk.Template.Callback()
def on_presets_button_clicked(self, *args):
presets = GradiencePresetWindow(self.get_application())
presets.set_transient_for(self)
presets.set_modal(True)
presets.present()
def on_presets_dropdown_activate(self, *args):
self.get_application().reload_user_defined_presets()

View file

@ -61,6 +61,8 @@ conf.set('PYTHON', PY_INSTALLDIR.full_path())
conf.set('VERSION', meson.project_version() + VERSION_SUFFIX)
conf.set('BUILD_TYPE', get_option('buildtype'))
conf.set('SCHEMAS_DIR', PKGDATA_DIR)
conf.set('SOURCE_DIR', meson.current_source_dir())
conf.set('BUILD_DIR', meson.current_build_dir())
conf.set('local_build', 'False')
@ -73,6 +75,8 @@ local_conf.set('PYTHON', meson.current_source_dir())
local_conf.set('VERSION', meson.project_version() + VERSION_SUFFIX)
local_conf.set('BUILD_TYPE', get_option('buildtype'))
local_conf.set('SCHEMAS_DIR', join_paths(meson.current_build_dir(), 'data'))
local_conf.set('SOURCE_DIR', meson.current_source_dir())
local_conf.set('BUILD_DIR', meson.current_build_dir())
local_conf.set('local_build', 'True')
@ -81,8 +85,6 @@ subdir('gradience')
subdir('data')
subdir('po')
#meson.add_install_script('build-aux/meson_post_install.py')
gnome.post_install(
glib_compile_schemas: true,
gtk_update_icon_cache: true,