Jak vyzrát na GUI - začátky GUI - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



C/C++

Jak vyzrát na GUI - začátky GUI

GUI

1. srpna 2002, 00.00 | Seznamte se blíže s knihovnou SDL. Tímto článkem dokončíme programování console a vrhneme se na základy "opravdového" GUI.

{Filtrování kláves}

Jak jsem v minulém díle slíbil, dnes dokončíme programování console a vrhneme se ne začátky GUI. Vezměme to tedy hezky po pořádku. Z minulého článku nám zbývá filtrování kláves a popsání funkcí, měnících vlastnosti console. K načtení kláves a jejich zpracování použijeme již zmíněnou knihovnu SDL (naleznete ji na www.libsdl.org).

Filtrování kláves
Knihovna SDL ukládá veškeré události do SDL_Event, ať jde o pohyb myší, poslání žádosti o zavření okna, atd. Musíme si tedy vytvořit proměnnou tohoto typu (SDL_Event event). Doporučuji ji začleňovat do třídy console, co když budeme chtít filtrovat události i v jiné části programu (např. EDITBOXY). Do třídy console přidáme pouze tyto dvě věci:

class C_CONSOLE
{
  public:
  ...
  int Run(SDL_Event * event);
  int Poll_Events(SDL_Event * event);
  ...
};

Funkce int Run(SDL_Event*) zavolá funkci int Poll_Events(SDL_Event*), která přefiltruje klávesy a následně je zavolána funkce int Draw();, která consoli vykreslí. Celou dobu tady píši o nějakém filtrování událostí, kláves, atd. Ale ještě jsem vám neřekl, jak je do proměnné event "nacpeme". Před spuštěním fce. int Run(SDL_Event*); (v našem případě Run(&event);) zavoláme funkci SDL_PollEvent(event);, která proměnnou  event naplní. Nesmíme však zaměnit fci SDL_PollEvent za SDL_WaitEvent. Rozdíl je dosti podstatný. První funkce naplní proměnnou aktuálními událostmi, kdežto funkce druhá vyčkává na první událost, která se od jejího zavolání stane. Ve výsledném efektu by program "zamrzl" dokud by jsme nestiskli klávesu, pohli myší nebo joystickem. Pro snadnější načítání znaků z klávesnice také aktivujeme konverzi UNICODE a to příkazem SDL_EnableUNICODE(TRUE).

Popišme si tedy ony dvě funkce:

int C_CONSOLE::Run(SDL_Event * event)
{
  Poll_Events(event); -prefiltrujeme klavesy

  Draw(); -konsoli vykreslíme

  return FCE_OK; -vše je v pořádku, tak to oznámíme
};


