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/window.h CHANGED
@@ -9,6 +9,7 @@
9
9
  #include <map>
10
10
  #include <xot/time.h>
11
11
  #include <rays/point.h>
12
+ #include <rays/image.h>
12
13
  #include <rays/painter.h>
13
14
  #include "reflex/window.h"
14
15
  #include "reflex/view.h"
@@ -41,16 +42,26 @@ namespace Reflex
41
42
  enum Flag
42
43
  {
43
44
 
44
- ACTIVE = Xot::bit(1, FLAG_LAST),
45
+ ACTIVE = Xot::bit(1, FLAG_LAST),
46
+
47
+ REDRAW = Xot::bit(2, FLAG_LAST),
48
+
49
+ POINTER_THROUGH_PAUSED = Xot::bit(3, FLAG_LAST),
50
+
51
+ POINTER_THROUGH_ENTERED = Xot::bit(4, FLAG_LAST),
45
52
 
46
53
  };// Flag
47
54
 
48
55
  int hide_count = 1;
49
56
 
50
- bool redraw = true;
57
+ uint flags;
51
58
 
52
59
  Painter painter;
53
60
 
61
+ Image draw_cache;
62
+
63
+ Painter draw_cache_painter;
64
+
54
65
  View::Ref root, focus;
55
66
 
56
67
  Menu::Ref menu;
@@ -59,14 +70,16 @@ namespace Reflex
59
70
 
60
71
  double prev_time_update, prev_time_draw, prev_fps = 0;
61
72
 
62
- int next_pointer_id = 1;
73
+ int next_pointer_id = 1;
74
+
75
+ uint pointer_cancels = 0;
76
+
77
+ float pointer_through_alpha = 1;
63
78
 
64
79
  Pointer prev_mouse_pointer;
65
80
 
66
81
  PointerList prev_pointers;
67
82
 
68
- uint flags;
69
-
70
83
  CaptureMap captures;
71
84
 
72
85
  HoveredViewMap hovered_views;
@@ -90,7 +103,9 @@ namespace Reflex
90
103
  };// Window::Data
91
104
 
92
105
 
93
- Window::Data* Window_create_data ();
106
+ typedef View* (*Window_CreateRootViewFun) ();
107
+
108
+ void Window_set_create_root_view_fun (Window_CreateRootViewFun fun);
94
109
 
95
110
  void Window_register (Window* win);
96
111
 
@@ -100,6 +115,49 @@ namespace Reflex
100
115
 
101
116
  Window* Window_get_active ();
102
117
 
118
+ void Window_skip_update_time_of_all (double seconds);
119
+
120
+
121
+ void Window_set_focus (Window* window, View* view);
122
+
123
+ void Window_register_capture (
124
+ Window* window, View* view, Pointer::ID target);
125
+
126
+ void Window_unregister_capture (
127
+ Window* window, View* view, Pointer::ID target);
128
+
129
+ void Window_cancel_active_pointers (Window* window);
130
+
131
+ uint Window_get_pointer_cancels (const Window& window);
132
+
133
+ void Window_call_close (Window* window);
134
+
135
+ void Window_call_activate_event (Window* window);
136
+
137
+ void Window_call_deactivate_event (Window* window);
138
+
139
+ void Window_call_update_event (Window* window);
140
+
141
+ void Window_call_draw_event (Window* window, DrawEvent* event);
142
+
143
+ void Window_call_frame_event (Window* window);
144
+
145
+ void Window_call_key_event (
146
+ Window* window, KeyEvent* event, bool capture = true);
147
+
148
+ void Window_call_text_event (
149
+ Window* window, TextEvent* event, bool synthesize_key_events = false);
150
+
151
+ void Window_call_pointer_event (Window* window, PointerEvent* event);
152
+
153
+ void Window_call_wheel_event (Window* window, WheelEvent* event);
154
+
155
+ void Window_call_file_event (Window* window, FileEvent* event);
156
+
157
+ void Window_call_midi_event (Window* window, MIDIEvent* event);
158
+
159
+
160
+ Window::Data* Window_create_data ();
103
161
 
