Hlavní navigace

GLUT (7): prvky pro tvorbu GUI

Pavel Tišnovský 10. 6. 2003

Z prvků pro tvorbu grafického uživatelského rozhraní (GUI) nabízí knihovna GLUT kromě možnosti otevření více oken pouze použití takzvaných vyskakovacích (pop-up) menu. Složitější prvky GUI, jako jsou scrollbary, editační pole, tlačítka, listboxy apod., nejsou přímo podporovány a podle autorů knihovny se s jejich podporou nepočítá ani do budoucnosti. Na druhou stranu je třeba říci, že pro jednodušší aplikace nám minimalistický přístup reprezentovaný knihovnou GLUT dostačuje. Pro složitější aplikace (ne nutně z hlediska složitosti algoritmu, ale grafického uživatelského rozhraní) lze použít dalších knihoven postavených na GLUT.

Grafické uživatelské rozhraní – vyskakovací menu

Vyskakovací (pop-up) menu se někdy také podle svého významu nazývají kontextová menu (context menu). Jsou vyvolávána většinou stisknutím druhého (pravého) tlačítka myši nad některým objektem v okně aplikace. Výhodou vyskakovacích menu je, že zbytečně nezabírají místo na obrazovce a většinou nabízejí pouze položky (příkazy), které mají pro vybraný objekt smysl. Nevýhodou oproti klasickým (pull-down) menu je, že uživatel musí předem vědět, že k určitému objektu je nějaké vyskakovací menu přiřazeno, protože existence vyskakovacích menu není nijak graficky reprezentována. U klasických menu je situace jednodušší tím, že menu je stále viditelné a uživatel si po chvíli práce jeho pozici zapamatuje.

Vyskakovací (pop-up) menu mohou být vnořena, tzn. při výběru některé položky z menu se může zobrazit podmenu (submenu). V pojetí knihovny GLUT musí být vyskakovací menu navázáno na některé z tlačítek myši, nelze je tedy vyvolat například stiskem klávesy (což představuje určité omezení, zejména na klávesnicích s „okenními“ klávesami) či výběrem objektu na obrazovce. Položky menu lze za běhu aplikace přidávat, ubírat nebo měnit. Tyto operace však nelze provádět v době, kdy je vyskakovací menu zobrazeno. Při výběru položky z menu je zavolána předem zaregistrovaná callback funkce, které je jako parametr předán číselný identifikátor vybrané položky. Běžnou praxí je mít pro všechna menu zaregistrovanou jednu callback funkci a v této funkci vytvořit rozeskok pomocí příkazu switch.

Pro práci s vyskakovacím menu poskytuje knihovna GLUT několik funkcí:
glutCreateMenu(void (*func)(int value)),
glutSetMenu(int menu),
glutGetMenu(void),
glutDestroyMenu(int menu),
glutAddMenuEn­try(char *name, int value),
glutAddSubMenu(char *name, int menu),
glutChangeToMe­nuEntry(int entry, char *name, int value),
glutChangeToSub­Menu(int entry, char *name, int menu),
glutRemoveMenu­Item(int entry),
glutAttachMenu(int button) a
glutDetachMenu(int button).

Funkce glutCreateMenu(void (*func)(int value)) vytvoří (prozatím) prázdné menu a jako svoji návratovou hodnotu vrátí celé číslo identifikující toto nové menu. Funkce má jeden argument func, což je ukazatel na callback funkci zavolanou v případě výběru některé položky menu. Funkce glutSetMenu(int menu) nastaví některé menu jako aktivní, takže veškeré další operace (například přidání položky) se budou provádět s tímto menu. Identifikační číslo právě aktivního menu lze zjistit voláním funkce glutGetMenu(void). Aktivní menu lze zrušit voláním funkce glutDestroyMenu(int menu). Podmínkou je, aby menu nebylo při rušení zobrazené.

Po vytvoření menu je nutné přidat do aktivního menu položky voláním funkce glutAddMenuEn­try(char *name, int value). Tato funkce má dva argumenty. V prvním argumentu name se předává řetězec, který bude na místě položky zobrazen. V druhém argumentu value je libovolné číslo, které specifikuje vybranou položku. Toto číslo bude předáno callback funkci zavolané v případě výběru položky z menu. Položky jsou do menu přidávány za sebou tak, jak je volána funkce glutAddMenuEntry(). Změnu položek (například popisu položky) lze dosáhnout voláním funkce glutChangeToMe­nuEntry(int entry, char *name, int value). V prvním argumentu entrytéto funkce se specifikuje pořadové číslo položky, která se má změnit. Další dva argumenty name a value jsou shodné jako u funkce glutAddMenuEntry. Libovolnou položku lze z menu odstranit voláním funkce glutRemoveMenu­Item(int entry).

Pro práci s kaskádovým menu je nejprve zapotřebí vytvořit všechna podmenu (submenu) a potom funkcí glutAddSubMenu(char *name, int menu) přidat tato submenu do nadřazeného menu. Změnu submenu zajistí funkce glutChangeToSub­Menu(int entry, char *name, int menu).

Vazba menu s tlačítky myši

