mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Support both mouse and touch input in GUIs in a single binary (#14146)
This commit is contained in:
		@@ -3656,22 +3656,18 @@ void GUIFormSpecMenu::drawMenu()
 | 
			
		||||
			NULL, m_client, IT_ROT_HOVERED);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// On touchscreens, m_pointer is set by GUIModalMenu::preprocessEvent instead.
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	m_pointer = RenderingEngine::get_raw_device()->getCursorControl()->getPosition();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
		Draw fields/buttons tooltips and update the mouse cursor
 | 
			
		||||
	*/
 | 
			
		||||
	gui::IGUIElement *hovered =
 | 
			
		||||
			Environment->getRootGUIElement()->getElementFromPoint(m_pointer);
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	gui::ICursorControl *cursor_control = RenderingEngine::get_raw_device()->
 | 
			
		||||
			getCursorControl();
 | 
			
		||||
	gui::ECURSOR_ICON current_cursor_icon = cursor_control->getActiveIcon();
 | 
			
		||||
#endif
 | 
			
		||||
	gui::ECURSOR_ICON current_cursor_icon = gui::ECI_NORMAL;
 | 
			
		||||
	if (cursor_control)
 | 
			
		||||
		current_cursor_icon = cursor_control->getActiveIcon();
 | 
			
		||||
 | 
			
		||||
	bool hovered_element_found = false;
 | 
			
		||||
 | 
			
		||||
	if (hovered) {
 | 
			
		||||
@@ -3715,11 +3711,10 @@ void GUIFormSpecMenu::drawMenu()
 | 
			
		||||
							m_tooltips[field.fname].bgcolor);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
				if (field.ftype != f_HyperText && // Handled directly in guiHyperText
 | 
			
		||||
				if (cursor_control &&
 | 
			
		||||
						field.ftype != f_HyperText && // Handled directly in guiHyperText
 | 
			
		||||
						current_cursor_icon != field.fcursor_icon)
 | 
			
		||||
					cursor_control->setActiveIcon(field.fcursor_icon);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
				hovered_element_found = true;
 | 
			
		||||
 | 
			
		||||
@@ -3730,10 +3725,8 @@ void GUIFormSpecMenu::drawMenu()
 | 
			
		||||
 | 
			
		||||
	if (!hovered_element_found) {
 | 
			
		||||
		// no element is hovered
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
		if (current_cursor_icon != ECI_NORMAL)
 | 
			
		||||
		if (cursor_control && current_cursor_icon != ECI_NORMAL)
 | 
			
		||||
			cursor_control->setActiveIcon(ECI_NORMAL);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_tooltip_element->draw();
 | 
			
		||||
@@ -3764,16 +3757,13 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text,
 | 
			
		||||
	v2u32 screenSize = Environment->getVideoDriver()->getScreenSize();
 | 
			
		||||
	int tooltip_offset_x = m_btn_height;
 | 
			
		||||
	int tooltip_offset_y = m_btn_height;
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	tooltip_offset_x *= 3;
 | 
			
		||||
	tooltip_offset_y  = 0;
 | 
			
		||||
	if (m_pointer.X > (s32)screenSize.X / 2)
 | 
			
		||||
		tooltip_offset_x = -(tooltip_offset_x + tooltip_width);
 | 
			
		||||
 | 
			
		||||
	// Hide tooltip after ETIE_LEFT_UP
 | 
			
		||||
	if (m_pointer.X == 0)
 | 
			
		||||
		return;
 | 
			
		||||
#endif
 | 
			
		||||
	if (m_pointer_type == PointerType::Touch) {
 | 
			
		||||
		tooltip_offset_x *= 3;
 | 
			
		||||
		tooltip_offset_y  = 0;
 | 
			
		||||
		if (m_pointer.X > (s32)screenSize.X / 2)
 | 
			
		||||
			tooltip_offset_x = -(tooltip_offset_x + tooltip_width);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Calculate and set the tooltip position
 | 
			
		||||
	s32 tooltip_x = m_pointer.X + tooltip_offset_x;
 | 
			
		||||
@@ -4070,6 +4060,11 @@ void GUIFormSpecMenu::acceptInput(FormspecQuitMode quitmode)
 | 
			
		||||
 | 
			
		||||
bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
 | 
			
		||||
{
 | 
			
		||||
	// This must be done first so that GUIModalMenu can set m_pointer_type
 | 
			
		||||
	// correctly.
 | 
			
		||||
	if (GUIModalMenu::preprocessEvent(event))
 | 
			
		||||
		return true;
 | 
			
		||||
 | 
			
		||||
	// The IGUITabControl renders visually using the skin's selected
 | 
			
		||||
	// font, which we override for the duration of form drawing,
 | 
			
		||||
	// but computes tab hotspots based on how it would have rendered
 | 
			
		||||
@@ -4147,7 +4142,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
 | 
			
		||||
		return handled;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return GUIModalMenu::preprocessEvent(event);
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GUIFormSpecMenu::tryClose()
 | 
			
		||||
@@ -4326,14 +4321,12 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
		// The second touch (see GUIModalMenu::preprocessEvent() function)
 | 
			
		||||
		ButtonEventType touch = BET_OTHER;
 | 
			
		||||
		if (event.EventType == EET_TOUCH_INPUT_EVENT) {
 | 
			
		||||
			if (event.TouchInput.Event == ETIE_LEFT_UP)
 | 
			
		||||
				touch = BET_RIGHT;
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		// Set this number to a positive value to generate a move action
 | 
			
		||||
		// from m_selected_item to s.
 | 
			
		||||
@@ -4678,7 +4671,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
		if (touch == BET_RIGHT && m_selected_item && !m_left_dragging) {
 | 
			
		||||
			if (!s.isValid()) {
 | 
			
		||||
				// Not a valid slot
 | 
			
		||||
@@ -4698,7 +4690,6 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		// Update left-dragged slots
 | 
			
		||||
		if (m_left_dragging && m_left_drag_stacks.size() > 1) {
 | 
			
		||||
@@ -5067,10 +5058,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	if (m_second_touch)
 | 
			
		||||
		return true; // Stop propagating the event
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return Parent ? Parent->OnEvent(event) : false;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1052,14 +1052,10 @@ void GUIHyperText::checkHover(s32 X, s32 Y)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	if (m_drawer.m_hovertag)
 | 
			
		||||
		RenderingEngine::get_raw_device()->getCursorControl()->setActiveIcon(
 | 
			
		||||
				gui::ECI_HAND);
 | 
			
		||||
	else
 | 
			
		||||
		RenderingEngine::get_raw_device()->getCursorControl()->setActiveIcon(
 | 
			
		||||
				gui::ECI_NORMAL);
 | 
			
		||||
#endif
 | 
			
		||||
	ICursorControl *cursor_control = RenderingEngine::get_raw_device()->getCursorControl();
 | 
			
		||||
 | 
			
		||||
	if (cursor_control)
 | 
			
		||||
		cursor_control->setActiveIcon(m_drawer.m_hovertag ? gui::ECI_HAND : gui::ECI_NORMAL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GUIHyperText::OnEvent(const SEvent &event)
 | 
			
		||||
@@ -1075,12 +1071,11 @@ bool GUIHyperText::OnEvent(const SEvent &event)
 | 
			
		||||
	if (event.EventType == EET_GUI_EVENT &&
 | 
			
		||||
			event.GUIEvent.EventType == EGET_ELEMENT_LEFT) {
 | 
			
		||||
		m_drawer.m_hovertag = nullptr;
 | 
			
		||||
#ifndef HAVE_TOUCHSCREENGUI
 | 
			
		||||
		gui::ICursorControl *cursor_control =
 | 
			
		||||
				RenderingEngine::get_raw_device()->getCursorControl();
 | 
			
		||||
		if (cursor_control->isVisible())
 | 
			
		||||
 | 
			
		||||
		ICursorControl *cursor_control = RenderingEngine::get_raw_device()->getCursorControl();
 | 
			
		||||
 | 
			
		||||
		if (cursor_control && cursor_control->isVisible())
 | 
			
		||||
			cursor_control->setActiveIcon(gui::ECI_NORMAL);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (event.EventType == EET_MOUSE_INPUT_EVENT) {
 | 
			
		||||
 
 | 
			
		||||
@@ -152,10 +152,10 @@ void GUIInventoryList::draw()
 | 
			
		||||
 | 
			
		||||
		// Add hovering tooltip
 | 
			
		||||
		bool show_tooltip = !item.empty() && hovering && !selected_item;
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
		// Make it possible to see item tooltips on touchscreens
 | 
			
		||||
		show_tooltip |= hovering && selected && m_fs_menu->getSelectedAmount() != 0;
 | 
			
		||||
#endif
 | 
			
		||||
		if (m_fs_menu->getPointerType() == PointerType::Touch) {
 | 
			
		||||
			show_tooltip |= hovering && selected && m_fs_menu->getSelectedAmount() != 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (show_tooltip) {
 | 
			
		||||
			std::string tooltip = orig_item.getDescription(client->idef());
 | 
			
		||||
			if (m_fs_menu->doTooltipAppendItemname())
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 | 
			
		||||
#include "irr_ptr.h"
 | 
			
		||||
#include "util/string.h"
 | 
			
		||||
 | 
			
		||||
enum class PointerType {
 | 
			
		||||
	Mouse,
 | 
			
		||||
	Touch,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GUIModalMenu;
 | 
			
		||||
 | 
			
		||||
class IMenuManager
 | 
			
		||||
@@ -58,6 +63,8 @@ public:
 | 
			
		||||
	bool hasAndroidUIInput();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	PointerType getPointerType() { return m_pointer_type; };
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	virtual std::wstring getLabelByID(s32 id) = 0;
 | 
			
		||||
	virtual std::string getNameByID(s32 id) = 0;
 | 
			
		||||
@@ -69,18 +76,25 @@ protected:
 | 
			
		||||
	 */
 | 
			
		||||
	bool DoubleClickDetection(const SEvent &event);
 | 
			
		||||
 | 
			
		||||
	// Stores the last known pointer type.
 | 
			
		||||
	PointerType m_pointer_type = PointerType::Mouse;
 | 
			
		||||
	// Stores the last known pointer position.
 | 
			
		||||
	// If the last input event was a mouse event, it's the cursor position.
 | 
			
		||||
	// If the last input event was a touch event, it's the finger position.
 | 
			
		||||
	v2s32 m_pointer;
 | 
			
		||||
	v2s32 m_old_pointer;  // Mouse position after previous mouse event
 | 
			
		||||
 | 
			
		||||
	v2u32 m_screensize_old;
 | 
			
		||||
	float m_gui_scale;
 | 
			
		||||
#ifdef __ANDROID__
 | 
			
		||||
	std::string m_jni_field_name;
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
 | 
			
		||||
	// This is set to true if the menu is currently processing a second-touch event.
 | 
			
		||||
	bool m_second_touch = false;
 | 
			
		||||
	bool m_touchscreen_visible = true;
 | 
			
		||||
#endif
 | 
			
		||||
	// This is set to true if the menu is currently processing a mouse event
 | 
			
		||||
	// that was synthesized by the menu itself from a touch event.
 | 
			
		||||
	bool m_simulated_mouse = false;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	struct clickpos
 | 
			
		||||
@@ -102,11 +116,11 @@ private:
 | 
			
		||||
	// wants to launch other menus
 | 
			
		||||
	bool m_allow_focus_removal = false;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_TOUCHSCREENGUI
 | 
			
		||||
	irr_ptr<gui::IGUIElement> m_hovered;
 | 
			
		||||
	// Stuff related to touchscreen input
 | 
			
		||||
 | 
			
		||||
	irr_ptr<gui::IGUIElement> m_touch_hovered;
 | 
			
		||||
 | 
			
		||||
	bool simulateMouseEvent(gui::IGUIElement *target, ETOUCH_INPUT_EVENT touch_event);
 | 
			
		||||
	void enter(gui::IGUIElement *element);
 | 
			
		||||
	void leave();
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user