diff options
author | 2024-04-12 02:49:15 +1000 | |
---|---|---|
committer | 2024-04-12 02:49:15 +1000 | |
commit | 4ddd26fe21edba8e7df65b12d721e9bed579e6e4 (patch) | |
tree | e1452c7d52a51fcefdf83a686f585c53ce10f5c0 /src/emu/uiinput.cpp | |
parent | 78ef444ea6b639336b174e8e47d782a016ae6ae7 (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.cpp | 262 |
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); } |