66import math
77
88# Couleurs RGB565
9- BLACK = gc9a01 .color565 (0 , 0 , 0 )
10- WHITE = gc9a01 .color565 (255 , 255 , 255 )
11- RED = gc9a01 .color565 (220 , 50 , 50 )
12- GREEN = gc9a01 .color565 (50 , 200 , 80 )
13- ORANGE = gc9a01 .color565 (255 , 150 , 0 )
14- BLUE = gc9a01 .color565 (0 , 120 , 220 )
15- GRAY = gc9a01 .color565 (80 , 80 , 80 )
16- DK_GRAY = gc9a01 .color565 (40 , 40 , 40 )
17- CYAN = gc9a01 .color565 (0 , 200 , 200 )
9+ BLACK = gc9a01 .color565 (0 , 0 , 0 )
10+ WHITE = gc9a01 .color565 (255 , 255 , 255 )
11+ RED = gc9a01 .color565 (220 , 50 , 50 )
12+ GREEN = gc9a01 .color565 (50 , 200 , 80 )
13+ ORANGE = gc9a01 .color565 (255 , 150 , 0 )
14+ ORANGE_MED = gc9a01 .color565 (180 , 90 , 0 ) # comete milieu
15+ ORANGE_DIM = gc9a01 .color565 (90 , 45 , 0 ) # comete queue
16+ BLUE = gc9a01 .color565 (0 , 120 , 220 )
17+ GRAY = gc9a01 .color565 (80 , 80 , 80 )
18+ DK_GRAY = gc9a01 .color565 (40 , 40 , 40 )
19+ CYAN = gc9a01 .color565 (0 , 200 , 200 )
1820
1921CENTER_X = 120
2022CENTER_Y = 120
7678}
7779
7880# ------------------------------------------------------------------
79- # Pre-calcul des positions du spinner (evite math.cos/sin en boucle)
81+ # Pre-calcul du cercle anime BOOTING — 12 points en comete
8082# ------------------------------------------------------------------
81- _SR = 28
82- _SEG_LEN = 12
83- _SPIN_SEGS = []
84- for _i in range (8 ):
85- _rad = _i * math .pi / 4.0
86- _x1 = int (CENTER_X + math .cos (_rad ) * _SR )
87- _y1 = int (CENTER_Y + math .sin (_rad ) * _SR )
88- _x2 = int (CENTER_X + math .cos (_rad ) * (_SR + _SEG_LEN ))
89- _y2 = int (CENTER_Y + math .sin (_rad ) * (_SR + _SEG_LEN ))
90- _SPIN_SEGS .append ((
91- min (_x1 , _x2 ), min (_y1 , _y2 ),
92- max (2 , abs (_x2 - _x1 )), max (2 , abs (_y2 - _y1 ))
83+ _N_TICKS = 12
84+ _TICK_R = 75 # rayon des points sur le cercle
85+ _TICK_SIZE = 8 # taille de chaque point (carré)
86+
87+ # Couleurs de la comete : tete → queue (le dernier DK_GRAY efface la queue)
88+ _ARC_COLORS = [ORANGE , ORANGE_MED , ORANGE_DIM , DK_GRAY ]
89+
90+ _TICKS = []
91+ for _i in range (_N_TICKS ):
92+ _a = - math .pi / 2 + _i * 2 * math .pi / _N_TICKS # depart haut, sens horaire
93+ _TICKS .append ((
94+ int (CENTER_X + _TICK_R * math .cos (_a )) - _TICK_SIZE // 2 ,
95+ int (CENTER_Y + _TICK_R * math .sin (_a )) - _TICK_SIZE // 2 ,
96+ _TICK_SIZE , _TICK_SIZE ,
9397 ))
9498
9599# Flags pour eviter le full-redraw a chaque frame d'animation
@@ -164,27 +168,24 @@ def _progress_bar(tft, x, y, w, h, pct, color):
164168# ------------------------------------------------------------------
165169
166170def draw_booting (tft , full = False ):
167- """Spinner orange — full=True force un redraw complet (changement d'etat) ."""
171+ """Cercle anime orange (comete 12 points) — full=True force redraw complet."""
168172 global _spin_frame , _booting_bg_drawn
169- prev_frame = _spin_frame
170- _spin_frame = (_spin_frame + 1 ) % 8
173+ _spin_frame = (_spin_frame + 1 ) % _N_TICKS
171174
172175 if full or not _booting_bg_drawn :
173176 tft .fill (BLACK )
174- _draw_ring (tft , CENTER_X , CENTER_Y , 115 , 8 , ORANGE )
175- _text_center (tft , 'SYSTEM STATUS:' , CENTER_Y - 66 , ORANGE )
176- _text_center (tft , 'STARTING UP' , CENTER_Y - 52 , ORANGE )
177- _text_center (tft , 'BOOT...' , CENTER_Y + 48 , GRAY )
178- for sx , sy , sw , sh in _SPIN_SEGS :
179- tft .fill_rect (sx , sy , sw , sh , DK_GRAY )
177+ _draw_ring (tft , CENTER_X , CENTER_Y , 115 , 4 , ORANGE )
178+ _text_center (tft , 'R2-D2' , CENTER_Y - 12 , ORANGE )
179+ _text_center (tft , 'STARTING UP' , CENTER_Y + 4 , WHITE )
180+ for tx , ty , tw , th in _TICKS :
181+ tft .fill_rect (tx , ty , tw , th , DK_GRAY )
180182 _booting_bg_drawn = True
181- sx , sy , sw , sh = _SPIN_SEGS [_spin_frame ]
182- tft .fill_rect (sx , sy , sw , sh , ORANGE )
183- else :
184- px , py , pw , ph = _SPIN_SEGS [prev_frame ]
185- tft .fill_rect (px , py , pw , ph , DK_GRAY )
186- sx , sy , sw , sh = _SPIN_SEGS [_spin_frame ]
187- tft .fill_rect (sx , sy , sw , sh , ORANGE )
183+
184+ # Mise a jour incrementale — 4 fill_rect par frame
185+ # Le dernier _ARC_COLORS est DK_GRAY => efface automatiquement la queue
186+ for i , col in enumerate (_ARC_COLORS ):
187+ tx , ty , tw , th = _TICKS [(_spin_frame - i ) % _N_TICKS ]
188+ tft .fill_rect (tx , ty , tw , th , col )
188189
189190
190191def draw_locked (tft , full = False ):
@@ -245,7 +246,8 @@ def draw_ok(tft, version, bus_pct=100.0, full=False):
245246 elif color_changed :
246247 # Couleur franchit le seuil 80% : redessiner anneau + label uniquement
247248 _draw_ring (tft , CENTER_X , CENTER_Y , 115 , 4 , bus_color )
248- tft .fill_rect (0 , 106 , 240 , 9 , BLACK )
249+ # y=106 : dy=-14, inner_r=111 → dx≈110 → safe x [10, 230]
250+ tft .fill_rect (10 , 106 , 220 , 9 , BLACK )
249251 _text_center (tft , 'UART BUS HEALTH' , 106 , bus_color )
250252
251253 # Parties dynamiques : toujours mises a jour sans effacer tout l'ecran
@@ -255,7 +257,8 @@ def draw_ok(tft, version, bus_pct=100.0, full=False):
255257 if bus_pct < 80.0 :
256258 _text_center (tft , 'PARASITES DETECTES' , 147 , ORANGE )
257259 elif not full :
258- tft .fill_rect (0 , 147 , 240 , 9 , BLACK ) # efface avertissement si recupere
260+ # y=147 : dy=27, inner_r=111 → dx≈108 → safe x [12, 228]
261+ tft .fill_rect (12 , 147 , 216 , 9 , BLACK ) # efface avertissement si recupere
259262 # NOTE: PAS de reset_animations() ici — draw_ok ne doit pas reset les flags des autres ecrans
260263
261264
0 commit comments