gsetup: Load a Gio Resource with our application icons

We can put all our icons into a single resource bundle that gets loaded
and only exists for our app.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
This commit is contained in:
Anna Schumaker 2022-07-15 14:53:04 -04:00
parent 5cd5d2640d
commit 4be26c5fee
8 changed files with 185 additions and 5 deletions

1
.gitignore vendored
View File

@ -5,3 +5,4 @@
*.txt *.txt
*.patch *.patch
PKGBUILD PKGBUILD
emmental.gresource*

View File

@ -6,9 +6,10 @@ export EMMENTAL_LIB = ${PREFIX}/lib/emmental
export EMMENTAL_BIN = ${PREFIX}/bin export EMMENTAL_BIN = ${PREFIX}/bin
export EMMENTAL_SHARE = ${PREFIX}/share export EMMENTAL_SHARE = ${PREFIX}/share
all: flake8 all: emmental.gresource flake8
clean: clean:
find . -type f -name "*gresource*" -exec rm {} \+
find . -type d -name __pycache__ -exec rm -r {} \+ find . -type d -name __pycache__ -exec rm -r {} \+
find data/ -type d -name "Test Album" -exec rm -r {} \+ find data/ -type d -name "Test Album" -exec rm -r {} \+
find data/ -type d -name "Test Library" -exec rm -r {} \+ find data/ -type d -name "Test Library" -exec rm -r {} \+
@ -17,8 +18,16 @@ clean:
flake8: flake8:
flake8 emmental/ tests/ flake8 emmental/ tests/
.PHONY: emmental.gresource.xml
emmental.gresource.xml:
exec tools/find-resources.py
.PHONY: emmental.gresource
emmental.gresource: emmental.gresource.xml
glib-compile-resources emmental.gresource.xml
.PHONY: install .PHONY: install
install: install: emmental.gresource
exec tools/install.sh exec tools/install.sh
.PHONY: uninstall .PHONY: uninstall
@ -40,7 +49,7 @@ pkgbuild:
cd aur && makepkg --printsrcinfo > .SRCINFO cd aur && makepkg --printsrcinfo > .SRCINFO
.PHONY: pytest .PHONY: pytest
pytest: pytest: emmental.gresource
pytest pytest
.PHONY: tests .PHONY: tests

View File

@ -15,7 +15,8 @@ class Application(Adw.Application):
def __init__(self): def __init__(self):
"""Initialize an Application.""" """Initialize an Application."""
super().__init__(application_id=gsetup.APPLICATION_ID) super().__init__(application_id=gsetup.APPLICATION_ID,
resource_base_path=gsetup.RESOURCE_PATH)
self.add_main_option_entries([options.Version]) self.add_main_option_entries([options.Version])
def do_handle_local_options(self, opts: GLib.VariantDict) -> int: def do_handle_local_options(self, opts: GLib.VariantDict) -> int:

View File

@ -1,5 +1,5 @@
# Copyright 2022 (c) Anna Schumaker. # Copyright 2022 (c) Anna Schumaker.
"""Set up GObject Introspection and custom styling.""" """Set up GObject Introspection, and custom styling, and icons."""
import pathlib import pathlib
import sys import sys
import gi import gi
@ -8,6 +8,7 @@ gi.require_version("Gdk", "4.0")
gi.require_version("Gtk", "4.0") gi.require_version("Gtk", "4.0")
gi.require_version("Adw", "1") gi.require_version("Adw", "1")
gi.importlib.import_module("gi.repository.Gio")
gi.importlib.import_module("gi.repository.Gtk") gi.importlib.import_module("gi.repository.Gtk")
DEBUG_STR = "-debug" if __debug__ else "" DEBUG_STR = "-debug" if __debug__ else ""
@ -18,6 +19,12 @@ CSS_PRIORITY = gi.repository.Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
CSS_PROVIDER = gi.repository.Gtk.CssProvider() CSS_PROVIDER = gi.repository.Gtk.CssProvider()
CSS_PROVIDER.load_from_path(str(CSS_FILE)) CSS_PROVIDER.load_from_path(str(CSS_FILE))
RESOURCE_PATH = "/com/nowheycreamery/emmental"
RESOURCE_ICONS = f"{RESOURCE_PATH}/icons/scalable/apps"
RESOURCE_FILE = pathlib.Path(__file__).parent.parent / "emmental.gresource"
RESOURCE = gi.repository.Gio.Resource.load(str(RESOURCE_FILE))
gi.repository.Gio.resources_register(RESOURCE)
def add_style(): def add_style():
"""Add our stylesheet to the default display.""" """Add our stylesheet to the default display."""

View File

