reflexion 0.5.3 → 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 (309) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/reflex/application.cpp +56 -7
  3. data/.doc/ext/reflex/capture_event.cpp +1 -1
  4. data/.doc/ext/reflex/chase_constraint.cpp +84 -0
  5. data/.doc/ext/reflex/clipboard.cpp +65 -0
  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 +135 -0
  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 +178 -0
  26. data/.doc/ext/reflex/menu.cpp +303 -0
  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 +40 -10
  31. data/.doc/ext/reflex/note_event.cpp +1 -1
  32. data/.doc/ext/reflex/pin.cpp +156 -0
  33. data/.doc/ext/reflex/pointer.cpp +3 -1
  34. data/.doc/ext/reflex/pointer_event.cpp +3 -3
  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 +606 -237
  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 +5 -5
  41. data/.doc/ext/reflex/shape.cpp +1 -1
  42. data/.doc/ext/reflex/snap_constraint.cpp +125 -0
  43. data/.doc/ext/reflex/style.cpp +1 -1
  44. data/.doc/ext/reflex/style_length.cpp +4 -3
  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 +206 -79
  50. data/.doc/ext/reflex/wheel_constraint.cpp +142 -0
  51. data/.doc/ext/reflex/wheel_event.cpp +1 -1
  52. data/.doc/ext/reflex/window.cpp +282 -31
  53. data/.github/workflows/release-gem.yml +2 -40
  54. data/.github/workflows/tag.yml +5 -28
  55. data/.github/workflows/test.yml +1 -28
  56. data/ChangeLog.md +79 -0
  57. data/Gemfile.lock +13 -8
  58. data/README.md +1 -0
  59. data/Rakefile +13 -2
  60. data/Reflex.podspec +2 -2
  61. data/VERSION +1 -1
  62. data/ext/reflex/application.cpp +62 -7
  63. data/ext/reflex/capture_event.cpp +1 -1
  64. data/ext/reflex/chase_constraint.cpp +89 -0
  65. data/ext/reflex/clipboard.cpp +69 -0
  66. data/ext/reflex/color_event.cpp +80 -0
  67. data/ext/reflex/color_picker.cpp +121 -0
  68. data/ext/reflex/constraint.cpp +146 -0
  69. data/ext/reflex/contact_event.cpp +1 -1
  70. data/ext/reflex/control_change_event.cpp +1 -1
  71. data/ext/reflex/device.cpp +1 -1
  72. data/ext/reflex/device_event.cpp +1 -1
  73. data/ext/reflex/draw_event.cpp +1 -1
  74. data/ext/reflex/ellipse_shape.cpp +1 -1
  75. data/ext/reflex/event.cpp +1 -1
  76. data/ext/reflex/extconf.rb +4 -2
  77. data/ext/reflex/file_dialog.cpp +194 -0
  78. data/ext/reflex/file_event.cpp +108 -0
  79. data/ext/reflex/filter.cpp +1 -1
  80. data/ext/reflex/focus_event.cpp +1 -1
  81. data/ext/reflex/frame_event.cpp +1 -1
  82. data/ext/reflex/gamepad.cpp +50 -0
  83. data/ext/reflex/image_view.cpp +1 -1
  84. data/ext/reflex/key_event.cpp +1 -275
  85. data/ext/reflex/line_shape.cpp +1 -1
  86. data/ext/reflex/link_constraint.cpp +194 -0
  87. data/ext/reflex/menu.cpp +331 -0
  88. data/ext/reflex/midi.cpp +11 -3
  89. data/ext/reflex/midi_event.cpp +1 -1
  90. data/ext/reflex/motion_event.cpp +1 -1
  91. data/ext/reflex/native.cpp +40 -10
  92. data/ext/reflex/note_event.cpp +1 -1
  93. data/ext/reflex/pin.cpp +165 -0
  94. data/ext/reflex/pointer.cpp +3 -1
  95. data/ext/reflex/pointer_event.cpp +3 -3
  96. data/ext/reflex/polygon_shape.cpp +1 -1
  97. data/ext/reflex/rect_shape.cpp +1 -1
  98. data/ext/reflex/reflex.cpp +608 -237
  99. data/ext/reflex/screen.cpp +31 -2
  100. data/ext/reflex/scroll_event.cpp +1 -1
  101. data/ext/reflex/selector.cpp +5 -5
  102. data/ext/reflex/selector.h +10 -10
  103. data/ext/reflex/shape.cpp +1 -1
  104. data/ext/reflex/snap_constraint.cpp +135 -0
  105. data/ext/reflex/style.cpp +1 -1
  106. data/ext/reflex/style_length.cpp +4 -3
  107. data/ext/reflex/text_event.cpp +111 -0
  108. data/ext/reflex/timer.cpp +1 -1
  109. data/ext/reflex/timer_event.cpp +1 -1
  110. data/ext/reflex/update_event.cpp +1 -1
  111. data/ext/reflex/view.cpp +236 -96
  112. data/ext/reflex/wheel_constraint.cpp +154 -0
  113. data/ext/reflex/wheel_event.cpp +1 -1
  114. data/ext/reflex/window.cpp +318 -40
  115. data/include/reflex/application.h +19 -0
  116. data/include/reflex/clipboard.h +53 -0
  117. data/include/reflex/color_picker.h +65 -0
  118. data/include/reflex/constraint.h +275 -0
  119. data/include/reflex/defs.h +204 -195
  120. data/include/reflex/event.h +180 -88
  121. data/include/reflex/file_dialog.h +73 -0
  122. data/include/reflex/gamepad.h +3 -0
  123. data/include/reflex/menu.h +120 -0
  124. data/include/reflex/midi.h +3 -0
  125. data/include/reflex/pin.h +68 -0
  126. data/include/reflex/pointer.h +4 -0
  127. data/include/reflex/reflex.h +2 -0
  128. data/include/reflex/ruby/application.h +6 -1
  129. data/include/reflex/ruby/clipboard.h +23 -0
  130. data/include/reflex/ruby/color_picker.h +89 -0
  131. data/include/reflex/ruby/constraint.h +94 -0
  132. data/include/reflex/ruby/event.h +62 -29
  133. data/include/reflex/ruby/file_dialog.h +89 -0
  134. data/include/reflex/ruby/gamepad.h +46 -0
  135. data/include/reflex/ruby/menu.h +103 -0
  136. data/include/reflex/ruby/pin.h +40 -0
  137. data/include/reflex/ruby/reflex.h +3 -0
  138. data/include/reflex/ruby/view.h +123 -39
  139. data/include/reflex/ruby/window.h +96 -19
  140. data/include/reflex/ruby.h +3 -0
  141. data/include/reflex/screen.h +11 -2
  142. data/include/reflex/view.h +66 -27
  143. data/include/reflex/window.h +57 -12
  144. data/include/reflex.h +8 -0
  145. data/lib/reflex/application.rb +5 -5
  146. data/lib/reflex/autoinit.rb +3 -1
  147. data/lib/reflex/button.rb +3 -3
  148. data/lib/reflex/chase_constraint.rb +15 -0
  149. data/lib/reflex/clipboard.rb +19 -0
  150. data/lib/reflex/color_event.rb +16 -0
  151. data/lib/reflex/color_picker.rb +45 -0
  152. data/lib/reflex/constraint.rb +29 -0
  153. data/lib/reflex/control_change_event.rb +17 -0
  154. data/lib/reflex/extension.rb +1 -1
  155. data/lib/reflex/file_dialog.rb +70 -0
  156. data/lib/reflex/file_event.rb +37 -0
  157. data/lib/reflex/helper.rb +79 -0
  158. data/lib/reflex/key_event.rb +14 -14
  159. data/lib/reflex/link_constraint.rb +31 -0
  160. data/lib/reflex/menu.rb +92 -0
  161. data/lib/reflex/model.rb +19 -19
  162. data/lib/reflex/note_event.rb +1 -1
  163. data/lib/reflex/pin.rb +39 -0
  164. data/lib/reflex/pointer.rb +30 -1
  165. data/lib/reflex/pointer_event.rb +13 -2
  166. data/lib/reflex/reflex.rb +5 -0
  167. data/lib/reflex/shape.rb +14 -14
  168. data/lib/reflex/snap_constraint.rb +28 -0
  169. data/lib/reflex/style.rb +16 -16
  170. data/lib/reflex/text_event.rb +40 -0
  171. data/lib/reflex/timer.rb +3 -3
  172. data/lib/reflex/view.rb +85 -18
  173. data/lib/reflex/wheel_constraint.rb +28 -0
  174. data/lib/reflex/wheel_event.rb +19 -1
  175. data/lib/reflex/window.rb +25 -13
  176. data/lib/reflex.rb +23 -8
  177. data/pod.rake +1 -1
  178. data/reflex.gemspec +4 -4
  179. data/samples/constraint.rb +152 -0
  180. data/samples/ime.rb +100 -0
  181. data/samples/ios/hello/hello.xcodeproj/project.pbxproj +236 -224
  182. data/samples/menu.rb +32 -0
  183. data/samples/model.rb +3 -3
  184. data/samples/test/alert.rb +93 -0
  185. data/samples/test/always_on.rb +76 -0
  186. data/samples/test/app_background.rb +51 -0
  187. data/samples/test/boundary.rb +75 -0
  188. data/samples/test/callback_exception.rb +101 -0
  189. data/samples/test/cancel.rb +53 -0
  190. data/samples/test/color_picker.rb +63 -0
  191. data/samples/test/file_dialog.rb +102 -0
  192. data/samples/window_style.rb +156 -0
  193. data/src/application.cpp +180 -20
  194. data/src/application.h +95 -5
  195. data/src/clipboard.cpp +81 -0
  196. data/src/color_picker.cpp +113 -0
  197. data/src/color_picker.h +36 -0
  198. data/src/constraint.cpp +1662 -0
  199. data/src/constraint.h +64 -0
  200. data/src/event.cpp +416 -252
  201. data/src/event.h +13 -2
  202. data/src/file_dialog.cpp +163 -0
  203. data/src/file_dialog.h +52 -0
  204. data/src/gamepad.cpp +42 -5
  205. data/src/gamepad.h +4 -0
  206. data/src/ios/app_delegate.mm +5 -3
  207. data/src/ios/application.mm +29 -0
  208. data/src/ios/clipboard.mm +44 -0
  209. data/src/ios/color_picker.mm +19 -0
  210. data/src/ios/event.h +6 -2
  211. data/src/ios/event.mm +31 -12
  212. data/src/ios/file_dialog.mm +21 -0
  213. data/src/ios/gamepad.mm +4 -4
  214. data/src/ios/menu.mm +41 -0
  215. data/src/ios/reflex.mm +8 -0
  216. data/src/ios/screen.mm +26 -0
  217. data/src/ios/view_controller.mm +47 -42
  218. data/src/ios/window.mm +44 -9
  219. data/src/menu.cpp +387 -0
  220. data/src/menu.h +81 -0
  221. data/src/midi.cpp +61 -31
  222. data/src/osx/app_delegate.h +4 -0
  223. data/src/osx/app_delegate.mm +168 -139
  224. data/src/osx/application.mm +103 -5
  225. data/src/osx/clipboard.mm +45 -0
  226. data/src/osx/color_picker.mm +112 -0
  227. data/src/osx/event.h +10 -0
  228. data/src/osx/event.mm +114 -30
  229. data/src/osx/file_dialog.mm +168 -0
  230. data/src/osx/gamepad.mm +2 -2
  231. data/src/osx/gamepad_hid.mm +1 -1
  232. data/src/osx/menu.h +25 -0
  233. data/src/osx/menu.mm +516 -0
  234. data/src/osx/native_window.h +16 -2
  235. data/src/osx/native_window.mm +141 -57
  236. data/src/osx/opengl_view.h +2 -1
  237. data/src/osx/opengl_view.mm +229 -37
  238. data/src/osx/reflex.mm +38 -0
  239. data/src/osx/screen.mm +36 -0
  240. data/src/osx/window.mm +117 -24
  241. data/src/pin.cpp +137 -0
  242. data/src/pointer.cpp +36 -16
  243. data/src/pointer.h +10 -0
  244. data/src/rays.h +46 -0
  245. data/src/sdl/application.cpp +73 -8
  246. data/src/sdl/clipboard.cpp +39 -0
  247. data/src/sdl/color_picker.cpp +18 -0
  248. data/src/sdl/event.cpp +44 -6
  249. data/src/sdl/event.h +18 -3
  250. data/src/sdl/file_dialog.cpp +20 -0
  251. data/src/sdl/gamepad.cpp +3 -7
  252. data/src/sdl/menu.cpp +40 -0
  253. data/src/sdl/reflex.cpp +20 -0
  254. data/src/sdl/screen.cpp +36 -0
  255. data/src/sdl/window.cpp +168 -37
  256. data/src/shape.cpp +15 -10
  257. data/src/view.cpp +583 -233
  258. data/src/view.h +22 -4
  259. data/src/vk.h +416 -0
  260. data/src/win32/application.cpp +167 -12
  261. data/src/win32/application.h +20 -0
  262. data/src/win32/clipboard.cpp +210 -0
  263. data/src/win32/color_picker.cpp +82 -0
  264. data/src/win32/event.cpp +123 -11
  265. data/src/win32/event.h +22 -3
  266. data/src/win32/file_dialog.cpp +226 -0
  267. data/src/win32/gamepad.cpp +9 -2
  268. data/src/win32/menu.cpp +490 -0
  269. data/src/win32/menu.h +35 -0
  270. data/src/win32/opengl.cpp +2 -9
  271. data/src/win32/reflex.cpp +44 -3
  272. data/src/win32/screen.cpp +164 -3
  273. data/src/win32/screen.h +8 -0
  274. data/src/win32/tray.cpp +191 -0
  275. data/src/win32/tray.h +22 -0
  276. data/src/win32/vk.cpp +11 -0
  277. data/src/win32/window.cpp +858 -135
  278. data/src/win32/window.h +9 -0
  279. data/src/window.cpp +929 -183
  280. data/src/window.h +77 -33
  281. data/src/world.cpp +86 -15
  282. data/src/world.h +9 -2
  283. data/test/helper.rb +24 -0
  284. data/test/test_application.rb +101 -1
  285. data/test/test_chase_constraint.rb +122 -0
  286. data/test/test_clipboard.rb +54 -0
  287. data/test/test_color_event.rb +36 -0
  288. data/test/test_color_picker.rb +62 -0
  289. data/test/test_constraint.rb +184 -0
  290. data/test/test_event.rb +1 -1
  291. data/test/test_file_dialog.rb +48 -0
  292. data/test/test_file_event.rb +43 -0
  293. data/test/test_has_text_preedit.rb +54 -0
  294. data/test/test_key_event.rb +23 -2
  295. data/test/test_link_constraint.rb +237 -0
  296. data/test/test_menu.rb +237 -0
  297. data/test/test_pin.rb +65 -0
  298. data/test/test_pointer.rb +50 -26
  299. data/test/test_pointer_event.rb +25 -10
  300. data/test/test_reflex.rb +36 -0
  301. data/test/test_screen.rb +24 -2
  302. data/test/test_snap_constraint.rb +140 -0
  303. data/test/test_text_event.rb +54 -0
  304. data/test/test_view.rb +152 -25
  305. data/test/test_wheel_constraint.rb +125 -0
  306. data/test/test_wheel_event.rb +24 -10
  307. data/test/test_window.rb +205 -43
  308. metadata +154 -10
  309. data/.github/workflows/utils.rb +0 -127
@@ -2,9 +2,12 @@
2
2
  #include "application.h"
3
3
 
4
4
 
5
- #import <AppKit/NSApplication.h>
5
+ #import <AppKit/AppKit.h>
6
6
  #include "reflex/exception.h"
7
7
  #include "reflex/debug.h"
8
+ #include "window.h"
9
+ #include "menu.h"
10
+ #import "native_window.h"
8
11
  #import "app_delegate.h"
9
12
 
10
13
 
@@ -18,6 +21,16 @@ namespace Reflex
18
21
  return new ApplicationData();
19
22
  }
20
23
 
24
+ String
25
+ Application_get_default_name ()
26
+ {
27
+ NSBundle* bundle = NSBundle.mainBundle;
28
+ NSString* name = [bundle objectForInfoDictionaryKey: @"CFBundleDisplayName"];
29
+ if (!name) name = [bundle objectForInfoDictionaryKey: @"CFBundleName"];
30
+ if (!name) name = NSProcessInfo.processInfo.processName;
31
+ return name ? name.UTF8String : "";
32
+ }
33
+
21
34
  ApplicationData&
22
35
  Application_get_data (Application* app)
23
36
  {
@@ -34,6 +47,60 @@ namespace Reflex
34
47
  }
35
48
 
36
49
 
50
+ static void
51
+ update_status_item (Application* app)
52
+ {
53
+ [Application_get_data(app).delegate updateStatusItem];
54
+ }
55
+
56
+ void
57
+ Application_stop (Application* app)
58
+ {
59
+ [NSApp stop: nil];
60
+
61
+ // stop: takes effect only after an event is handled, so post one
62
+ NSEvent* e = [NSEvent
63
+ otherEventWithType: NSEventTypeApplicationDefined
64
+ location: NSZeroPoint modifierFlags: 0 timestamp: 0
65
+ windowNumber: 0 context: nil subtype: 0 data1: 0 data2: 0];
66
+ [NSApp postEvent: e atStart: YES];
67
+ }
68
+
69
+ void
70
+ Application_set_menu (Application* app, Menu* menu)
71
+ {
72
+ update_status_item(app);
73
+
74
+ for (auto it = app->window_begin(), end = app->window_end(); it != end; ++it)
75
+ {
76
+ Window* win = it->get();
77
+ if (win->menu() && Window_get_data(win).native.isMainWindow)
78
+ return;
79
+ }
80
+
81
+ Menu_apply_to_main_menu(menu);
82
+ }
83
+
84
+ void
85
+ Application_set_background (Application* app, bool state)
86
+ {
87
+ [NSApp setActivationPolicy: state
88
+ ? NSApplicationActivationPolicyAccessory
89
+ : NSApplicationActivationPolicyRegular];
90
+
91
+ if (!state)
92
+ [NSApp activateIgnoringOtherApps: YES];
93
+
94
+ update_status_item(app);
95
+ }
96
+
97
+ void
98
+ Application_set_background_menu (Application* app, Menu* menu)
99
+ {
100
+ update_status_item(app);
101
+ }
102
+
103
+
37
104
  ApplicationData::ApplicationData ()
38
105
  : delegate(nil)
39
106
  {
@@ -63,16 +130,47 @@ namespace Reflex
63
130
  ReflexAppDelegate* delegate = setup_app_delegate(app);
64
131
  [delegate bind: this];
65
132
 
66
- if (!app.isRunning)
67
- [app run];
68
- else
133
+ if (app.isRunning)
134
+ {
135
+ // the host app runs the event loop
69
136
  [delegate callOnStart];
137
+ return;
138
+ }
139
+
140
+ if (delegate.isLaunched)
141
+ {
142
+ // the app is launched only once, so the later runs start by themselves
143
+ [delegate performSelector: @selector(callOnStart) withObject: nil afterDelay: 0];
144
+ }
145
+
146
+ self->started = false;
147
+ self->quitting = false;
148
+ self->running = true;
149
+ [app run];
150
+ self->running = false;
151
+
152
+ Application_cleanup(this);
153
+ [delegate unbind];
154
+
155
+ Application_throw_exception(this);
70
156
  }
71
157
 
72
158
  void
73
159
  Application::quit ()
74
160
  {
75
- [NSApp terminate: nil];
161
+ // terminate exits the process even before run, which would take down
162
+ // irb or a test process
163
+ if (!NSApp.isRunning)
164
+ invalid_state_error(__FILE__, __LINE__, "the application is not running.");
165
+
166
+ Event e;
167
+ Application_call_quit_event(this, &e);
168
+ if (e.is_blocked()) return;
169
+
170
+ if (self->running)
171
+ Application_stop(this);
172
+ else
173
+ [NSApp terminate: nil];
76
174
  }
77
175
 
78
176
  void
