Pioneer
InputBindings.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #pragma once
5 
6 #include "DeleteEmitter.h"
7 #include <SDL_events.h>
8 #include <SDL_keycode.h>
9 #include <sigc++/sigc++.h>
10 #include <cstdint>
11 #include <iostream>
12 #include <string_view>
13 
14 namespace InputBindings {
15  enum class Response {
16  Ignored = 0,
17  Pressed,
18  Released
19  };
20 
21  struct KeyBinding {
22  enum class Type : uint8_t {
23  Disabled,
28  };
29 
31  union {
32  SDL_Keycode keycode = 0;
33  struct {
34  // 65536 possible IDs should be more than plenty, even with lots of hot-plug noise.
35  uint16_t id;
36  // if type = JoystickHat, this is the hat direction; otherwise it's the button index
37  uint8_t button;
38  uint8_t hat;
40  struct {
41  uint8_t button;
42  } mouse;
43  };
44 
45  KeyBinding() = default;
46 
47  KeyBinding(SDL_Keycode k) :
48  type(Type::KeyboardKey), keycode(k) {}
49 
50  static KeyBinding JoystickButton(uint16_t joystickID, uint8_t button)
51  {
52  KeyBinding t;
54  t.joystick = { joystickID, button, 0 };
55  return t;
56  }
57 
58  static KeyBinding JoystickHat(uint16_t joystickID, uint8_t hat, uint8_t direction)
59  {
60  KeyBinding t;
62  t.joystick = { joystickID, direction, hat };
63  return t;
64  }
65 
66  static KeyBinding MouseButton(uint8_t mouseButton)
67  {
68  KeyBinding t;
70  t.mouse.button = mouseButton;
71  return t;
72  }
73 
74  static KeyBinding FromEvent(SDL_Event &event);
75 
76  bool Enabled() const { return type != Type::Disabled; }
77  Response Matches(const SDL_Event &ev) const;
78 
79  bool operator==(const KeyBinding &rhs) const;
80  bool operator<(const KeyBinding &rhs) const;
81 
82  // serialization
83  friend std::string_view &operator>>(std::string_view &, KeyBinding &);
84  friend std::ostream &operator<<(std::ostream &, const KeyBinding &);
85  };
86 
87  struct JoyAxis {
88  uint16_t joystickId;
89  uint8_t axis;
90  int8_t direction; // if 0, the axis is disabled
91 
92  bool Enabled() const { return direction != 0; }
93 
94  bool operator==(const JoyAxis &rhs) const
95  {
96  if (!direction && !rhs.direction)
97  return true;
98 
99  return joystickId == rhs.joystickId && axis == rhs.axis && direction == rhs.direction;
100  }
101 
102  // serialization
103  friend std::string_view &operator>>(std::string_view &, JoyAxis &);
104  friend std::ostream &operator<<(std::ostream &, const JoyAxis &);
105  };
106 
107  struct KeyChord {
111 
112  KeyChord() = default;
113  KeyChord(KeyBinding a, KeyBinding m1 = {}, KeyBinding m2 = {}) :
114  activator(a),
115  modifier1(m1),
116  modifier2(m2)
117  {}
118 
119  bool IsActive() const { return Enabled() && m_active; }
120  bool Enabled() const { return activator.Enabled(); }
121 
122  bool operator==(const KeyChord &rhs) const
123  {
124  return activator == rhs.activator && modifier1 == rhs.modifier1 && modifier2 == rhs.modifier2;
125  }
126  bool operator!=(const KeyChord &rhs) const { return !(*this == rhs); }
127 
128  // Groups chords by number of modifiers in descending order
129  bool operator<(const KeyChord &rhs) const
130  {
131  return (modifier2.Enabled() && !rhs.modifier2.Enabled()) || (modifier1.Enabled() && !rhs.modifier1.Enabled());
132  }
133 
134  bool m_active = false;
135  uint8_t m_queuedEvents = 0;
136 
137  // serialization
138  friend std::string_view &operator>>(std::string_view &, KeyChord &);
139  friend std::ostream &operator<<(std::ostream &, const KeyChord &);
140  };
141 
142  struct Action : public DeleteEmitter {
145  bool m_active = false;
146  sigc::signal<void> onPressed;
147  sigc::signal<void> onReleased;
148 
149  Action() = default;
150  Action(KeyChord b1, KeyChord b2 = {}) :
151  binding(b1),
152  binding2(b2)
153  {}
154 
155  // NOTE: sigc::signals cannot be copied, this function is for convenience to copy bindings only
156  Action &operator=(const Action &rhs);
157 
158  bool IsActive() { return m_active; }
159  bool Enabled() { return binding.Enabled() || binding2.Enabled(); }
160 
161  // serialization
162  friend std::string_view &operator>>(std::string_view &, Action &);
163  friend std::ostream &operator<<(std::ostream &, const Action &);
164  };
165 
166  struct Axis : public DeleteEmitter {
170  float m_value;
172  sigc::signal<void, float> onAxisValue;
173 
174  Axis() = default;
175  Axis(JoyAxis a, KeyChord p = {}, KeyChord n = {}) :
176  axis(a),
177  positive(p),
178  negative(n)
179  {}
180 
181  Axis(KeyChord p, KeyChord n = {}) :
182  axis{},
183  positive(p),
184  negative(n)
185  {}
186 
187  // NOTE: sigc::signals cannot be copied, this function is for convenience to copy bindings only
188  Axis &operator=(const Axis &rhs);
189 
190  bool IsActive() { return m_value != 0.0 || positive.IsActive() || negative.IsActive(); }
191  float GetValue() { return m_value; }
192  // if we want to set the value of the axis, for example from the UI slider
193  // must be remembered separately, because m_value is overwritten by data from the joystick
194  void SetValue(float value) { m_manualValue = value; }
195  bool Enabled() { return axis.Enabled() || positive.Enabled() || negative.Enabled(); }
196 
197  // serialization
198  friend std::string_view &operator>>(std::string_view &, Axis &);
199  friend std::ostream &operator<<(std::ostream &, const Axis &);
200  };
201 
202  std::string_view &operator>>(std::string_view &, KeyBinding &);
203  std::ostream &operator<<(std::ostream &, const KeyBinding &);
204 
205  std::string_view &operator>>(std::string_view &, JoyAxis &);
206  std::ostream &operator<<(std::ostream &, const JoyAxis &);
207 
208  std::string_view &operator>>(std::string_view &, KeyChord &);
209  std::ostream &operator<<(std::ostream &, const KeyChord &);
210 
211  std::string_view &operator>>(std::string_view &, Action &);
212  std::ostream &operator<<(std::ostream &, const Action &);
213 
214  std::string_view &operator>>(std::string_view &, Axis &);
215  std::ostream &operator<<(std::ostream &, const Axis &);
216 }; // namespace InputBindings
Definition: DeleteEmitter.h:16
Definition: InputBindings.h:14
Response
Definition: InputBindings.h:15
std::string_view & operator>>(std::string_view &, KeyBinding &)
Definition: InputBindings.cpp:159
std::ostream & operator<<(std::ostream &, const KeyBinding &)
Definition: InputBindings.cpp:206
Definition: InputBindings.h:142
friend std::string_view & operator>>(std::string_view &, Action &)
sigc::signal< void > onPressed
Definition: InputBindings.h:146
bool Enabled()
Definition: InputBindings.h:159
Action(KeyChord b1, KeyChord b2={})
Definition: InputBindings.h:150
KeyChord binding
Definition: InputBindings.h:143
KeyChord binding2
Definition: InputBindings.h:144
friend std::ostream & operator<<(std::ostream &, const Action &)
Action & operator=(const Action &rhs)
Definition: InputBindings.cpp:121
sigc::signal< void > onReleased
Definition: InputBindings.h:147
bool m_active
Definition: InputBindings.h:145
bool IsActive()
Definition: InputBindings.h:158
Definition: InputBindings.h:166
bool Enabled()
Definition: InputBindings.h:195
Axis(JoyAxis a, KeyChord p={}, KeyChord n={})
Definition: InputBindings.h:175
Axis & operator=(const Axis &rhs)
Definition: InputBindings.cpp:128
KeyChord negative
Definition: InputBindings.h:169
friend std::ostream & operator<<(std::ostream &, const Axis &)
float GetValue()
Definition: InputBindings.h:191
float m_manualValue
Definition: InputBindings.h:171
float m_value
Definition: InputBindings.h:170
friend std::string_view & operator>>(std::string_view &, Axis &)
bool IsActive()
Definition: InputBindings.h:190
KeyChord positive
Definition: InputBindings.h:168
void SetValue(float value)
Definition: InputBindings.h:194
sigc::signal< void, float > onAxisValue
Definition: InputBindings.h:172
JoyAxis axis
Definition: InputBindings.h:167
Axis(KeyChord p, KeyChord n={})
Definition: InputBindings.h:181
Definition: InputBindings.h:87
friend std::ostream & operator<<(std::ostream &, const JoyAxis &)
friend std::string_view & operator>>(std::string_view &, JoyAxis &)
uint8_t axis
Definition: InputBindings.h:89
bool operator==(const JoyAxis &rhs) const
Definition: InputBindings.h:94
int8_t direction
Definition: InputBindings.h:90
bool Enabled() const
Definition: InputBindings.h:92
uint16_t joystickId
Definition: InputBindings.h:88
Definition: InputBindings.h:21
bool Enabled() const
Definition: InputBindings.h:76
struct InputBindings::KeyBinding::@4::@6 joystick
KeyBinding(SDL_Keycode k)
Definition: InputBindings.h:47
Type
Definition: InputBindings.h:22
static KeyBinding JoystickButton(uint16_t joystickID, uint8_t button)
Definition: InputBindings.h:50
bool operator==(const KeyBinding &rhs) const
Definition: InputBindings.cpp:74
uint8_t hat
Definition: InputBindings.h:38
friend std::string_view & operator>>(std::string_view &, KeyBinding &)
SDL_Keycode keycode
Definition: InputBindings.h:32
Response Matches(const SDL_Event &ev) const
Definition: InputBindings.cpp:53
struct InputBindings::KeyBinding::@4::@7 mouse
bool operator<(const KeyBinding &rhs) const
Definition: InputBindings.cpp:93
friend std::ostream & operator<<(std::ostream &, const KeyBinding &)
static KeyBinding MouseButton(uint8_t mouseButton)
Definition: InputBindings.h:66
uint8_t button
Definition: InputBindings.h:37
Type type
Definition: InputBindings.h:30
static KeyBinding FromEvent(SDL_Event &event)
uint16_t id
Definition: InputBindings.h:35
static KeyBinding JoystickHat(uint16_t joystickID, uint8_t hat, uint8_t direction)
Definition: InputBindings.h:58
Definition: InputBindings.h:107
bool operator<(const KeyChord &rhs) const
Definition: InputBindings.h:129
friend std::string_view & operator>>(std::string_view &, KeyChord &)
bool operator!=(const KeyChord &rhs) const
Definition: InputBindings.h:126
KeyChord(KeyBinding a, KeyBinding m1={}, KeyBinding m2={})
Definition: InputBindings.h:113
bool IsActive() const
Definition: InputBindings.h:119
friend std::ostream & operator<<(std::ostream &, const KeyChord &)
KeyBinding activator
Definition: InputBindings.h:108
KeyBinding modifier2
Definition: InputBindings.h:110
bool Enabled() const
Definition: InputBindings.h:120
bool operator==(const KeyChord &rhs) const
Definition: InputBindings.h:122
bool m_active
Definition: InputBindings.h:134
uint8_t m_queuedEvents
Definition: InputBindings.h:135
KeyBinding modifier1
Definition: InputBindings.h:109