104
162
  uint Window_default_flags ();
105
163
 
@@ -128,34 +186,9 @@ namespace Reflex
128
186
 
129
187
  float Window_get_pixel_density (const Window& window);
130
188
 
131
- void Window_set_focus (Window* window, View* view);
132
-
133
- void Window_register_capture (
134
- Window* window, View* view, Pointer::ID target);
135
-
136
- void Window_unregister_capture (
137
- Window* window, View* view, Pointer::ID target);
189
+ void Window_set_pointer_through (Window* window, bool through);
138
190
 
139
- void Window_call_activate_event (Window* window);
140
-
141
- void Window_call_deactivate_event (Window* window);
142
-
143
- void Window_call_update_event (Window* window);
144
-
145
- void Window_call_draw_event (Window* window, DrawEvent* event);
146
-
147
- void Window_call_key_event (Window* window, KeyEvent* event);
148
-
149
- void Window_call_pointer_event (Window* window, PointerEvent* event);
150
-
151
- void Window_call_wheel_event (Window* window, WheelEvent* event);
152
-
153
- void Window_call_midi_event (Window* window, MIDIEvent* event);
154
-
155
-
156
- typedef View* (*Window_CreateRootViewFun) ();
157
-
158
- void Window_set_create_root_view_fun (Window_CreateRootViewFun fun);
191
+ bool Window_is_pointer_over_and_uncovered (Point* position, const Window& window);
159
192
 
160
193
 
161
194
  }// Reflex
data/src/world.cpp CHANGED
@@ -220,7 +220,7 @@ namespace Reflex
220
220
  static Shape*
221
221
  get_shape (b2ShapeId b2shape)
222
222
  {
223
- if (B2_IS_NULL(b2shape)) return NULL;
223
+ if (!b2Shape_IsValid(b2shape)) return NULL;
224
224
  return (Shape*) b2Shape_GetUserData(b2shape);
225
225
  }
226
226
 
@@ -259,6 +259,11 @@ namespace Reflex
259
259
  if (!v1 || !v2 || !View_is_active(*v1) || !View_is_active(*v2))
260
260
  return;
261
261
 
262
+ // the first handler is free to remove either view, so hold everything
263
+ // the second one needs until both have run
264
+ Shape::Ref sref1 = s1, sref2 = s2;
265
+ View::Ref vref1 = v1, vref2 = v2;
266
+
262
267
  ContactEvent e1(action, s2), e2(action, s1);
263
268
  Shape_call_contact_event(s1, &e1);
264
269
  Shape_call_contact_event(s2, &e2);
@@ -322,6 +327,9 @@ namespace Reflex
322
327
  ShapePair pair = it->second;
323
328
  touching_pairs.erase(it);
324
329
 
330
+ if (!b2Shape_IsValid(id1) || !b2Shape_IsValid(id2))
331
+ return;
332
+
325
333
  call_contact_events(pair.first, pair.second, ContactEvent::END);
326
334
  }
327
335
 
data/test/helper.rb CHANGED
@@ -10,6 +10,23 @@ require 'test/unit'
10
10
  include Xot::Test
11
11
 
12
12
 
13
+ module HasWindow
14
+
15
+ def window(*args, **kwargs, &block)
16
+ win = Reflex::Window.new(*args, **kwargs, &block)
17
+ (@windows_for_test__ ||= []).push win
18
+ win
19
+ end
20
+
21
+ def teardown()
22
+ super
23
+ @windows_for_test__&.each(&:close)
24
+ @windows_for_test__ = nil
25
+ end
26
+
27
+ end# HasWindow
28
+
29
+
13
30
  def assert_equal_point(expected, actual, delta = 0.01, *args)
14
31
  assert_in_delta expected.x, actual.x, delta, *args
15
32
  assert_in_delta expected.y, actual.y, delta, *args
@@ -5,8 +5,78 @@ class TestApplication < Test::Unit::TestCase
5
5
 
6
6
  @@app = Reflex::Application.new
7
7
 