@@ -0,0 +1,45 @@
1
+ // -*- objc -*-
2
+ #include "reflex/clipboard.h"
3
+
4
+
5
+ #import <AppKit/NSPasteboard.h>
6
+ #include "reflex/exception.h"
7
+
8
+
9
+ namespace Reflex
10
+ {
11
+
12
+
13
+ void
14
+ set_clipboard (const Clipboard& clipboard)
15
+ {
16
+ const char* text = clipboard.text();
17
+ NSString* nstext = nil;
18
+ if (text)
19
+ {
20
+ nstext = [NSString stringWithUTF8String: text];
21
+ if (!nstext)
22
+ argument_error(__FILE__, __LINE__);
23
+ }
24
+
25
+ NSPasteboard* pasteboard = NSPasteboard.generalPasteboard;
26
+ [pasteboard clearContents];
27
+
28
+ if (nstext)
29
+ [pasteboard setString: nstext forType: NSPasteboardTypeString];
30
+ }
31
+
32
+ Clipboard
33
+ get_clipboard ()
34
+ {
35
+ Clipboard clipboard;
36
+
37
+ NSString* nstext = [NSPasteboard.generalPasteboard stringForType: NSPasteboardTypeString];
38
+ const char* text = nstext ? nstext.UTF8String : NULL;
39
+ if (text) clipboard.set_text(text);
40
+
41
+ return clipboard;
42
+ }
43
+
44
+
45
+ }// Reflex
@@ -0,0 +1,112 @@
1
+ // -*- objc -*-
2
+ #include "../color_picker.h"
3
+
4
+
5
+ #import <AppKit/AppKit.h>
6
+ #include "reflex/exception.h"
7
+
8
+
9
+ @interface ReflexColorPanelTarget : NSObject
10
+
11
+ - (void) setCurrentPicker: (Reflex::ColorPicker*) picker;
12
+
13
+ @end
14
+
15
+
16
+ @implementation ReflexColorPanelTarget
17
+
18
+ {
19
+ // not a static, that would be released at exit after the ruby vm is gone
20
+ Reflex::ColorPicker::Ref current;
21
+ }
22
+
23
+ - (void) setCurrentPicker: (Reflex::ColorPicker*) picker
24
+ {
25
+ if (current && current != picker)
26
+ [self closeCurrent];
27
+
28
+ current = picker;
29
+ }
30
+
31
+ - (void) closeCurrent
32
+ {
33
+ if (!current) return;
34
+
35
+ Reflex::ColorPicker::Ref picker = current;
36
+ current = NULL;
37
+
38
+ Reflex::Event e;
39
+ Reflex::ColorPicker_call_close_event(picker, &e);
40
+ }
41
+
42
+ - (void) colorChanged: (NSColorPanel*) panel
43
+ {
44
+ if (!current) return;
45
+
46
+ NSColor* color = [panel.color colorUsingColorSpace: NSColorSpace.sRGBColorSpace];
47
+ if (!color) return;
48
+
49
+ Reflex::ColorEvent e(Reflex::Color(
50
+ color.redComponent,
51
+ color.greenComponent,
52
+ color.blueComponent,
53
+ color.alphaComponent));
54
+ Reflex::ColorPicker_call_color_event(current, &e);
55
+ }
56
+
57
+ - (void) panelWillClose: (NSNotification*) notification
58
+ {
59
+ [self closeCurrent];
60
+ }
61
+
62
+ @end
63
+
64
+
65
+ namespace Reflex
66
+ {
67
+
68
+
69
+ static ReflexColorPanelTarget*
70
+ get_target (NSColorPanel* panel)
71
+ {
72
+ static ReflexColorPanelTarget* target = nil;
73
+ if (!target)
74
+ {
75
+ target = [[ReflexColorPanelTarget alloc] init];
76
+ [NSNotificationCenter.defaultCenter
77
+ addObserver: target
78
+ selector: @selector(panelWillClose:)
79
+ name: NSWindowWillCloseNotification
80
+ object: panel];
81
+ }
82
+ return target;
83
+ }
84
+
85
+ void
86
+ ColorPicker_show (ColorPicker* picker, const Color* initial)
87
+ {
88
+ if (!picker)
89
+ argument_error(__FILE__, __LINE__);
90
+
91
+ NSColorPanel* panel = NSColorPanel.sharedColorPanel;
92
+ ReflexColorPanelTarget* target = get_target(panel);
93
+ [target setCurrentPicker: picker];
94
+
95
+ panel.showsAlpha = picker->alpha();
96
+ panel.continuous = YES;
97
+ panel.target = target;
98
+ panel.action = @selector(colorChanged:);
99
+ if (initial)
100
+ {
101
+ panel.color = [NSColor
102
+ colorWithSRGBRed: initial->red
103
+ green: initial->green
104
+ blue: initial->blue
105
+ alpha: initial->alpha];
106
+ }
107
+
108
+ [panel makeKeyAndOrderFront: nil];
109
+ }
110
+
111
+
112
+ }// Reflex
data/src/osx/event.h CHANGED
@@ -32,6 +32,16 @@ namespace Reflex
32
32
  };// NativeFlagKeyEvent
33
33
 
34
34
 
35
+ class NativeTextEvent : public TextEvent
36
+ {
37
+
38
+ public:
39
+
40
+ NativeTextEvent (Action action, NSString* text, NSRange selection);
41
+
42
+ };// NativeTextEvent
43
+
44
+
35
45
  class NativePointerEvent : public PointerEvent
