mirror of
https://github.com/luanti-org/luanti.git
synced 2025-08-06 17:41:04 +00:00
Support both mouse and touch input in GUIs in a single binary (#14146)
This commit is contained in:
parent
4f1dbb127a
commit
32e492837c
5 changed files with 95 additions and 83 deletions
|
@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <IEventReceiver.h>
|
||||
#include "client/renderingengine.h"
|
||||
#include "modalMenu.h"
|
||||
#include "gettext.h"
|
||||
|
@ -103,7 +104,7 @@ void GUIModalMenu::quitMenu()
|
|||
m_menumgr->deletingMenu(this);
|
||||
this->remove();
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
if (g_touchscreengui && m_touchscreen_visible)
|
||||
if (g_touchscreengui)
|
||||
g_touchscreengui->show();
|
||||
#endif
|
||||
}
|
||||
|
@ -169,8 +170,6 @@ static bool isChild(gui::IGUIElement *tocheck, gui::IGUIElement *parent)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
|
||||
bool GUIModalMenu::simulateMouseEvent(
|
||||
gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event)
|
||||
{
|
||||
|
@ -194,41 +193,51 @@ bool GUIModalMenu::simulateMouseEvent(
|
|||
default:
|
||||
return false;
|
||||
}
|
||||
if (preprocessEvent(mouse_event))
|
||||
return true;
|
||||
if (!target)
|
||||
return false;
|
||||
return target->OnEvent(mouse_event);
|
||||
|
||||
bool retval;
|
||||
m_simulated_mouse = true;
|
||||
do {
|
||||
if (preprocessEvent(mouse_event)) {
|
||||
retval = true;
|
||||
break;
|
||||
}
|
||||
if (!target) {
|
||||
retval = false;
|
||||
break;
|
||||
}
|
||||
retval = target->OnEvent(mouse_event);
|
||||
} while (false);
|
||||
m_simulated_mouse = false;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void GUIModalMenu::enter(gui::IGUIElement *hovered)
|
||||
{
|
||||
if (!hovered)
|
||||
return;
|
||||
sanity_check(!m_hovered);
|
||||
m_hovered.grab(hovered);
|
||||
sanity_check(!m_touch_hovered);
|
||||
m_touch_hovered.grab(hovered);
|
||||
SEvent gui_event{};
|
||||
gui_event.EventType = EET_GUI_EVENT;
|
||||
gui_event.GUIEvent.Caller = m_hovered.get();
|
||||
gui_event.GUIEvent.EventType = EGET_ELEMENT_HOVERED;
|
||||
gui_event.GUIEvent.Caller = m_touch_hovered.get();
|
||||
gui_event.GUIEvent.EventType = gui::EGET_ELEMENT_HOVERED;
|
||||
gui_event.GUIEvent.Element = gui_event.GUIEvent.Caller;
|
||||
m_hovered->OnEvent(gui_event);
|
||||
m_touch_hovered->OnEvent(gui_event);
|
||||
}
|
||||
|
||||
void GUIModalMenu::leave()
|
||||
{
|
||||
if (!m_hovered)
|
||||
if (!m_touch_hovered)
|
||||
return;
|
||||
SEvent gui_event{};
|
||||
gui_event.EventType = EET_GUI_EVENT;
|
||||
gui_event.GUIEvent.Caller = m_hovered.get();
|
||||
gui_event.GUIEvent.EventType = EGET_ELEMENT_LEFT;
|
||||
m_hovered->OnEvent(gui_event);
|
||||
m_hovered.reset();
|
||||
gui_event.GUIEvent.Caller = m_touch_hovered.get();
|
||||
gui_event.GUIEvent.EventType = gui::EGET_ELEMENT_LEFT;
|
||||
m_touch_hovered->OnEvent(gui_event);
|
||||
m_touch_hovered.reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
|
@ -268,25 +277,26 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TOUCHSCREENGUI
|
||||
// Convert touch events into mouse events.
|
||||
if (event.EventType == EET_TOUCH_INPUT_EVENT) {
|
||||
irr_ptr<GUIModalMenu> holder;
|
||||
holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
|
||||
|
||||
if (event.TouchInput.touchedCount == 1) {
|
||||
if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED)
|
||||
m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y);
|
||||
m_pointer_type = PointerType::Touch;
|
||||
m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y);
|
||||
|
||||
gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer));
|
||||
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
|
||||
Environment->setFocus(hovered);
|
||||
if (m_hovered != hovered) {
|
||||
if (m_touch_hovered != hovered) {
|
||||
leave();
|
||||
enter(hovered);
|
||||
}
|
||||
gui::IGUIElement *focused = Environment->getFocus();
|
||||
bool ret = simulateMouseEvent(focused, event.TouchInput.Event);
|
||||
if (!ret && m_hovered != focused)
|
||||
ret = simulateMouseEvent(m_hovered.get(), event.TouchInput.Event);
|
||||
if (!ret && m_touch_hovered != focused)
|
||||
ret = simulateMouseEvent(m_touch_hovered.get(), event.TouchInput.Event);
|
||||
if (event.TouchInput.Event == ETIE_LEFT_UP)
|
||||
leave();
|
||||
return ret;
|
||||
|
@ -306,20 +316,24 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (event.EventType == EET_MOUSE_INPUT_EVENT) {
|
||||
s32 x = event.MouseInput.X;
|
||||
s32 y = event.MouseInput.Y;
|
||||
if (!m_simulated_mouse) {
|
||||
// Only set the pointer type to mouse if this is a real mouse event.
|
||||
m_pointer_type = PointerType::Mouse;
|
||||
m_pointer = v2s32(event.MouseInput.X, event.MouseInput.Y);
|
||||
m_touch_hovered.reset();
|
||||
}
|
||||
|
||||
gui::IGUIElement *hovered =
|
||||
Environment->getRootGUIElement()->getElementFromPoint(
|
||||
core::position2d<s32>(x, y));
|
||||
Environment->getRootGUIElement()->getElementFromPoint(m_pointer);
|
||||
if (!isChild(hovered, this)) {
|
||||
if (DoubleClickDetection(event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue