mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 08:03:45 +01:00
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
|
||||
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 &&
|
||||
(event.MouseInput.Event != EMIE_MOUSE_MOVED ||
|
||||
((event.MouseInput.isLeftPressed() ||
|
||||
event.MouseInput.isRightPressed() ||
|
||||
event.MouseInput.isMiddlePressed()) &&
|
||||
getItemAtPos(m_pointer).i != getItemAtPos(m_old_pointer).i))) {
|
||||
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))) ||
|
||||
event.EventType == EET_TOUCH_INPUT_EVENT) {
|
||||
|
||||
// Get selected item and hovered/clicked item (s)
|
||||
|
||||
@ -4276,37 +4278,50 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
||||
|
||||
ButtonEventType button = BET_OTHER;
|
||||
ButtonEventType updown = BET_OTHER;
|
||||
switch (event.MouseInput.Event) {
|
||||
case EMIE_LMOUSE_PRESSED_DOWN:
|
||||
button = BET_LEFT; updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_RMOUSE_PRESSED_DOWN:
|
||||
button = BET_RIGHT; updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_MMOUSE_PRESSED_DOWN:
|
||||
button = BET_MIDDLE; updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_MOUSE_WHEEL:
|
||||
button = (event.MouseInput.Wheel > 0) ?
|
||||
BET_WHEEL_UP : BET_WHEEL_DOWN;
|
||||
updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
button = BET_LEFT; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_RMOUSE_LEFT_UP:
|
||||
button = BET_RIGHT; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_MMOUSE_LEFT_UP:
|
||||
button = BET_MIDDLE; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_MOUSE_MOVED:
|
||||
updown = BET_MOVE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case EMIE_RMOUSE_PRESSED_DOWN:
|
||||
button = BET_RIGHT; updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_MMOUSE_PRESSED_DOWN:
|
||||
button = BET_MIDDLE; updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_MOUSE_WHEEL:
|
||||
button = (event.MouseInput.Wheel > 0) ?
|
||||
BET_WHEEL_UP : BET_WHEEL_DOWN;
|
||||
updown = BET_DOWN;
|
||||
break;
|
||||
case EMIE_LMOUSE_LEFT_UP:
|
||||
button = BET_LEFT; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_RMOUSE_LEFT_UP:
|
||||
button = BET_RIGHT; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_MMOUSE_LEFT_UP:
|
||||
button = BET_MIDDLE; updown = BET_UP;
|
||||
break;
|
||||
case EMIE_MOUSE_MOVED:
|
||||
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
|
||||
// from m_selected_item to s.
|
||||
u32 move_amount = 0;
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user