I've tried various ways but always end up with seg faults and I'm not sure why or how to seek help for such. Here's one version which attempts to put the gui setup code in its own function (I'd prefer it in a class initialised from within xeng):
main.cpp
Code: Select all
/** Example 005 User Interface
*/
#include <irrlicht.h>
#include "driverChoice.h"
#include "xeng.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
struct SAppContext
{
IrrlichtDevice *device;
s32 counter;
IGUIListBox* listbox;
};
enum{
GUI_ID_QUIT_BUTTON = 101,
GUI_ID_NEW_WINDOW_BUTTON,
GUI_ID_FILE_OPEN_BUTTON,
GUI_ID_TRANSPARENCY_SCROLL_BAR
};
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);
}
}
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)
{
case EGET_SCROLL_BAR_CHANGED:
if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
{
s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
setSkinTransparency(pos, env->getSkin());
}
break;
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");
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;
};
void app_init_gui(IrrlichtDevice *device, video::IVideoDriver* driver, gui::IGUIEnvironment* env){
// We add three buttons. The first one closes the engine. The second
// creates a window and the third opens a file open dialog. The third
// parameter is the id of the button, with which we can easily identify
// the button in the event receiver.
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");
// Now, we add a static text and a scrollbar, which modifies the
// transparency of all gui elements. We set the maximum value of
// the scrollbar to 255, because that's the maximal value for
// a color value.
// Then we create an other static text and 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, 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);
// And at last, we create a nice Irrlicht Engine logo in the top left corner.
env->addImage(driver->getTexture("data/irrlichtlogo2.png"),position2d<int>(10,10));
}
int main()
{
Xeng eng;
int iret=eng.init();
// TMP
IrrlichtDevice* device = eng.device;
video::IVideoDriver* driver = eng.driver;
gui::IGUIEnvironment* env = eng.env;
app_init_gui(device,driver,env);
// That's all, we only have to draw everything.
eng.loop();
return 0;
}
xeng.h
Code: Select all
#ifndef ___XAPP
#define ___XAPP
#include <irrlicht.h>
#include "driverChoice.h"
//#include "xapp.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
class Xeng{
public:
int init();
int init_driver();
int init_basics();
int loop();
IrrlichtDevice * device;
video::IVideoDriver* driver;
gui::IGUIEnvironment* env;
//Xapp* app;
};
#endif
xeng.cpp
Code: Select all
#include "xeng.h"
#include <iostream>
using namespace std;
int Xeng::loop(){
while(device->run() && driver){
if (device->isWindowActive()){
driver->beginScene(true, true, SColor(0,200,200,200));
env->drawAll();
driver->endScene();
}
}
device->drop();
return 0;
}
int Xeng::init()
{
cout << "Xeng init()" << endl;
int iret=init_driver();
iret=init_basics();
/*
//Xapp app;
app = new Xapp();
//iret=app->init(device,driver,env);
app->device=device;
app->driver=driver;
app->env=env;
iret=app->init();
*/
return 0;
}
int Xeng::init_driver(){
device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(640, 480));
//if (device == 0)
// return 1; // could not create selected driver.
return 1;
}
int Xeng::init_basics(){
device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
device->setResizable(true);
driver = device->getVideoDriver();
env = device->getGUIEnvironment();
IGUISkin* skin = env->getSkin();
IGUIFont* font = env->getFont("data/fonthaettenschweiler.bmp");
if (font)
skin->setFont(font);
skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
return 1;
}
Many thanks
EDIT: Changed #ifndef in xeng.h