Hi Leute
wollte mich mal mit der Grundstruktur von Menüs beschäftigen. Will die
Schriften im EEPROM ablegen. Das Funktioniert auch super. Aber wie
Realisiert man z.b. am besten hier so ein Menu?
http://www.youtube.com/watch?v=YKGr041Erxg
Peter schrieb:> Hi Leute>> wollte mich mal mit der Grundstruktur von Menüs beschäftigen. Will die> Schriften im EEPROM ablegen. Das Funktioniert auch super. Aber wie> Realisiert man z.b. am besten hier so ein Menu?
:-)
Lustig: Wenn jemand nach 'am Besten' fragt, fragt er meistens nach
"Hilfe, ich hab überhaupt keine Idee wie ich das machen soll".
Mach doch mal ein Brainstorming. Was fällt dir alles zu diesem Thema
ein.
* Da gibt es Menüpunkte
* Jeder Menüpunkt besteht aus einem Text
* Wird der Menüpunkt ausgewählt, dann soll er eine Aktion auslösen.
* Es kann mehr Menüpunkte geben, als das Display Anzeigezeilen hat.
* Menüpunkte haben eine bestimmte Reihenfolge in der sie angezeigt
werden.
* Um ein Menü zu bedienen, braucht es Eingabeelemente.
Damit muss es möglich sein, diese Operationen auszulösen:
einen Menüpunkt vorwärts
einen Menüpunkt rückwärts
Menüpunkt auswählen
* Es wäre gut, wenn der Benutzer sieht welches der gerade 'aktive'
Menüpunkt ist. Das ist der, der eine Aktion auslöst, wenn er
das entsprechende Eingabeelement betätigt.
* Das heißt aber auch, es gibt so etwas wie einen 'aktiven' Menüpunkt.
* Wie signalisiert eigentlich der Benutzer einen Abbruch des jeweiligen
Menüs als ganzes?
Was fällt dir zu dem Thema sonst noch ein?
Jetzt muss eine Frage geklärt werden: Wie soll das Menü eine Aktion
auslösen? Soll das Menü zb selbsttätig bei entsprechender Auswahl eine
Funktion aufrufen? Oder reicht es, wenn die Menüsteuerung den
entsprechend angewählten Menüpunkt zb in Form einer Nummer
zurückliefert?
So gehts los:
Ehe man die erste Codezeile schreibt, überlegt man sich erst einmal, was
man da überhaupt machen will. Welche Eigenschaften soll es haben, was
weiß ich alles darüber.
Hat man den Punkt erledigt, könnte man zb auf die Idee kommen, dass ein
Menü programmintern nichts anderes als ein Array von Menüpunkten
darstellt. Damit wäre zb das Reihenfolgeproblem schon gelöst. Durch das
Array ist die gegeben. Da das Array größer als die Anzeigeeinheit sein
kann, wird man wahrscheinlich eine Funktion benötigen, die nur einen
Ausschnitt aus dem Array auf dem LCD anzeigt. Das heißt aber auch: man
wird einen Mechanismus benötigen, der zb darüber Buch führt, welches der
gerade oberste angezeigte Menüpunkt ist. SCrollt der Benutzer unten um
1 Zeile raus, dann wandert diese oberste angezeigte Zeile eben um 1 nach
unten und die Anzeigereoutine stellt dann einen anderen Ausschnitt aus
dem Array dar: nämlich so, dass das Menü um 1 Zeile gescrollt ist.
Damit wissen wir schon, dass so ein Menü aus diesen Bestandteilen
bestehen wird:
Menüpunkte
aktiver Menüpunkt
oberster angezeigter Menüpunkt
Und so führt eines zum anderen. Irgendwann wird man seine Überlegungen
als zunächst abgeschlossen erklären und mal mit einer Implementierung
anfangen, wobei dann meistens immer noch fehlende Details auftauchen
werden. Aber da man im Großen und Ganzen weiß, wo die Reise hingehen
soll, sind die dann eher kein Problem mehr.
zb
1
structMenuPoint
2
{
3
chardisplayText[40];
4
};
5
6
structMenu
7
{
8
MenuPoint*items;
9
uint8_tactiveItem;
10
uint8_tfirstVisibleItem;
11
};
12
13
structMenuPoint[]testMenuPoints=
14
{
15
"1. Eintrag",
16
"2. Eintrag",
17
"3. Eintrag"
18
};
19
20
structMenutestMenu={testMenuPoints,0,0};
21
22
voidShowMenu(structMenu*theMenu)
23
{
24
// zeige die ersten n Menüeinträge aus dem Menü an
25
// (falls sie existieren)
26
// und zwar beginnend mit theMenu->firstVisibleItem
27
...
28
}
29
30
uint8_tprocessMenu(structMenu*theMenu)
31
{
32
// am Anfang ist der 1. Eintrag der aktive
33
// und das Menu wird auch so angezeigt, dass der
34
// ganz oben ist
35
theMenu->activeItem=0;
36
theMenu->firstVisibleItem=0;
37
38
ShowMenu(theMenu);
39
40
while(...
41
42
....
43
44
returntheMenu->activeItem;
45
}
Und nein. Wenn man mit sowas anfängt, fängt man NICHT damit an sich zu
überlegen, ob die Texte nun im SRAM, im EEPROM oder im Flash liegen. Bei
einer guten Grundstruktur kann man die im Nachhinein immer noch in den
Speicher verschieben, in dem man sie haben möchte. Erst mal muss das
Grundgerüst stehen und funktionieren ohne sich in derartigen Details zu
verzetteln.
@ Peter (Gast)
>wollte mich mal mit der Grundstruktur von Menüs beschäftigen. Will die>Schriften im EEPROM ablegen.
Sowas packt man eher ins Flash, denn die meisten Texte/Daten sind
konstant.
Peter schrieb:> Hi Leute>> wollte mich mal mit der Grundstruktur von Menüs beschäftigen. Will die> Schriften im EEPROM ablegen. Das Funktioniert auch super. Aber wie> Realisiert man z.b. am besten hier so ein Menu?>> http://www.youtube.com/watch?v=YKGr041Erxg
Nennt sich "Programmieren", versuchs doch auch mal.
Also Grundidee steht ja. Steuerung soll aus 4 Tastern (hoch runter, ins
menu und aus dem menu) bestehen, oder einem Drehgeber mit Taster (links
rechts kurzer-langer Tasterdruck.
1
charmenutext[18][11]={
2
3
"1.0.0 Test",//0 Ebene 1
4
"2.0.0 Test",//1 Ebene 1
5
"3.0.0 Test",//2 Ebene 1
6
"1.1.0 Test",//3 Ebene 2
7
"1.2.0 Test",//4 Ebene 2
8
"1.3.0 Test",//5 Ebene 2
9
"1.3.1 Test",//6 Ebene 3
10
"1.3.2 Test",//7 Ebene 3
11
"1.3.3 Test",//8 Ebene 3
12
"2.1.0 Test",//9 Ebene 2
13
"2.2.0 Test",//10 Ebene 2
14
"2.3.0 Test",//11 Ebene 2
15
"3.1.0 Test",//12 Ebene 2
16
"3.2.0 Test",//13 Ebene 2
17
"3.3.0 Test",//14 Ebene 2
18
"2.1.0 Test",//15 Ebene 2
19
"2.2.0 Test",//16 Ebene 2
20
"2.3.0 Test"//17 Ebene 2
21
};
Hab leider im mom nur ein 2 Zeilen Display zum Testen. Wie bekomm ich
jetzt am besten die 3 Ebenen aufgerufen inklusive anwahl?
Wobei in diesem Fall "doppelt verkette Liste" auch so aussehen kann,
dass man sich bei jedem Menüpunkt vermerkt, welcher andere Menüpunkt der
'Nachfolger' bei einer bestimmten Aktion ist.
D.h. zb beim Punkt 0 steht dabei
wenn Benutzer 'Links' macht, kommt er zum Menüpunkt 2
wenn Benutzer 'Rechts' macht, kommt er zum Menüpunkt 1
wenn Benutzer 'Runter' macht, kommt er zum Menüpunkt 3
wenn Benutzer 'Rauf' macht, passiert gar nichts
also
{
{ "1.0.0 Test", 2, 1, 3, -1 },
...
Und dazu nimmt man sinnvollerweise (wie Falk schon sagte) eine struct
die EINEN Menüpunkt beschreibt und macht dann ein Array von
Menuepunkten.
Steinigt mich ruhig, weil ich den Thread wieder ausgrabe. Leider hat
sich bislang niemand bei Karl Heinz für seine Bemühungen diese tolle
Erklärung zu verfassen bedankt.
Daher nochmal von mir ein ganz großes Dankeschön dafür!!
Leider melden sich hier in diesem Forum viel zu häufig irgendwelche
Klugscheißer mit negativen Kommentaren zu Rechtschreibung oder
mangelnder Fachkompetenz zu Wort. Aber das ist ja längst Tradition.
Anke schrieb:> Leider melden sich hier in diesem Forum viel zu häufig irgendwelche> Klugscheißer mit negativen Kommentaren zu Rechtschreibung oder> mangelnder Fachkompetenz zu Wort.
Die manchmal etwas bissigen Kommentare drücken wohl eher eine Kritik an
der Grundeinstellung mancher Frager aus, die sich nicht einmal die Mühe
machen, ihr Problem strukturiert und in halbwegs vernünftiger
Schriftsprache zu formulieren oder vorher eigenständig ein bisschen in
den diversen Tutorials und Grundlagenartikeln zu recherchieren.
Sorry, habe ich hier einen "Hmm" beleidigt, der noch gar nicht
aufgetreten ist?
Bist du von der Volksfront von Judäa? Oder einer von der Kampagne für
ein freies Galiläa? Oder gar einer der Spalter von der judäischen
Volksfront?
Und vor allem: Geht es hier zur Steinigung?
Karl Heinz schrieb:> struct Menuepunkt> {> char Text[11];> int8_t Links;> int8_t Rechts;> int8_t Runter;> int8_t Rauf;> };>> struct Menuepunkt Menu[] => {>> { "1.0.0 Test", 2, 1, 3, -1 },> { ...>> };
Hallo zusammen, entschuldigt, dass ich diesen alten aber in meinen Augen
sehr wichtigen Thread ausgrabe, aber ich habe zu diesem Thema eine Frage
und ich wollte jetzt nicht einen neuen Thread aufmachen.
Und zwar hab ich meine Menüstruktur genau so aufgebaut aber ich frage
mich wie verwende ich jetzt in meinem Programm die int8_t werte (rauf,
runter, etc.)
finde leider keinen kompletten Code den ich mir mal anschauen könnte, um
zu verstehen wie die Logik hinter diesem struct und deren weiteren
Verwendung aussieht..
Vllt. könnte sich ja jemand erbarmen und mir sagen wie ich diese
erstellte Menüstruktur sinnvoll verwenden kann..
Katze D. schrieb:
ganz einfach. In 'links' 'rechts' 'rauf' 'runter' steht jeweils die
Nummer des Menu-Eintrags, der als aktiver Menüeintrag gilt, wenn die
entsprechende Taste gedrückt wird. (und es dann auch einen entsprechend
auszuwählenden Menüpunkt gibt)
wenn der Menüpunkt gewechselt wird, wird man natürlich dann auch noch
den neuen aktiven Menüpunkt irgendwo anzeigen oder, wenn er schon mit
seinen restlichen Menü-Kollegen an der Anzeige ist, irgendwie markieren.
Aus dem Original:
1
// links rechts runter rauf
2
"1.0.0 Test", 2, 1, 3, -1 //0 Ebene 1
3
"2.0.0 Test", 0, 2, 9, -1 //1 Ebene 1
4
"3.0.0 Test", 1, 0, 12, -1 //2 Ebene 1
5
"1.1.0 Test", 5, 4, -1, 0 //3 Ebene 2
6
"1.2.0 Test", 3, 5, -1, 0 //4 Ebene 2
7
"1.3.0 Test", 4, 3, 6, 0 //5 Ebene 2
8
"1.3.1 Test", ............... //6 Ebene 3
9
"1.3.2 Test", ............... //7 Ebene 3
Ist der Menüpunkt "1.0.0" aktiv und drückt der Benutzer auf 'rechts',
dann ist laut
1
// links rechts runter rauf
2
"1.0.0 Test", 2, 1, 3, -1 //0 Ebene 1
damit der Menüpunkt mit dem Index 1 der nächste aktive. Das ist dieser
hier
1
"2.0.0 Test", 0, 2, 9, -1 //1 Ebene 1
Drückt der Benutzer jetzt auf 'runter', dann aktiviert er damit den
Menüpunkt mit dem Index 9, welcher dieser hier ist
1
"2.1.0 Test", ......... //9 Ebene 2
was ja auch stimmt. Denn er hat ja den Punkt 2.0.0 sozusagen geöffnet
und ist dadurch zu 2.1.0 'eingestiegen'. In diesem Menüpunkt würde es
beim drücken von 'rauf' wieder zurückgehen zum Menüpunkt wo er
hergekommen ist, also zum Punkkt "2.0.0.". Daher wird bei "2.1.0" bei
rauf dann die 1 als zu aktivierender Menüpunkt eingetragen sein.
...ahhh.... so langsam dämmert es...mhhh.. muss das noch irgendwie
sortieren aber ich denke deine Hilfe (der Chef persönlich hat
geantwortet :) ) hat mir die Logik hinter diesem Menüaufbau näher
gebracht, danke!
LG
Katze D. schrieb:> ...ahhh.... so langsam dämmert es...mhhh.. muss das noch irgendwie> sortieren
am einfachsten mit Papier und Bleistift aufmalen
von welchem menüpunkt soll es beim drücken welcher Taste zu welch
anderem Menüpunkt gehen
1
L ... Taste 'links'
2
R ... Taste 'rechts'
3
U ... Taste 'rauf' (up)
4
D ... Taste 'runter (down)
5
6
"Run" R ----> "Options" R -----> "Explode"
7
<---- L <----- L
8
D ^ D ^
9
| | | |
10
| | v U
11
| |
12
| | "Color" R -----> "Time"
13
| | <----- L
14
| |
15
v U
16
"Stop"
Dieses Diagreamm beschreibt die Logik im Menü. Aus ihm ersieht man, in
welchem Menüpunkt man landen soll wenn die entsprechende Taste gedrückt
wird. Das kann natürlich auch kreuz und quer sein. Wenn man im Punkt
"Time" auf Up drückt (rauf), dann will man wieder bei "Options" landen.
Aber mit ASCII kann ich so schlecht schräge Linien zeichnen :-)
Dann nummerierst du die Punkte in beliebiger Reihenfolge durch
1
0: "Run" R ----> 1: "Options" R -----> 2: "Explode"
2
<---- L <----- L
3
D ^ D ^
4
| | | |
5
| | v U
6
| |
7
| | 3: "Color" R -----> 4: "Time"
8
| | <----- L
9
| |
10
v U
11
5: "Stop"
und trägst das was du im Diagramm siehst in die Datenstruktur ein
:) Hehe danke für den Tipp mit dem aufzeichnen... war zufälligerweise
gerade dabei mit Word und SmartArts mir die Menüstruktur "aufzumalen"
finde das hilft ungemein..
Und danke für die Mühe mit der Veranschaulichung der Menüstruktur!
Hatte schon Angst, wenn ich bei dem Thema nachhake, einen Rüffel zu
bekommen. :)
Würde deinen Beiträgen 5* geben, wenn man das hier könnte und über:
"
> Lustig: Wenn jemand nach 'am Besten' fragt, fragt er meistens nach> "Hilfe, ich hab überhaupt keine Idee wie ich das machen soll".
"
musste ich sehr lachen. daumenHoch
Hallo nochmal,
ich hätte noch eine kleine Frage, wenn ich die Struktur auslagern will,
dass heißt ich würde gerne das Struct und die Variablen in eine .h Datei
auslagern wäre das der korrekte Weg? Also, müsste ich alles in die z.B.
LCD.h Datei packen oder müsste noch was davon in die LCD.c?
Ich denke an der Frage erkennt man schon, dass ich noch nicht ganz die
grundlegende Struktur kenne und mir bei dem Thema noch recht unsicher
bin.
Gruß
KatzE
/EDIT
zur Verdeutlichung:
das würde ich jetzt in meine LCD.h schreiben:
1
voidmenu_punkt(uint16_tADC_READ_IN);
2
3
voidpunkt1(void);
4
5
voidpunkt1.1(void);
6
7
voidpunkt1.2(void);
8
9
usw...
10
11
12
staticconstcharMenue_E1[]="punkt1 ";//0
13
staticconstcharMenue_E2[]="punkt2";//1
14
staticconstcharMenue_E1_1[]="punkt1.1";//2
15
staticconstcharMenue_E1_2[]="punkt1.2 ";//3
16
staticconstcharMenue_E1_1_1[]="punkt1.1.1 ";//4
17
usw....
18
19
20
21
//Struktur festlegen
22
typedefstructMenu{
23
constunsignedchar*text;
24
int8_thoch;
25
int8_trunter;
26
int8_trechts;
27
int8_tlinks;
28
void(*fp)(void);
29
30
}MENU_ENTRY;
31
32
33
34
//Menü einträge plus Nachtbarn auflisten
35
constMENU_ENTRYmenue[]={
36
{Menue_E1,9,9,1,-1},//0
37
{Menue_E1_1,5,5,2,0,},//1
38
{Menue_E1_1_1,4,3,-1,1,blabla},//2
39
{Menue_E1_1_2,2,4,-1,1,blalba},//3
40
{Menue_E1_1_3,3,2,-1,1,bla},//4
41
42
usw...
43
44
};
würde das alles so in die lcd.h datei kommen? Bin ich da auf dem
richtigen Weg?