Come gestire la messa a fuoco per una piccola serie di semplici widget

2

Sto sviluppando una serie di semplici widget per un piccolo display (128x128).

Ad esempio mi piacerebbe avere una schermata principale con un menu di sovrapposizione che posso usare per attivare la visibilità degli elementi della schermata principale. Ogni opzione sarebbe un'icona con un riquadro attorno mentre è selezionata. Gli eventi Button (sinistra, su, destra, giù, invio) dovrebbero essere assegnati al widget che ha "focus".

La messa a fuoco è una cosa semplice da capire quando utilizza una GUI, ma ho problemi ad implementarlo. Puoi suggerire un concetto semplice per gestire l'attenzione e inserire gli eventi? Ho queste idee semplici:

  • Solo un widget può avere lo stato attivo, quindi ho bisogno di un singolo puntatore per quel widget.
  • Quando questo widget riceve una sorta di input "ciclo" (come in "evidenzia l'elemento successivo in questo elenco"), l'attenzione viene assegnata a un altro widget.
  • un widget deve avere un modo di dire all'applicazione quale widget viene messo a fuoco al prossimo.
  • se un widget non può fornire un suggerimento sul "prossimo fuoco", l'applicazione deve essere in grado di capire dove dovrebbe andare l'attenzione.

I widget sono attualmente strutturati in questo modo:

  • Un widget può avere un genitore, che viene passato al costruttore. I widget vengono creati staticamente, poiché voglio evitare l'allocazione dinamica della memoria (ho solo 16kB di RAM e mi piacerebbe avere il controllo su quello).
  • I widget
  • hanno fratelli, implementati come un elenco collegato intrusivo (hanno un membro next ). Un genitore ha un puntatore alla testa del suo elenco di bambini.

Gli eventi di input sono argomenti ai metodi di buttonEvent dei widget che possono accettare o ignorare quell'evento. Se ignora l'evento, può passare l'evento al suo genitore.

Le mie domande:

  1. Come posso gestire l'attivazione di questi widget?
  2. Sto rendendo questo troppo complicato?
posta Christoph 20.02.2014 - 01:01
fonte

3 risposte

1

Penso che tu stia rendendo il problema più complicato di quello che è. Creare una matrice per contenere un riferimento a ciascun widget. Aggiungi i widget alla matrice nell'ordine in cui sono stati creati. Il prossimo widget per mettere a fuoco è solo il prossimo widget nella lista che è focalizzabile.

Puoi quindi aggiungere funzioni per aumentare e diminuire l'ordine relativo dei widget per quando vuoi attraversarli in un ordine diverso da quello in cui sono stati creati.

Se vuoi essere elegante, dai a ciascun widget un metodo "canAcceptFocus", quindi spostare lo stato attivo significa andare in loop sui widget, chiamando il metodo finché uno di essi non restituisce true. In questo modo un widget può decidere da solo se deve essere focalizzato (come restituire False se il proprio stato è disabilitato, o se è solo un semplice widget etichetta, ecc.). Non deve sapere di altri widget, deve solo sapere se esso può essere focalizzato o meno.

    
risposta data 05.05.2014 - 21:13
fonte
0

Ho implementato un sistema come questo in passato e il tuo design è molto simile al mio. Una gerarchia di widget (i widget possono contenere widget figlio), i widget figlio sanno chi sono i loro genitori, c'è un solo widget globalmente focalizzato in qualsiasi momento e deve essere un widget foglia (nessun figlio).

La differenza nel mio design era che era possibile specificare quali widget sarebbero stati messi a fuoco popolando ogni widget con una mappa ad altri fratelli.

Ad esempio. Il mio input consentiva su, giù, sinistra e destra, quindi ogni widget aveva fino a 4 fratelli mappati a ciascuno di questi comandi. Il widget A potrebbe avere un "fratello giusto" che era il Widget B e il Widget B poteva avere un "fratello sinistro" che era il Widget A. Qualsiasi comando emesso controllerebbe il fratello del widget attualmente attivo per quel comando. Se non esisteva, la messa a fuoco non cambiava. Se la mappatura di pari livello esiste, lo stato attivo è stato modificato.

Se questo si rivela troppo costoso per te, puoi memorizzare i mapping di pari livello nei genitori in qualche modo.

    
risposta data 20.02.2014 - 01:44
fonte
0

Ecco quello che ho adesso, e penso che non sia eccessivamente ingegnerizzato e faccia il suo compito di gestione della focalizzazione (cioè quale widget ottiene i miei eventi con il pulsante?)

  • Ho una classe widget astratta che mantiene un puntatore statico a un widget astratto, focus_ .
  • Un widget ha una proprietà protetta, acceptsFocus_ che viene utilizzata per abilitare l'attivazione per quel widget (o meno). Questa è più o meno una proprietà costante, credo.
  • L'attenzione può essere data a un widget con un metodo pubblico. Se non accetta la messa a fuoco, la messa a fuoco viene passata al widget genitore (che a sua volta può accettare o meno la messa a fuoco, si ottiene l'idea). Questo imposta lo statico focus_ in modo che punti al primo widget che l'ha accettato.
  • Quando un widget è costruito, diventa focalizzato. Questo potrebbe non essere necessario, ma ho pensato che potrebbe essere utile nel caso in cui dimenticassi di mettere a fuoco alcuni widget quando l'intera app è inizializzata. D'altra parte, potrei finire per chiedermi perché succede qualcosa di inaspettato quando preme un pulsante.

Se non rovino completamente le cose, questo assicura che gli eventi del pulsante finiscano per essere gestiti da qualcosa.

    
risposta data 06.03.2014 - 11:58
fonte

Leggi altre domande sui tag