mini-arcade-native-backend 0.4.0__tar.gz → 0.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (20) hide show
  1. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/CHANGELOG.md +29 -0
  2. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/PKG-INFO +2 -2
  3. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/cpp/bindings.cpp +20 -1
  4. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/cpp/engine.cpp +57 -5
  5. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/cpp/engine.h +34 -3
  6. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/pyproject.toml +2 -2
  7. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/src/mini_arcade_native_backend/__init__.py +83 -5
  8. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/tests/test_init.py +94 -16
  9. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.github/workflows/ci.yml +0 -0
  10. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.github/workflows/create-release-branch.yml +0 -0
  11. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.github/workflows/release-finalize.yml +0 -0
  12. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.github/workflows/release-publish.yml +0 -0
  13. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.gitignore +0 -0
  14. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/.vscode/settings.json +0 -0
  15. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/CMakeLists.txt +0 -0
  16. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/LICENSE +0 -0
  17. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/README.md +0 -0
  18. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/examples/native_backend_demo.py +0 -0
  19. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/poetry.lock +0 -0
  20. {mini_arcade_native_backend-0.4.0 → mini_arcade_native_backend-0.4.2}/poetry.toml +0 -0
@@ -6,6 +6,35 @@ This project adheres to [Semantic Versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.2] - 2025-12-16
10
+
11
+ ### Added
12
+ - enhance event handling by adding key_code to event mapping in NativeBackend
13
+
14
+ ## [0.4.1] - 2025-12-15
15
+
16
+ ### Added
17
+ - extend event handling with additional mouse and window events in engine and bindings
18
+ - enhance font handling by returning font ID and updating draw_text signature
19
+
20
+ ### Fixed
21
+ - update mini-arcade-core dependency version to ensure compatibility
22
+
23
+ ### Other
24
+ - Merge release/0.3 into develop
25
+
26
+ ## [0.4.0] - 2025-12-15
27
+
28
+ ### Added
29
+ - extend event handling with additional mouse and window events in engine and bindings
30
+ - enhance font handling by returning font ID and updating draw_text signature
31
+
32
+ ### Fixed
33
+ - update mini-arcade-core dependency version to ensure compatibility
34
+
35
+ ### Other
36
+ - Merge release/0.3 into develop
37
+
9
38
  ## [0.3.3] - 2025-12-05
10
39
 
11
40
  ### Other
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mini-arcade-native-backend
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Native SDL2 backend for mini-arcade-core using SDL2 + pybind11.
5
5
  Author-Email: Santiago Rincon <rincores@gmail.com>
6
6
  License: Copyright (c) 2025 Santiago Rincón
@@ -24,7 +24,7 @@ License: Copyright (c) 2025 Santiago Rincón
24
24
  SOFTWARE.
25
25
 
26
26
  Requires-Python: <3.12,>=3.9
27
- Requires-Dist: mini-arcade-core>=0.2.3
27
+ Requires-Dist: mini-arcade-core~=0.9
28
28
  Provides-Extra: dev
29
29
  Requires-Dist: pytest~=8.3; extra == "dev"
30
30
  Requires-Dist: pytest-cov~=6.0; extra == "dev"