@ -0,0 +1,118 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="0 0 135.46666 135.46667"
version="1.1"
id="svg75"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="emmental.svg">
<defs
id="defs69">
<symbol
id="icon-music-note">
<title
id="title78520">music-note</title>
<path
d="M26.625 2.006c-0.137 0-0.319 0.038-0.319 0.038l-13.6 2.075c-0.863 0.231-1.644 1.069-1.706 1.975v17.906h-3.813v-0.006c-1.75 0-3.194 1.25-3.194 3s1.444 3 3.206 3h2.263c0.956 0 1.806-0.431 2.394-1.094 0.006-0.006 0.019-0.006 0.025-0.012 0.037-0.038 0.063-0.094 0.094-0.131 0.081-0.1 0.15-0.2 0.213-0.313 0.6-0.881 0.813-2.050 0.813-2.569v-14.5l13-2.375c0 0 0 8.5 0 12h-3.781c-1.769 0-3.2 1.244-3.2 3s1.431 3 3.2 3h2.325c1.137 0 2.131-0.375 2.7-1.313 0 0 0.006 0 0.012 0 0.563-0.75 0.75-1.887 0.75-3.431 0-1.55 0-18.925 0-18.925-0.006-0.731-0.625-1.325-1.381-1.325z"
id="path78522" />
</symbol>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="-114.53623"
inkscape:cy="26.266036"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="992"
inkscape:window-x="0"
inkscape:window-y="49"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata72">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-161.53332)">
<path
id="path15"
style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 0.26458333,188.52082 135.20208,221.59374 m 0,0 v 15.875 c -12.17431,8.4e-4 -12.20048,27.68831 0,27.78125 v 31.75 L 79.374999,283.37394 c 2.35699,-19.88199 -19.689115,-25.71573 -23.8125,-5.82083 L 0.26458333,263.92707 V 188.52082 C 17.837267,162.07974 75.40625,161.53332 75.40625,161.53332 Z"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccc" />
<path
style="display:inline;fill:#f8da4a;fill-opacity:1;stroke-width:0.71428573"
d="M 255.34656,163.53518 C 116.62289,129.63458 2.7276541,101.76636 2.2460509,101.60583 -0.02198624,100.84982 18.093321,80.754076 29.000001,71.927033 69.000157,39.553927 134.66532,16.65992 217.92857,6.0575146 c 19.46392,-2.478456 51.1476,-5.0575103 62.13152,-5.0575103 h 4.6559 L 396.85714,113.14286 c 61.67764,61.67857 111.82011,112.11742 111.42773,112.08632 -0.3924,-0.0311 -114.21463,-27.79339 -252.93831,-61.694 z"
id="path819"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,161.53332)" />
<path
style="fill:#f3b722;fill-opacity:1;stroke-width:1.42857146"
d="m 408.89234,485.99486 c -55,-13.51607 -101.71207,-25.0166 -103.8046,-25.55674 -3.73443,-0.96396 -3.8052,-1.20196 -3.83781,-12.90451 -0.0849,-30.43852 -18.1526,-54.01679 -43.12787,-56.28146 -20.53696,-1.86223 -38.83107,12.75464 -46.46432,37.12467 -1.41508,4.51786 -3.03845,8.21429 -3.60748,8.21429 -0.56903,0 -39.82663,-9.57995 -87.23912,-21.28875 C 73.398659,403.59355 27.374486,392.28746 18.5352,390.17774 L 2.4637718,386.34188 V 244.88305 103.42423 l 3.9285714,1.00678 c 2.1607143,0.55373 113.8571468,27.96349 248.2142868,60.91058 134.35714,32.94709 246.69643,60.5528 249.64286,61.34601 l 5.35714,1.4422 v 29.04808 29.04806 l -6.06056,0.96912 c -9.02576,1.44328 -19.56647,12.79662 -24.09478,25.95235 -4.51516,13.11753 -4.85962,38.48575 -0.6869,50.58655 5.73031,16.61778 17.11014,28.57143 27.19987,28.57143 h 3.64237 v 59.28572 c 0,32.60714 -0.16072,59.21657 -0.35714,59.13207 -0.19643,-0.0846 -45.35715,-11.21226 -100.35715,-24.72832 z"
id="path822"
inkscape:connector-curvature="0"
transform="matrix(0.26458333,0,0,0.26458333,0,161.53332)" />
<ellipse
style="fill:#db9822;fill-opacity:1;stroke-width:0.26458332"
id="path828"
cx="52.72768"
cy="179.44939"
rx="14.552083"
ry="6.4255953" />
<ellipse
style="fill:#e7af19;fill-opacity:1;stroke-width:0.26458332"
id="path830"
cx="92.604164"
cy="200.99403"
rx="8.6934528"
ry="3.7797618" />
<ellipse
style="fill:#db9518;fill-opacity:1;stroke-width:0.26458332"
id="path836"
cx="109.04613"
cy="266.19492"
rx="7.3705359"
ry="6.614583" />
<ellipse
style="fill:#db9518;fill-opacity:1;stroke-width:0.26458332"
id="path838"
cx="21.544643"
cy="218.94791"
rx="13.229166"
ry="11.90625" />
<path
style="fill:#b36d00;fill-opacity:1;stroke:none;stroke-width:1.84337676"
inkscape:connector-curvature="0"
d="m 86.73677,215.05635 c -0.282072,0 -0.656796,0.0627 -0.656796,0.0627 l -28.00136,3.42457 c -1.776851,0.38124 -3.38487,1.76427 -3.512523,3.25953 v 29.55198 h -7.850676 v -0.01 c -3.603116,0 -6.576201,2.06299 -6.576201,4.95118 0,2.8882 2.973085,4.95119 6.600908,4.95119 h 4.659344 c 1.968331,0 3.718416,-0.71132 4.929063,-1.80553 0.01235,-0.01 0.03912,-0.01 0.05147,-0.0198 0.07618,-0.0627 0.129712,-0.15513 0.193539,-0.2162 0.166773,-0.16504 0.308838,-0.33008 0.438551,-0.51657 1.235354,-1.454 1.673904,-3.38331 1.673904,-4.23987 V 230.5188 l 26.766006,-3.91969 c 0,0 0,14.02836 0,19.80474 h -7.78479 c -3.642236,0 -6.588555,2.0531 -6.588555,4.95119 0,2.89809 2.946319,4.95119 6.588555,4.95119 h 4.786997 c 2.340996,0 4.387566,-0.6189 5.559094,-2.16697 0,0 0.01235,0 0.02471,0 1.159174,-1.2378 1.544192,-3.1143 1.544192,-5.66251 0,-2.55811 0,-31.23373 0,-31.23373 -0.01235,-1.20644 -1.286827,-2.18678 -2.843373,-2.18678 z"
id="path860" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@ -23,3 +23,5 @@ class TestEmmental(unittest.TestCase):
self.assertIsInstance(self.application, gi.repository.Adw.Application) self.assertIsInstance(self.application, gi.repository.Adw.Application)
self.assertEqual(self.application.get_application_id(), self.assertEqual(self.application.get_application_id(),
"com.nowheycreamery.emmental-debug") "com.nowheycreamery.emmental-debug")
self.assertEqual(self.application.get_property("resource-base-path"),
"/com/nowheycreamery/emmental")

