Posted By

xterminhate on 03/05/13


Tagged

CGUIDynamicGrid


Versions (?)

main.cpp


 / Published in: C++
 

URL: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=48291&p=278332#p278332

http://irrlicht.sourceforge.net/forum/viewtopic.php?f=9&t=48291&p=278332#p278332

  1. /** Example 005 User Interface
  2.  
  3. This tutorial shows how to use the built in User Interface of
  4. the Irrlicht Engine. It will give a brief overview and show
  5. how to create and use windows, buttons, scroll bars, static
  6. texts, and list boxes.
  7.  
  8. As always, we include the header files, and use the irrlicht
  9. namespaces. We also store a pointer to the Irrlicht device,
  10. a counter variable for changing the creation position of a window,
  11. and a pointer to a listbox.
  12. */
  13. #include <irrlicht.h>
  14. //#include "driverChoice.h"
  15. #include "CGUIDynamicGrid.h"
  16.  
  17. using namespace irr;
  18.  
  19. using namespace core;
  20. using namespace scene;
  21. using namespace video;
  22. using namespace io;
  23. using namespace gui;
  24.  
  25. #ifdef _IRR_WINDOWS_
  26. #pragma comment(lib, "Irrlicht.lib")
  27. #endif
  28.  
  29. // Declare a structure to hold some context for the event receiver so that it
  30. // has it available inside its OnEvent() method.
  31. struct SAppContext
  32. {
  33. IrrlichtDevice *device;
  34. s32 counter;
  35. IGUIListBox* listbox;
  36. IGUIDynamicGrid * grid; ///< ADDED
  37. };
  38.  
  39. // Define some values that we'll use to identify individual GUI controls.
  40. enum
  41. {
  42. GUI_ID_QUIT_BUTTON = 101,
  43. GUI_ID_NEW_SMALL_WINDOW_BUTTON, ///< ADDED
  44. GUI_ID_NEW_LARGE_WINDOW_BUTTON, ///< ADDED
  45. GUI_ID_FILE_OPEN_BUTTON,
  46. GUI_ID_TRANSPARENCY_SCROLL_BAR,
  47. GUI_ID_SHOW_JOINTS_BUTTON, ///< ADDED
  48. GUI_ID_HIDE_JOINTS_BUTTON, ///< ADDED
  49. GUI_ID_GRID_RESET, ///< ADDED
  50. GUI_ID_GRID_ATTACH_RUN_ONCE, ///< ADDED
  51. GUI_ID_GRID_ATTACH_FOCUSED, ///< ADDED
  52. GUI_ID_GRID_RUN, ///< ADDED
  53. GUI_ID_GRID_DETACH_FOCUSED, ///< ADDED
  54. GUI_ID_GRID_DETACH_ALL ///< ADDED
  55. };
  56.  
  57. /*
  58. The Event Receiver is not only capable of getting keyboard and
  59. mouse input events, but also events of the graphical user interface
  60. (gui). There are events for almost everything: Button click,
  61. Listbox selection change, events that say that a element was hovered
  62. and so on. To be able to react to some of these events, we create
  63. an event receiver.
  64. We only react to gui events, and if it's such an event, we get the
  65. id of the caller (the gui element which caused the event) and get
  66. the pointer to the gui environment.
  67. */
  68. class MyEventReceiver : public IEventReceiver
  69. {
  70. public:
  71. MyEventReceiver(SAppContext & context) : Context(context) { }
  72.  
  73. virtual bool OnEvent(const SEvent& event)
  74. {
  75. if (event.EventType == EET_GUI_EVENT)
  76. {
  77. s32 id = event.GUIEvent.Caller->getID();
  78. IGUIEnvironment* env = Context.device->getGUIEnvironment();
  79.  
  80. switch(event.GUIEvent.EventType)
  81. {
  82.  
  83. /*
  84. If a scrollbar changed its scroll position, and it is
  85. 'our' scrollbar (the one with id GUI_ID_TRANSPARENCY_SCROLL_BAR), then we change
  86. the transparency of all gui elements. This is a very
  87. easy task: There is a skin object, in which all color
  88. settings are stored. We simply go through all colors
  89. stored in the skin and change their alpha value.
  90. */
  91. case EGET_SCROLL_BAR_CHANGED:
  92. if (id == GUI_ID_TRANSPARENCY_SCROLL_BAR)
  93. {
  94. s32 pos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
  95.  
  96. for (u32 i=0; i<EGDC_COUNT ; ++i)
  97. {
  98. SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
  99. col.setAlpha(pos);
  100. env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
  101. }
  102.  
  103. }
  104. break;
  105.  
  106. /*
  107. If a button was clicked, it could be one of 'our'
  108. three buttons. If it is the first, we shut down the engine.
  109. If it is the second, we create a little window with some
  110. text on it. We also add a string to the list box to log
  111. what happened. And if it is the third button, we create
  112. a file open dialog, and add also this as string to the list box.
  113. That's all for the event receiver.
  114. */
  115. case EGET_BUTTON_CLICKED:
  116. switch(id)
  117. {
  118. case GUI_ID_QUIT_BUTTON:
  119. Context.device->closeDevice();
  120. return true;
  121.  
  122. case GUI_ID_NEW_SMALL_WINDOW_BUTTON:
  123. {
  124. Context.listbox->addItem(L"Small Window created");
  125. Context.counter += 60;
  126. if (Context.counter > 500)
  127. Context.counter = 0;
  128.  
  129. IGUIWindow* window = env->addWindow(
  130. rect<s32>(150 + Context.counter, 100 + Context.counter, 350 + Context.counter, 200 + Context.counter),
  131. false, // modal?
  132. L"Test window",
  133. Context.grid);
  134.  
  135. env->addStaticText(L"Please close me",
  136. rect<s32>(35,35,140,50),
  137. true, // border?
  138. false, // wordwrap?
  139. window);
  140. EGUI_DYNAMIC_GRID_BEHAVIOR previous_behavior = Context.grid->getBehavior();
  141. Context.grid->setBehavior(EGDGB_RESET); ///< Need to stop dynamic grid as it is not possible to detect new child GUI element (Irr 1.8)
  142. Context.grid->setBehavior(EGDGB_ATTACH_RUN_ONCE); ///< Try to reattach all
  143. Context.grid->setBehavior(previous_behavior); ///< Restore behavior
  144. }
  145. return true;
  146.  
  147. case GUI_ID_NEW_LARGE_WINDOW_BUTTON:
  148. {
  149. Context.listbox->addItem(L"Large Window created");
  150. Context.counter += 60;
  151. if (Context.counter > 500)
  152. Context.counter = 0;
  153.  
  154. IGUIWindow* window = env->addWindow(
  155. rect<s32>(150 + Context.counter, 100 + Context.counter, 550 + Context.counter, 300 + Context.counter),
  156. false, // modal?
  157. L"Test window",
  158. Context.grid);
  159.  
  160. env->addStaticText(L"Please close me",
  161. rect<s32>(35,35,140,50),
  162. true, // border?
  163. false, // wordwrap?
  164. window);
  165. EGUI_DYNAMIC_GRID_BEHAVIOR previous_behavior = Context.grid->getBehavior();
  166. Context.grid->setBehavior(EGDGB_RESET); ///< Need to stop dynamic grid as it is not possible to detect new child GUI element (Irr 1.8)
  167. Context.grid->setBehavior(EGDGB_ATTACH_RUN_ONCE); ///< Try to reattach all
  168. Context.grid->setBehavior(previous_behavior); ///< Restore behavior
  169. }
  170. return true;
  171.  
  172. case GUI_ID_FILE_OPEN_BUTTON:
  173. {
  174. Context.listbox->addItem(L"File open");
  175. // There are some options for the file open dialog
  176. // We set the title, make it a modal window, and make sure
  177. // that the working directory is restored after the dialog
  178. // is finished.
  179. env->addFileOpenDialog(L"Please choose a file.", true, 0, -1, true);
  180. EGUI_DYNAMIC_GRID_BEHAVIOR previous_behavior = Context.grid->getBehavior();
  181. Context.grid->setBehavior(EGDGB_RESET); ///< Need to stop dynamic grid as it is not possible to detect new child GUI element (Irr 1.8)
  182. Context.grid->setBehavior(EGDGB_ATTACH_RUN_ONCE); ///< Try to reattach all
  183. Context.grid->setBehavior(previous_behavior); ///< Restore behavior
  184. }
  185. return true;
  186.  
  187. case GUI_ID_SHOW_JOINTS_BUTTON:
  188. Context.grid->setJointVisible(true);
  189. return true;
  190.  
  191. case GUI_ID_HIDE_JOINTS_BUTTON:
  192. Context.grid->setJointVisible(false);
  193. return true;
  194.  
  195. case GUI_ID_GRID_RESET:
  196. case GUI_ID_GRID_ATTACH_RUN_ONCE:
  197. case GUI_ID_GRID_ATTACH_FOCUSED:
  198. case GUI_ID_GRID_RUN:
  199. case GUI_ID_GRID_DETACH_FOCUSED:
  200. case GUI_ID_GRID_DETACH_ALL:
  201. Context.grid->setBehavior((EGUI_DYNAMIC_GRID_BEHAVIOR)(id-GUI_ID_GRID_RESET));
  202. return true;
  203.  
  204.  
  205. default:
  206. return false;
  207. }
  208. break;
  209.  
  210. case EGET_FILE_SELECTED:
  211. {
  212. // show the model filename, selected in the file dialog
  213. IGUIFileOpenDialog* dialog =
  214. (IGUIFileOpenDialog*)event.GUIEvent.Caller;
  215. Context.listbox->addItem(dialog->getFileName());
  216. }
  217. break;
  218.  
  219. default:
  220. break;
  221. }
  222. }
  223.  
  224. return false;
  225. }
  226.  
  227. private:
  228. SAppContext & Context;
  229. };
  230.  
  231.  
  232. /*
  233. Ok, now for the more interesting part. First, create the Irrlicht device. As in
  234. some examples before, we ask the user which driver he wants to use for this
  235. example:
  236. */
  237. int main()
  238. {
  239. // // ask user for driver
  240. // video::E_DRIVER_TYPE driverType=driverChoiceConsole();
  241. // if (driverType==video::EDT_COUNT)
  242. // return 1;
  243.  
  244. // create device and exit if creation failed
  245.  
  246. IrrlichtDevice * device = createDevice(video::EDT_OPENGL , core::dimension2d<u32>(800, 600));
  247.  
  248. if (device == 0)
  249. return 1; // could not create selected driver.
  250.  
  251. /* The creation was successful, now we set the event receiver and
  252. store pointers to the driver and to the gui environment. */
  253.  
  254. device->setWindowCaption(L"Irrlicht Engine - User Interface Demo");
  255. device->setResizable(true);
  256.  
  257. video::IVideoDriver* driver = device->getVideoDriver();
  258. IGUIEnvironment* env = device->getGUIEnvironment();
  259.  
  260. /*
  261. To make the font a little bit nicer, we load an external font
  262. and set it as the new default font in the skin.
  263. To keep the standard font for tool tip text, we set it to
  264. the built-in font.
  265. */
  266.  
  267. IGUISkin* skin = env->getSkin();
  268. IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
  269. if (font)
  270. skin->setFont(font);
  271.  
  272. skin->setFont(env->getBuiltInFont(), EGDF_TOOLTIP);
  273.  
  274. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  275. /// Add a dynamic grid (first GUI root child = background GUI = last called when event)
  276. IGUIDynamicGrid * grid = new CGUIDynamicGrid( env, env->getRootGUIElement() );
  277. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  278.  
  279. /*
  280. We add three buttons. The first one closes the engine. The second
  281. creates a window and the third opens a file open dialog. The third
  282. parameter is the id of the button, with which we can easily identify
  283. the button in the event receiver.
  284. */
  285.  
  286. env->addButton(rect<s32>(10,240,110,240 + 32), 0, GUI_ID_QUIT_BUTTON,
  287. L"Quit", L"Exits Program");
  288. env->addButton(rect<s32>(10,280,110,280 + 32), 0, GUI_ID_NEW_SMALL_WINDOW_BUTTON,
  289. L"New Small Window", L"Launches a new Window");
  290. env->addButton(rect<s32>(10,320,110,320 + 32), 0, GUI_ID_NEW_LARGE_WINDOW_BUTTON,
  291. L"New Large Window", L"Launches a new Window");
  292. env->addButton(rect<s32>(10,360,110,360 + 32), 0, GUI_ID_FILE_OPEN_BUTTON,
  293. L"File Open", L"Opens a file");
  294. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  295. /// Add a few controls to control the dynamic grad behavior and appearance
  296. env->addButton(rect<s32>(10,440,120,460), 0, GUI_ID_SHOW_JOINTS_BUTTON,
  297. L"Show Joints", L"DYNAMIC GRID DEBUG : Shows the joints");
  298. env->addButton(rect<s32>(130,440,240,460), 0, GUI_ID_HIDE_JOINTS_BUTTON,
  299. L"Hide Joints", L"DYNAMIC GRID DEBUG : Hides the joints");
  300. IGUIStaticText * behavior = env->addStaticText(0, rect<s32>(10,470,240,490), true );
  301. env->addButton(rect<s32>(10,500,120,520), 0, GUI_ID_GRID_RESET,
  302. stringw(GUIDynamicGridBehaviorNames[0]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  303. env->addButton(rect<s32>(130,500,240,520), 0, GUI_ID_GRID_ATTACH_RUN_ONCE,
  304. stringw(GUIDynamicGridBehaviorNames[1]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  305. env->addButton(rect<s32>(10,530,120,550), 0, GUI_ID_GRID_ATTACH_FOCUSED,
  306. stringw(GUIDynamicGridBehaviorNames[2]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  307. env->addButton(rect<s32>(130,530,240,550), 0, GUI_ID_GRID_RUN,
  308. stringw(GUIDynamicGridBehaviorNames[3]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  309. env->addButton(rect<s32>(10,560,120,580), 0, GUI_ID_GRID_DETACH_FOCUSED,
  310. stringw(GUIDynamicGridBehaviorNames[4]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  311. env->addButton(rect<s32>(130,560,240,580), 0, GUI_ID_GRID_DETACH_ALL,
  312. stringw(GUIDynamicGridBehaviorNames[5]).c_str(), L"DYNAMIC GRID BEHAVIOR : Reset");
  313. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  314.  
  315. /*
  316. Now, we add a static text and a scrollbar, which modifies the
  317. transparency of all gui elements. We set the maximum value of
  318. the scrollbar to 255, because that's the maximal value for
  319. a color value.
  320. Then we create an other static text and a list box.
  321. */
  322.  
  323. env->addStaticText(L"Transparent Control:", rect<s32>(150,20,350,40), true);
  324. IGUIScrollBar* scrollbar = env->addScrollBar(true,
  325. rect<s32>(150, 45, 350, 60), 0, GUI_ID_TRANSPARENCY_SCROLL_BAR);
  326. scrollbar->setMax(255);
  327.  
  328. // set scrollbar position to alpha value of an arbitrary element
  329. scrollbar->setPos(env->getSkin()->getColor(EGDC_WINDOW).getAlpha());
  330.  
  331. env->addStaticText(L"Logging ListBox:", rect<s32>(50,110,250,130), true);
  332. IGUIListBox * listbox = env->addListBox(rect<s32>(50, 140, 250, 210));
  333.  
  334. // Store the appropriate data in a context structure.
  335. SAppContext context;
  336. context.device = device;
  337. context.counter = 0;
  338. context.listbox = listbox;
  339. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  340. /// Add dynamic grid to context
  341. context.grid = grid;
  342. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
  343.  
  344. // Then create the event receiver, giving it that context structure.
  345. MyEventReceiver receiver(context);
  346.  
  347. // And tell the device to use our custom event receiver.
  348. device->setEventReceiver(&receiver);
  349.  
  350. /*
  351. And at last, we create a nice Irrlicht Engine logo in the top left corner.
  352. */
  353. env->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
  354. position2d<int>(10,10));
  355.  
  356. /*
  357. That's all, we only have to draw everything.
  358. */
  359.  
  360. while(device->run() && driver)
  361. if (device->isWindowActive())
  362. {
  363. behavior->setText( stringw(GUIDynamicGridBehaviorNames[grid->getBehavior()]).c_str() );
  364. driver->beginScene(true, true, SColor(0,200,200,200));
  365.  
  366. env->drawAll();
  367.  
  368. driver->endScene();
  369. }
  370.  
  371. device->drop();
  372.  
  373. return 0;
  374. }
  375.  
  376. /*
  377. **/

Report this snippet  

You need to login to post a comment.