8
+ def start(&block)
9
+ @@app.on(:start) {|e| block.call}
10
+ @@app.start
11
+ ensure
12
+ @@app.singleton_class.remove_method :on_start
13
+ end
14
+
15
+ def omit_on_macos_ci()
16
+ omit 'the macos runner aborts in CoreAnimation on an event loop' if ci? && osx?
17
+ end
18
+
19
+ def test_start_returns_on_quit()
20
+ omit_on_macos_ci
21
+
22
+ started = false
23
+ start {started = true; @@app.quit}
24
+ assert_true started
25
+ end
26
+
27
+ def test_start_returns_when_last_window_closed()
28
+ omit_on_macos_ci
29
+
30
+ quit = false
31
+ @@app.on(:quit) {|e| quit = true}
32
+ start {w = Reflex.window; w.on(:update) {|e| w.close}}
33
+ assert_true quit
34
+ end
35
+
36
+ def test_start_raises_on_start_block()
37
+ omit_on_macos_ci
38
+
39
+ e = assert_raise(RuntimeError) {start {raise 'boom'}}
40
+ assert_equal 'boom', e.message
41
+ assert_match(/#{__FILE__}/, e.backtrace.first)
42
+ end
43
+
44
+ def test_start_raises_from_window_event()
45
+ omit_on_macos_ci
46
+
47
+ w = nil
48
+ e = assert_raise(RuntimeError) do
49
+ start {w = Reflex::Window.new; w.on(:update) {|e| raise 'in update'}}
50
+ end
51
+ assert_equal 'in update', e.message
52
+ ensure
53
+ w&.close
54
+ end
55
+
56
+ def test_start_passes_exit()
57
+ omit_on_macos_ci
58
+
59
+ e = assert_raise(SystemExit) {start {exit 3}}
60
+ assert_equal 3, e.status
61
+ end
62
+
63
+ def test_start_passes_throw()
64
+ omit_on_macos_ci
65
+
66
+ assert_throw(:tag) {start {throw :tag}}
67
+ end
68
+
69
+ def test_start_twice()
70
+ omit_on_macos_ci
71
+
72
+ count = 0
73
+ 2.times {start {count += 1; @@app.quit}}
74
+ assert_equal 2, count
75
+ end
76
+
8
77
  def test_name()
9
- assert_equal '', @@app.name
78
+ assert_not_empty @@app.name
79
+
10
80
  @@app.name = 'AppName'
11
81
  assert_equal 'AppName', @@app.name
12
82
  end
@@ -22,6 +92,25 @@ class TestApplication < Test::Unit::TestCase
22
92
  assert_raise(TypeError) {@@app.menu = 1}
23
93
  end
24
94
 
95
+ def test_background()
96
+ assert_false @@app.background?
97
+ @@app.background = true
98
+ assert_true @@app.background?
99
+ @@app.background = false
100
+ assert_false @@app.background?
101
+ end
102
+
103
+ def test_background_menu()
104
+ m = Reflex::Menu.new
105
+ assert_nil @@app.background_menu
106
+ @@app.background_menu = m
107
+ assert_equal m, @@app.background_menu
108
+ @@app.background_menu = nil
109
+ assert_nil @@app.background_menu
110
+
111
+ assert_raise(TypeError) {@@app.background_menu = 1}
112
+ end
113
+
25
114
  def test_inspect()
26
115
  assert_match %r|#<Reflex::Application:0x\w{16}>|, @@app.inspect
27
116
  end
@@ -3,9 +3,7 @@ require_relative 'helper'
3
3
 
4
4
  class TestChaseConstraint < Test::Unit::TestCase
5
5
 
6
- def window()
7
- Reflex::Window.new
8
- end
6
+ include HasWindow
9
7
 
10
8
  def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
11
9
  Reflex::View.new(
@@ -0,0 +1,36 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestColorEvent < Test::Unit::TestCase
5
+
6
+ def event(*args)
7
+ Reflex::ColorEvent.new(*args)
8
+ end
9
+
10
+ def color(*args)
11
+ Reflex::Color.new(*args)
12
+ end
13
+
14
+ def test_initialize()
15
+ assert_equal color(1, 0, 0), event(color(1, 0, 0)).color
16
+ assert_equal color(0, 1, 0, 0.5), event([0, 1, 0, 0.5]).color
17
+
18
+ assert_raise(ArgumentError) {event}
19
+ assert_raise(ArgumentError) {event(nil)}
20
+ end
21
+
22
+ def test_dup()
23
+ e1 = event color(1, 0, 0)
24
+ e2 = e1.dup
25
+ e1.block
26
+ e3 = e1.dup
27
+ assert_true e1.blocked?
28
+ assert_false e2.blocked?
29
+ assert_true e3.blocked?
30
+ end
31
+
32
+ def test_inspect()
33
+ assert_equal "#<Reflex::ColorEvent color:[1.0, 0.0, 0.0, 1.0]>", event(color(1, 0, 0)).inspect
34
+ end
35
+
36
+ end# TestColorEvent
@@ -0,0 +1,62 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestColorPicker < Test::Unit::TestCase
5
+
6
+ include HasWindow
7
+
8
+ def picker(*args, &block)
9
+ Reflex::ColorPicker.new(*args, &block)
10
+ end
11
+
12
+ def event(color)
13
+ Reflex::ColorEvent.new color
14
+ end
15
+
16
+ def color(*args)
17
+ Reflex::Color.new(*args)
18
+ end
19
+
20
+ def test_initialize()
21
+ assert_nil picker .owner
22
+ assert_false picker .alpha?
23
+ assert_true picker( alpha: true) .alpha?
24
+ assert_true picker {alpha true} .alpha?
25
+ assert_true picker {self.alpha = true} .alpha?
26
+ end
27
+
28
+ def test_owner()
29
+ w = window
30
+ picker.tap do |p|
31
+ p.owner = w
32
+ assert_equal w, p.owner
33
+ p.owner = nil
34
+ assert_nil p.owner
35
+ end
36
+
37
+ assert_raise(TypeError) {picker.owner = 1}
38
+ end
39
+
40
+ def test_alpha()
41
+ picker.tap do |p|
42
+ p.alpha = true
43
+ assert_true p.alpha?
44
+ p.alpha = false
45
+ assert_false p.alpha?
46
+ end
47
+ end
48
+
49
+ def test_color_block_stays_until_close()
50
+ # the native side calls call_color_block and clear_color_block
51
+ p, got = picker, []
52
+ p.instance_variable_set :@color_block, -> e {got << e.color}
53
+ p.send :call_color_block, event(color(1, 0, 0))
54
+ p.send :call_color_block, event(color(0, 1, 0))
55
+ assert_equal [color(1, 0, 0), color(0, 1, 0)], got
56
+
57
+ p.send :clear_color_block
58
+ p.send :call_color_block, event(color(0, 0, 1))
59
+ assert_equal [color(1, 0, 0), color(0, 1, 0)], got
60
+ end
61
+
62
+ end# TestColorPicker
@@ -3,11 +3,9 @@ require_relative 'helper'
3
3
 
4
4
  class TestConstraint < Test::Unit::TestCase
5
5
 
6
- R = Reflex
6
+ include HasWindow
7
7
 
8
- def window()
9
- R::Window.new
10
- end
8
+ R = Reflex
11
9
 
12
10
  def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
13
11
  R::View.new(
data/test/test_event.rb CHANGED
@@ -46,7 +46,7 @@ class TestEvent < Test::Unit::TestCase
46
46
  end
47
47
 
48
48
  def test_time()
49
- assert_in_delta Time.now.to_f, event.time, 0.001
49
+ assert_in_delta Time.now.to_f, event.time, 0.1
50
50
  end
51
51
 
52
52
  end# TestEvent
@@ -0,0 +1,48 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestFileDialog < Test::Unit::TestCase
5
+
6
+ def dialog(*args, &block)
7
+ Reflex::FileDialog.new(*args, &block)
8
+ end
9
+
10
+ def test_initialize()
11
+ assert_nil dialog .owner
12
+ assert_equal '', dialog .title
13
+ assert_equal 'hoge', dialog( title: 'hoge') .title
14
+ assert_equal 'hoge', dialog {title 'hoge'} .title
15
+ assert_equal 'hoge', dialog {self.title = 'hoge'} .title
16
+ assert_equal [], dialog .extensions
17
+ assert_equal ['png'], dialog( extensions: ['png']).extensions
18
+ assert_equal ['png'], dialog {extensions ['png']}.extensions
19
+ assert_equal ['png'], dialog {self.extensions = ['png']}.extensions
20
+ end
21
+
22
+ def test_extensions()
23
+ dialog.tap do |d|
24
+ d.extensions = %w[png jpg]
25
+ assert_equal %w[png jpg], d.extensions
26
+ d.extensions = ['txt']
27
+ assert_equal ['txt'], d.extensions
28
+ end
29
+
30
+ assert_equal %w[png], dialog(extensions: 'png') .extensions
31
+ assert_equal %w[png], dialog(extensions: ['png']) .extensions
32
+ assert_equal %w[png], dialog(extensions: [:png]) .extensions
33
+ assert_equal %w[jpg], dialog(extensions: ['.jpg']) .extensions
34
+ assert_equal %w[gif], dialog(extensions: ['..gif']) .extensions
35
+ assert_equal %w[tar.gz], dialog(extensions: ['.tar.gz']).extensions
36
+
37
+ assert_raise(ArgumentError) {dialog.extensions = ['']}
38
+ assert_raise(ArgumentError) {dialog.extensions = ['.']}
39
+ assert_raise(ArgumentError) {dialog.extensions = ['png', '']}
40
+ assert_raise(ArgumentError) {dialog.extensions = ['*.png']}
41
+ assert_raise(ArgumentError) {dialog.extensions = ['p?g']}
42
+ assert_raise(ArgumentError) {dialog.extensions = ['png;jpg']}
43
+ assert_raise(ArgumentError) {dialog.extensions = ['a/b']}
44
+ assert_raise(ArgumentError) {dialog.extensions = [/png/]}
45
+ assert_raise(ArgumentError) {dialog.extensions = [1]}
46
+ end
47
+
48
+ end# TestFileDialog
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+
4
+ class TestFileEvent < Test::Unit::TestCase
5
+
6
+ Event = Reflex::FileEvent
7
+
8
+ NONE, OPEN, SAVE = Event::ACTION_NONE, Event::OPEN, Event::SAVE
9
+
10
+ def event(*args)
11
+ Event.new(*args)
12
+ end
13
+
14
+ def test_initialize()
15
+ assert_equal :open, event(OPEN, ['/a', '/b']).action
16
+ assert_equal ['/a', '/b'], event(OPEN, ['/a', '/b']).paths
17
+ assert_equal '/a', event(OPEN, ['/a', '/b']).path
18
+ end
19
+
20
+ def test_dup()
21
+ e1 = event OPEN, ['/a']
22
+ e2 = e1.dup
23
+ e1.block
24
+ e3 = e1.dup
25
+ assert_true e1.blocked?
26
+ assert_false e2.blocked?
27
+ assert_true e3.blocked?
28
+ end
29
+
30
+ def test_action()
31
+ assert_equal :none, event(NONE, []).action
32
+ assert_equal :open, event(OPEN, []).action
33
+ assert_equal :save, event(SAVE, []).action
34
+ end
35
+
36
+ def test_open_save?()
37
+ assert_true event(OPEN, ['/a']).open?
38
+ assert_false event(OPEN, ['/a']).save?
39
+ assert_false event(SAVE, ['/a']).open?
40
+ assert_true event(SAVE, ['/a']).save?
41
+ end
42
+
43
+ end# TestFileEvent
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative 'helper'
3
+
4
+
5
+ class TestHasTextPreedit < Test::Unit::TestCase
6
+
7
+ PREEDIT, COMMIT = Reflex::TextEvent::PREEDIT, Reflex::TextEvent::COMMIT
8
+
9
+ def view(*args)
10
+ Class.new(Reflex::View) {include Reflex::HasTextPreedit}.new(*args)
11
+ end
12
+
13
+ def event(*args)
14
+ Reflex::TextEvent.new(*args)
15
+ end
16
+
17
+ def test_initial_state()
18
+ v = view
19
+ assert_equal '', v.preedit
20
+ assert_nil v.preedit_selection
21
+ assert_false v.preedit?
22
+ end
23
+
24
+ def test_preedit()
25
+ v = view
26
+ v.on_text_preedit event(PREEDIT, 'こんにちは', 1, 2)
27
+ assert_equal 'こんにちは', v.preedit
28
+ assert_equal 1...3, v.preedit_selection
29
+ assert_true v.preedit?
30
+ end
31
+
32
+ def test_cancel()
33
+ v = view
34
+ v.on_text_preedit event(PREEDIT, 'こんにちは', 1, 2)
35
+ v.on_text_preedit event(PREEDIT, '', -1, 0)
36
+ assert_equal '', v.preedit
37
+ assert_nil v.preedit_selection
38
+ assert_false v.preedit?
39
+ end
40
+
41
+ def test_commit_clears_preedit()
42
+ v = view
43
+ v.on_text_preedit event(PREEDIT, 'こんにちは', 1, 2)
44
+ v.on_text_commit event(COMMIT, '今日は', -1, 0)
45
+ assert_equal '', v.preedit
46
+ assert_nil v.preedit_selection
47
+ assert_false v.preedit?
48
+ end
49
+
50
+ def test_include_accepts_text_input()
51
+ assert_true view.accepts_text_input?
52
+ end
53
+
54
+ end# TestHasTextPreedit
@@ -3,10 +3,12 @@ require_relative 'helper'
3
3
 
4
4
  class TestKeyEvent < Test::Unit::TestCase
5
5
 
6
- DOWN, UP = Reflex::KeyEvent::DOWN, Reflex::KeyEvent::UP
6
+ R = Reflex
7
+
8
+ DOWN, UP = R::KeyEvent::DOWN, R::KeyEvent::UP
7
9
 
8
10
  def event(*args)
9
- Reflex::KeyEvent.new(*args)
11
+ R::KeyEvent.new(*args)
10
12
  end
11
13
 
12
14
  def test_initialize()
@@ -43,10 +45,23 @@ class TestKeyEvent < Test::Unit::TestCase
43
45
  assert_nil event(DOWN, nil, 1, 2, 3).chars
44
46
  end
45
47
 
48
+ def test_key()
49
+ assert_equal :a, event(DOWN, 'a', R::KEY_A, 0, 0).key
50
+ assert_equal :f1, event(DOWN, '', R::KEY_F1, 0, 0).key
51
+ assert_equal :left, event(DOWN, '', R::KEY_LEFT, 0, 0).key
52
+ end
53
+
46
54
  def test_modifiers()
47
- e = event DOWN, 'a', 1, Reflex::MOD_CONTROL | Reflex::MOD_CAPS, 0
48
- assert_equal [:control, :caps], e.modifiers
49
- assert_equal [:control], e.modifiers(locks: false)
55
+ e = event DOWN, 'a', 1, R::MOD_CONTROL | R::MOD_CAPS, 0
56
+ assert_equal [:control], e.modifiers
57
+ assert_equal [:control, :caps], e.modifiers(all: true)
58
+ end
59
+
60
+ def test_inspect()
61
+ hex_z = R::KEY_Z.to_s(16).upcase
62
+ assert_equal(
63
+ "#<Reflex::KeyEvent :down chars:'z' key:z code:0x#{hex_z} mod:[:control, :caps] repeat:2 captured?:false>",
64
+ event(DOWN, 'z', R::KEY_Z, R::MOD_CONTROL | R::MOD_CAPS, 2).inspect)
50
65
  end
51
66
 
52
67
  end# TestKeyEvent
@@ -3,9 +3,7 @@ require_relative 'helper'
3
3
 
4
4
  class TestLinkConstraint < Test::Unit::TestCase
5
5
 
6
- def window()
7
- Reflex::Window.new
8
- end
6
+ include HasWindow
9
7
 
10
8
  def view(x = 0, y = 0, w = 50, h = 50, **options, &block)
11
9
  Reflex::View.new(