summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/uiinput.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2024-04-12 02:49:15 +1000
committer Vas Crabb <vas@vastheman.com>2024-04-12 02:49:15 +1000
commit4ddd26fe21edba8e7df65b12d721e9bed579e6e4 (patch)
treee1452c7d52a51fcefdf83a686f585c53ce10f5c0 /src/emu/uiinput.cpp
parent78ef444ea6b639336b174e8e47d782a016ae6ae7 (diff)
Initial touch input support:
* Feed mouse/pen/touch pointer events through UI input manager with Win32 and SDL. * Started migrating UI code to use new API and reworking mouse/touch interaction. * emu/render.cpp: Support pressing multiple clickable layout items simultaneously. * emu/render.cpp: Allow UI elements to be drawn in any window. * emu/rendlay.cpp, luaengine_render.cpp: Added layout view events for pointer input. * ui/ui.cpp: Allow the UI handler to control pointer display. * ui/analogipt.cpp: Added mouse/touch and more keys for navigating field state list. * ui/menu.cpp: Use vertical swipe to scroll and horizontal swipe to adjust. * ui/menu.cpp: Draw after processing input - greatly improves responsiveness. * ui/menu.cpp: Ignore keyboard/gamepad input during pointer actions. * ui/selmenu.cpp: Made left/right info pane arrows repeat when held. * ui/selmenu.cpp: Use middle click to move keyboard focus. * ui/selmenu.cpp: Let filter list scroll if it's too tall, and use a bit of horizontal padding. * ui/selmenu.cpp: Improved divider sizing. * ui/state.cpp: Don't allow clicks to pass through the confirm deletion prompt to the menu. * ui/simpleselgame.cpp: Fixed error message display and graphics/sound status not showing. * ui/simpleselgame.cpp: Allow tap/click to dismiss error message. * ui/utils.cpp: Show UI for choice filters when there are no choices - it's less confusing. * modules/input/input_sdl.cpp: Made scaling for mouse scroll better match RawInput and DirectInput. * modules/input/input_rawinput.cpp: Added support for horizontal scroll axis. * modules/input/input_win32.cpp: Added support for scroll axes and more buttons to mouse/lightgun. * modules/debugger/debugimgui.cpp: Don't fight over events with the UI manager - it breaks menus. * osd/windows/window.cpp: Translate mouse position to window cooridinates for scroll wheel events. * osd/sdl/window.cpp: Supply last mouse position for scroll wheel events if possible. * scripts/build/complay.py: Made zero input mask an error - it was only being used to block clicks.
Diffstat (limited to 'src/emu/uiinput.cpp')
-rw-r--r--src/emu/uiinput.cpp262
1 files changed, 67 insertions, 195 deletions
diff --git a/src/emu/uiinput.cpp b/src/emu/uiinput.cpp
index 138bf67055d..12ba8a08bb0 100644
--- a/src/emu/uiinput.cpp
+++ b/src/emu/uiinput.cpp
@@ -36,19 +36,11 @@ enum
ui_input_manager::ui_input_manager(running_machine &machine)
: m_machine(machine)
, m_presses_enabled(true)
- , m_current_mouse_target(nullptr)
- , m_current_mouse_x(-1)
- , m_current_mouse_y(-1)
- , m_current_mouse_down(false)
- , m_current_mouse_field(nullptr)
, m_events_start(0)
, m_events_end(0)
{
std::fill(std::begin(m_next_repeat), std::end(m_next_repeat), 0);
std::fill(std::begin(m_seqpressed), std::end(m_seqpressed), 0);
-
- // add a frame callback to poll inputs
- machine.add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&ui_input_manager::frame_update, this));
}
@@ -58,12 +50,12 @@ ui_input_manager::ui_input_manager(running_machine &machine)
***************************************************************************/
/*-------------------------------------------------
- frame_update - looks through pressed
- input as per events pushed our way and posts
+ check_ui_inputs - looks through pressed input
+ as per events pushed our way and posts
corresponding IPT_UI_* events
-------------------------------------------------*/
-void ui_input_manager::frame_update()
+void ui_input_manager::check_ui_inputs()
{
// update the state of all the UI keys
for (ioport_type code = ioport_type(IPT_UI_FIRST + 1); code < IPT_UI_LAST; ++code)
@@ -80,22 +72,6 @@ void ui_input_manager::frame_update()
m_seqpressed[code] = false;
}
}
-
- // perform mouse hit testing
- ioport_field *mouse_field = m_current_mouse_down ? find_mouse_field() : nullptr;
- if (m_current_mouse_field != mouse_field)
- {
- // clear the old field if there was one
- if (m_current_mouse_field != nullptr)
- m_current_mouse_field->set_value(0);
-
- // set the new field if it exists and isn't already being pressed
- if (mouse_field != nullptr && !mouse_field->digital_value())
- mouse_field->set_value(1);
-
- // update internal state
- m_current_mouse_field = mouse_field;
- }
}
@@ -106,37 +82,6 @@ void ui_input_manager::frame_update()
bool ui_input_manager::push_event(ui_event evt)
{
- // some pre-processing (this is an icky place to do this stuff!)
- switch (evt.event_type)
- {
- case ui_event::type::MOUSE_MOVE:
- m_current_mouse_target = evt.target;
- m_current_mouse_x = evt.mouse_x;
- m_current_mouse_y = evt.mouse_y;
- break;
-
- case ui_event::type::MOUSE_LEAVE:
- if (m_current_mouse_target == evt.target)
- {
- m_current_mouse_target = nullptr;
- m_current_mouse_x = -1;
- m_current_mouse_y = -1;
- }
- break;
-
- case ui_event::type::MOUSE_DOWN:
- m_current_mouse_down = true;
- break;
-
- case ui_event::type::MOUSE_UP:
- m_current_mouse_down = false;
- break;
-
- default:
- /* do nothing */
- break;
- }
-
// is the queue filled up?
if ((m_events_end + 1) % std::size(m_events) == m_events_start)
return false;
@@ -186,64 +131,12 @@ void ui_input_manager::reset()
}
-/*-------------------------------------------------
- find_mouse - retrieves the current
- location of the mouse
--------------------------------------------------*/
-
-render_target *ui_input_manager::find_mouse(s32 *x, s32 *y, bool *button) const
-{
- if (x != nullptr)
- *x = m_current_mouse_x;
- if (y != nullptr)
- *y = m_current_mouse_y;
- if (button != nullptr)
- *button = m_current_mouse_down;
- return m_current_mouse_target;
-}
-
-
-/*-------------------------------------------------
- find_mouse_field - retrieves the input field
- the mouse is currently pointing at
--------------------------------------------------*/
-
-ioport_field *ui_input_manager::find_mouse_field() const
-{
- // map the point and determine what was hit
- if (m_current_mouse_target != nullptr)
- {
- ioport_port *port = nullptr;
- ioport_value mask;
- float x, y;
- if (m_current_mouse_target->map_point_input(m_current_mouse_x, m_current_mouse_y, port, mask, x, y))
- {
- if (port != nullptr)
- return port->field(mask);
- }
- }
- return nullptr;
-}
-
-
/***************************************************************************
USER INTERFACE SEQUENCE READING
***************************************************************************/
/*-------------------------------------------------
- pressed - return true if a key down
- for the given user interface sequence is
- detected
--------------------------------------------------*/
-
-bool ui_input_manager::pressed(int code)
-{
- return pressed_repeat(code, 0);
-}
-
-
-/*-------------------------------------------------
pressed_repeat - return true if a key
down for the given user interface sequence is
detected, or if autorepeat at the given speed
@@ -272,7 +165,7 @@ bool ui_input_manager::pressed_repeat(int code, int speed)
/* if this is an autorepeat case, set a 1x delay and leave pressed = 1 */
else if (speed > 0 && (osd_ticks() + tps - m_next_repeat[code]) >= tps)
{
- // In the autorepeatcase, we need to double check the key is still pressed
+ // In the autorepeat case, we need to double-check the key is still pressed
// as there can be a delay between the key polling and our processing of the event
m_seqpressed[code] = machine().ioport().type_pressed(ioport_type(code));
pressed = (m_seqpressed[code] == SEQ_PRESSED_TRUE);
@@ -319,105 +212,84 @@ void ui_input_manager::push_window_defocus_event(render_target *target)
}
/*-------------------------------------------------
- push_mouse_move_event - pushes a mouse
- move event to the specified render_target
--------------------------------------------------*/
-
-void ui_input_manager::push_mouse_move_event(render_target *target, s32 x, s32 y)
-{
- ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_MOVE;
- event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
- push_event(event);
-}
-
-/*-------------------------------------------------
- push_mouse_leave_event - pushes a
- mouse leave event to the specified render_target
--------------------------------------------------*/
-
-void ui_input_manager::push_mouse_leave_event(render_target *target)
-{
- ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_LEAVE;
- event.target = target;
- push_event(event);
-}
-
-/*-------------------------------------------------
- push_mouse_down_event - pushes a mouse
- down event to the specified render_target
--------------------------------------------------*/
-
-void ui_input_manager::push_mouse_down_event(render_target *target, s32 x, s32 y)
-{
- ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_DOWN;
- event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
- push_event(event);
-}
-
-/*-------------------------------------------------
- push_mouse_down_event - pushes a mouse
- down event to the specified render_target
--------------------------------------------------*/
-
-void ui_input_manager::push_mouse_up_event(render_target *target, s32 x, s32 y)
-{
- ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_UP;
- event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
- push_event(event);
-}
-
-/*-------------------------------------------------
-push_mouse_down_event - pushes a mouse
-down event to the specified render_target
+ push_pointer_update - pushes a pointer update
+ event to the specified render_target
-------------------------------------------------*/
-void ui_input_manager::push_mouse_rdown_event(render_target *target, s32 x, s32 y)
+void ui_input_manager::push_pointer_update(
+ render_target *target,
+ pointer type,
+ u16 ptrid,
+ u16 device,
+ s32 x,
+ s32 y,
+ u32 buttons,
+ u32 pressed,
+ u32 released,
+ s16 clicks)
{
ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_RDOWN;
+ event.event_type = ui_event::type::POINTER_UPDATE;
event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
+ event.pointer_type = type;
+ event.pointer_id = ptrid;
+ event.pointer_device = device;
+ event.pointer_x = x;
+ event.pointer_y = y;
+ event.pointer_buttons = buttons;
+ event.pointer_pressed = pressed;
+ event.pointer_released = released;
+ event.pointer_clicks = clicks;
push_event(event);
}
-/*-------------------------------------------------
-push_mouse_down_event - pushes a mouse
-down event to the specified render_target
--------------------------------------------------*/
-
-void ui_input_manager::push_mouse_rup_event(render_target *target, s32 x, s32 y)
+void ui_input_manager::push_pointer_leave(
+ render_target *target,
+ pointer type,
+ u16 ptrid,
+ u16 device,
+ s32 x,
+ s32 y,
+ u32 released,
+ s16 clicks)
{
ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_RUP;
+ event.event_type = ui_event::type::POINTER_LEAVE;
event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
+ event.pointer_type = type;
+ event.pointer_id = ptrid;
+ event.pointer_device = device;
+ event.pointer_x = x;
+ event.pointer_y = y;
+ event.pointer_buttons = 0U;
+ event.pointer_pressed = 0U;
+ event.pointer_released = released;
+ event.pointer_clicks = clicks;
push_event(event);
}
-/*-------------------------------------------------
- push_mouse_double_click_event - pushes
- a mouse double-click event to the specified
- render_target
--------------------------------------------------*/
-void ui_input_manager::push_mouse_double_click_event(render_target *target, s32 x, s32 y)
+void ui_input_manager::push_pointer_abort(
+ render_target *target,
+ pointer type,
+ u16 ptrid,
+ u16 device,
+ s32 x,
+ s32 y,
+ u32 released,
+ s16 clicks)
{
ui_event event = { ui_event::type::NONE };
- event.event_type = ui_event::type::MOUSE_DOUBLE_CLICK;
+ event.event_type = ui_event::type::POINTER_ABORT;
event.target = target;
- event.mouse_x = x;
- event.mouse_y = y;
+ event.pointer_type = type;
+ event.pointer_id = ptrid;
+ event.pointer_device = device;
+ event.pointer_x = x;
+ event.pointer_y = y;
+ event.pointer_buttons = 0U;
+ event.pointer_pressed = 0U;
+ event.pointer_released = released;
+ event.pointer_clicks = clicks;
push_event(event);
}
@@ -439,7 +311,7 @@ void ui_input_manager::push_char_event(render_target *target, char32_t ch)
wheel event to the specified render_target
-------------------------------------------------*/
-void ui_input_manager::push_mouse_wheel_event(render_target *target, s32 x, s32 y, short delta, int ucNumLines)
+void ui_input_manager::push_mouse_wheel_event(render_target *target, s32 x, s32 y, short delta, int lines)
{
ui_event event = { ui_event::type::NONE };
event.event_type = ui_event::type::MOUSE_WHEEL;
@@ -447,7 +319,7 @@ void ui_input_manager::push_mouse_wheel_event(render_target *target, s32 x, s32
event.mouse_x = x;
event.mouse_y = y;
event.zdelta = delta;
- event.num_lines = ucNumLines;
+ event.num_lines = lines;
push_event(event);
}