36
46
  {
37
47
 
data/src/osx/event.mm CHANGED
@@ -18,14 +18,14 @@ namespace Reflex
18
18
  {
19
19
  NSUInteger flags = event ? event.modifierFlags : NSEvent.modifierFlags;
20
20
  return
21
- (flags & NSAlphaShiftKeyMask) ? MOD_CAPS : 0 |
22
- (flags & NSShiftKeyMask) ? MOD_SHIFT : 0 |
23
- (flags & NSControlKeyMask) ? MOD_CONTROL : 0 |
24
- (flags & NSAlternateKeyMask) ? MOD_OPTION : 0 |
25
- (flags & NSCommandKeyMask) ? MOD_COMMAND : 0 |
26
- (flags & NSNumericPadKeyMask) ? MOD_NUMPAD : 0 |
27
- (flags & NSHelpKeyMask) ? MOD_HELP : 0 |
28
- (flags & NSFunctionKeyMask) ? MOD_FUNCTION : 0;
21
+ (flags & NSEventModifierFlagCapsLock ? MOD_CAPS : 0) |
22
+ (flags & NSEventModifierFlagShift ? MOD_SHIFT : 0) |
23
+ (flags & NSEventModifierFlagControl ? MOD_CONTROL : 0) |
24
+ (flags & NSEventModifierFlagOption ? MOD_OPTION : 0) |
25
+ (flags & NSEventModifierFlagCommand ? MOD_COMMAND : 0) |
26
+ (flags & NSEventModifierFlagNumericPad ? MOD_NUMPAD : 0) |
27
+ (flags & NSEventModifierFlagHelp ? MOD_HELP : 0) |
28
+ (flags & NSEventModifierFlagFunction ? MOD_FUNCTION : 0);
29
29
  }
30
30
 
31
31
  static Point
@@ -52,8 +52,17 @@ namespace Reflex
52
52
  return [chars UTF8String];
53
53
  }
54
54
 
55
+ static int
56
+ get_key_code (NSEvent* e)
57
+ {
58
+ // fn+return on a laptop keyboard reports a code of its own, which
59
+ // has no kVK_* name; it is the same key as the enter on the keypad
60
+ // of an external keyboard
61
+ return e.keyCode == 0x34 ? kVK_ANSI_KeypadEnter : e.keyCode;
62
+ }
63
+
55
64
  NativeKeyEvent::NativeKeyEvent (NSEvent* e, Action action, int repeat)
56
- : KeyEvent(action, get_chars(e), [e keyCode], get_modifiers(e), repeat)
65
+ : KeyEvent(action, get_chars(e), get_key_code(e), get_modifiers(e), repeat)
57
66
  {
58
67
  }
59
68
 
@@ -64,15 +73,15 @@ namespace Reflex
64
73
  switch ([e keyCode])
65
74
  {
66
75
  case kVK_Shift:
67
- case kVK_RightShift: return NSShiftKeyMask;
76
+ case kVK_RightShift: return NSEventModifierFlagShift;
68
77
  case kVK_Control:
69
- case kVK_RightControl: return NSControlKeyMask;
78
+ case kVK_RightControl: return NSEventModifierFlagControl;
70
79
  case kVK_Option:
71
- case kVK_RightOption: return NSAlternateKeyMask;
80
+ case kVK_RightOption: return NSEventModifierFlagOption;
72
81
  case kVK_Command:
73
- case kVK_RightCommand: return NSCommandKeyMask;
74
- case kVK_CapsLock: return NSAlphaShiftKeyMask;
75
- case kVK_Function: return NSFunctionKeyMask;
82
+ case kVK_RightCommand: return NSEventModifierFlagCommand;
83
+ case kVK_CapsLock: return NSEventModifierFlagCapsLock;
84
+ case kVK_Function: return NSEventModifierFlagFunction;
76
85
  }
77
86
  return 0;
78
87
  }
@@ -96,13 +105,56 @@ namespace Reflex
96
105
  }
97
106
 
98
107
 
108
+ static int
109
+ to_char_index (NSString* str, NSUInteger utf16_index)
110
+ {
111
+ if (utf16_index > str.length) utf16_index = str.length;
112
+
113
+ int index = 0;
114
+ for (NSUInteger i = 0; i < utf16_index; ++i, ++index)
115
+ {
116
+ unichar c = [str characterAtIndex: i];
117
+ if (!CFStringIsSurrogateHighCharacter(c) || i + 1 >= str.length)
118
+ continue;
119
+
120
+ if (CFStringIsSurrogateLowCharacter([str characterAtIndex: i + 1]))
121
+ ++i;
122
+ }
123
+ return index;
124
+ }
125
+
126
+ static int
127
+ get_selection_offset (NSString* str, NSRange selection)
128
+ {
129
+ if (selection.location == NSNotFound) return -1;
130
+ return to_char_index(str, selection.location);
131
+ }
132
+
133
+ static int
134
+ get_selection_size (NSString* str, NSRange selection)
135
+ {
136
+ if (selection.location == NSNotFound) return 0;
137
+ return
138
+ to_char_index(str, selection.location + selection.length) -
139
+ to_char_index(str, selection.location);
140
+ }
141
+
142
+ NativeTextEvent::NativeTextEvent (
143
+ Action action, NSString* text, NSRange selection)
144
+ : TextEvent(
145
+ action, text.UTF8String,
146
+ get_selection_offset(text, selection), get_selection_size(text, selection))
147
+ {
148
+ }
149
+
150
+
99
151
  static bool
100
152
  is_pointer_dragging (NSEvent* e)
101
153
  {
102
154
  return
103
- [e type] == NSLeftMouseDragged ||
104
- [e type] == NSRightMouseDragged ||
105
- [e type] == NSOtherMouseDragged;
155
+ [e type] == NSEventTypeLeftMouseDragged ||
156
+ [e type] == NSEventTypeRightMouseDragged ||
157
+ [e type] == NSEventTypeOtherMouseDragged;
106
158
  }