int C_CONSOLE::Poll_Events(SDL_Event * event)
{
  int i;
  static int command_pos = -1; -aktualni pozice v retezci, do ktereho zadavame prikazy

  if(event->type == SDL_KEYDOWN) -zjistime, zda jde o stisk klavesy
  {
    switch (event->key.keysym.sym) -zde budeme porovnavat scancody klavesnice
    {
      case SDLK_PAGEUP: -posouvame se v historii vypisu
      {
        act_line++; -zvetsime index prvni zobrazovane radky
        if(act_line + max_display_lines >= line_count)  -ohlidame, aby jsme nepresahovali pres hranici historie vypisu
           act_line = line_count - max_display_lines - 1; -zasahujeme mimo, musime to opravit
        if(act_line < 0) act_line = 0; -zasahujeme mimo, musime to osetrit
        break; -vse je hotovo
      };

      case SDLK_PAGEDOWN: -to same jako pro PAGE UP, akorat dolu
      {
        act_line--;
        if(act_line < 0) act_line = 0; 
        break;
      };

      case SDLK_END: -tato klavesa nas jaksi nezajima
          break;

      case SDLK_DOWN: -sipkou dolu se budeme poybovat v historii prikazu
      {
        if(command_history_count < 1) break; -pokud nejsou zadne prikazy v historii, neni cim posouvat
        act_command_history++; -zvetsime index o 1 (posuneme se nahoru)
        if(act_command_history >= command_history_count) act_command_history = 0; -osetrime hranice historie

        strcpy(command,command_history[act_command_history]); -zkopirujeme prikaz z historie do prikazove radky

        break; -hotovo
      }

      case SDLK_UP: -to same akorat pro sipku nahoru
      {
        if(command_history_count < 1) break;
        act_command_history--;
        if(act_command_history < 0) act_command_history = command_history_count - 1;

        strcpy(command,command_history[act_command_history]);

        break;
      }

      case SDLK_BACKSPACE: -mazeme aktualni prikaz
      {
        command[command_pos] = '\0'; -na misto v retezci, kde je zrovna kurzor ulozime znak \0 - nevypisuje se
        command_pos--; -a posuneme se o jedno misto zpatky
        if(command_pos <= -1) command_pos = -1;  -musime si dat pozor, aby jsme nemazali mimo exitujici retezec (napr. pozice -1 je dosti zajimava)
        break;
      }

      case SDLK_TAB: -tato klavesa nas opet nezajima
        break;

      case SDLK_KP_ENTER : -pro klavesy ENTER a ENTER na numericke klavesnici plati stejne prikazy, proto nesmime za tento radek doplnit break; (takto automaticky skoci na dalsi radku
      case SDLK_RETURN:
      {
        act_line = 0; -pravdepodobne neco pribyde do historie vypisu, tak nastavime aktualni vypisovanou radku na prvni (kdyby jsme nahodou meli odscrollovano)
        act_command_history = -1; -to same plati i pro historii prikazu

        command_history_count++; -do historie prikazu pribyde dalsi prikaz
        if(command_history_count >= CONSOLE_COMMAND_HISTORY_MAX) command_history_count = CONSOLE_COMMAND_HISTORY_MAX; -co kdyby byla historie jiz plna

        //posuneme radky historie o jednu uroven niz tak, aby nejaktualnejsi byla na zacatky pole
        if(command_history_count >= 2) -pokud je jen jeden prikaz, nemusime nic posouvat cyklem
        {
          for(i = command_history_count - 1; i >= 1; i--)
          {
            strcpy(command_history[i],command_history[i - 1]); -prekopirujeme retezce
          };
        }

        strcpy(command_history[0],command); -a tady nahrajeme aktualni prikaz na prvni misto

        //provedeme prikaz
        Run_Command(command,command); -prvni je jmeno prikazu a druhe jsou jeho parametry (sam si je ze zadaneho prikazu vypreparuje)

        for(i = 0; i < CONSOLE_CHAR_PER_LINE; i++)
        {
          command[i] = '\0'; -ted vymazeme prikazovou radku
        }
        command_pos = -1; -nastavime index kurzoru prikazove radky na zacatek

        break; -hotovo
      }

      // ted nas cekaji klavesy na numericke klavesnici
      case SDLK_KP0 :
      case SDLK_KP1 :
      case SDLK_KP2 :
      case SDLK_KP3 :
      case SDLK_KP4 :
      case SDLK_KP5 :
      case SDLK_KP6 :
      case SDLK_KP7 :
      case SDLK_KP8 :
      case SDLK_KP9 :
      case SDLK_KP_PERIOD: - toto je .
      case SDLK_KP_DIVIDE: -toto je /
      {
        if(act_command_history != -1) - pokud jsme prochazeli hostorii prikazu a chceme nyni psat, je dobre si prikazovou radku nejprve vymazat
        {
            command_pos = -1;
            for(i = 0; i < CONSOLE_CHAR_PER_LINE; i++)
            {
                command[i] = '\0';
            }
            act_command_history = -1;
        };

        command_pos++; -posuneme si index kurzoru o jednu pozici doprava
        if(command_pos >= CONSOLE_CHAR_PER_LINE) command_pos = CONSOLE_CHAR_PER_LINE - 1; -zjisitme si, zda nezapisujeme mimo hranici retezce prikazove radky

        if(event->key.keysym.sym == SDLK_KP_PERIOD) command[command_pos] = (char)'.';  - tyto znaky nejsou osetreny UNICODE, doplnime je tedy "natvrdo"
        else
        if(event->key.keysym.sym == SDLK_KP_DIVIDE) command[command_pos] = (char)'/'; -           -----| |-----
        else
        command[command_pos] = (char)(event->key.keysym.sym - 256) + '0'; - a tady je jiz konverze scancodu na znak. 256 je pozice od ktere se pocita NUMERICKA klavesnice a '0' je index 0. Takto zkonvertovany znak ulozime do retezce prikazove radky

        break; -vse hotovo
      };

      default: -standatrni klavesa
            if(event->key.keysym.unicode) -pokud se jedna o UNICODE znak, neni co resit
            {
              //zde plati to same jako u predesleho zapisovani, proste vymazeme prikazovou radku, pokud jsme se stourali v historii prikazu
              if(act_command_history != -1)
              {
                  command_pos = -1;
                  for(i = 0; i < CONSOLE_CHAR_PER_LINE; i++)
                  {
                    command[i] = '\0';
                  }
                  act_command_history = -1;
              };

             command_pos++; -posuneme si index kurzoru v retezci prikazu
             if(command_pos >= CONSOLE_CHAR_PER_LINE) command_pos = CONSOLE_CHAR_PER_LINE - 1; -osetrime, zda nezapisujeme mimo hranici retezce prikazove redky

             command[command_pos] = (char)event->key.keysym.unicode; -zapiseme znak. Do event->key-keysym.unicode se uklada jiz pretrasformovany znak ze scancodu do char. !!!Pozor!!! musi byt zapnute SDL_EnableUNICODE(true);
          }
      }
  }
  return FCE_OK;  -a mame to za sebou
};

Funkci int Poll_Event(SDL_Event*) použijeme s menší úpravou i v objektu C_EDIT_BOX, ale to až dále. Nyní jsme dokončili poslední z důležitých funkcí pro práci s consolí. Zbývají nám jen funkce, pomocí kterých budeme měnit vlastnosti console, jako výšku, šířky, pozici, barvy. Napíšeme si pouze jejich funkční prototypy (aby jsme měli celou třídu C_CONSOLE úplnou), tělo funkce je velmi jednoduché. Prostě v nich naplníme proměnné jako bkg_img_ID nebo line_color, atd.

class C_CONSOLE
{
  public:
  ...
  ...
  //SET COLORS
  int Set_Background_Color(float r,float g,float b,float alpha);
  int Set_Background_Color(T_COLOR_RGBA color);
  int Set_Border_Color(float r,float g,float b,float alpha);
  int Set_Border_Color(T_COLOR_RGBA color);
  int Set_Text_Color(float r,float g,float b,float alpha);
  int Set_Text_Color(T_COLOR_RGBA color);

  //SET SIZE AND POSITION
  int Set_Size(float width,float height);
  int Set_Position(float X,float Y);
  int Set_Font_Size(float to);

  //SET BACKGROUND IMAGE PROPERTIES
  int Set_Image_Texture(char file[]);
  int Set_Image_Texture(int ID);
  int Set_Image_Position(int x1,int y1,int x2,int y2);
  int Set_Image_TexCoords(float tx1,float ty1,float tx2,float ty2);
  int Set_Image_Color(float r,float g,float b,float a);
};
[-more-]{GUI}

GUI
Tímto máme za sebou celou třídu C_CONSOLE. Jak jsem již psal v minulém článku do koncepce GUI jako takového příliš nezapadala, ale pro tvůrce her může být užitečná. Co se týká GUI samotného máme před sebou docela slušný kus práce. Zapomeňme teď na konkrétní názvy jako tlačítka (buttony), zaškrtávátka (checkboxy), atd. Nazvěme je souhrnně objekty GUI. Každý objekt GUI bude určitého typu, tzn. přiřadíme mu určitou třídu. Všechny třídy jak pro tlačítka, zaškrtávátka, atd. mají mnoho společných věcí. Můžeme začít od pozice, velikosti, barvy, velikosti fontu, názvu, ID vlastníka, funkcí pro vykreslování a testování myši. Také všechny objekty GUI uložíme do jednoho velkého pole, abychom si ušetřili práci se samostatným polem pro tlačítka nebo popisky. Díky těmto faktorům jsem se rozhodl pro použití jednoho mateřského objektu od kterého zbylé objekty odvodíme. Nadefinujme si tedy objekt pod názvem C_GUI_OBJECT

class C_GUI_OBJECT
{
public:
  int x,y,width,height; -pozice a velikost
  char name[GUI_OBJECT_NAME_LEN_MAX]; -jmeno obejktu (napr. "Koupit"), pomocí tohoto nazvu objekt v poli vyhledame
  char visible; -je videt ci ne
  char mouse_state; -co zrovna dela myska (je nad objektem, je nad objektem stisknuta, ...)
  float font_size; -velikost fontu
  char owner_ID; -ID vlastnika v poli, zpravidla pujde o objekt C_MENU, ale to az dale
  char used; -jestli je tato pozice v poli pouzita ci ne
  char type; -o jaky typ objektu se jedna (tlacitko, zaskrtavatko, popisek, ...) je to velmi dulezite, ale to si popiseme az dale
  char func_name[GUI_FUNC_NAME_LEN_MAX]; -jmeno volane funkce (napriklad pri stisku tlacitka, atd.)
  T_GUI_FUNC function; -odkaz na funkci, ktera se ma provest po ...  (stejne jako u console)

  virtual int Draw(void) = 0;  -funkce pro vykresleni
  virtual int Test(int mouse_x,int mouse_y,int left_but) = 0; -funkce pro otestovani pozice a tlacitek mysi
};

Vše je to moc hezké až na jednu věc. Právě jsem vám zahltil hlavu hromadou "neznámých" věcí. Například owner_ID. Jak jsem psal výše, všechny objekty se uloží do jednoho pole vytvořeného z ukazatelů na C_GUI_OBJECT. Jelikož ostatní objekty budou od této třídy odvozeny (sama existovat nemůže, musí být vždy předkem), mohou ji "zastoupit". Zděděné objekty budou vlastnit funkce Draw() i Test(), potřebné pro práci s nimi. Jakmile ale přiřadíme do pole objekt od tohoto objektu odvozený, ztratíme informace o potomkovy a budeme mít přístup pouze k proměnným a metodám (funkcím) předka (pokud tento objekt opět nepřetypujeme zpět, ale to až dále). Jenže funkce potřebné pro vykreslení objektu a jeho otestování předek již obsahuje, nebude s tím žádný problém a práce se nám velmi zjednoduší. owner_ID je tedy ID vlastníka. Zpravidla půjde o objekt typu C_MENU, který bude odvozen od C_GUI_OBJECT. Pokud bude mít C_MENU (vlastník) proměnnou visible nastavenou na false, nevykreslíme ani objekt, pro který je objekt C_MENU vlastníkem. To je dosti kostrbatě napsané, ale doufám, že to pochopíte. Vše podrobně popíšu, až se k tomu prokoušeme. Další věcí je odkaz na funkci, která se má provést po splnění určité, objektu typické vlastnosti. U tlačítka půjde o stisknutí, u zaškrtávátka zaškrtnutí nebo u editboxu stisknutí klávesy Enter. Funkční prototyp se bude od toho, který jsme použili u console trochu lišit. Jelikož různé funkce budou vyžadovat různé parametry, rezervujeme si tři čísla typu int (například pozice kurzoru a tlačítka při zavolání funkce) a jeden ukazatel na void (void * data), který můžeme použít (po přetypování na char * například k uložení řetězce editboxu). 

Definice, definice, definice
Proměnné mouse_state, type, atd. mohou nabývat různých číselných hodnot, navrhuji proto zavedení jistých definic :

DEFINICE PRO PRACI S RETEZCI A POLI RETEZCU (viz. dale)
#define GUI_CAPTION_LEN_MAX 50 - maximalni delka nazvu (zobrazeneho, napr napis na tlacitku)
#define GUI_OBJECT_NAME_LEN_MAX 100 -maximalni delka retezce do ktereho ulozime jmeno objektu (pro vyhledavani v poli)
#define GUI_FUNC_NAME_LEN_MAX 100 -maximalni delka nazvu(retezce) funkce (slouzi pro nahravani a doplneni podle tabylky funkci)
#define GUI_STRING_LEN_MAX 101 -maximalni delka retezce, je to 100 znaku plus 1 ukoncovaci
#define GUI_LIST_BOX_LINES_MAX 100 -maximalni pocet radek v listboxu (az dale)
//101 = 100 chars + 1 ending

typedef (*T_GUI_FUNC)(int a,int b,int c,void * pointer = NULL); -definice ukazatele na funkci, void * pointer nastavime defaultne na NULL - zadne dalsi parametry, za behu programu se to da velmi snadno zmenit

#define GUI_OBJECT_MAX 500 -maximalni pocet obejktu jednoho GUI

TOTO JSOU NAZVY JEDNOTLIVYCH TYPU OBJETU V GUI, ulozime je do C_GUI_OBJECT::type
#define GUI_BUTTON 1
#define GUI_LABEL 2
#define GUI_MENU 3
#define GUI_CHECK_BOX 4
#define GUI_EDIT_BOX 5
#define GUI_IMAGE 6
#define GUI_SCROLL_BAR 7
#define GUI_LIST_BOX 8
#define GUI_FRAME 9

#define GUI_BUTTON_DOWN 1
#define GUI_BUTTON_UP 2

TOTO JSOU PARAMTERY FUNKCE PRO VYHLEDAVANI V POLI PRI NAHRAVANI
#define GUI_FREE_POSITION 1 -najde prvni volnou pozici a vrati jeji ID
#define GUI_LAST_USED_POSITION 2 -najde posledni pouzitou pozici a vrati jeji ID
#define GUI_FIRST_USED_POSITION 3 -najde prvni pouzitou pozici a vrati jeji ID

BAREVNA SCHEMATA (to az dale)
#define GUI_NORMAL 0 -normalni vykresleni
#define GUI_HIGHLIGHTED 1 -barva kdyz je mys nad objektem
#define GUI_DOWN 2 -barava, kdyz jsme nad objetem stiskli tlacitko mysi a stale ho drzime
#define GUI_SELECTED 2 -barava pri vybrani objektu (napr. editbox - psani)

POZICE MYSI A KLACESNICE ulozime do C_GUI_OBJECT::mouse_state
#define GUI_LEFT_MOUSE 0 -leve mysitko
#define GUI_RIGHT_MOUSE 1 -prave mysitko
#define GUI_MIDDLE_MOUSE 2 -prostredni mysitko
#define GUI_MOUSE_MOVE 3 -mys je nad objektem, zadne tlacitko neni stisteno, pouzije se barevne chema GUI_HIGHLIGHTED
#define GUI_NOTHING 4 -mys neni nad objektem
#define GUI_ENTER 5 -byl stisknuty ENTER
#define GUI_KB_UP 6 -stisknuta sipka nahoru
#define GUI_KB_DOWN 7 -stisknuta sipka dolu
#define GUI_MOUSE_DOWN 8 -tlacitko na mysi bylo stisknuto

Toto je většina definic, některé jsou pro nás zatím zbytečné, ale chtěl jsem, aby jste si udělali nějaký obrázek o tom, jak to bude asi vypadat a co se kam bude ukládat. Nejsou zde obsažený definice pro scrollbary, neboť na ty máme ještě dost času.  
[-more-]{První třída/objekt GUI}

První třída/objekt GUI
Ve hře můžeme mít několik GUI najednou, nebylo by proto moudré ukládat objekty GUI do globálního pole. Vytvoříme si tedy objekt C_GUI pomocí kterého budeme vše obsluhovat. Podle mého názoru by mohl vypadat asi takto:

class C_GUI
{
public:
  C_GUI_OBJECT * object_array[GUI_OBJECT_MAX]; -pole do ktereho ulozime objekty GUI

  C_GUI_OBJECT * focus; - ukazatel na aktualne vybrany objekt (napriklad stisknute tlacitko), jeho funkci si popiseme pozdeji

  int Init(void); -nastavi GUI
  int Clear(void); -vymaze GUI
  int Hide_All_Menus(void); -skryje vsechna menu

  int Load_Menu(char file[]); -nahraje menu

  int Find_Position(int which); -najede pozici podle kriteria (viz. vyse - GUI_FREE_POSITION,...) a vrati jeji ID

  int Draw(void); - vykresli GUI

  int Edit_String(char text[GUI_STRING_LEN_MAX],int& act_pos); -postara se o editaci retezce (napriklad pro editbox), je to podobne jako u console

  int Bind_Function(char func_name[GUI_FUNC_NAME_LEN_MAX],T_GUI_FUNC func); -"navaze"/priradi objektum, ktere maji jmeno funkce func_name, funkci func
};

V šedém rámečku je pouze nutný základ, postupem času ho budeme rozšiřovat o přístupové funkce k objektům GUI, k nahrávání a rozšířenému vykreslování. Funkce Init() zavolá funkci Clear(), která vymaže pole GUI objektů (object_array[]) a vymaže focus (nastaví ho na NULL). K čemu budeme focus potřebovat? Tato otázka je opravdu na místě. Představte si situaci, kdy kliknete na tlačítko, ale myš nepustíte, popojedete mimo tlačítko a pustíte. V momentě, kdy najedete na talčítko a myš zmáčknete (myslím tím tlačítko), do focus se uloží ukazatel na GUI objekt na kterém k této akci došlo. To nám velmi ulehčí práci. V případě, že neklikneme na žádný objekt, bude hodota fucus rovna NULL, pokud se stisklým tlačítkem myši poté najedeme například na tlačítko a pustíme, jednoduše otestujeme, zd byla myš stisknuta na tlačítku nad kterým byla puštěna. Prostě porovnáme ukazatel focus a ukazatel na GUI objekt, který je uložený v object_array[]. Stejným způseb zjistíme, zda máme provést nějakou akci po uvolnění tlačítka myši. Po odchycení kódu pro uvolnění tlačítka (popíšeme si níže), otestujeme, jestli je myš nad nějakým objektem, respektive nad objektem, nad kterým byla stištěna. Stačí k tomu jednoduchá podmínka : if(focus->mouse_state == GUI_MOUSE_DOWN) focus->func(x,y,tlacitko,data); Podobných příkladů je nespočet, každý si popíšeme až u konkrétního objektu. Ve třídě C_GUI se také objevila funkce Load_Menu(), která má prý nahrávat menu ze souboru file[]. Po jisté době jsem dospěl k závěru, že vlastnosti jednotlivých objektů (pozice, barva, velikost,...) bude lepší uchovávat mimo zdrojový kód, jelikož pro jejich změnu stačí upravit menší skript a nemusíme kompilovat znovu celý program. Díky tomuto můžeme velmi jednoduše měnit skiny našeho GUI. Jediné co musí být zadané v programu je tabulka funkcí, které se po nahrání GUI přiřazují jednotlivým objektům. Skript je velmi jednoduchý, ale k jeho úplnému pochopení budeme potřebovat znát jednotlivé objekty GUI. Vše si samozřejmě popíšeme a vysvětlíme, až na to nastane ten správný čas, respektive až budeme znát ten či onen objekt. Ukáži vám jeden demonstrační skriptík, na kterém si později budeme vysvětlovat jednotlivé objekty GUI. Nelamte si tedy hlavu, když mu nebudete rozumět, neboť vše má svůj čas. Tak tady je :

#MENU [menu1]  -timto dame najevo, ze nahravame menu (objekt C_MENU) s nazvem [menu1]
{
ZDE NASTAVIME BAREVNE SCHEMA MENU
#line_color 1.0 1.0 1.0 1.0
#line_move_color 1.0 1.0 0.0 1.0
#line_down_color 0.0 0.0 1.0 1.0
#button_color 0.0 0.0 0.0 0.0
#button_move_color 1.0 1.0 0.0 0.5
#button_down_color 1.0 0.0 0.0 0.5
#text_color 1.0 1.0 1.0 1.0
#text_move_color 1.0 1.0 0.0 1.0
#text_down_color 1.0 0.0 0.0 1.0
#scrbar_back_color 0.5 0.5 0.5 1.0
#edit_color 0.8 0.8 0.8 0.5
#edit_move_color 0.5 0.5 0.5 0.5
#edit_selected_color 1.0 1.0 1.0 0.5
#edit_font_color 1.0 1.0 1.0 1.0
#edit_font_move_color 1.0 1.0 0.0 1.0
#edit_font_selected_color 0

#FRAME [menu2_frame]  -toto je ramecek se jmenem [menu2_frame], bude obklopovat tlacitko
-1,430,105,45 -jeho pozice (x,y,sirka,vyska)
1.0 1.0 1.0 1.0 -barva okrajove cary
1.0 1.0 0.0 0.5 -barva vyplne

#LABEL [manu_label2] -popisek
10,435 -pozice (x,y)
MENU2 -text popisku
0.5 -velikost fontu
0.8 0.8 0.8 1.0 -barva textu

#BUTTON [console] -tlacitko, pokud ho budeme chtit najit v poli objektu GUI, jmeno pro hledani je [console]
10,450,90,20 -pozice (x,y,sirka,vyska)
Show_menu1 -text tlacitka
0.5 -velikost fontu
Show_menu1 -jmenu funkce, ktera se spusti po stisknuti tlacitka
};

Takto nějak vypadá skript GUI, který budeme používat. Jak jste si jistě všimli, každý objekt C_MENU shlukuje objekty ostatní a má vlastní barevné schéma. V tomto případě je uloženo tlačítko s nápisem "Show_menu1", okolo něj je rámeček se žlutým pozadím (r = 1,g = 1,b = 0) a bílou okrajovou linkou. Uvnitř toho rámečku je ještě popisek "MENU2". Měli bychom si tedy nadefinovat objekty C_MENU(menu), C_FRAME(rámeček), C_LABEL(popisek), C_BUTTON(tlačítko). Dále funkce sloužící k jejich nahrání a obsluze. Ale říká se, že v nejlepším se má přestat. Nuže těším se na vás u dalšího dílu seriálu Jak vyzrát na GUI.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

Diskuse k článku

 

Vložit nový příspěvek   Sbalit příspěvky

 

Zatím nebyl uložen žádný příspěvek, buďte první.

 

 

Vložit nový příspěvek

Jméno:

Pohlaví:

,

E-mail:

Předmět:

Příspěvek:

 

Kontrola:

Do spodního pole opište z obrázku 5 znaků:

Kód pro ověření

 

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: