enabled/disabled test for gui-elements

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

enabled/disabled test for gui-elements

Post by CuteAlien »

I was a little curious how the irrlicht gui elements behave when enabled/disabled, so I wrote a small test. The code is maybe also nice for testing other gui-features with minor modifications.

Code: Select all

#include <irrlicht.h>
#include <iostream>

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

enum
{
	GUI_ID_CHECKBOX_VISIBLE,
	GUI_ID_CHECKBOX_ENABLED,
};


struct SAppContext
{
	IrrlichtDevice * device;
	array<IGUIElement*> mGuiElements;
};


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();
			switch(event.GUIEvent.EventType)
			{
				case EGET_CHECKBOX_CHANGED:
				{
					IGUICheckBox *cb = static_cast<IGUICheckBox *>(event.GUIEvent.Caller);
					switch ( id )
					{
						case GUI_ID_CHECKBOX_VISIBLE:
							for ( u32 i=0; i < Context.mGuiElements.size(); ++i )
							{
								Context.mGuiElements[i]->setVisible( cb->isChecked() );
							}
							break;
						case GUI_ID_CHECKBOX_ENABLED:
							for ( u32 i=0; i < Context.mGuiElements.size(); ++i )
							{
								Context.mGuiElements[i]->setEnabled( cb->isChecked() );
							}
							break;
					default:
						break;
					}
					break;
				}
			default:
				break;
			}
		}

		return false;
	}

private:
	SAppContext & Context;
};


void AddTestGuiElements(IGUIEnvironment* env, IGUIElement * parent, SAppContext & context)
{
	context.mGuiElements.push_back( env->addToolBar (parent, /*s32 id=*/-1) );
	
	s32 top = 40;
	s32 default_height = 15;
	s32 default_width = 150;
	s32 default_gap = 30;
	core::rect<s32> rect(10, top, 10 + default_width, top + default_height);
	
	context.mGuiElements.push_back( env->addButton (rect, parent, /*s32 id=*/-1, /*const wchar_t *text=*/L"button", /*const wchar_t *tooltiptext=*/L"tooltip") );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;
	context.mGuiElements.push_back( env->addCheckBox (/*bool checked*/true, rect, parent, /*s32 id=*/-1, /*const wchar_t *text=*/L"checkbox") );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;
	IGUIComboBox * combo = env->addComboBox (rect, parent=0, /*s32 id=*/-1);
	combo->addItem(L"one");
	combo->addItem(L"two");
	context.mGuiElements.push_back( combo );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;
	context.mGuiElements.push_back( env->addEditBox (/*const wchar_t *text*/L"editbox", rect, /*bool border=*/true, parent, /*s32 id=*/-1) );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;	
	context.mGuiElements.push_back( env->addEditBox (/*const wchar_t *text*/L"", rect, /*bool border=*/true, parent, /*s32 id=*/-1) );			// no text 
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height*3;	
	IGUIListBox * lb = env->addListBox (rect, parent, /*s32 id=*/-1, /*bool drawBackground=*/true);
	lb->addItem(L"one");
	lb->addItem(L"two");
	context.mGuiElements.push_back( lb );	
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;	
	context.mGuiElements.push_back( env->addScrollBar (/*bool horizontal*/true, rect, parent, /*s32 id=*/-1) );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;	
	context.mGuiElements.push_back( env->addSpinBox (/*const wchar_t *text*/L"0", rect, /*bool border=*/true, parent, /*s32 id=*/-1) );
	
	
	rect.UpperLeftCorner.X = 10 + default_width + default_gap;
	rect.LowerRightCorner.X = rect.UpperLeftCorner.X + default_width;
	rect.UpperLeftCorner.Y = top;
	rect.LowerRightCorner.Y = top + default_height;	
	context.mGuiElements.push_back( env->addStaticText (/*const wchar_t *text*/L"static", rect, /*bool border=*/false, /*bool wordWrap=*/true, parent, /*s32 id=*/-1,/* bool fillBackground=*/true) );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height;	
	context.mGuiElements.push_back( env->addStaticText (/*const wchar_t *text*/L"", rect, /*bool border=*/true, /*bool wordWrap=*/true, parent, /*s32 id=*/-1,/* bool fillBackground=*/true) );	// no text
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 4*default_height;
	IGUITabControl * tabctrl = env->addTabControl (rect, parent, /*bool fillbackground=*/true, /*bool border=*/true, /*s32 id=*/-1);
	tabctrl->addTab(/*const wchar_t *caption*/L"tab1", /*s32 id=*/-1);
	tabctrl->addTab(/*const wchar_t *caption*/L"tab2", /*s32 id=*/-1);
	context.mGuiElements.push_back( tabctrl );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + default_height*3;	
	IGUITable * table = env->addTable (rect, parent, /*s32 id=*/-1, /*bool drawBackground=*/true);
	table->addColumn(L"col1");
	table->addColumn(L"col2");
	table->addRow(0);
	table->addRow(1);
	table->setCellText(/*u32 rowIndex*/1, /*u32 columnIndex*/1, /*const wchar_t *text*/L"text");
	context.mGuiElements.push_back(table );
	
	rect.UpperLeftCorner.Y = rect.LowerRightCorner.Y + default_gap;
	rect.LowerRightCorner.Y = rect.UpperLeftCorner.Y + 4*default_height;	
	context.mGuiElements.push_back( env->addWindow (rect, /*bool modal=*/false, /*const wchar_t *text=*/L"window", parent, /*s32 id=*/-1) );	
}