107
159
 
108
160
  static uint
@@ -121,22 +173,24 @@ namespace Reflex
121
173
  {
122
174
  switch ([e type])
123
175
  {
124
- case NSLeftMouseDown:
125
- case NSLeftMouseUp:
126
- case NSLeftMouseDragged:
176
+ case NSEventTypeLeftMouseDown:
177
+ case NSEventTypeLeftMouseUp:
178
+ case NSEventTypeLeftMouseDragged:
127
179
  return Reflex::Pointer::MOUSE | Reflex::Pointer::MOUSE_LEFT;
128
180
 
129
- case NSRightMouseDown:
130
- case NSRightMouseUp:
131
- case NSRightMouseDragged:
181
+ case NSEventTypeRightMouseDown:
182
+ case NSEventTypeRightMouseUp:
183
+ case NSEventTypeRightMouseDragged:
132
184
  return Reflex::Pointer::MOUSE | Reflex::Pointer::MOUSE_RIGHT;
133
185
 
134
- case NSOtherMouseDown:
135
- case NSOtherMouseUp:
136
- case NSOtherMouseDragged:
186
+ case NSEventTypeOtherMouseDown:
187
+ case NSEventTypeOtherMouseUp:
188
+ case NSEventTypeOtherMouseDragged:
137
189
  return Reflex::Pointer::MOUSE | Reflex::Pointer::MOUSE_MIDDLE;
138
190
 
139
- case NSMouseMoved:
191
+ case NSEventTypeMouseMoved:
192
+ case NSEventTypeMouseEntered:
193
+ case NSEventTypeMouseExited:
140
194
  return Reflex::Pointer::MOUSE | get_current_pointer_type();
141
195
 
142
196
  default:
@@ -144,6 +198,25 @@ namespace Reflex
144
198
  }
145
199
  }
146
200
 
201
+ static uint
202
+ get_click_count (NSEvent* e, Pointer::Action action, bool dragging)
203
+ {
204
+ switch (action)
205
+ {
206
+ case Pointer::DOWN:
207
+ case Pointer::UP:
208
+ return (uint) e.clickCount;
209
+
210
+ case Pointer::MOVE:
211
+ return dragging ? (uint) e.clickCount : 0;
212
+
213
+ default:
214
+ // asking clickCount raises NSInternalInconsistencyException for
215
+ // tracking (enter/exit) events.
216
+ return 0;
217
+ }
218
+ }
219
+
147
220
  NativePointerEvent::NativePointerEvent (
148
221
  NSEvent* event, NSView* view, Pointer::Action action)
149
222
  {
@@ -154,14 +227,25 @@ namespace Reflex
154
227
  action,
155
228
  get_pointer_position(event, view),
156
229
  get_modifiers(event),
157
- action == Pointer::MOVE && !dragging ? 0 : (uint) event.clickCount,
230
+ get_click_count(event, action, dragging),
158
231
  dragging,
159
232
  time()));
160
233
  }
161
234
 
162
235
 
236
+ static coord
237
+ to_wheel_pixels (NSEvent* e, CGFloat delta)
238
+ {
239
+ return delta * (e.hasPreciseScrollingDeltas ? 1 : WHEEL_PIXELS_PER_LINE);
240
+ }
241
+
163
242
  NativeWheelEvent::NativeWheelEvent (NSEvent* e, NSView* view)
164
- : WheelEvent(0, 0, 0, [e deltaX], -[e deltaY], [e deltaZ], get_modifiers(e))
243
+ : WheelEvent(
244
+ 0, 0, 0,
245
+ to_wheel_pixels(e, e.scrollingDeltaX),
246
+ to_wheel_pixels(e, -e.scrollingDeltaY),
247
+ 0,
248
+ get_modifiers(e))
165
249
  {
166
250
  WheelEvent_set_position(this, get_pointer_position(e, view));
167
251
  }
