N'Abend,
dann will ich hier mal meine Menüerweiterung für MCURSES (Dank an
der Stelle an Frank M. (ukw)) publik machen:
Im Anhang, seht ihr einmal einen Screenshot in Arbeit. Nicht sonderlich
spektakulär, aber wie ich finde doch sehr praktisch um z.B. ein
umfangreicheres Interface zu realisieren oder Funktionen gezielt
aufzurufen, wenn man sich gerade in ein neues Hardware Modul
einarbeitet.
Zum Code:
In das Projekt müssen nur die beiden Dateien menu.h und menu.c
eingebunden werden, diese sollten komplett unabhängig von der Hardware
laufen. Natürlich muss auch MCurses eingebunden werden ;)
Um ein Menü zu erstellen muss dann ein Array vom Typ menu_entries
erstellt werden. menu_entries setzt sich aus folgenden Elementen
zusammen:
Der Name des Menü-Elements. Kann bei Bedarf natürlich auch in
geändert werden. Da ich Menüeinträge teilweise aber auch dynamisch
erstelle war mir das Hantieren mit malloc irgendwann zu blöd.
1 | int entry_number_of_entries
|
Dieser Wert hat mehrere Funktionen: Wenn der Eintrag im Menü auf ein
Untermenü verweist, müssen hier die Anzahl der Eiträge im Untermenü
angegeben werden. Verweist der Eintrag direkt auf eine Funktion muss
eine 1 angegeben werden. Ist der Wert 0 passiert nichts bei der Auswahl,
war ganz praktisch um Dummy Einträge zu erstellen, als ich die
Scrollfunktion eingebaut habe.
Hier muss der Name der aufzurufenden Funktion angegeben werden. Die
Funktion muss vom Typ void Funktion(void) sein, Parameter werden also
keine Übergeben. Verweist der Menüeintrag auf ein Untermenü muss die
Funktion show_menu angeben werden. Wenn entry_number_of_entries 0 ist,
muss hier nichts eingetragen werden.
1 | struct menu_entries *new_menu_entries
|
Wenn der Eintrag auf ein Untermenü verweist, muss hier auf das
aufzurufende menu_entries Array verwiesen werden.
Hier einmal ein Beispiel für ein solches Array:
1 | menu_entries main_menu[] =
|
2 | {
|
3 | {"Main Menu"},
|
4 | {"LEDs", LEDS_MENU_ENTRIES,show_menu, leds_menu},
|
5 | {"WLAN", init_wlan},
|
6 | {"Speicher", SPEICHER_MENU_ENTRIES, show_menu, speicher_menu},
|
7 | {"Mikrofon", inti_mic}
|
8 | };
|
Achja: Im ersten Eintrag des Arrays braucht nur der text angegeben zu
werden, dies ist dann der Titel des Menüs.
Folgende vier Funktionen werden verwendet:
Aufzurufen, um im Menü einen Eintrag nach oben zu gehen. Ist man schon
im obersten Menüpunkt, wird zum letzten gesprungen.
Wie menu_up() nur eben nach unten. Ganz unten wird auch wieder nach
oben gesprungen.
Der aktuell ausgewählte Menüpunkt wird ausgeführt. Es kann also
entweder ein Untermenü geöffnet werden, eine Funktion aufgerufen werden,
oder es passiert gar nichts.
Diese Funktion ist ganz zu Anfang aufzurufen und gibt das Menü zum
ersten mal aus.
Das #define LAST_ROW ist dafür verantwortlich, bis zu welcher Zeile eine
Menü angezeigt wird. Da MCurses für gewöhnlich 24 Zeilen hat, habe ich
erstmal 23 angegeben, um die unterste Zeile noch für Anzeigen o.Ä. frei
zu lassen.
Die Einbindung im Hauptprogramm kann dann beispielsweise so aussehen:
1 | int main(void)
|
2 | {
|
3 | if (mcurses_is_up){
|
4 | ch = getch ();
|
5 |
|
6 | switch (ch)
|
7 | {
|
8 | case 'm': show_main_menu(); break;
|
9 | case KEY_UP: menu_up(); break;
|
10 | case KEY_DOWN: menu_down(); break;
|
11 | case KEY_CR: case KEY_RIGHT: menu_select(); break;
|
12 | }
|
13 | }
|
14 | }
|
15 |
|
16 | void show_main_menu(void)
|
17 | {
|
18 | current_number_of_entries = MAIN_MENU_ENTRIES;
|
19 | current_menu_entries = main_menu;
|
20 | show_menu();
|
21 | }
|
Sollte soweit selbsterklärend sein, denke ich. Mit einem Druck auf "m"
kommt man erstmals und auch später wieder zurück zum Hauptmenü.
Ich habe das ganze im Augenblick auf einem STM32F407Discovery über USB
und Putty am laufen, und konnte auch nach längerem Testen keine Fehler
mehr finden. Selbstredend ist konstruktive Kritik erwünscht, denn ich
bin mir sicher, dass da noch einiges zu verbessern ist. Etwaige fehlende
Optimierungen bitte ich zu entschuldigen, ich war bis vor kurzen noch
Matlab und nahezu endlose Rechenkapazität gewohnt, da verliert man
irgendwann das Auge dazu ;) Aber unter Anderem auch deswegen
veröffentliche ich es ja auch hier^^
Also, freut mich, falls ich damit jemandem behilflich sein kann, bis
dahin
beste Grüße
Niels