Irrlicht Engine logo

Tutorial 5: User Interface
Přeložil: Martin Cmar

V tomto tutoriálu si ukážeme jak používat uživatelské rozhraní vestavěné v irrlicht enginu. Budete tak umět vytvořit okno, tlačítka, scroll bary(posuvníky), statický text a list box(seznam výběru).

Výsledný program:


Začínáme!

Tak jako vždy, přidáme hlavičkové soubory, použijeme irr namespace pro zkrácený zápis a řekneme linkeru kde se nachází soubor *.lib. Také si uložíme ukazatel na Irrlicht device a početní proměnnou pro změnu pozice okna. Dále také ukazatel na listbox.

#include <irrlicht.h>

#include <iostream>
using namespace irr;
using namespace core;

using namespace scene;

using namespace video;

using namespace io;

using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
IrrlichtDevice *device = 0;

s32 cnt = 0;

IGUIListBox* listbox = 0;

Event Receiver není pouze schopen indikovat stisk tlačítek, ale také události v GUI. Většina událostí jsou: klik na tlačítko, výběr ze seznamu, událost jež sdělí že máte kurzor na nějakém prvku, ale zatím jste na něj neklikli a tak dále. Aby jsme zapnuli reakci na některou z těchto událostí, vytvoříme tedy event receiver.

class MyEventReceiver : public IEventReceiver
{
public:
virtual bool OnEvent(SEvent event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = device->getGUIEnvironment();
            switch(event.GUIEvent.EventType)

            {

Náš scroll bar má id 104. Pokud scrollbar změní svou scroll pozici změníme také průhlednost všech prvků GUI. Je to velmi snadné: Všechny nastavení barev jsou uložena v objektu skin. My tedy jednoduše změníme hodnotu alphy(průhlednosti).

case EGET_SCROLL_BAR_CHANGED:
if (id == 104)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();

for (s32 i=0; i<EGDC_COUNT ; ++i)
{
SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
col.setAlpha(pos);
env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
}
}
break;

Pokud je kliknuto na první tlačítko, aplikace se zavře. Druhé vytvoří malé okno s textem a třetí vytvoří file open dialog, který přídá řetězec do listboxu. To je z event receiveru vše.

       case EGET_BUTTON_CLICKED:

              if (id == 101)

              {

                 device->closeDevice();

                 return true;

              }
              if (id == 102)

              {

                 listbox->addItem(L"Window created");

                 cnt += 30;

                 if (cnt > 200) 

                   cnt = 0;
                 IGUIWindow* window = env->addWindow(

                       rect<s32>(100 + cnt, 100 + cnt, 300 + cnt, 200 + cnt), 
false, // modal? L"Test window");
                 env->addStaticText(L"Please close me", 

                       rect<s32>(35,35,140,50),

                       true, // border?,

                       false, // wordwrap?

                       window);



                 return true;

              }
              if (id == 103)

              {

                 listbox->addItem(L"File open");

                 env->addFileOpenDialog(L"Please choose a file.");

                 return true;

              }
              break;

          }

       }

       return false;

    }

 };

Ok, teď jdeme na více zajímavou část. Nejdříve vytvoříme irrlicht device. I v jako jiných příkladech necháme uživatele vybrat zda chce použít D3D8, D3D9, OpenGL, nebo software render.

int main()

{

  // ask user for driver

  video::E_DRIVER_TYPE driverType;





  printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_SOFTWARE2;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
} // create device and exit if creation failed device = createDevice(driverType, core::dimension2d<s32>(640, 480));
if (device == 0) return 1;

Pokud bylo vytvoření úspěšné, zapneme náš event treceiver a vytvoříme potřebné ukazatele na GUI a VideoDriver. Připomínám že tyto řádky lze vynechat pokud v kódu nahradíte všechna driver a env za příslušné řádky (device->getVideoDriver() a device->getGUIEnvironment() ) tento zápis však přispěje k přehlednosti a jasnosti kódu.

MyEventReceiver receiver;

device->setEventReceiver(&receiver);

device->setWindowCaption(L"Irrlicht Engine - User Inferface Demo");
video::IVideoDriver* driver = device->getVideoDriver();

IGUIEnvironment* env = device->getGUIEnvironment();

Přidáme tři tlačítka. Jak již bylo řečeno: první ukončí program., druhé vytvoří okno a třetí otevře File Open okno pro otevření souboru (jedná se pouze o demonstraci prvků, čili žadný soubor nelze otevřít). Třetí parametr je id tlačítka potřebný pro event receiver.

env->addButton(rect<s32>(10,210,100,240), 0, 101, L"Quit");
env->addButton(rect<s32>(10,250,100,290), 0, 102, L"New Window");
env->addButton(rect<s32>(10,300,100,340), 0, 103, L"File Open");

Nyní přidáme statický (běžný) text a scroll bar (posuvník) který bude měnit průhlednost všech prvků rozhraní. Jako maximální hodnotu nastavíme 255 protože to je největší možná hodnota barvy. Dále přidáme statický text a list box.

env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);
IGUIScrollBar* scrollbar = env->addScrollBar(true, rect<s32>(150, 45, 350, 60), 0, 104);
scrollbar->setMax(255);
env->addStaticText(L"Logging ListBox:", rect<s32>(50,80,250,100), true);

listbox = env->addListBox(rect<s32>(50, 110, 250, 180));

Aby se v našem programu používal font který se nám líbí, nahradíme původní našim vlastním (musí být uložen jako obrázek. Pro převod z běžného fontu použijte program přiložený k enginu). Jako poslední přidáme logo enginu do levého horního rohu.
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
IGUIImage* img = env->addImage(
driver->getTexture("../../media/irrlichtlogoalpha.tga"),
position2d<int>(10,10));

Teď to jen všechno musíme vykreslit (jen připomenu že příkaz while testuje danou podmínku. Pokud je pravdivá, vykonává následující blok příkazů. To má za následek neustále obnovování scény.)

  while(device->run() && driver)
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(0,122,65,171)); env->drawAll(); driver->endScene(); } device->drop();
  return 0;

}

 

 

 


Kopírování obsahu bez souhlasu autorů je zakázáno.
Copyright 2007 Irrlicht3d.cz