@@ -14,12 +14,31 @@ PYBIND11_MODULE(_native, m) {
14
14
  .value("Quit", mini::EventType::Quit)
15
15
  .value("KeyDown", mini::EventType::KeyDown)
16
16
  .value("KeyUp", mini::EventType::KeyUp)
17
+ .value("MouseMotion", mini::EventType::MouseMotion)
18
+ .value("MouseButtonDown", mini::EventType::MouseButtonDown)
19
+ .value("MouseButtonUp", mini::EventType::MouseButtonUp)
20
+ .value("MouseWheel", mini::EventType::MouseWheel)
21
+ .value("WindowResized", mini::EventType::WindowResized)
22
+ .value("TextInput", mini::EventType::TextInput)
17
23
  .export_values();
18
24
 
19
25
  // Bind the Event struct
20
26
  py::class_<mini::Event>(m, "Event")
21
27
  .def_readonly("type", &mini::Event::type)
22
- .def_readonly("key", &mini::Event::key);
28
+ .def_readonly("key", &mini::Event::key)
29
+ .def_readonly("scancode", &mini::Event::scancode)
30
+ .def_readonly("mod", &mini::Event::mod)
31
+ .def_readonly("repeat", &mini::Event::repeat)
32
+ .def_readonly("x", &mini::Event::x)
33
+ .def_readonly("y", &mini::Event::y)
34
+ .def_readonly("dx", &mini::Event::dx)
35
+ .def_readonly("dy", &mini::Event::dy)
36
+ .def_readonly("button", &mini::Event::button)
37
+ .def_readonly("wheel_x", &mini::Event::wheel_x)
38
+ .def_readonly("wheel_y", &mini::Event::wheel_y)
39
+ .def_readonly("width", &mini::Event::width)
40
+ .def_readonly("height", &mini::Event::height)
41
+ .def_readonly("text", &mini::Event::text);
23
42
 
24
43
  // Bind the Engine class
25
44
  py::class_<mini::Engine>(m, "Engine")
@@ -10,7 +10,8 @@ namespace mini {
10
10
  renderer_(nullptr),
11
11
  initialized_(false),
12
12
  font_(nullptr),
13
- clear_color_{0, 0, 0, 255}
13
+ clear_color_{0, 0, 0, 255},
14
+ default_font_id_(-1)
14
15
  {
15
16
  }
16
17
 
@@ -87,6 +88,8 @@ namespace mini {
87
88
  // Enable alpha blending for RGBA drawing
88
89
  SDL_SetRenderDrawBlendMode(renderer_, SDL_BLENDMODE_BLEND);
89
90
 
91
+ SDL_StartTextInput(); // <--- needed for SDL_TEXTINPUT
92
+
90
93
  initialized_ = true;
91
94
  }
92
95
 
@@ -245,7 +248,6 @@ namespace mini {
245
248
  SDL_RenderFillRect(renderer_, &rect);
246
249
  }
247
250
 
248
-
249
251
  bool Engine::capture_frame(const char* path)
250
252
  {
251
253
  if (!initialized_ || renderer_ == nullptr) {
@@ -305,8 +307,6 @@ namespace mini {
305
307
 
306
308
  while (SDL_PollEvent(&sdl_event)) {
307
309
  Event ev;
308
- ev.type = EventType::Unknown;
309
- ev.key = 0;
310
310
 
311
311
  switch (sdl_event.type) {
312
312
  case SDL_QUIT:
@@ -316,11 +316,63 @@ namespace mini {
316
316
  case SDL_KEYDOWN:
317
317
  ev.type = EventType::KeyDown;
318
318
  ev.key = sdl_event.key.keysym.sym;
319
+ ev.scancode = (int)sdl_event.key.keysym.scancode;
320
+ ev.mod = (int)sdl_event.key.keysym.mod;
321
+ ev.repeat = (int)sdl_event.key.repeat;
319
322
  break;
320
323
 
321
324
  case SDL_KEYUP:
322
325
  ev.type = EventType::KeyUp;
323
326
  ev.key = sdl_event.key.keysym.sym;
327
+ ev.scancode = (int)sdl_event.key.keysym.scancode;
328
+ ev.mod = (int)sdl_event.key.keysym.mod;
329
+ ev.repeat = 0;
330
+ break;
331
+
332
+ case SDL_MOUSEMOTION:
333
+ ev.type = EventType::MouseMotion;
334
+ ev.x = sdl_event.motion.x;
335
+ ev.y = sdl_event.motion.y;
336
+ ev.dx = sdl_event.motion.xrel;
337
+ ev.dy = sdl_event.motion.yrel;
338
+ break;
339
+
340
+ case SDL_MOUSEBUTTONDOWN:
341
+ ev.type = EventType::MouseButtonDown;
342
+ ev.button = (int)sdl_event.button.button;
343
+ ev.x = sdl_event.button.x;
344
+ ev.y = sdl_event.button.y;
345
+ break;
346
+
347
+ case SDL_MOUSEBUTTONUP:
348
+ ev.type = EventType::MouseButtonUp;
349
+ ev.button = (int)sdl_event.button.button;
350
+ ev.x = sdl_event.button.x;
351
+ ev.y = sdl_event.button.y;
352
+ break;
353
+
354
+ case SDL_MOUSEWHEEL:
355
+ ev.type = EventType::MouseWheel;
356
+ ev.wheel_x = sdl_event.wheel.x;
357
+ ev.wheel_y = sdl_event.wheel.y;
358
+ // If you want "natural" direction handling, you can flip based on sdl_event.wheel.direction
359
+ break;
360
+
361
+ case SDL_TEXTINPUT:
362
+ ev.type = EventType::TextInput;
363
+ ev.text = sdl_event.text.text; // UTF-8
364
+ break;
365
+
366
+ case SDL_WINDOWEVENT:
367
+ if (sdl_event.window.event == SDL_WINDOWEVENT_RESIZED ||
368
+ sdl_event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
369
+ {
370
+ ev.type = EventType::WindowResized;
371
+ ev.width = sdl_event.window.data1;
372
+ ev.height = sdl_event.window.data2;
373
+ } else {
374
+ continue; // ignore other window events
375
+ }
324
376
  break;
325
377
 
326
378
  default:
@@ -328,7 +380,7 @@ namespace mini {
328
380
  break;
329
381
  }
330
382
 
331
- events.push_back(ev);
383
+ events.push_back(std::move(ev));
332
384
  }
333
385
 
334
386
  return events;
@@ -3,6 +3,7 @@
3
3
  #include <SDL.h>
4
4
  #include <SDL_ttf.h>
5
5
  #include <vector>
6
+ #include <string>
6
7
 
7
8
  // A minimal 2D graphics engine binding for Python using SDL.
8
9
  namespace mini {
@@ -11,14 +12,44 @@ namespace mini {
11
12
  enum class EventType {
12
13
  Unknown = 0,
13
14
  Quit,
15
+
14
16
  KeyDown,
15
- KeyUp
17
+ KeyUp,
18
+
19
+ MouseMotion,
20
+ MouseButtonDown,
21
+ MouseButtonUp,
22
+ MouseWheel,
23
+
24
+ WindowResized,
25
+ TextInput
16
26
  };
17
27
 
18
28
  // A simple event structure to pass events to Python.
19
29
  struct Event {
20
- EventType type;
21
- int key; // SDL key code (e.g., 27 for ESC). 0 if not applicable.
30
+ EventType type = EventType::Unknown;
31
+
32
+ // Keyboard
33
+ int key = 0; // SDL_Keycode
34
+ int scancode = 0; // SDL_Scancode
35
+ int mod = 0; // SDL_Keymod bitmask
36
+ int repeat = 0; // 1 if key repeat, else 0
37
+
38
+ // Mouse
39
+ int x = 0;
40
+ int y = 0;
41
+ int dx = 0; // motion relative
42
+ int dy = 0;
43
+ int button = 0; // SDL_BUTTON_LEFT etc.
44
+ int wheel_x = 0;
45
+ int wheel_y = 0;
46
+
47
+ // Window
48
+ int width = 0;
49
+ int height = 0;
50
+
51
+ // Text input
52
+ std::string text;
22
53
  };
23
54
 
24
55
  // The main engine class that wraps SDL functionality.
@@ -8,7 +8,7 @@ build-backend = "scikit_build_core.build"
8
8
 
9
9
  [project]
10
10
  name = "mini-arcade-native-backend"
11
- version = "0.4.0"
11
+ version = "0.4.2"
12
12
  description = "Native SDL2 backend for mini-arcade-core using SDL2 + pybind11."
13
13
  authors = [
14
14
  { name = "Santiago Rincon", email = "rincores@gmail.com" },
@@ -17,7 +17,7 @@ readme = "README.md"
17
17
  requires-python = ">=3.9,<3.12"
18
18
  license = { file = "LICENSE" }
19
19
  dependencies = [
20
- "mini-arcade-core>=0.2.3",
20
+ "mini-arcade-core~=0.9",
21
21
  ]
22
22
 
23
23
  [project.optional-dependencies]
@@ -37,6 +37,7 @@ if sys.platform == "win32":
37
37
  # Justification: Need to import core after setting DLL path on Windows
38
38
  # pylint: disable=wrong-import-position
39
39
  from mini_arcade_core import Backend, Event, EventType
40
+ from mini_arcade_core.keymaps.sdl import SDL_KEYCODE_TO_KEY
40
41
 
41
42
  # Justification: Importing the native extension module
42
43
  # pylint: disable=import-self,no-name-in-module
@@ -53,6 +54,12 @@ _NATIVE_TO_CORE = {
53
54
  native.EventType.Quit: EventType.QUIT,
54
55
  native.EventType.KeyDown: EventType.KEYDOWN,
55
56
  native.EventType.KeyUp: EventType.KEYUP,
57
+ native.EventType.MouseMotion: EventType.MOUSEMOTION,
58
+ native.EventType.MouseButtonDown: EventType.MOUSEBUTTONDOWN,
59
+ native.EventType.MouseButtonUp: EventType.MOUSEBUTTONUP,
60
+ native.EventType.MouseWheel: EventType.MOUSEWHEEL,
61
+ native.EventType.WindowResized: EventType.WINDOWRESIZED,
62
+ native.EventType.TextInput: EventType.TEXTINPUT,
56
63
  }
57
64
 
58
65
 
@@ -108,6 +115,8 @@ class NativeBackend(Backend):
108
115
  """
109
116
  self._engine.set_clear_color(int(r), int(g), int(b))
110
117
 
118
+ # Justification: Many local variables needed for event mapping
119
+ # pylint: disable=too-many-locals
111
120
  def poll_events(self) -> list[Event]:
112
121
  """
113
122
  Poll for events from the backend and return them as a list of Event objects.
@@ -115,12 +124,81 @@ class NativeBackend(Backend):
115
124
  :return: List of Event objects representing the polled events.
116
125
  :rtype: list[Event]
117
126
  """
118
- events: list[Event] = []
127
+ out: list[Event] = []
119
128
  for ev in self._engine.poll_events():
120
- core_type = _NATIVE_TO_CORE.get(ev.type, EventType.UNKNOWN)
121
- key = ev.key if getattr(ev, "key", 0) != 0 else None
122
- events.append(Event(type=core_type, key=key))
123
- return events
129
+ etype = _NATIVE_TO_CORE.get(ev.type, EventType.UNKNOWN)
130
+
131
+ key = None
132
+ key_code = None
133
+ scancode = None
134
+ mod = None
135
+ repeat = None
136
+
137
+ x = y = dx = dy = None
138
+ button = None
139
+ wheel = None
140
+ size = None
141
+ text = None
142
+
143
+ if etype in (EventType.KEYDOWN, EventType.KEYUP):
144
+ raw_key = int(getattr(ev, "key", 0) or 0)
145
+ key_code = raw_key if raw_key != 0 else None
146
+ key = SDL_KEYCODE_TO_KEY.get(raw_key) if raw_key != 0 else None
147
+
148
+ scancode = (
149
+ int(ev.scancode) if getattr(ev, "scancode", 0) else None
150
+ )
151
+ mod = int(ev.mod) if getattr(ev, "mod", 0) else None
152
+
153
+ rep = int(getattr(ev, "repeat", 0) or 0)
154
+ repeat = bool(rep) if etype == EventType.KEYDOWN else None
155
+
156
+ elif etype == EventType.MOUSEMOTION:
157
+ x = int(ev.x)
158
+ y = int(ev.y)
159
+ dx = int(ev.dx)
160
+ dy = int(ev.dy)
161
+
162
+ elif etype in (EventType.MOUSEBUTTONDOWN, EventType.MOUSEBUTTONUP):
163
+ button = int(ev.button) if ev.button else None
164
+ x = int(ev.x)
165
+ y = int(ev.y)
166
+
167
+ elif etype == EventType.MOUSEWHEEL:
168
+ wx = int(ev.wheel_x)
169
+ wy = int(ev.wheel_y)
170
+ wheel = (wx, wy) if (wx or wy) else None
171
+
172
+ elif etype == EventType.WINDOWRESIZED:
173
+ w = int(ev.width)
174
+ h = int(ev.height)
175
+ size = (w, h) if (w and h) else None
176
+
177
+ elif etype == EventType.TEXTINPUT:
178
+ t = getattr(ev, "text", "")
179
+ text = t if t else None
180
+
181
+ out.append(
182
+ Event(
183
+ type=etype,
184
+ key=key,
185
+ key_code=key_code,
186
+ scancode=scancode,
187
+ mod=mod,
188
+ repeat=repeat,
189
+ x=x,
190
+ y=y,
191
+ dx=dx,
192
+ dy=dy,
193
+ button=button,
194
+ wheel=wheel,
195
+ size=size,
196
+ text=text,
197
+ )
198
+ )
199
+ return out
200
+
201
+ # pylint: enable=too-many-locals
124
202
 
125
203
  def begin_frame(self):
126
204
  """Begin a new frame for rendering."""
@@ -18,18 +18,34 @@ def setup_fake_core_and_native(monkeypatch):
18
18
  class FakeBackend:
19
19
  """Minimal base class just to satisfy inheritance."""
20
20
 
21
- pass
22
-
23
21
  class FakeCoreEventType:
24
22
  UNKNOWN = "core_unknown"
25
23
  QUIT = "core_quit"
26
24
  KEYDOWN = "core_keydown"
27
25
  KEYUP = "core_keyup"
26
+ MOUSEMOTION = "core_mousemotion"
27
+ MOUSEBUTTONDOWN = "core_mousebuttondown"
28
+ MOUSEBUTTONUP = "core_mousebuttonup"
29
+ MOUSEWHEEL = "core_mousewheel"
30
+ WINDOWRESIZED = "core_windowresized"
31
+ TEXTINPUT = "core_textinput"
28
32
 
29
33
  @dataclass
30
34
  class FakeEvent:
31
35
  type: object
32
36
  key: object = None
37
+ key_code: object = None
38
+ x: object = None
39
+ y: object = None
40
+ dx: object = None
41
+ dy: object = None
42
+ button: object = None
43
+ wheel: object = None
44
+ size: object = None
45
+ text: object = None
46
+ scancode: object = None
47
+ mod: object = None
48
+ repeat: object = None
33
49
 
34
50
  fake_core.Backend = FakeBackend
35
51
  fake_core.Event = FakeEvent
@@ -37,6 +53,13 @@ def setup_fake_core_and_native(monkeypatch):
37
53
 
38
54
  sys.modules["mini_arcade_core"] = fake_core
39
55
 
56
+ fake_keymaps = types.ModuleType("mini_arcade_core.keymaps")
57
+ fake_sdl = types.ModuleType("mini_arcade_core.keymaps.sdl")
58
+ fake_sdl.SDL_KEYCODE_TO_KEY = {} # or mapping your test expects
59
+
60
+ sys.modules["mini_arcade_core.keymaps"] = fake_keymaps
61
+ sys.modules["mini_arcade_core.keymaps.sdl"] = fake_sdl
62
+
40
63
  # --- Fake native extension: mini_arcade_native_backend._native -------------
41
64
  fake_native = types.ModuleType("mini_arcade_native_backend._native")
42
65
 
@@ -45,6 +68,12 @@ def setup_fake_core_and_native(monkeypatch):
45
68
  Quit = "native_quit"
46
69
  KeyDown = "native_keydown"
47
70
  KeyUp = "native_keyup"
71
+ MouseMotion = "native_mousemotion"
72
+ MouseButtonDown = "native_mousebuttondown"
73
+ MouseButtonUp = "native_mousebuttonup"
74
+ MouseWheel = "native_mousewheel"
75
+ WindowResized = "native_windowresized"
76
+ TextInput = "native_textinput"
48
77
 
49
78
  class FakeEngine:
50
79
  def __init__(self):
@@ -226,36 +255,85 @@ def test_poll_events_maps_native_events_to_core_events_and_keys(
226
255
  backend_module,
227
256
  ):
228
257
  pkg, fake_core, fake_native = backend_module
229
-
230
258
  backend = pkg.NativeBackend()
231
259
 
232
- # Create fake native events
233
260
  @dataclass
234
261
  class FakeNativeEvent:
235
262
  type: object
236
263
  key: int = 0
264
+ key_code: int = 0
265
+ x: int = 0
266
+ y: int = 0
267
+ dx: int = 0
268
+ dy: int = 0
269
+ button: int = 0
270
+ wheel_x: int = 0
271
+ wheel_y: int = 0
272
+ width: int = 0
273
+ height: int = 0
274
+ text: str = ""
275
+ scancode: int = 0
276
+ mod: int = 0
277
+ repeat: int = 0
237
278
 
238
279
  engine = backend._engine
239
280
  engine._events_to_return = [
240
- FakeNativeEvent(fake_native.EventType.Quit, 0), # -> QUIT, key=None
281
+ FakeNativeEvent(fake_native.EventType.Quit), # -> QUIT
241
282
  FakeNativeEvent(
242
- fake_native.EventType.KeyDown, 32
283
+ fake_native.EventType.KeyDown, key=32
243
284
  ), # -> KEYDOWN, key=32
244
- FakeNativeEvent("something_unknown", 10), # -> UNKNOWN, key=10
285
+ FakeNativeEvent(
286
+ fake_native.EventType.MouseMotion, x=10, y=20, dx=1, dy=-2
287
+ ),
288
+ FakeNativeEvent(
289
+ fake_native.EventType.MouseButtonDown, x=5, y=6, button=1
290
+ ),
291
+ FakeNativeEvent(
292
+ fake_native.EventType.MouseWheel, wheel_x=0, wheel_y=-1
293
+ ),
294
+ FakeNativeEvent(
295
+ fake_native.EventType.WindowResized, width=800, height=600
296
+ ),
297
+ FakeNativeEvent(fake_native.EventType.TextInput, text="á"),
298
+ FakeNativeEvent("something_unknown", key=10), # -> UNKNOWN, key=10
245
299
  ]
246
300
 
247
301
  events = backend.poll_events()
302
+ assert len(events) == 8
248
303
 
249
- assert len(events) == 3
250
-
251
- # 1) Quit event, key==0 -> key should become None
304
+ # Quit: key 0 -> None
252
305
  assert events[0].type == fake_core.EventType.QUIT
253
306
  assert events[0].key is None
254
307
 
255
- # 2) KeyDown, key!=0 passes through
308
+ # KeyDown: key passes through
256
309
  assert events[1].type == fake_core.EventType.KEYDOWN
257
- assert events[1].key == 32
258
-
259
- # 3) Unknown type -> UNKNOWN
260
- assert events[2].type == fake_core.EventType.UNKNOWN
261
- assert events[2].key == 10
310
+ assert events[1].key_code == 32
311
+
312
+ # MouseMotion: x/y/dx/dy mapped (0 becomes None; here non-zero)
313
+ assert events[2].type == fake_core.EventType.MOUSEMOTION
314
+ assert events[2].x == 10
315
+ assert events[2].y == 20
316
+ assert events[2].dx == 1
317
+ assert events[2].dy == -2
318
+
319
+ # MouseButtonDown
320
+ assert events[3].type == fake_core.EventType.MOUSEBUTTONDOWN
321
+ assert events[3].x == 5
322
+ assert events[3].y == 6
323
+ assert events[3].button == 1
324
+
325
+ # MouseWheel -> wheel tuple
326
+ assert events[4].type == fake_core.EventType.MOUSEWHEEL
327
+ assert events[4].wheel == (0, -1)
328
+
329
+ # WindowResized -> size tuple
330
+ assert events[5].type == fake_core.EventType.WINDOWRESIZED
331
+ assert events[5].size == (800, 600)
332
+
333
+ # TextInput -> text
334
+ assert events[6].type == fake_core.EventType.TEXTINPUT
335
+ assert events[6].text == "á"
336
+
337
+ # Unknown
338
+ assert events[7].type == fake_core.EventType.UNKNOWN
339
+ assert events[7].key_code is None