View File

@ -38,3 +38,18 @@ class TestGSetup(unittest.TestCase):
gi.repository.Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION) gi.repository.Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
self.assertIsInstance(emmental.gsetup.CSS_PROVIDER, self.assertIsInstance(emmental.gsetup.CSS_PROVIDER,
gi.repository.Gtk.CssProvider) gi.repository.Gtk.CssProvider)
def test_resource(self):
"""Check that emmental.resource has been loaded."""
path = pathlib.Path(emmental.__file__).parent.parent
path = path / "emmental.gresource"
self.assertEqual(emmental.gsetup.RESOURCE_PATH,
"/com/nowheycreamery/emmental")
icons = f"{emmental.gsetup.RESOURCE_PATH}/icons/scalable/apps"
self.assertEqual(emmental.gsetup.RESOURCE_ICONS, icons)
self.assertEqual(emmental.gsetup.RESOURCE_FILE, path)
self.assertTrue(emmental.gsetup.RESOURCE_FILE.is_file())
self.assertIsInstance(emmental.gsetup.RESOURCE,
gi.repository.Gio.Resource)

27
tools/find-resources.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/python
# Copyright 2022 (c) Anna Schumaker.
"""Generate the emmental.gresource.xml file."""
from xml.dom import minidom
import pathlib
project_dir = pathlib.Path(__file__).parent.parent
resource_file = project_dir / "emmental.gresource.xml"
xml = minidom.Document()
gresources = xml.createElement("gresources")
xml.appendChild(gresources)
gresource = xml.createElement("gresource")
gresource.setAttribute("prefix", "/com/nowheycreamery/emmental")
gresources.appendChild(gresource)
for f in (project_dir / "icons").glob("**/*"):
if f.is_file():
file = xml.createElement("file")
text = xml.createTextNode(str(f.relative_to(project_dir)))
file.appendChild(text)
gresource.appendChild(file)
with open(project_dir / "emmental.gresource.xml", "w") as f:
f.write(xml.toprettyxml())