reflexion 0.6.0 → 0.7.0

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 (275) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/application.cpp +37 -6
  3. data/.doc/ext/reflex/capture_event.cpp +1 -1
  4. data/.doc/ext/reflex/chase_constraint.cpp +1 -1
  5. data/.doc/ext/reflex/clipboard.cpp +1 -1
  6. data/.doc/ext/reflex/color_event.cpp +76 -0
  7. data/.doc/ext/reflex/color_picker.cpp +113 -0
  8. data/.doc/ext/reflex/constraint.cpp +1 -1
  9. data/.doc/ext/reflex/contact_event.cpp +1 -1
  10. data/.doc/ext/reflex/control_change_event.cpp +1 -1
  11. data/.doc/ext/reflex/device.cpp +1 -1
  12. data/.doc/ext/reflex/device_event.cpp +1 -1
  13. data/.doc/ext/reflex/draw_event.cpp +1 -1
  14. data/.doc/ext/reflex/ellipse_shape.cpp +1 -1
  15. data/.doc/ext/reflex/event.cpp +1 -1
  16. data/.doc/ext/reflex/file_dialog.cpp +181 -0
  17. data/.doc/ext/reflex/file_event.cpp +103 -0
  18. data/.doc/ext/reflex/filter.cpp +1 -1
  19. data/.doc/ext/reflex/focus_event.cpp +1 -1
  20. data/.doc/ext/reflex/frame_event.cpp +1 -1
  21. data/.doc/ext/reflex/gamepad.cpp +48 -0
  22. data/.doc/ext/reflex/image_view.cpp +1 -1
  23. data/.doc/ext/reflex/key_event.cpp +1 -274
  24. data/.doc/ext/reflex/line_shape.cpp +1 -1
  25. data/.doc/ext/reflex/link_constraint.cpp +1 -1
  26. data/.doc/ext/reflex/menu.cpp +6 -5
  27. data/.doc/ext/reflex/midi.cpp +9 -2
  28. data/.doc/ext/reflex/midi_event.cpp +1 -1
  29. data/.doc/ext/reflex/motion_event.cpp +1 -1
  30. data/.doc/ext/reflex/native.cpp +18 -6
  31. data/.doc/ext/reflex/note_event.cpp +1 -1
  32. data/.doc/ext/reflex/pin.cpp +1 -1
  33. data/.doc/ext/reflex/pointer.cpp +1 -1
  34. data/.doc/ext/reflex/pointer_event.cpp +2 -2
  35. data/.doc/ext/reflex/polygon_shape.cpp +1 -1
  36. data/.doc/ext/reflex/rect_shape.cpp +1 -1
  37. data/.doc/ext/reflex/reflex.cpp +566 -232
  38. data/.doc/ext/reflex/screen.cpp +27 -1
  39. data/.doc/ext/reflex/scroll_event.cpp +1 -1
  40. data/.doc/ext/reflex/selector.cpp +1 -1
  41. data/.doc/ext/reflex/shape.cpp +1 -1
  42. data/.doc/ext/reflex/snap_constraint.cpp +1 -1
  43. data/.doc/ext/reflex/style.cpp +1 -1
  44. data/.doc/ext/reflex/style_length.cpp +1 -1
  45. data/.doc/ext/reflex/text_event.cpp +104 -0
  46. data/.doc/ext/reflex/timer.cpp +1 -1
  47. data/.doc/ext/reflex/timer_event.cpp +1 -1
  48. data/.doc/ext/reflex/update_event.cpp +1 -1
  49. data/.doc/ext/reflex/view.cpp +110 -56
  50. data/.doc/ext/reflex/wheel_constraint.cpp +1 -1
  51. data/.doc/ext/reflex/wheel_event.cpp +1 -1
  52. data/.doc/ext/reflex/window.cpp +226 -17
  53. data/.github/workflows/release-gem.yml +2 -49
  54. data/.github/workflows/tag.yml +5 -28
  55. data/.github/workflows/test.yml +1 -37
  56. data/ChangeLog.md +54 -0
  57. data/Gemfile.lock +13 -8
  58. data/Rakefile +13 -2
  59. data/Reflex.podspec +2 -2
  60. data/VERSION +1 -1
  61. data/ext/reflex/application.cpp +41 -6
  62. data/ext/reflex/capture_event.cpp +1 -1
  63. data/ext/reflex/chase_constraint.cpp +1 -1
  64. data/ext/reflex/clipboard.cpp +1 -1
  65. data/ext/reflex/color_event.cpp +80 -0
  66. data/ext/reflex/color_picker.cpp +121 -0
  67. data/ext/reflex/constraint.cpp +1 -1
  68. data/ext/reflex/contact_event.cpp +1 -1
  69. data/ext/reflex/control_change_event.cpp +1 -1
  70. data/ext/reflex/device.cpp +1 -1
  71. data/ext/reflex/device_event.cpp +1 -1
  72. data/ext/reflex/draw_event.cpp +1 -1
  73. data/ext/reflex/ellipse_shape.cpp +1 -1
  74. data/ext/reflex/event.cpp +1 -1
  75. data/ext/reflex/extconf.rb +4 -2
  76. data/ext/reflex/file_dialog.cpp +194 -0
  77. data/ext/reflex/file_event.cpp +108 -0
  78. data/ext/reflex/filter.cpp +1 -1
  79. data/ext/reflex/focus_event.cpp +1 -1
  80. data/ext/reflex/frame_event.cpp +1 -1
  81. data/ext/reflex/gamepad.cpp +50 -0
  82. data/ext/reflex/image_view.cpp +1 -1
  83. data/ext/reflex/key_event.cpp +1 -275
  84. data/ext/reflex/line_shape.cpp +1 -1
  85. data/ext/reflex/link_constraint.cpp +1 -1
  86. data/ext/reflex/menu.cpp +8 -7
  87. data/ext/reflex/midi.cpp +11 -3
  88. data/ext/reflex/midi_event.cpp +1 -1
  89. data/ext/reflex/motion_event.cpp +1 -1
  90. data/ext/reflex/native.cpp +18 -6
  91. data/ext/reflex/note_event.cpp +1 -1
  92. data/ext/reflex/pin.cpp +1 -1
  93. data/ext/reflex/pointer.cpp +1 -1
  94. data/ext/reflex/pointer_event.cpp +2 -2
  95. data/ext/reflex/polygon_shape.cpp +1 -1
  96. data/ext/reflex/rect_shape.cpp +1 -1
  97. data/ext/reflex/reflex.cpp +568 -232
  98. data/ext/reflex/screen.cpp +31 -2
  99. data/ext/reflex/scroll_event.cpp +1 -1
  100. data/ext/reflex/selector.cpp +1 -1
  101. data/ext/reflex/selector.h +9 -9
  102. data/ext/reflex/shape.cpp +1 -1
  103. data/ext/reflex/snap_constraint.cpp +1 -1
  104. data/ext/reflex/style.cpp +1 -1
  105. data/ext/reflex/style_length.cpp +1 -1
  106. data/ext/reflex/text_event.cpp +111 -0
  107. data/ext/reflex/timer.cpp +1 -1
  108. data/ext/reflex/timer_event.cpp +1 -1
  109. data/ext/reflex/update_event.cpp +1 -1
  110. data/ext/reflex/view.cpp +121 -61
  111. data/ext/reflex/wheel_constraint.cpp +1 -1
  112. data/ext/reflex/wheel_event.cpp +1 -1
  113. data/ext/reflex/window.cpp +256 -25
  114. data/include/reflex/application.h +10 -0
  115. data/include/reflex/color_picker.h +65 -0
  116. data/include/reflex/event.h +178 -88
  117. data/include/reflex/file_dialog.h +73 -0
  118. data/include/reflex/gamepad.h +3 -0
  119. data/include/reflex/menu.h +3 -3
  120. data/include/reflex/midi.h +3 -0
  121. data/include/reflex/reflex.h +2 -0
  122. data/include/reflex/ruby/application.h +6 -1
  123. data/include/reflex/ruby/color_picker.h +89 -0
  124. data/include/reflex/ruby/event.h +62 -29
  125. data/include/reflex/ruby/file_dialog.h +89 -0
  126. data/include/reflex/ruby/gamepad.h +46 -0
  127. data/include/reflex/ruby/reflex.h +3 -0
  128. data/include/reflex/ruby/view.h +92 -44
  129. data/include/reflex/ruby/window.h +60 -1
  130. data/include/reflex/ruby.h +3 -0
  131. data/include/reflex/screen.h +11 -2
  132. data/include/reflex/view.h +28 -16
  133. data/include/reflex/window.h +40 -8
  134. data/include/reflex.h +3 -0
  135. data/lib/reflex/application.rb +5 -5
  136. data/lib/reflex/autoinit.rb +3 -1
  137. data/lib/reflex/button.rb +3 -3
  138. data/lib/reflex/color_event.rb +16 -0
  139. data/lib/reflex/color_picker.rb +45 -0
  140. data/lib/reflex/control_change_event.rb +17 -0
  141. data/lib/reflex/file_dialog.rb +70 -0
  142. data/lib/reflex/file_event.rb +37 -0
  143. data/lib/reflex/helper.rb +58 -7
  144. data/lib/reflex/key_event.rb +9 -4
  145. data/lib/reflex/menu.rb +17 -1
  146. data/lib/reflex/model.rb +19 -19
  147. data/lib/reflex/note_event.rb +1 -1
  148. data/lib/reflex/pointer.rb +14 -3
  149. data/lib/reflex/pointer_event.rb +12 -1
  150. data/lib/reflex/reflex.rb +5 -0
  151. data/lib/reflex/shape.rb +14 -14
  152. data/lib/reflex/style.rb +16 -16
  153. data/lib/reflex/text_event.rb +40 -0
  154. data/lib/reflex/timer.rb +3 -3
  155. data/lib/reflex/view.rb +29 -14
  156. data/lib/reflex/wheel_event.rb +12 -3
  157. data/lib/reflex/window.rb +25 -13
  158. data/lib/reflex.rb +8 -2
  159. data/reflex.gemspec +4 -4
  160. data/samples/ime.rb +100 -0
  161. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +236 -224
  162. data/samples/menu.rb +4 -1
  163. data/samples/model.rb +3 -3
  164. data/samples/test/alert.rb +93 -0
  165. data/samples/test/always_on.rb +76 -0
  166. data/samples/test/app_background.rb +51 -0
  167. data/samples/test/boundary.rb +75 -0
  168. data/samples/test/callback_exception.rb +101 -0
  169. data/samples/test/cancel.rb +53 -0
  170. data/samples/test/color_picker.rb +63 -0
  171. data/samples/test/file_dialog.rb +102 -0
  172. data/samples/window_style.rb +156 -0
  173. data/src/application.cpp +159 -18
  174. data/src/application.h +92 -7
  175. data/src/color_picker.cpp +113 -0
  176. data/src/color_picker.h +36 -0
  177. data/src/event.cpp +410 -252
  178. data/src/event.h +12 -0
  179. data/src/file_dialog.cpp +163 -0
  180. data/src/file_dialog.h +52 -0
  181. data/src/gamepad.cpp +42 -5
  182. data/src/gamepad.h +4 -0
  183. data/src/ios/app_delegate.mm +5 -3
  184. data/src/ios/application.mm +24 -0
  185. data/src/ios/color_picker.mm +19 -0
  186. data/src/ios/file_dialog.mm +21 -0
  187. data/src/ios/gamepad.mm +4 -4
  188. data/src/ios/menu.mm +5 -0
  189. data/src/ios/reflex.mm +8 -0
  190. data/src/ios/screen.mm +26 -0
  191. data/src/ios/view_controller.mm +2 -30
  192. data/src/ios/window.mm +38 -9
  193. data/src/menu.cpp +66 -4
  194. data/src/menu.h +17 -1
  195. data/src/midi.cpp +61 -31
  196. data/src/osx/app_delegate.h +4 -0
  197. data/src/osx/app_delegate.mm +102 -22
  198. data/src/osx/application.mm +88 -6
  199. data/src/osx/color_picker.mm +112 -0
  200. data/src/osx/event.h +10 -0
  201. data/src/osx/event.mm +84 -30
  202. data/src/osx/file_dialog.mm +168 -0
  203. data/src/osx/gamepad.mm +2 -2
  204. data/src/osx/gamepad_hid.mm +1 -1
  205. data/src/osx/menu.mm +177 -33
  206. data/src/osx/native_window.h +16 -2
  207. data/src/osx/native_window.mm +114 -57
  208. data/src/osx/opengl_view.h +2 -1
  209. data/src/osx/opengl_view.mm +184 -43
  210. data/src/osx/reflex.mm +38 -0
  211. data/src/osx/screen.mm +36 -0
  212. data/src/osx/window.mm +106 -24
  213. data/src/pointer.cpp +13 -4
  214. data/src/pointer.h +4 -0
  215. data/src/rays.h +46 -0
  216. data/src/sdl/application.cpp +68 -8
  217. data/src/sdl/color_picker.cpp +18 -0
  218. data/src/sdl/event.cpp +24 -3
  219. data/src/sdl/event.h +12 -0
  220. data/src/sdl/file_dialog.cpp +20 -0
  221. data/src/sdl/gamepad.cpp +3 -7
  222. data/src/sdl/menu.cpp +5 -0
  223. data/src/sdl/reflex.cpp +20 -0
  224. data/src/sdl/screen.cpp +36 -0
  225. data/src/sdl/window.cpp +142 -29
  226. data/src/shape.cpp +15 -10
  227. data/src/view.cpp +287 -198
  228. data/src/view.h +4 -2
  229. data/src/vk.h +416 -0
  230. data/src/win32/application.cpp +162 -12
  231. data/src/win32/application.h +20 -0
  232. data/src/win32/color_picker.cpp +82 -0
  233. data/src/win32/event.cpp +114 -12
  234. data/src/win32/event.h +21 -4
  235. data/src/win32/file_dialog.cpp +226 -0
  236. data/src/win32/gamepad.cpp +9 -2
  237. data/src/win32/menu.cpp +191 -53
  238. data/src/win32/menu.h +9 -1
  239. data/src/win32/opengl.cpp +2 -9
  240. data/src/win32/reflex.cpp +44 -3
  241. data/src/win32/screen.cpp +164 -3
  242. data/src/win32/screen.h +8 -0
  243. data/src/win32/tray.cpp +191 -0
  244. data/src/win32/tray.h +22 -0
  245. data/src/win32/vk.cpp +11 -0
  246. data/src/win32/window.cpp +809 -148
  247. data/src/win32/window.h +6 -0
  248. data/src/window.cpp +718 -185
  249. data/src/window.h +66 -33
  250. data/src/world.cpp +9 -1
  251. data/test/helper.rb +17 -0
  252. data/test/test_application.rb +90 -1
  253. data/test/test_chase_constraint.rb +1 -3
  254. data/test/test_color_event.rb +36 -0
  255. data/test/test_color_picker.rb +62 -0
  256. data/test/test_constraint.rb +2 -4
  257. data/test/test_event.rb +1 -1
  258. data/test/test_file_dialog.rb +48 -0
  259. data/test/test_file_event.rb +43 -0
  260. data/test/test_has_text_preedit.rb +54 -0
  261. data/test/test_key_event.rb +20 -5
  262. data/test/test_link_constraint.rb +1 -3
  263. data/test/test_menu.rb +40 -10
  264. data/test/test_pointer.rb +33 -23
  265. data/test/test_pointer_event.rb +24 -9
  266. data/test/test_reflex.rb +36 -0
  267. data/test/test_screen.rb +24 -2
  268. data/test/test_snap_constraint.rb +1 -3
  269. data/test/test_text_event.rb +54 -0
  270. data/test/test_view.rb +41 -4
  271. data/test/test_wheel_constraint.rb +1 -3
  272. data/test/test_wheel_event.rb +13 -5
  273. data/test/test_window.rb +196 -44
  274. metadata +80 -10
  275. data/.github/workflows/utils.rb +0 -127
