Files
harbour-aira/tests/label_fit_check.py
T
Carlo 2b397b6c3a 0.7.1: i tasti delle azioni rapide dichiarano la loro altezza
In Silica il tasto piglia l'altezza dal tema (itemSizeExtraSmall, ~56 px) e non
dal contenuto: con icona e etichetta (~110) il testo usciva dalla scatola e la
riga di contorno della colonna finiva sopra le etichette. Ora height:
Theme.itemSizeMedium. Aggiunto il controllo in tests/label_fit_check.py e il
registro di posizione e altezza di ogni riga della Home.
2026-10-11 12:26:20 +02:00

114 lines
4.4 KiB
Python

#!/usr/bin/env python3
"""Controllo statico: le etichette dei tre tasti delle azioni rapide ci stanno?
Sul pulsante Silica il carattere non si puo' rimpicciolire (il tipo non espone
proprieta' `font`), quindi lo spazio per il testo dipende solo dall'icona. I
numeri qui sotto sono MISURATI sullo screenshot di un telefono vero (0.6.7):
tasto 161 px logici, rientri 16, distacco icona-testo 24
icona di Silica senza dichiarazione = 64 px (Theme.iconSizeMedium)
-> restavano 41 px di testo: le etichette uscivano tagliate
Con Theme.iconSizeExtraSmall (32 px) restano 73 px. Il carattere di Sailfish e'
piu' stretto di quello usato qui per misurare (DejaVu): dal confronto sul
telefono risulta circa 0,78 volte, quindi si misura col fattore di sicurezza.
Il test legge i testi veri da qml/pages/MainPage.qml e le traduzioni da
translations/harbour-aira-it.ts: non ci sono etichette scritte a mano qui.
Se cambia la geometria della riga (margini, spazi, altezza) questi numeri vanno
rimisurati su uno screenshot nuovo.
"""
import pathlib
import re
import sys
RADICE = pathlib.Path(__file__).resolve().parent.parent
TASTO, RIENTRO, DISTACCO = 161.0, 16.0, 24.0
ICONA = 32.0 # Theme.iconSizeExtraSmall
CARATTERE = 22 # carattere dei pulsanti Silica
FATTORE = 0.78 # Sailfish (Nokia Pure) rispetto a DejaVu
FONT = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"
def testi_dei_tasti(qml: str):
"""I tasti con icona: (testo, altezza dichiarata o None), in ordine."""
fuori = []
for blocco in re.finditer(r"Button\s*\{(.*?)\n\s*\}", qml, re.S):
corpo = blocco.group(1)
if "../icons/quick-" not in corpo:
continue
riga = re.search(r"text:\s*(.+)", corpo)
if not riga:
continue
testo = re.findall(r'qsTr\("([^"]+)"\)', riga.group(1))
if not testo:
continue
alt = re.search(r"^\s*height:\s*(.+)$", corpo, re.M)
fuori.append((testo[0], alt.group(1).strip() if alt else None))
return fuori
def traduzioni(ts: str):
coppie = {}
for blocco in re.finditer(r"<source>(.*?)</source>\s*<translation[^>]*>(.*?)</translation>",
ts, re.S):
coppie[blocco.group(1)] = blocco.group(2)
return coppie
def main():
try:
from PIL import ImageFont
except ImportError:
print("salto: manca Pillow (serve solo per misurare il testo)")
return 0
qml = (RADICE / "qml" / "pages" / "MainPage.qml").read_text(encoding="utf-8")
ts = (RADICE / "translations" / "harbour-aira-it.ts").read_text(encoding="utf-8")
it = traduzioni(ts)
origine = testi_dei_tasti(qml)
if len(origine) < 3:
print("ESITO: trovati %d testi con icona, ne servono 3" % len(origine))
return 1
sorgenti = [t for t, _ in origine]
problema = 0
# 1. L'altezza. In Silica il tasto la piglia dal tema
# (Theme.itemSizeExtraSmall, ~56 px) e non dal contenuto: con icona E
# etichetta il contenuto ne occupa ~110, esce dalla scatola, e la riga
# successiva della colonna viene messa sopra la scatola -- cioe' sopra
# l'etichetta che sporge. Chi ha entrambi deve dichiarare l'altezza.
for testo, alt in origine:
if not alt:
print(" %-9s nessuna altezza dichiarata: il tema ne da' ~56 px, il contenuto ~110" % testo)
problema += 1
disponibile = TASTO - 2 * RIENTRO - ICONA - DISTACCO
f = ImageFont.truetype(FONT, CARATTERE)
def largo(testo):
# Pillow >= 9.2 ha getlength; prima si misurava con getsize
if hasattr(f, "getlength"):
return f.getlength(testo)
from PIL import Image, ImageDraw
return ImageDraw.Draw(Image.new("L", (1, 1))).textlength(testo, font=f)
prova = [("it", [it.get(s, s) for s in sorgenti]), ("en", sorgenti)]
print("spazio per il testo: %.0f px (tasto %.0f, icona %.0f)" % (disponibile, TASTO, ICONA))
for lingua, etichette in prova:
for t in etichette:
serve = largo(t) * FATTORE
esito = "ok" if serve <= disponibile else "NON CI STA"
if serve > disponibile:
problema += 1
print(" %s %-9s %5.0f px %s" % (lingua, t, serve, esito))
if problema:
print("ESITO: %d etichette non ci stanno: accorciarle o ridurre l'icona" % problema)
return 1
print("ESITO: tutte le etichette ci stanno")
return 0
if __name__ == "__main__":
sys.exit(main())