diff --git a/.github/workflows/flatpak-nightly.yml b/.github/workflows/flatpak-nightly.yml new file mode 100644 index 00000000..61345721 --- /dev/null +++ b/.github/workflows/flatpak-nightly.yml @@ -0,0 +1,19 @@ +name: Build flatpak nightly +on: + push: + branches: [next] +jobs: + flatpak: + name: "Flatpak" + runs-on: ubuntu-latest + container: + image: bilelmoussaoui/flatpak-github-actions:gnome-nightly + options: --privileged + steps: + - name: Checkout + uses: actions/checkout@v3.0.2 + - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 + with: + bundle: com.github.AdwCustomizerTeam.AdwCustomizer.Devel.flatpak + manifest-path: com.github.AdwCustomizerTeam.AdwCustomizer.Devel.json + cache-key: flatpak-builder-${{ github.sha }}-nightly \ No newline at end of file diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml new file mode 100644 index 00000000..69360a41 --- /dev/null +++ b/.github/workflows/flatpak.yml @@ -0,0 +1,19 @@ +name: Build flatpak +on: + push: + branches: [main] +jobs: + flatpak: + name: "Flatpak" + runs-on: ubuntu-latest + container: + image: bilelmoussaoui/flatpak-github-actions:gnome-nightly + options: --privileged + steps: + - name: Checkout + uses: actions/checkout@v3.0.2 + - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 + with: + bundle: com.github.AdwCustomizerTeam.AdwCustomizer.flatpak + manifest-path: com.github.AdwCustomizerTeam.AdwCustomizer.json + cache-key: flatpak-builder-${{ github.sha }} \ No newline at end of file diff --git a/com.github.AdwCustomizerTeam.AdwCustomizer.Devel.json b/com.github.AdwCustomizerTeam.AdwCustomizer.Devel.json new file mode 100644 index 00000000..31be453c --- /dev/null +++ b/com.github.AdwCustomizerTeam.AdwCustomizer.Devel.json @@ -0,0 +1,82 @@ +{ + "app-id" : "com.github.AdwCustomizerTeam.AdwCustomizer", + "runtime" : "org.gnome.Platform", + "runtime-version" : "master", + "sdk" : "org.gnome.Sdk", + "command" : "adwcustomizer", + "finish-args" : [ + "--share=network", + "--share=ipc", + "--socket=fallback-x11", + "--device=dri", + "--socket=wayland", + "--filesystem=xdg-config/gtk-3.0", + "--filesystem=xdg-config/gtk-4.0" + ], + "cleanup" : [ + "/include", + "/lib/pkgconfig", + "/man", + "/share/doc", + "/share/gtk-doc", + "/share/man", + "/share/pkgconfig", + "*.la", + "*.a" + ], + "modules" : [ + "pypi-dependencies.json", + { + "name" : "blueprint-compiler", + "buildsystem" : "meson", + "sources" : [ + { + "type" : "git", + "url" : "https://gitlab.gnome.org/jwestman/blueprint-compiler", + "branch" : "main" + } + ] + }, + { + "name": "libportal", + "buildsystem": "meson", + "config-opts": ["-Ddocs=false", "-Dvapi=false", "-Dbackends=gtk4"], + "sources": [ + { + "type": "git", + "url": "https://github.com/flatpak/libportal", + "branch": "main" + } + ] + }, + { + "name": "material-color-utilities-python", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"material_color_utilities_python~=0.1.0\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "path": "./monet/material_color_utilities_python-0.1.0-py3-none-any.whl", + "sha256": "735d40c0afae660e319798c697da8fe332cfc7103fbed8a081a187f437ed4523" + } + ] + }, + { + "name" : "adwcustomizer", + "builddir" : true, + "buildsystem" : "meson", + "sources" : [ + { + "type" : "git", + "path" : ".", + "branch": "next" + } + ] + } + ], + "build-options" : { + "env" : { } + } +} diff --git a/com.github.AdwCustomizerTeam.AdwCustomizer.json b/com.github.AdwCustomizerTeam.AdwCustomizer.json index bccf7bf1..2bb34ef9 100644 --- a/com.github.AdwCustomizerTeam.AdwCustomizer.json +++ b/com.github.AdwCustomizerTeam.AdwCustomizer.json @@ -49,6 +49,20 @@ } ] }, + { + "name": "material-color-utilities-python", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"material_color_utilities_python~=0.1.0\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "path": "./monet/material_color_utilities_python-0.1.0-py3-none-any.whl", + "sha256": "735d40c0afae660e319798c697da8fe332cfc7103fbed8a081a187f437ed4523" + } + ] + }, { "name" : "adwcustomizer", "builddir" : true, diff --git a/data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in b/data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in index b37c49bf..0c3a7ce6 100644 --- a/data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in +++ b/data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in @@ -104,13 +104,29 @@

First release of Adwaita Manager.

+ https://github.com/AdwCustomizerTeam/AdwCustomizer https://github.com/AdwCustomizerTeam/AdwCustomizer/issues - https://github.com/AdwCustomizerTeam/AdwCustomizer/issues + https://github.com/orgs/AdwCustomizerTeam/discussions https://www.transifex.com/adwcustomizerteam/adwcustomizer - add-team-email-here + AdwCustomizerTeam@proton.me diff --git a/data/com.github.AdwCustomizerTeam.AdwCustomizer.gschema.xml b/data/com.github.AdwCustomizerTeam.AdwCustomizer.gschema.xml index 16539ddc..fe28f555 100644 --- a/data/com.github.AdwCustomizerTeam.AdwCustomizer.gschema.xml +++ b/data/com.github.AdwCustomizerTeam.AdwCustomizer.gschema.xml @@ -13,5 +13,8 @@ false + + true + \ No newline at end of file diff --git a/meson.build b/meson.build index 36f2ff2f..e22a4fc1 100644 --- a/meson.build +++ b/meson.build @@ -1,11 +1,15 @@ project('adwcustomizer', - version: 'git', + version: '0.1.0', meson_version: '>= 0.59.0', default_options: [ 'warning_level=2', 'werror=false', ], ) +dependency('glib-2.0') +dependency('pygobject-3.0') +dependency('libadwaita-1') + i18n = import('i18n') gnome = import('gnome') diff --git a/monet/material_color_utilities_python-0.1.0-py3-none-any.whl b/monet/material_color_utilities_python-0.1.0-py3-none-any.whl new file mode 100644 index 00000000..d1d1e19d Binary files /dev/null and b/monet/material_color_utilities_python-0.1.0-py3-none-any.whl differ diff --git a/po/AdwCustomizer.pot b/po/AdwCustomizer.pot index c45e6035..13f7a243 100644 --- a/po/AdwCustomizer.pot +++ b/po/AdwCustomizer.pot @@ -1,6 +1,6 @@ # Adwaita Manager POT file # Copyright (C) 2022 Adwaita Manager Team -# This file is distributed under the MIT/X11 license. +# This file is distributed under the GNU GPLv3 license. # Adwaita Manager Team, 2022. # #, fuzzy @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-08-09 22:21+0300\n" +"POT-Creation-Date: 2022-08-12 11:24+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -18,11 +18,13 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: data/com.github.AdwCustomizerTeam.AdwCustomizer.desktop.in:3 -#: src/ui/window.blp:5 src/main.py:332 +#: data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in:6 +#: src/ui/window.blp:5 src/main.py:642 msgid "Adwaita Manager" msgstr "" #: data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in:7 +#: data/com.github.AdwCustomizerTeam.AdwCustomizer.appdata.xml.in:9 msgid "Change the look of Adwaita, with ease" msgstr "" @@ -70,225 +72,236 @@ msgstr "" msgid "Toggle Text Value" msgstr "" -#: src/ui/window.blp:13 src/main.py:245 +#: src/ui/window.blp:23 src/main.py:428 msgid "Apply" msgstr "" -#: src/ui/window.blp:20 -msgid "Save Preset" -msgstr "" - -#: src/ui/window.blp:36 +#: src/ui/window.blp:35 msgid "Presets" msgstr "" -#: src/ui/window.blp:58 +#: src/ui/window.blp:42 +msgid "Save Preset" +msgstr "" + +#: src/ui/window.blp:112 msgid "Built-in Presets" msgstr "" -#: src/ui/window.blp:73 +#: src/ui/window.blp:134 +msgid "Release Notes" +msgstr "" + +#: src/ui/window.blp:138 msgid "Reset Applied Color Scheme" msgstr "" -#: src/ui/window.blp:74 +#: src/ui/window.blp:142 msgid "About Adwaita Manager" msgstr "" -#: src/app_type_dialog.py:43 src/main.py:264 +#: src/app_type_dialog.py:44 src/main.py:474 msgid "Cancel" msgstr "" -#: src/main.py:123 +#: src/main.py:140 src/main.py:146 msgid "Failed to load preset" msgstr "" -#: src/main.py:139 +#: src/main.py:163 msgid "Open in File Manager" msgstr "" -#: src/main.py:142 +#: src/main.py:169 msgid "User Defined Presets" msgstr "" -#: src/main.py:203 +#: src/main.py:358 msgid "Unsaved changes" msgstr "" -#: src/main.py:243 +#: src/main.py:423 msgid "Apply this color scheme?" msgstr "" -#: src/main.py:244 +#: src/main.py:425 msgid "" "Warning: any custom CSS files for those app types will be irreversibly " "overwritten!" msgstr "" -#: src/main.py:251 +#: src/main.py:448 msgid "Reset applied color scheme?" msgstr "" -#: src/main.py:252 +#: src/main.py:449 msgid "Make sure you have the current settings saved as a preset." msgstr "" -#: src/main.py:253 +#: src/main.py:451 msgid "Reset" msgstr "" -#: src/main.py:260 +#: src/main.py:461 msgid "Save preset as..." msgstr "" -#: src/main.py:261 src/main.py:274 src/main.py:277 +#: src/main.py:463 src/main.py:487 src/main.py:501 #, python-brace-format msgid "" "Saving preset to {0}. If that preset already exists, it will be " "overwritten!" msgstr "" -#: src/main.py:265 +#: src/main.py:475 msgid "Save" msgstr "" -#: src/main.py:334 +#: src/main.py:541 +msgid "Scheme successfully saved!" +msgstr "" + +#: src/main.py:605 +msgid "Scheme set successfully!" +msgstr "" + +#: src/main.py:637 +msgid "Reset successfully!" +msgstr "" + +#: src/main.py:644 msgid "Adwaita Manager Team" msgstr "" -#. Translators: This is a place to put your credits (formats: "Name https://example.com" or "Name ", no quotes) and is not meant to be translated literally. -#: src/main.py:338 -msgid "translator-credits" -msgstr "" - -#: src/option.py:55 +#: src/option.py:47 msgid "This option is only partially supported by the adw-gtk3 theme." msgstr "" -#: src/option.py:58 +#: src/option.py:52 msgid "This option is not supported by the adw-gtk3 theme." msgstr "" -#: src/option.py:97 +#: src/option.py:94 msgid "Not a color, see text value" msgstr "" -#: src/settings_schema.py:5 +#: src/settings_schema.py:23 msgid "Accent Colors" msgstr "" -#: src/settings_schema.py:6 +#: src/settings_schema.py:25 msgid "" "These colors are used across many different widgets, such as buttons, " "labels, and entries, to indicate that a widget is important, interactive, or " "currently active." msgstr "" -#: src/settings_schema.py:10 src/settings_schema.py:33 -#: src/settings_schema.py:56 src/settings_schema.py:79 -#: src/settings_schema.py:102 +#: src/settings_schema.py:30 src/settings_schema.py:57 +#: src/settings_schema.py:84 src/settings_schema.py:111 +#: src/settings_schema.py:138 msgid "Standalone Color" msgstr "" -#: src/settings_schema.py:11 src/settings_schema.py:34 -#: src/settings_schema.py:57 src/settings_schema.py:80 -#: src/settings_schema.py:103 +#: src/settings_schema.py:32 src/settings_schema.py:59 +#: src/settings_schema.py:86 src/settings_schema.py:113 +#: src/settings_schema.py:140 msgid "" "The standalone colors are similar to the background ones, but provide better " "contrast when used as foreground color on top of a neutral background - for " "example, colorful text in a window." msgstr "" -#: src/settings_schema.py:16 src/settings_schema.py:39 -#: src/settings_schema.py:62 src/settings_schema.py:85 -#: src/settings_schema.py:108 src/settings_schema.py:125 -#: src/settings_schema.py:142 src/settings_schema.py:159 -#: src/settings_schema.py:194 src/settings_schema.py:217 -#: src/settings_schema.py:234 +#: src/settings_schema.py:38 src/settings_schema.py:65 +#: src/settings_schema.py:92 src/settings_schema.py:119 +#: src/settings_schema.py:146 src/settings_schema.py:163 +#: src/settings_schema.py:182 src/settings_schema.py:201 +#: src/settings_schema.py:242 src/settings_schema.py:267 +#: src/settings_schema.py:284 msgid "Background Color" msgstr "" -#: src/settings_schema.py:21 src/settings_schema.py:44 -#: src/settings_schema.py:67 src/settings_schema.py:90 -#: src/settings_schema.py:113 src/settings_schema.py:130 -#: src/settings_schema.py:147 src/settings_schema.py:164 -#: src/settings_schema.py:199 src/settings_schema.py:222 -#: src/settings_schema.py:239 +#: src/settings_schema.py:43 src/settings_schema.py:70 +#: src/settings_schema.py:97 src/settings_schema.py:124 +#: src/settings_schema.py:151 src/settings_schema.py:168 +#: src/settings_schema.py:187 src/settings_schema.py:206 +#: src/settings_schema.py:247 src/settings_schema.py:272 +#: src/settings_schema.py:289 msgid "Foreground Color" msgstr "" -#: src/settings_schema.py:28 +#: src/settings_schema.py:50 msgid "Destructive Colors" msgstr "" -#: src/settings_schema.py:29 +#: src/settings_schema.py:52 msgid "" "These colors are used for buttons to indicate a dangerous action, such as " "deleting a file." msgstr "" -#: src/settings_schema.py:51 +#: src/settings_schema.py:77 msgid "Success Colors" msgstr "" -#: src/settings_schema.py:52 +#: src/settings_schema.py:79 msgid "" "These colors are used across many different widgets, such as buttons, " "labels, entries, and level bars, to indicate a success or a high level." msgstr "" -#: src/settings_schema.py:74 +#: src/settings_schema.py:104 msgid "Warning Colors" msgstr "" -#: src/settings_schema.py:75 +#: src/settings_schema.py:106 msgid "" "These colors are used across many different widgets, such as buttons, " "labels, entries, and level bars, to indicate a warning or a low level." msgstr "" -#: src/settings_schema.py:97 +#: src/settings_schema.py:131 msgid "Error Colors" msgstr "" -#: src/settings_schema.py:98 +#: src/settings_schema.py:133 msgid "" "These colors are used across many different widgets, such as buttons, " "labels, and entries, to indicate a failure." msgstr "" -#: src/settings_schema.py:120 +#: src/settings_schema.py:158 msgid "Window Colors" msgstr "" -#: src/settings_schema.py:121 +#: src/settings_schema.py:159 msgid "These colors are used primarily for windows." msgstr "" -#: src/settings_schema.py:137 +#: src/settings_schema.py:175 msgid "View Colors" msgstr "" -#: src/settings_schema.py:138 +#: src/settings_schema.py:177 msgid "" "These colors are used in a variety of widgets, such as text views and " "entries." msgstr "" -#: src/settings_schema.py:154 +#: src/settings_schema.py:194 msgid "Header Bar Colors" msgstr "" -#: src/settings_schema.py:155 +#: src/settings_schema.py:196 msgid "" "These colors are used for header bars, as well as widgets that are meant to " "be visually attached to it, such as search bars or tab bars." msgstr "" -#: src/settings_schema.py:169 +#: src/settings_schema.py:211 msgid "Border Color" msgstr "" -#: src/settings_schema.py:170 +#: src/settings_schema.py:213 msgid "" "The border color has the same default value as a foreground color, but " "doesn't change along with it. This can be useful if a light window has a " @@ -297,11 +310,11 @@ msgid "" "example, separators between the two header bars in a split header bar layout." msgstr "" -#: src/settings_schema.py:175 +#: src/settings_schema.py:219 msgid "Backdrop Color" msgstr "" -#: src/settings_schema.py:176 +#: src/settings_schema.py:221 msgid "" "The backdrop color is used instead of the background color when the window " "is not focused. By default it's an alias of the window's background color " @@ -309,113 +322,139 @@ msgid "" "it to a value matching your header bar background color." msgstr "" -#: src/settings_schema.py:181 src/settings_schema.py:204 -#: src/settings_schema.py:251 +#: src/settings_schema.py:227 src/settings_schema.py:252 +#: src/settings_schema.py:301 msgid "Shade Color" msgstr "" -#: src/settings_schema.py:182 +#: src/settings_schema.py:229 msgid "" "The shade color is used to provide a dark border for header bars and similar " "widgets that separates them from the main window." msgstr "" -#: src/settings_schema.py:189 +#: src/settings_schema.py:237 msgid "Card Colors" msgstr "" -#: src/settings_schema.py:190 +#: src/settings_schema.py:238 msgid "These colors are used for cards and boxed lists." msgstr "" -#: src/settings_schema.py:205 +#: src/settings_schema.py:254 msgid "" "The shade color is used for shadows that are used by cards to separate " "themselves from the window background, as well as for row dividers in the " "cards." msgstr "" -#: src/settings_schema.py:212 +#: src/settings_schema.py:262 msgid "Dialog Colors" msgstr "" -#: src/settings_schema.py:213 +#: src/settings_schema.py:263 msgid "These colors are used for message dialogs." msgstr "" -#: src/settings_schema.py:229 +#: src/settings_schema.py:279 msgid "Popover Colors" msgstr "" -#: src/settings_schema.py:230 +#: src/settings_schema.py:280 msgid "These colors are used for popovers." msgstr "" -#: src/settings_schema.py:246 +#: src/settings_schema.py:296 msgid "Miscalleneous Colors" msgstr "" -#: src/settings_schema.py:247 +#: src/settings_schema.py:297 msgid "Colors that don't fit in any particular group." msgstr "" -#: src/settings_schema.py:252 +#: src/settings_schema.py:303 msgid "" "The shade color is used by inline tab bars, as well as the transitions in " "leaflets and flaps, and info bar borders." msgstr "" -#: src/settings_schema.py:257 +#: src/settings_schema.py:309 msgid "Scrollbar Outline Color" msgstr "" -#: src/settings_schema.py:258 +#: src/settings_schema.py:311 msgid "" "The scrollbar outline color is used by scrollbars to ensure that overlay " "scrollbars are visible regardless of the content color." msgstr "" -#: src/settings_schema.py:267 +#: src/settings_schema.py:319 msgid "Blue" msgstr "" -#: src/settings_schema.py:272 +#: src/settings_schema.py:320 msgid "Green" msgstr "" -#: src/settings_schema.py:277 +#: src/settings_schema.py:321 msgid "Yellow" msgstr "" -#: src/settings_schema.py:282 +#: src/settings_schema.py:322 msgid "Orange" msgstr "" -#: src/settings_schema.py:287 +#: src/settings_schema.py:323 msgid "Red" msgstr "" -#: src/settings_schema.py:292 +#: src/settings_schema.py:324 msgid "Purple" msgstr "" -#: src/settings_schema.py:297 +#: src/settings_schema.py:325 msgid "Brown" msgstr "" -#: src/settings_schema.py:302 +#: src/settings_schema.py:326 msgid "Light" msgstr "" -#: src/settings_schema.py:307 +#: src/settings_schema.py:327 msgid "Dark" msgstr "" -#: src/window.py:70 +#: src/window.py:104 +msgid "Monet Engine" +msgstr "" + +#: src/window.py:107 +msgid "" +"Monet is an engine that generates Material Design 3 palette from backgrounds " +"color. The generation can be slow" +msgstr "" + +#: src/window.py:112 +msgid "Background Image" +msgstr "" + +#: src/window.py:118 +msgid "Choose a file" +msgstr "" + +#: src/window.py:137 +msgid "Tone" +msgstr "" + +#: src/window.py:149 +msgid "Theme" +msgstr "" + +#: src/window.py:189 msgid "Palette Colors" msgstr "" -#: src/window.py:71 +#: src/window.py:192 msgid "" "Named palette colors used by some applications. Default colors follow the GNOME Human " diff --git a/po/update_potfile.sh b/po/update_potfile.sh index b20cc2c9..8c9c7f35 100755 --- a/po/update_potfile.sh +++ b/po/update_potfile.sh @@ -3,7 +3,7 @@ po_dir=$(dirname "$(realpath "$0")") xgettext -f "$po_dir"/POTFILES -o "$po_dir"/AdwCustomizer.pot --add-comments=Translators --keyword=_ --keyword=C_1c,2 --from-code=UTF-8 sed -i "s/SOME DESCRIPTIVE TITLE./Adwaita Manager POT file/" "$po_dir"/AdwCustomizer.pot sed -i "s/YEAR THE PACKAGE'S COPYRIGHT HOLDER/$(date +%Y) Adwaita Manager Team/" "$po_dir"/AdwCustomizer.pot -sed -i "s@same license as the PACKAGE package.@MIT/X11 license.@" "$po_dir"/AdwCustomizer.pot +sed -i "s@same license as the PACKAGE package.@GNU GPLv3 license.@" "$po_dir"/AdwCustomizer.pot sed -i "s/FIRST AUTHOR , YEAR./Adwaita Manager Team, $(date +%Y)./" "$po_dir"/AdwCustomizer.pot regex="$po_dir/([a-zA-Z_]*).po" diff --git a/pypi-dependencies.json b/pypi-dependencies.json index 55270718..04f5137a 100644 --- a/pypi-dependencies.json +++ b/pypi-dependencies.json @@ -1,14 +1,49 @@ { - "name": "python3-anyascii", + "name": "pypi-dependencies", "buildsystem": "simple", - "build-commands": [ - "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"anyascii~=0.3\" --no-build-isolation" - ], - "sources": [ + "build-commands": [], + "modules": [ { - "type": "file", - "url": "https://files.pythonhosted.org/packages/39/f6/7c1e3a2a54f18b67c5bd092c25ac7327083d4b3b15731b98a9c193df2db9/anyascii-0.3.1-py3-none-any.whl", - "sha256": "8707d3185017435933360462a65e2c70a4818490745804f38a5ca55e59eb56a0" + "name": "python3-anyascii", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"anyascii~=0.3\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/39/f6/7c1e3a2a54f18b67c5bd092c25ac7327083d4b3b15731b98a9c193df2db9/anyascii-0.3.1-py3-none-any.whl", + "sha256": "8707d3185017435933360462a65e2c70a4818490745804f38a5ca55e59eb56a0" + } + ] + }, + { + "name": "python3-Pillow", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"Pillow>=9.2.0\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/8c/92/2975b464d9926dc667020ed1abfa6276e68c3571dcb77e43347e15ee9eed/Pillow-9.2.0.tar.gz", + "sha256": "75e636fd3e0fb872693f23ccb8a5ff2cd578801251f3a4f6854c6a5d437d3c04" + } + ] + }, + { + "name": "python3-regex", + "buildsystem": "simple", + "build-commands": [ + "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"regex\" --no-build-isolation" + ], + "sources": [ + { + "type": "file", + "url": "https://files.pythonhosted.org/packages/c6/5a/e266ef579433b9cbd3e704032bb3ffa66b89ff3f0b0874a8cbaa4d451427/regex-2022.7.25.tar.gz", + "sha256": "bd0883e86964cd61360ffc36dbebbc49b928e92a306f886eab02c11dfde5b7aa" + } + ] } ] } \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index ece31cd8..280847f0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,27 @@ +# requirements.txt +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + # After changing this file, download the flatpak pip generator script: # curl -O https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/pip/flatpak-pip-generator # chmod +x flatpak-pip-generator # Then run: # ./flatpak-pip-generator --requirements-file=requirements.txt --output pypi-dependencies -anyascii~=0.3 \ No newline at end of file +anyascii~=0.3 +Pillow>=9.2.0 +regex diff --git a/src/adwcustomizer.gresource.xml b/src/adwcustomizer.gresource.xml index 26e33d91..fa71a593 100644 --- a/src/adwcustomizer.gresource.xml +++ b/src/adwcustomizer.gresource.xml @@ -20,5 +20,37 @@ preprocess="xml-stripblanks" alias="palette-symbolic.svg" >icons/com.github.AdwCustomizerTeam.AdwCustomizer-palette-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-larger-brush-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-color-picker-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-code-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-saved-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-open-menu-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-fill-symbolic.svg + icons/com.github.AdwCustomizerTeam.AdwCustomizer-settings-symbolic.svg diff --git a/src/adwcustomizer.in b/src/adwcustomizer.in index 7bca420b..7f88fc5f 100755 --- a/src/adwcustomizer.in +++ b/src/adwcustomizer.in @@ -2,31 +2,21 @@ # adwcustomizer.in # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . import os import sys diff --git a/src/app_type_dialog.py b/src/app_type_dialog.py index fd48494d..f7f88133 100644 --- a/src/app_type_dialog.py +++ b/src/app_type_dialog.py @@ -1,41 +1,42 @@ # window.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . from gi.repository import Gtk, Adw -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/app_type_dialog.ui') + +@Gtk.Template( + resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/app_type_dialog.ui" +) class AdwcustomizerAppTypeDialog(Adw.MessageDialog): - __gtype_name__ = 'AdwcustomizerAppTypeDialog' + __gtype_name__ = "AdwcustomizerAppTypeDialog" gtk4_app_type = Gtk.Template.Child("gtk4-app-type") gtk3_app_type = Gtk.Template.Child("gtk3-app-type") - def __init__(self, heading, body, ok_response_name, ok_response_label, ok_response_appearance, **kwargs): + def __init__( + self, + heading, + body, + ok_response_name, + ok_response_label, + ok_response_appearance, + **kwargs + ): super().__init__(**kwargs) self.set_heading(heading) self.set_body(body) @@ -49,5 +50,5 @@ class AdwcustomizerAppTypeDialog(Adw.MessageDialog): def get_app_types(self): return { "gtk4": self.gtk4_app_type.get_active(), - "gtk3": self.gtk3_app_type.get_active() + "gtk3": self.gtk3_app_type.get_active(), } diff --git a/src/custom_css_group.py b/src/custom_css_group.py index 84219c51..1f98ab80 100644 --- a/src/custom_css_group.py +++ b/src/custom_css_group.py @@ -1,36 +1,29 @@ # custom_css_group.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . from gi.repository import Gtk, Adw -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/custom_css_group.ui') + +@Gtk.Template( + resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/custom_css_group.ui" +) class AdwcustomizerCustomCSSGroup(Adw.PreferencesGroup): - __gtype_name__ = 'AdwcustomizerCustomCSSGroup' + __gtype_name__ = "AdwcustomizerCustomCSSGroup" app_type_dropdown = Gtk.Template.Child("app-type-dropdown") custom_css_text_view = Gtk.Template.Child("custom-css-text-view") @@ -41,14 +34,21 @@ class AdwcustomizerCustomCSSGroup(Adw.PreferencesGroup): def load_custom_css(self, custom_css): self.custom_css = custom_css - self.custom_css_text_view.get_buffer().set_text(list(self.custom_css.values())[self.app_type_dropdown.get_selected()]) + self.custom_css_text_view.get_buffer().set_text( + list(self.custom_css.values())[self.app_type_dropdown.get_selected()] + ) @Gtk.Template.Callback() def on_custom_css_changed(self, buffer): Gtk.Application.get_default().mark_as_dirty() - Gtk.Application.get_default().update_custom_css_text(list(self.custom_css.keys())[self.app_type_dropdown.get_selected()], buffer.props.text) + Gtk.Application.get_default().update_custom_css_text( + list(self.custom_css.keys())[self.app_type_dropdown.get_selected()], + buffer.props.text, + ) @Gtk.Template.Callback() def on_dropdown_notify(self, _unused, pspec): if pspec.name == "selected": - self.custom_css_text_view.get_buffer().set_text(list(self.custom_css.values())[self.app_type_dropdown.get_selected()]) + self.custom_css_text_view.get_buffer().set_text( + list(self.custom_css.values())[self.app_type_dropdown.get_selected()] + ) diff --git a/src/error.py b/src/error.py index db99a8f9..2760bd54 100644 --- a/src/error.py +++ b/src/error.py @@ -1,36 +1,27 @@ # error.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . from gi.repository import Gtk -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/error.ui') + +@Gtk.Template(resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/error.ui") class AdwcustomizerError(Gtk.ListBoxRow): - __gtype_name__ = 'AdwcustomizerError' + __gtype_name__ = "AdwcustomizerError" error_label = Gtk.Template.Child("error-label") element_label = Gtk.Template.Child("element-label") diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-code-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-code-symbolic.svg new file mode 100644 index 00000000..540341b8 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-code-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-color-picker-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-color-picker-symbolic.svg new file mode 100644 index 00000000..3c37c417 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-color-picker-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-saved-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-saved-symbolic.svg new file mode 100644 index 00000000..79a74915 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-saved-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-fill-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-fill-symbolic.svg new file mode 100644 index 00000000..cb4f2ae5 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-fill-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-symbolic.svg new file mode 100644 index 00000000..4d4e0c27 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-disk-unsaved-symbolic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-larger-brush-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-larger-brush-symbolic.svg new file mode 100644 index 00000000..25f75867 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-larger-brush-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-open-menu-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-open-menu-symbolic.svg new file mode 100644 index 00000000..7f447433 --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-open-menu-symbolic.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-palette-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-palette-symbolic.svg index 93d29ccc..2198e059 100644 --- a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-palette-symbolic.svg +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-palette-symbolic.svg @@ -1,5 +1,5 @@ - + diff --git a/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-settings-symbolic.svg b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-settings-symbolic.svg new file mode 100644 index 00000000..408d7e5d --- /dev/null +++ b/src/icons/com.github.AdwCustomizerTeam.AdwCustomizer-settings-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/info.py.in b/src/info.py.in new file mode 100644 index 00000000..20fc3494 --- /dev/null +++ b/src/info.py.in @@ -0,0 +1,2 @@ +version = '@version@' +build_type = '@build_type@' \ No newline at end of file diff --git a/src/main.py b/src/main.py index 4c284ec2..acd4983c 100644 --- a/src/main.py +++ b/src/main.py @@ -1,30 +1,20 @@ # main.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . import sys import json @@ -36,6 +26,7 @@ from anyascii import anyascii import gi from gi.repository import Gtk, Gdk, Gio, Adw, GLib, Xdp, XdpGtk4 +from material_color_utilities_python import * from .settings_schema import settings_schema from .window import AdwcustomizerMainWindow @@ -43,6 +34,8 @@ from .palette_shades import AdwcustomizerPaletteShades from .option import AdwcustomizerOption from .app_type_dialog import AdwcustomizerAppTypeDialog from .custom_css_group import AdwcustomizerCustomCSSGroup +from .plugins_list import AdwcustomizerPluginsList +from . import info def to_slug_case(non_slug): @@ -86,9 +79,9 @@ class AdwcustomizerApplication(Adw.Application): necessary. """ - win = self.props.active_window - if not win: - win = AdwcustomizerMainWindow(application=self) + self.win = self.props.active_window + if not self.win: + self.win = AdwcustomizerMainWindow(application=self) self.create_action("open_preset_directory", self.open_preset_directory) self.create_stateful_action( @@ -97,26 +90,33 @@ class AdwcustomizerApplication(Adw.Application): GLib.Variant("s", "adwaita"), self.load_preset_action, ) - self.create_action("apply_color_scheme", - self.show_apply_color_scheme_dialog) - self.create_action("reset_color_scheme", - self.show_reset_color_scheme_dialog) + self.create_action("apply_color_scheme", self.show_apply_color_scheme_dialog) + self.create_action("reset_color_scheme", self.show_reset_color_scheme_dialog) self.create_action("save_preset", self.show_save_preset_dialog) self.create_action("about", self.show_about_window) self.reload_user_defined_presets() - self.load_preset_from_resource( - "/com/github/AdwCustomizerTeam/AdwCustomizer/presets/adwaita.json" - ) - win.present() + self.style_manager = Adw.StyleManager.get_default() + if self.style_manager.get_dark(): + self.load_preset_from_resource( + "/com/github/AdwCustomizerTeam/AdwCustomizer/presets/adwaita-dark.json" + ) + else: + self.load_preset_from_resource( + "/com/github/AdwCustomizerTeam/AdwCustomizer/presets/adwaita.json" + ) + + self.win.present() def reload_user_defined_presets(self): 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["XDG_CONFIG_HOME"], "presets") + os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"), + "presets", + ) if not os.path.exists(preset_directory): os.makedirs(preset_directory) @@ -133,8 +133,7 @@ class AdwcustomizerApplication(Adw.Application): raise KeyError("variables") if preset.get("palette") is None: raise KeyError("palette") - self.custom_presets[file_name.replace( - ".json", "")] = preset["name"] + self.custom_presets[file_name.replace(".json", "")] = preset["name"] except Exception: self.global_errors.append( { @@ -143,6 +142,10 @@ class AdwcustomizerApplication(Adw.Application): "line": traceback.format_exc().strip(), } ) + self.win.toast_overlay.add_toast( + Adw.Toast(title=_("Failed to load preset")) + ) + self.props.active_window.update_errors(self.global_errors) custom_menu_section = Gio.Menu() @@ -174,7 +177,11 @@ class AdwcustomizerApplication(Adw.Application): self.portal.open_uri( parent, - "file://" + os.path.join(os.environ["XDG_CONFIG_HOME"], "presets"), + "file://" + + os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"), + "presets", + ), Xdp.OpenUriFlags.NONE, None, open_dir_callback, @@ -187,8 +194,7 @@ class AdwcustomizerApplication(Adw.Application): self.load_preset_variables(json.loads(preset_text)) def load_preset_from_resource(self, preset_path): - preset_text = Gio.resources_lookup_data( - preset_path, 0).get_data().decode() + preset_text = Gio.resources_lookup_data(preset_path, 0).get_data().decode() self.load_preset_variables(json.loads(preset_text)) def load_preset_variables(self, preset): @@ -214,6 +220,125 @@ class AdwcustomizerApplication(Adw.Application): self.reload_variables() + def rgba_from_argb(self, argb, alpha=None) -> str: + base = "rgba({}, {}, {}, {})" + + red = redFromArgb(argb) + green = greenFromArgb(argb) + blue = blueFromArgb(argb) + if not alpha: + alpha = alphaFromArgb(argb) + + return base.format(red, green, blue, alpha) + + def update_theme_from_monet(self, theme, tone, monet_theme): + palettes = theme["palettes"] + + monet_theme = monet_theme.get_string().lower() # dark / light + + palette = {} + i = 0 + for color in palettes.values(): + i += 1 + palette[str(i)] = hexFromArgb(color.tone(int(tone.get_string()))) + self.pref_palette_shades["monet"].update_shades(palette) + if monet_theme == "automatic": + if self.style_manager.get_dark(): + monet_theme = "dark" + else: + monet_theme = "light" + + if monet_theme == "dark": + dark_theme = theme["schemes"]["dark"] + variable = { + "accent_color": self.rgba_from_argb(dark_theme.primary), + "accent_bg_color": self.rgba_from_argb(dark_theme.primaryContainer), + "accent_fg_color": self.rgba_from_argb(dark_theme.onPrimaryContainer), + "destructive_color": self.rgba_from_argb(dark_theme.error), + "destructive_bg_color": self.rgba_from_argb(dark_theme.errorContainer), + "destructive_fg_color": self.rgba_from_argb(dark_theme.onError), + "success_color": self.rgba_from_argb(dark_theme.tertiary), + "success_bg_color": self.rgba_from_argb(dark_theme.onTertiary), + "success_fg_color": self.rgba_from_argb(dark_theme.tertiaryContainer), + "warning_color": self.rgba_from_argb(dark_theme.secondaryContainer), + "warning_bg_color": self.rgba_from_argb(dark_theme.inversePrimary), + "warning_fg_color": self.rgba_from_argb(dark_theme.primary, "0.8"), + "error_color": self.rgba_from_argb(dark_theme.error), + "error_bg_color": self.rgba_from_argb(dark_theme.errorContainer), + "error_fg_color": self.rgba_from_argb(dark_theme.onError), + "window_bg_color": self.rgba_from_argb(dark_theme.surface), + "window_fg_color": self.rgba_from_argb(dark_theme.onSurface), + "view_bg_color": self.rgba_from_argb(dark_theme.surface), + "view_fg_color": self.rgba_from_argb(dark_theme.onSurface), + "headerbar_bg_color": self.rgba_from_argb(dark_theme.surface), + "headerbar_fg_color": self.rgba_from_argb(dark_theme.onSurface), + "headerbar_border_color": self.rgba_from_argb( + dark_theme.primary, "0.8" + ), + "headerbar_backdrop_color": "@window_bg_color", + "headerbar_shade_color": self.rgba_from_argb(dark_theme.shadow), + "card_bg_color": self.rgba_from_argb(dark_theme.primary, "0.05"), + "card_fg_color": self.rgba_from_argb(dark_theme.onSurface), + "card_shade_color": self.rgba_from_argb(dark_theme.shadow), + "dialog_bg_color": self.rgba_from_argb(dark_theme.secondaryContainer), + "dialog_fg_color": self.rgba_from_argb(dark_theme.onSecondaryContainer), + "popover_bg_color": self.rgba_from_argb(dark_theme.secondaryContainer), + "popover_fg_color": self.rgba_from_argb( + dark_theme.onSecondaryContainer + ), + "shade_color": self.rgba_from_argb(dark_theme.shadow), + "scrollbar_outline_color": self.rgba_from_argb(dark_theme.outline), + } + else: # light + light_theme = theme["schemes"]["light"] + variable = { + "accent_color": self.rgba_from_argb(light_theme.primary), + "accent_bg_color": self.rgba_from_argb(light_theme.primaryContainer), + "accent_fg_color": self.rgba_from_argb(light_theme.onPrimaryContainer), + "destructive_color": self.rgba_from_argb(light_theme.error), + "destructive_bg_color": self.rgba_from_argb(light_theme.errorContainer), + "destructive_fg_color": self.rgba_from_argb(light_theme.onError), + "success_color": self.rgba_from_argb(light_theme.tertiary), + "success_bg_color": self.rgba_from_argb(light_theme.onTertiary), + "success_fg_color": self.rgba_from_argb(light_theme.tertiaryContainer), + "warning_color": self.rgba_from_argb(light_theme.secondaryContainer), + "warning_bg_color": self.rgba_from_argb(light_theme.inversePrimary), + "warning_fg_color": self.rgba_from_argb(light_theme.primary, "0.8"), + "error_color": self.rgba_from_argb(light_theme.error), + "error_bg_color": self.rgba_from_argb(light_theme.errorContainer), + "error_fg_color": self.rgba_from_argb(light_theme.onError), + "window_bg_color": self.rgba_from_argb(light_theme.surface), + "window_fg_color": self.rgba_from_argb(light_theme.onSurface), + "view_bg_color": self.rgba_from_argb(light_theme.surface), + "view_fg_color": self.rgba_from_argb(light_theme.onSurface), + "headerbar_bg_color": self.rgba_from_argb(light_theme.surface), + "headerbar_fg_color": self.rgba_from_argb(light_theme.onSurface), + "headerbar_border_color": self.rgba_from_argb( + light_theme.primary, "0.8" + ), + "headerbar_backdrop_color": "@window_bg_color", + "headerbar_shade_color": self.rgba_from_argb(light_theme.shadow), + "card_bg_color": self.rgba_from_argb(light_theme.primary, "0.05"), + "card_fg_color": self.rgba_from_argb(light_theme.surfaceVariant), + "card_shade_color": self.rgba_from_argb(light_theme.shadow), + "dialog_bg_color": self.rgba_from_argb(light_theme.secondaryContainer), + "dialog_fg_color": self.rgba_from_argb( + light_theme.onSecondaryContainer + ), + "popover_bg_color": self.rgba_from_argb(light_theme.secondaryContainer), + "popover_fg_color": self.rgba_from_argb( + light_theme.onSecondaryContainer + ), + "shade_color": self.rgba_from_argb(light_theme.shadow), + "scrollbar_outline_color": self.rgba_from_argb(light_theme.outline), + } + + for key in variable.keys(): + if key in self.pref_variables: + self.pref_variables[key].update_value(variable[key]) + + self.reload_variables() + def generate_gtk_css(self, app_type): final_css = "" for key in self.variables.keys(): @@ -226,16 +351,18 @@ class AdwcustomizerApplication(Adw.Application): def mark_as_dirty(self): self.is_dirty = True - self.props.active_window.save_preset_button.add_css_class("warning") - self.props.active_window.save_preset_button.add_css_class("raised") - self.props.active_window.save_preset_button.get_child().set_label( + self.props.active_window.save_preset_button.get_child().set_icon_name( + "disk-unsaved-symbolic" + ) + self.props.active_window.save_preset_button.get_child().set_tooltip_text( _("Unsaved changes") ) def clear_dirty(self): self.is_dirty = False - self.props.active_window.save_preset_button.remove_css_class("warning") - self.props.active_window.save_preset_button.remove_css_class("raised") + self.props.active_window.save_preset_button.get_child().set_icon_name( + "disk-saved-symbolic" + ) self.props.active_window.save_preset_button.get_child().set_label("") def reload_variables(self): @@ -259,8 +386,7 @@ class AdwcustomizerApplication(Adw.Application): css_provider.connect("parsing-error", on_error) css_provider.load_from_data(gtk_css.encode()) - self.props.active_window.update_errors( - self.global_errors + parsing_errors) + self.props.active_window.update_errors(self.global_errors + parsing_errors) # loading with the priority above user to override the applied config if self.current_css_provider is not None: Gtk.StyleContext.remove_provider_for_display( @@ -279,7 +405,7 @@ class AdwcustomizerApplication(Adw.Application): if args[0].get_string().startswith("custom-"): self.load_preset_from_file( os.path.join( - os.environ["XDG_CONFIG_HOME"], + os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"), "presets", args[0].get_string().replace("custom-", "", 1) + ".json", ) @@ -303,7 +429,18 @@ class AdwcustomizerApplication(Adw.Application): Adw.ResponseAppearance.SUGGESTED, transient_for=self.props.active_window, ) - dialog.connect("response", self.apply_color_scheme) + + box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=6) + + label = Gtk.Label(label="Apply as Dark theme") + switch = Gtk.Switch() + + box.append(label) + box.append(switch) + + dialog.set_extra_child(box) + + dialog.connect("response", self.apply_color_scheme, switch) dialog.present() def show_reset_color_scheme_dialog(self, *_args): @@ -326,7 +463,7 @@ class AdwcustomizerApplication(Adw.Application): "Saving preset to {0}. If that preset already exists, it will be overwritten!" ).format( os.path.join( - os.environ["XDG_CONFIG_HOME"], + os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"), "presets", to_slug_case(self.preset_name) + ".json", ) @@ -336,8 +473,7 @@ class AdwcustomizerApplication(Adw.Application): dialog.add_response("cancel", _("Cancel")) dialog.add_response("save", _("Save")) - dialog.set_response_appearance( - "save", Adw.ResponseAppearance.SUGGESTED) + dialog.set_response_appearance("save", Adw.ResponseAppearance.SUGGESTED) dialog.set_default_response("cancel") dialog.set_close_response("cancel") @@ -349,7 +485,14 @@ class AdwcustomizerApplication(Adw.Application): dialog.set_body( _( "Saving preset to {0}. If that preset already exists, it will be overwritten!" - ).format(os.path.join(os.environ["XDG_CONFIG_HOME"], "presets")) + ).format( + os.path.join( + os.environ.get( + "XDG_CONFIG_HOME", os.environ["HOME"] + "/.config" + ), + "presets", + ) + ) ) dialog.set_response_enabled("save", False) else: @@ -358,7 +501,9 @@ class AdwcustomizerApplication(Adw.Application): "Saving preset to {0}. If that preset already exists, it will be overwritten!" ).format( os.path.join( - os.environ["XDG_CONFIG_HOME"], + os.environ.get( + "XDG_CONFIG_HOME", os.environ["HOME"] + "/.config" + ), "presets", to_slug_case(preset_entry.get_text()) + ".json", ) @@ -377,7 +522,7 @@ class AdwcustomizerApplication(Adw.Application): if response == "save": with open( os.path.join( - os.environ["XDG_CONFIG_HOME"], + os.environ.get("XDG_CONFIG_HOME", os.environ["HOME"] + "/.config"), "presets", to_slug_case(entry.get_text()) + ".json", ), @@ -392,50 +537,104 @@ class AdwcustomizerApplication(Adw.Application): } file.write(json.dumps(object_to_write, indent=4)) self.clear_dirty() + self.win.toast_overlay.add_toast( + Adw.Toast(title=_("Scheme successfully saved!")) + ) - def apply_color_scheme(self, widget, response): + def apply_color_scheme(self, widget, response, switch): if response == "apply": - if widget.get_app_types()["gtk4"]: - gtk4_dir = os.path.join( - os.environ["XDG_CONFIG_HOME"], "gtk-4.0") - if not os.path.exists(gtk4_dir): - os.makedirs(gtk4_dir) - gtk4_css = self.generate_gtk_css("gtk4") - 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"]: - gtk3_dir = os.path.join( - os.environ["XDG_CONFIG_HOME"], "gtk-3.0") - if not os.path.exists(gtk3_dir): - os.makedirs(gtk3_dir) - gtk3_css = self.generate_gtk_css("gtk3") - with open( - os.path.join(gtk3_dir, "gtk.css"), "w", encoding="utf-8" - ) as file: - file.write(gtk3_css) + if switch.get_active(): + if widget.get_app_types()["gtk4"]: + gtk4_dir = os.path.join( + 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") + with open( + os.path.join(gtk4_dir, "gtk-dark.css"), "w", encoding="utf-8" + ) as file: + file.write(gtk4_css) + if widget.get_app_types()["gtk3"]: + gtk3_dir = os.path.join( + 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") + with open( + os.path.join(gtk3_dir, "gtk-dark.css"), "w", encoding="utf-8" + ) as file: + file.write(gtk3_css) + else: + if widget.get_app_types()["gtk4"]: + gtk4_dir = os.path.join( + 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") + 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"]: + gtk3_dir = os.path.join( + 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") + with open( + os.path.join(gtk3_dir, "gtk.css"), "w", encoding="utf-8" + ) as file: + file.write(gtk3_css) + self.win.toast_overlay.add_toast( + Adw.Toast(title=_("Scheme set successfully!")) + ) def reset_color_scheme(self, widget, response): if response == "reset": if widget.get_app_types()["gtk4"]: file = Gio.File.new_for_path( os.path.join( - os.environ["XDG_CONFIG_HOME"], "/gtk-3.0/gtk.css") + os.environ.get( + "XDG_CONFIG_HOME", os.environ["HOME"] + "/.config" + ), + "gtk-4.0/gtk.css", + ) ) try: file.delete() except Exception: pass + if widget.get_app_types()["gtk3"]: file = Gio.File.new_for_path( os.path.join( - os.environ["XDG_CONFIG_HOME"], "/gtk-3.0/gtk.css") + os.environ.get( + "XDG_CONFIG_HOME", os.environ["HOME"] + "/.config" + ), + "gtk-3.0/gtk.css", + ) ) try: file.delete() except Exception: pass + self.win.toast_overlay.add_toast(Adw.Toast(title=_("Reset successfully!"))) def show_about_window(self, *_args): about = Adw.AboutWindow( @@ -443,17 +642,61 @@ class AdwcustomizerApplication(Adw.Application): application_name=_("Adwaita Manager"), application_icon="com.github.AdwCustomizerTeam.AdwCustomizer", developer_name=_("Adwaita Manager Team"), + website="https://github.com/AdwCustomizerTeam/AdwCustomizer", + support_url="https://github.com/orgs/AdwCustomizerTeam/discussions", + issue_url="https://github.com/AdwCustomizerTeam/AdwCustomizer/issues", developers=[ 'Artyom "ArtyIF" Fomin https://github.com/ArtyIF', + "0xMRTT https://github.com/0xMRTT", "Verantor https://github.com/Verantor", ], artists=['David "Daudix UFO" Lapshin https://github.com/daudix-UFO'], + designers=['David "Daudix UFO" Lapshin https://github.com/daudix-UFO'], # Translators: This is a place to put your credits (formats: "Name https://example.com" or "Name ", no quotes) and is not meant to be translated literally. - translator_credits=_("translator-credits"), + translator_credits="""Maxime V https://www.transifex.com/user/profile/Adaoh/ + FineFindus https://github.com/FineFindus + Karol Lademan https://www.transifex.com/user/profile/karlod/ + Monty Monteusz https://www.transifex.com/user/profile/MontyQIQI/ + Renato Corrêa https://www.transifex.com/user/profile/renatocrrs/ + Aggelos Tselios https://www.transifex.com/user/profile/AndroGR/ + David "Daudix UFO" Lapshin https://github.com/daudix-UFO' + 0xMRTT https://github.com/0xMRTT + Juanjo Cillero https://www.transifex.com/user/profile/renux918/ + Taylan Tatlı https://www.transifex.com/user/profile/TaylanTatli34/""", copyright="© 2022 Adwaita Manager Team", - license_type=Gtk.License.MIT_X11, + license_type=Gtk.License.GPL_3_0, + version=f"{info.version}", + release_notes=""" +
    +
  • Add AdwViewSwitcher in the header bar.
  • +
  • Move CSS to the "Advanced" tab
  • +
  • Move the rest to the "Colours" tab
  • +
  • Add Monet tab which generates a theme from a background
  • +
  • Add disk saved and disk unsaved icon in the header bar
  • +
  • Update about dialog
  • +
  • Change license to GNU GPLv3
  • +
  • Begin plugin support
  • +
  • Move preset selector to a drop-down called palette (icon palette)
  • +
  • Add ability to apply the theme onlyfor dark theme or oy for light theme
  • +
  • Automaticly use Adwaita-dark preset if the user prefered scheme is dark.
  • +
  • Added Flatpak CI build
  • +
  • Added issue template for bug and feature request
  • +
  • `Main` branch is now protected by GitHub branch protection. The development is done on `next` branch
  • +
+ """, + comments=""" +Adwaita Manager (AdwCustomizer) is a tool for customizing Libadwaita applications and the adw-gtk3 theme. +With Adwaita Manager you can: + + - Change any color of Adwaita theme + - Apply Material 3 colors from wallaper + - Use other users presets + - Change advanced options with CSS + - Extend functionality using plugins + +This app is written in Python and uses GTK 4 and libadwaita. + """ ) - about.present() def update_custom_css_text(self, app_type, new_value): @@ -479,8 +722,7 @@ class AdwcustomizerApplication(Adw.Application): self, name, parameter_type, initial_state, callback, shortcuts=None ): """Add a stateful application action.""" - action = Gio.SimpleAction.new_stateful( - name, parameter_type, initial_state) + action = Gio.SimpleAction.new_stateful(name, parameter_type, initial_state) action.connect("activate", callback) self.add_action(action) if shortcuts: diff --git a/src/meson.build b/src/meson.build index 62f39eef..d3e13293 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,6 @@ pkgdatadir = join_paths(get_option('prefix'), get_option('datadir'), meson.project_name()) moduledir = join_paths(pkgdatadir, 'adwcustomizer') +pluginsdir = join_paths(pkgdatadir, 'adwcustomizer', 'plugins') gnome = import('gnome') blueprints = custom_target('blueprints', @@ -39,16 +40,36 @@ configure_file( install_dir: get_option('bindir') ) +configure_file( + input: 'info.py.in', + output: '@BASENAME@', + install: true, + install_dir: moduledir, + configuration: configuration_data({ + 'version': meson.project_version(), + 'build_type': get_option('buildtype'), + }), +) + adwcustomizer_sources = [ '__init__.py', 'settings_schema.py', 'main.py', 'error.py', 'palette_shades.py', + 'plugin.py', + 'plugins_list.py', + 'setting.py', 'option.py', 'window.py', 'app_type_dialog.py', 'custom_css_group.py', ] +plugins_sources = [ + 'plugins/__init__.py', + 'plugins/gtk4.py' +] + install_data(adwcustomizer_sources, install_dir: moduledir) +install_data(plugins_sources, install_dir: pluginsdir) \ No newline at end of file diff --git a/src/option.py b/src/option.py index d2803c8f..885339f2 100644 --- a/src/option.py +++ b/src/option.py @@ -1,36 +1,27 @@ # option.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . from gi.repository import Gtk, Gdk, Adw -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/option.ui') + +@Gtk.Template(resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/option.ui") class AdwcustomizerOption(Adw.ActionRow): - __gtype_name__ = 'AdwcustomizerOption' + __gtype_name__ = "AdwcustomizerOption" color_value = Gtk.Template.Child("color-value") text_value = Gtk.Template.Child("text-value") @@ -41,7 +32,7 @@ class AdwcustomizerOption(Adw.ActionRow): explanation_button = Gtk.Template.Child("explanation-button") explanation_label = Gtk.Template.Child("explanation-label") - def __init__(self, name, title, adw_gtk3_support, explanation, **kwargs): + def __init__(self, name, title, explanation, adw_gtk3_support="yes", **kwargs): super().__init__(**kwargs) self.set_name(name) @@ -52,10 +43,14 @@ class AdwcustomizerOption(Adw.ActionRow): self.warning_button.set_visible(False) elif adw_gtk3_support == "partial": self.warning_button.add_css_class("warning") - self.warning_label.set_label(_("This option is only partially supported by the adw-gtk3 theme.")) + self.warning_label.set_label( + _("This option is only partially supported by the adw-gtk3 theme.") + ) elif adw_gtk3_support == "no": self.warning_button.add_css_class("error") - self.warning_label.set_label(_("This option is not supported by the adw-gtk3 theme.")) + self.warning_label.set_label( + _("This option is not supported by the adw-gtk3 theme.") + ) self.explanation_label.set_label(explanation or "") if explanation is None: @@ -63,7 +58,9 @@ class AdwcustomizerOption(Adw.ActionRow): @Gtk.Template.Callback() def on_color_value_changed(self, *_args): - self.update_value(self.color_value.get_rgba().to_string(), update_from="color_value") + self.update_value( + self.color_value.get_rgba().to_string(), update_from="color_value" + ) @Gtk.Template.Callback() def on_text_value_changed(self, *_args): @@ -96,7 +93,11 @@ class AdwcustomizerOption(Adw.ActionRow): self.color_value.set_rgba(rgba) self.color_value.set_tooltip_text(_("Not a color, see text value")) - if Gtk.Application.get_default().is_ready and kwargs.get("update_from") == "text_value" and new_value != "": + if ( + Gtk.Application.get_default().is_ready + and kwargs.get("update_from") == "text_value" + and new_value != "" + ): Gtk.Application.get_default().variables[self.get_name()] = new_value Gtk.Application.get_default().mark_as_dirty() Gtk.Application.get_default().reload_variables() diff --git a/src/palette_shades.py b/src/palette_shades.py index fff40349..dcb0cc63 100644 --- a/src/palette_shades.py +++ b/src/palette_shades.py @@ -1,36 +1,29 @@ # palette_shades.py # -# Copyright 2022 Adwaita Manager Team +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team # -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. # -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written -# authorization. +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . from gi.repository import Gtk, Gdk, Adw -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/palette_shades.ui') + +@Gtk.Template( + resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/palette_shades.ui" +) class AdwcustomizerPaletteShades(Adw.ActionRow): - __gtype_name__ = 'AdwcustomizerPaletteShades' + __gtype_name__ = "AdwcustomizerPaletteShades" def __init__(self, prefix, color_title, n_shades, **kwargs): super().__init__(**kwargs) @@ -62,9 +55,17 @@ class AdwcustomizerPaletteShades(Adw.ActionRow): if new_rgba.parse(shades[str(i)]): self.color_pickers[str(i)].set_rgba(new_rgba) self.color_pickers[str(i)].set_tooltip_text(shades[str(i)]) - if Gtk.Application.get_default().is_ready and kwargs.get("update_from") == "color_value": - Gtk.Application.get_default().palette[self.prefix][str(i)] = shades[str(i)] + if ( + Gtk.Application.get_default().is_ready + and kwargs.get("update_from") == "color_value" + ): + Gtk.Application.get_default().palette[self.prefix][str(i)] = shades[ + str(i) + ] - if Gtk.Application.get_default().is_ready and kwargs.get("update_from") == "color_value": + if ( + Gtk.Application.get_default().is_ready + and kwargs.get("update_from") == "color_value" + ): Gtk.Application.get_default().mark_as_dirty() Gtk.Application.get_default().reload_variables() diff --git a/src/plugin.py b/src/plugin.py new file mode 100644 index 00000000..cceb7e01 --- /dev/null +++ b/src/plugin.py @@ -0,0 +1,64 @@ +# plugin.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from .setting import AdwcustomizerSetting + + +class AdwcustomizerPlugin: + def __init__(self): + self.title = None + + self.colors = None + self.palette = None + + # Custom settings shown on a separate view + self.custom_settings = {} + # A dict to alias parameters to different names + # Key is the alias name, value is the parameter name + # Parameter can be any key in colors, palette or custom settings + self.alias_dict = {} + + def update_builtin_parameters(self, colors, palette): + self.colors = colors + self.palette = palette + + def load_custom_settings(self, settings): + for setting_key, setting in self.custom_settings: + self.custom_settings[setting_key].set_value(settings[setting_key]) + + def get_custom_settings_for_preset(self): + setting_dict = {} + for setting_key, setting in self.custom_settings: + return setting_dict[setting_key] + + def get_alias_values(self): + alias_values = {} + for key, value in self.alias_dict.items(): + alias_values[key] = self.colors.get( + value, self.palette.get(value, self.custom_settings.get(value)) + ) + return alias_values + + def validate(self): + raise NotImplementedError() + + def apply(self): + raise NotImplementedError() + + def save(self): + pass diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py new file mode 100644 index 00000000..f93ffe53 --- /dev/null +++ b/src/plugins/__init__.py @@ -0,0 +1,17 @@ +# plugins/__init__.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . diff --git a/src/plugins/gtk4.py b/src/plugins/gtk4.py new file mode 100644 index 00000000..dd5fe68e --- /dev/null +++ b/src/plugins/gtk4.py @@ -0,0 +1,23 @@ +# plugins/gtk4.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from ..plugin import AdwcustomizerPlugin + + +class AdwcustomizerGtk4Plugin(AdwcustomizerPlugin): + pass diff --git a/src/plugins_list.py b/src/plugins_list.py new file mode 100644 index 00000000..d2c14499 --- /dev/null +++ b/src/plugins_list.py @@ -0,0 +1,51 @@ +# plugins_list.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from .plugins.gtk4 import AdwcustomizerGtk4Plugin +import os +from pathlib import Path +import importlib + + +class AdwcustomizerPluginsList: + def __init__(self): + self.plugins = {"gtk4": AdwcustomizerGtk4Plugin()} # AdwCustomizerTeam plugins + self.add_user_plugins() + + def add_user_plugins(self): + self.user_plugin_dir = ( + Path(os.environ.get("XDG_DATA_HOME", os.environ["HOME"])) + / ".local" + / "share" + / "AdwCustomizer" + / "plugins" + ) + if self.user_plugin_dir.exists(): + for path, _, name in os.walk(self.user_plugin_dir): + print(name[0]) + else: + print("No plugins dir found") + + def load_all_custom_settings(self, settings): + for plugin_id, plugin in self.plugins.items(): + plugin.load_custom_settings(settings[plugin_id]) + + def get_all_custom_settings_for_preset(self): + custom_settings = {} + for plugin_id, plugin in self.plugins.items(): + custom_settings[plugin_id] = plugin.get_custom_settings_for_preset() diff --git a/src/setting.py b/src/setting.py new file mode 100644 index 00000000..a2d3479b --- /dev/null +++ b/src/setting.py @@ -0,0 +1,38 @@ +# setting.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +class AdwcustomizerSetting: + def __init__(self, name, title, value_type, explanation=None, default_value=None): + # TODO supported types: + # text + # integer + # float + # color only + # color shades + # color and text + # code field + self.name = name + self.title = title + self.value_type = value_type + self.explanation = explanation + self.value = default_value + + def set_value(self, new_value): + # TODO checks + self.value = new_value diff --git a/src/settings_schema.py b/src/settings_schema.py index 4ed3dcff..ea22ce84 100644 --- a/src/settings_schema.py +++ b/src/settings_schema.py @@ -1,119 +1,157 @@ +# settings_schema.py +# +# Change the look of Adwaita, with ease +# Copyright (C) 2022 Adwaita Manager Team +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + settings_schema = { "groups": [ { "name": "accent_colors", "title": _("Accent Colors"), - "description": _("These colors are used across many different widgets, such as buttons, labels, and entries, to indicate that a widget is important, interactive, or currently active."), + "description": _( + "These colors are used across many different widgets, such as buttons, labels, and entries, to indicate that a widget is important, interactive, or currently active." + ), "variables": [ { "name": "accent_color", "title": _("Standalone Color"), - "explanation": _("The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window."), - "adw_gtk3_support": "yes" + "explanation": _( + "The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window." + ), + "adw_gtk3_support": "yes", }, { "name": "accent_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "accent_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" - } - ] + "adw_gtk3_support": "yes", + }, + ], }, { "name": "destructive_colors", "title": _("Destructive Colors"), - "description": _("These colors are used for buttons to indicate a dangerous action, such as deleting a file."), + "description": _( + "These colors are used for buttons to indicate a dangerous action, such as deleting a file." + ), "variables": [ { "name": "destructive_color", "title": _("Standalone Color"), - "explanation": _("The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window."), - "adw_gtk3_support": "yes" + "explanation": _( + "The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window." + ), + "adw_gtk3_support": "yes", }, { "name": "destructive_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "destructive_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "partial" - } - ] + "adw_gtk3_support": "partial", + }, + ], }, { "name": "success_colors", "title": _("Success Colors"), - "description": _("These colors are used across many different widgets, such as buttons, labels, entries, and level bars, to indicate a success or a high level."), + "description": _( + "These colors are used across many different widgets, such as buttons, labels, entries, and level bars, to indicate a success or a high level." + ), "variables": [ { "name": "success_color", "title": _("Standalone Color"), - "explanation": _("The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window."), - "adw_gtk3_support": "yes" + "explanation": _( + "The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window." + ), + "adw_gtk3_support": "yes", }, { "name": "success_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "success_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "partial" - } - ] + "adw_gtk3_support": "partial", + }, + ], }, { "name": "warning_colors", "title": _("Warning Colors"), - "description": _("These colors are used across many different widgets, such as buttons, labels, entries, and level bars, to indicate a warning or a low level."), + "description": _( + "These colors are used across many different widgets, such as buttons, labels, entries, and level bars, to indicate a warning or a low level." + ), "variables": [ { "name": "warning_color", "title": _("Standalone Color"), - "explanation": _("The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window."), - "adw_gtk3_support": "yes" + "explanation": _( + "The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window." + ), + "adw_gtk3_support": "yes", }, { "name": "warning_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "warning_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "partial" - } - ] + "adw_gtk3_support": "partial", + }, + ], }, { "name": "error_colors", "title": _("Error Colors"), - "description": _("These colors are used across many different widgets, such as buttons, labels, and entries, to indicate a failure."), + "description": _( + "These colors are used across many different widgets, such as buttons, labels, and entries, to indicate a failure." + ), "variables": [ { "name": "error_color", "title": _("Standalone Color"), - "explanation": _("The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window."), - "adw_gtk3_support": "yes" + "explanation": _( + "The standalone colors are similar to the background ones, but provide better contrast when used as foreground color on top of a neutral background - for example, colorful text in a window." + ), + "adw_gtk3_support": "yes", }, { "name": "error_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "error_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "partial" - } - ] + "adw_gtk3_support": "partial", + }, + ], }, { "name": "window_colors", @@ -123,66 +161,76 @@ settings_schema = { { "name": "window_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "window_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" - } - ] + "adw_gtk3_support": "yes", + }, + ], }, { "name": "view_colors", "title": _("View Colors"), - "description": _("These colors are used in a variety of widgets, such as text views and entries."), + "description": _( + "These colors are used in a variety of widgets, such as text views and entries." + ), "variables": [ { "name": "view_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "view_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" - } - ] + "adw_gtk3_support": "yes", + }, + ], }, { "name": "headerbar_colors", "title": _("Header Bar Colors"), - "description": _("These colors are used for header bars, as well as widgets that are meant to be visually attached to it, such as search bars or tab bars."), + "description": _( + "These colors are used for header bars, as well as widgets that are meant to be visually attached to it, such as search bars or tab bars." + ), "variables": [ { "name": "headerbar_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "headerbar_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "headerbar_border_color", "title": _("Border Color"), - "explanation": _("The border color has the same default value as a foreground color, but doesn't change along with it. This can be useful if a light window has a dark header bar with light text; in this case it may be desirable to keep the border dark. This variable is only used for vertical borders - for example, separators between the two header bars in a split header bar layout."), - "adw_gtk3_support": "no" + "explanation": _( + "The border color has the same default value as a foreground color, but doesn't change along with it. This can be useful if a light window has a dark header bar with light text; in this case it may be desirable to keep the border dark. This variable is only used for vertical borders - for example, separators between the two header bars in a split header bar layout." + ), + "adw_gtk3_support": "no", }, { "name": "headerbar_backdrop_color", "title": _("Backdrop Color"), - "explanation": _("The backdrop color is used instead of the background color when the window is not focused. By default it's an alias of the window's background color and changes together with it. When changing this variable, make sure to set it to a value matching your header bar background color."), - "adw_gtk3_support": "yes" + "explanation": _( + "The backdrop color is used instead of the background color when the window is not focused. By default it's an alias of the window's background color and changes together with it. When changing this variable, make sure to set it to a value matching your header bar background color." + ), + "adw_gtk3_support": "yes", }, { "name": "headerbar_shade_color", "title": _("Shade Color"), - "explanation": _("The shade color is used to provide a dark border for header bars and similar widgets that separates them from the main window."), - "adw_gtk3_support": "no" - } - ] + "explanation": _( + "The shade color is used to provide a dark border for header bars and similar widgets that separates them from the main window." + ), + "adw_gtk3_support": "no", + }, + ], }, { "name": "card_colors", @@ -192,20 +240,22 @@ settings_schema = { { "name": "card_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "card_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "card_shade_color", "title": _("Shade Color"), - "explanation": _("The shade color is used for shadows that are used by cards to separate themselves from the window background, as well as for row dividers in the cards."), - "adw_gtk3_support": "no" - } - ] + "explanation": _( + "The shade color is used for shadows that are used by cards to separate themselves from the window background, as well as for row dividers in the cards." + ), + "adw_gtk3_support": "no", + }, + ], }, { "name": "dialog_colors", @@ -215,14 +265,14 @@ settings_schema = { { "name": "dialog_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "no" + "adw_gtk3_support": "no", }, { "name": "dialog_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "no" - } - ] + "adw_gtk3_support": "no", + }, + ], }, { "name": "popover_colors", @@ -232,14 +282,14 @@ settings_schema = { { "name": "popover_bg_color", "title": _("Background Color"), - "adw_gtk3_support": "yes" + "adw_gtk3_support": "yes", }, { "name": "popover_fg_color", "title": _("Foreground Color"), - "adw_gtk3_support": "yes" - } - ] + "adw_gtk3_support": "yes", + }, + ], }, { "name": "misc_colors", @@ -249,67 +299,32 @@ settings_schema = { { "name": "shade_color", "title": _("Shade Color"), - "explanation": _("The shade color is used by inline tab bars, as well as the transitions in leaflets and flaps, and info bar borders."), - "adw_gtk3_support": "no" + "explanation": _( + "The shade color is used by inline tab bars, as well as the transitions in leaflets and flaps, and info bar borders." + ), + "adw_gtk3_support": "no", }, { "name": "scrollbar_outline_color", "title": _("Scrollbar Outline Color"), - "explanation": _("The scrollbar outline color is used by scrollbars to ensure that overlay scrollbars are visible regardless of the content color."), - "adw_gtk3_support": "no" - } - ] - } + "explanation": _( + "The scrollbar outline color is used by scrollbars to ensure that overlay scrollbars are visible regardless of the content color." + ), + "adw_gtk3_support": "no", + }, + ], + }, ], "palette": [ - { - "prefix": "blue_", - "title": _("Blue"), - "n_shades": 5 - }, - { - "prefix": "green_", - "title": _("Green"), - "n_shades": 5 - }, - { - "prefix": "yellow_", - "title": _("Yellow"), - "n_shades": 5 - }, - { - "prefix": "orange_", - "title": _("Orange"), - "n_shades": 5 - }, - { - "prefix": "red_", - "title": _("Red"), - "n_shades": 5 - }, - { - "prefix": "purple_", - "title": _("Purple"), - "n_shades": 5 - }, - { - "prefix": "brown_", - "title": _("Brown"), - "n_shades": 5 - }, - { - "prefix": "light_", - "title": _("Light"), - "n_shades": 5 - }, - { - "prefix": "dark_", - "title": _("Dark"), - "n_shades": 5 - } + {"prefix": "blue_", "title": _("Blue"), "n_shades": 5}, + {"prefix": "green_", "title": _("Green"), "n_shades": 5}, + {"prefix": "yellow_", "title": _("Yellow"), "n_shades": 5}, + {"prefix": "orange_", "title": _("Orange"), "n_shades": 5}, + {"prefix": "red_", "title": _("Red"), "n_shades": 5}, + {"prefix": "purple_", "title": _("Purple"), "n_shades": 5}, + {"prefix": "brown_", "title": _("Brown"), "n_shades": 5}, + {"prefix": "light_", "title": _("Light"), "n_shades": 5}, + {"prefix": "dark_", "title": _("Dark"), "n_shades": 5}, ], - "custom_css_app_types": [ - "gtk4", - "gtk3" - ] + "custom_css_app_types": ["gtk4", "gtk3"], } diff --git a/src/style.css b/src/style.css index b6badc1c..f2f0cbb4 100644 --- a/src/style.css +++ b/src/style.css @@ -1,3 +1,21 @@ +/* + * Change the look of Adwaita, with ease + * Copyright (C) 2022 Adwaita Manager Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +**/ + .custom-css-view { padding: 12px; } diff --git a/src/ui/window.blp b/src/ui/window.blp index 0562b4d1..ba11eeb9 100644 --- a/src/ui/window.blp +++ b/src/ui/window.blp @@ -1,56 +1,111 @@ using Gtk 4.0; using Adw 1; -template AdwcustomizerMainWindow : ApplicationWindow { +template AdwcustomizerMainWindow : Adw.ApplicationWindow { title: _("Adwaita Manager"); default-width: 1280; default-height: 720; - titlebar: HeaderBar { - [start] - Button apply-button { - styles ["suggested-action"] - label: _("Apply"); - action-name: "app.apply_color_scheme"; - } + Adw.ToastOverlay toast_overlay { + Adw.Leaflet leaflet { + can-navigate-back: true; + can-unfold: false; - [start] - Button save-preset-button { - action-name: "app.save_preset"; - tooltip-text: _("Save Preset"); - Adw.ButtonContent { - icon-name: "document-save-symbolic"; + Gtk.Box main_view { + orientation: vertical; + + Adw.HeaderBar titlebar { + centering-policy: strict; + + [start] + Button apply-button { + styles ["suggested-action"] + label: _("Apply"); + action-name: "app.apply_color_scheme"; + } + + [title] + Adw.ViewSwitcherTitle title { + stack: view_stack; + } + + [end] + Gtk.MenuButton { + icon-name: "open-menu-symbolic"; + menu-model: main-menu; + } + + [end] + MenuButton presets-dropdown { + menu-model: presets-menu; + label: _("Presets"); + icon-name: "palette-symbolic"; + } + + [end] + Button save-preset-button { + action-name: "app.save_preset"; + tooltip-text: _("Save Preset"); + Adw.ButtonContent { + icon-name: "disk-saved-symbolic"; + } + } + + + [end] + MenuButton errors-button { + styles ["raised", "error"] + icon-name: "dialog-warning-symbolic"; + popover: errors-popover; + } + + + + } + + Gtk.Box { + orientation: vertical; + + Adw.ViewStack view_stack { + vexpand: true; + hexpand: true; + + Adw.ViewStackPage { + name: "colors"; + title: C_("Navigation", "Colors"); + icon-name: "larger-brush-symbolic"; + + child: Adw.PreferencesPage content { }; + + } + + Adw.ViewStackPage { + name: "monet"; + title: C_("Navigation", "Monet"); + icon-name: "color-picker-symbolic"; + + child: Adw.PreferencesPage content_monet { }; + } + + Adw.ViewStackPage { + name: "plugins"; + title: C_("Navigation", "Advanced"); + icon-name: "settings-symbolic"; + + + child: Adw.PreferencesPage content_plugins { }; + + } + } + + Adw.ViewSwitcherBar { + stack: view_stack; + reveal: bind title.title-visible; + } + } } } - - // [start] - // MenuButton presets-dropdown { - // icon-name: "palette-symbolic"; - // menu-model: presets-menu; - // tooltip-text: _("Presets"); - // } - - [title] - MenuButton presets-dropdown { - menu-model: presets-menu; - label: _("Presets"); - } - - [end] - MenuButton { - icon-name: "open-menu-symbolic"; - menu-model: main-menu; - } - - [end] - MenuButton errors-button { - styles ["raised", "error"] - icon-name: "dialog-warning-symbolic"; - popover: errors-popover; - } - }; - - Adw.PreferencesPage content { } + } } menu presets-menu { @@ -66,12 +121,29 @@ menu presets-menu { action: "app.load_preset"; target: "adwaita-dark"; } + item { + label: "Manage Presets"; + action: "app.manage_presets"; + } } } + menu main-menu { - item (_("Reset Applied Color Scheme"), "app.reset_color_scheme") - item (_("About Adwaita Manager"), "app.about") + section { + item { + label: _("Release Notes"); + action: "win.show-release-notes"; + } + item { + label: _("Reset Applied Color Scheme"); + action: "app.reset_color_scheme"; + } + item { + label: _("About Adwaita Manager"); + action: "app.about"; + } + } } Popover errors-popover { diff --git a/src/window.py b/src/window.py index 267ae017..2e35d7f4 100644 --- a/src/window.py +++ b/src/window.py @@ -26,20 +26,26 @@ # use or other dealings in this Software without prior written # authorization. -from gi.repository import Gtk, Adw, Gio +from gi.repository import Gtk, Adw, Gio, Gdk from .error import AdwcustomizerError from .settings_schema import settings_schema from .palette_shades import AdwcustomizerPaletteShades from .option import AdwcustomizerOption from .app_type_dialog import AdwcustomizerAppTypeDialog from .custom_css_group import AdwcustomizerCustomCSSGroup +from material_color_utilities_python import * -@Gtk.Template(resource_path='/com/github/AdwCustomizerTeam/AdwCustomizer/ui/window.ui') -class AdwcustomizerMainWindow(Gtk.ApplicationWindow): - __gtype_name__ = 'AdwcustomizerMainWindow' + +@Gtk.Template(resource_path="/com/github/AdwCustomizerTeam/AdwCustomizer/ui/window.ui") +class AdwcustomizerMainWindow(Adw.ApplicationWindow): + __gtype_name__ = "AdwcustomizerMainWindow" content = Gtk.Template.Child() + toast_overlay = Gtk.Template.Child() + content_monet = Gtk.Template.Child("content_monet") + content_plugins = Gtk.Template.Child("content_plugins") save_preset_button = Gtk.Template.Child("save-preset-button") + main_menu = Gtk.Template.Child("main-menu") presets_dropdown = Gtk.Template.Child("presets-dropdown") presets_menu = Gtk.Template.Child("presets-menu") errors_button = Gtk.Template.Child("errors-button") @@ -47,45 +53,15 @@ class AdwcustomizerMainWindow(Gtk.ApplicationWindow): def __init__(self, **kwargs): super().__init__(**kwargs) - self.presets_dropdown.get_popover().connect("show", self.on_presets_dropdown_activate) + self.presets_dropdown.get_popover().connect( + "show", self.on_presets_dropdown_activate + ) - for group in settings_schema["groups"]: - pref_group = Adw.PreferencesGroup() - pref_group.set_name(group["name"]) - pref_group.set_title(group["title"]) - pref_group.set_description(group["description"]) + self.setup_monet_page() + self.setup_plugins_page() + self.setup_colors_page() - for variable in group["variables"]: - pref_variable = AdwcustomizerOption(variable["name"], - variable["title"], - variable["adw_gtk3_support"], - variable.get("explanation")) - pref_group.add(pref_variable) - self.get_application().pref_variables[variable["name"]] = pref_variable - - self.content.add(pref_group) - - palette_pref_group = Adw.PreferencesGroup() - palette_pref_group.set_name("palette_colors") - palette_pref_group.set_title(_("Palette Colors")) - palette_pref_group.set_description(_("Named palette colors used by some applications. Default colors follow the
GNOME Human Interface Guidelines.")) - for color in settings_schema["palette"]: - palette_shades = AdwcustomizerPaletteShades(color["prefix"], - color["title"], - color["n_shades"]) - palette_pref_group.add(palette_shades) - self.get_application().pref_palette_shades[color["prefix"]] = palette_shades - self.content.add(palette_pref_group) - - custom_css_group = AdwcustomizerCustomCSSGroup() - for app_type in settings_schema["custom_css_app_types"]: - self.get_application().custom_css[app_type] = "" - custom_css_group.load_custom_css(self.get_application().custom_css) - self.content.add(custom_css_group) - self.get_application().custom_css_group = custom_css_group - - self.settings = Gio.Settings( - "com.github.AdwCustomizerTeam.AdwCustomizer") + self.settings = Gio.Settings("com.github.AdwCustomizerTeam.AdwCustomizer") self.settings.bind( "window-width", self, "default-width", Gio.SettingsBindFlags.DEFAULT @@ -102,6 +78,128 @@ class AdwcustomizerMainWindow(Gtk.ApplicationWindow): "window-fullscreen", self, "fullscreened", Gio.SettingsBindFlags.DEFAULT ) + def on_file_picker_button_clicked(self, *args): + self.monet_file_chooser_dialog.show() + + def on_monet_file_chooser_response(self, widget, response): + if response == Gtk.ResponseType.ACCEPT: + self.monet_image_file = self.monet_file_chooser_dialog.get_file() + image_basename = self.monet_image_file.get_basename() + self.monet_file_chooser_button.set_label(image_basename) + self.monet_file_chooser_dialog.hide() + + if response == Gtk.ResponseType.ACCEPT: + self.monet_img = Image.open(self.monet_image_file.get_path()) + self.theme = themeFromImage(self.monet_img) + self.tone = self.tone_row.get_selected_item() + self.monet_theme = self.monet_theme_row.get_selected_item() + self.get_application().update_theme_from_monet( + self.theme, self.tone, self.monet_theme + ) + + def setup_monet_page(self): + + self.monet_pref_group = Adw.PreferencesGroup() + self.monet_pref_group.set_name("monet") + self.monet_pref_group.set_title(_("Monet Engine")) + self.monet_pref_group.set_description( + _( + "Monet is an engine that generates Material Design 3 palette from backgrounds color. The generation can be slow" + ) + ) + + self.monet_file_chooser_row = Adw.ActionRow() + self.monet_file_chooser_row.set_title(_("Background Image")) + + self.monet_file_chooser_dialog = Gtk.FileChooserNative() + self.monet_file_chooser_dialog.set_transient_for(self) + + self.monet_file_chooser_button = Gtk.Button() + self.monet_file_chooser_button.set_label(_("Choose a file")) + self.monet_file_chooser_button.set_icon_name("folder-pictures-symbolic") + + self.monet_file_chooser_button.connect( + "clicked", self.on_file_picker_button_clicked + ) + self.monet_file_chooser_dialog.connect( + "response", self.on_monet_file_chooser_response + ) + self.monet_file_chooser_row.add_suffix(self.monet_file_chooser_button) + self.monet_pref_group.add(self.monet_file_chooser_row) + + self.monet_palette_shades = AdwcustomizerPaletteShades( + "monet", "Monet Palette", 6 + ) + self.get_application().pref_palette_shades["monet"] = self.monet_palette_shades + self.monet_pref_group.add(self.monet_palette_shades) + + self.tone_row = Adw.ComboRow() + self.tone_row.set_title(_("Tone")) + + store = Gtk.StringList() + store_values = [] + for i in range(20, 80, 5): + store_values.append(str(i)) + for v in store_values: + store.append(v) + self.tone_row.set_model(store) + self.monet_pref_group.add(self.tone_row) + + self.monet_theme_row = Adw.ComboRow() + self.monet_theme_row.set_title(_("Theme")) + + store = Gtk.StringList() + store.append("Auto") + store.append("Dark") + store.append("Light") + self.monet_theme_row.set_model(store) + self.monet_pref_group.add(self.monet_theme_row) + + self.content_monet.add(self.monet_pref_group) + + def setup_plugins_page(self): + custom_css_group = AdwcustomizerCustomCSSGroup() + for app_type in settings_schema["custom_css_app_types"]: + self.get_application().custom_css[app_type] = "" + custom_css_group.load_custom_css(self.get_application().custom_css) + self.content_plugins.add(custom_css_group) + self.get_application().custom_css_group = custom_css_group + + def setup_colors_page(self): + for group in settings_schema["groups"]: + pref_group = Adw.PreferencesGroup() + pref_group.set_name(group["name"]) + pref_group.set_title(group["title"]) + pref_group.set_description(group["description"]) + + for variable in group["variables"]: + pref_variable = AdwcustomizerOption( + variable["name"], + variable["title"], + variable.get("explanation"), + variable["adw_gtk3_support"], + ) + pref_group.add(pref_variable) + self.get_application().pref_variables[variable["name"]] = pref_variable + + self.content.add(pref_group) + + palette_pref_group = Adw.PreferencesGroup() + palette_pref_group.set_name("palette_colors") + palette_pref_group.set_title(_("Palette Colors")) + palette_pref_group.set_description( + _( + 'Named palette colors used by some applications. Default colors follow the GNOME Human Interface Guidelines.' + ) + ) + for color in settings_schema["palette"]: + palette_shades = AdwcustomizerPaletteShades( + color["prefix"], color["title"], color["n_shades"] + ) + palette_pref_group.add(palette_shades) + self.get_application().pref_palette_shades[color["prefix"]] = palette_shades + self.content.add(palette_pref_group) + def update_errors(self, errors): child = self.errors_list.get_row_at_index(0) while child is not None: @@ -109,7 +207,9 @@ class AdwcustomizerMainWindow(Gtk.ApplicationWindow): child = self.errors_list.get_row_at_index(0) self.errors_button.set_visible(len(errors) > 0) for error in errors: - self.errors_list.append(AdwcustomizerError(error["error"], error["element"], error["line"])) + self.errors_list.append( + AdwcustomizerError(error["error"], error["element"], error["line"]) + ) def on_presets_dropdown_activate(self, *args): self.get_application().reload_user_defined_presets()