10-08-2015, 12:51 PM
(Questo messaggio è stato modificato l'ultima volta il: 10-08-2015, 12:52 PM da Chip.)
Tutorial 5: User Interface
Questo tutorial spiega come utilizzare la User Interface (UI) integrata in Irrlicht Engine. Verrà fornita una breve panoramica su come si creano finestre, pulsanti, scrollbars, etichette di testo e listbox. Come sempre iniziamo mostrando l'header dove si utilizza il namespace irr e diamo indicazioni al linker di inserire la libreria irrlicht.lib. Creiamo anche una variabile puntatore al device Irrlicht, una variabile per gestire la posizione della finestra e un puntatore ad una listbox.
Variamo la trasparenza dello skin della nostra GUI agendo sul valore alpha della proprietà skin-colors.
L'Event Receiver non è solo in grado di catturare gli eventi dalla tastiera o dal mouse, può anche catturare gli eventi che provengono dalla GUI. Ogni componente ha i suoi eventi: un click sul pulsante, la selezione di un range per la Listbox, tutti eventi che ci dicono quando un elemento ha interagito con i nostri input. Per gestire la reazione a questi eventi creiamo un event receiver. Reagiremo solo ad eventi della GUI e quando ciò accadrà andremo a prenderci l'id del chiamante (cioè identifichiamo chi della componente GUI ha sollevato l'evento) e con questo otterremo il puntatore a quell'elemento grafico.
Quando la scrollbar cambia la sua posizione e capiamo che si tratta della “nostra” (quella con l'id GUI_ID_TRANSPARENCY_SCROLL_BAR) allora andremo a cambiare la trasparenza di tutti gli elementi della GUI. La cosa è facile perché c'è l'oggetto skin che contiene tutti i settaggi dei colori. Basterà scorrerci tutti questi valori e cambiare di conseguenza il valore alpha.
Quando un pulsante è premuto ed è uno dei nostri. Se è il primo chiudiamo l'engine. Se il secondo andiamo a creare un'altra finestra con del testo dentro “Test windows”. Inseriamo anche nella listbox che fa da log quello che accade. Se è il terzo pulsante apriamo una finestra di dialogo di tipo “Apri file” e anche in questo caso aggiungiamo al log sulla listbox. Questo è tutto per levent receiver.
Ok ora la parte più interessante. Primo creiamo il device Irrlicht. Come in un esempio precedente chiediamo all'utente che genere di device vuole utilizzare (risoluzione, ecc..):
Se il device è stato creato correttamente settiamo il nostro event receiver e prendiamoci il puntatore al nostro driver e quello del nostro nuovi ambiente GUI.
Per rendere il font un po' più carino, carichiamone uno esterno e lo settiamo come default per la skin della nostra GUI. Per mantenere invece il font standard sui tool tip, lo andiamo a reimpostare tramite la proprietà getBuiltInFont().
Aggiungiamo i tre pulsanti. Il primo chiude l'engine. Il secondo crea una finestra e il terzo apre una finestra di dialogo. Il terzo parametro è l'id del pulsante, con cui potremo facilmente identificarlo quando saremo nell'event receiver.
Ora aggiungiamo un'etichetta testo e una scrollbar che modichi la trasparenza di tutti gli elementi della GUI. Impostiamo il valore massimo della scrollbar a 255, perché è il massimo che il valore dei colori può assumere. Quindi creiamo l'etichetta di test e una listbox.
Alla fine creiamo un simpatico logo dell'Irrlicht Engine in alto a sinistra.
Questo è tutto, non resta che disegnare tutto quanto.
Versione pdf da scaricare QUI
Questo tutorial spiega come utilizzare la User Interface (UI) integrata in Irrlicht Engine. Verrà fornita una breve panoramica su come si creano finestre, pulsanti, scrollbars, etichette di testo e listbox. Come sempre iniziamo mostrando l'header dove si utilizza il namespace irr e diamo indicazioni al linker di inserire la libreria irrlicht.lib. Creiamo anche una variabile puntatore al device Irrlicht, una variabile per gestire la posizione della finestra e un puntatore ad una listbox.
Codice PHP:
#include <irrlicht.h>
#include "driverChoice.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif
// Declare a structure to hold some context for the event receiver so that it
// has it available inside its OnEvent() method.
struct SAppContext
{
IrrlichtDevice *device;
s32 counter;
IGUIListBox* listbox;
};
// Define some values that we'll use to identify individual GUI controls.
enum
{
GUI_ID_QUIT_BUTTON = 101,
GUI_ID_NEW_WINDOW_BUTTON,
GUI_ID_FILE_OPEN_BUTTON,
GUI_ID_TRANSPARENCY_SCROLL_BAR
};
Codice PHP:
void setSkinTransparency(s32 alpha, irr::gui::IGUISkin * skin)
{
for (s32 i=0; i<irr::gui::EGDC_COUNT ; ++i)
{
video::SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
col.setAlpha(alpha);
skin->setColor((EGUI_DEFAULT_COLOR)i, col);
}
}
Codice PHP:
class MyEventReceiver : public IEventReceiver
{
public:
MyEventReceiver(SAppContext & context) : Context(context) { }
virtual bool OnEvent(const SEvent& event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
IGUIEnvironment* env = Context.device->getGUIEnvironment();
switch(event.GUIEvent.EventType)
{
Codice PHP:
case EGET_SCROLL_BAR_CHANGED:
if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
setSkinTransparency(pos, env->getSkin());
}
break;
Codice PHP:
case EGET_BUTTON_CLICKED:
switch(id)
{
case GUI_ID_QUIT_BUTTON:
Context.device->closeDevice();
return true;
case GUI_ID_NEW_WINDOW_BUTTON:
{
Context.listbox->addItem(L"Window created");
Context.counter += 30;
if (Context.counter > 200)
Context.counter = 0;
IGUIWindow* window = env->addWindow(
rect<s32>(100 + Context.counter, 100 + Context.counter, 300 + Context.counter, 200 + Context.counter),
false, // modal?
L"Test window");
env->addStaticText(L"Please close me",
rect<s32>(35,35,140,50),
true, // border?
false, // wordwrap?
window);
}
return true;
case GUI_ID_FILE_OPEN_BUTTON:
Context.listbox->addItem(L"File open");
// There are some options for the file open dialog
// We set the title, make it a modal window, and make sure
// that the working directory is restored after the dialog
// is finished.
env->addFileOpenDialog(L"Please choose a file.", true, 0, -1, true);
return true;
default:
return false;
}
break;
case EGET_FILE_SELECTED:
{
// show the model filename, selected in the file dialog
IGUIFileOpenDialog* dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
Context.listbox->addItem(dialog->getFileName());
}
break;
default:
break;
}
}
return false;
}
private:
SAppContext & Context;
};
Codice PHP:
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device and exit if creation failed
IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
Codice PHP:
device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
device->setResizable(true);
video::IVideoDriver* driver = device->getVideoDriver();
IGUIEnvironment* env = device->getGUIEnvironment();
Codice PHP:
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
Codice PHP:
env->addButton(rect<s32>(10,240,110,240 + 32), 0, GUI_ID_QUIT_BUTTON,
L"Quit", L"Exits Program");
env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_NEW_WINDOW_BUTTON,
L"New Window", L"Launches a new Window");
env->addButton(rect<s32>(10,320,110,320 + 32), 0, GUI_ID_FILE_OPEN_BUTTON,
L"File Open", L"Opens a file");
Codice PHP:
env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);
IGUIScrollBar* scrollbar = env->addScrollBar(true,
rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
scrollbar->setMax(255);
scrollbar->setPos(255);
setSkinTransparency( scrollbar->getPos(), env->getSkin());
// set scrollbar position to alpha value of an arbitrary element
scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
env->addStaticText(L"Logging ListBox:", rect<s32>(50,110,250,130), true);
IGUIListBox * listbox = env->addListBox(rect<s32>(50, 140, 250, 210));
env->addEditBox(L"Editable Text", rect<s32>(350, 80, 550, 100));
// Store the appropriate data in a context structure.
SAppContext context;
context.device = device;
context.counter = 0;
context.listbox = listbox;
// Then create the event receiver, giving it that context structure.
MyEventReceiver receiver(context);
// And tell the device to use our custom event receiver.
device->setEventReceiver(&receiver);
Codice PHP:
env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
position2d<int>(10,10));
Codice PHP:
while(device->run() && driver)
if (device->isWindowActive())
{
driver->beginScene(true, true, SColor(0,200,200,200));
env->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Versione pdf da scaricare QUI