data/src/pointer.h CHANGED
@@ -16,8 +16,12 @@ namespace Reflex
16
16
 
17
17
  void Pointer_set_id (Pointer* it, Pointer::ID id);
18
18
 
19
+ void Pointer_set_types (Pointer* it, uint types);
20
+
19
21
  void Pointer_set_action (Pointer* it, Pointer::Action action);
20
22
 
23
+ void Pointer_set_time (Pointer* it, double time);
24
+
21
25
  void Pointer_set_floatable (Pointer* it, bool floatable);
22
26
 
23
27
  bool Pointer_is_floatable (const Pointer& it);
data/src/rays.h ADDED
@@ -0,0 +1,46 @@
1
+ // -*- c++ -*-
2
+ #pragma once
3
+ #ifndef __REFLEX_SRC_RAYS_H__
4
+ #define __REFLEX_SRC_RAYS_H__
5
+
6
+
7
+ #include <rays/color.h>
8
+ #include <rays/bitmap.h>
9
+ #include <rays/painter.h>
10
+
11
+ #if defined(OSX) && defined(__OBJC__)
12
+ @class NSImage;
13
+ #elif defined(WIN32)
14
+ #include <xot/windows.h>
15
+ #endif
16
+
17
+
18
+ namespace Rays
19
+ {
20
+
21
+
22
+ bool Painter_get_pixel (Color* color, Painter* painter, coord x, coord y);
23
+
24
+
25
+ #if defined(OSX) && defined(__OBJC__)
26
+
27
+ NSImage* Bitmap_get_nsimage (const Bitmap& bitmap);
28
+
29
+ #endif
30
+
31
+
32
+ #ifdef WIN32
33
+
34
+ void Rays_set_pre_init_fun (void (*)());
35
+
36
+ HBITMAP Bitmap_get_hbitmap (const Bitmap& bitmap);
37
+
38
+ const PIXELFORMATDESCRIPTOR* OpenGL_get_pixel_format_descriptor ();
39
+
40
+ #endif
41
+
42
+
43
+ }// Rays
44
+
45
+
46
+ #endif//EOH
@@ -5,6 +5,11 @@
5
5
  #ifdef WASM
