shoes 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. 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
+ }