Tvorba aplikací s dotykovým displejem

Zdravim,

chtěl bych se zeptat, jak řešit správně nějakou aplikaci s dotykovým displejem. Např. budu mít mít menu a přes to se proklikám na nějaký další možnosti aplikace. Třeba např. na zobrazení nějakýho grafu apod… Vím, že existují RTOS s kterýma nemám prozatím žádné zkušenosti, tak to chci řešit bez toho.

To co mě napadlo bylo využítí pointrů na funkce, takže asi nějak takto bych si definoval strukturu:

typedef struct {
	char *title;//název
	void (*drawTFT[20])();//funkce pro vykreslení
	void (*controlTouch[20])(int x, int y);//funkce pro kontrolu dotykového činosti
              int draw[20];//nastavení, jestli už byla daná funkce vykreslena či nikoliv
	int countDrawTFT;//počet funkcí pro vykreslení
	int countControlTouch;//počet funkcí pro kontrolu dotyku
} TFT_Applications;

Takže poté bych si např. funkci drawKeyPad(), controllKeyPad(int posX, int posY):

TFT_Applications keyPad;
keyPad.title="KeyPad";
keypad.drawTFT[0]=drawKeyPad;
keypad.controlTouch[0]=controllKeyPad;
keypad.draw[0]=0;
keypad.countDrawTFT=1;
keypad.countControlTouch=1;

Poté bych bych např. každých 10ms kontroloval funkce, které jsou nastaveny v controlTouch, a popřípadě, že něco sedí, tak na to reagoval. Musel bych mít potm asi ještě nějakou strukturu, kde bych měl kompletní zobrazované data na displeji, a tam bych měl např. právě uloženou tuto strukturu KeyPad+ nějaké kontrolní tlačítka apod.

Zajímalo by mě, jestli se to dá takto řešit a hlavně, jak by se to mělo správně řešit. Děkuji za odpověď.

Zkusím stručně popsat jak to realizuji:

Grafický driver zajišťuje vykreslení obsahu paměti (obrázku) na displej na určité místo

Ovladač displeje obsahuje canvas = kreslící plátno, do kterého se realizuje vykreslování. Nelze kreslit přímo na displej, prvky by problikávaly. Ale protože RAM není dost velká na celou obrazovku, je canvas jenom výřez (určitý počet linek). Ovladač displeje kreslý po pásech - při kreslení projede všechny pásy, při každém pásu všechny prvky a překreslí je, ale ořezává pro aktuální pás. Tím se dá realizovat každá velikost displeje i při malém bufferu bez blikání, rychlost kreslení je i přes to dost vysoká.

Ovládací prvky mám definované jako třídy (ve skutečnosti struktury, je to pod C). Obecný prvek obsahuje definici - rozměry a umístění na displeji, obrázek který může obsahovat, barvu podkladu a písma, text. Od základního prvku se odvozují prvky jako tlačítko, obdélník, obrázek, video atd. Prvky jsou jen ve statickém poli, obrázky jsou jako konstantní pole v programu, takže veškerá obsluha displeje se obejde bez alokace paměti malloc, všechno je jenom změnou ukazatelů v RAM.

Prvky jsou pomocí ukazatelů řazeny do stromových struktur. Pokud se přepne stránka displeje, přepne se jen ukazatel na Root prvek (obvykle jím je obrázek pozadí, jeho potomky je několik tlačítek). Kreslící funkce vezme Root prvek, zajistí jeho vykreslení do canvasu a potom vykresluje jeho potomky atd. Po vykreslení všech prvků překreslí pás canvasu na displej a opakuje kreslení pro další pás. Oříznutí na pás realizuje kreslící funkce pro základní prvek.

Ovladač displeje má uchované souřadnice rectanglu změn. Pokud se změní obsah displeje (stisk tlačítka, vytvoření nebo zrušení prvku atd), aktualizuje hranice rectanglu změn. Z hlavní smyčky se volá obsluha překreslení displeje - otestuje se rectangl změn a pokud je nějaká změna na displeji, zajistí se překreslení oblasti. Je to optimální kompromis mezi překreslováním celého displeje a mezi opakovaným kreslením po každé změně.

Ovladač touche zjistí stav stisk/uvolnění a souřadnice stisku, tyto informace se uloží do globálních proměnných. Z hlavní smyčky pokud je změna touche (např. stisk nebo přesun), zavolá se funkce Root prvku s informací o této události. Root prvek přepošle zprávu všem svým potomkům. Každý potomek testuje zda jeho souřadnice spadají do souřadnice události a pokud má na událost reagovat (např. je to tlačítko reagující na stisk), obslouží událost a vrátí rodič příznak, že událost už neplatí (tedy pokud ji prvku nezachytí nějaký jeho potomek).

Tlačítko při stisku neobsluhuje přímo požadovanou funkci - to by se funkce cyklicky zahltily a např. by nešlo změnit obsah displeje atd. Takže obsluha tlačítka jen vyšle událost do fronty zpráv - což je jen seznam struktur. Po návratu do hlavní smyčky prochází hlavní smyčka frontu zpráv a zprávy zpracovává - to znamená že volá funkci která se má zprávou obsloužit, např. funkci která zruší prvky a přepne na jinou stránku. Zpráva obsahuje adresu funkce která se má provést, ukazatel na prvek který zprávu vyvolal a volitelné parametry převzaté z definice od tlačítka - např. na kterou stránku displeje se má přepnout.

Děkuji za rozsáhlý příspěvek, uvidim co z toho všechno pochopím. :slight_smile: Jinak nejsou na toto téma nějaký články? Zkoušel sem něco najít bohužel bez úspěchu.

Podívejte se na FTDI Eve, třeba vám to ulehčí práci. Je to pro nějaký hobby vývoj nebo připravujete komerční projekt?

Nemělo by se jednat o nějak extra složitou aplikaci, ale rád bych věděl jak na to hned na začátku. Jedná se o školní projekt, kterej bych dělal pro externí firmu, zatím bez finanční odměny. Nevím ještě přesně o co půjde, zatím vím, že by mělo jít o zobrazení dat z motoru, který posílá údaje po CAN sběrnici.