6
6
  #include <emscripten.h>
7
7
  #endif
8
+ #ifdef LINUX
9
+ #include <limits.h>
10
+ #include <string.h>
11
+ #include <unistd.h>
12
+ #endif
8
13
  #include <xot/time.h>
9
14
  #include "reflex/exception.h"
10
15
  #include "reflex/debug.h"
@@ -41,11 +46,43 @@ namespace Reflex
41
46
  return new ApplicationData();
42
47
  }
43
48
 
49
+ String
50
+ Application_get_default_name ()
51
+ {
52
+ #ifdef LINUX
53
+ char path[PATH_MAX];
54
+ ssize_t len = readlink("/proc/self/exe", path, sizeof(path) - 1);
55
+ if (len > 0)
56
+ {
57
+ path[len] = '\0';
58
+ char* slash = strrchr(path, '/');
59
+ return slash ? slash + 1 : path;
60
+ }
61
+ #endif
62
+ return "";
63
+ }
64
+
65
+ void
66
+ Application_stop (Application* app)
67
+ {
68
+ get_data(app)->quit = true;
69
+ }
70
+
44
71
  void
45
72
  Application_set_menu (Application* app, Menu* menu)
46
73
  {
47
74
  }
48
75
 
76
+ void
77
+ Application_set_background (Application* app, bool state)
78
+ {
79
+ }
80
+
81
+ void
82
+ Application_set_background_menu (Application* app, Menu* menu)
83
+ {
84
+ }
85
+
49
86
 