Po vytvoření celé hierarchie menu (hlavní pop-up menu s případnými submenu) lze provést vazbu menu s určitým tlačítkem myši. To znamená, že po stisknutí některého předem vybraného tlačítka bude menu zobrazeno a v případě výběru položky z menu bude zavolána příslušná callback funkce. Vytvoření vazby mezi tlačítkem myši a menu se provede voláním funkce glutAttachMenu(int button), zrušení vazby se provede funkcí glutDetachMenu(int button). Do jediného argumentu button se těmto funkcím zadává identifikátor tlačítka myši, se kterým má být menu svázáno – GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, nebo GLUT_RIGHT_BUTTON.

Ukázkový příklad číslo 12

V tomto příkladu je ukázána tvorba jednoduchého menu, které je svázáno s levým tlačítkem myši. Vlastní vytvoření menu je provedeno ve funkci createMenu(). Tato funkce nejprve zavolá příkaz glutCreateMenu(), přičemž do argumentu této funkce je zadán ukazatel na callback funkci onCommand(). Poté se pomocí příkazů glutAddMenuEntry() přidají do menu jednotlivé položky. Každé položce je přiřazeno jednoznačné číslo typu int, které je předáno při volání callback funkce. Po vložení všech položek menu je voláním funkce glutAttachMenu() provedena vazba na levé tlačítko myši (GLUT_LEFT_BUTTON).

Po výběru určité položky z menu je zavolána callback funkce onCommand(), jíž je předáno identifikační číslo položky. Toto číslo je vhodně zvoleno tak, aby jeho rozložením na jednotlivé slabiky (byty) vznikl barevný kód RGB. Po rozkódování barvy je touto barvou přemazána klientská část okna.

Zdrojový kód dvanáctého příkladu a zdrojový kód se zvýrazněnou syntaxí.

ukázka příkladu číslo 12

Ukázkový příklad číslo 13

V tomto příkladu jsou vytvořena dvě pop-up (vyskakovací) menu, z nichž každé obsahuje další submenu. Ke každému pop-up menu je zaregistrována jedna callback funkce. Před vytvořením pop-up menu je nutné vytvořit všechna submenu a zapamatovat si jejich identifikační čísla. To je provedeno ve funkci createMenu(). Poté lze již vytvořit pop-up menu a přidat do něj všechny položky i příslušná submenu. Posledním krokem je svázání pop-up menu s některým tlačítkem myši.

V příkladu číslo 13 je levým tlačítkem myši vyvoláno menu pro změnu barev jednotlivých vrcholů (vertexů) nakresleného trojúhelníka. Pravým tlačítkem myši se vyvolává menu pro přepnutí do plného okna, zmenšení aplikace do okna a pro ukončení aplikace. Za povšimnutí stojí položka Quit-No, která po výběru neprovede žádnou akci.

U některých platforem (mimo jiné i v operačním systému Microsoft Windows) existuje nedokumentovaná vlastnost knihovny GLUT, kdy lze v řetězci u každé položky přidat před některé písmeno znak &. Ten naznačuje, že následující písmeno či jiný alfanumerický v položce menu bude podtržený a bude ho tedy možné vybrat stisknutím příslušné písmenné klávesy. Příklad zobrazení příkazů z menu: File, Edit apod. U jiných platforem či operačních systémů nemusí být tato možnost podporována a znak & bude v menu přímo zobrazen. Proto je vhodné tuto nedokumentovanou vlastnost používat pouze na předem otestovaných systémech a popřípadě použít podmíněného překladu.

Zdrojový kód třináctého příkladu a zdrojový kód se zvýrazněnou syntaxí.

ukázka příkladu číslo 13

V příštím dílu si řekneme, jak lze pomocí funkcí z knihovny GLUT vykreslovat bitmapové a vektorové znaky.

Našli jste v článku chybu?

13. 6. 2003 17:45

hkmaly (neregistrovaný)

No, na mem linuxu by ty priklady diky fvwm95 vypadali stejne ... a cloveku hned nedojde ze screenshot z linuxu obvykle okraj neobsahuje, protoze se jedna o jine okno ...

12. 6. 2003 8:55

Pavel Tišnovský (neregistrovaný)

Taky zdravím a gratuluju k výsledku z Multimedií. Jinak jsem psal tuším už u prvního dílu, že jsem poslední úpravy článku dělal na notebooku, takže ty screenshoty jsou opravdu z Windows. Docela mě překvapilo, že tato nezamýšlená "malá provokace" nevyvolala větší diskuzi či flamewar. Pravděpodobně jsou čtenáři roota kultivovanější než na Živě ;-)

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

DigiZone.cz: Ohrozí Freedom TV přechodové sítě?

Ohrozí Freedom TV přechodové sítě?

Podnikatel.cz: Na poslední chvíli šokuje výjimkami v EET

Na poslední chvíli šokuje výjimkami v EET

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

DigiZone.cz: Sat novinky: slovenská TV8 HD i ruský NTV Mir

Sat novinky: slovenská TV8 HD i ruský NTV Mir

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

120na80.cz: Rakovina oka. Jak ji poznáte?

Rakovina oka. Jak ji poznáte?

Root.cz: Certifikáty zadarmo jsou horší než za peníze?

Certifikáty zadarmo jsou horší než za peníze?

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

DigiZone.cz: ČT má dalšího zástupce v EBU

ČT má dalšího zástupce v EBU

Root.cz: Vypadl Google a rozbilo se toho hodně

Vypadl Google a rozbilo se toho hodně

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

DigiZone.cz: Flix TV má set-top box s HEVC

Flix TV má set-top box s HEVC