summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/uiinput.h
blob: a69abc07c6b90546f3c894640b122c04fd140869 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************

    uiinput.h

    Internal MAME user interface input state.

***************************************************************************/

#ifndef MAME_EMU_UIINPUT_H
#define MAME_EMU_UIINPUT_H

#pragma once

#include "render.h"


/***************************************************************************
    TYPE DEFINITIONS
***************************************************************************/

struct ui_event
{
	enum class type
	{
		NONE,
		WINDOW_FOCUS,
		WINDOW_DEFOCUS,
		MOUSE_MOVE,
		MOUSE_LEAVE,
		MOUSE_DOWN,
		MOUSE_UP,
		MOUSE_RDOWN,
		MOUSE_RUP,
		MOUSE_DOUBLE_CLICK,
		MOUSE_WHEEL,
		IME_CHAR
	};

	type                event_type;
	render_target *     target;
	s32                 mouse_x;
	s32                 mouse_y;
	input_item_id       key;
	char32_t            ch;
	short               zdelta;
	int                 num_lines;
};

// ======================> ui_input_manager

class ui_input_manager
{
public:
	// construction/destruction
	ui_input_manager(running_machine &machine);

	void frame_update();

	// pushes a single event onto the queue
	bool push_event(ui_event event);

	// pops an event off of the queue
	bool pop_event(ui_event *event);

	// check the next event type without removing it
	ui_event::type peek_event_type() const { return (m_events_start != m_events_end) ? m_events[m_events_start].event_type : ui_event::type::NONE; }

	// clears all outstanding events
	void reset();

	// retrieves the current location of the mouse
	render_target *find_mouse(s32 *x, s32 *y, bool *button) const;
	ioport_field *find_mouse_field(float &xoffs, float &yoffs, render_target::item_handle &item) const;

	// return true if a key down for the given user interface sequence is detected
	bool pressed(int code);

	// enable/disable UI key presses
	bool presses_enabled() const { return m_presses_enabled; }
	void set_presses_enabled(bool enabled) { m_presses_enabled = enabled; }

	// return true if a key down for the given user interface sequence is detected, or if autorepeat at the given speed is triggered
	bool pressed_repeat(int code, int speed);

	// getters
	running_machine &machine() const { return m_machine; }

	// queueing events
	void push_window_focus_event(render_target *target);
	void push_window_defocus_event(render_target *target);
	void push_mouse_move_event(render_target *target, s32 x, s32 y);
	void push_mouse_leave_event(render_target *target);
	void push_mouse_down_event(render_target *target, s32 x, s32 y);
	void push_mouse_up_event(render_target *target, s32 x, s32 y);
	void push_mouse_rdown_event(render_target *target, s32 x, s32 y);
	void push_mouse_rup_event(render_target *target, s32 x, s32 y);
	void push_mouse_double_click_event(render_target *target, s32 x, s32 y);
	void push_char_event(render_target *target, char32_t ch);
	void push_mouse_wheel_event(render_target *target, s32 x, s32 y, short delta, int ucNumLines);

	void mark_all_as_pressed();

private:

	// constants
	constexpr static unsigned EVENT_QUEUE_SIZE = 128;

	// internal state
	running_machine &   m_machine;                  // reference to our machine

	// pressed states; retrieved with ui_input_pressed()
	bool                        m_presses_enabled;
	osd_ticks_t                 m_next_repeat[IPT_COUNT];
	u8                          m_seqpressed[IPT_COUNT];

	// mouse position/info
	render_target *             m_current_mouse_target;
	s32                         m_current_mouse_x;
	s32                         m_current_mouse_y;
	bool                        m_current_mouse_down;
	ioport_field *              m_current_mouse_field;
	render_target::item_handle  m_current_mouse_drag_item;
	float                       m_current_mouse_target_dx;
	float                       m_current_mouse_target_dy;

	// popped states; ring buffer of ui_events
	ui_event                    m_events[EVENT_QUEUE_SIZE];
	int                         m_events_start;
	int                         m_events_end;
};

#endif // MAME_EMU_UIINPUT_H