mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:27:02 +01:00
app_icons: tunedeck gets headphones; later entries move to _apps_more
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
Python tests / test (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
apps.py was one entry short of the 250-line cap, so tutor and the new tunedeck entry live in _apps_more.MORE_APPS, merged into APPS unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CyiH5e86uaQzhXzVXTQiVc
This commit is contained in:
parent
70df11f306
commit
6383bd7452
@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "tunedeck launcher icon (headphones)",
|
||||
"objective": "The shared app_icons generator registers `tunedeck` with a new `headphones` glyph that stays inside SAFE_BOX and reads at 48dp, without a per-repo copy of the generator, while apps.py stays under the 250-line cap.",
|
||||
"acceptance_criteria": [
|
||||
"generate --app tunedeck --android --web writes assets/icon/*, the Android mipmaps and the web icons",
|
||||
"python_pkg/app_icons stays at 100% line and branch coverage; every file <= 250 lines",
|
||||
"every other app's registry entry is unchanged (tutor only moves module)"
|
||||
],
|
||||
"out_of_scope": [
|
||||
"Changing style.py or any other app's glyph",
|
||||
"Committing the generated files in ~/src/tunedeck from this repo"
|
||||
],
|
||||
"verifier": "pytest --cov=python_pkg.app_icons --cov-branch; the generate and preview commands; pre-commit hooks on the staged files"
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
{
|
||||
"intent": "Give the new tunedeck Flutter app (music / podcast player) an on-style launcher icon: headphones in the shared accent on the family charcoal.",
|
||||
"scope": [
|
||||
"python_pkg/app_icons/_glyph_art_extra.py, glyphs.py: the `headphones` glyph",
|
||||
"python_pkg/app_icons/_apps_more.py, apps.py: tutor moves to MORE_APPS (apps.py was at 249 lines) and tunedeck joins it",
|
||||
"python_pkg/app_icons/tests/test_registry.py: headphones registry tests"
|
||||
],
|
||||
"changes": [
|
||||
"New `headphones` glyph: stroked r=216 headband over two filled 112x216 ear cups, 288px gap between cups, ink 512x428 inside SAFE_BOX",
|
||||
"tunedeck registered with accent #B8862E, linux=True (desktop is a web build in a Chrome --app window)",
|
||||
"APPS merges MORE_APPS unchanged, so lookups and ordering of existing apps are the same"
|
||||
],
|
||||
"verification": [
|
||||
{
|
||||
"command": "PYTHONPATH=~/src/testsAndMisc python3 -m python_pkg.app_icons generate --app tunedeck --android --web",
|
||||
"result": "pass",
|
||||
"evidence": "tunedeck: wrote 6 asset files; wrote 5 web icons; regenerated Android mipmaps; icon.png viewed: headphones on #211D1B"
|
||||
},
|
||||
{
|
||||
"command": "PYTHONPATH=~/src/testsAndMisc python3 -m python_pkg.app_icons preview -o ~/data/claude-scratch/tunedeck-icon-sheet.png",
|
||||
"result": "pass",
|
||||
"evidence": "Sheet viewed: headphones read at full size, circle-masked and 48dp next to the other glyphs; no safe-box warning"
|
||||
},
|
||||
{
|
||||
"command": "python3 -m pytest -q python_pkg/app_icons/tests --cov=python_pkg.app_icons --cov-branch",
|
||||
"result": "pass",
|
||||
"evidence": "55 passed; every python_pkg/app_icons module 100% line and branch"
|
||||
}
|
||||
],
|
||||
"risks": [
|
||||
"The band's round caps show as small shoulders above the cups; intended as the headphone yoke"
|
||||
],
|
||||
"rollback": [
|
||||
"git revert this commit; tunedeck and the headphones glyph leave the registry; tutor's entry is byte-identical either way"
|
||||
]
|
||||
}
|
||||
36
python_pkg/app_icons/_apps_more.py
Normal file
36
python_pkg/app_icons/_apps_more.py
Normal file
@ -0,0 +1,36 @@
|
||||
"""Later registry entries, split out of :mod:`apps` for the 250-line cap.
|
||||
|
||||
Which file an entry lives in carries no meaning; :data:`apps.APPS` merges both.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
from python_pkg.app_icons._app_icon import AppIcon
|
||||
|
||||
_HOME = Path.home()
|
||||
|
||||
MORE_APPS: Final[tuple[AppIcon, ...]] = (
|
||||
AppIcon(
|
||||
key="tutor",
|
||||
repo=_HOME / "src/tutor/app",
|
||||
accent="#B8862E",
|
||||
glyph="lightbulb",
|
||||
icon_name="tutor",
|
||||
# Desktop is the web build in a Chrome --app window, as for todo
|
||||
# and home_inventory, whose desktop entries use the hicolor set.
|
||||
linux=True,
|
||||
),
|
||||
AppIcon(
|
||||
key="tunedeck",
|
||||
repo=_HOME / "src/tunedeck",
|
||||
accent="#B8862E",
|
||||
glyph="headphones",
|
||||
icon_name="tunedeck",
|
||||
# Desktop is a web build behind a local wrapper in a Chrome --app
|
||||
# window (see the repo's SPEC.md), so it gets the hicolor set too.
|
||||
linux=True,
|
||||
),
|
||||
)
|
||||
@ -24,3 +24,20 @@ _LIGHTBULB = """\
|
||||
A 150 150 0 0 1 662 442 C 662 500 576 510 576 556 Z"/>
|
||||
<path d="M 440 668 L 584 668"/>
|
||||
<path d="M 480 780 L 544 780"/>"""
|
||||
|
||||
# Headphones -- tunedeck, a music player: the listening itself. A stroked
|
||||
# headband over two filled ear cups. The music note (``note-ascender``) is
|
||||
# lyricanki's, and a cassette's reels need more negative space than a 560px
|
||||
# box leaves at the family stroke weight, so the ear cups carry the meaning.
|
||||
#
|
||||
# Geometry, ink inside SAFE_BOX (x=256..768 = 512 wide, y=308..736 = 428 tall):
|
||||
# band semicircle r=216 about (512,560), so its ink tops out at y=308 and
|
||||
# its ends land at x=296 / x=728, buried inside the cups.
|
||||
# cups filled rounded rects x=256..368 and x=656..768, y=520..736; the
|
||||
# 288px gap between them is far clear of MIN_NEGATIVE_SPACE=36.
|
||||
_HEADPHONES = """\
|
||||
<path d="M 296 560 A 216 216 0 0 1 728 560"/>
|
||||
<rect x="256" y="520" width="112" height="216" rx="40" \
|
||||
fill="{{ACCENT}}" stroke="none"/>
|
||||
<rect x="656" y="520" width="112" height="216" rx="40" \
|
||||
fill="{{ACCENT}}" stroke="none"/>"""
|
||||
|
||||
@ -13,6 +13,7 @@ from pathlib import Path
|
||||
from typing import Final
|
||||
|
||||
from python_pkg.app_icons._app_icon import AppIcon
|
||||
from python_pkg.app_icons._apps_more import MORE_APPS
|
||||
|
||||
__all__ = ["APPS", "AppIcon", "get_app"]
|
||||
|
||||
@ -215,16 +216,7 @@ APPS: Final[dict[str, AppIcon]] = {
|
||||
icon_name="daily-limits",
|
||||
linux=False,
|
||||
),
|
||||
AppIcon(
|
||||
key="tutor",
|
||||
repo=_HOME / "src/tutor/app",
|
||||
accent="#B8862E",
|
||||
glyph="lightbulb",
|
||||
icon_name="tutor",
|
||||
# Desktop is the web build in a Chrome --app window, as for todo
|
||||
# and home_inventory, whose desktop entries use the hicolor set.
|
||||
linux=True,
|
||||
),
|
||||
*MORE_APPS,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ from python_pkg.app_icons._glyph_art import (
|
||||
_SHIELD_CUTLERY,
|
||||
_STORAGE_BOX,
|
||||
)
|
||||
from python_pkg.app_icons._glyph_art_extra import _LIGHTBULB
|
||||
from python_pkg.app_icons._glyph_art_extra import _HEADPHONES, _LIGHTBULB
|
||||
from python_pkg.app_icons._glyph_art_more import (
|
||||
_BOWL_STAR,
|
||||
_HOURGLASS,
|
||||
@ -100,6 +100,7 @@ GLYPHS: Final[dict[str, Glyph]] = {
|
||||
_REMOTE_WAVE,
|
||||
),
|
||||
Glyph("lightbulb", "Filled lightbulb over a two-bar screw base", _LIGHTBULB),
|
||||
Glyph("headphones", "Headband arc over two filled ear cups", _HEADPHONES),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -93,3 +93,16 @@ class TestLightbulbGlyph:
|
||||
def test_bulb_is_filled_in_the_accent(self) -> None:
|
||||
"""The bulb takes the accent marker, so the monochrome layer recolours it."""
|
||||
assert f'fill="{style.ACCENT_MARKER}"' in glyphs.get_glyph("lightbulb").body
|
||||
|
||||
|
||||
class TestHeadphonesGlyph:
|
||||
def test_tunedeck_uses_it(self) -> None:
|
||||
app = apps.get_app("tunedeck")
|
||||
assert app.glyph == "headphones"
|
||||
assert app.linux
|
||||
|
||||
def test_cups_are_filled_in_the_accent(self) -> None:
|
||||
"""The cups take the accent marker, so the monochrome layer recolours it."""
|
||||
body = glyphs.get_glyph("headphones").body
|
||||
assert f'fill="{style.ACCENT_MARKER}"' in body
|
||||
assert 'stroke="none"' in body
|
||||
|
||||
Loading…
Reference in New Issue
Block a user