50
87
  static bool
51
88
  dispatch_window_event (const SDL_Event& event)
@@ -65,11 +102,18 @@ namespace Reflex
65
102
  SDL_Event event;
66
103
  while (SDL_PollEvent(&event))
67
104
  {
68
- if (dispatch_window_event(event))
69
- continue;
105
+ bool dispatched = dispatch_window_event(event);
106
+
107
+ #if SDL_VERSION_ATLEAST(2, 0, 22)
108
+ // the text of an extended composition event is handed over to
109
+ // whoever takes the event, so it is freed here rather than in the
110
+ // window that may or may not have been found for it
111
+ if (event.type == SDL_TEXTEDITING_EXT)
112
+ SDL_free(event.editExt.text);
113
+ #endif
70
114
 
71
- if (event.type == SDL_QUIT)
72
- app->quit();
115
+ if (!dispatched && event.type == SDL_QUIT)
116
+ Application_call_quit(app);
73
117
  }
74
118
  }
75
119
 
@@ -115,7 +159,10 @@ namespace Reflex
115
159
  dispatch_events(app);
116
160
 
117
161
  if (get_data(app)->quit)
162
+ {
118
163
  emscripten_cancel_main_loop();
164
+ Application_cleanup(app);
165
+ }
119
166
  else
120
167
  update_all_windows(app);
