http://irrlicht.sourceforge.net/

Çeviri : Yunus Kara (www.darkscythe.net)

Örnek 5.Kullanıcı Arayüzü

Bu örnekte irrlicht motorundaki dahili grafik arayüzünün kullanımını ele alacağız. Grafik arayüzden kısaca bahsettikten sonra pencere,buton,kaydırma çubuğu,sabit yazılar ve liste kutularının kullanımını örnekleyeceğiz.

Açıklayacağımız program şuna benzeyecek:



Başlıyoruz!

Her zamanki gibi başlık dosyalarını ekleyip, ad uzayı kullanımını belirtiyoruz. Sonra kütüphane dosyamızı 'link' ediyoruz. Ayrıca 'Device' nesnemize bir gösterici, bir sayaç değişkeni(pencere oluşum yerini ayarlamak için) ve bir liste kutusu nesnesini gösteren bir gösterici tanımlıyoruz.

#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;

Olay kotarıcı(Event Receiver) sadece klavye ve fare olaylarını algılamakla kalmaz, kullanıcı arayüzünün sağladığı tüm olayları(buton tıklama,listeden bir eleman seçme vb.) işleyebilir. Arayüz elemanlarına tepki verebilmek için bir olay kotarıcı oluşturuyoruz.Bu örnekte sadece arayüz olaylarına reaksiyon gösteren bir olay kotarıcı yazacağız. Bir olay gerçekleştiğinde (buton tıklama gibi) olay çağırıcısının (olay yaratan arayüz elemanı[tıklanan buton vb.]) id'sini alıyoruz(arayüz nesnesini oluştururken id'sini biz belirliyoruz) ve bu elemanın göstericisini elde ediyoruz. Burada fazladan şuna değinmek istiyorum. Irrlicht motorunda s32,u32,f32 vb. değişken tipleri ile karşılaşabilirsiniz. Bunlar aslında sadece birer isim değişikliğidir. s32 'signed integer' anlamında 32 bitlik bir int'dir. f32'yi sizde tahmin ediyorsunuzdur, 32 bitlik bir float.

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)
            {

Eğer bir kaydırma çubuğunun çubuk pozisyonu değiştirilirse(burada bizim id'sini belirlediğimiz nesnenin olayını işliyoruz), pozisyona göre tüm arayüz elemanlarının görünürlük(transparancy) oranını değiştiriyoruz.Bu basit bir işlem: Tüm renk ayarlarının bulunduğu bir 'skin' nesnesi vardır. Sadece bu nesnedeki tüm renklerin 'alpha' değerlerini değiştiriyoruz.

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;

Eğer bir buton tıklandı ise, bu bizim 3 butonumuzdan biri olabilir :).Id'sine göre kontrol ediyoruz. Eğer ilki ise motoru kapatıyoruz. İkincisi ise üzerinde yazı bulunan bir pencere oluşturuyoruz. 3. buton tıklanırsa bir dosya açma arayüzü oluşturuyoruz. Ayrıca liste kutusuna 'log' benzeri yapılan eylemi belirten yazı ekliyoruz. Olay kotarıcı için yapılacaklar bu kadar.

       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;
    }
 };

Şimdi biraz eyleme geçelim. Önce irrlicht device'ı oluşturuyoruz. Önceki örneklerdeki gibi kullanıcıya hangi sürücüyü kullanmak istediğini soruyoruz(DX,GL vb).

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;

Buradan sonra, olay kotarıcıyı ayarlayıp 'VideoDriver' ve 'GUIEnvironment' nesnelerine birer gösterici tanımlıyoruz.

MyEventReceiver receiver;
device->setEventReceiver(&receiver);
device->setWindowCaption(L"Irrlicht Engine - User Inferface Demo");
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();

3 buton ekledik. Birincisi motoru kapatıyor. İkincisi bir pencere oluşturuyor ve üçüncüsü bir dosya açma arayüzü oluşturuyor.Buradaki 3. parametre nesnenin 'id' sini belirtiyor.'id' özelliğini kullanarak olay kotarıcıdan kolayca bu nesneye ulaşabiliyoruz.

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");

Şimdi, sabit bir yazı ve bir kaydırma çubuğu ekliyoruz. Kaydırma çubuğunun işlevinden bahsetmiştik. Kaydırma çubuğunun maximum değerini 255 olarak ayarlıyoruz çünkü bir renk değerinin maximum değeri 255'dir.
Sonra bir başka sabit yazı ve bir liste(listbox) oluşturuyoruz.

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));

Yazı tipi değişikliği yapabilmek için harici bir font yükleyip 'skin' nesnesinin yazı tipi olarak ayarlıyoruz(yeni fontlar oluşturabilmek için irrlicht sdk'sı ile birlikte bir tool gelmektedir). Son olarak sol üst köşede bir irrlicht logosu oluşturuyoruz.

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));

Hepsi bu kadar, şimdi sadece herşeyi çizdirmemiz gerekiyor.

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