shoes 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (275) hide show
  1. data/.gitignore +12 -0
  2. data/CHANGELOG +29 -0
  3. data/COPYING +30 -0
  4. data/README.md +76 -0
  5. data/README.old +117 -0
  6. data/Rakefile +130 -0
  7. data/Rakefile.bk +651 -0
  8. data/app.yaml +7 -0
  9. data/bin/main.skel +104 -0
  10. data/bugs/issue-012e9468ddc7b0cb7e1503413a8a11c4f8707b67.yaml +21 -0
  11. data/bugs/issue-0711ff8b67baa63586f11d0096fee9dd4436bf58.yaml +23 -0
  12. data/bugs/issue-07f87998d93eb401e22395c11085676389b935c4.yaml +22 -0
  13. data/bugs/issue-0bff2d80008803cbc7efbcdacdc60ef2163664d2.yaml +22 -0
  14. data/bugs/issue-0c66f223d19efbca7b692f3b91961f407ad7abec.yaml +24 -0
  15. data/bugs/issue-183bc3c7a8f575aff2b24e0bf22aa0dfcc8e4fc2.yaml +29 -0
  16. data/bugs/issue-1bad1e60a04cb3adb6a8f3ded128af2e16b56ffe.yaml +18 -0
  17. data/bugs/issue-1f1d43f76bf4de79d7f94adbae6dd506a9d81633.yaml +41 -0
  18. data/bugs/issue-320924117cadb045cc91f2a6fca922b4d81d4bb5.yaml +20 -0
  19. data/bugs/issue-33e5c8355fbf65252ea9e939714651df8bd8cb3b.yaml +25 -0
  20. data/bugs/issue-36f7c8262a72bcd5e28cfa4ed29328b8237ea79b.yaml +20 -0
  21. data/bugs/issue-39bf04ee50c3bef67b89b8e9beb28657805587ce.yaml +18 -0
  22. data/bugs/issue-3e28ba7754f73d02ef416eef989af707a8c00f01.yaml +23 -0
  23. data/bugs/issue-3f638cc03f41f9c3fdf217355321f1563f8fee45.yaml +22 -0
  24. data/bugs/issue-41e48e14f1ef4f6deb69be68165d7dd3ffd99156.yaml +22 -0
  25. data/bugs/issue-4c9408166a2aa5dd333bbb05520deebf4ded08e0.yaml +22 -0
  26. data/bugs/issue-55c687e108ecd5aeb8e0d0aeb4294984f84acd3e.yaml +18 -0
  27. data/bugs/issue-5811d34692cc292717a58ec1df1f8948cf30d826.yaml +28 -0
  28. data/bugs/issue-5a7c1f59a0526f9cea7fb366867cf1e6ed8ef69d.yaml +22 -0
  29. data/bugs/issue-688a2c2566bef6a03efa57a4ae1f7cfa8fc74444.yaml +21 -0
  30. data/bugs/issue-78b16c7988ade2ef96e716fa8cb9a004bd4ced65.yaml +33 -0
  31. data/bugs/issue-804ee49f9800154eddf0650690c7a9bb5626253f.yaml +27 -0
  32. data/bugs/issue-807dd1c610b2e941a5d454e26b2eac27e89a0ab4.yaml +22 -0
  33. data/bugs/issue-822ee33ec11ebd25f90ea86e8438de7891e63aee.yaml +18 -0
  34. data/bugs/issue-82ff7152cebb8a1cb065b864cb4fe22de2328146.yaml +29 -0
  35. data/bugs/issue-856afbdcdd4970ad54b8ce4a6c017fbaab45f49d.yaml +31 -0
  36. data/bugs/issue-8d49e32fb21522651c67490adb4d80076dbb14e1.yaml +24 -0
  37. data/bugs/issue-91583359653a9d530c1e32be72d874d847a306e7.yaml +21 -0
  38. data/bugs/issue-af41a5229613172764e7d3c98431172db337053d.yaml +20 -0
  39. data/bugs/issue-bd9856b3788dd429c998a5af1b2aae8221cb80b7.yaml +28 -0
  40. data/bugs/issue-be22aef5c564fb7b5e9938343136a9cd6a2edb7b.yaml +22 -0
  41. data/bugs/issue-bf8697523c77c326e7e35fc82cf3dd739ae92310.yaml +27 -0
  42. data/bugs/issue-cdd4b4795f34d6ff46e56ece10f8216a4a5456b2.yaml +25 -0
  43. data/bugs/issue-d9bfb5581d745ef9deb3b9b2e08ef74d1cd43082.yaml +20 -0
  44. data/bugs/issue-e0ce2f687cc096f35715d28b0af88589f4ab6cc6.yaml +18 -0
  45. data/bugs/issue-e4b0aca4a10a574b333aeaecaaf221dbc5ed22c6.yaml +38 -0
  46. data/bugs/issue-f263746594b95ba778455730478ee8df60ee639d.yaml +22 -0
  47. data/bugs/project.yaml +72 -0
  48. data/builddeps.sh +102 -0
  49. data/fonts/Coolvetica.ttf +0 -0
  50. data/fonts/Lacuna.ttf +0 -0
  51. data/gemlib/shoes.rb +1 -0
  52. data/lib/shoes.rb +548 -0
  53. data/lib/shoes/cache.rb +54 -0
  54. data/lib/shoes/chipmunk.rb +35 -0
  55. data/lib/shoes/data.rb +39 -0
  56. data/lib/shoes/help.rb +468 -0
  57. data/lib/shoes/image.rb +25 -0
  58. data/lib/shoes/inspect.rb +128 -0
  59. data/lib/shoes/log.rb +48 -0
  60. data/lib/shoes/minitar.rb +986 -0
  61. data/lib/shoes/override.rb +38 -0
  62. data/lib/shoes/pack.rb +543 -0
  63. data/lib/shoes/search.rb +46 -0
  64. data/lib/shoes/setup.rb +329 -0
  65. data/lib/shoes/shy.rb +131 -0
  66. data/lib/shoes/shybuilder.rb +44 -0
  67. data/lib/shoes/version.rb +3 -0
  68. data/make/darwin/deps.vlc +12 -0
  69. data/make/darwin/dylibs.shoes +22 -0
  70. data/make/darwin/dylibs.video +11 -0
  71. data/make/darwin/env.rb +81 -0
  72. data/make/darwin/tasks.rb +105 -0
  73. data/make/linux/env.rb +65 -0
  74. data/make/linux/tasks.rb +61 -0
  75. data/make/make.rb +85 -0
  76. data/make/mingw/dlls +19 -0
  77. data/make/mingw/env.rb +69 -0
  78. data/make/mingw/tasks.rb +70 -0
  79. data/make/rakefile_common.rb +8 -0
  80. data/manual-snapshots/class-book.png +0 -0
  81. data/manual-snapshots/expert-definr.png +0 -0
  82. data/manual-snapshots/expert-funnies.png +0 -0
  83. data/manual-snapshots/expert-irb.png +0 -0
  84. data/manual-snapshots/expert-minesweeper.png +0 -0
  85. data/manual-snapshots/expert-othello.png +0 -0
  86. data/manual-snapshots/expert-pong.png +0 -0
  87. data/manual-snapshots/expert-tankspank.png +0 -0
  88. data/manual-snapshots/good-arc.png +0 -0
  89. data/manual-snapshots/good-clock.png +0 -0
  90. data/manual-snapshots/good-follow.png +0 -0
  91. data/manual-snapshots/good-reminder.png +0 -0
  92. data/manual-snapshots/good-vjot.png +0 -0
  93. data/manual-snapshots/simple-accordion.png +0 -0
  94. data/manual-snapshots/simple-anim-shapes.png +0 -0
  95. data/manual-snapshots/simple-anim-text.png +0 -0
  96. data/manual-snapshots/simple-arc.png +0 -0
  97. data/manual-snapshots/simple-bounce.png +0 -0
  98. data/manual-snapshots/simple-calc.png +0 -0
  99. data/manual-snapshots/simple-chipmunk.png +0 -0
  100. data/manual-snapshots/simple-control-sizes.png +0 -0
  101. data/manual-snapshots/simple-curve.png +0 -0
  102. data/manual-snapshots/simple-dialogs.png +0 -0
  103. data/manual-snapshots/simple-downloader.png +0 -0
  104. data/manual-snapshots/simple-draw.png +0 -0
  105. data/manual-snapshots/simple-editor.png +0 -0
  106. data/manual-snapshots/simple-form.png +0 -0
  107. data/manual-snapshots/simple-mask.png +0 -0
  108. data/manual-snapshots/simple-menu.png +0 -0
  109. data/manual-snapshots/simple-menu1.png +0 -0
  110. data/manual-snapshots/simple-rubygems.png +0 -0
  111. data/manual-snapshots/simple-slide.png +0 -0
  112. data/manual-snapshots/simple-sphere.png +0 -0
  113. data/manual-snapshots/simple-sqlite3.png +0 -0
  114. data/manual-snapshots/simple-timer.png +0 -0
  115. data/manual-snapshots/simple-video.png +0 -0
  116. data/platform/mac/Info.plist +55 -0
  117. data/platform/mac/build-deps.sh +658 -0
  118. data/platform/mac/command-manual.rb +1 -0
  119. data/platform/mac/deps-osx.patch +159 -0
  120. data/platform/mac/dmg_ds_store +0 -0
  121. data/platform/mac/pangorc +2 -0
  122. data/platform/mac/pkg-dmg +1447 -0
  123. data/platform/mac/shoes +31 -0
  124. data/platform/mac/shoes-launch +7 -0
  125. data/platform/mac/stub.m +178 -0
  126. data/platform/mac/version.plist +14 -0
  127. data/platform/msw/base.nsi +644 -0
  128. data/platform/msw/installer-1.bmp +0 -0
  129. data/platform/msw/installer-2.bmp +0 -0
  130. data/platform/msw/shoes.exe.manifest +17 -0
  131. data/platform/msw/shoes.ico +0 -0
  132. data/platform/msw/stub-inject.c +59 -0
  133. data/platform/msw/stub.c +271 -0
  134. data/platform/msw/stub32.h +14 -0
  135. data/platform/msw/stub32.rc +16 -0
  136. data/platform/nix/INSTALL +56 -0
  137. data/platform/nix/Makefile +144 -0
  138. data/platform/nix/shoes.launch +20 -0
  139. data/platform/skel.rb +27 -0
  140. data/rakefile_darwin.rb +7 -0
  141. data/rakefile_linux.rb +3 -0
  142. data/rakefile_mingw.rb +7 -0
  143. data/samples/class-book.rb +43 -0
  144. data/samples/class-book.yaml +387 -0
  145. data/samples/expert-definr.rb +23 -0
  146. data/samples/expert-funnies.rb +51 -0
  147. data/samples/expert-irb.rb +112 -0
  148. data/samples/expert-minesweeper.rb +267 -0
  149. data/samples/expert-othello.rb +319 -0
  150. data/samples/expert-pong.rb +62 -0
  151. data/samples/expert-tankspank.rb +385 -0
  152. data/samples/good-arc.rb +37 -0
  153. data/samples/good-clock.rb +51 -0
  154. data/samples/good-follow.rb +26 -0
  155. data/samples/good-reminder.rb +174 -0
  156. data/samples/good-vjot.rb +56 -0
  157. data/samples/simple-accordion.rb +75 -0
  158. data/samples/simple-anim-shapes.rb +17 -0
  159. data/samples/simple-anim-text.rb +13 -0
  160. data/samples/simple-arc.rb +23 -0
  161. data/samples/simple-bounce.rb +24 -0
  162. data/samples/simple-calc.rb +70 -0
  163. data/samples/simple-chipmunk.rb +26 -0
  164. data/samples/simple-control-sizes.rb +24 -0
  165. data/samples/simple-curve.rb +26 -0
  166. data/samples/simple-dialogs.rb +29 -0
  167. data/samples/simple-downloader.rb +27 -0
  168. data/samples/simple-draw.rb +13 -0
  169. data/samples/simple-editor.rb +28 -0
  170. data/samples/simple-form.rb +28 -0
  171. data/samples/simple-form.shy +0 -0
  172. data/samples/simple-mask.rb +21 -0
  173. data/samples/simple-menu.rb +31 -0
  174. data/samples/simple-menu1.rb +35 -0
  175. data/samples/simple-rubygems.rb +29 -0
  176. data/samples/simple-slide.rb +45 -0
  177. data/samples/simple-sphere.rb +28 -0
  178. data/samples/simple-sqlite3.rb +13 -0
  179. data/samples/simple-timer.rb +13 -0
  180. data/samples/simple-video.rb +13 -0
  181. data/shoes.gemspec +21 -0
  182. data/shoes/app.c +591 -0
  183. data/shoes/app.h +110 -0
  184. data/shoes/appwin32.h +13 -0
  185. data/shoes/appwin32.rc +28 -0
  186. data/shoes/canvas.c +2202 -0
  187. data/shoes/canvas.h +682 -0
  188. data/shoes/code.h +14 -0
  189. data/shoes/config.h +232 -0
  190. data/shoes/effects.c +243 -0
  191. data/shoes/effects.h +7 -0
  192. data/shoes/http.h +44 -0
  193. data/shoes/http/common.h +86 -0
  194. data/shoes/http/curl.c +259 -0
  195. data/shoes/http/nsurl.m +274 -0
  196. data/shoes/http/windownload.c +114 -0
  197. data/shoes/http/winhttp.c +216 -0
  198. data/shoes/http/winhttp.h +19 -0
  199. data/shoes/image.c +1020 -0
  200. data/shoes/internal.c +46 -0
  201. data/shoes/internal.h +63 -0
  202. data/shoes/native.h +110 -0
  203. data/shoes/native/cocoa.h +105 -0
  204. data/shoes/native/cocoa.m +1557 -0
  205. data/shoes/native/gtk.c +1257 -0
  206. data/shoes/native/windows.c +2392 -0
  207. data/shoes/ruby.c +5221 -0
  208. data/shoes/ruby.h +299 -0
  209. data/shoes/world.c +243 -0
  210. data/shoes/world.h +63 -0
  211. data/static/Shoes.icns +0 -0
  212. data/static/avatar.png +0 -0
  213. data/static/code_highlighter.js +188 -0
  214. data/static/code_highlighter_ruby.js +26 -0
  215. data/static/icon-debug.png +0 -0
  216. data/static/icon-error.png +0 -0
  217. data/static/icon-info.png +0 -0
  218. data/static/icon-warn.png +0 -0
  219. data/static/listbox_button1.png +0 -0
  220. data/static/listbox_button2.png +0 -0
  221. data/static/man-app.png +0 -0
  222. data/static/man-builds.png +0 -0
  223. data/static/man-builds1.png +0 -0
  224. data/static/man-editor-notepad.png +0 -0
  225. data/static/man-editor-osx.png +0 -0
  226. data/static/man-ele-background.png +0 -0
  227. data/static/man-ele-border.png +0 -0
  228. data/static/man-ele-button.png +0 -0
  229. data/static/man-ele-check.png +0 -0
  230. data/static/man-ele-editbox.png +0 -0
  231. data/static/man-ele-editline.png +0 -0
  232. data/static/man-ele-image.png +0 -0
  233. data/static/man-ele-listbox.png +0 -0
  234. data/static/man-ele-progress.png +0 -0
  235. data/static/man-ele-radio.png +0 -0
  236. data/static/man-ele-shape.png +0 -0
  237. data/static/man-ele-textblock.png +0 -0
  238. data/static/man-ele-video.png +0 -0
  239. data/static/man-intro-dmg.png +0 -0
  240. data/static/man-intro-exe.png +0 -0
  241. data/static/man-look-tiger.png +0 -0
  242. data/static/man-look-ubuntu.png +0 -0
  243. data/static/man-look-vista.png +0 -0
  244. data/static/man-run-osx.png +0 -0
  245. data/static/man-run-vista.png +0 -0
  246. data/static/man-run-xp.png +0 -0
  247. data/static/man-shot1.png +0 -0
  248. data/static/manual-en.txt +3531 -0
  249. data/static/manual-ja.txt +2825 -0
  250. data/static/manual.css +167 -0
  251. data/static/menu-corner1.png +0 -0
  252. data/static/menu-corner2.png +0 -0
  253. data/static/menu-gray.png +0 -0
  254. data/static/menu-left.png +0 -0
  255. data/static/menu-right.png +0 -0
  256. data/static/menu-top.png +0 -0
  257. data/static/shoes-dmg.jpg +0 -0
  258. data/static/shoes-icon-blue.png +0 -0
  259. data/static/shoes-icon.png +0 -0
  260. data/static/shoes-manual-apps.gif +0 -0
  261. data/static/shoes_main_window.png +0 -0
  262. data/static/stripe.png +0 -0
  263. data/static/stubs/blank.exe +0 -0
  264. data/static/stubs/blank.hfz +0 -0
  265. data/static/stubs/blank.run +375 -0
  266. data/static/stubs/cocoa-install +0 -0
  267. data/static/stubs/sh-install +49 -0
  268. data/static/stubs/shoes-stub-inject.exe +0 -0
  269. data/static/stubs/shoes-stub.exe +0 -0
  270. data/static/tutor-back.png +0 -0
  271. data/test/shoes_test.rb +8 -0
  272. data/test/test_helper.rb +25 -0
  273. data/use-deps +12 -0
  274. data/use-tmp-dep +8 -0
  275. metadata +509 -0
