Let every screen choose its top bar: clocks, date and entities (0.2.38)
The name stays on the left; up to six items go on the right: the time, an analog clock, the date, or a Home Assistant entity with its icon, showing its state or how long ago it changed, always or only while active. The add-on formats entity text in Dutch and sends it as op: header right after the layout to firmware 0.2.32+; older firmware keeps the clock of show_clock, which now follows the clock item. The firmware draws every value in one font on the name's baseline, centres icons and the dial on the digit height and measures gaps between glyph ink, so the bar looks even; the editor's mockup uses Roboto and the same integer rules. tools/render_topbar.py renders the real LVGL code on a computer (ESPHome host + SDL2). The editor's section buttons are gone. Firmware 0.2.32 for both boards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+27
-4
@@ -1,11 +1,12 @@
|
||||
"""Write the tile icon set into both board profiles and build the editor's icon font.
|
||||
"""Write the tile icon set into both board profiles and build the editor's fonts.
|
||||
|
||||
The list lives in screen_manager/app/tile_icons.py. Every Material Design Icons
|
||||
font of a board profile gets exactly those glyphs (the first font carries the
|
||||
list as a YAML anchor, the smaller sizes reuse it), and the editor gets a subset
|
||||
of the same TTF so its mockup shows the glyphs the screen draws. Run
|
||||
tools/generate_packages.py afterwards; --check changes nothing and fails when
|
||||
anything is out of date.
|
||||
of the same TTF so its mockup shows the glyphs the screen draws. The top bar
|
||||
mockup also gets Roboto 400/500 with the glyphs of header_bar.GLYPHS, so text
|
||||
widths in the editor match the screen. Run tools/generate_packages.py afterwards;
|
||||
--check changes nothing and fails when anything is out of date.
|
||||
"""
|
||||
import argparse
|
||||
import io
|
||||
@@ -18,11 +19,13 @@ from fontTools.ttLib import TTFont
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
sys.path.insert(0, str(ROOT / 'screen_manager/app'))
|
||||
import header_bar # noqa: E402
|
||||
import tile_icons # noqa: E402
|
||||
|
||||
TTF = ROOT / 'fonts/materialdesignicons-webfont.ttf'
|
||||
PROFILES = [ROOT / 'home-like-2432s028.yaml', ROOT / 'guition-4848s040.yaml']
|
||||
WEB_FONT = ROOT / 'screen_manager/app/static/tile-icons.woff'
|
||||
BAR_FONTS = {weight: ROOT / f'screen_manager/app/static/bar-roboto-{weight}.woff' for weight in (400, 500)}
|
||||
NAME_TABLE = ROOT / 'components/smart_display/tile_icon_names.h'
|
||||
FONT_BLOCK = re.compile(r"( - file: 'fonts/materialdesignicons-webfont\.ttf'\n id: \w+\n size: \d+\n) glyphs:.*\n(?: .*\n)*")
|
||||
|
||||
@@ -103,6 +106,21 @@ def web_font():
|
||||
font.save(buffer)
|
||||
return buffer.getvalue()
|
||||
|
||||
def bar_font(weight):
|
||||
"""Roboto subset for the editor's top bar mockup: the glyphs and metrics the screens draw."""
|
||||
font = TTFont(ROOT / f'fonts/Roboto-{weight}.ttf')
|
||||
options = subset.Options()
|
||||
options.flavor = 'woff'
|
||||
options.layout_features = ['kern']
|
||||
options.name_IDs = [0, 1, 2]
|
||||
subsetter = subset.Subsetter(options)
|
||||
subsetter.populate(unicodes=[ord(char) for char in header_bar.GLYPHS])
|
||||
subsetter.subset(font)
|
||||
buffer = io.BytesIO()
|
||||
font.flavor = 'woff'
|
||||
font.save(buffer)
|
||||
return buffer.getvalue()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--check', action='store_true')
|
||||
@@ -120,9 +138,14 @@ def main():
|
||||
wanted = {int(code, 16) for code in tile_icons.GLYPHS.values()}
|
||||
if not WEB_FONT.exists() or set(TTFont(WEB_FONT).getBestCmap()) != wanted:
|
||||
raise SystemExit(f'Outdated: {WEB_FONT.name}')
|
||||
for weight, path in BAR_FONTS.items():
|
||||
if not path.exists() or set(TTFont(path).getBestCmap()) != {ord(char) for char in header_bar.GLYPHS}:
|
||||
raise SystemExit(f'Outdated: {path.name}')
|
||||
else:
|
||||
NAME_TABLE.write_text(name_table())
|
||||
WEB_FONT.write_bytes(web_font())
|
||||
for weight, path in BAR_FONTS.items():
|
||||
path.write_bytes(bar_font(weight))
|
||||
print(f'{len(tile_icons.ICONS)} pickable icons, {len(tile_icons.GLYPHS)} glyphs: ' + ('verified' if args.check else 'generated'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user