INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Pulldown-Menü für UTFT
06.09.2015, 17:56 (Dieser Beitrag wurde zuletzt bearbeitet: 07.09.2015 00:32 von rkuehle.)
Beitrag #1
Pulldown-Menü für UTFT
Hallo Forum,
als "Nebenprodukt" hier mal ein Code für ein einfaches Pulldown-Menü auf UTFT-Displays.
Aktuell ist es auf das Hauptmenü mit jeweils einem Untermenü pro Hauptmenüpunkt begrenzt.
Ich habe es so geschrieben, dass man sich nicht um irgendwelche Koordinaten der Menüitems kümmern muss
(wird über den gewählten Font und die Beschriftung der Items berechnet).
Durch die Kommentare sollte eigentlich alles erklärt sein.
Werde es um verschachtelte Untermenüs erweitern und dann reinstellen.
Grüße Ricardo
Code:
#include <UTFT.h>
#include <UTouch.h>
extern uint8_t BigFont[];                  // Font
// Menükonstanten
const int icount=13;                       // Gesamtanzahl Menüitems
const int menu_start_x=10;                 // x - Koordinate Start des Menüs
const int menu_start_y=10;                 // y - Koordinate Start des Menüs
const word back_color=VGA_SILVER;          // Menüfarbe
const word text_color=VGA_BLUE;            // Menütextfarbe

