tutorial.html 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
  5. <meta http-equiv="X-UA-Compatible" content="IE=9"/>
  6. <meta name="generator" content="Doxygen 1.8.13"/>
  7. <meta name="viewport" content="width=device-width, initial-scale=1"/>
  8. <title>Tutorial 24: CursorControl</title>
  9. <html xmlns="http://www.w3.org/1999/xhtml">
  10. <!-- Wanted to avoid copying .css to each folder, so copied default .css from doxyen in here, kicked out most stuff we don't need for examples and modified some a little bit.
  11. Target was having a single html in each example folder which is created from the main.cpp files and needs no files besides some images below media folder.
  12. Feel free to improve :)
  13. -->
  14. <style>
  15. body, table, div, p, dl {
  16. font: 400 14px/22px;
  17. }
  18. body {
  19. background-color: #F0F0F0;
  20. color: black;
  21. margin-left: 5%;
  22. margin-right: 5%;
  23. }
  24. p.reference, p.definition {
  25. font: 400 14px/22px;
  26. }
  27. .title {
  28. font: 400 14px/28px;
  29. font-size: 150%;
  30. font-weight: bold;
  31. margin: 10px 2px;
  32. }
  33. h1, h2, h3, h4, h5, h6 {
  34. -webkit-transition: text-shadow 0.5s linear;
  35. -moz-transition: text-shadow 0.5s linear;
  36. -ms-transition: text-shadow 0.5s linear;
  37. -o-transition: text-shadow 0.5s linear;
  38. transition: text-shadow 0.5s linear;
  39. margin-right: 15px;
  40. }
  41. caption {
  42. font-weight: bold;
  43. }
  44. h3.version {
  45. font-size: 90%;
  46. text-align: center;
  47. }
  48. a {
  49. color: #3D578C;
  50. font-weight: normal;
  51. text-decoration: none;
  52. }
  53. .contents a:visited {
  54. color: #4665A2;
  55. }
  56. a:hover {
  57. text-decoration: underline;
  58. }
  59. a.el {
  60. font-weight: bold;
  61. }
  62. a.code, a.code:visited, a.line, a.line:visited {
  63. color: #4665A2;
  64. }
  65. a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
  66. color: #4665A2;
  67. }
  68. pre.fragment {
  69. border: 1px solid #C4CFE5;
  70. background-color: #FBFCFD;
  71. padding: 4px 6px;
  72. margin: 4px 8px 4px 2px;
  73. overflow: auto;
  74. word-wrap: break-word;
  75. font-size: 9pt;
  76. line-height: 125%;
  77. font-family: monospace, fixed;
  78. font-size: 105%;
  79. }
  80. div.fragment {
  81. padding: 0px;
  82. margin: 4px 8px 4px 2px;
  83. background-color: #FBFCFD;
  84. border: 1px solid #C4CFE5;
  85. }
  86. div.line {
  87. font-family: monospace, fixed;
  88. font-size: 13px;
  89. min-height: 13px;
  90. line-height: 1.0;
  91. text-wrap: unrestricted;
  92. white-space: -moz-pre-wrap; /* Moz */
  93. white-space: -pre-wrap; /* Opera 4-6 */
  94. white-space: -o-pre-wrap; /* Opera 7 */
  95. white-space: pre-wrap; /* CSS3 */
  96. word-wrap: break-word; /* IE 5.5+ */
  97. text-indent: -53px;
  98. padding-left: 53px;
  99. padding-bottom: 0px;
  100. margin: 0px;
  101. -webkit-transition-property: background-color, box-shadow;
  102. -webkit-transition-duration: 0.5s;
  103. -moz-transition-property: background-color, box-shadow;
  104. -moz-transition-duration: 0.5s;
  105. -ms-transition-property: background-color, box-shadow;
  106. -ms-transition-duration: 0.5s;
  107. -o-transition-property: background-color, box-shadow;
  108. -o-transition-duration: 0.5s;
  109. transition-property: background-color, box-shadow;
  110. transition-duration: 0.5s;
  111. }
  112. div.contents {
  113. margin-top: 10px;
  114. margin-left: 12px;
  115. margin-right: 8px;
  116. }
  117. div.center {
  118. text-align: center;
  119. margin-top: 0px;
  120. margin-bottom: 0px;
  121. padding: 0px;
  122. }
  123. div.center img {
  124. border: 0px;
  125. }
  126. span.keyword {
  127. color: #008000
  128. }
  129. span.keywordtype {
  130. color: #604020
  131. }
  132. span.keywordflow {
  133. color: #e08000
  134. }
  135. span.comment {
  136. color: #800000
  137. }
  138. span.preprocessor {
  139. color: #806020
  140. }
  141. span.stringliteral {
  142. color: #002080
  143. }
  144. span.charliteral {
  145. color: #008080
  146. }
  147. blockquote {
  148. background-color: #F7F8FB;
  149. border-left: 2px solid #9CAFD4;
  150. margin: 0 24px 0 4px;
  151. padding: 0 12px 0 16px;
  152. }
  153. hr {
  154. height: 0px;
  155. border: none;
  156. border-top: 1px solid #4A6AAA;
  157. }
  158. address {
  159. font-style: normal;
  160. color: #2A3D61;
  161. }
  162. div.header {
  163. background-image:url('nav_h.png');
  164. background-repeat:repeat-x;
  165. background-color: #F9FAFC;
  166. margin: 0px;
  167. border-bottom: 1px solid #C4CFE5;
  168. }
  169. div.headertitle {
  170. padding: 5px 5px 5px 10px;
  171. }
  172. .image {
  173. text-align: center;
  174. }
  175. .caption {
  176. font-weight: bold;
  177. }
  178. div.zoom {
  179. border: 1px solid #90A5CE;
  180. }
  181. tr.heading h2 {
  182. margin-top: 12px;
  183. margin-bottom: 4px;
  184. }
  185. </style>
  186. </head>
  187. <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
  188. <!--END TITLEAREA-->
  189. <!-- end header part -->
  190. <!-- Generated by Doxygen 1.8.13 -->
  191. </div><!-- top -->
  192. <div class="header">
  193. <div class="headertitle">
  194. <div class="title">Tutorial 24: CursorControl </div> </div>
  195. </div><!--header-->
  196. <div class="contents">
  197. <div class="textblock"><div class="image">
  198. <img src="../../media/example_screenshots/024shot.jpg" alt="024shot.jpg"/>
  199. </div>
  200. <p>Show how to modify cursors and offer some useful tool-functions for creating cursors. It can also be used for experiments with the mouse in general. </p><div class="fragment"><div class="line"><span class="preprocessor">#include &lt;irrlicht.h&gt;</span></div><div class="line"><span class="preprocessor">#include &quot;driverChoice.h&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;exampleHelper.h&quot;</span></div><div class="line"></div><div class="line"><span class="keyword">using namespace </span>irr;</div><div class="line"><span class="keyword">using namespace </span>core;</div><div class="line"><span class="keyword">using namespace </span>scene;</div><div class="line"><span class="keyword">using namespace </span>video;</div><div class="line"><span class="keyword">using namespace </span>io;</div><div class="line"><span class="keyword">using namespace </span>gui;</div><div class="line"></div><div class="line"><span class="preprocessor">#ifdef _MSC_VER</span></div><div class="line"><span class="preprocessor">#pragma comment(lib, &quot;Irrlicht.lib&quot;)</span></div><div class="line"><span class="preprocessor">#endif</span></div><div class="line"></div><div class="line"><span class="keyword">const</span> <span class="keywordtype">int</span> DELAY_TIME = 3000;</div><div class="line"></div><div class="line"><span class="keyword">enum</span> ETimerAction</div><div class="line">{</div><div class="line"> ETA_MOUSE_VISIBLE,</div><div class="line"> ETA_MOUSE_INVISIBLE,</div><div class="line">};</div></div><!-- fragment --><p> Structure to allow delayed execution of some actions. </p><div class="fragment"><div class="line"><span class="keyword">struct </span>TimerAction</div><div class="line">{</div><div class="line"> u32 TargetTime;</div><div class="line"> ETimerAction Action;</div><div class="line">};</div></div><!-- fragment --> <div class="fragment"><div class="line"><span class="keyword">struct </span>SAppContext</div><div class="line">{</div><div class="line"> SAppContext()</div><div class="line"> : Device(0), InfoStatic(0), EventBox(0), CursorBox(0), SpriteBox(0)</div><div class="line"> , ButtonSetVisible(0), ButtonSetInvisible(0), ButtonSimulateBadFps(0)</div><div class="line"> , ButtonChangeIcon(0)</div><div class="line"> , SimulateBadFps(false)</div><div class="line"> {</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordtype">void</span> update()</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (!Device)</div><div class="line"> <span class="keywordflow">return</span>;</div><div class="line"> u32 timeNow = Device-&gt;getTimer()-&gt;getTime();</div><div class="line"> <span class="keywordflow">for</span> ( u32 i=0; i &lt; TimerActions.size(); ++i )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> ( timeNow &gt;= TimerActions[i].TargetTime )</div><div class="line"> {</div><div class="line"> runTimerAction(TimerActions[i]);</div><div class="line"> TimerActions.erase(i);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> ++i;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordtype">void</span> runTimerAction(<span class="keyword">const</span> TimerAction&amp; action)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (ETA_MOUSE_VISIBLE == action.Action)</div><div class="line"> {</div><div class="line"> Device-&gt;getCursorControl()-&gt;setVisible(<span class="keyword">true</span>);</div><div class="line"> ButtonSetVisible-&gt;setEnabled(<span class="keyword">true</span>);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( ETA_MOUSE_INVISIBLE == action.Action)</div><div class="line"> {</div><div class="line"> Device-&gt;getCursorControl()-&gt;setVisible(<span class="keyword">false</span>);</div><div class="line"> ButtonSetInvisible-&gt;setEnabled(<span class="keyword">true</span>);</div><div class="line"> }</div><div class="line"> }</div></div><!-- fragment --><p> Add another icon which the user can click and select as cursor later on. </p><div class="fragment"><div class="line"><span class="keywordtype">void</span> addIcon(<span class="keyword">const</span> stringw&amp; name, <span class="keyword">const</span> SCursorSprite &amp;sprite, <span class="keywordtype">bool</span> addCursor=<span class="keyword">true</span>)</div><div class="line">{</div><div class="line"> <span class="comment">// Sprites are just icons - not yet cursors. They can be displayed by Irrlicht sprite functions and be used to create cursors.</span></div><div class="line"> SpriteBox-&gt;addItem(name.c_str(), sprite.SpriteId);</div><div class="line"> Sprites.push_back(sprite);</div><div class="line"></div><div class="line"> <span class="comment">// create the cursor together with the icon?</span></div><div class="line"> <span class="keywordflow">if</span> ( addCursor )</div><div class="line"> {</div></div><!-- fragment --><p> Here we create a hardware cursor from a sprite</p><div class="fragment"><div class="line"> Device-&gt;getCursorControl()-&gt;addIcon(sprite);</div><div class="line"></div><div class="line"> <span class="comment">// ... and add it to the cursors selection listbox to the other system cursors.</span></div><div class="line"> CursorBox-&gt;addItem(name.c_str());</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> IrrlichtDevice * Device;</div><div class="line"> gui::IGUIStaticText * InfoStatic;</div><div class="line"> gui::IGUIListBox * EventBox;</div><div class="line"> gui::IGUIListBox * CursorBox;</div><div class="line"> gui::IGUIListBox * SpriteBox;</div><div class="line"> gui::IGUIButton * ButtonSetVisible;</div><div class="line"> gui::IGUIButton * ButtonSetInvisible;</div><div class="line"> gui::IGUIButton * ButtonSimulateBadFps;</div><div class="line"> gui::IGUIButton * ButtonChangeIcon;</div><div class="line"> array&lt;TimerAction&gt; TimerActions;</div><div class="line"> <span class="keywordtype">bool</span> SimulateBadFps;</div><div class="line"> array&lt;SCursorSprite&gt; Sprites;</div><div class="line">};</div></div><!-- fragment --><p> Helper function to print mouse event names into a stringw </p><div class="fragment"><div class="line"><span class="keywordtype">void</span> PrintMouseEventName(<span class="keyword">const</span> SEvent&amp; event, stringw &amp;result)</div><div class="line">{</div><div class="line"> <span class="keywordflow">switch</span> ( event.MouseInput.Event )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">case</span> EMIE_LMOUSE_PRESSED_DOWN: result += stringw(L<span class="stringliteral">&quot;EMIE_LMOUSE_PRESSED_DOWN&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_RMOUSE_PRESSED_DOWN: result += stringw(L<span class="stringliteral">&quot;EMIE_RMOUSE_PRESSED_DOWN&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MMOUSE_PRESSED_DOWN: result += stringw(L<span class="stringliteral">&quot;EMIE_MMOUSE_PRESSED_DOWN&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_LMOUSE_LEFT_UP: result += stringw(L<span class="stringliteral">&quot;EMIE_LMOUSE_LEFT_UP&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_RMOUSE_LEFT_UP: result += stringw(L<span class="stringliteral">&quot;EMIE_RMOUSE_LEFT_UP&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MMOUSE_LEFT_UP: result += stringw(L<span class="stringliteral">&quot;EMIE_MMOUSE_LEFT_UP&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MOUSE_MOVED: result += stringw(L<span class="stringliteral">&quot;EMIE_MOUSE_MOVED&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MOUSE_WHEEL: result += stringw(L<span class="stringliteral">&quot;EMIE_MOUSE_WHEEL&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_LMOUSE_DOUBLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_LMOUSE_DOUBLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_RMOUSE_DOUBLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_RMOUSE_DOUBLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MMOUSE_DOUBLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_MMOUSE_DOUBLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_LMOUSE_TRIPLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_LMOUSE_TRIPLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_RMOUSE_TRIPLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_RMOUSE_TRIPLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">case</span> EMIE_MMOUSE_TRIPLE_CLICK: result += stringw(L<span class="stringliteral">&quot;EMIE_MMOUSE_TRIPLE_CLICK&quot;</span>); <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">default</span>:</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> }</div><div class="line">}</div></div><!-- fragment --><p> Helper function to print all the state information which get from a mouse-event into a stringw </p><div class="fragment"><div class="line"><span class="keywordtype">void</span> PrintMouseState(<span class="keyword">const</span> SEvent&amp; event, stringw &amp;result)</div><div class="line">{</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;X: &quot;</span>);</div><div class="line"> result += stringw(event.MouseInput.X);</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;Y: &quot;</span>);</div><div class="line"> result += stringw(event.MouseInput.Y);</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"></div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;Wheel: &quot;</span>);</div><div class="line"> result += stringw(event.MouseInput.Wheel);</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;Shift: &quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.Shift )</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;true\n&quot;</span>);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;false\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;Control: &quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.Control )</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;true\n&quot;</span>);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;false\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;ButtonStates: &quot;</span>);</div><div class="line"> result += stringw(event.MouseInput.ButtonStates);</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;isLeftPressed: &quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.isLeftPressed() )</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;true\n&quot;</span>);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;false\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;isRightPressed: &quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.isRightPressed() )</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;true\n&quot;</span>);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;false\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;isMiddlePressed: &quot;</span>);</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.isMiddlePressed() )</div><div class="line"> result += stringw(L<span class="stringliteral">&quot;true\n&quot;</span>);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;false\n&quot;</span>);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;Event: &quot;</span>);</div><div class="line"></div><div class="line"> PrintMouseEventName(event, result);</div><div class="line"></div><div class="line"> result += stringw(L<span class="stringliteral">&quot;\n&quot;</span>);</div><div class="line">}</div></div><!-- fragment --><p> A typical event receiver. </p><div class="fragment"><div class="line"><span class="keyword">class </span>MyEventReceiver : <span class="keyword">public</span> IEventReceiver</div><div class="line">{</div><div class="line"><span class="keyword">public</span>:</div><div class="line"> MyEventReceiver(SAppContext &amp; context) : Context(context) { }</div><div class="line"></div><div class="line"> <span class="keyword">virtual</span> <span class="keywordtype">bool</span> OnEvent(<span class="keyword">const</span> SEvent&amp; event)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">if</span> (event.EventType == EET_GUI_EVENT )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">switch</span> ( event.GUIEvent.EventType )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">case</span> EGET_BUTTON_CLICKED:</div><div class="line"> {</div><div class="line"> u32 timeNow = Context.Device-&gt;getTimer()-&gt;getTime();</div><div class="line"> TimerAction action;</div><div class="line"> action.TargetTime = timeNow + DELAY_TIME;</div><div class="line"> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == Context.ButtonSetVisible )</div><div class="line"> {</div><div class="line"> action.Action = ETA_MOUSE_VISIBLE;</div><div class="line"> Context.TimerActions.push_back(action);</div><div class="line"> Context.ButtonSetVisible-&gt;setEnabled(<span class="keyword">false</span>);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == Context.ButtonSetInvisible )</div><div class="line"> {</div><div class="line"> action.Action = ETA_MOUSE_INVISIBLE;</div><div class="line"> Context.TimerActions.push_back(action);</div><div class="line"> Context.ButtonSetInvisible-&gt;setEnabled(<span class="keyword">false</span>);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == Context.ButtonSimulateBadFps )</div><div class="line"> {</div><div class="line"> Context.SimulateBadFps = Context.ButtonSimulateBadFps-&gt;isPressed();</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == Context.ButtonChangeIcon )</div><div class="line"> {</div></div><!-- fragment --><p> Replace an existing cursor icon by another icon. The user has to select both - the icon which should be replaced and the icon which will replace it. </p><div class="fragment"><div class="line">s32 selectedCursor = Context.CursorBox-&gt;getSelected();</div><div class="line">s32 selectedSprite = Context.SpriteBox-&gt;getSelected();</div><div class="line"><span class="keywordflow">if</span> ( selectedCursor &gt;= 0 &amp;&amp; selectedSprite &gt;= 0 )</div><div class="line">{</div></div><!-- fragment --><p> This does replace the icon. </p><div class="fragment"><div class="line">Context.Device-&gt;getCursorControl()-&gt;changeIcon((ECURSOR_ICON)selectedCursor, Context.Sprites[selectedSprite] );</div></div><!-- fragment --><p> Do also show the new icon. </p><div class="fragment"><div class="line"> Context.Device-&gt;getCursorControl()-&gt;setActiveIcon( ECURSOR_ICON(selectedCursor) );</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div><div class="line"><span class="keywordflow">break</span>;</div><div class="line"><span class="keywordflow">case</span> EGET_LISTBOX_CHANGED:</div><div class="line"><span class="keywordflow">case</span> EGET_LISTBOX_SELECTED_AGAIN:</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> ( event.GUIEvent.Caller == Context.CursorBox )</div><div class="line"> {</div></div><!-- fragment --><p> Find out which cursor the user selected </p><div class="fragment"><div class="line">s32 selected = Context.CursorBox-&gt;getSelected();</div><div class="line"><span class="keywordflow">if</span> ( selected &gt;= 0 )</div><div class="line">{</div></div><!-- fragment --><p> Here we set the new cursor icon which will now be used within our window. </p><div class="fragment"><div class="line"> Context.Device-&gt;getCursorControl()-&gt;setActiveIcon( ECURSOR_ICON(selected) );</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> <span class="keywordflow">default</span>:</div><div class="line"> <span class="keywordflow">break</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (event.EventType == EET_MOUSE_INPUT_EVENT)</div><div class="line"> {</div><div class="line"> stringw infoText;</div><div class="line"> PrintMouseState(event, infoText);</div><div class="line"> Context.InfoStatic-&gt;setText(infoText.c_str());</div><div class="line"> <span class="keywordflow">if</span> ( event.MouseInput.Event != EMIE_MOUSE_MOVED &amp;&amp; event.MouseInput.Event != EMIE_MOUSE_WHEEL ) <span class="comment">// no spam</span></div><div class="line"> {</div><div class="line"> infoText = L<span class="stringliteral">&quot;&quot;</span>;</div><div class="line"> PrintMouseEventName(event, infoText);</div><div class="line"> Context.EventBox-&gt;insertItem(0, infoText.c_str(), -1);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> <span class="keyword">false</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"><span class="keyword">private</span>:</div><div class="line"> SAppContext &amp; Context;</div><div class="line">};</div></div><!-- fragment --><p> Use several imagefiles as animation frames for a sprite which can be used as cursor icon. The images in those files all need to have the same size. Return sprite index on success or -1 on failure </p><div class="fragment"><div class="line">s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, <span class="keyword">const</span> array&lt; io::path &gt;&amp; files, u32 frameTime )</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> ( !spriteBank || !driver || !files.size() )</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line"></div><div class="line"> video::ITexture * tex = driver-&gt;getTexture( files[0] );</div><div class="line"> <span class="keywordflow">if</span> ( tex )</div><div class="line"> {</div><div class="line"> array&lt; rect&lt;s32&gt; &gt;&amp; spritePositions = spriteBank-&gt;getPositions();</div><div class="line"> u32 idxRect = spritePositions.size();</div><div class="line"> spritePositions.push_back( rect&lt;s32&gt;(0,0, tex-&gt;getSize().Width, tex-&gt;getSize().Height) );</div><div class="line"></div><div class="line"> SGUISprite sprite;</div><div class="line"> sprite.frameTime = frameTime;</div><div class="line"></div><div class="line"> array&lt; SGUISprite &gt;&amp; sprites = spriteBank-&gt;getSprites();</div><div class="line"> u32 startIdx = spriteBank-&gt;getTextureCount();</div><div class="line"> <span class="keywordflow">for</span> ( u32 f=0; f &lt; files.size(); ++f )</div><div class="line"> {</div><div class="line"> tex = driver-&gt;getTexture( files[f] );</div><div class="line"> <span class="keywordflow">if</span> ( tex )</div><div class="line"> {</div><div class="line"> spriteBank-&gt;addTexture( driver-&gt;getTexture(files[f]) );</div><div class="line"> gui::SGUISpriteFrame frame;</div><div class="line"> frame.rectNumber = idxRect;</div><div class="line"> frame.textureNumber = startIdx+f;</div><div class="line"> sprite.Frames.push_back( frame );</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> sprites.push_back( sprite );</div><div class="line"> <span class="keywordflow">return</span> sprites.size()-1;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div></div><!-- fragment --><p> Use several images within one imagefile as animation frames for a sprite which can be used as cursor icon The sizes of the icons within that file all need to have the same size Return sprite index on success or -1 on failure </p><div class="fragment"><div class="line">s32 AddAnimatedIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, <span class="keyword">const</span> io::path&amp; file, <span class="keyword">const</span> array&lt; rect&lt;s32&gt; &gt;&amp; rects, u32 frameTime )</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> ( !spriteBank || !driver || !rects.size() )</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line"></div><div class="line"> video::ITexture * tex = driver-&gt;getTexture( file );</div><div class="line"> <span class="keywordflow">if</span> ( tex )</div><div class="line"> {</div><div class="line"> array&lt; rect&lt;s32&gt; &gt;&amp; spritePositions = spriteBank-&gt;getPositions();</div><div class="line"> u32 idxRect = spritePositions.size();</div><div class="line"> u32 idxTex = spriteBank-&gt;getTextureCount();</div><div class="line"> spriteBank-&gt;addTexture( tex );</div><div class="line"></div><div class="line"> SGUISprite sprite;</div><div class="line"> sprite.frameTime = frameTime;</div><div class="line"></div><div class="line"> array&lt; SGUISprite &gt;&amp; sprites = spriteBank-&gt;getSprites();</div><div class="line"> <span class="keywordflow">for</span> ( u32 i=0; i &lt; rects.size(); ++i )</div><div class="line"> {</div><div class="line"> spritePositions.push_back( rects[i] );</div><div class="line"></div><div class="line"> gui::SGUISpriteFrame frame;</div><div class="line"> frame.rectNumber = idxRect+i;</div><div class="line"> frame.textureNumber = idxTex;</div><div class="line"> sprite.Frames.push_back( frame );</div><div class="line"> }</div><div class="line"></div><div class="line"> sprites.push_back( sprite );</div><div class="line"> <span class="keywordflow">return</span> sprites.size()-1;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div></div><!-- fragment --><p> Create a non-animated icon from the given file and position and put it into the spritebank. We can use this icon later on in a cursor. </p><div class="fragment"><div class="line">s32 AddIconToSpriteBank( gui::IGUISpriteBank * spriteBank, video::IVideoDriver* driver, <span class="keyword">const</span> io::path&amp; file, <span class="keyword">const</span> core::rect&lt;s32&gt;&amp; rect )</div><div class="line">{</div><div class="line"> <span class="keywordflow">if</span> ( !spriteBank || !driver )</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line"></div><div class="line"> video::ITexture * tex = driver-&gt;getTexture( file );</div><div class="line"> <span class="keywordflow">if</span> ( tex )</div><div class="line"> {</div><div class="line"> core::array&lt; core::rect&lt;irr::s32&gt; &gt;&amp; spritePositions = spriteBank-&gt;getPositions();</div><div class="line"> spritePositions.push_back( rect );</div><div class="line"> array&lt; SGUISprite &gt;&amp; sprites = spriteBank-&gt;getSprites();</div><div class="line"> spriteBank-&gt;addTexture( tex );</div><div class="line"></div><div class="line"> gui::SGUISpriteFrame frame;</div><div class="line"> frame.rectNumber = spritePositions.size()-1;</div><div class="line"> frame.textureNumber = spriteBank-&gt;getTextureCount()-1;</div><div class="line"></div><div class="line"> SGUISprite sprite;</div><div class="line"> sprite.frameTime = 0;</div><div class="line"> sprite.Frames.push_back( frame );</div><div class="line"></div><div class="line"> sprites.push_back( sprite );</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> sprites.size()-1;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main()</div><div class="line">{</div><div class="line"> video::E_DRIVER_TYPE driverType = driverChoiceConsole();</div><div class="line"> <span class="keywordflow">if</span> (driverType==video::EDT_COUNT)</div><div class="line"> <span class="keywordflow">return</span> 1;</div><div class="line"></div><div class="line"> IrrlichtDevice * device = createDevice(driverType, dimension2d&lt;u32&gt;(640, 480));</div><div class="line"> <span class="keywordflow">if</span> (device == 0)</div><div class="line"> <span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span></div><div class="line"></div><div class="line"> <span class="comment">// It&#39;s sometimes of interest to know how the mouse behaves after a resize</span></div><div class="line"> device-&gt;setResizable(<span class="keyword">true</span>);</div><div class="line"></div><div class="line"> device-&gt;setWindowCaption(L<span class="stringliteral">&quot;Cursor control - Irrlicht engine tutorial&quot;</span>);</div><div class="line"> video::IVideoDriver* driver = device-&gt;getVideoDriver();</div><div class="line"> IGUIEnvironment* env = device-&gt;getGUIEnvironment();</div><div class="line"></div><div class="line"> gui::IGUISpriteBank * SpriteBankIcons;</div><div class="line"></div><div class="line"> SAppContext context;</div><div class="line"> context.Device = device;</div><div class="line"></div><div class="line"> rect&lt; s32 &gt; rectInfoStatic(10,10, 200, 200);</div><div class="line"> env-&gt;addStaticText (L<span class="stringliteral">&quot;Cursor state information&quot;</span>, rectInfoStatic, <span class="keyword">true</span>, <span class="keyword">true</span>);</div><div class="line"> rectInfoStatic.UpperLeftCorner += dimension2di(0, 15);</div><div class="line"> context.InfoStatic = env-&gt;addStaticText (L<span class="stringliteral">&quot;&quot;</span>, rectInfoStatic, <span class="keyword">true</span>, <span class="keyword">true</span>);</div><div class="line"> rect&lt; s32 &gt; rectEventBox(10,210, 200, 400);</div><div class="line"> env-&gt;addStaticText (L<span class="stringliteral">&quot;click events (new on top)&quot;</span>, rectEventBox, <span class="keyword">true</span>, <span class="keyword">true</span>);</div><div class="line"> rectEventBox.UpperLeftCorner += dimension2di(0, 15);</div><div class="line"> context.EventBox = env-&gt;addListBox(rectEventBox);</div><div class="line"> rect&lt; s32 &gt; rectCursorBox(210,10, 400, 250);</div><div class="line"> env-&gt;addStaticText (L<span class="stringliteral">&quot;cursors, click to set the active one&quot;</span>, rectCursorBox, <span class="keyword">true</span>, <span class="keyword">true</span>);</div><div class="line"> rectCursorBox.UpperLeftCorner += dimension2di(0, 15);</div><div class="line"> context.CursorBox = env-&gt;addListBox(rectCursorBox);</div><div class="line"> rect&lt; s32 &gt; rectSpriteBox(210,260, 400, 400);</div><div class="line"> env-&gt;addStaticText (L<span class="stringliteral">&quot;sprites&quot;</span>, rectSpriteBox, <span class="keyword">true</span>, <span class="keyword">true</span>);</div><div class="line"> rectSpriteBox.UpperLeftCorner += dimension2di(0, 15);</div><div class="line"> context.SpriteBox = env-&gt;addListBox(rectSpriteBox);</div><div class="line"></div><div class="line"> context.ButtonSetVisible = env-&gt;addButton( rect&lt;s32&gt;( 410, 20, 560, 40 ), 0, -1, L<span class="stringliteral">&quot;set visible (delayed)&quot;</span> );</div><div class="line"> context.ButtonSetInvisible = env-&gt;addButton( rect&lt;s32&gt;( 410, 50, 560, 70 ), 0, -1, L<span class="stringliteral">&quot;set invisible (delayed)&quot;</span> );</div><div class="line"> context.ButtonSimulateBadFps = env-&gt;addButton( rect&lt;s32&gt;( 410, 80, 560, 100 ), 0, -1, L<span class="stringliteral">&quot;simulate bad FPS&quot;</span> );</div><div class="line"> context.ButtonSimulateBadFps-&gt;setIsPushButton(<span class="keyword">true</span>);</div><div class="line"> context.ButtonChangeIcon = env-&gt;addButton( rect&lt;s32&gt;( 410, 140, 560, 160 ), 0, -1, L<span class="stringliteral">&quot;replace cursor icon\n(cursor+sprite must be selected)&quot;</span> );</div><div class="line"></div><div class="line"> <span class="comment">// set the names for all the system cursors</span></div><div class="line"> <span class="keywordflow">for</span> ( <span class="keywordtype">int</span> i=0; i &lt; (int)gui::ECI_COUNT; ++i )</div><div class="line"> {</div><div class="line"> context.CursorBox-&gt;addItem(stringw( GUICursorIconNames[i] ).c_str());</div><div class="line"> }</div></div><!-- fragment --><p> Create sprites which then can be used as cursor icons. </p><div class="fragment"><div class="line"> SpriteBankIcons = env-&gt;addEmptySpriteBank(io::path(<span class="stringliteral">&quot;cursor_icons&quot;</span>));</div><div class="line"> context.SpriteBox-&gt;setSpriteBank(SpriteBankIcons);</div><div class="line"></div><div class="line"> <span class="keyword">const</span> io::path mediaPath = getExampleMediaPath();</div><div class="line"></div><div class="line"> <span class="comment">// create one animated icon from several files</span></div><div class="line"> array&lt; io::path &gt; files;</div><div class="line"> files.push_back( io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16bw1.png&quot;</span>) );</div><div class="line"> files.push_back( io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16bw2.png&quot;</span>) );</div><div class="line"> files.push_back( io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16bw3.png&quot;</span>) );</div><div class="line"> files.push_back( io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16bw3.png&quot;</span>) );</div><div class="line"> files.push_back( io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16bw2.png&quot;</span>) );</div><div class="line"> SCursorSprite spriteBw; <span class="comment">// the sprite + some additional information needed for cursors</span></div><div class="line"> spriteBw.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, files, 200 );</div><div class="line"> spriteBw.SpriteBank = SpriteBankIcons;</div><div class="line"> spriteBw.HotSpot = position2d&lt;s32&gt;(7,7);</div><div class="line"> context.addIcon(L<span class="stringliteral">&quot;crosshair_bw&quot;</span>, spriteBw);</div><div class="line"></div><div class="line"> <span class="comment">// create one animated icon from one file</span></div><div class="line"> array&lt; rect&lt;s32&gt; &gt; iconRects;</div><div class="line"> iconRects.push_back( rect&lt;s32&gt;(0,0, 16, 16) );</div><div class="line"> iconRects.push_back( rect&lt;s32&gt;(16,0, 32, 16) );</div><div class="line"> iconRects.push_back( rect&lt;s32&gt;(0,16, 16, 32) );</div><div class="line"> iconRects.push_back( rect&lt;s32&gt;(0,16, 16, 32) );</div><div class="line"> iconRects.push_back( rect&lt;s32&gt;(16,0, 32, 16) );</div><div class="line"> SCursorSprite spriteCol; <span class="comment">// the sprite + some additional information needed for cursors</span></div><div class="line"> spriteCol.SpriteId = AddAnimatedIconToSpriteBank( SpriteBankIcons, driver, io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16col.png&quot;</span>), iconRects, 200 );</div><div class="line"> spriteCol.HotSpot = position2d&lt;s32&gt;(7,7);</div><div class="line"> spriteCol.SpriteBank = SpriteBankIcons;</div><div class="line"> context.addIcon(L<span class="stringliteral">&quot;crosshair_colored&quot;</span>, spriteCol);</div><div class="line"></div><div class="line"> <span class="comment">// Create some non-animated icons</span></div><div class="line"> rect&lt;s32&gt; rectIcon;</div><div class="line"> SCursorSprite spriteNonAnimated(SpriteBankIcons, 0, position2d&lt;s32&gt;(7,7));</div><div class="line"></div><div class="line"> rectIcon = rect&lt;s32&gt;(0,0, 16, 16);</div><div class="line"> spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16col.png&quot;</span>), rectIcon );</div><div class="line"> context.addIcon(L<span class="stringliteral">&quot;crosshair_col1&quot;</span>, spriteNonAnimated, <span class="keyword">false</span>);</div><div class="line"></div><div class="line"> rectIcon = rect&lt;s32&gt;(16,0, 32, 16);</div><div class="line"> spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16col.png&quot;</span>), rectIcon );</div><div class="line"> context.addIcon(L<span class="stringliteral">&quot;crosshair_col2&quot;</span>, spriteNonAnimated, <span class="keyword">false</span>);</div><div class="line"></div><div class="line"> rectIcon = rect&lt;s32&gt;(0,16, 16, 32);</div><div class="line"> spriteNonAnimated.SpriteId = AddIconToSpriteBank( SpriteBankIcons, driver, io::path(mediaPath + <span class="stringliteral">&quot;icon_crosshairs16x16col.png&quot;</span>), rectIcon );</div><div class="line"> context.addIcon(L<span class="stringliteral">&quot;crosshair_col3&quot;</span>, spriteNonAnimated, <span class="keyword">false</span>);</div><div class="line"></div><div class="line"></div><div class="line"> MyEventReceiver receiver(context);</div><div class="line"> device-&gt;setEventReceiver(&amp;receiver);</div><div class="line"></div><div class="line"> <span class="keywordflow">while</span>(device-&gt;run() &amp;&amp; driver)</div><div class="line"> {</div><div class="line"> <span class="comment">// if (device-&gt;isWindowActive())</span></div><div class="line"> {</div><div class="line"> u32 realTimeNow = device-&gt;getTimer()-&gt;getRealTime();</div><div class="line"></div><div class="line"> context.update();</div><div class="line"></div><div class="line"> driver-&gt;beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, SColor(0,200,200,200));</div><div class="line"></div><div class="line"> env-&gt;drawAll();</div><div class="line"></div><div class="line"> <span class="comment">// draw custom sprite with Irrlicht functions for comparison. It should usually look the same as the cursors.</span></div><div class="line"> <span class="keywordflow">if</span> ( context.SpriteBox )</div><div class="line"> {</div><div class="line"> s32 selectedSprite = context.SpriteBox-&gt;getSelected();</div><div class="line"> <span class="keywordflow">if</span> ( selectedSprite &gt;= 0 &amp;&amp; context.Sprites[selectedSprite].SpriteId &gt;= 0 )</div><div class="line"> {</div><div class="line"> SpriteBankIcons-&gt;draw2DSprite(u32(context.Sprites[selectedSprite].SpriteId), position2di(580, 140), 0, video::SColor(255, 255, 255, 255), 0, realTimeNow);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> driver-&gt;endScene();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// By simulating bad fps we can find out if hardware-support for cursors works or not. If it works the cursor will move as usual,while it otherwise will just update with 2 fps now.</span></div><div class="line"> <span class="keywordflow">if</span> ( context.SimulateBadFps )</div><div class="line"> {</div><div class="line"> device-&gt;sleep(500); <span class="comment">// 2 fps</span></div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> device-&gt;sleep(10);</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> device-&gt;drop();</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">}</div></div><!-- fragment --> </div></div><!-- contents -->
  201. <!-- HTML footer for doxygen 1.8.13-->
  202. <!-- start footer part -->
  203. <p>&nbsp;</p>
  204. </body>
  205. </html>