forked from Mirrorlandia_minetest/minetest
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:
parent
771da80bbb
commit
53886dcdb5
@ -4200,14 +4200,16 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Mouse event other than movement, or crossing the border of inventory
|
/* Mouse event other than movement, or crossing the border of inventory
|
||||||
field while holding left, right, or middle mouse button
|
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.Event != EMIE_MOUSE_MOVED ||
|
||||||
((event.MouseInput.isLeftPressed() ||
|
((event.MouseInput.isLeftPressed() ||
|
||||||
event.MouseInput.isRightPressed() ||
|
event.MouseInput.isRightPressed() ||
|
||||||
event.MouseInput.isMiddlePressed()) &&
|
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)
|
// Get selected item and hovered/clicked item (s)
|
||||||
|
|
||||||
@ -4276,37 +4278,50 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
|
|
||||||
ButtonEventType button = BET_OTHER;
|
ButtonEventType button = BET_OTHER;
|
||||||
ButtonEventType updown = BET_OTHER;
|
ButtonEventType updown = BET_OTHER;
|
||||||
switch (event.MouseInput.Event) {
|
bool mouse_shift = false;
|
||||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
if (event.EventType == EET_MOUSE_INPUT_EVENT) {
|
||||||
button = BET_LEFT; updown = BET_DOWN;
|
mouse_shift = event.MouseInput.Shift;
|
||||||
break;
|
switch (event.MouseInput.Event) {
|
||||||
case EMIE_RMOUSE_PRESSED_DOWN:
|
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||||
button = BET_RIGHT; updown = BET_DOWN;
|
button = BET_LEFT; updown = BET_DOWN;
|
||||||
break;
|
break;
|
||||||
case EMIE_MMOUSE_PRESSED_DOWN:
|
case EMIE_RMOUSE_PRESSED_DOWN:
|
||||||
button = BET_MIDDLE; updown = BET_DOWN;
|
button = BET_RIGHT; updown = BET_DOWN;
|
||||||
break;
|
break;
|
||||||
case EMIE_MOUSE_WHEEL:
|
case EMIE_MMOUSE_PRESSED_DOWN:
|
||||||
button = (event.MouseInput.Wheel > 0) ?
|
button = BET_MIDDLE; updown = BET_DOWN;
|
||||||
BET_WHEEL_UP : BET_WHEEL_DOWN;
|
break;
|
||||||
updown = BET_DOWN;
|
case EMIE_MOUSE_WHEEL:
|
||||||
break;
|
button = (event.MouseInput.Wheel > 0) ?
|
||||||
case EMIE_LMOUSE_LEFT_UP:
|
BET_WHEEL_UP : BET_WHEEL_DOWN;
|
||||||
button = BET_LEFT; updown = BET_UP;
|
updown = BET_DOWN;
|
||||||
break;
|
break;
|
||||||
case EMIE_RMOUSE_LEFT_UP:
|
case EMIE_LMOUSE_LEFT_UP:
|
||||||
button = BET_RIGHT; updown = BET_UP;
|
button = BET_LEFT; updown = BET_UP;
|
||||||
break;
|
break;
|
||||||
case EMIE_MMOUSE_LEFT_UP:
|
case EMIE_RMOUSE_LEFT_UP:
|
||||||
button = BET_MIDDLE; updown = BET_UP;
|
button = BET_RIGHT; updown = BET_UP;
|
||||||
break;
|
break;
|
||||||
case EMIE_MOUSE_MOVED:
|
case EMIE_MMOUSE_LEFT_UP:
|
||||||
updown = BET_MOVE;
|
button = BET_MIDDLE; updown = BET_UP;
|
||||||
break;
|
break;
|
||||||
default:
|
case EMIE_MOUSE_MOVED:
|
||||||
break;
|
updown = BET_MOVE;
|
||||||
|
break;
|
||||||
|
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
|
// Set this number to a positive value to generate a move action
|
||||||
// from m_selected_item to s.
|
// from m_selected_item to s.
|
||||||
u32 move_amount = 0;
|
u32 move_amount = 0;
|
||||||
@ -4332,6 +4347,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
|
|
||||||
if (m_held_mouse_button != BET_OTHER)
|
if (m_held_mouse_button != BET_OTHER)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (button == BET_LEFT || button == BET_RIGHT || button == BET_MIDDLE)
|
if (button == BET_LEFT || button == BET_RIGHT || button == BET_MIDDLE)
|
||||||
m_held_mouse_button = button;
|
m_held_mouse_button = button;
|
||||||
|
|
||||||
@ -4351,13 +4367,13 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
// Craft preview has been clicked: craft
|
// Craft preview has been clicked: craft
|
||||||
if (button == BET_MIDDLE)
|
if (button == BET_MIDDLE)
|
||||||
craft_amount = 10;
|
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());
|
craft_amount = list_s->getItem(s.i).getStackMax(m_client->idef());
|
||||||
else
|
else
|
||||||
craft_amount = 1;
|
craft_amount = 1;
|
||||||
|
|
||||||
// Holding shift moves the crafted item to the inventory
|
// 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) {
|
} else if (!m_selected_item && button != BET_WHEEL_UP && !empty) {
|
||||||
// Non-empty stack has been clicked: select or shift-move it
|
// 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)
|
else if (button == BET_LEFT)
|
||||||
count = s_count;
|
count = s_count;
|
||||||
|
|
||||||
if (event.MouseInput.Shift) {
|
if (mouse_shift) {
|
||||||
// Shift pressed: move item, right click moves 1
|
// Shift pressed: move item, right click moves 1
|
||||||
shift_move_amount = button == BET_RIGHT ? 1 : count;
|
shift_move_amount = button == BET_RIGHT ? 1 : count;
|
||||||
} else {
|
} else {
|
||||||
@ -4392,7 +4408,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
else if (button == BET_LEFT)
|
else if (button == BET_LEFT)
|
||||||
move_amount = m_selected_amount;
|
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
|
// Shift-move all items the same as the selected item to the next list
|
||||||
move_amount = 0;
|
move_amount = 0;
|
||||||
|
|
||||||
@ -4530,7 +4546,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
if (!s.isValid() || s.listname == "craftpreview")
|
if (!s.isValid() || s.listname == "craftpreview")
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!m_selected_item && event.MouseInput.Shift) {
|
if (!m_selected_item && mouse_shift) {
|
||||||
// Shift-move items while dragging
|
// Shift-move items while dragging
|
||||||
if (m_held_mouse_button == BET_RIGHT)
|
if (m_held_mouse_button == BET_RIGHT)
|
||||||
shift_move_amount = 1;
|
shift_move_amount = 1;
|
||||||
@ -4580,7 +4596,8 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
case BET_OTHER: {
|
case BET_OTHER: {
|
||||||
// Some other mouse event has occured
|
// Some other mouse event has occured
|
||||||
// Currently only left-double-click should trigger this
|
// 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;
|
break;
|
||||||
|
|
||||||
// Only do the pickup all thing when putting down an item.
|
// Only do the pickup all thing when putting down an item.
|
||||||
@ -4648,6 +4665,28 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||||||
break;
|
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
|
// Update left-dragged slots
|
||||||
if (m_left_dragging && m_left_drag_stacks.size() > 1) {
|
if (m_left_dragging && m_left_drag_stacks.size() > 1) {
|
||||||
// The split amount will always at least one, because the number
|
// 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;
|
return Parent ? Parent->OnEvent(event) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,12 +278,9 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||||||
irr_ptr<GUIModalMenu> holder;
|
irr_ptr<GUIModalMenu> holder;
|
||||||
holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
|
holder.grab(this); // keep this alive until return (it might be dropped downstream [?])
|
||||||
|
|
||||||
switch ((int)event.TouchInput.touchedCount) {
|
if (event.TouchInput.ID == 0) {
|
||||||
case 1: {
|
|
||||||
if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED)
|
if (event.TouchInput.Event == ETIE_PRESSED_DOWN || event.TouchInput.Event == ETIE_MOVED)
|
||||||
m_pointer = v2s32(event.TouchInput.X, event.TouchInput.Y);
|
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));
|
gui::IGUIElement *hovered = Environment->getRootGUIElement()->getElementFromPoint(core::position2d<s32>(m_pointer));
|
||||||
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
|
if (event.TouchInput.Event == ETIE_PRESSED_DOWN)
|
||||||
Environment->setFocus(hovered);
|
Environment->setFocus(hovered);
|
||||||
@ -298,26 +295,19 @@ bool GUIModalMenu::preprocessEvent(const SEvent &event)
|
|||||||
if (event.TouchInput.Event == ETIE_LEFT_UP)
|
if (event.TouchInput.Event == ETIE_LEFT_UP)
|
||||||
leave();
|
leave();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else if (event.TouchInput.ID == 1) {
|
||||||
case 2: {
|
if (event.TouchInput.Event != ETIE_LEFT_UP)
|
||||||
if (event.TouchInput.Event != ETIE_PRESSED_DOWN)
|
|
||||||
return true; // ignore
|
return true; // ignore
|
||||||
auto focused = Environment->getFocus();
|
auto focused = Environment->getFocus();
|
||||||
if (!focused)
|
if (!focused)
|
||||||
return true;
|
return true;
|
||||||
SEvent rclick_event{};
|
// The second-touch event is propagated as is (not converted).
|
||||||
rclick_event.EventType = EET_MOUSE_INPUT_EVENT;
|
m_second_touch = true;
|
||||||
rclick_event.MouseInput.Event = EMIE_RMOUSE_PRESSED_DOWN;
|
focused->OnEvent(event);
|
||||||
rclick_event.MouseInput.ButtonStates = EMBSM_LEFT | EMBSM_RIGHT;
|
m_second_touch = false;
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
} else {
|
||||||
default: // ignored
|
// Any other touch after the second touch is ignored.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,8 @@ protected:
|
|||||||
std::string m_jni_field_name;
|
std::string m_jni_field_name;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
#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;
|
bool m_touchscreen_visible = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user