struct Items                               // Struct für Speicherung der Daten der Items
{                                          // mit * gekennzeichnete Werte werden berechnet
  int v;                                   // vertikaler Abschnitt des Items
  int h;                                   // horizontaler Abschnitt des Items
  String  d;                               // Beschriftung des Items
  int     p_x_start;                       // x - Koordinate Start des Items *
  int     p_x_end;                         // x - Koordinate Ende des Items  *
  int     p_y_start;                       // y - Koordinate Start des Items *
  int     p_y_end;                         // y - Koordinate Ende des Items  *
};
Items rec[icount];                         // Struct - Array anlegen
// Display und Touch erstellen
UTFT myGLCD(CTE70, 38, 39, 40, 41);
UTouch myTouch(6, 5, 4, 3, 2);
int tx,ty;                                 // Touchkoordinaten
boolean sub_isactive=false;
void setup()
{
  // Display und Touch initialisieren
  myGLCD.InitLCD();
  myGLCD.clrScr();
  myTouch.InitTouch();
  myGLCD.setFont(BigFont);
  // Items brauchen nicht geordnet addiert werden
  addItem(0,0,"Datei");                   // Haptmenüitems - 0,0 - Wurzelitem
  addItem(0,1,"Bearbeiten");
  addItem(0,2,"Sketch");
  addItem(1,0,"Neu");                     // Untermü Datei
  addItem(2,0,"Oeffnen");
  addItem(3,0,"Schliessen");
  addItem(4,0,"Speichern unter");
  addItem(5,0,"Beenden");
  addItem(1,1,"Ausschneiden");            // Untermenü Bearbeiten
  addItem(2,1,"Kopieren");
  addItem(3,1,"Einfuegen");
  addItem(1,2,"Sketchordner anzeigen");   // Untermenü Sketch
  addItem(2,2,"Datei hinzufuegen");
  // Koordinaten der Items einmalig berechnen
  calcItems();
  // Hauptmenü darstellen
  drawMainMenu();
}
void loop()
{
  if (myTouch.dataAvailable() == true)    // Abfrage auf Touch
  {
    myTouch.read();
    tx = myTouch.getX();
    ty = myTouch.getY();
    for (int i=0;i<icount;i++)
    {
      // ... Koordinaten abfragen
      if (tx>=rec[i].p_x_start && tx <=rec[i].p_x_end && ty>=rec[i].p_y_start && ty<=rec[i].p_y_end)
      {
        if (rec[i].v==0)                  // Wenn Hauptmenü (v==0)
        {
          drawMainMenu();
          drawSubMenu(rec[i].h);          //... dann zugehöriges Untermneü anzeigen
          break;
        }
        else                              // ... wenn nicht dann wohl Untermenüs
        {
          if (sub_isactive== true)
          {
            drawMainMenu();                
            myGLCD.print(rec[i].d,CENTER,240); // ... Untermnüfunktionen ausführen
          }
        }
      }
    }
  }
}
/*************************************************************
* D:  Funktion füllt Strukturarray mit Grunddaten
* O:  kein
* I:  v: vertikale Abschnitt des Item
*     h: horizontale Abschnitt des Item
*     d: Beschriftung des Item
************************************************************/
void addItem(int v,int h,String d)
{
  static int i=0;
  rec[i] = (Items) {
    v, h,d                       };
  i++;
}
/*************************************************************
* D:  Funktion berechnet die x,y - Koordinaten der Items
* O:  kein
* I:  kein
************************************************************/
void calcItems()
{
  for (int i=0;i< icount;i++)
  {    
    // ...fuer Wurzelitem
    if (rec[i].v==0 && rec[i].h==0)
    {
      rec[i].p_x_start=menu_start_x;
      rec[i].p_y_start=menu_start_y;
      rec[i].p_x_end=menu_start_x+calcXend(0);
      rec[i].p_y_end=2+menu_start_y+myGLCD.getFontYsize();
    }
    // ... für Items des Hauptmenü ausser Wurzelitem
    if (rec[i].v==0 && rec[i].h!=0)
    {
      for (int j=0;j<icount;j++)
      {
        if (rec[j].v==0 && rec[j].h==rec[i].h-1)
        {
          rec[i].p_x_start=rec[j].p_x_end+1;
          rec[i].p_y_start=rec[j].p_y_start;
          rec[i].p_x_end=rec[i].p_x_start+calcXend(rec[i].h);
          rec[i].p_y_end=2+rec[i].p_y_start+myGLCD.getFontYsize();
          break;
        }
      }
    }
    // ...für alle Items ausser Hauptmenü
    if (rec[i].v!=0)
    {
      for (int j=0;j<icount;j++)
      {
        if (rec[j].v==rec[i].v-1 && rec[j].h==rec[i].h && rec[j].p_x_end!=0)
        {
          rec[i].p_x_start=rec[j].p_x_start;
          rec[i].p_y_start=rec[j].p_y_end+1;
          rec[i].p_x_end=rec[j].p_x_end;
          rec[i].p_y_end=2+rec[i].p_y_start+myGLCD.getFontYsize();
          break;
        }
      }
    }
  }
}
/***************************************************************
* D:  Funktion berechnet die Anzahl der horizontalen Abschnitte
* O:  kein
* I:  kein
**************************************************************/
int calcHmax()
{
  int h_mxm=rec[0].h;
  for (int i = 0; i < icount; i++)
  {
    if (rec[i].h > h_mxm) h_mxm = rec[i].h;
  }
  return h_mxm;
}
/*****************************************************************************
* D:  Funktion berechnet max. Breite der Items eines horizontalen Abschnittes
* O:  kein
* I:  h - horizontaler Abschnitt
*****************************************************************************/
int calcXend(int h)
{
  int p_mxm=0,p_temp=0;
  for (int i=0;i<icount;i++)
  {
    if (rec[i].h==h)
    {
      p_temp=2+rec[i].d.length()*myGLCD.getFontXsize();
      if (p_temp > p_mxm) p_mxm=p_temp;
    }
  }
  return p_mxm;
}
/*************************************************************
* D:  Funktion zeichnet das Hauptmenü
* O:  kein
* I:  kein
************************************************************/
void drawMainMenu()
{
  sub_isactive=false;
  myGLCD.clrScr();
  for (int i=0;i<icount;i++)
  {
    if (rec[i].v==0)
    {
      myGLCD.setColor(back_color);
      myGLCD.fillRect(rec[i].p_x_start,rec[i].p_y_start,rec[i].p_x_end,rec[i].p_y_end);
      myGLCD.setColor(text_color);
      myGLCD.setBackColor(back_color);
      myGLCD.print(rec[i].d,rec[i].p_x_start+1,rec[i].p_y_start+1);
    }
  }
}
/*************************************************************
* D:  Funktion zeichnet das jeweilige Untermenü
* O:  kein
* I:  h: horizontaler Abschnitt des Hauptmenü-Item
************************************************************/
void drawSubMenu(int h)
{
  sub_isactive=true;
  for (int i=0;i<icount;i++)
  {
    if (rec[i].h == h)
    {
      myGLCD.setColor(back_color);
      myGLCD.fillRect(rec[i].p_x_start,rec[i].p_y_start,rec[i].p_x_end,rec[i].p_y_end);
      myGLCD.setColor(text_color);
      myGLCD.setBackColor(back_color);
      myGLCD.print(rec[i].d,rec[i].p_x_start+1,rec[i].p_y_start+1);
    }
  }
}

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
07.09.2015, 22:06
Beitrag #2
RE: Pulldown-Menü für UTFT
Update:
- clrScr() durch eigene Funktion ersetzt - dadurch keine Verzögerung beim Menüaufbau mehr
- kleinere Fehler beseitigt.
Grüße Ricardo