121
168
  }
@@ -124,13 +171,26 @@ namespace Reflex
124
171
  void
125
172
  Application::start ()
126
173
  {
174
+ get_data(this)->quit = false;
175
+ self->started = false;
176
+ self->quitting = false;
177
+ self->running = true;
178
+
127
179
  Event e;
128
- Application_call_start(this, &e);
180
+ Application_call_start_event(this, &e);
129
181
 
130
182
  #ifdef WASM
131
183
  emscripten_set_main_loop_arg(emscripten_main_loop, this, 0, true);
132
184
  #else
133
- main_loop(this);
185
+ // guarded here too, since rays can throw while drawing
186
+ Application_guard([&]()
187
+ {
188
+ main_loop(this);
189
+ });
190
+ self->running = false;
191
+
192
+ Application_cleanup(this);
193
+ Application_throw_exception(this);
134
194
  #endif
135
195
  }
136
196
 
@@ -138,10 +198,10 @@ namespace Reflex
138
198
  Application::quit ()
139
199
  {
140
200
  Event e;
141
- Application_call_quit(this, &e);
201
+ Application_call_quit_event(this, &e);
142
202
  if (e.is_blocked()) return;
143
203
 
144
- get_data(this)->quit = true;
204
+ Application_stop(this);
145
205
  }
146
206
 
147
207
  void
@@ -0,0 +1,18 @@
1
+ #include "../color_picker.h"
2
+
3
+
4
+ #include "reflex/exception.h"
5
+
6
+
7
+ namespace Reflex
8
+ {
9
+
10
+
11
+ void
12
+ ColorPicker_show (ColorPicker* picker, const Color* initial)
13
+ {
14
+ not_implemented_error(__FILE__, __LINE__);
15
+ }
16
+
17
+
18
+ }// Reflex
data/src/sdl/event.cpp CHANGED
@@ -70,6 +70,21 @@ namespace Reflex
70
70
  }
71
71
 
72
72
 
73
+ NativeTextEvent::NativeTextEvent (
74
+ const char* text, int selection_offset, int selection_size)
75
+ : TextEvent(
76
+ PREEDIT, text, selection_offset,
77
+ // a size below zero is how sdl says nothing is selected
78
+ selection_size < 0 ? 0 : selection_size)
79
+ {
80
+ }
81
+
82
+ NativeTextEvent::NativeTextEvent (const SDL_TextInputEvent& e)
83
+ : TextEvent(COMMIT, e.text)
84
+ {
85
+ }
86
+
87
+
73
88
  static uint
74
89
  get_pointer_type (Uint8 button)
75
90
  {
@@ -175,13 +190,19 @@ namespace Reflex
175
190
  }
176
191
 
177
192
 
193
+ static coord
194
+ to_wheel_pixels (const SDL_MouseWheelEvent& e, float delta)
195
+ {
196
+ float scale = WHEEL_PIXELS_PER_NOTCH;
197
+ if (e.direction == SDL_MOUSEWHEEL_FLIPPED) scale = -scale;
198
+ return delta * scale;
199
+ }
200
+
178
201
  NativeWheelEvent::NativeWheelEvent (
179
202
  const SDL_MouseWheelEvent& e, SDL_Window* window)
180
203
  : WheelEvent(
181
204
  0, 0, 0,
182
- e.direction == SDL_MOUSEWHEEL_FLIPPED ? -e.preciseX : e.preciseX,
183
- e.direction == SDL_MOUSEWHEEL_FLIPPED ? -e.preciseY : e.preciseY,
184
- 0,
205
+ to_wheel_pixels(e, e.preciseX), to_wheel_pixels(e, -e.preciseY), 0,
185
206
  get_modifiers(SDL_GetModState()))
186
207
  {
187
208
  int mx, my;
data/src/sdl/event.h CHANGED
@@ -22,6 +22,18 @@ namespace Reflex
22
22
  };// NativeKeyEvent
23
23
 
24
24
 
25
+ class NativeTextEvent : public TextEvent
26
+ {
27
+
28
+ public:
29
+
30
+ NativeTextEvent (const char* text, int selection_offset, int selection_size);
31
+
32
+ NativeTextEvent (const SDL_TextInputEvent& event);
33
+
34
+ };// NativeTextEvent
35
+
36
+
25
37
  class NativePointerEvent : public PointerEvent
26
38
  {
27
39
 
@@ -0,0 +1,20 @@
1
+ #include "../file_dialog.h"
2
+
3
+
4
+ #include "reflex/exception.h"
5
+
6
+
7
+ namespace Reflex
8
+ {
9
+
10
+
11
+ void
12
+ FileDialog_show (
13
+ FileDialog* dialog, FileDialog::Data::Mode mode,
14
+ const char* dir, const char* name)
15
+ {
16
+ not_implemented_error(__FILE__, __LINE__);
17
+ }
18
+
19
+
20
+ }// Reflex
data/src/sdl/gamepad.cpp CHANGED
@@ -9,17 +9,13 @@ namespace Reflex
9
9
 
10
10
 
11
11
  void
12
- Gamepad_init (Application* app)
12
+ Gamepad_init_native (Application* app)
13
13
  {
14
+ not_implemented_error(__FILE__, __LINE__);
14
15
  }
15
16
 
16
17
  void
17
- Gamepad_fin (Application* app)
18
- {
19
- }
20
-
21
- void
22
- Gamepad_poll ()
18
+ Gamepad_fin_native (Application* app)
23
19
  {
24
20
  }
25
21
 
data/src/sdl/menu.cpp CHANGED
@@ -11,6 +11,11 @@ namespace Reflex
11
11
  return new Menu::Data();
12
12
  }
13
13
 
14
+ void
15
+ Menu_validate_shortcut_modifiers (uint modifiers)
16
+ {
17
+ }
18
+
14
19
  void
15
20
  Menu_update (Menu* menu)
16
21
  {
data/src/sdl/reflex.cpp CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include <SDL.h>
5
5
  #include "reflex/exception.h"
6
+ #include "../vk.h"
6
7
 
7
8
 
8
9
  namespace Reflex
@@ -23,6 +24,13 @@ namespace Reflex
23
24
  if (global::initialized)
24
25
  reflex_error(__FILE__, __LINE__, "already initialized.");
25
26
 
27
+ #if SDL_VERSION_ATLEAST(2, 0, 22)
28
+ // without this, sdl cuts a composition longer than 32 bytes into
29
+ // pieces and reuses the offset field to say where each piece goes,
30
+ // which leaves no way to tell a composition from its selection
31
+ SDL_SetHint(SDL_HINT_IME_SUPPORT_EXTENDED_TEXT, "1");
32
+ #endif
33
+
26
34
  global::initialized = true;
27
35
  }
28
36
 
@@ -35,5 +43,17 @@ namespace Reflex
35
43
  global::initialized = false;
36
44
  }
37
45
 
46
+ void
47
+ alert (const char* message, const char* title)
48
+ {
49
+ if (!message)
50
+ argument_error(__FILE__, __LINE__);
51
+
52
+ int ret = SDL_ShowSimpleMessageBox(
53
+ SDL_MESSAGEBOX_INFORMATION, title ? title : "", message, NULL);
54
+ if (ret < 0)
55
+ reflex_error(__FILE__, __LINE__, SDL_GetError());
56
+ }
57
+
38
58
 
39
59
  }// Reflex
data/src/sdl/screen.cpp CHANGED
@@ -35,6 +35,16 @@ namespace Reflex
35
35
  {
36
36
  }
37
37
 
38
+ String
39
+ Screen::name () const
40
+ {
41
+ if (!*this)
42
+ invalid_state_error(__FILE__, __LINE__);
43
+
44
+ const char* name = SDL_GetDisplayName(self->display_index);
45
+ return name ? name : "";
46
+ }
47
+
38
48
  Bounds
39
49
  Screen::frame () const
40
50
  {
@@ -48,6 +58,15 @@ namespace Reflex
48
58
  return Bounds(rect.x, rect.y, rect.w, rect.h);
49
59
  }
50
60
 
61
+ float
62
+ Screen::pixel_density () const
63
+ {
64
+ if (!*this)
65
+ invalid_state_error(__FILE__, __LINE__);
66
+
67
+ return 1;
68
+ }
69
+
51
70
  Screen::operator bool () const
52
71
  {
53
72
  return self->display_index >= 0;
@@ -59,5 +78,22 @@ namespace Reflex
59
78
  return !operator bool();
60
79
  }
61
80
 
81
+ Screen::List
82
+ Screen::all ()
83
+ {
84
+ int count = SDL_GetNumVideoDisplays();
85
+ if (count < 0)
86
+ reflex_error(__FILE__, __LINE__, SDL_GetError());
87
+
88
+ List list;
89
+ for (int i = 0; i < count; ++i)
90
+ {
91
+ Screen s;
92
+ Screen_initialize(&s, i);
93
+ list.emplace_back(s);
94
+ }
95
+ return list;
96
+ }
97
+
62
98
 
63
99
  }// Reflex
data/src/sdl/window.cpp CHANGED
@@ -24,6 +24,10 @@ namespace Reflex
24
24
 
25
25
  bool need_rebind = false;
26
26
 
27
+ // whether the input method is composing, which is what tells the text
28
+ // it commits apart from the text a key produces on its own
29
+ bool composing = false;
30
+
27
31
  OpenGLContext context;
28
32
 
29
33
  mutable String title_tmp;
@@ -87,13 +91,16 @@ namespace Reflex
87
91
  if (win) win->release();
88
92
 
89
93
  if (Window_all().empty())
90
- Reflex::app()->quit();
94
+ Reflex::Application_call_quit(Reflex::app());
91
95
  }
92
96
 
93
97
  Uint32 to_sdl_flags (uint flags)
94
98
  {
95
99
  Uint32 sdl_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI;
96
100
 
101
+ if (!Xot::has_flag(flags, Window::FLAG_TITLEBAR_BACKGROUND))
102
+ sdl_flags |= SDL_WINDOW_BORDERLESS;
103
+
97
104
  if (Xot::has_flag(flags, Window::FLAG_RESIZABLE))
98
105
  sdl_flags |= SDL_WINDOW_RESIZABLE;
99
106
 
@@ -157,32 +164,60 @@ namespace Reflex
157
164
  Window_call_draw_event(win, &e);
158
165
  }
159
166
 
167
+ static bool
168
+ accepts_text_input (Window* win)
169
+ {
170
+ const View* focus = win->focus();
171
+ return focus && focus->accepts_text_input();
172
+ }
173
+
160
174
  static void
161
- frame_changed (Window* win)
175
+ update_text_input_rect (Window* win)
162
176
  {
163
- Rays::Bounds b = win->frame();
164
- Rays::Point dpos = b.position() - win->self->prev_position;
165
- Rays::Point dsize = b.size() - win->self->prev_size;
166
- win->self->prev_position = b.position();
167
- win->self->prev_size = b.size();
177
+ const View* focus = win->focus();
178
+ if (!focus) return;
168
179
 
169
- if (dpos == 0 && dsize == 0) return;
180
+ Bounds b = focus->text_input_bounds();
181
+ Point p1 = focus->to_window(b.position());
182
+ Point p2 = focus->to_window(b.position() + b.size());
170
183
 
171
- Reflex::FrameEvent e(b, dpos.x, dpos.y, 0, dsize.x, dsize.y, 0);
172
- if (dpos != 0) win->on_move(&e);
173
- if (dsize != 0)
174
- {
175
- Rays::Bounds b = win->frame();
176
- b.move_to(0, 0);
184
+ SDL_Rect rect = {(int) p1.x, (int) p1.y, (int) (p2.x - p1.x), (int) (p2.y - p1.y)};
185
+ SDL_SetTextInputRect(&rect);
186
+ }
177
187
 
178
- if (win->painter())
179
- win->painter()->canvas(b, win->painter()->pixel_density());
188
+ static void
189
+ preedit (Window* win, const char* text, int offset, int size)
190
+ {
191
+ WindowData* self = get_data(win);
180
192
 
181
- if (win->root())
182
- View_set_frame(win->root(), b);
193
+ // the input method reports an empty composition before anything is typed
194
+ bool empty = !text || *text == '\0';
195
+ if (empty && !self->composing)
196
+ return;
183
197
 
184
- win->on_resize(&e);
185
- }
198
+ self->composing = !empty;
199
+
200
+ if (!accepts_text_input(win))
201
+ return;
202
+
203
+ NativeTextEvent e(text ? text : "", offset, size);
204
+ Window_call_text_event(win, &e);
205
+
206
+ update_text_input_rect(win);
207
+ }
208
+
209
+ static void
210
+ commit (Window* win, const SDL_TextInputEvent& event)
211
+ {
212
+ WindowData* self = get_data(win);
213
+
214
+ bool composed = self->composing;
215
+
216
+ if (!accepts_text_input(win))
217
+ return;
218
+
219
+ NativeTextEvent e(event);
220
+ Window_call_text_event(win, &e, composed);
186
221
  }
187
222
 
188
223
 
@@ -196,9 +231,12 @@ namespace Reflex
196
231
  Window_default_flags ()
197
232
  {
198
233
  return
199
- Window::FLAG_CLOSABLE |
200
- Window::FLAG_RESIZABLE |
201
- Window::FLAG_MINIMIZABLE;
234
+ Window::FLAG_CLOSABLE |
235
+ Window::FLAG_MINIMIZABLE |
236
+ Window::FLAG_RESIZABLE |
237
+ Window::FLAG_TITLEBAR_BUTTONS |
238
+ Window::FLAG_TITLEBAR_BACKGROUND |
239
+ Window::FLAG_SHADOW;
202
240
  }
203
241
 
204
242
  void
@@ -311,13 +349,48 @@ namespace Reflex
311
349
  if (!*win)
312
350
  invalid_state_error(__FILE__, __LINE__);
313
351
 
352
+ bool buttons = Xot::has_flag(flags, Window::FLAG_TITLEBAR_BUTTONS);
353
+ bool background = Xot::has_flag(flags, Window::FLAG_TITLEBAR_BACKGROUND);
354
+ if (buttons != background)
355
+ {
356
+ argument_error(
357
+ __FILE__, __LINE__,
358
+ "FLAG_TITLEBAR_BUTTONS and FLAG_TITLEBAR_BACKGROUND must match");
359
+ }
360
+
361
+ if (Xot::has_flag(flags, Window::FLAG_UNLISTED))
362
+ not_implemented_error(__FILE__, __LINE__, "FLAG_UNLISTED");
363
+
364
+ if (!Xot::has_flag(flags, Window::FLAG_SHADOW))
365
+ not_implemented_error(__FILE__, __LINE__, "missing FLAG_SHADOW");
366
+
367
+ if (Xot::has_flag(flags, Window::FLAG_TRANSPARENT))
368
+ not_implemented_error(__FILE__, __LINE__, "FLAG_TRANSPARENT");
369
+
370
+ if (Xot::has_flag(flags, Window::FLAG_ALWAYS_ON_BOTTOM))
371
+ not_implemented_error(__FILE__, __LINE__, "FLAG_ALWAYS_ON_BOTTOM");
372
+
373
+ if (Xot::has_flag(flags, Window::FLAG_POINTER_THROUGH))
374
+ not_implemented_error(__FILE__, __LINE__, "FLAG_POINTER_THROUGH");
375
+
314
376
  WindowData* self = get_data(win);
