Gestion logique de l'interface utilisateur Brick. Plus de détails...
#include "ui_controller.h"
#include "ui_backend.h"
#include "ui_spec.h"
#include <string.h>
#include <stdbool.h>
#include "ui_led_backend.h"
#include "ui_keyboard_ui.h"
#include "seq_led_bridge.h"
#include "ui_overlay.h"
Structures de données | |
struct | ui_cycle_t |
Structure interne représentant un cycle BM (bouton menu cyclant). Plus de détails... | |
Fonctions | |
void | ui_mark_dirty (void) |
bool | ui_is_dirty (void) |
void | ui_clear_dirty (void) |
void | ui_init (const ui_cart_spec_t *spec) |
Initialise la couche UI avec la spécification fournie. | |
void | ui_switch_cart (const ui_cart_spec_t *spec) |
Changement de cartouche (reload complet de la spécification). | |
const ui_state_t * | ui_get_state (void) |
const ui_cart_spec_t * | ui_get_cart (void) |
const ui_menu_spec_t * | ui_resolve_menu (uint8_t bm_index) |
void | ui_on_button_menu (int index) |
Gestion des boutons MENU (BM1..BM8). | |
void | ui_on_button_page (int index) |
Gestion des boutons PAGE (1..5). | |
void | ui_on_encoder (int enc_index, int delta) |
Gestion des encodeurs rotatifs (édition de paramètre). | |
Gestion logique de l'interface utilisateur Brick.
Logique centrale de l’UI Brick : menus, pages, encodeurs + cycles BM.
*
Traduit les entrées (boutons, encodeurs) en modifications d'état UI
Valeur
NULLpar défaut — les specs existantes restent **compatibles**.
overlay_tag
, le renderer utilise ui_backend_get_mode_label()
(dernière valeur gérée par le backend, par défaut « SEQ » au démarrage).ui_renderer.c
)*).drv_display
/primitives.Statut de la phase :
ui_shortcuts.c
: Couche de mapping pure (évènement → ui_shortcut_action_t
), sans effets secondaires.ui_backend.c
: Conserve le contexte ui_mode_context_t
, applique les actions (mute, overlays, transport) et publie les tags.ui_task.c
: Simplifié — délègue désormais tous les événements à ui_backend_process_input()
et se concentre sur le rendu.ui_overlay.c
: Conserve la logique d’ouverture/fermeture et de bannière, appelée depuis le backend.ui_controller.c
/ ui_model.c
: Inchangés, découplés et stables.ui_renderer.c
: Rendu prioritaire par overlay_tag
> model_tag
, permettant un affichage correct des états MUTE/PMUTE.cart_registry.c
: Sert de registre déclaratif de specs pour les “apps custom” (SEQ, ARP, FX, etc.).✅ Architecture validée sans dépendance circulaire.
📦 Prochaine étape : création des futures UIs custom (
ui_fx_ui
, ui_drum_ui
, etc.) sur le modèle SEQ/ARP.
ui_led_seq
reste mis à jour uniquement via ui_led_backend
(aucune dépendance à clock_manager
dans le renderer). (UIs custom + LEDs adressables)Ajouts Phase 6½ (runtime Keyboard)
apps/ui_keyboard_app.c/.h
: moteur notes/accords (inversions/extensions inspirées Orchid), API claire (`_note_on/off,
*_chord_on/off,
*_all_notes_off). -
apps/kbd_chords_dict.c/.h: dictionnaire d’accords (intervalles relatifs root) + utilitaires de transposition par *Gamme/Root*. -
apps/kbd_input_mapper.c/.h: mapping
SEQ1..16→ actions note/accord + détection de combinaisons **Chord+Note** (ordre libre). -
apps/ui_keyboard_bridge.c/.h: lecture **shadow UI** (Root/Gamme/Omni) → app+mapper+LEDs ; **émission directe** via
ui_backend_note_on/off(). -
ui/ui_backend.c: ajout **shadow UI** (espace
UI_DEST_UI) + APIs **NoteOn/Off/AllOff** + PANIC via **CC#123** ; routage
MIDI_DEST_BOTH, canal par défaut **0**. -
ui/ui_task.c: latence entrée **réduite** (poll 2 ms, priorité **NORMALPRIO**, yield 1 ms), synchro **à chaque itération** vers le bridge ; routing **SEQ1..16** vers
kbd_input_mapper_process(...)`.Cette section récapitule les ajouts réalisés en Phase 6, sans modifier l’architecture de la Phase 5.
ui/led/
ui_led_backend.c/.h
: observateur passif de l’UI (aucune logique LED dans ui_task
/ ui_controller
/ ui_shortcuts
). Pilote drv_leds_addr
(format GRB).ui_led_palette.h
: palette centralisée des couleurs (C1..C4, REC, Playhead, Keyboard/Omnichord).ui_led_seq.c/.h
: renderer SEQ (playhead absolu, pages, priorités d’état, sans dépendre de clock_manager
).ui/seq/
seq_led_bridge.c/.h
: pont SEQ ↔ renderer (pages, P-Lock mask, publication snapshot, total_span pages×16
) adossé au seq_model_pattern_t
partagé.ui/customs/
ui_keyboard_ui.c/.h
: vitrine UI KEYBOARD (menu unique Mode avec 4 paramètres : Gamme, Root, Arp On/Off, Omnichord On/Off).apps/
ui_keyboard_app.c/.h
, kbd_chords_dict.c/.h
, kbd_input_mapper.c/.h
, ui_keyboard_bridge.c/.h
: app Keyboard (runtime), dictionnaire d’accords, mapper SEQ→actions, bridge UI↔app↔backend."KEY"
apparaît à droite (comme "SEQ"
/ "ARP"
).SHIFT+SEQx
ne s’active).pages × 16
), sans auto-changer la page visible. +
/−
(sans SHIFT) changent la page visible ; SHIFT + (+/−)
= MUTE/PMUTE (prioritaire). seq_led_bridge_set_max_pages(N)
.ui_controller.c
, un hook met à jour instantanément le rendu LEDs lorsque le paramètre Omnichord (Off/On) de la vitrine Keyboard change : ui_led_backend_set_mode(UI_LED_MODE_KEYBOARD);
ui_led_backend_set_keyboard_omnichord(on_off);
ui/led/
→ ui_led_backend.*
, ui_led_palette.h
ui/customs/
→ ui_keyboard_ui.*
ℹ️ L’**ordre d’initialisation** reste identique ; la boucle principale continue d’appeler
drv_leds_addr_render()
pour rafraîchir les LEDs.ui_led_backend
ne bloque pas le flux principal.
Depuis 2025‑10 : capture des boutons PLUS/MINUS pour piloter l’**octave shift** lorsque KEY est le contexte actif (overlay visible ou non) ; mise à jour du label bandeau en conséquence.
ui/customs/
→ ui_keyboard_ui.*
(menus Keyboard, page 2)apps/
→ ui_keyboard_app.*
, kbd_input_mapper.*
, kbd_chords_dict.*
ui/
→ ui_shortcuts.*
(mapping neutre → actions), ui_backend.*
(contexte UI + effets secondaires)Les vérifications rapides à lancer avant une PR :
make
— compilation firmware complète (nécessite le dépôt ChibiOS ../../chibios2111
).make lint-cppcheck
— analyse statique (cppcheck
) des dossiers core/
et ui/
.make check-host
— exécute les tests hôtes (modèle SEQ, bridge hold/runtime, transitions UI, edge-cases), la régression ui_track_pmute_regression_tests
(overlay Track + QUICK/PMute) via stubs LED/flash et les garde-fous quick-step / live capture (note fantôme) dans seq_hold_runtime_tests
.ui_backend_param_changed()
.ui_led_backend_*
.Architecture :
clock_manager
).ui_cart_spec_t
.void ui_clear_dirty | ( | void | ) |
const ui_cart_spec_t * ui_get_cart | ( | void | ) |
const ui_state_t * ui_get_state | ( | void | ) |
void ui_init | ( | const ui_cart_spec_t * | spec | ) |
Initialise la couche UI avec la spécification fournie.
bool ui_is_dirty | ( | void | ) |
void ui_mark_dirty | ( | void | ) |
void ui_on_button_menu | ( | int | index | ) |
Gestion des boutons MENU (BM1..BM8).
void ui_on_button_page | ( | int | index | ) |
Gestion des boutons PAGE (1..5).
void ui_on_encoder | ( | int | enc_index, |
int | delta | ||
) |
Gestion des encodeurs rotatifs (édition de paramètre).
Hooks LED :
KBD_OMNICHORD_ID
, alors :UI_LED_MODE_KEYBOARD
.ui_led_backend_set_keyboard_omnichord()
. const ui_menu_spec_t * ui_resolve_menu | ( | uint8_t | bm_index | ) |
void ui_switch_cart | ( | const ui_cart_spec_t * | spec | ) |
Changement de cartouche (reload complet de la spécification).