Hallo zusammen,
es geht wie in so vielen anderen Beiträgen hier mal wieder um ein Menü.
Allerdings hat mich bisher kein anderer Beitrag hier wirklich weiter
gebracht. Deshalb habe ich nun etwas eigenes ausgedacht, was meine
Anforderungen erfüllt.
Ich möchte nämlich auf keinen Fall in irgendwelche undefinierten
Zustände (Arraygrenzen etc.) laufen, und möglichst komfortabel die
Menüstruktur einpflegen können.
Dazu ist mir folgendes eingefallen: Ein Menüpunkt als Struct
beschreiben, ihm einen Namen zur Anzeige geben, die Nachbarn auf
gleicher Menü-Ebene sowie in der darüber und darunter über Zeiger
vermerken, Reaktionen auf jeweilige Eingabe über Funktionszeiger.
Das Struct dazu sieht folgendermaßen aus:
1 | typedef const struct MENU_ITEM {
|
2 | const char *name;
|
3 | const struct MENU_ITEM *up, *down, *left, *right;
|
4 | void(*f_up)(const struct MENU_ITEM**), (*f_down)(const struct MENU_ITEM**),
|
5 | (*f_left)(const struct MENU_ITEM**), (*f_right)(const struct MENU_ITEM**);
|
6 | }menu_item_t;
|
Eine Beispielinitalisierung sähe dann so aus:
1 | menu_item_t menu01 = {"Motor", &menu03, &menu02, NULL, NULL, std_up, std_down, std_left, show_motor_value};
|
Dabei sind die 'std_'-Funktionen als Standard vordefiniert und
verschieben sich (den Pointer) quasi selbst auf eine andere Menü-Ebene.
Das sähe dann wie folgt aus:
1 | void std_up(menu_item_t** self) {
|
2 | if((*self)->up) (*self) = (*self)->up;
|
3 | return;
|
4 | }
|
Der Vorteil ist, dass auch auf der untersten Menü-Ebene - wo wirklich
was gemacht und nicht nur navigiert werden soll - die Funktionspointer
sehr einfach zu setzen sind, und dann die Aktionen ausgeführt werden.
Außerdem erachte ich es als Vorteil einfach die 'std_'-Funktionen als
default hinzuschreiben, und wenn kein Nachbar existier (NULL), dann
stürzt auch nichts ab.
Damit finde ich die Menü-Einprogrammierung recht komfortabel.
Um das ganze vielleicht noch einmal ein bisschen klarer zu mache, hänge
ich nochmal ein kleines Beispielprojekt an.
Nun zu meinen Fragen: Ist das vom Programmierstil her halbwegs in
Ordnung? Sollte man irgendwas komplett anders machen? Andere Ideen?
Ach ja, wenn ich das Programm dann auf den AVR portiere, wo es
eigentlich laufen soll, würde ich die Menü-Struktur natürlich mit PROMEM
ins Flasch verfrachten.
Danke schonmal für Tipps und Anregungen,
eFPeGeA