315
377
  Uint32 sdl_flags = self->to_sdl_flags(flags);
316
378
 
379
+ #if SDL_VERSION_ATLEAST(2, 0, 16)
380
+ SDL_SetWindowAlwaysOnTop(
381
+ self->native,
382
+ Xot::has_flag(flags, Window::FLAG_ALWAYS_ON_TOP) ? SDL_TRUE : SDL_FALSE);
383
+ #else
384
+ if (Xot::has_flag(flags, Window::FLAG_ALWAYS_ON_TOP))
385
+ not_implemented_error(__FILE__, __LINE__, "FLAG_ALWAYS_ON_TOP");
386
+ #endif
387
+
317
388
  SDL_SetWindowResizable(
318
389
  self->native,
319
390
  sdl_flags & SDL_WINDOW_RESIZABLE ? SDL_TRUE : SDL_FALSE);
320
391
 
392
+ SDL_SetWindowBordered(self->native, background ? SDL_TRUE : SDL_FALSE);
393
+
321
394
  int result = SDL_SetWindowFullscreen(
322
395
  self->native,
323
396
  sdl_flags & SDL_WINDOW_FULLSCREEN_DESKTOP ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
@@ -344,6 +417,17 @@ namespace Reflex
344
417
  return (float) draw_w / (float) win_w;
345
418
  }
346
419
 
420
+ void
421
+ Window_set_pointer_through (Window* window, bool through)
422
+ {
423
+ }
424
+
425
+ bool
426
+ Window_is_pointer_over_and_uncovered (Point* position, const Window& window)
427
+ {
428
+ return false;
429
+ }
430
+
347
431
  Window*
348
432
  Window_from (SDL_Window* native)
349
433
  {
@@ -364,7 +448,7 @@ namespace Reflex
364
448
  switch (event.window.event)
365
449
  {
366
450
  case SDL_WINDOWEVENT_CLOSE:
367
- win->close();
451
+ Window_call_close(win);
368
452
  break;
369
453
 
370
454
  case SDL_WINDOWEVENT_EXPOSED:
@@ -379,7 +463,7 @@ namespace Reflex
379
463
  case SDL_WINDOWEVENT_RESTORED:
380
464
  case SDL_WINDOWEVENT_MAXIMIZED:
381
465
  case SDL_WINDOWEVENT_MINIMIZED:
382
- frame_changed(win);
466
+ Window_call_frame_event(win);
383
467
  break;
384
468
 
385
469
  case SDL_WINDOWEVENT_FOCUS_GAINED:
@@ -387,6 +471,7 @@ namespace Reflex
387
471
  break;
388
472
 
389
473
  case SDL_WINDOWEVENT_FOCUS_LOST:
474
+ Window_cancel_active_pointers(win);
390
475
  Window_call_deactivate_event(win);
391
476
  break;
392
477
 
@@ -421,10 +506,34 @@ namespace Reflex
421
506
  break;
422
507
  }
423
508
 
509
+ case SDL_TEXTEDITING:
510
+ {
511
+ preedit(win, event.edit.text, event.edit.start, event.edit.length);
512
+ break;
513
+ }
514
+
515
+ #if SDL_VERSION_ATLEAST(2, 0, 22)
516
+ case SDL_TEXTEDITING_EXT:
517
+ {
518
+ preedit(win, event.editExt.text, event.editExt.start, event.editExt.length);
519
+ break;
520
+ }
521
+ #endif
522
+
523
+ case SDL_TEXTINPUT:
524
+ {
525
+ commit(win, event.text);
526
+ break;
527
+ }
528
+
424
529
  case SDL_MOUSEBUTTONDOWN:
425
530
  {
426
531
  NativePointerEvent e(self->native, event.button, Pointer::DOWN);
427
532
  Window_call_pointer_event(win, &e);
533
+
534
+ #if SDL_VERSION_ATLEAST(2, 0, 4)
535
+ SDL_CaptureMouse(SDL_TRUE);
536
+ #endif
428
537
  break;
429
538
  }
430
539
 
@@ -432,6 +541,13 @@ namespace Reflex
432
541
  {
433
542
  NativePointerEvent e(self->native, event.button, Pointer::UP);
434
543
  Window_call_pointer_event(win, &e);
544
+
545
+ #if SDL_VERSION_ATLEAST(2, 0, 4)
546
+ static const uint32_t BUTTONS =
547
+ SDL_BUTTON_LMASK | SDL_BUTTON_RMASK | SDL_BUTTON_MMASK;
548
+ if ((SDL_GetMouseState(NULL, NULL) & BUTTONS) == 0)
549
+ SDL_CaptureMouse(SDL_FALSE);
550
+ #endif
435
551
  break;
436
552
  }
437
553
 
@@ -494,11 +610,8 @@ namespace Reflex
494
610
 
495
611
  Window_call_update_event(win);
496
612
 
497
- if (self->redraw)
498
- {
613
+ if (Xot::check_and_remove_flag(&self->flags, Window::Data::REDRAW))
499
614
  redraw_window(self->native);
500
- self->redraw = false;
501
- }
502
615
  }
503
616
 
504
617