Урок 5. Пользовательский интерфейс.
Автор: Иван Аракчеев
Этот урок покажет нам, как создавать пользовательский интерфейс в Irrlicht Engine. Мы научимся использовать кнопки, окна и прочие рюшечки. :)
Вот как будет выглядеть нижеописанная программа:
Поехали!
Как всегда пропишем необходимые заголовки файлов и пространства имён. Вам это уже знакомо. Дополнительно мы пропишем указатель на список (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 предназначен не только для получения сигналов от клавиатуры и мышки, также он перехватывает сообщения от GUI ( Graphical User Interface, Графический Интерфнйс Пользователя ). События есть для всего, для щелчка мышки, для изменения списка и так далее. Чтобы управлять всем этим создадим event receiver. Как только случится событие и это будет событие GUI, мы возьмём ID элемента вызвавшего событие, определим, что это за элемент и произведём некие действия.
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) {
Если линейка прокрутки изменит позицию и это будет "наша" линейка ( с ID = 104 ) мы изменим прозрачность всех GUI элементов.
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;
Если нажата первая кнопка, мы остановим движок, если вторая, то создадим маленькое окно с текстом, если же это будет третья, то мы откороем диалог открытия файла, а имя файла, которое выберет пользователь, добавим в список.
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, // модальное? L"Test window"); env->addStaticText( L"Please close me", rect<s32>( 35,35,140,50), true, // рамка?, false, // перенос слов? window); return true; } if ( id == 103) { listbox->addItem( L"File open"); env->addFileOpenDialog( L"Please choose a file."); return true; } break; } } return false; } };
Теперь начнём писать нашу главную функцию, начало вполне стандартное.
int main() { // позволим пользователю выбрать драйвер 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.2\n"\ " (d) Software Renderer\n (e) NullDevice\n (otherKey) exit\n\n"); char i; std::cin >> i; switch( i) { case 'a': driverType = video::EDT_DIRECTX9; break; case 'b': driverType = video::EDT_DIRECTX8; break; case 'c': driverType = video::EDT_OPENGL; break; case 'd': driverType = video::EDT_SOFTWARE; break; case 'e': driverType = video::EDT_NULL; break; default: return 1; } // создадим устройство и выйдем если не получится device = createDevice( driverType, core::dimension2d<s32>( 640, 480)); if ( device == 0) return 1;
OK, всё успешно инициализировалось, самое время получить указатель на видео драйвер и GUI.
MyEventReceiver receiver; device->setEventReceiver(&receiver); device->setWindowCaption( L"Irrlicht Engine - User Inferface Demo"); video::IVideoDriver* driver = device->getVideoDriver( ); IGUIEnvironment* env = device->getGUIEnvironment( );
Теперь добавим 3 кнопки.
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");
Теперь добавим текстовую метку и линейку прокрутки, меняющую прозраность элементов. Затем создадим другую текстовую метку и список.
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));
Чтобы сделать шрифт немного лучше мы загрузим внешний шрифт и установим его как основной.
IGUISkin* skin = env->getSkin(); IGUIFont* font = env->getFont( "../../media/fonthaettenschweiler.bmp"); if ( font) skin->setFont( font); IGUIImage* img = env->addImage( rect<int>( 10,10,98,41)); img->setImage( driver->getTexture( "../../media/irrlichtlogoaligned.jpg"));
Всё. Осталось написать цикл отрисовки.
while(device->run( ) && driver) if ( device->isWindowActive( )) { driver->beginScene( true, true, SColor( 0,122,65,171)); env->drawAll( ); driver->endScene( ); } device->drop( ); return 0; }
Компилируем и радуемся.
Оригинал: http://irrlicht.sourceforge.net/tut005.html
Перевод: http://irrlicht.kytron.com/
6 мая 2006 (Обновление: 24 сен 2006)
Комментарии [5]