Skip to content

Commit

Permalink
Auto-toggle TouchScreenGUI in-game when receiving touch/mouse input
Browse files Browse the repository at this point in the history
  • Loading branch information
grorp committed Apr 17, 2024
1 parent f2b5c35 commit f4ca1ea
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 22 deletions.
9 changes: 9 additions & 0 deletions irr/include/IEventReceiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ILogger.h"
#include "Keycodes.h"
#include "irrString.h"
#include <cstring>

namespace irr
{
Expand Down Expand Up @@ -297,6 +298,11 @@ enum EGUI_EVENT_TYPE
//! SEvents hold information about an event. See irr::IEventReceiver for details on event handling.
struct SEvent
{
SEvent()
{
memset(this, 0, sizeof(*this));
}

//! Any kind of GUI event.
struct SGUIEvent
{
Expand Down Expand Up @@ -345,6 +351,9 @@ struct SEvent

//! Type of mouse event
EMOUSE_INPUT_EVENT Event;

//! Is this a simulated mouse event generated by Minetest itself?
bool Simulated;
};

//! Any kind of keyboard event.
Expand Down
9 changes: 6 additions & 3 deletions src/client/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "content/subgames.h"
#include "client/event_manager.h"
#include "fontengine.h"
#include "gui/pointer_type.h"
#include "gui/touchscreengui.h"
#include "itemdef.h"
#include "log.h"
Expand Down Expand Up @@ -1227,6 +1228,7 @@ void Game::shutdown()
// Clear text when exiting.
m_game_ui->clearText();

g_touchscreengui_tsrc = nullptr;
if (g_touchscreengui)
g_touchscreengui->hide();

Expand Down Expand Up @@ -1555,8 +1557,9 @@ bool Game::initGui()
gui_chat_console = new GUIChatConsole(guienv, guienv->getRootGUIElement(),
-1, chat_backend, client, &g_menumgr);

if (g_settings->getBool("enable_touch"))
g_touchscreengui = new TouchScreenGUI(device, texture_src);
g_touchscreengui_tsrc = texture_src;
if (g_last_pointer_type == PointerType::Touch)
g_touchscreengui = new TouchScreenGUI(device, g_touchscreengui_tsrc);

return true;
}
Expand Down Expand Up @@ -2609,7 +2612,7 @@ void Game::updateCameraDirection(CameraOrientation *cam, float dtime)
cur_control->setVisible(false);
}

if (m_first_loop_after_window_activation) {
if (m_first_loop_after_window_activation && !g_touchscreengui) {
m_first_loop_after_window_activation = false;

input->setMousePos(driver->getScreenSize().Width / 2,
Expand Down
17 changes: 17 additions & 0 deletions src/client/inputhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "gui/pointer_type.h"
#include "util/numeric.h"
#include "inputhandler.h"
#include "gui/mainmenumanager.h"
Expand Down Expand Up @@ -99,6 +100,22 @@ void KeyCache::populate()

bool MyEventReceiver::OnEvent(const SEvent &event)
{
if (event.EventType == EET_MOUSE_INPUT_EVENT && !event.MouseInput.Simulated)
g_last_pointer_type = PointerType::Mouse;
else if (event.EventType == EET_TOUCH_INPUT_EVENT)
g_last_pointer_type = PointerType::Touch;

if (g_touchscreengui_tsrc && g_last_pointer_type == PointerType::Mouse &&
g_touchscreengui) {
g_touchscreengui->hide();
delete g_touchscreengui;
g_touchscreengui = nullptr;
} else if (g_touchscreengui_tsrc && g_last_pointer_type == PointerType::Touch &&
!g_touchscreengui) {
g_touchscreengui = new TouchScreenGUI(RenderingEngine::get_raw_device(),
g_touchscreengui_tsrc);
}

/*
React to nothing here if a menu is active
*/
Expand Down
3 changes: 2 additions & 1 deletion src/gui/guiFormSpecMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h"
#include "gamedef.h"
#include "client/keycode.h"
#include "gui/pointer_type.h"
#include "util/strfnd.h"
#include <IGUIButton.h>
#include <IGUICheckBox.h>
Expand Down Expand Up @@ -3775,7 +3776,7 @@ void GUIFormSpecMenu::showTooltip(const std::wstring &text,
int tooltip_offset_x = m_btn_height;
int tooltip_offset_y = m_btn_height;

if (m_pointer_type == PointerType::Touch) {
if (g_last_pointer_type == PointerType::Touch) {
tooltip_offset_x *= 3;
tooltip_offset_y = 0;
if (m_pointer.X > (s32)screenSize.X / 2)
Expand Down
3 changes: 2 additions & 1 deletion src/gui/guiInventoryList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/

#include "guiInventoryList.h"
#include "gui/pointer_type.h"
#include "guiFormSpecMenu.h"
#include "client/hud.h"
#include "client/client.h"
Expand Down Expand Up @@ -153,7 +154,7 @@ void GUIInventoryList::draw()
// Add hovering tooltip
bool show_tooltip = !item.empty() && hovering && !selected_item;
// Make it possible to see item tooltips on touchscreens
if (m_fs_menu->getPointerType() == PointerType::Touch) {
if (g_last_pointer_type == PointerType::Touch) {
show_tooltip |= hovering && selected && m_fs_menu->getSelectedAmount() != 0;
}
if (show_tooltip) {
Expand Down
10 changes: 4 additions & 6 deletions src/gui/modalMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "client/renderingengine.h"
#include "modalMenu.h"
#include "gettext.h"
#include "gui/pointer_type.h"
#include "porting.h"
#include "settings.h"
#include "touchscreengui.h"
Expand Down Expand Up @@ -165,6 +166,7 @@ bool GUIModalMenu::simulateMouseEvent(ETOUCH_INPUT_EVENT touch_event, bool secon
mouse_event.EventType = EET_MOUSE_INPUT_EVENT;
mouse_event.MouseInput.X = m_pointer.X;
mouse_event.MouseInput.Y = m_pointer.Y;
mouse_event.MouseInput.Simulated = true;
switch (touch_event) {
case ETIE_PRESSED_DOWN:
mouse_event.MouseInput.Event = EMIE_LMOUSE_PRESSED_DOWN;
Expand All @@ -188,7 +190,6 @@ bool GUIModalMenu::simulateMouseEvent(ETOUCH_INPUT_EVENT touch_event, bool secon
}

bool retval;
m_simulated_mouse = true;
do {
if (preprocessEvent(mouse_event)) {
retval = true;
Expand All @@ -200,7 +201,6 @@ bool GUIModalMenu::simulateMouseEvent(ETOUCH_INPUT_EVENT touch_event, bool secon
}
retval = target->OnEvent(mouse_event);
} while (false);
m_simulated_mouse = false;

if (!retval && !second_try)
return simulateMouseEvent(touch_event, true);
Expand Down Expand Up @@ -303,7 +303,6 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
holder.grab(this); // keep this alive until return (it might be dropped downstream [?])

if (event.TouchInput.touchedCount == 1) {
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));
Expand Down Expand Up @@ -354,9 +353,8 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
}

if (event.EventType == EET_MOUSE_INPUT_EVENT) {
if (!m_simulated_mouse) {
// Only set the pointer type to mouse if this is a real mouse event.
m_pointer_type = PointerType::Mouse;
if (!event.MouseInput.Simulated) {
// Only process if this is a real mouse event.
m_pointer = v2s32(event.MouseInput.X, event.MouseInput.Y);
m_touch_hovered.reset();
}
Expand Down
11 changes: 0 additions & 11 deletions src/gui/modalMenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <porting_android.h>
#endif

enum class PointerType {
Mouse,
Touch,
};

class GUIModalMenu;

Expand Down Expand Up @@ -66,14 +62,10 @@ class GUIModalMenu : public gui::IGUIElement
porting::AndroidDialogState getAndroidUIInputState();
#endif

PointerType getPointerType() { return m_pointer_type; };

protected:
virtual std::wstring getLabelByID(s32 id) = 0;
virtual std::string getNameByID(s32 id) = 0;

// 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.
Expand All @@ -88,9 +80,6 @@ class GUIModalMenu : public gui::IGUIElement

// This is set to true if the menu is currently processing a second-touch event.
bool m_second_touch = false;
// 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:
IMenuManager *m_menumgr;
Expand Down
10 changes: 10 additions & 0 deletions src/gui/pointer_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once
#include "client/texturesource.h"

enum class PointerType {
Mouse,
Touch,
};

inline PointerType g_last_pointer_type = PointerType::Mouse;
inline ITextureSource *g_touchscreengui_tsrc = nullptr;
1 change: 1 addition & 0 deletions src/gui/touchscreengui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,7 @@ void TouchScreenGUI::emitMouseEvent(EMOUSE_INPUT_EVENT type)
event.MouseInput.Control = false;
event.MouseInput.ButtonStates = 0;
event.MouseInput.Event = type;
event.MouseInput.Simulated = true;
m_receiver->OnEvent(event);
}

Expand Down

0 comments on commit f4ca1ea

Please sign in to comment.