@@ -183,6 +183,64 @@ static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent)
183
183
return false ;
184
184
}
185
185
186
+ #ifdef __ANDROID__
187
+
188
+ bool GUIModalMenu::simulateMouseEvent (
189
+ gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event)
190
+ {
191
+ SEvent mouse_event{}; // value-initialized, not unitialized
192
+ mouse_event.EventType = EET_MOUSE_INPUT_EVENT;
193
+ mouse_event.MouseInput .X = m_pointer.X ;
194
+ mouse_event.MouseInput .Y = m_pointer.Y ;
195
+ switch (touch_event) {
196
+ case ETIE_PRESSED_DOWN:
197
+ mouse_event.MouseInput .Event = EMIE_LMOUSE_PRESSED_DOWN;
198
+ mouse_event.MouseInput .ButtonStates = EMBSM_LEFT;
199
+ break ;
200
+ case ETIE_MOVED:
201
+ mouse_event.MouseInput .Event = EMIE_MOUSE_MOVED;
202
+ mouse_event.MouseInput .ButtonStates = EMBSM_LEFT;
203
+ break ;
204
+ case ETIE_LEFT_UP:
205
+ mouse_event.MouseInput .Event = EMIE_LMOUSE_LEFT_UP;
206
+ mouse_event.MouseInput .ButtonStates = 0 ;
207
+ break ;
208
+ default :
209
+ return false ;
210
+ }
211
+ if (preprocessEvent (mouse_event))
212
+ return true ;
213
+ if (!target)
214
+ return false ;
215
+ return target->OnEvent (mouse_event);
216
+ }
217
+
218
+ void GUIModalMenu::enter (gui::IGUIElement *hovered)
219
+ {
220
+ sanity_check (!m_hovered);
221
+ m_hovered.grab (hovered);
222
+ SEvent gui_event{};
223
+ gui_event.EventType = EET_GUI_EVENT;
224
+ gui_event.GUIEvent .Caller = m_hovered.get ();
225
+ gui_event.GUIEvent .EventType = EGET_ELEMENT_HOVERED;
226
+ gui_event.GUIEvent .Element = gui_event.GUIEvent .Caller ;
227
+ m_hovered->OnEvent (gui_event);
228
+ }
229
+
230
+ void GUIModalMenu::leave ()
231
+ {
232
+ if (!m_hovered)
233
+ return ;
234
+ SEvent gui_event{};
235
+ gui_event.EventType = EET_GUI_EVENT;
236
+ gui_event.GUIEvent .Caller = m_hovered.get ();
237
+ gui_event.GUIEvent .EventType = EGET_ELEMENT_LEFT;
238
+ m_hovered->OnEvent (gui_event);
239
+ m_hovered.reset ();
240
+ }
241
+
242
+ #endif
243
+
186
244
bool GUIModalMenu::preprocessEvent (const SEvent &event)
187
245
{
188
246
#ifdef __ANDROID__
@@ -230,89 +288,50 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
230
288
}
231
289
232
290
if (event.EventType == EET_TOUCH_INPUT_EVENT) {
233
- SEvent translated;
234
- memset (&translated, 0 , sizeof (SEvent));
235
- translated.EventType = EET_MOUSE_INPUT_EVENT;
236
- gui::IGUIElement *root = Environment->getRootGUIElement ();
237
-
238
- if (!root) {
239
- errorstream << " GUIModalMenu::preprocessEvent"
240
- << " unable to get root element" << std::endl;
241
- return false ;
242
- }
243
- gui::IGUIElement *hovered =
244
- root->getElementFromPoint (core::position2d<s32>(
245
- event.TouchInput .X , event.TouchInput .Y ));
246
-
247
- translated.MouseInput .X = event.TouchInput .X ;
248
- translated.MouseInput .Y = event.TouchInput .Y ;
249
- translated.MouseInput .Control = false ;
291
+ irr_ptr<GUIModalMenu> holder;
292
+ holder.grab (this ); // keep this alive until return (it might be dropped downstream [?])
250
293
251
- if ( event.TouchInput .touchedCount == 1 ) {
252
- switch (event. TouchInput . Event ) {
253
- case ETIE_PRESSED_DOWN:
294
+ switch (( int ) event.TouchInput .touchedCount ) {
295
+ case 1 : {
296
+ if (event. TouchInput . Event == ETIE_PRESSED_DOWN || event. TouchInput . Event == ETIE_MOVED)
254
297
m_pointer = v2s32 (event.TouchInput .X , event.TouchInput .Y );
255
- translated.MouseInput .Event = EMIE_LMOUSE_PRESSED_DOWN;
256
- translated.MouseInput .ButtonStates = EMBSM_LEFT;
298
+ if (event.TouchInput .Event == ETIE_PRESSED_DOWN)
257
299
m_down_pos = m_pointer;
258
- break ;
259
- case ETIE_MOVED:
260
- m_pointer = v2s32 (event.TouchInput .X , event.TouchInput .Y );
261
- translated.MouseInput .Event = EMIE_MOUSE_MOVED;
262
- translated.MouseInput .ButtonStates = EMBSM_LEFT;
263
- break ;
264
- case ETIE_LEFT_UP:
265
- translated.MouseInput .Event = EMIE_LMOUSE_LEFT_UP;
266
- translated.MouseInput .ButtonStates = 0 ;
267
- hovered = root->getElementFromPoint (m_down_pos);
268
- // we don't have a valid pointer element use last
269
- // known pointer pos
270
- translated.MouseInput .X = m_pointer.X ;
271
- translated.MouseInput .Y = m_pointer.Y ;
272
-
273
- // reset down pos
274
- m_down_pos = v2s32 (0 , 0 );
275
- break ;
276
- default :
277
- break ;
300
+ gui::IGUIElement *hovered = Environment->getRootGUIElement ()->getElementFromPoint (core::position2d<s32>(m_pointer));
301
+ if (event.TouchInput .Event == ETIE_PRESSED_DOWN)
302
+ Environment->setFocus (hovered);
303
+ if (m_hovered != hovered) {
304
+ leave ();
305
+ enter (hovered);
278
306
}
279
- } else if ((event.TouchInput .touchedCount == 2 ) &&
280
- (event.TouchInput .Event == ETIE_PRESSED_DOWN)) {
281
- hovered = root->getElementFromPoint (m_down_pos);
282
-
283
- translated.MouseInput .Event = EMIE_RMOUSE_PRESSED_DOWN;
284
- translated.MouseInput .ButtonStates = EMBSM_LEFT | EMBSM_RIGHT;
285
- translated.MouseInput .X = m_pointer.X ;
286
- translated.MouseInput .Y = m_pointer.Y ;
287
- if (hovered)
288
- hovered->OnEvent (translated);
289
-
290
- translated.MouseInput .Event = EMIE_RMOUSE_LEFT_UP;
291
- translated.MouseInput .ButtonStates = EMBSM_LEFT;
292
-
293
- if (hovered)
294
- hovered->OnEvent (translated);
295
-
296
- return true ;
297
- } else {
298
- // ignore unhandled 2 touch events (accidental moving for example)
307
+ gui::IGUIElement *focused = Environment->getFocus ();
308
+ bool ret = simulateMouseEvent (focused, event.TouchInput .Event );
309
+ if (!ret && m_hovered != focused)
310
+ ret = simulateMouseEvent (m_hovered.get (), event.TouchInput .Event );
311
+ if (event.TouchInput .Event == ETIE_LEFT_UP)
312
+ leave ();
313
+ return ret;
314
+ }
315
+ case 2 : {
316
+ if (event.TouchInput .Event != ETIE_PRESSED_DOWN)
317
+ return true ; // ignore
318
+ auto focused = Environment->getFocus ();
319
+ if (!focused)
320
+ return true ;
321
+ SEvent rclick_event{};
322
+ rclick_event.EventType = EET_MOUSE_INPUT_EVENT;
323
+ rclick_event.MouseInput .Event = EMIE_RMOUSE_PRESSED_DOWN;
324
+ rclick_event.MouseInput .ButtonStates = EMBSM_LEFT | EMBSM_RIGHT;
325
+ rclick_event.MouseInput .X = m_pointer.X ;
326
+ rclick_event.MouseInput .Y = m_pointer.Y ;
327
+ focused->OnEvent (rclick_event);
328
+ rclick_event.MouseInput .Event = EMIE_RMOUSE_LEFT_UP;
329
+ rclick_event.MouseInput .ButtonStates = EMBSM_LEFT;
330
+ focused->OnEvent (rclick_event);
299
331
return true ;
300
332
}
301
-
302
- // check if translated event needs to be preprocessed again
303
- if (preprocessEvent (translated))
333
+ default : // ignored
304
334
return true ;
305
-
306
- if (hovered) {
307
- grab ();
308
- bool retval = hovered->OnEvent (translated);
309
-
310
- if (event.TouchInput .Event == ETIE_LEFT_UP)
311
- // reset pointer
312
- m_pointer = v2s32 (0 , 0 );
313
-
314
- drop ();
315
- return retval;
316
335
}
317
336
}
318
337
#endif
0 commit comments