@@ -0,0 +1,168 @@
1
+ // -*- objc -*-
2
+ #include "../file_dialog.h"
3
+
4
+
5
+ #import <AppKit/AppKit.h>
6
+ #include "reflex/exception.h"
7
+ #include "window.h"
8
+
9
+
10
+ @interface ReflexOpenSavePanelDelegate : NSObject <NSOpenSavePanelDelegate>
11
+ @end
12
+
13
+
14
+ @implementation ReflexOpenSavePanelDelegate
15
+
16
+ {
17
+ NSArray<NSString*>* suffixes;
18
+ }
19
+
20
+ - (id) initWithExtensions: (const Reflex::StringList&) extensions
21
+ {
22
+ self = [super init];
23
+ if (!self) return nil;
24
+
25
+ NSMutableArray* array = [NSMutableArray arrayWithCapacity: extensions.size()];
26
+ for (const auto& extension : extensions)
27
+ {
28
+ NSString* str = [NSString stringWithUTF8String: ("." + extension).c_str()];
29
+ if (!str)
30
+ Reflex::argument_error(__FILE__, __LINE__);
31
+
32
+ [array addObject: str];
33
+ }
34
+ suffixes = [array retain];
35
+
36
+ return self;
37
+ }
38
+
39
+ - (void) dealloc
40
+ {
41
+ [suffixes release];
42
+
43
+ [super dealloc];
44
+ }
45
+
46
+ - (BOOL) panel: (id) sender shouldEnableURL: (NSURL*) url
47
+ {
48
+ NSNumber* directory = nil;
49
+ if (![url getResourceValue: &directory forKey: NSURLIsDirectoryKey error: NULL])
50
+ return YES;// what cannot be classified is better shown than hidden
51
+
52
+ if (directory.boolValue)
53
+ return YES;
54
+
55
+ NSString* name = url.lastPathComponent.lowercaseString;
56
+ for (NSString* suffix in suffixes)
57
+ {
58
+ if ([name hasSuffix: suffix.lowercaseString])
59
+ return YES;
60
+ }
61
+ return NO;
62
+ }
63
+
64
+ @end
65
+
66
+
67
+ namespace Reflex
68
+ {
69
+
70
+
71
+ static NSOpenPanel*
72
+ create_open_panel (FileDialog* dialog, FileDialog::Data::Mode mode)
73
+ {
74
+ NSOpenPanel* panel = [NSOpenPanel openPanel];
75
+ panel.canChooseFiles = mode != FileDialog::Data::OPEN_DIRECTORY;
76
+ panel.canChooseDirectories = mode == FileDialog::Data::OPEN_DIRECTORY;
77
+ panel.allowsMultipleSelection = mode == FileDialog::Data::OPEN_FILES;
78
+
79
+ const StringList& extensions = dialog->extensions();
80
+ if (mode != FileDialog::Data::OPEN_DIRECTORY && !extensions.empty())
81
+ {
82
+ panel.delegate = [[[ReflexOpenSavePanelDelegate alloc]
83
+ initWithExtensions: extensions]
84
+ autorelease];
85
+ }
86
+
87
+ return panel;
88
+ }
89
+
90
+ static NSSavePanel*
91
+ create_save_panel (const char* name)
92
+ {
93
+ NSSavePanel* panel = [NSSavePanel savePanel];
94
+
95
+ if (name && *name)
96
+ panel.nameFieldStringValue = [NSString stringWithUTF8String: name];
97
+
98
+ return panel;
99
+ }
100
+
101
+ void
102
+ FileDialog_show (
103
+ FileDialog* dialog, FileDialog::Data::Mode mode,
104
+ const char* dir, const char* name)
105
+ {
106
+ if (!dialog)
107
+ argument_error(__FILE__, __LINE__);
108
+
109
+ bool save = mode == FileDialog::Data::SAVE_FILE;
110
+ NSSavePanel* panel = save
111
+ ? create_save_panel(name)
112
+ : create_open_panel(dialog, mode);
113
+
114
+ const char* title = dialog->title();
115
+ if (*title)
116
+ panel.message = [NSString stringWithUTF8String: title];
117
+
118
+ if (dir && *dir)
119
+ {
120
+ NSString* nsdir = [NSString stringWithUTF8String: dir];
121
+ panel.directoryURL = [NSURL fileURLWithPath: nsdir isDirectory: YES];
122
+ }
123
+
124
+ FileDialog::Ref dialog_ref = dialog;
125
+ id delegate = panel.delegate;
126
+ void (^completion)(NSModalResponse) = ^(NSModalResponse result)
127
+ {
128
+ (void) delegate;// panel.delegate is weak ref, so capture it here
129
+
130
+ FileDialog* pdialog = const_cast<FileDialog*>(dialog_ref.get());
131
+
132
+ if (result == NSModalResponseOK)
133
+ {
134
+ StringList paths;
135
+ if (save)
136
+ {
137
+ const char* path = panel.URL.path.UTF8String;
138
+ if (path) paths.emplace_back(path);
139
+ }
140
+ else
141
+ {
142
+ for (NSURL* url in ((NSOpenPanel*) panel).URLs)
143
+ {
144
+ const char* path = url.path.UTF8String;
145
+ if (path) paths.emplace_back(path);
146
+ }
147
+ }
148
+
149
+ FileEvent e(save ? FileEvent::SAVE : FileEvent::OPEN, paths);
150
+ FileDialog_call_file_event(pdialog, &e);
151
+ }
152
+ else
153
+ {
154
+ Event e;
155
+ FileDialog_call_cancel_event(pdialog, &e);
156
+ }
157
+ };
158
+
159
+ Window* owner = dialog->owner();
160
+ NSWindow* nswindow = owner ? (NSWindow*) Window_get_data(owner).native : nil;
161
+ if (nswindow)
162
+ [panel beginSheetModalForWindow: nswindow completionHandler: completion];
163
+ else
164
+ [panel beginWithCompletionHandler: completion];
165
+ }
166
+
167
+
168
+ }// Reflex
data/src/osx/gamepad.mm CHANGED
@@ -21,14 +21,14 @@ namespace Reflex
21
21
 
22
22
 
23
23
  void
24
- Gamepad_init (Application* app)
24
+ Gamepad_init_native (Application* app)
25
25
  {
26
26
  init_gc_gamepads(app);
27
27
  init_hid_gamepads(app);
28
28
  }
29
29
 
30
30
  void
31
- Gamepad_fin (Application* app)
31
+ Gamepad_fin_native (Application* app)
32
32
  {
33
33
  fin_gc_gamepads(app);
34
34
  fin_hid_gamepads(app);