void AddControlElements(IGUIEnvironment* env, IGUIElement * parent)
{
	env->addStaticText (/*const wchar_t *text*/L"", rect<s32>(500, 50, 630, 480), /*bool border=*/true, /*bool wordWrap=*/false, parent, /*s32 id=*/-1,/* bool fillBackground=*/false);
	env->addCheckBox (/*bool checked*/true, rect<s32>(510, 60, 620, 80), parent, /*s32 id=*/GUI_ID_CHECKBOX_VISIBLE, /*const wchar_t *text=*/L"visible");
	env->addCheckBox (/*bool checked*/true, rect<s32>(510, 100, 620, 120), parent, /*s32 id=*/GUI_ID_CHECKBOX_ENABLED, /*const wchar_t *text=*/L"enabled");
}

int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
	IrrlichtDevice * device = createDevice(driverType, core::dimension2d<u32>(640, 480));
	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	IGUIEnvironment* env = device->getGUIEnvironment();
	
	SAppContext context;
	context.device = device;
	AddTestGuiElements(env, 0, context);
	MyEventReceiver receiver(context);
	device->setEventReceiver(&receiver);
	
	AddControlElements(env, 0);
	
	while(device->run() && driver)
	{
		if (device->isWindowActive())
		{
			driver->beginScene(true, true, SColor(0,200,200,200));
	
			env->drawAll();
		
			driver->endScene();
		}
	}

	device->drop();

	return 0;
}
Personally I would prefer seeing a few things handled different:
- checkboxtext should have disabled color
- editbox background should have a new EGUI_DEFAULT_COLOR for the state when text can be entered
- combobox icon should change color
- listbox textcolors (and/or backgrounds) should change color
- scrollbar icons should change color
- spinbox should set textcolor and iconcolors
- not sure about static-background - I guess I would let it as it is
- tabcontrol header texts should change color
- not sure about windows - I guess I would also let it be
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

nice work 8)
estamisu
Posts: 15
Joined: Thu Mar 18, 2010 12:06 am

Great Work

Post by estamisu »

Hi
this is great work

But can you explain why should we use SAppContext. I tried without this struct but I can not see result. Can you give some information???????
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

SAppContext is used here to pass variables to the eventreceiver (MyEventReceiver ) which otherwise wouldn't have access to them. The alternative would be global variables which would also be OK in such a short example, but using globals is a bad practice as they will make your code harder to read in larger applications and so I just avoid them always.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply