Formspec: Pass the second-touch event as is (#13872)

The second-touch event is passed to the GUIFormSpecMenu::OnEvent() function as a touch event.
There are two types of event for inventory formspec: (1) mouse event and (2) touch event.
The touch event is just a modifier of the mouse event.


Co-authored-by: Gregor Parzefall <82708541+grorp@users.noreply.github.com>
This commit is contained in:
Muhammad Rifqi Priyo Susanto 2023-11-28 07:00:07 +07:00 committed by GitHub
parent 771da80bbb
commit 53886dcdb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 97 additions and 62 deletions

View File

@ -4201,13 +4201,15 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
/* Mouse event other than movement, or crossing the border of inventory
field while holding left, right, or middle mouse button
or touch event (for touch screen devices)
*/
if (event.EventType == EET_MOUSE_INPUT_EVENT &&
if ((event.EventType == EET_MOUSE_INPUT_EVENT &&
(event.MouseInput.Event != EMIE_MOUSE_MOVED ||
((event.MouseInput.isLeftPressed() ||
event.MouseInput.isRightPressed() ||
event.MouseInput.isMiddlePressed()) &&
getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) {
getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) ||
event.EventType == EET_TOUCH_INPUT_EVENT) {
// Get selected item and hovered/clicked item (s)
@ -4276,6 +4278,9 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
ButtonEventType button = BET_OTHER;
ButtonEventType updown = BET_OTHER;
bool mouse_shift = false;
if (event.EventType == EET_MOUSE_INPUT_EVENT) {
mouse_shift = event.MouseInput.Shift;
switch (event.MouseInput.Event) {
case EMIE_LMOUSE_PRESSED_DOWN:
button = BET_LEFT; updown = BET_DOWN;
@ -4306,6 +4311,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
default:
break;
}
}
#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.
@ -4332,6 +4347,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if (m_held_mouse_button != BET_OTHER)
break;
if (button == BET_LEFT || button == BET_RIGHT || button == BET_MIDDLE)
m_held_mouse_button = button;
@ -4351,13 +4367,13 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
// Craft preview has been clicked: craft
if (button == BET_MIDDLE)
craft_amount = 10;
else if (event.MouseInput.Shift && button == BET_LEFT)
else if (mouse_shift && button == BET_LEFT)
craft_amount = list_s->getItem(s.i).getStackMax(m_client->idef());
else
craft_amount = 1;
// Holding shift moves the crafted item to the inventory
m_shift_move_after_craft = event.MouseInput.Shift;
m_shift_move_after_craft = mouse_shift;
} else if (!m_selected_item && button != BET_WHEEL_UP && !empty) {
// Non-empty stack has been clicked: select or shift-move it
@ -4371,7 +4387,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
else if (button == BET_LEFT)
count = s_count;
if (event.MouseInput.Shift) {
if (mouse_shift) {
// Shift pressed: move item, right click moves 1
shift_move_amount = button == BET_RIGHT ? 1 : count;
} else {
@ -4392,7 +4408,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
else if (button == BET_LEFT)
move_amount = m_selected_amount;
if (event.MouseInput.Shift && !identical && matching) {
if (mouse_shift && !identical && matching) {
// Shift-move all items the same as the selected item to the next list
move_amount = 0;
@ -4530,7 +4546,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
if (!s.isValid() || s.listname == "craftpreview")
break;
if (!m_selected_item && event.MouseInput.Shift) {
if (!m_selected_item && mouse_shift) {
// Shift-move items while dragging
if (m_held_mouse_button == BET_RIGHT)
shift_move_amount = 1;
@ -4580,7 +4596,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
case BET_OTHER: {
// Some other mouse event has occured
// Currently only left-double-click should trigger this
if (!s.isValid() || event.MouseInput.Event != EMIE_LMOUSE_DOUBLE_CLICK)
if (!s.isValid() || event.EventType != EET_MOUSE_INPUT_EVENT ||
event.MouseInput.Event != EMIE_LMOUSE_DOUBLE_CLICK)
break;
// Only do the pickup all thing when putting down an item.
@ -4648,6 +4665,28 @@ 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
if (!getAbsoluteClippingRect().isPointInside(m_pointer))
// Is outside the menu
drop_amount = 1;
} else {
// Over a valid slot
move_amount = 1;
if (identical) {
// Change the selected amount instead of moving
if (move_amount >= m_selected_amount)
m_selected_amount = 0;
else
m_selected_amount -= move_amount;
move_amount = 0;
}
}
}
#endif
// Update left-dragged slots
if (m_left_dragging && m_left_drag_stacks.size() > 1) {
// The split amount will always at least one, because the number
@ -5014,6 +5053,11 @@ 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;
}

View File

@ -278,12 +278,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
irr_ptr<GUIModalMenu> holder;
holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
switch ((int)event.TouchInput.touchedCount) {
case 1: {
if (event.TouchInput.ID == 0) {
if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED)
m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y);
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
m_down_pos = m_pointer;
gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer));
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
Environment->setFocus(hovered);
@ -298,26 +295,19 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
if (event.TouchInput.Event == ETIE_LEFT_UP)
leave();
return ret;
}
case 2: {
if (event.TouchInput.Event != ETIE_PRESSED_DOWN)
} else if (event.TouchInput.ID == 1) {
if (event.TouchInput.Event != ETIE_LEFT_UP)
return true; // ignore
auto focused = Environment->getFocus();
if (!focused)
return true;
SEvent rclick_event{};
rclick_event.EventType = EET_MOUSE_INPUT_EVENT;
rclick_event.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN;
rclick_event.MouseInput.ButtonStates = EMBSM_LEFT | EMBSM_RIGHT;
rclick_event.MouseInput.X = m_pointer.X;
rclick_event.MouseInput.Y = m_pointer.Y;
focused->OnEvent(rclick_event);
rclick_event.MouseInput.Event = EMIE_RMOUSE_LEFT_UP;
rclick_event.MouseInput.ButtonStates = EMBSM_LEFT;
focused->OnEvent(rclick_event);
// The second-touch event is propagated as is (not converted).
m_second_touch = true;
focused->OnEvent(event);
m_second_touch = false;
return true;
}
default: // ignored
} else {
// Any other touch after the second touch is ignored.
return true;
}
}

View File

@ -77,7 +77,8 @@ protected:
std::string m_jni_field_name;
#endif
#ifdef HAVE_TOUCHSCREENGUI
v2s32 m_down_pos;
// 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