@@ -0,0 +1,46 @@
1
+ //
2
+ // shoes/internal.c
3
+ // Internal debug functions.
4
+ //
5
+ #ifdef _MSC_VER
6
+ #include <stdio.h>
7
+ #include <stdarg.h>
8
+ #include <ctype.h>
9
+ #include <windows.h>
10
+
11
+ void odprintf(const char *format, ...)
12
+ {
13
+ char buf[4096], *p = buf;
14
+ va_list args;
15
+ int n;
16
+
17
+ va_start(args, format);
18
+ n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
19
+ va_end(args);
20
+
21
+ p += (n < 0) ? sizeof buf - 3 : n;
22
+
23
+ while(p > buf && isspace(p[-1]))
24
+ *--p = '\0';
25
+
26
+ *p++ = '\r';
27
+ *p++ = '\n';
28
+ *p = '\0';
29
+
30
+ OutputDebugString(buf);
31
+ }
32
+
33
+ int
34
+ shoes_snprintf(char* str, size_t size, const char* format, ...)
35
+ {
36
+ size_t count;
37
+ va_list args;
38
+
39
+ va_start(args, format);
40
+ count = _vscprintf(format, args);
41
+ _vsnprintf(str, size, format, args);
42
+ va_end(args);
43
+
44
+ return count;
45
+ }
46
+ #endif
@@ -0,0 +1,63 @@
1
+ //
2
+ // shoes/internal.h
3
+ // Debugging and allocation functions within Shoes.
4
+ //
5
+
6
+ #ifndef SHOES_INTERNAL_H
7
+ #define SHOES_INTERNAL_H
8
+
9
+ #define SHOE_REALLOC_N(V, T, N) (V)=(T *)realloc((char*)(V), sizeof(T)*(N))
10
+ #define SHOE_ALLOC_N(T, N) (T *)malloc(sizeof(T) * N)
11
+ #define SHOE_ALLOC(T) (T *)malloc(sizeof(T))
12
+ #define SHOE_FREE(T) free((void*)T)
13
+
14
+ #define SHOE_MEMZERO(p,type,n) memset((p), 0, sizeof(type)*(n))
15
+ #define SHOE_MEMCPY(p1,p2,type,n) memcpy((p1), (p2), sizeof(type)*(n))
16
+ #define SHOE_MEMMOVE(p1,p2,type,n) memmove((p1), (p2), sizeof(type)*(n))
17
+ #define SHOE_MEMCMP(p1,p2,type,n) memcmp((p1), (p2), sizeof(type)*(n))
18
+
19
+ #ifndef min
20
+ #define min(a, b) ((a) <= (b) ? (a) : (b))
21
+ #endif
22
+
23
+ #ifndef max
24
+ #define max(a, b) ((a) >= (b) ? (a) : (b))
25
+ #endif
26
+
27
+ #ifdef _MSC_VER
28
+
29
+ void odprintf(const char *format, ...);
30
+ static inline void odignore(const char *format, ...) {}
31
+ int shoes_snprintf(char* str, size_t size, const char* format, ...);
32
+ #define PUTS odprintf
33
+
34
+ #ifdef DEBUG
35
+ #define INFO PUTS
36
+ #else
37
+ #define INFO odignore
38
+ #endif
39
+ #define WARN PUTS
40
+ #define QUIT(msg) \
41
+ if (code == SHOES_OK) code = SHOES_FAIL; \
42
+ PUTS(msg); \
43
+ goto quit
44
+
45
+ #else
46
+
47
+ #define shoes_snprintf snprintf
48
+
49
+ #define PUTS printf
50
+ #ifdef DEBUG
51
+
52
+ #define INFO(f, s...) PUTS(f, ## s)
53
+ #else
54
+ #define INFO(f, s...)
55
+ #endif
56
+ #define WARN(f, s...) PUTS(f, ## s)
57
+ #define QUIT(f, s...) \
58
+ if (code == SHOES_OK) code = SHOES_FAIL; \
59
+ PUTS(f, ## s); \
60
+ goto quit
61
+ #endif
62
+
63
+ #endif
@@ -0,0 +1,110 @@
1
+ //
2
+ // shoes/native.h
3
+ // Common native Shoes routines.
4
+ //
5
+ #define CHANGED_COORDS() \
6
+ (p1->ix != p2->ix || p1->iy != p2->iy || \
7
+ p1->iw != p2->iw || p1->dx != p2->dx || \
8
+ p1->dy != p2->dy || p1->ih - HEIGHT_PAD != p2->ih)
9
+ #define CHANGED_COORDS_NO_PAD() \
10
+ (p1->ix != p2->ix || p1->iy != p2->iy || \
11
+ p1->iw != p2->iw || p1->dx != p2->dx || \
12
+ p1->dy != p2->dy || p1->ih != p2->ih)
13
+ #define PLACE_COORDS() p2->h -= HEIGHT_PAD; p2->ih -= HEIGHT_PAD; *p1 = *p2
14
+ #define PLACE_COORDS_NO_PAD() *p1 = *p2
15
+
16
+ #ifndef SHOES_GTK
17
+ #define SHOES_FORCE_RADIO 1
18
+ #endif
19
+
20
+ #define SHOES_THREAD_DOWNLOAD 41
21
+ #define SHOES_IMAGE_DOWNLOAD 42
22
+ #define SHOES_MAX_MESSAGE 100
23
+
24
+ VALUE shoes_font_list();
25
+ VALUE shoes_load_font(const char *);
26
+ void shoes_native_init();
27
+ void shoes_native_cleanup(shoes_world_t *world);
28
+ void shoes_native_quit();
29
+ int shoes_throw_message(unsigned int, VALUE, void *);
30
+ void shoes_native_slot_mark(SHOES_SLOT_OS *);
31
+ void shoes_native_slot_reset(SHOES_SLOT_OS *);
32
+ void shoes_native_slot_clear(shoes_canvas *);
33
+ void shoes_native_slot_paint(SHOES_SLOT_OS *);
34
+ void shoes_native_slot_lengthen(SHOES_SLOT_OS *, int, int);
35
+ void shoes_native_slot_scroll_top(SHOES_SLOT_OS *);
36
+ int shoes_native_slot_gutter(SHOES_SLOT_OS *);
37
+ void shoes_native_remove_item(SHOES_SLOT_OS *, VALUE, char);
38
+ shoes_code shoes_app_cursor(shoes_app *, ID);
39
+ void shoes_native_app_resized(shoes_app *);
40
+ void shoes_native_app_title(shoes_app *, char *);
41
+ void shoes_native_app_fullscreen(shoes_app *, char);
42
+ shoes_code shoes_native_app_open(shoes_app *, char *, int);
43
+ void shoes_native_app_show(shoes_app *);
44
+ void shoes_native_loop();
45
+ void shoes_native_app_close(shoes_app *);
46
+ void shoes_browser_open(char *);
47
+ void shoes_slot_init(VALUE, SHOES_SLOT_OS *, int, int, int, int, int, int);
48
+ cairo_t *shoes_cairo_create(shoes_canvas *);
49
+ void shoes_slot_destroy(shoes_canvas *, shoes_canvas *);
50
+ void shoes_cairo_destroy(shoes_canvas *);
51
+ void shoes_group_clear(SHOES_GROUP_OS *);
52
+ void shoes_native_canvas_place(shoes_canvas *, shoes_canvas *);
53
+ void shoes_native_canvas_resize(shoes_canvas *);
54
+ void shoes_native_control_hide(SHOES_CONTROL_REF);
55
+ void shoes_native_control_show(SHOES_CONTROL_REF);
56
+ void shoes_native_control_position(SHOES_CONTROL_REF, shoes_place *,
57
+ VALUE, shoes_canvas *, shoes_place *);
58
+ void shoes_native_control_position_no_pad(SHOES_CONTROL_REF, shoes_place *,
59
+ VALUE, shoes_canvas *, shoes_place *);
60
+ void shoes_native_control_repaint(SHOES_CONTROL_REF, shoes_place *,
61
+ shoes_canvas *, shoes_place *);
62
+ void shoes_native_control_repaint_no_pad(SHOES_CONTROL_REF, shoes_place *,
63
+ shoes_canvas *, shoes_place *);
64
+ void shoes_native_control_focus(SHOES_CONTROL_REF);
65
+ void shoes_native_control_state(SHOES_CONTROL_REF, SHOES_BOOL, SHOES_BOOL);
66
+ void shoes_native_control_remove(SHOES_CONTROL_REF, shoes_canvas *);
67
+ void shoes_native_control_free(SHOES_CONTROL_REF);
68
+ SHOES_SURFACE_REF shoes_native_surface_new(shoes_canvas *, VALUE, shoes_place *);
69
+ void shoes_native_surface_position(SHOES_SURFACE_REF, shoes_place *,
70
+ VALUE, shoes_canvas *, shoes_place *);
71
+ void shoes_native_surface_hide(SHOES_SURFACE_REF);
72
+ void shoes_native_surface_show(SHOES_SURFACE_REF);
73
+ void shoes_native_surface_remove(shoes_canvas *, SHOES_SURFACE_REF);
74
+ SHOES_CONTROL_REF shoes_native_button(VALUE, shoes_canvas *, shoes_place *, char *);
75
+ SHOES_CONTROL_REF shoes_native_edit_line(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
76
+ VALUE shoes_native_edit_line_get_text(SHOES_CONTROL_REF);
77
+ void shoes_native_edit_line_set_text(SHOES_CONTROL_REF, char *);
78
+ SHOES_CONTROL_REF shoes_native_edit_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
79
+ VALUE shoes_native_edit_box_get_text(SHOES_CONTROL_REF);
80
+ void shoes_native_edit_box_set_text(SHOES_CONTROL_REF, char *);
81
+ SHOES_CONTROL_REF shoes_native_list_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
82
+ void shoes_native_list_box_update(SHOES_CONTROL_REF, VALUE);
83
+ VALUE shoes_native_list_box_get_active(SHOES_CONTROL_REF, VALUE);
84
+ SHOES_CONTROL_REF shoes_native_progress(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
85
+ double shoes_native_progress_get_fraction(SHOES_CONTROL_REF);
86
+ void shoes_native_progress_set_fraction(SHOES_CONTROL_REF, double);
87
+ SHOES_CONTROL_REF shoes_native_slider(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
88
+ double shoes_native_slider_get_fraction(SHOES_CONTROL_REF);
89
+ void shoes_native_slider_set_fraction(SHOES_CONTROL_REF, double);
90
+ SHOES_CONTROL_REF shoes_native_check(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
91
+ VALUE shoes_native_check_get(SHOES_CONTROL_REF);
92
+ void shoes_native_check_set(SHOES_CONTROL_REF, int);
93
+ void shoes_native_list_box_set_active(SHOES_CONTROL_REF, VALUE, VALUE);
94
+ SHOES_CONTROL_REF shoes_native_radio(VALUE, shoes_canvas *, shoes_place *, VALUE, VALUE);
95
+ void shoes_native_timer_remove(shoes_canvas *, SHOES_TIMER_REF);
96
+ SHOES_TIMER_REF shoes_native_timer_start(VALUE, shoes_canvas *, unsigned int);
97
+ VALUE shoes_native_clipboard_get(shoes_app *);
98
+ void shoes_native_clipboard_set(shoes_app *, VALUE);
99
+ VALUE shoes_native_to_s(VALUE);
100
+ char *shoes_native_to_utf8(VALUE, int *);
101
+ VALUE shoes_native_window_color(shoes_app *);
102
+ VALUE shoes_native_dialog_color(shoes_app *);
103
+ VALUE shoes_dialog_alert(VALUE, VALUE);
104
+ VALUE shoes_dialog_ask(int argc, VALUE *argv, VALUE self);
105
+ VALUE shoes_dialog_confirm(VALUE, VALUE);
106
+ VALUE shoes_dialog_color(VALUE, VALUE);
107
+ VALUE shoes_dialog_open(int,VALUE*,VALUE);
108
+ VALUE shoes_dialog_save(int,VALUE*,VALUE);
109
+ VALUE shoes_dialog_open_folder(int,VALUE*,VALUE);
110
+ VALUE shoes_dialog_save_folder(int,VALUE*,VALUE);
@@ -0,0 +1,105 @@
1
+ //
2
+ // shoes/native/cocoa.h
3
+ // Custom Cocoa interfaces for Shoes
4
+ //
5
+ #import <Cocoa/Cocoa.h>
6
+
7
+ @interface ShoesEvents : NSObject
8
+ {
9
+ int count;
10
+ }
11
+ @end
12
+
13
+ @interface ShoesWindow : NSWindow
14
+ {
15
+ VALUE app;
16
+ }
17
+ @end
18
+
19
+ @interface ShoesView : NSView
20
+ {
21
+ VALUE canvas;
22
+ }
23
+ @end
24
+
25
+ @interface ShoesButton : NSButton
26
+ {
27
+ VALUE object;
28
+ }
29
+ @end
30
+
31
+ @interface ShoesTextField : NSTextField
32
+ {
33
+ VALUE object;
34
+ }
35
+ @end
36
+
37
+ @interface ShoesSecureTextField : NSSecureTextField
38
+ {
39
+ VALUE object;
40
+ }
41
+ @end
42
+
43
+ @interface ShoesTextView : NSScrollView
44
+ {
45
+ VALUE object;
46
+ NSTextView *textView;
47
+ }
48
+ @end
49
+
50
+ @interface ShoesPopUpButton : NSPopUpButton
51
+ {
52
+ VALUE object;
53
+ }
54
+ @end
55
+
56
+ @interface ShoesSlider : NSSlider
57
+ {
58
+ VALUE object;
59
+ }
60
+ @end
61
+
62
+ @interface ShoesAlert : NSWindow
63
+ {
64
+ NSWindow *win;
65
+ BOOL answer;
66
+ }
67
+ @end
68
+
69
+ @interface ShoesTimer : NSObject
70
+ {
71
+ VALUE object;
72
+ NSTimer *timer;
73
+ }
74
+ @end
75
+
76
+ #define VK_ESCAPE 53
77
+ #define VK_DELETE 117
78
+ #define VK_INSERT 114
79
+ #define VK_TAB 48
80
+ #define VK_BS 51
81
+ #define VK_PRIOR 116
82
+ #define VK_NEXT 121
83
+ #define VK_HOME 115
84
+ #define VK_END 119
85
+ #define VK_LEFT 123
86
+ #define VK_UP 126
87
+ #define VK_RIGHT 124
88
+ #define VK_DOWN 125
89
+ #define VK_F1 122
90
+ #define VK_F2 120
91
+ #define VK_F3 99
92
+ #define VK_F4 118
93
+ #define VK_F5 96
94
+ #define VK_F6 97
95
+ #define VK_F7 98
96
+ #define VK_F8 100
97
+ #define VK_F9 101
98
+ #define VK_F10 109
99
+ #define VK_F11 103
100
+ #define VK_F12 111
101
+
102
+ #define KEY_SYM(name, sym) \
103
+ if (key == VK_##name) \
104
+ v = ID2SYM(rb_intern("" # sym)); \
105
+ else
@@ -0,0 +1,1557 @@
1
+ //
2
+ // shoes/native-cocoa.m
3
+ // ObjC Cocoa-specific code for Shoes.
4
+ //
5
+ #include "shoes/app.h"
6
+ #include "shoes/ruby.h"
7
+ #include "shoes/config.h"
8
+ #include "shoes/world.h"
9
+ #include "shoes/native.h"
10
+ #include "shoes/internal.h"
11
+
12
+ #define HEIGHT_PAD 6
13
+
14
+ #define INIT NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
15
+ #define RELEASE [pool release]
16
+ #define COCOA_DO(statements) do {\
17
+ INIT; \
18
+ @try { statements; } \
19
+ @catch (NSException *e) { ; } \
20
+ RELEASE; \
21
+ } while (0)
22
+
23
+ @implementation ShoesEvents
24
+ - (id)init
25
+ {
26
+ if ((self = [super init]))
27
+ count = 0;
28
+ return self;
29
+ }
30
+ - (void)idle: (NSTimer *)t
31
+ {
32
+ if (count < 100)
33
+ {
34
+ count++;
35
+ if (count == 100 && RARRAY_LEN(shoes_world->apps) == 0)
36
+ rb_eval_string("Shoes.splash");
37
+ }
38
+ rb_eval_string("sleep(0.001)");
39
+ }
40
+ - (BOOL) application: (NSApplication *) anApplication
41
+ openFile: (NSString *) aFileName
42
+ {
43
+ shoes_load([aFileName UTF8String]);
44
+
45
+ return YES;
46
+ }
47
+ - (void)openFile: (id)sender
48
+ {
49
+ rb_eval_string("Shoes.show_selector");
50
+ }
51
+ - (void)package: (id)sender
52
+ {
53
+ rb_eval_string("Shoes.make_pack");
54
+ }
55
+ - (void)showLog: (id)sender
56
+ {
57
+ rb_eval_string("Shoes.show_log");
58
+ }
59
+ - (void)emulateKey: (NSString *)key modifierFlags: (unsigned int)flags withoutModifiers: (NSString *)key2
60
+ {
61
+ ShoesWindow *win = [NSApp keyWindow];
62
+ [win keyDown: [NSEvent keyEventWithType:NSKeyDown
63
+ location:NSMakePoint(0,0) modifierFlags:flags
64
+ timestamp:0 windowNumber:0 context:nil
65
+ characters:key charactersIgnoringModifiers:key2 isARepeat:NO
66
+ keyCode:0]];
67
+ }
68
+ - (void)help: (id)sender
69
+ {
70
+ rb_eval_string("Shoes.show_manual");
71
+ }
72
+ - (void)undo: (id)sender
73
+ {
74
+ [self emulateKey: @"z" modifierFlags: NSCommandKeyMask withoutModifiers: @"z"];
75
+ }
76
+ - (void)redo: (id)sender
77
+ {
78
+ [self emulateKey: @"Z" modifierFlags: NSCommandKeyMask|NSShiftKeyMask withoutModifiers: @"z"];
79
+ }
80
+ - (void)cut: (id)sender
81
+ {
82
+ [self emulateKey: @"x" modifierFlags: NSCommandKeyMask withoutModifiers: @"x"];
83
+ }
84
+ - (void)copy: (id)sender
85
+ {
86
+ [self emulateKey: @"c" modifierFlags: NSCommandKeyMask withoutModifiers: @"c"];
87
+ }
88
+ - (void)paste: (id)sender
89
+ {
90
+ [self emulateKey: @"v" modifierFlags: NSCommandKeyMask withoutModifiers: @"v"];
91
+ }
92
+ - (void)selectAll: (id)sender
93
+ {
94
+ [self emulateKey: @"a" modifierFlags: NSCommandKeyMask withoutModifiers: @"a"];
95
+ }
96
+ @end
97
+
98
+ @implementation ShoesWindow
99
+ - (void)prepareWithApp: (VALUE)a
100
+ {
101
+ app = a;
102
+ [self center];
103
+ [self makeKeyAndOrderFront: self];
104
+ [self setAcceptsMouseMovedEvents: YES];
105
+ [self setDelegate: self];
106
+ }
107
+ - (void)disconnectApp
108
+ {
109
+ app = Qnil;
110
+ }
111
+ - (void)sendMotion: (NSEvent *)e ofType: (ID)type withButton: (int)b
112
+ {
113
+ shoes_app *a;
114
+ shoes_canvas *canvas;
115
+ NSPoint p = [e locationInWindow];
116
+ Data_Get_Struct(app, shoes_app, a);
117
+ Data_Get_Struct(a->canvas, shoes_canvas, canvas);
118
+ if (type == s_motion)
119
+ shoes_app_motion(a, p.x, (canvas->height - p.y) + canvas->slot->scrolly);
120
+ else if (type == s_click)
121
+ shoes_app_click(a, b, p.x, (canvas->height - p.y) + canvas->slot->scrolly);
122
+ else if (type == s_release)
123
+ shoes_app_release(a, b, p.x, (canvas->height - p.y) + canvas->slot->scrolly);
124
+ }
125
+ - (void)mouseDown: (NSEvent *)e
126
+ {
127
+ [self sendMotion: e ofType: s_click withButton: 1];
128
+ }
129
+ - (void)rightMouseDown: (NSEvent *)e
130
+ {
131
+ [self sendMotion: e ofType: s_click withButton: 2];
132
+ }
133
+ - (void)otherMouseDown: (NSEvent *)e
134
+ {
135
+ [self sendMotion: e ofType: s_click withButton: 3];
136
+ }
137
+ - (void)mouseUp: (NSEvent *)e
138
+ {
139
+ [self sendMotion: e ofType: s_release withButton: 1];
140
+ }
141
+ - (void)rightMouseUp: (NSEvent *)e
142
+ {
143
+ [self sendMotion: e ofType: s_release withButton: 2];
144
+ }
145
+ - (void)otherMouseUp: (NSEvent *)e
146
+ {
147
+ [self sendMotion: e ofType: s_release withButton: 3];
148
+ }
149
+ - (void)mouseMoved: (NSEvent *)e
150
+ {
151
+ [self sendMotion: e ofType: s_motion withButton: 0];
152
+ }
153
+ - (void)mouseDragged: (NSEvent *)e
154
+ {
155
+ [self sendMotion: e ofType: s_motion withButton: 0];
156
+ }
157
+ - (void)rightMouseDragged: (NSEvent *)e
158
+ {
159
+ [self sendMotion: e ofType: s_motion withButton: 0];
160
+ }
161
+ - (void)otherMouseDragged: (NSEvent *)e
162
+ {
163
+ [self sendMotion: e ofType: s_motion withButton: 0];
164
+ }
165
+ - (void)scrollWheel: (NSEvent *)e
166
+ {
167
+ ID wheel;
168
+ float dy = [e deltaY];
169
+ NSPoint p = [e locationInWindow];
170
+ shoes_app *a;
171
+
172
+ if (dy == 0)
173
+ return;
174
+ else if (dy > 0)
175
+ wheel = s_up;
176
+ else
177
+ {
178
+ wheel = s_down;
179
+ dy = -dy;
180
+ }
181
+
182
+ Data_Get_Struct(app, shoes_app, a);
183
+ for (; dy > 0.; dy--)
184
+ shoes_app_wheel(a, wheel, p.x, p.y);
185
+ }
186
+ - (void)keyDown: (NSEvent *)e
187
+ {
188
+ shoes_app *a;
189
+ VALUE v = Qnil;
190
+ unsigned int modifier = [e modifierFlags];
191
+ unsigned short key = [e keyCode];
192
+ INIT;
193
+
194
+ Data_Get_Struct(app, shoes_app, a);
195
+ KEY_SYM(ESCAPE, escape)
196
+ KEY_SYM(INSERT, insert)
197
+ KEY_SYM(DELETE, delete)
198
+ KEY_SYM(TAB, tab)
199
+ KEY_SYM(BS, backspace)
200
+ KEY_SYM(PRIOR, page_up)
201
+ KEY_SYM(NEXT, page_down)
202
+ KEY_SYM(HOME, home)
203
+ KEY_SYM(END, end)
204
+ KEY_SYM(LEFT, left)
205
+ KEY_SYM(UP, up)
206
+ KEY_SYM(RIGHT, right)
207
+ KEY_SYM(DOWN, down)
208
+ KEY_SYM(F1, f1)
209
+ KEY_SYM(F2, f2)
210
+ KEY_SYM(F3, f3)
211
+ KEY_SYM(F4, f4)
212
+ KEY_SYM(F5, f5)
213
+ KEY_SYM(F6, f6)
214
+ KEY_SYM(F7, f7)
215
+ KEY_SYM(F8, f8)
216
+ KEY_SYM(F9, f9)
217
+ KEY_SYM(F10, f10)
218
+ KEY_SYM(F11, f11)
219
+ KEY_SYM(F12, f12)
220
+ {
221
+ NSString *str = [e charactersIgnoringModifiers];
222
+ if (str)
223
+ {
224
+ char *utf8 = [str UTF8String];
225
+ if (utf8[0] == '\r' && [str length] == 1)
226
+ v = rb_str_new2("\n");
227
+ else
228
+ v = rb_str_new2(utf8);
229
+ }
230
+ }
231
+
232
+ if (SYMBOL_P(v))
233
+ {
234
+ if ((modifier & NSCommandKeyMask) || (modifier & NSAlternateKeyMask))
235
+ KEY_STATE(alt);
236
+ if (modifier & NSShiftKeyMask)
237
+ KEY_STATE(shift);
238
+ if (modifier & NSControlKeyMask)
239
+ KEY_STATE(control);
240
+ }
241
+ else
242
+ {
243
+ if ((modifier & NSCommandKeyMask) || (modifier & NSAlternateKeyMask))
244
+ KEY_STATE(alt);
245
+ }
246
+
247
+ if (v != Qnil)
248
+ shoes_app_keypress(a, v);
249
+ RELEASE;
250
+ }
251
+ - (BOOL)canBecomeKeyWindow
252
+ {
253
+ return YES;
254
+ }
255
+ - (BOOL)canBecomeMainWindow
256
+ {
257
+ return YES;
258
+ }
259
+ - (void)windowWillClose: (NSNotification *)n
260
+ {
261
+ if (!NIL_P(app)) {
262
+ shoes_app *a;
263
+ Data_Get_Struct(app, shoes_app, a);
264
+ shoes_app_remove(a);
265
+ }
266
+ }
267
+ @end
268
+
269
+ @implementation ShoesView
270
+ - (id)initWithFrame: (NSRect)frame andCanvas: (VALUE)c
271
+ {
272
+ if ((self = [super initWithFrame: frame]))
273
+ {
274
+ canvas = c;
275
+ }
276
+ return self;
277
+ }
278
+ - (BOOL)isFlipped
279
+ {
280
+ return YES;
281
+ }
282
+ - (void)drawRect: (NSRect)rect
283
+ {
284
+ shoes_canvas *c;
285
+ NSRect bounds = [self bounds];
286
+ Data_Get_Struct(canvas, shoes_canvas, c);
287
+
288
+ c->width = bounds.size.width;
289
+ c->height = bounds.size.height;
290
+ if (c->slot->vscroll)
291
+ {
292
+ [c->slot->vscroll setFrame: NSMakeRect(c->width - [NSScroller scrollerWidth], 0,
293
+ [NSScroller scrollerWidth], c->height)];
294
+ shoes_native_slot_lengthen(c->slot, c->height, c->endy);
295
+ }
296
+ c->place.iw = c->place.w = c->width;
297
+ c->place.ih = c->place.h = c->height;
298
+ c->slot->context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
299
+ shoes_canvas_paint(canvas);
300
+ }
301
+ - (void)scroll: (NSScroller *)scroller
302
+ {
303
+ shoes_canvas *c;
304
+ Data_Get_Struct(canvas, shoes_canvas, c);
305
+
306
+ switch ([scroller hitPart])
307
+ {
308
+ case NSScrollerIncrementLine:
309
+ shoes_slot_scroll_to(c, 16, 1);
310
+ break;
311
+ case NSScrollerDecrementLine:
312
+ shoes_slot_scroll_to(c, -16, 1);
313
+ break;
314
+ case NSScrollerIncrementPage:
315
+ shoes_slot_scroll_to(c, c->height - 32, 1);
316
+ break;
317
+ case NSScrollerDecrementPage:
318
+ shoes_slot_scroll_to(c, -(c->height - 32), 1);
319
+ break;
320
+ case NSScrollerKnobSlot:
321
+ case NSScrollerKnob:
322
+ default:
323
+ shoes_slot_scroll_to(c, (c->endy - c->height) * [scroller floatValue], 0);
324
+ break;
325
+ }
326
+ }
327
+ @end
328
+
329
+ @implementation ShoesButton
330
+ - (id)initWithType: (NSButtonType)t andObject: (VALUE)o
331
+ {
332
+ if ((self = [super init]))
333
+ {
334
+ object = o;
335
+ [self setButtonType: t];
336
+ [self setBezelStyle: NSRoundedBezelStyle];
337
+ [self setTarget: self];
338
+ [self setAction: @selector(handleClick:)];
339
+ }
340
+ return self;
341
+ }
342
+ -(IBAction)handleClick: (id)sender
343
+ {
344
+ shoes_button_send_click(object);
345
+ }
346
+ @end
347
+
348
+ @implementation ShoesTextField
349
+ - (id)initWithFrame: (NSRect)frame andObject: (VALUE)o
350
+ {
351
+ if ((self = [super initWithFrame: frame]))
352
+ {
353
+ object = o;
354
+ [self setBezelStyle: NSRegularSquareBezelStyle];
355
+ [self setDelegate: self];
356
+ }
357
+ return self;
358
+ }
359
+ -(void)textDidChange: (NSNotification *)n
360
+ {
361
+ shoes_control_send(object, s_change);
362
+ }
363
+ @end
364
+
365
+ @implementation ShoesSecureTextField
366
+ - (id)initWithFrame: (NSRect)frame andObject: (VALUE)o
367
+ {
368
+ if ((self = [super initWithFrame: frame]))
369
+ {
370
+ object = o;
371
+ [self setBezelStyle: NSRegularSquareBezelStyle];
372
+ [self setDelegate: self];
373
+ }
374
+ return self;
375
+ }
376
+ -(void)textDidChange: (NSNotification *)n
377
+ {
378
+ shoes_control_send(object, s_change);
379
+ }
380
+ @end
381
+
382
+ @implementation ShoesTextView
383
+ - (id)initWithFrame: (NSRect)frame andObject: (VALUE)o
384
+ {
385
+ if ((self = [super initWithFrame: frame]))
386
+ {
387
+ object = o;
388
+ textView = [[NSTextView alloc] initWithFrame:
389
+ NSMakeRect(0, 0, frame.size.width, frame.size.height)];
390
+ [textView setVerticallyResizable: YES];
391
+ [textView setHorizontallyResizable: YES];
392
+
393
+ [self setBorderType: NSBezelBorder];
394
+ [self setHasVerticalScroller: YES];
395
+ [self setHasHorizontalScroller: NO];
396
+ [self setDocumentView: textView];
397
+ [textView setDelegate: self];
398
+ }
399
+ return self;
400
+ }
401
+ -(NSTextStorage *)textStorage
402
+ {
403
+ return [textView textStorage];
404
+ }
405
+ -(void)textDidChange: (NSNotification *)n
406
+ {
407
+ shoes_control_send(object, s_change);
408
+ }
409
+ @end
410
+
411
+ @implementation ShoesPopUpButton
412
+ - (id)initWithFrame: (NSRect)frame andObject: (VALUE)o
413
+ {
414
+ if ((self = [super initWithFrame: frame pullsDown: NO]))
415
+ {
416
+ object = o;
417
+ [self setTarget: self];
418
+ [self setAction: @selector(handleChange:)];
419
+ }
420
+ return self;
421
+ }
422
+ -(IBAction)handleChange: (id)sender
423
+ {
424
+ shoes_control_send(object, s_change);
425
+ }
426
+ @end
427
+
428
+ @implementation ShoesSlider
429
+ - (id)initWithObject: (VALUE)o
430
+ {
431
+ if ((self = [super init]))
432
+ {
433
+ object = o;
434
+ [self setTarget: self];
435
+ [self setAction: @selector(handleChange:)];
436
+ }
437
+ return self;
438
+ }
439
+ -(IBAction)handleChange: (id)sender
440
+ {
441
+ shoes_control_send(object, s_change);
442
+ }
443
+ @end
444
+
445
+ @implementation ShoesAlert
446
+ - (id)init
447
+ {
448
+ if ((self = [super initWithContentRect: NSMakeRect(0, 0, 340, 140)
449
+ styleMask: NSTitledWindowMask backing: NSBackingStoreBuffered defer: NO]))
450
+ {
451
+ answer = FALSE;
452
+ [self setDelegate: self];
453
+ }
454
+ return self;
455
+ }
456
+ -(IBAction)cancelClick: (id)sender
457
+ {
458
+ [[NSApplication sharedApplication] stopModal];
459
+ }
460
+ -(IBAction)okClick: (id)sender
461
+ {
462
+ answer = TRUE;
463
+ [[NSApplication sharedApplication] stopModal];
464
+ }
465
+ - (void)windowWillClose: (NSNotification *)n
466
+ {
467
+ [[NSApplication sharedApplication] stopModal];
468
+ }
469
+ - (BOOL)accepted
470
+ {
471
+ return answer;
472
+ }
473
+ @end
474
+
475
+ @implementation ShoesTimer
476
+ - (id)initWithTimeInterval: (NSTimeInterval)i andObject: (VALUE)o repeats: (BOOL)r
477
+ {
478
+ if ((self = [super init]))
479
+ {
480
+ object = o;
481
+ timer = [NSTimer scheduledTimerWithTimeInterval: i
482
+ target: self selector: @selector(animate:) userInfo: self
483
+ repeats: r];
484
+ }
485
+ return self;
486
+ }
487
+ - (void)animate: (NSTimer *)t
488
+ {
489
+ shoes_timer_call(object);
490
+ }
491
+ - (void)invalidate
492
+ {
493
+ [timer invalidate];
494
+ }
495
+ @end
496
+
497
+ void
498
+ add_to_menubar(NSMenu *main, NSMenu *menu)
499
+ {
500
+ NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@""
501
+ action:nil keyEquivalent:@""];
502
+ [dummyItem setSubmenu:menu];
503
+ [main addItem:dummyItem];
504
+ [dummyItem release];
505
+ }
506
+
507
+ void
508
+ create_apple_menu(NSMenu *main)
509
+ {
510
+ NSMenuItem *menuitem;
511
+ // Create the application (Apple) menu.
512
+ NSMenu *menuApp = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
513
+
514
+ NSMenu *menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
515
+ [NSApp setServicesMenu:menuServices];
516
+
517
+ menuitem = [menuApp addItemWithTitle:@"Open..."
518
+ action:@selector(openFile:) keyEquivalent:@"o"];
519
+ [menuitem setTarget: shoes_world->os.events];
520
+ menuitem = [menuApp addItemWithTitle:@"Package..."
521
+ action:@selector(package:) keyEquivalent:@"P"];
522
+ [menuitem setTarget: shoes_world->os.events];
523
+ [menuApp addItemWithTitle:@"Preferences..." action:nil keyEquivalent:@""];
524
+ [menuApp addItem: [NSMenuItem separatorItem]];
525
+ menuitem = [[NSMenuItem alloc] initWithTitle: @"Services"
526
+ action:nil keyEquivalent:@""];
527
+ [menuitem setSubmenu:menuServices];
528
+ [menuApp addItem: menuitem];
529
+ [menuitem release];
530
+ [menuApp addItem: [NSMenuItem separatorItem]];
531
+ menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide"
532
+ action:@selector(hide:) keyEquivalent:@""];
533
+ [menuitem setTarget: NSApp];
534
+ [menuApp addItem: menuitem];
535
+ [menuitem release];
536
+ menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others"
537
+ action:@selector(hideOtherApplications:) keyEquivalent:@""];
538
+ [menuitem setTarget: NSApp];
539
+ [menuApp addItem: menuitem];
540
+ [menuitem release];
541
+ menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All"
542
+ action:@selector(unhideAllApplications:) keyEquivalent:@""];
543
+ [menuitem setTarget: NSApp];
544
+ [menuApp addItem: menuitem];
545
+ [menuitem release];
546
+ [menuApp addItem: [NSMenuItem separatorItem]];
547
+ menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit"
548
+ action:@selector(terminate:) keyEquivalent:@"q"];
549
+ [menuitem setTarget: NSApp];
550
+ [menuApp addItem: menuitem];
551
+ [menuitem release];
552
+
553
+ [NSApp setAppleMenu:menuApp];
554
+ add_to_menubar(main, menuApp);
555
+ [menuApp release];
556
+ }
557
+
558
+ void
559
+ create_edit_menu(NSMenu *main)
560
+ {
561
+ NSMenuItem *menuitem;
562
+ NSMenu *menuEdit = [[NSMenu alloc] initWithTitle: @"Edit"];
563
+
564
+ menuitem = [menuEdit addItemWithTitle:@"Undo"
565
+ action:@selector(undo:) keyEquivalent:@"z"];
566
+ [menuitem setTarget: shoes_world->os.events];
567
+ menuitem = [menuEdit addItemWithTitle:@"Redo"
568
+ action:@selector(redo:) keyEquivalent:@"Z"];
569
+ [menuitem setTarget: shoes_world->os.events];
570
+ [menuEdit addItem: [NSMenuItem separatorItem]];
571
+ menuitem = [menuEdit addItemWithTitle:@"Cut"
572
+ action:@selector(cut:) keyEquivalent:@"x"];
573
+ [menuitem setTarget: shoes_world->os.events];
574
+ menuitem = [menuEdit addItemWithTitle:@"Copy"
575
+ action:@selector(copy:) keyEquivalent:@"c"];
576
+ [menuitem setTarget: shoes_world->os.events];
577
+ menuitem = [menuEdit addItemWithTitle:@"Paste"
578
+ action:@selector(paste:) keyEquivalent:@"v"];
579
+ [menuitem setTarget: shoes_world->os.events];
580
+ menuitem = [menuEdit addItemWithTitle:@"Select All"
581
+ action:@selector(selectAll:) keyEquivalent:@"a"];
582
+ [menuitem setTarget: shoes_world->os.events];
583
+ add_to_menubar(main, menuEdit);
584
+ [menuEdit release];
585
+ }
586
+
587
+ void
588
+ create_window_menu(NSMenu *main)
589
+ {
590
+ NSMenu *menuWindows = [[NSMenu alloc] initWithTitle: @"Window"];
591
+
592
+ [menuWindows addItemWithTitle:@"Minimize"
593
+ action:@selector(performMiniaturize:) keyEquivalent:@""];
594
+ [menuWindows addItemWithTitle:@"Close current Window"
595
+ action:@selector(performClose:) keyEquivalent:@"w"];
596
+ [menuWindows addItem: [NSMenuItem separatorItem]];
597
+ [menuWindows addItemWithTitle:@"Bring All to Front"
598
+ action:@selector(arrangeInFront:) keyEquivalent:@""];
599
+
600
+ [NSApp setWindowsMenu:menuWindows];
601
+ add_to_menubar(main, menuWindows);
602
+ [menuWindows release];
603
+ }
604
+
605
+ void
606
+ create_help_menu(NSMenu *main)
607
+ {
608
+ NSMenuItem *menuitem;
609
+ NSMenu *menuHelp = [[NSMenu alloc] initWithTitle: @"Help"];
610
+ menuitem = [menuHelp addItemWithTitle:@"Console"
611
+ action:@selector(showLog:) keyEquivalent:@"/"];
612
+ [menuitem setTarget: shoes_world->os.events];
613
+ [menuHelp addItem: [NSMenuItem separatorItem]];
614
+ menuitem = [menuHelp addItemWithTitle:@"Manual"
615
+ action:@selector(help:) keyEquivalent:@"m"];
616
+ [menuitem setTarget: shoes_world->os.events];
617
+ add_to_menubar(main, menuHelp);
618
+ [menuHelp release];
619
+ }
620
+
621
+ VALUE
622
+ shoes_font_list()
623
+ {
624
+ INIT;
625
+ ATSFontIterator fi = NULL;
626
+ ATSFontRef fontRef = 0;
627
+ NSMutableArray *outArray;
628
+ VALUE ary = rb_ary_new();
629
+ if (noErr == ATSFontIteratorCreate(kATSFontContextLocal, nil, nil,
630
+ kATSOptionFlagsUnRestrictedScope, &fi))
631
+ {
632
+ while (noErr == ATSFontIteratorNext(fi, &fontRef))
633
+ {
634
+ NSString *fontName;
635
+ ATSFontGetName(fontRef, kATSOptionFlagsDefault, &fontName);
636
+ if (fontName != NULL)
637
+ rb_ary_push(ary, rb_str_new2([fontName UTF8String]));
638
+ }
639
+ }
640
+
641
+ ATSFontIteratorRelease(&fi);
642
+ RELEASE;
643
+ rb_funcall(ary, rb_intern("uniq!"), 0);
644
+ rb_funcall(ary, rb_intern("sort!"), 0);
645
+ return ary;
646
+ }
647
+
648
+ VALUE
649
+ shoes_load_font(const char *filename)
650
+ {
651
+ FSRef fsRef;
652
+ FSSpec fsSpec;
653
+ Boolean isDir;
654
+ VALUE families = Qnil;
655
+ ATSFontContainerRef ref;
656
+ NSString *fontName;
657
+ FSPathMakeRef(filename, &fsRef, &isDir);
658
+ if (FSGetCatalogInfo(&fsRef, kFSCatInfoNone, NULL, NULL, &fsSpec, NULL) == noErr)
659
+ {
660
+ ATSFontActivateFromFileReference(&fsRef, kATSFontContextLocal, kATSFontFormatUnspecified,
661
+ NULL, kATSOptionFlagsDefault, &ref);
662
+ if (ref != NULL)
663
+ {
664
+ int i = 0;
665
+ ItemCount count = 0;
666
+ ATSFontRef *fonts;
667
+ ATSFontFindFromContainer(ref, kATSOptionFlagsDefault, 0, NULL, &count);
668
+ families = rb_ary_new();
669
+ if (count > 0)
670
+ {
671
+ fonts = SHOE_ALLOC_N(ATSFontRef, count);
672
+ ATSFontFindFromContainer(ref, kATSOptionFlagsDefault, count, fonts, &count);
673
+ for (i = 0; i < count; i++)
674
+ {
675
+ fontName = NULL;
676
+ ATSFontGetName(fonts[i], kATSOptionFlagsDefault, &fontName);
677
+ if (fontName != NULL)
678
+ rb_ary_push(families, rb_str_new2([fontName UTF8String]));
679
+ }
680
+ SHOE_FREE(fonts);
681
+ }
682
+ }
683
+ }
684
+
685
+ shoes_update_fonts(shoes_font_list());
686
+ return families;
687
+ }
688
+
689
+ void shoes_native_init()
690
+ {
691
+ INIT;
692
+ NSTimer *idle;
693
+ NSApplication *NSApp = [NSApplication sharedApplication];
694
+ NSMenu *main = [[NSMenu alloc] initWithTitle: @""];
695
+ shoes_world->os.events = [[ShoesEvents alloc] init];
696
+ [NSApp setMainMenu: main];
697
+ create_apple_menu(main);
698
+ create_edit_menu(main);
699
+ create_window_menu(main);
700
+ create_help_menu(main);
701
+ [NSApp setDelegate: shoes_world->os.events];
702
+
703
+ idle = [NSTimer scheduledTimerWithTimeInterval: 0.01
704
+ target: shoes_world->os.events selector: @selector(idle:) userInfo: nil
705
+ repeats: YES];
706
+ [[NSRunLoop currentRunLoop] addTimer: idle forMode: NSEventTrackingRunLoopMode];
707
+ RELEASE;
708
+ }
709
+
710
+ void shoes_native_cleanup(shoes_world_t *world)
711
+ {
712
+ INIT;
713
+ [shoes_world->os.events release];
714
+ RELEASE;
715
+ }
716
+
717
+ void shoes_native_quit()
718
+ {
719
+ INIT;
720
+ NSApplication *NSApp = [NSApplication sharedApplication];
721
+ [NSApp stop: nil];
722
+ RELEASE;
723
+ }
724
+
725
+ void shoes_get_time(SHOES_TIME *ts)
726
+ {
727
+ gettimeofday(ts, NULL);
728
+ }
729
+
730
+ unsigned long shoes_diff_time(SHOES_TIME *start, SHOES_TIME *end)
731
+ {
732
+ unsigned long usec;
733
+ if ((end->tv_usec-start->tv_usec)<0) {
734
+ usec = (end->tv_sec-start->tv_sec - 1) * 1000;
735
+ usec += (1000000 + end->tv_usec - start->tv_usec) / 1000;
736
+ } else {
737
+ usec = (end->tv_sec - start->tv_sec) * 1000;
738
+ usec += (end->tv_usec - start->tv_usec) / 1000;
739
+ }
740
+ return usec;
741
+ }
742
+
743
+ int shoes_throw_message(unsigned int name, VALUE obj, void *data)
744
+ {
745
+ return shoes_catch_message(name, obj, data);
746
+ }
747
+
748
+ void shoes_native_slot_mark(SHOES_SLOT_OS *slot)
749
+ {
750
+ rb_gc_mark_maybe(slot->controls);
751
+ }
752
+
753
+ void shoes_native_slot_reset(SHOES_SLOT_OS *slot)
754
+ {
755
+ slot->controls = rb_ary_new();
756
+ rb_gc_register_address(&slot->controls);
757
+ }
758
+
759
+ void shoes_native_slot_clear(shoes_canvas *canvas)
760
+ {
761
+ rb_ary_clear(canvas->slot->controls);
762
+ if (canvas->slot->vscroll)
763
+ {
764
+ shoes_native_slot_lengthen(canvas->slot, canvas->height, 1);
765
+ }
766
+ }
767
+
768
+ void shoes_native_slot_paint(SHOES_SLOT_OS *slot)
769
+ {
770
+ [slot->view setNeedsDisplay: YES];
771
+ }
772
+
773
+ void shoes_native_slot_lengthen(SHOES_SLOT_OS *slot, int height, int endy)
774
+ {
775
+ if (slot->vscroll)
776
+ {
777
+ float s = slot->scrolly * 1., e = endy * 1., h = height * 1., d = (endy - height) * 1.;
778
+ COCOA_DO({
779
+ [slot->vscroll setFloatValue: (d > 0 ? s / d : 0) knobProportion: (h / e)];
780
+ [slot->vscroll setHidden: endy <= height ? YES : NO];
781
+ });
782
+ }
783
+ }
784
+
785
+ void shoes_native_slot_scroll_top(SHOES_SLOT_OS *slot)
786
+ {
787
+ }
788
+
789
+ int shoes_native_slot_gutter(SHOES_SLOT_OS *slot)
790
+ {
791
+ return (int)[NSScroller scrollerWidth];
792
+ }
793
+
794
+ void shoes_native_remove_item(SHOES_SLOT_OS *slot, VALUE item, char c)
795
+ {
796
+ if (c)
797
+ {
798
+ long i = rb_ary_index_of(slot->controls, item);
799
+ if (i >= 0)
800
+ rb_ary_insert_at(slot->controls, i, 1, Qnil);
801
+ }
802
+ }
803
+
804
+ shoes_code
805
+ shoes_app_cursor(shoes_app *app, ID cursor)
806
+ {
807
+ if (app->os.window == NULL || app->cursor == cursor)
808
+ goto done;
809
+
810
+ if (cursor == s_hand || cursor == s_link)
811
+ [[NSCursor pointingHandCursor] set];
812
+ else if (cursor == s_arrow)
813
+ [[NSCursor arrowCursor] set];
814
+ else if (cursor == s_text)
815
+ [[NSCursor IBeamCursor] set];
816
+ else
817
+ goto done;
818
+
819
+ app->cursor = cursor;
820
+
821
+ done:
822
+ return SHOES_OK;
823
+ }
824
+
825
+ void
826
+ shoes_native_app_resized(shoes_app *app)
827
+ {
828
+ NSRect rect = [app->os.window frame];
829
+ rect.size.width = app->width;
830
+ rect.size.height = app->height;
831
+ [app->os.window setFrame: rect display: YES];
832
+ }
833
+
834
+ void
835
+ shoes_native_app_title(shoes_app *app, char *msg)
836
+ {
837
+ COCOA_DO([app->os.window setTitle: [NSString stringWithUTF8String: msg]]);
838
+ }
839
+
840
+ static ShoesWindow *
841
+ shoes_native_app_window(shoes_app *app, int dialog)
842
+ {
843
+ ShoesWindow *window;
844
+ unsigned int mask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
845
+ NSRect rect = NSMakeRect(0, 0, app->width, app->height);
846
+ NSSize size = {app->minwidth, app->minheight};
847
+
848
+ if (app->resizable)
849
+ mask |= NSResizableWindowMask;
850
+ if (app->fullscreen) {
851
+ mask = NSBorderlessWindowMask;
852
+ rect = [[NSScreen mainScreen] frame];
853
+ }
854
+ window = [[ShoesWindow alloc] initWithContentRect: rect
855
+ styleMask: mask backing: NSBackingStoreBuffered defer: NO];
856
+ if (app->minwidth > 0 || app->minheight > 0)
857
+ [window setContentMinSize: size];
858
+ [window prepareWithApp: app->self];
859
+ return window;
860
+ }
861
+
862
+ void
863
+ shoes_native_view_supplant(NSView *from, NSView *to)
864
+ {
865
+ int i, count = [[from subviews] count];
866
+ for (i = 0; i < count; i++)
867
+ [to addSubview: [[from subviews] objectAtIndex: i]];
868
+ }
869
+
870
+ void
871
+ shoes_native_app_fullscreen(shoes_app *app, char yn)
872
+ {
873
+ ShoesWindow *old = app->os.window;
874
+ if (yn)
875
+ {
876
+ int level;
877
+ NSRect screen;
878
+ if (CGDisplayCapture(kCGDirectMainDisplay) != kCGErrorSuccess)
879
+ return;
880
+ app->os.normal = [old frame];
881
+ level = CGShieldingWindowLevel();
882
+ screen = [[NSScreen mainScreen] frame];
883
+ COCOA_DO({
884
+ app->width = screen.size.width;
885
+ app->height = screen.size.height;
886
+ app->os.window = shoes_native_app_window(app, 0);
887
+ [app->os.window setLevel: level];
888
+ shoes_native_view_supplant([old contentView], [app->os.window contentView]);
889
+ app->os.view = [app->os.window contentView];
890
+ [old disconnectApp];
891
+ [old close];
892
+ [app->os.window setFrame: screen display: YES];
893
+ });
894
+ }
895
+ else
896
+ {
897
+ COCOA_DO({
898
+ app->width = app->os.normal.size.width;
899
+ app->height = app->os.normal.size.height;
900
+ app->os.window = shoes_native_app_window(app, 0);
901
+ [app->os.window setLevel: NSNormalWindowLevel];
902
+ CGDisplayRelease(kCGDirectMainDisplay);
903
+ shoes_native_view_supplant([old contentView], [app->os.window contentView]);
904
+ app->os.view = [app->os.window contentView];
905
+ [old disconnectApp];
906
+ [old close];
907
+ [app->os.window setFrame: app->os.normal display: YES];
908
+ });
909
+ }
910
+ }
911
+
912
+ shoes_code
913
+ shoes_native_app_open(shoes_app *app, char *path, int dialog)
914
+ {
915
+ shoes_code code = SHOES_OK;
916
+ app->os.normal = NSMakeRect(0, 0, app->width, app->height);
917
+ COCOA_DO({
918
+ app->os.window = shoes_native_app_window(app, dialog);
919
+ app->slot->view = [app->os.window contentView];
920
+ });
921
+ quit:
922
+ return code;
923
+ }
924
+
925
+ void
926
+ shoes_native_app_show(shoes_app *app)
927
+ {
928
+ COCOA_DO([app->os.window orderFront: nil]);
929
+ }
930
+
931
+ void
932
+ shoes_native_loop()
933
+ {
934
+ NSApplication *NSApp = [NSApplication sharedApplication];
935
+ [NSApp run];
936
+ }
937
+
938
+ void
939
+ shoes_native_app_close(shoes_app *app)
940
+ {
941
+ COCOA_DO([app->os.window close]);
942
+ }
943
+
944
+ void
945
+ shoes_browser_open(char *url)
946
+ {
947
+ VALUE browser = rb_str_new2("open ");
948
+ rb_str_cat2(browser, url);
949
+ shoes_sys(RSTRING_PTR(browser), 1);
950
+ }
951
+
952
+ void
953
+ shoes_slot_init(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int width, int height, int scrolls, int toplevel)
954
+ {
955
+ shoes_canvas *canvas;
956
+ SHOES_SLOT_OS *slot;
957
+ Data_Get_Struct(c, shoes_canvas, canvas);
958
+
959
+ COCOA_DO({
960
+ slot = shoes_slot_alloc(canvas, parent, toplevel);
961
+ slot->controls = parent->controls;
962
+ slot->view = [[ShoesView alloc] initWithFrame: NSMakeRect(x, y, width, height) andCanvas: c];
963
+ [slot->view setAutoresizesSubviews: NO];
964
+ if (toplevel)
965
+ [slot->view setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)];
966
+ slot->vscroll = NULL;
967
+ if (scrolls)
968
+ {
969
+ slot->vscroll = [[NSScroller alloc] initWithFrame:
970
+ NSMakeRect(width - [NSScroller scrollerWidth], 0, [NSScroller scrollerWidth], height)];
971
+ [slot->vscroll setEnabled: YES];
972
+ [slot->vscroll setTarget: slot->view];
973
+ [slot->vscroll setAction: @selector(scroll:)];
974
+ [slot->view addSubview: slot->vscroll];
975
+ }
976
+ if (parent->vscroll)
977
+ [parent->view addSubview: slot->view positioned: NSWindowBelow relativeTo: parent->vscroll];
978
+ else
979
+ [parent->view addSubview: slot->view];
980
+ });
981
+ }
982
+
983
+ void
984
+ shoes_slot_destroy(shoes_canvas *canvas, shoes_canvas *pc)
985
+ {
986
+ INIT;
987
+ if (canvas->slot->vscroll != NULL)
988
+ [canvas->slot->vscroll removeFromSuperview];
989
+ [canvas->slot->view removeFromSuperview];
990
+ RELEASE;
991
+ }
992
+
993
+ cairo_t *
994
+ shoes_cairo_create(shoes_canvas *canvas)
995
+ {
996
+ cairo_t *cr;
997
+ canvas->slot->surface = cairo_quartz_surface_create_for_cg_context(canvas->slot->context,
998
+ canvas->width, canvas->height);
999
+ cr = cairo_create(canvas->slot->surface);
1000
+ cairo_translate(cr, 0, 0 - canvas->slot->scrolly);
1001
+ return cr;
1002
+ }
1003
+
1004
+ void shoes_cairo_destroy(shoes_canvas *canvas)
1005
+ {
1006
+ cairo_surface_destroy(canvas->slot->surface);
1007
+ }
1008
+
1009
+ void
1010
+ shoes_group_clear(SHOES_GROUP_OS *group)
1011
+ {
1012
+ }
1013
+
1014
+ void
1015
+ shoes_native_canvas_place(shoes_canvas *self_t, shoes_canvas *pc)
1016
+ {
1017
+ NSRect rect, rect2;
1018
+ int newy = (self_t->place.iy + self_t->place.dy) - pc->slot->scrolly;
1019
+ rect.origin.x = (self_t->place.ix + self_t->place.dx) * 1.;
1020
+ rect.origin.y = ((newy) * 1.);
1021
+ rect.size.width = (self_t->place.iw * 1.);
1022
+ rect.size.height = (self_t->place.ih * 1.);
1023
+ rect2 = [self_t->slot->view frame];
1024
+ if (rect.origin.x != rect2.origin.x || rect.origin.y != rect2.origin.y ||
1025
+ rect.size.width != rect2.size.width || rect.size.height != rect2.size.height)
1026
+ {
1027
+ [self_t->slot->view setFrame: rect];
1028
+ }
1029
+ }
1030
+
1031
+ void
1032
+ shoes_native_canvas_resize(shoes_canvas *canvas)
1033
+ {
1034
+ NSSize size = {canvas->width, canvas->height};
1035
+ [canvas->slot->view setFrameSize: size];
1036
+ }
1037
+
1038
+ void
1039
+ shoes_native_control_hide(SHOES_CONTROL_REF ref)
1040
+ {
1041
+ COCOA_DO([ref setHidden: YES]);
1042
+ }
1043
+
1044
+ void
1045
+ shoes_native_control_show(SHOES_CONTROL_REF ref)
1046
+ {
1047
+ COCOA_DO([ref setHidden: NO]);
1048
+ }
1049
+
1050
+ static void
1051
+ shoes_native_control_frame(SHOES_CONTROL_REF ref, shoes_place *p)
1052
+ {
1053
+ NSRect rect;
1054
+ rect.origin.x = p->ix + p->dx; rect.origin.y = p->iy + p->dy;
1055
+ rect.size.width = p->iw; rect.size.height = p->ih;
1056
+ [ref setFrame: rect];
1057
+ }
1058
+
1059
+ void
1060
+ shoes_native_control_position(SHOES_CONTROL_REF ref, shoes_place *p1, VALUE self,
1061
+ shoes_canvas *canvas, shoes_place *p2)
1062
+ {
1063
+ PLACE_COORDS();
1064
+ if (canvas->slot->vscroll)
1065
+ [canvas->slot->view addSubview: ref positioned: NSWindowBelow relativeTo: canvas->slot->vscroll];
1066
+ else
1067
+ [canvas->slot->view addSubview: ref];
1068
+ shoes_native_control_frame(ref, p2);
1069
+ rb_ary_push(canvas->slot->controls, self);
1070
+ }
1071
+
1072
+ void
1073
+ shoes_native_control_repaint(SHOES_CONTROL_REF ref, shoes_place *p1,
1074
+ shoes_canvas *canvas, shoes_place *p2)
1075
+ {
1076
+ p2->iy -= canvas->slot->scrolly;
1077
+ if (CHANGED_COORDS()) {
1078
+ PLACE_COORDS();
1079
+ shoes_native_control_frame(ref, p2);
1080
+ }
1081
+ p2->iy += canvas->slot->scrolly;
1082
+ }
1083
+
1084
+ void
1085
+ shoes_native_control_state(SHOES_CONTROL_REF ref, BOOL sensitive, BOOL setting)
1086
+ {
1087
+ COCOA_DO({
1088
+ [ref setEnabled: sensitive];
1089
+ if ([ref respondsToSelector: @selector(setEditable:)])
1090
+ [ref setEditable: setting];
1091
+ });
1092
+ }
1093
+
1094
+ void
1095
+ shoes_native_control_focus(SHOES_CONTROL_REF ref)
1096
+ {
1097
+ COCOA_DO([[ref window] makeFirstResponder: ref]);
1098
+ }
1099
+
1100
+ void
1101
+ shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas)
1102
+ {
1103
+ COCOA_DO([ref removeFromSuperview]);
1104
+ }
1105
+
1106
+ void
1107
+ shoes_native_control_free(SHOES_CONTROL_REF ref)
1108
+ {
1109
+ }
1110
+
1111
+ SHOES_SURFACE_REF
1112
+ shoes_native_surface_new(shoes_canvas *canvas, VALUE self, shoes_place *place)
1113
+ {
1114
+ return canvas->app->os.window;
1115
+ }
1116
+
1117
+ void
1118
+ shoes_native_surface_position(SHOES_SURFACE_REF ref, shoes_place *p1,
1119
+ VALUE self, shoes_canvas *canvas, shoes_place *p2)
1120
+ {
1121
+ PLACE_COORDS();
1122
+ }
1123
+
1124
+ void
1125
+ shoes_native_surface_hide(SHOES_SURFACE_REF ref)
1126
+ {
1127
+ HIViewSetVisible(ref, false);
1128
+ }
1129
+
1130
+ void
1131
+ shoes_native_surface_show(SHOES_SURFACE_REF ref)
1132
+ {
1133
+ HIViewSetVisible(ref, true);
1134
+ }
1135
+
1136
+ void
1137
+ shoes_native_surface_remove(shoes_canvas *canvas, SHOES_SURFACE_REF ref)
1138
+ {
1139
+ }
1140
+
1141
+ SHOES_CONTROL_REF
1142
+ shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, char *msg)
1143
+ {
1144
+ INIT;
1145
+ ShoesButton *button = [[ShoesButton alloc] initWithType: NSMomentaryPushInButton
1146
+ andObject: self];
1147
+ [button setTitle: [NSString stringWithUTF8String: msg]];
1148
+ RELEASE;
1149
+ return (NSControl *)button;
1150
+ }
1151
+
1152
+ SHOES_CONTROL_REF
1153
+ shoes_native_edit_line(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1154
+ {
1155
+ INIT;
1156
+ NSTextField *field;
1157
+ if (RTEST(ATTR(attr, secret)))
1158
+ field = [[ShoesSecureTextField alloc] initWithFrame:
1159
+ NSMakeRect(place->ix + place->dx, place->iy + place->dy,
1160
+ place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
1161
+ andObject: self];
1162
+ else
1163
+ field = [[ShoesTextField alloc] initWithFrame:
1164
+ NSMakeRect(place->ix + place->dx, place->iy + place->dy,
1165
+ place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
1166
+ andObject: self];
1167
+ [field setStringValue: [NSString stringWithUTF8String: msg]];
1168
+ [field setEditable: YES];
1169
+ RELEASE;
1170
+ return (NSControl *)field;
1171
+ }
1172
+
1173
+ VALUE
1174
+ shoes_native_edit_line_get_text(SHOES_CONTROL_REF ref)
1175
+ {
1176
+ VALUE text = Qnil;
1177
+ INIT;
1178
+ text = rb_str_new2([[ref stringValue] UTF8String]);
1179
+ RELEASE;
1180
+ return text;
1181
+ }
1182
+
1183
+ void
1184
+ shoes_native_edit_line_set_text(SHOES_CONTROL_REF ref, char *msg)
1185
+ {
1186
+ COCOA_DO([ref setStringValue: [NSString stringWithUTF8String: msg]]);
1187
+ }
1188
+
1189
+ SHOES_CONTROL_REF
1190
+ shoes_native_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1191
+ {
1192
+ INIT;
1193
+ ShoesTextView *tv = [[ShoesTextView alloc] initWithFrame:
1194
+ NSMakeRect(place->ix + place->dx, place->iy + place->dy,
1195
+ place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
1196
+ andObject: self];
1197
+ shoes_native_edit_box_set_text((NSControl *)tv, msg);
1198
+ RELEASE;
1199
+ return (NSControl *)tv;
1200
+ }
1201
+
1202
+ VALUE
1203
+ shoes_native_edit_box_get_text(SHOES_CONTROL_REF ref)
1204
+ {
1205
+ VALUE text = Qnil;
1206
+ INIT;
1207
+ text = rb_str_new2([[[(ShoesTextView *)ref textStorage] string] UTF8String]);
1208
+ RELEASE;
1209
+ return text;
1210
+ }
1211
+
1212
+ void
1213
+ shoes_native_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
1214
+ {
1215
+ COCOA_DO([[[(ShoesTextView *)ref textStorage] mutableString] setString: [NSString stringWithUTF8String: msg]]);
1216
+ }
1217
+
1218
+ SHOES_CONTROL_REF
1219
+ shoes_native_list_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1220
+ {
1221
+ INIT;
1222
+ ShoesPopUpButton *pop = [[ShoesPopUpButton alloc] initWithFrame:
1223
+ NSMakeRect(place->ix + place->dx, place->iy + place->dy,
1224
+ place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
1225
+ andObject: self];
1226
+ RELEASE;
1227
+ return (NSControl *)pop;
1228
+ }
1229
+
1230
+ void
1231
+ shoes_native_list_box_update(SHOES_CONTROL_REF ref, VALUE ary)
1232
+ {
1233
+ long i;
1234
+ ShoesPopUpButton *pop = (ShoesPopUpButton *)ref;
1235
+ COCOA_DO({
1236
+ [pop removeAllItems];
1237
+ for (i = 0; i < RARRAY_LEN(ary); i++)
1238
+ {
1239
+ VALUE msg_s = shoes_native_to_s(rb_ary_entry(ary, i));
1240
+ char *msg = RSTRING_PTR(msg_s);
1241
+ [[pop menu] insertItemWithTitle: [NSString stringWithUTF8String: msg] action: nil
1242
+ keyEquivalent: @"" atIndex: i];
1243
+ }
1244
+ });
1245
+ }
1246
+
1247
+ VALUE
1248
+ shoes_native_list_box_get_active(SHOES_CONTROL_REF ref, VALUE items)
1249
+ {
1250
+ int sel = [(ShoesPopUpButton *)ref indexOfSelectedItem];
1251
+ if (sel >= 0)
1252
+ return rb_ary_entry(items, sel);
1253
+ return Qnil;
1254
+ }
1255
+
1256
+ void
1257
+ shoes_native_list_box_set_active(SHOES_CONTROL_REF ref, VALUE ary, VALUE item)
1258
+ {
1259
+ int idx = rb_ary_index_of(ary, item);
1260
+ if (idx < 0) return;
1261
+ COCOA_DO([(ShoesPopUpButton *)ref selectItemAtIndex: idx]);
1262
+ }
1263
+
1264
+ SHOES_CONTROL_REF
1265
+ shoes_native_progress(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1266
+ {
1267
+ INIT;
1268
+ NSProgressIndicator *pop = [[NSProgressIndicator alloc] init];
1269
+ [pop setIndeterminate: FALSE];
1270
+ [pop setDoubleValue: 0.];
1271
+ [pop setBezeled: YES];
1272
+ RELEASE;
1273
+ return (NSControl *)pop;
1274
+ }
1275
+
1276
+ double
1277
+ shoes_native_progress_get_fraction(SHOES_CONTROL_REF ref)
1278
+ {
1279
+ return [(NSProgressIndicator *)ref doubleValue] * 0.01;
1280
+ }
1281
+
1282
+ void
1283
+ shoes_native_progress_set_fraction(SHOES_CONTROL_REF ref, double perc)
1284
+ {
1285
+ COCOA_DO([(NSProgressIndicator *)ref setDoubleValue: perc * 100.]);
1286
+ }
1287
+
1288
+ SHOES_CONTROL_REF
1289
+ shoes_native_slider(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1290
+ {
1291
+ INIT;
1292
+ ShoesSlider *pop = [[ShoesSlider alloc] initWithObject: self];
1293
+ [pop setMinValue: 0.];
1294
+ [pop setMaxValue: 100.];
1295
+ RELEASE;
1296
+ return (NSControl *)pop;
1297
+ }
1298
+
1299
+ double
1300
+ shoes_native_slider_get_fraction(SHOES_CONTROL_REF ref)
1301
+ {
1302
+ return [(ShoesSlider *)ref doubleValue] * 0.01;
1303
+ }
1304
+
1305
+ void
1306
+ shoes_native_slider_set_fraction(SHOES_CONTROL_REF ref, double perc)
1307
+ {
1308
+ COCOA_DO([(ShoesSlider *)ref setDoubleValue: perc * 100.]);
1309
+ }
1310
+
1311
+ SHOES_CONTROL_REF
1312
+ shoes_native_check(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
1313
+ {
1314
+ INIT;
1315
+ ShoesButton *button = [[ShoesButton alloc] initWithType: NSSwitchButton andObject: self];
1316
+ RELEASE;
1317
+ return (NSControl *)button;
1318
+ }
1319
+
1320
+ VALUE
1321
+ shoes_native_check_get(SHOES_CONTROL_REF ref)
1322
+ {
1323
+ return [(ShoesButton *)ref state] == NSOnState ? Qtrue : Qfalse;
1324
+ }
1325
+
1326
+ void
1327
+ shoes_native_check_set(SHOES_CONTROL_REF ref, int on)
1328
+ {
1329
+ COCOA_DO([(ShoesButton *)ref setState: on ? NSOnState : NSOffState]);
1330
+ }
1331
+
1332
+ SHOES_CONTROL_REF
1333
+ shoes_native_radio(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, VALUE group)
1334
+ {
1335
+ INIT;
1336
+ ShoesButton *button = [[ShoesButton alloc] initWithType: NSRadioButton
1337
+ andObject: self];
1338
+ RELEASE;
1339
+ return (NSControl *)button;
1340
+ }
1341
+
1342
+ void
1343
+ shoes_native_timer_remove(shoes_canvas *canvas, SHOES_TIMER_REF ref)
1344
+ {
1345
+ COCOA_DO([ref invalidate]);
1346
+ }
1347
+
1348
+ SHOES_TIMER_REF
1349
+ shoes_native_timer_start(VALUE self, shoes_canvas *canvas, unsigned int interval)
1350
+ {
1351
+ INIT;
1352
+ ShoesTimer *timer = [[ShoesTimer alloc] initWithTimeInterval: interval * 0.001
1353
+ andObject: self repeats:(rb_obj_is_kind_of(self, cTimer) ? NO : YES)];
1354
+ RELEASE;
1355
+ return timer;
1356
+ }
1357
+
1358
+ VALUE
1359
+ shoes_native_clipboard_get(shoes_app *app)
1360
+ {
1361
+ VALUE txt = Qnil;
1362
+ INIT;
1363
+ NSString *paste = [[NSPasteboard generalPasteboard] stringForType: NSStringPboardType];
1364
+ if (paste) txt = rb_str_new2([paste UTF8String]);
1365
+ RELEASE;
1366
+ return txt;
1367
+ }
1368
+
1369
+ void
1370
+ shoes_native_clipboard_set(shoes_app *app, VALUE string)
1371
+ {
1372
+ COCOA_DO({
1373
+ [[NSPasteboard generalPasteboard] declareTypes: [NSArray arrayWithObject: NSStringPboardType] owner: nil];
1374
+ [[NSPasteboard generalPasteboard] setString: [NSString stringWithUTF8String: RSTRING_PTR(string)]
1375
+ forType: NSStringPboardType];
1376
+ });
1377
+ }
1378
+
1379
+ VALUE
1380
+ shoes_native_to_s(VALUE text)
1381
+ {
1382
+ text = rb_funcall(text, s_to_s, 0);
1383
+ return text;
1384
+ }
1385
+
1386
+ VALUE
1387
+ shoes_native_window_color(shoes_app *app)
1388
+ {
1389
+ // float r, g, b, a;
1390
+ // INIT;
1391
+ // [[[app->os.window backgroundColor] colorUsingColorSpace: [NSColorSpace genericRGBColorSpace]]
1392
+ // getRed: &r green: &g blue: &b alpha: &a];
1393
+ // RELEASE;
1394
+ // return shoes_color_new((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(a * 255));
1395
+ return shoes_color_new(255, 255, 255, 255);
1396
+ }
1397
+
1398
+ VALUE
1399
+ shoes_native_dialog_color(shoes_app *app)
1400
+ {
1401
+ return shoes_native_window_color(app);
1402
+ }
1403
+
1404
+ VALUE
1405
+ shoes_dialog_alert(VALUE self, VALUE msg)
1406
+ {
1407
+ VALUE answer = Qnil;
1408
+ COCOA_DO({
1409
+ msg = shoes_native_to_s(msg);
1410
+ NSAlert *alert = [NSAlert alertWithMessageText: @"Shoes says:"
1411
+ defaultButton: @"OK" alternateButton: nil otherButton: nil
1412
+ informativeTextWithFormat: [NSString stringWithUTF8String: RSTRING_PTR(msg)]];
1413
+ [alert runModal];
1414
+ });
1415
+ return Qnil;
1416
+ }
1417
+
1418
+ VALUE
1419
+ shoes_dialog_ask(int argc, VALUE *argv, VALUE self)
1420
+ {
1421
+ rb_arg_list args;
1422
+ VALUE answer = Qnil;
1423
+ rb_parse_args(argc, argv, "s|h", &args);
1424
+ COCOA_DO({
1425
+ NSApplication *NSApp = [NSApplication sharedApplication];
1426
+ ShoesAlert *alert = [[ShoesAlert alloc] init];
1427
+ NSButton *okButton = [[[NSButton alloc] initWithFrame:
1428
+ NSMakeRect(244, 10, 88, 30)] autorelease];
1429
+ NSButton *cancelButton = [[[NSButton alloc] initWithFrame:
1430
+ NSMakeRect(156, 10, 88, 30)] autorelease];
1431
+ NSTextField *text = [[[NSTextField alloc] initWithFrame:
1432
+ NSMakeRect(20, 110, 260, 18)] autorelease];
1433
+ NSTextField *input;
1434
+ if (RTEST(ATTR(args.a[1], secret)))
1435
+ input = [[NSSecureTextField alloc] initWithFrame:NSMakeRect(20, 72, 300, 24)];
1436
+ else
1437
+ input = [[NSTextField alloc] initWithFrame:NSMakeRect(20, 72, 300, 24)];
1438
+
1439
+ [alert setTitle: @"Shoes asks:"];
1440
+ [text setStringValue: [NSString stringWithUTF8String: RSTRING_PTR(args.a[0])]];
1441
+ [text setBezeled: NO];
1442
+ [text setBackgroundColor: [NSColor windowBackgroundColor]];
1443
+ [text setEditable: NO];
1444
+ [text setSelectable: NO];
1445
+ [[alert contentView] addSubview: text];
1446
+ [input setStringValue:@""];
1447
+ [[alert contentView] addSubview: input];
1448
+ [okButton setTitle: @"OK"];
1449
+ [okButton setBezelStyle: 1];
1450
+ [okButton setTarget: alert];
1451
+ [okButton setAction: @selector(okClick:)];
1452
+ [[alert contentView] addSubview: okButton];
1453
+ [cancelButton setTitle: @"Cancel"];
1454
+ [cancelButton setBezelStyle: 1];
1455
+ [cancelButton setTarget: alert];
1456
+ [cancelButton setAction: @selector(cancelClick:)];
1457
+ [[alert contentView] addSubview: cancelButton];
1458
+ [alert setDefaultButtonCell: okButton];
1459
+ [NSApp runModalForWindow: alert];
1460
+ if ([alert accepted])
1461
+ answer = rb_str_new2([[input stringValue] UTF8String]);
1462
+ [alert close];
1463
+ });
1464
+ return answer;
1465
+ }
1466
+
1467
+ VALUE
1468
+ shoes_dialog_confirm(VALUE self, VALUE quiz)
1469
+ {
1470
+ char *msg;
1471
+ VALUE answer = Qnil;
1472
+ COCOA_DO({
1473
+ quiz = shoes_native_to_s(quiz);
1474
+ msg = RSTRING_PTR(quiz);
1475
+ NSAlert *alert = [NSAlert alertWithMessageText: @"Shoes asks:"
1476
+ defaultButton: @"OK" alternateButton: @"Cancel" otherButton:nil
1477
+ informativeTextWithFormat: [NSString stringWithUTF8String: msg]];
1478
+ answer = ([alert runModal] == NSOKButton ? Qtrue : Qfalse);
1479
+ });
1480
+ return answer;
1481
+ }
1482
+
1483
+ VALUE
1484
+ shoes_dialog_color(VALUE self, VALUE title)
1485
+ {
1486
+ Point where;
1487
+ RGBColor colwh = { 0xFFFF, 0xFFFF, 0xFFFF };
1488
+ RGBColor _color;
1489
+ VALUE color = Qnil;
1490
+ GLOBAL_APP(app);
1491
+
1492
+ where.h = where.v = 0;
1493
+ title = shoes_native_to_s(title);
1494
+ if (GetColor(where, RSTRING_PTR(title), &colwh, &_color))
1495
+ {
1496
+ color = shoes_color_new(_color.red/256, _color.green/256, _color.blue/256, SHOES_COLOR_OPAQUE);
1497
+ }
1498
+ return color;
1499
+ }
1500
+
1501
+ static VALUE
1502
+ shoes_dialog_chooser(VALUE self, NSString *title, BOOL directories, VALUE attr)
1503
+ {
1504
+ VALUE path = Qnil;
1505
+ COCOA_DO({
1506
+ NSOpenPanel* openDlg = [NSOpenPanel openPanel];
1507
+ [openDlg setCanChooseFiles: !directories];
1508
+ [openDlg setCanChooseDirectories: directories];
1509
+ [openDlg setAllowsMultipleSelection: NO];
1510
+ if ( [openDlg runModalForDirectory: nil file: nil] == NSOKButton )
1511
+ {
1512
+ NSArray* files = [openDlg filenames];
1513
+ char *filename = [[files objectAtIndex: 0] UTF8String];
1514
+ path = rb_str_new2(filename);
1515
+ }
1516
+ });
1517
+ return path;
1518
+ }
1519
+
1520
+ VALUE
1521
+ shoes_dialog_open(int argc, VALUE *argv, VALUE self)
1522
+ {
1523
+ rb_arg_list args;
1524
+ rb_parse_args(argc, argv, "|h", &args);
1525
+ return shoes_dialog_chooser(self, @"Open file...", NO, args.a[0]);
1526
+ }
1527
+
1528
+ VALUE
1529
+ shoes_dialog_save(int argc, VALUE *argv, VALUE self)
1530
+ {
1531
+ VALUE path = Qnil;
1532
+ COCOA_DO({
1533
+ NSSavePanel* saveDlg = [NSSavePanel savePanel];
1534
+ if ( [saveDlg runModalForDirectory:nil file:nil] == NSOKButton )
1535
+ {
1536
+ char *filename = [[saveDlg filename] UTF8String];
1537
+ path = rb_str_new2(filename);
1538
+ }
1539
+ });
1540
+ return path;
1541
+ }
1542
+
1543
+ VALUE
1544
+ shoes_dialog_open_folder(int argc, VALUE *argv, VALUE self)
1545
+ {
1546
+ rb_arg_list args;
1547
+ rb_parse_args(argc, argv, "|h", &args);
1548
+ return shoes_dialog_chooser(self, @"Open folder...", YES, args.a[0]);
1549
+ }
1550
+
1551
+ VALUE
1552
+ shoes_dialog_save_folder(int argc, VALUE *argv, VALUE self)
1553
+ {
1554
+ rb_arg_list args;
1555
+ rb_parse_args(argc, argv, "|h", &args);
1556
+ return shoes_dialog_chooser(self, @"Save folder...", YES, args.a[0]);
1557
+ }