PS: aktueller Code ab jetzt als Anhang.


Angehängte Datei(en)
.ino  SAA.ino (Größe: 8,06 KB / Downloads: 67)

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2015, 09:15
Beitrag #3
RE: Pulldown-Menü für UTFT
Hallo Ricardo,

das liest sich sehr gut, ich denke, das ist es auch. Wink

Was für ein Display würdest du denn da empfehlen und welchen Arduino verwendest du?

I2C = weniger ist mehr: weniger Kabel, mehr Probleme. Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2015, 09:21
Beitrag #4
RE: Pulldown-Menü für UTFT
...und mich würde interessieren, wie die Ansteuerung mit Breadboard-Tastern oder Touchpads funktioniert! Cool
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2015, 16:19 (Dieser Beitrag wurde zuletzt bearbeitet: 08.09.2015 16:20 von rkuehle.)
Beitrag #5
RE: Pulldown-Menü für UTFT
Moin,
@hotsystems
Grundsätzlich kann man ja alle Displays benutzen, die von den UTFT-Libs unterstützt werden. Nachzulesen bei der UTFT-Lib in der PDF-Datei "UTFT_Supported_display_modules_&_controllers" oder, wenn man sich nur an den Controllern orientieren möchte in der Datei "memorysaver.h". Durch entkommentieren der nicht gebrauchten Controller kann man übrigens locker 10-12 K an Speicher sparen.
Ich selbst benutze ein 7" CTE70 mit 480*800 und SSD1963 Controller + Mega. Auf einem 3.2" mit 240*320 Pixeln und SSD1289 Controller +Uno bzw. Mega machts bei mir auch. Wirkt dann allerdings schon recht eng. Generell sollte man die Displays aber kalibrieren, sonst klappt es mit der Auswertung im loop() nicht so doll.
@HaWe
Taster oder externe Touchpads geben ja irgendwas zurück. Das muss man auswerten. Von daher sollte es reichen die Prüfung im loop() umzuschreiben. Alle anderen Funktionen berechnen ja entweder die Koordinaten der Menüanteile oder stellen diese dar bzw. löschen sie.

Die "Roadmap" sieht übrigens wie folgt aus:
- Verschachtelte Menüs möglich machen - ist mehr Denksport als Programmierung, da die grundlegenden Funktionen ja da sind.
- echte Erhaltung des Hintergrundes, egal was da steht - das dürfte in Richtung Switching der Memorypages gehen - würde aber die Nutzung auf CPLD-Displays begrenzen - bin ich noch am grübeln
- Umschreiben des ganzen Codes in eine Klassenbibliothek
Wird sicher noch eine Weile dauern...

Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2015, 16:44
Beitrag #6
RE: Pulldown-Menü für UTFT
ja genau, um das Auswerten geht es mir.

falls ich dafür z.B. 6-7 pins für buttons spendiere
#define up 3
#define down 4
#define left 5
#define right 6
#define enter 7
#define esc 8
#define del 9

- wie navigiere ich damit in deinem Menü?
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
08.09.2015, 17:19 (Dieser Beitrag wurde zuletzt bearbeitet: 08.09.2015 17:50 von rkuehle.)
Beitrag #7
RE: Pulldown-Menü für UTFT
@HaWe
Die Abfrage der Koordinaten in der loop() kann raus. Alternativ Pseudocode:
Code:
int v_temp=0,h_temp=0;
void loop()
{
//......Code zur Abfrage der Buttons
//...Buttons Up/Down setzen v_temp hoch/runter
//...Buttons Right/Left setzen h_temp hoch/runter
//...if (h_temp >calcHmax()) h_temp=0;
//...if (Button == 8 && v_temp >0) v_temp=0;
//...if (Button == 7)
{
if (v_temp==0)                  // Wenn Hauptmenü (v==0)
        {
          drawMainMenu();
          drawSubMenu(h_temp);          //... dann zugehöriges Untermneü anzeigen
        }
        else                              // ... wenn nicht dann wohl Untermenüs
        {
          if (sub_isactive== true)
          {
            drawMainMenu();                
            clrSubMenu(h_temp);
            menuFunction(v_temp,h_temp); // ... Untermnüfunktionen ausführen
          }
        }
}
}
Das müsste es im groben schon sein.
Grüße Ricardo

Nüchtern betrachtet...ist besoffen besser Big Grin
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste