@@ -183,6 +183,64 @@ static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent)
183183 return false ;
184184}
185185
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+
186244bool GUIModalMenu::preprocessEvent (const SEvent &event)
187245{
188246#ifdef __ANDROID__
@@ -230,89 +288,50 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
230288 }
231289
232290 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 [?])
250293
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)
254297 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)
257299 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);
278306 }
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);
299331 return true ;
300332 }
301-
302- // check if translated event needs to be preprocessed again
303- if (preprocessEvent (translated))
333+ default : // ignored
304334 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;
316335 }
317336 }
318337#endif
0 commit comments