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,110 @@
1
+ //
2
+ // shoes/app.h
3
+ // Abstract windowing for GTK, Quartz (OSX) and Win32.
4
+ //
5
+ // This is really just a light wrapper around Cairo, which does most of the
6
+ // work anyway. I'm not sure why they don't do this for ya. Probably so I
7
+ // could do it in Shoes!!
8
+ //
9
+
10
+ #ifndef SHOES_APP_H
11
+ #define SHOES_APP_H
12
+
13
+ #include <cairo.h>
14
+ #include <ruby.h>
15
+
16
+ #ifdef VIDEO
17
+ #ifdef VLC_0_8
18
+ #include <vlc/libvlc.h>
19
+ #define SHOES_VLC(self_t) self_t->vlc
20
+ #define shoes_libvlc_clear libvlc_playlist_clear
21
+ #define shoes_libvlc_prev libvlc_playlist_prev
22
+ #define shoes_libvlc_next libvlc_playlist_next
23
+ #define shoes_libvlc_pause libvlc_playlist_pause
24
+ #define shoes_libvlc_stop libvlc_playlist_stop
25
+ #else
26
+ #include <vlc/vlc.h>
27
+ #include <vlc/libvlc.h>
28
+ #define libvlc_destroy libvlc_media_player_release
29
+ #define vlc_int64_t libvlc_time_t
30
+ #define shoes_libvlc_clear libvlc_media_player_pause
31
+ #define shoes_libvlc_prev libvlc_media_player_stop
32
+ #define shoes_libvlc_next libvlc_media_player_stop
33
+ #define shoes_libvlc_pause libvlc_media_player_pause
34
+ #define shoes_libvlc_stop libvlc_media_player_stop
35
+ #define SHOES_VLC(self_t) shoes_world->vlc
36
+ #define VLC_0_9
37
+ #endif
38
+ #endif
39
+
40
+ #include "shoes/canvas.h"
41
+ #include "shoes/code.h"
42
+ #include "shoes/config.h"
43
+
44
+ #define SHOES_APP_HEIGHT 500
45
+ #define SHOES_APP_WIDTH 600
46
+ #define SHOES_SHORTNAME "shoes"
47
+ #define SHOES_APPNAME "Shoes"
48
+ #define SHOES_VLCLASS "Shoes VLC"
49
+ #define SHOES_SLOTCLASS "Shoes Slot"
50
+ #define SHOES_HIDDENCLS "Shoes Hidden"
51
+
52
+ //
53
+ // abstract window struct
54
+ //
55
+ typedef struct _shoes_app {
56
+ SHOES_APP_OS os;
57
+ SHOES_SLOT_OS *slot;
58
+ cairo_t *scratch;
59
+ int width, height, mouseb, mousex, mousey,
60
+ resizable, hidden, started, fullscreen,
61
+ minwidth, minheight;
62
+ VALUE self;
63
+ VALUE canvas;
64
+ VALUE keypresses;
65
+ VALUE nestslot;
66
+ VALUE nesting;
67
+ VALUE extras;
68
+ VALUE styles;
69
+ VALUE groups;
70
+ ID cursor;
71
+ VALUE title;
72
+ VALUE location;
73
+ VALUE owner;
74
+ } shoes_app;
75
+
76
+ //
77
+ // function signatures
78
+ //
79
+ VALUE shoes_app_alloc(VALUE);
80
+ VALUE shoes_app_new(VALUE);
81
+ VALUE shoes_apps_get(VALUE);
82
+ int shoes_app_remove(shoes_app *);
83
+ VALUE shoes_app_get_title(VALUE);
84
+ VALUE shoes_app_set_title(VALUE, VALUE);
85
+ VALUE shoes_app_get_fullscreen(VALUE);
86
+ VALUE shoes_app_set_fullscreen(VALUE, VALUE);
87
+ VALUE shoes_app_slot(VALUE);
88
+ shoes_code shoes_app_start(VALUE, char *);
89
+ shoes_code shoes_app_open(shoes_app *, char *);
90
+ shoes_code shoes_app_loop();
91
+ shoes_code shoes_app_visit(shoes_app *, char *);
92
+ shoes_code shoes_app_paint(shoes_app *);
93
+ shoes_code shoes_app_motion(shoes_app *, int, int);
94
+ shoes_code shoes_app_click(shoes_app *, int, int, int);
95
+ shoes_code shoes_app_release(shoes_app *, int, int, int);
96
+ shoes_code shoes_app_wheel(shoes_app *, ID, int, int);
97
+ shoes_code shoes_app_keydown(shoes_app *, VALUE);
98
+ shoes_code shoes_app_keypress(shoes_app *, VALUE);
99
+ shoes_code shoes_app_keyup(shoes_app *, VALUE);
100
+ VALUE shoes_app_close_window(shoes_app *);
101
+ VALUE shoes_sys(char *, int);
102
+ shoes_code shoes_app_goto(shoes_app *, char *);
103
+ shoes_code shoes_slot_repaint(SHOES_SLOT_OS *);
104
+ void shoes_app_reset_styles(shoes_app *);
105
+ void shoes_app_style(shoes_app *, VALUE, VALUE);
106
+ VALUE shoes_app_location(VALUE);
107
+ VALUE shoes_app_is_started(VALUE);
108
+ VALUE shoes_app_quit(VALUE);
109
+
110
+ #endif
@@ -0,0 +1,13 @@
1
+ //
2
+ // shoes/appwin32.h
3
+ // Resource IDs (see appwin32.rc also)
4
+ //
5
+ #ifndef SHOES_APPWIN32_H
6
+ #define SHOES_APPWIN32_H
7
+
8
+ #define ASKDLG 1
9
+ #define ASKSECRETDLG 2
10
+ #define IDQUIZ 111
11
+ #define IDQUED 112
12
+
13
+ #endif
@@ -0,0 +1,28 @@
1
+ #include <windows.h>
2
+ #include "shoes/appwin32.h"
3
+
4
+ IDI_APPLICATION ICON
5
+ "shoes/appwin32.ico"
6
+
7
+ ASKDLG DIALOG 20, 20, 299, 79
8
+ STYLE DS_SETFONT |DS_MODALFRAME |WS_POPUP |WS_VISIBLE |WS_SYSMENU |WS_CAPTION
9
+ CAPTION "Shoes asks:"
10
+ FONT 8, "MS Shell Dlg"
11
+ BEGIN
12
+ CONTROL "Question",IDQUIZ,"STATIC",SS_LEFT |WS_CHILD |WS_VISIBLE ,8,8,279,30
13
+ CONTROL "",IDQUED,"EDIT",SS_LEFT |WS_CHILD |WS_TABSTOP |WS_BORDER |WS_VISIBLE ,8,40,279,12
14
+ CONTROL "&OK",IDOK,"BUTTON",BS_DEFPUSHBUTTON |WS_CHILD |WS_TABSTOP |WS_VISIBLE ,200,58,40,14
15
+ CONTROL "&Cancel",IDCANCEL,"BUTTON",BS_PUSHBUTTON |WS_CHILD |WS_TABSTOP |WS_VISIBLE ,248,58,40,14
16
+ END
17
+
18
+ ASKSECRETDLG DIALOG 20, 20, 299, 79
19
+ STYLE DS_SETFONT |DS_MODALFRAME |WS_POPUP |WS_VISIBLE |WS_SYSMENU |WS_CAPTION
20
+ CAPTION "Shoes asks:"
21
+ FONT 8, "MS Shell Dlg"
22
+ BEGIN
23
+ CONTROL "Question",IDQUIZ,"STATIC",SS_LEFT |WS_CHILD |WS_VISIBLE ,8,8,279,30
24
+ CONTROL "",IDQUED,"EDIT",SS_LEFT |WS_CHILD |WS_TABSTOP |WS_BORDER |WS_VISIBLE |ES_PASSWORD,8,40,279,12
25
+ CONTROL "&OK",IDOK,"BUTTON",BS_DEFPUSHBUTTON |WS_CHILD |WS_TABSTOP |WS_VISIBLE ,200,58,40,14
26
+ CONTROL "&Cancel",IDCANCEL,"BUTTON",BS_PUSHBUTTON |WS_CHILD |WS_TABSTOP |WS_VISIBLE ,248,58,40,14
27
+ END
28
+
@@ -0,0 +1,2202 @@
1
+ //
2
+ // shoes/canvas.c
3
+ // Ruby methods for all the drawing ops.
4
+ //
5
+ #include "shoes/internal.h"
6
+ #include "shoes/app.h"
7
+ #include "shoes/canvas.h"
8
+ #include "shoes/ruby.h"
9
+ #include "shoes/world.h"
10
+ #include "shoes/native.h"
11
+ #include "shoes/http.h"
12
+
13
+ #define SETUP() \
14
+ shoes_canvas *canvas; \
15
+ cairo_t *cr; \
16
+ Data_Get_Struct(self, shoes_canvas, canvas); \
17
+ cr = CCR(canvas)
18
+ #define SETUP_IMAGE() \
19
+ shoes_place place; \
20
+ GET_STRUCT(image, image); \
21
+ shoes_image_ensure_dup(image); \
22
+ shoes_place_exact(&place, attr, 0, 0); \
23
+ if (NIL_P(attr)) attr = image->attr; \
24
+ else if (!NIL_P(image->attr)) attr = rb_funcall(image->attr, s_merge, 1, attr);
25
+ #define SETUP_SHAPE() \
26
+ shoes_canvas *canvas = NULL; \
27
+ VALUE c = shoes_find_canvas(self); \
28
+ Data_Get_Struct(c, shoes_canvas, canvas)
29
+
30
+ const double SHOES_PIM2 = 6.28318530717958647693;
31
+ const double SHOES_PI = 3.14159265358979323846;
32
+ const double SHOES_HALFPI = 1.57079632679489661923;
33
+ const double SHOES_RAD2PI = 0.01745329251994329577;
34
+
35
+ const char *dialog_title = USTR("Shoes asks:");
36
+ const char *dialog_title_says = USTR("Shoes says:");
37
+
38
+ static void shoes_canvas_send_start(VALUE);
39
+ static void shoes_canvas_send_finish(VALUE);
40
+
41
+ shoes_transform *
42
+ shoes_transform_new(shoes_transform *o)
43
+ {
44
+ shoes_transform *n = SHOE_ALLOC(shoes_transform);
45
+ n->mode = s_center;
46
+ n->refs = 1;
47
+ cairo_matrix_init_identity(&n->tf);
48
+ if (o != NULL)
49
+ {
50
+ cairo_matrix_multiply(&n->tf, &n->tf, &o->tf);
51
+ n->mode = o->mode;
52
+ }
53
+ return n;
54
+ }
55
+
56
+ shoes_transform *
57
+ shoes_transform_touch(shoes_transform *st)
58
+ {
59
+ if (st != NULL) st->refs++;
60
+ return st;
61
+ }
62
+
63
+ shoes_transform *
64
+ shoes_transform_detach(shoes_transform *old)
65
+ {
66
+ if (old != NULL && old->refs == 1) return old;
67
+ if (old != NULL) old->refs--;
68
+ return shoes_transform_new(old);
69
+ }
70
+
71
+ void
72
+ shoes_transform_release(shoes_transform *st)
73
+ {
74
+ if (st == NULL) return;
75
+ if (--st->refs) return;
76
+ SHOE_FREE(st);
77
+ }
78
+
79
+ VALUE
80
+ shoes_canvas_owner(VALUE self)
81
+ {
82
+ SETUP();
83
+ return canvas->app->owner;
84
+ }
85
+
86
+ VALUE
87
+ shoes_canvas_close(VALUE self)
88
+ {
89
+ SETUP();
90
+ return shoes_app_close_window(canvas->app);
91
+ }
92
+
93
+ VALUE
94
+ shoes_canvas_get_scroll_top(VALUE self)
95
+ {
96
+ GET_STRUCT(canvas, canvas);
97
+ return INT2NUM(canvas->slot->scrolly);
98
+ }
99
+
100
+ VALUE
101
+ shoes_canvas_set_scroll_top(VALUE self, VALUE num)
102
+ {
103
+ SETUP();
104
+ shoes_slot_scroll_to(canvas, NUM2INT(num), 0);
105
+ return num;
106
+ }
107
+
108
+ VALUE
109
+ shoes_canvas_get_scroll_max(VALUE self)
110
+ {
111
+ SETUP();
112
+ return INT2NUM(max(0, canvas->fully - canvas->height));
113
+ }
114
+
115
+ VALUE
116
+ shoes_canvas_get_scroll_height(VALUE self)
117
+ {
118
+ SETUP();
119
+ return INT2NUM(canvas->fully);
120
+ }
121
+
122
+ VALUE
123
+ shoes_canvas_get_gutter_width(VALUE self)
124
+ {
125
+ int scrollwidth = 0;
126
+ GET_STRUCT(canvas, canvas);
127
+ scrollwidth = shoes_native_slot_gutter(canvas->slot);
128
+ return INT2NUM(scrollwidth);
129
+ }
130
+
131
+ VALUE
132
+ shoes_canvas_displace(VALUE self, VALUE dx, VALUE dy)
133
+ {
134
+ SETUP();
135
+ ATTRSET(canvas->attr, displace_left, dx);
136
+ ATTRSET(canvas->attr, displace_top, dy);
137
+ shoes_canvas_repaint_all(canvas->parent);
138
+ return self;
139
+ }
140
+
141
+ VALUE
142
+ shoes_canvas_move(VALUE self, VALUE x, VALUE y)
143
+ {
144
+ SETUP();
145
+ ATTRSET(canvas->attr, left, x);
146
+ ATTRSET(canvas->attr, top, y);
147
+ shoes_canvas_repaint_all(canvas->parent);
148
+ return self;
149
+ }
150
+
151
+ VALUE
152
+ shoes_canvas_style(int argc, VALUE *argv, VALUE self)
153
+ {
154
+ rb_arg_list args;
155
+ SETUP();
156
+
157
+ switch (rb_parse_args(argc, argv, "kh,h,", &args))
158
+ {
159
+ case 1:
160
+ shoes_app_style(canvas->app, args.a[0], args.a[1]);
161
+ break;
162
+
163
+ case 2:
164
+ if (NIL_P(canvas->attr)) canvas->attr = rb_hash_new();
165
+ rb_funcall(canvas->attr, s_update, 1, args.a[0]);
166
+ shoes_canvas_repaint_all(canvas->parent);
167
+ break;
168
+
169
+ case 3: return rb_obj_freeze(rb_obj_dup(canvas->attr));
170
+ }
171
+
172
+ return self;
173
+ }
174
+
175
+ #define ELAPSED (shoes_diff_time(&start, &mid) * 0.001)
176
+
177
+ static VALUE
178
+ shoes_canvas_paint_call(VALUE self)
179
+ {
180
+ shoes_code code = SHOES_OK;
181
+ SHOES_TIME start, mid;
182
+ shoes_get_time(&start);
183
+
184
+ if (self == Qnil)
185
+ return self;
186
+
187
+ SETUP();
188
+ if (canvas->cr != NULL)
189
+ goto quit;
190
+
191
+ canvas->cr = cr = shoes_cairo_create(canvas);
192
+ if (cr == NULL)
193
+ goto quit;
194
+
195
+ cairo_save(cr);
196
+ shoes_canvas_draw(self, self, Qfalse);
197
+ shoes_get_time(&mid);
198
+ INFO("COMPUTE: %0.6f s\n", ELAPSED);
199
+ cairo_restore(cr);
200
+
201
+ canvas->cr = cr;
202
+ cairo_save(cr);
203
+ shoes_canvas_draw(self, self, Qtrue);
204
+ shoes_get_time(&mid);
205
+ INFO("DRAW: %0.6f s\n", ELAPSED);
206
+ cairo_restore(cr);
207
+
208
+ if (cairo_status(cr)) {
209
+ code = SHOES_FAIL;
210
+ PUTS("Cairo is unhappy: %s\n", cairo_status_to_string (cairo_status (cr)));
211
+ goto quit;
212
+ }
213
+
214
+ cairo_destroy(cr);
215
+ cr = canvas->cr = NULL;
216
+
217
+ shoes_cairo_destroy(canvas);
218
+ shoes_get_time(&mid);
219
+ INFO("PAINT: %0.6f s\n", ELAPSED);
220
+ shoes_canvas_send_start(self);
221
+ quit:
222
+ if (cr != NULL) cairo_destroy(cr);
223
+ return self;
224
+ }
225
+
226
+ void
227
+ shoes_canvas_paint(VALUE self)
228
+ {
229
+ rb_rescue2(CASTHOOK(shoes_canvas_paint_call), self,
230
+ CASTHOOK(shoes_canvas_error), self, rb_cObject, 0);
231
+ return;
232
+ }
233
+
234
+ void
235
+ shoes_apply_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force)
236
+ {
237
+ double x, y, w, h;
238
+ cairo_save(cr);
239
+ w = place->iw / 2.;
240
+ h = place->ih / 2.;
241
+ if (st != NULL)
242
+ {
243
+ x = (place->ix + place->dx) + w;
244
+ y = (place->iy + place->dy) + h;
245
+
246
+ if (st->mode == s_center)
247
+ cairo_translate(cr, x, y);
248
+ cairo_transform(cr, &st->tf);
249
+ if (st->mode == s_center)
250
+ cairo_translate(cr, -x, -y);
251
+ }
252
+ }
253
+
254
+ void
255
+ shoes_undo_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force)
256
+ {
257
+ cairo_restore(cr);
258
+ }
259
+
260
+ static VALUE
261
+ shoes_add_ele(shoes_canvas *canvas, VALUE ele)
262
+ {
263
+ if (NIL_P(ele)) return ele;
264
+ if (canvas->insertion <= -1)
265
+ rb_ary_push(canvas->contents, ele);
266
+ else
267
+ {
268
+ rb_ary_insert_at(canvas->contents, canvas->insertion, 0, ele);
269
+ canvas->insertion++;
270
+ }
271
+ return ele;
272
+ }
273
+
274
+ void
275
+ shoes_canvas_mark(shoes_canvas *canvas)
276
+ {
277
+ shoes_native_slot_mark(canvas->slot);
278
+ rb_gc_mark_maybe(canvas->contents);
279
+ rb_gc_mark_maybe(canvas->attr);
280
+ rb_gc_mark_maybe(canvas->parent);
281
+ }
282
+
283
+ static void
284
+ shoes_canvas_reset_transform(shoes_canvas *canvas)
285
+ {
286
+ if (canvas->sts != NULL)
287
+ {
288
+ int i;
289
+ for (i = 0; i < canvas->stl; i++)
290
+ shoes_transform_release(canvas->sts[i]);
291
+ SHOE_FREE(canvas->sts);
292
+ canvas->sts = NULL;
293
+ }
294
+ canvas->stl = 0;
295
+ canvas->stt = 0;
296
+
297
+ if (canvas->st != NULL)
298
+ {
299
+ shoes_transform_release(canvas->st);
300
+ canvas->st = NULL;
301
+ }
302
+ }
303
+
304
+ static void
305
+ shoes_canvas_free(shoes_canvas *canvas)
306
+ {
307
+ if (canvas->slot != NULL && canvas->slot->owner == canvas)
308
+ SHOE_FREE(canvas->slot);
309
+ shoes_canvas_reset_transform(canvas);
310
+ RUBY_CRITICAL(free(canvas));
311
+ }
312
+
313
+ VALUE
314
+ shoes_canvas_alloc(VALUE klass)
315
+ {
316
+ shoes_canvas *canvas = SHOE_ALLOC(shoes_canvas);
317
+ SHOE_MEMZERO(canvas, shoes_canvas, 1);
318
+ canvas->app = NULL;
319
+ canvas->stage = CANVAS_NADA;
320
+ canvas->contents = Qnil;
321
+ canvas->shape = NULL;
322
+ canvas->insertion = -2;
323
+ VALUE rb_canvas = Data_Wrap_Struct(klass, shoes_canvas_mark, shoes_canvas_free, canvas);
324
+ return rb_canvas;
325
+ }
326
+
327
+ VALUE
328
+ shoes_canvas_new(VALUE klass, shoes_app *app)
329
+ {
330
+ shoes_canvas *canvas;
331
+ VALUE self = shoes_canvas_alloc(klass);
332
+ Data_Get_Struct(self, shoes_canvas, canvas);
333
+ canvas->app = app;
334
+ return self;
335
+ }
336
+
337
+ static void
338
+ shoes_canvas_empty(shoes_canvas *canvas, int extras)
339
+ {
340
+ unsigned char stage = canvas->stage;
341
+ canvas->stage = CANVAS_EMPTY;
342
+ shoes_ele_remove_all(canvas->contents);
343
+ if (extras) shoes_extras_remove_all(canvas);
344
+ canvas->stage = stage;
345
+ }
346
+
347
+ void
348
+ shoes_canvas_clear(VALUE self)
349
+ {
350
+ shoes_canvas *canvas;
351
+ Data_Get_Struct(self, shoes_canvas, canvas);
352
+ canvas->cr = NULL;
353
+ canvas->attr = rb_hash_new();
354
+ ATTRSET(canvas->attr, cap, Qnil);
355
+ ATTRSET(canvas->attr, strokewidth, rb_float_new(1.));
356
+ ATTRSET(canvas->attr, stroke, shoes_color_new(0, 0, 0, 0xFF));
357
+ ATTRSET(canvas->attr, fill, shoes_color_new(0, 0, 0, 0xFF));
358
+ canvas->parent = Qnil;
359
+ canvas->stl = 0;
360
+ canvas->stt = 0;
361
+ shoes_canvas_reset_transform(canvas);
362
+ shoes_canvas_empty(canvas, TRUE);
363
+ canvas->contents = rb_ary_new();
364
+ canvas->place.x = canvas->place.y = 0;
365
+ canvas->place.dx = canvas->place.dy = 0;
366
+ canvas->place.ix = canvas->place.iy = 0;
367
+ canvas->hover = 0;
368
+ canvas->cx = 0;
369
+ canvas->cy = 0;
370
+ canvas->endy = 0;
371
+ canvas->endx = 0;
372
+ canvas->topy = 0;
373
+ canvas->fully = 0;
374
+ shoes_group_clear(&canvas->group);
375
+ }
376
+
377
+ shoes_canvas *
378
+ shoes_canvas_init(VALUE self, SHOES_SLOT_OS *slot, VALUE attr, int width, int height)
379
+ {
380
+ shoes_canvas *canvas;
381
+ Data_Get_Struct(self, shoes_canvas, canvas);
382
+ canvas->attr = attr;
383
+ canvas->place.iw = canvas->place.w = canvas->width = width;
384
+ canvas->place.ih = canvas->place.h = canvas->height = height;
385
+ return canvas;
386
+ }
387
+
388
+ void
389
+ shoes_slot_scroll_to(shoes_canvas *canvas, int dy, int rel)
390
+ {
391
+ if (rel)
392
+ canvas->slot->scrolly += dy;
393
+ else
394
+ canvas->slot->scrolly = dy;
395
+
396
+ if (canvas->slot->scrolly > canvas->endy - canvas->height)
397
+ canvas->slot->scrolly = canvas->endy - canvas->height;
398
+ if (canvas->slot->scrolly < 0)
399
+ canvas->slot->scrolly = 0;
400
+ if (DC(canvas->app->slot) == DC(canvas->slot)) canvas->app->slot->scrolly = canvas->slot->scrolly;
401
+ shoes_native_slot_scroll_top(canvas->slot);
402
+ shoes_slot_repaint(canvas->slot);
403
+ }
404
+
405
+ VALUE
406
+ shoes_canvas_nostroke(VALUE self)
407
+ {
408
+ SETUP_BASIC();
409
+ ATTRSET(basic->attr, stroke, Qnil);
410
+ return self;
411
+ }
412
+
413
+ VALUE
414
+ shoes_canvas_stroke(int argc, VALUE *argv, VALUE self)
415
+ {
416
+ VALUE pat;
417
+ SETUP_BASIC();
418
+ if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
419
+ pat = argv[0];
420
+ else
421
+ pat = shoes_pattern_args(argc, argv, self);
422
+ if (!rb_obj_is_kind_of(pat, cColor))
423
+ pat = rb_funcall(pat, s_to_pattern, 0);
424
+ ATTRSET(basic->attr, stroke, pat);
425
+ return pat;
426
+ }
427
+
428
+ VALUE
429
+ shoes_canvas_strokewidth(VALUE self, VALUE w)
430
+ {
431
+ SETUP_BASIC();
432
+ ATTRSET(basic->attr, strokewidth, w);
433
+ return self;
434
+ }
435
+
436
+ VALUE
437
+ shoes_canvas_dash(VALUE self, VALUE dash)
438
+ {
439
+ SETUP_BASIC();
440
+ ATTRSET(basic->attr, dash, dash);
441
+ return self;
442
+ }
443
+
444
+ VALUE
445
+ shoes_canvas_cap(VALUE self, VALUE cap)
446
+ {
447
+ SETUP_BASIC();
448
+ ATTRSET(basic->attr, cap, cap);
449
+ return self;
450
+ }
451
+
452
+ VALUE
453
+ shoes_canvas_nofill(VALUE self)
454
+ {
455
+ SETUP_BASIC();
456
+ ATTRSET(basic->attr, fill, Qnil);
457
+ return self;
458
+ }
459
+
460
+ VALUE
461
+ shoes_canvas_fill(int argc, VALUE *argv, VALUE self)
462
+ {
463
+ VALUE pat;
464
+ SETUP_BASIC();
465
+ if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
466
+ pat = argv[0];
467
+ else
468
+ pat = shoes_pattern_args(argc, argv, self);
469
+ if (!rb_obj_is_kind_of(pat, cColor))
470
+ pat = rb_funcall(pat, s_to_pattern, 0);
471
+ ATTRSET(basic->attr, fill, pat);
472
+ return pat;
473
+ }
474
+
475
+ VALUE
476
+ shoes_add_shape(VALUE self, ID name, VALUE attr, cairo_path_t *line)
477
+ {
478
+ if (rb_obj_is_kind_of(self, cImage))
479
+ {
480
+ SETUP_IMAGE();
481
+ shoes_shape_sketch(image->cr, name, &place, NULL, attr, line, 1);
482
+ return self;
483
+ }
484
+
485
+ SETUP();
486
+ if (canvas->shape != NULL)
487
+ {
488
+ shoes_place place;
489
+ shoes_place_exact(&place, attr, 0, 0);
490
+ cairo_new_sub_path(canvas->shape);
491
+ shoes_shape_sketch(canvas->shape, name, &place, canvas->st, attr, line, 0);
492
+ return self;
493
+ }
494
+
495
+ return shoes_add_ele(canvas, shoes_shape_new(self, name, attr, canvas->st, line));
496
+ }
497
+
498
+ VALUE
499
+ shoes_canvas_arc(int argc, VALUE *argv, VALUE self)
500
+ {
501
+ VALUE attr = shoes_shape_attr(argc, argv, 6, s_left, s_top, s_width, s_height, s_angle1, s_angle2);
502
+ return shoes_add_shape(self, s_arc, attr, NULL);
503
+ }
504
+
505
+ VALUE
506
+ shoes_canvas_rect(int argc, VALUE *argv, VALUE self)
507
+ {
508
+ VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_width, s_height, s_curve);
509
+ return shoes_add_shape(self, s_rect, attr, NULL);
510
+ }
511
+
512
+ VALUE
513
+ shoes_canvas_oval(int argc, VALUE *argv, VALUE self)
514
+ {
515
+ VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_width, s_height);
516
+ return shoes_add_shape(self, s_oval, attr, NULL);
517
+ }
518
+
519
+ VALUE
520
+ shoes_canvas_line(int argc, VALUE *argv, VALUE self)
521
+ {
522
+ VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_right, s_bottom);
523
+ return shoes_add_shape(self, s_line, attr, NULL);
524
+ }
525
+
526
+ VALUE
527
+ shoes_canvas_arrow(int argc, VALUE *argv, VALUE self)
528
+ {
529
+ VALUE attr = shoes_shape_attr(argc, argv, 3, s_left, s_top, s_width);
530
+ return shoes_add_shape(self, s_arrow, attr, NULL);
531
+ }
532
+
533
+ VALUE
534
+ shoes_canvas_star(int argc, VALUE *argv, VALUE self)
535
+ {
536
+ VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_points, s_outer, s_inner);
537
+ return shoes_add_shape(self, s_star, attr, NULL);
538
+ }
539
+
540
+ VALUE
541
+ shoes_add_effect(VALUE self, ID name, VALUE attr)
542
+ {
543
+ if (rb_obj_is_kind_of(self, cImage))
544
+ {
545
+ shoes_effect_filter filter = shoes_effect_for_type(name);
546
+ SETUP_IMAGE();
547
+ if (filter == NULL) return self;
548
+ filter(image->cr, attr, &place);
549
+ return self;
550
+ }
551
+
552
+ SETUP();
553
+ return shoes_add_ele(canvas, shoes_effect_new(name, attr, self));
554
+ }
555
+
556
+ VALUE
557
+ shoes_canvas_blur(int argc, VALUE *argv, VALUE self)
558
+ {
559
+ VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
560
+ return shoes_add_effect(self, s_blur, attr);
561
+ }
562
+
563
+ VALUE
564
+ shoes_canvas_glow(int argc, VALUE *argv, VALUE self)
565
+ {
566
+ VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
567
+ return shoes_add_effect(self, s_glow, attr);
568
+ }
569
+
570
+ VALUE
571
+ shoes_canvas_shadow(int argc, VALUE *argv, VALUE self)
572
+ {
573
+ VALUE attr = shoes_shape_attr(argc, argv, 2, s_distance, s_radius);
574
+ return shoes_add_effect(self, s_shadow, attr);
575
+ }
576
+
577
+ #define MARKUP_BLOCK(klass) \
578
+ text = shoes_textblock_new(klass, msgs, attr, self, canvas->st); \
579
+ shoes_add_ele(canvas, text)
580
+
581
+ #define MARKUP_INLINE(klass) \
582
+ text = shoes_text_new(klass, msgs, attr)
583
+
584
+ #define MARKUP_DEF(mname, fname, klass) \
585
+ VALUE \
586
+ shoes_canvas_##mname(int argc, VALUE *argv, VALUE self) \
587
+ { \
588
+ long i; \
589
+ VALUE msgs, attr, text; \
590
+ SETUP(); \
591
+ msgs = rb_ary_new(); \
592
+ attr = Qnil; \
593
+ for (i = 0; i < argc; i++) \
594
+ { \
595
+ if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
596
+ attr = argv[i]; \
597
+ else \
598
+ rb_ary_push(msgs, argv[i]); \
599
+ } \
600
+ MARKUP_##fname(klass); \
601
+ return text; \
602
+ }
603
+
604
+ MARKUP_DEF(para, BLOCK, cPara);
605
+ MARKUP_DEF(banner, BLOCK, cBanner);
606
+ MARKUP_DEF(title, BLOCK, cTitle);
607
+ MARKUP_DEF(subtitle, BLOCK, cSubtitle);
608
+ MARKUP_DEF(tagline, BLOCK, cTagline);
609
+ MARKUP_DEF(caption, BLOCK, cCaption);
610
+ MARKUP_DEF(inscription, BLOCK, cInscription);
611
+
612
+ MARKUP_DEF(code, INLINE, cCode);
613
+ MARKUP_DEF(del, INLINE, cDel);
614
+ MARKUP_DEF(em, INLINE, cEm);
615
+ MARKUP_DEF(ins, INLINE, cIns);
616
+ MARKUP_DEF(span, INLINE, cSpan);
617
+ MARKUP_DEF(strong, INLINE, cStrong);
618
+ MARKUP_DEF(sub, INLINE, cSub);
619
+ MARKUP_DEF(sup, INLINE, cSup);
620
+
621
+ VALUE
622
+ shoes_canvas_link(int argc, VALUE *argv, VALUE self)
623
+ {
624
+ long i;
625
+ VALUE msgs, attr, text;
626
+ SETUP();
627
+ msgs = rb_ary_new();
628
+ attr = Qnil;
629
+ for (i = 0; i < argc; i++)
630
+ {
631
+ if (rb_obj_is_kind_of(argv[i], rb_cHash))
632
+ attr = argv[i];
633
+ else
634
+ rb_ary_push(msgs, argv[i]);
635
+ }
636
+
637
+ if (rb_block_given_p())
638
+ {
639
+ if (NIL_P(attr)) attr = rb_hash_new();
640
+ rb_hash_aset(attr, ID2SYM(s_click), rb_block_proc());
641
+ }
642
+
643
+ MARKUP_INLINE(cLink);
644
+ return text;
645
+ }
646
+
647
+ VALUE
648
+ shoes_canvas_imagesize(VALUE self, VALUE _path)
649
+ {
650
+ int w, h;
651
+ if (shoes_load_imagesize(_path, &w, &h) == SHOES_OK)
652
+ return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
653
+ return Qnil;
654
+ }
655
+
656
+ VALUE
657
+ shoes_canvas_background(int argc, VALUE *argv, VALUE self)
658
+ {
659
+ VALUE pat;
660
+ SETUP();
661
+ if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
662
+ pat = argv[0];
663
+ else
664
+ pat = shoes_pattern_args(argc, argv, self);
665
+ if (!NIL_P(pat))
666
+ {
667
+ pat = rb_funcall(pat, s_to_pattern, 0);
668
+ pat = shoes_subpattern_new(cBackground, pat, self);
669
+ shoes_add_ele(canvas, pat);
670
+ }
671
+ return pat;
672
+ }
673
+
674
+ VALUE
675
+ shoes_canvas_border(int argc, VALUE *argv, VALUE self)
676
+ {
677
+ VALUE pat;
678
+ SETUP();
679
+ if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
680
+ pat = argv[0];
681
+ else
682
+ pat = shoes_pattern_args(argc, argv, self);
683
+ if (!NIL_P(pat))
684
+ {
685
+ pat = rb_funcall(pat, s_to_pattern, 0);
686
+ pat = shoes_subpattern_new(cBorder, pat, self);
687
+ shoes_add_ele(canvas, pat);
688
+ }
689
+ return pat;
690
+ }
691
+
692
+ VALUE
693
+ shoes_canvas_video(int argc, VALUE *argv, VALUE self)
694
+ {
695
+ #ifdef VIDEO
696
+ VALUE video;
697
+ rb_arg_list args;
698
+ SETUP();
699
+
700
+ rb_parse_args(argc, argv, "s|h", &args);
701
+ video = shoes_video_new(cVideo, args.a[0], args.a[1], self);
702
+ shoes_add_ele(canvas, video);
703
+ return video;
704
+ #else
705
+ rb_raise(eNotImpl, "no video support");
706
+ #endif
707
+ }
708
+
709
+ VALUE
710
+ shoes_canvas_image(int argc, VALUE *argv, VALUE self)
711
+ {
712
+ rb_arg_list args;
713
+ VALUE path = Qnil, attr = Qnil, _w, _h, image;
714
+
715
+ switch (rb_parse_args(argc, argv, "ii|h,s|h,|h", &args))
716
+ {
717
+ case 1:
718
+ _w = args.a[0];
719
+ _h = args.a[1];
720
+ attr = args.a[2];
721
+ ATTRSET(attr, width, _w);
722
+ ATTRSET(attr, height, _h);
723
+ if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
724
+ break;
725
+
726
+ case 2:
727
+ path = args.a[0];
728
+ attr = args.a[1];
729
+ if (rb_block_given_p()) ATTRSET(attr, click, rb_block_proc());
730
+ break;
731
+
732
+ case 3:
733
+ attr = args.a[0];
734
+ if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
735
+ break;
736
+ }
737
+
738
+ if (rb_obj_is_kind_of(self, cImage))
739
+ {
740
+ shoes_image_image(self, path, attr);
741
+ return self;
742
+ }
743
+
744
+ SETUP();
745
+ image = shoes_image_new(cImage, path, attr, self, canvas->st);
746
+ shoes_add_ele(canvas, image);
747
+
748
+ return image;
749
+ }
750
+
751
+ VALUE
752
+ shoes_canvas_animate(int argc, VALUE *argv, VALUE self)
753
+ {
754
+ rb_arg_list args;
755
+ VALUE anim;
756
+ SETUP();
757
+
758
+ rb_parse_args(argc, argv, "|I&", &args);
759
+ anim = shoes_timer_new(cAnim, args.a[0], args.a[1], self);
760
+ rb_ary_push(canvas->app->extras, anim);
761
+ return anim;
762
+ }
763
+
764
+ VALUE
765
+ shoes_canvas_every(int argc, VALUE *argv, VALUE self)
766
+ {
767
+ rb_arg_list args;
768
+ VALUE ev;
769
+ SETUP();
770
+
771
+ rb_parse_args(argc, argv, "|F&", &args);
772
+ ev = shoes_timer_new(cEvery, args.a[0], args.a[1], self);
773
+ rb_ary_push(canvas->app->extras, ev);
774
+ return ev;
775
+ }
776
+
777
+ VALUE
778
+ shoes_canvas_timer(int argc, VALUE *argv, VALUE self)
779
+ {
780
+ rb_arg_list args;
781
+ VALUE timer;
782
+ SETUP();
783
+
784
+ rb_parse_args(argc, argv, "|I&", &args);
785
+ timer = shoes_timer_new(cTimer, args.a[0], args.a[1], self);
786
+ rb_ary_push(canvas->app->extras, timer);
787
+ return timer;
788
+ }
789
+
790
+ VALUE
791
+ shoes_canvas_shape(int argc, VALUE *argv, VALUE self)
792
+ {
793
+ int x;
794
+ double x1, y1, x2, y2;
795
+ cairo_t *shape = NULL;
796
+ cairo_path_t *line = NULL;
797
+ SETUP_SHAPE();
798
+
799
+ shape = canvas->shape;
800
+ VALUE attr = shoes_shape_attr(argc, argv, 2, s_left, s_top);
801
+ canvas->shape = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
802
+ cairo_move_to(canvas->shape, 0, 0);
803
+ if (rb_block_given_p()) rb_funcall(rb_block_proc(), s_call, 0);
804
+
805
+ #if CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR <= 4
806
+ cairo_fill_extents(canvas->shape, &x1, &y1, &x2, &y2);
807
+ #else
808
+ cairo_path_extents(canvas->shape, &x1, &y1, &x2, &y2);
809
+ #endif
810
+ x = x2 - x1;
811
+ ATTRSET(attr, width, INT2NUM(x));
812
+ x = y2 - y1;
813
+ ATTRSET(attr, height, INT2NUM(x));
814
+ line = cairo_copy_path(canvas->shape);
815
+ canvas->shape = shape;
816
+ return shoes_add_shape(self, s_shape, attr, line);
817
+ }
818
+
819
+ VALUE
820
+ shoes_canvas_move_to(VALUE self, VALUE _x, VALUE _y)
821
+ {
822
+ double x, y;
823
+ SETUP_SHAPE();
824
+
825
+ x = NUM2DBL(_x);
826
+ y = NUM2DBL(_y);
827
+
828
+ if (canvas->shape != NULL) cairo_move_to(canvas->shape, x, y);
829
+ return self;
830
+ }
831
+
832
+ VALUE
833
+ shoes_canvas_line_to(VALUE self, VALUE _x, VALUE _y)
834
+ {
835
+ double x, y;
836
+ SETUP_SHAPE();
837
+
838
+ x = NUM2DBL(_x);
839
+ y = NUM2DBL(_y);
840
+
841
+ if (canvas->shape != NULL) cairo_line_to(canvas->shape, x, y);
842
+ return self;
843
+ }
844
+
845
+ VALUE
846
+ shoes_canvas_curve_to(VALUE self, VALUE _x1, VALUE _y1, VALUE _x2, VALUE _y2, VALUE _x3, VALUE _y3)
847
+ {
848
+ double x1, y1, x2, y2, x3, y3;
849
+ SETUP_SHAPE();
850
+
851
+ x1 = NUM2DBL(_x1);
852
+ y1 = NUM2DBL(_y1);
853
+ x2 = NUM2DBL(_x2);
854
+ y2 = NUM2DBL(_y2);
855
+ x3 = NUM2DBL(_x3);
856
+ y3 = NUM2DBL(_y3);
857
+
858
+ if (canvas->shape != NULL) cairo_curve_to(canvas->shape, x1, y1, x2, y2, x3, y3);
859
+ return self;
860
+ }
861
+
862
+ VALUE
863
+ shoes_canvas_arc_to(VALUE self, VALUE _x, VALUE _y, VALUE _w, VALUE _h, VALUE _a1, VALUE _a2)
864
+ {
865
+ double x, y, w, h, a1, a2;
866
+ SETUP_SHAPE();
867
+
868
+ x = NUM2DBL(_x);
869
+ y = NUM2DBL(_y);
870
+ w = NUM2DBL(_w);
871
+ h = NUM2DBL(_h);
872
+ a1 = NUM2DBL(_a1);
873
+ a2 = NUM2DBL(_a2);
874
+
875
+ if (canvas->shape != NULL)
876
+ {
877
+ cairo_save(canvas->shape);
878
+ shoes_cairo_arc(canvas->shape, x, y, w, h, a1, a2);
879
+ cairo_restore(canvas->shape);
880
+ }
881
+ return self;
882
+ }
883
+
884
+ VALUE
885
+ shoes_canvas_push(VALUE self)
886
+ {
887
+ shoes_transform *m;
888
+ SETUP();
889
+
890
+ m = canvas->st;
891
+ if (canvas->stl + 1 > canvas->stt)
892
+ {
893
+ canvas->stt += 8;
894
+ SHOE_REALLOC_N(canvas->sts, shoes_transform *, canvas->stt);
895
+ }
896
+ canvas->st = shoes_transform_new(m);
897
+ canvas->sts[canvas->stl++] = m;
898
+ return self;
899
+ }
900
+
901
+ VALUE
902
+ shoes_canvas_pop(VALUE self)
903
+ {
904
+ SETUP();
905
+
906
+ if (canvas->stl >= 1)
907
+ {
908
+ shoes_transform_release(canvas->st);
909
+ canvas->stl--;
910
+ canvas->st = canvas->sts[canvas->stl];
911
+ }
912
+ return self;
913
+ }
914
+
915
+ VALUE
916
+ shoes_canvas_reset(VALUE self)
917
+ {
918
+ SETUP();
919
+ shoes_canvas_reset_transform(canvas);
920
+ return self;
921
+ }
922
+
923
+ VALUE
924
+ shoes_canvas_button(int argc, VALUE *argv, VALUE self)
925
+ {
926
+ rb_arg_list args;
927
+ VALUE text = Qnil, attr = Qnil, button;
928
+ SETUP();
929
+
930
+ switch (rb_parse_args(argc, argv, "s|h,|h", &args))
931
+ {
932
+ case 1:
933
+ text = args.a[0];
934
+ attr = args.a[1];
935
+ break;
936
+
937
+ case 2:
938
+ attr = args.a[0];
939
+ break;
940
+ }
941
+
942
+ if (!NIL_P(text))
943
+ ATTRSET(attr, text, text);
944
+
945
+ if (rb_block_given_p())
946
+ ATTRSET(attr, click, rb_block_proc());
947
+
948
+ button = shoes_control_new(cButton, attr, self);
949
+ shoes_add_ele(canvas, button);
950
+ return button;
951
+ }
952
+
953
+ VALUE
954
+ shoes_canvas_edit_line(int argc, VALUE *argv, VALUE self)
955
+ {
956
+ rb_arg_list args;
957
+ VALUE phrase = Qnil, attr = Qnil, edit_line;
958
+ SETUP();
959
+
960
+ switch (rb_parse_args(argc, argv, "h,S|h,", &args))
961
+ {
962
+ case 1:
963
+ attr = args.a[0];
964
+ break;
965
+
966
+ case 2:
967
+ phrase = args.a[0];
968
+ attr = args.a[1];
969
+ break;
970
+ }
971
+
972
+ if (!NIL_P(phrase))
973
+ ATTRSET(attr, text, phrase);
974
+
975
+ if (rb_block_given_p())
976
+ ATTRSET(attr, change, rb_block_proc());
977
+
978
+ edit_line = shoes_control_new(cEditLine, attr, self);
979
+ shoes_add_ele(canvas, edit_line);
980
+ return edit_line;
981
+ }
982
+
983
+ VALUE
984
+ shoes_canvas_edit_box(int argc, VALUE *argv, VALUE self)
985
+ {
986
+ rb_arg_list args;
987
+ VALUE phrase = Qnil, attr = Qnil, edit_box;
988
+ SETUP();
989
+
990
+ switch (rb_parse_args(argc, argv, "h,S|h,", &args))
991
+ {
992
+ case 1:
993
+ attr = args.a[0];
994
+ break;
995
+
996
+ case 2:
997
+ phrase = args.a[0];
998
+ attr = args.a[1];
999
+ break;
1000
+ }
1001
+
1002
+ if (!NIL_P(phrase))
1003
+ ATTRSET(attr, text, phrase);
1004
+
1005
+ if (rb_block_given_p())
1006
+ ATTRSET(attr, change, rb_block_proc());
1007
+
1008
+ edit_box = shoes_control_new(cEditBox, attr, self);
1009
+ shoes_add_ele(canvas, edit_box);
1010
+ return edit_box;
1011
+ }
1012
+
1013
+ VALUE
1014
+ shoes_canvas_list_box(int argc, VALUE *argv, VALUE self)
1015
+ {
1016
+ rb_arg_list args;
1017
+ VALUE list_box;
1018
+ SETUP();
1019
+
1020
+ rb_parse_args(argc, argv, "|h&", &args);
1021
+
1022
+ if (!NIL_P(args.a[1]))
1023
+ ATTRSET(args.a[0], change, args.a[1]);
1024
+
1025
+ list_box = shoes_control_new(cListBox, args.a[0], self);
1026
+ shoes_add_ele(canvas, list_box);
1027
+ return list_box;
1028
+ }
1029
+
1030
+ VALUE
1031
+ shoes_canvas_progress(int argc, VALUE *argv, VALUE self)
1032
+ {
1033
+ rb_arg_list args;
1034
+ VALUE progress;
1035
+ SETUP();
1036
+
1037
+ rb_parse_args(argc, argv, "|h", &args);
1038
+ progress = shoes_control_new(cProgress, args.a[0], self);
1039
+ shoes_add_ele(canvas, progress);
1040
+ return progress;
1041
+ }
1042
+
1043
+ VALUE
1044
+ shoes_canvas_slider(int argc, VALUE *argv, VALUE self)
1045
+ {
1046
+ rb_arg_list args;
1047
+ VALUE slider;
1048
+ SETUP();
1049
+
1050
+ rb_parse_args(argc, argv, "|h&", &args);
1051
+
1052
+ if (!NIL_P(args.a[1]))
1053
+ ATTRSET(args.a[0], change, args.a[1]);
1054
+
1055
+ slider = shoes_control_new(cSlider, args.a[0], self);
1056
+ shoes_add_ele(canvas, slider);
1057
+ return slider;
1058
+ }
1059
+
1060
+ VALUE
1061
+ shoes_canvas_radio(int argc, VALUE *argv, VALUE self)
1062
+ {
1063
+ rb_arg_list args;
1064
+ VALUE group = Qnil, attr = Qnil, radio;
1065
+ SETUP();
1066
+
1067
+ switch (rb_parse_args(argc, argv, "h,o|h,", &args))
1068
+ {
1069
+ case 1:
1070
+ attr = args.a[0];
1071
+ break;
1072
+
1073
+ case 2:
1074
+ group = args.a[0];
1075
+ attr = args.a[1];
1076
+ break;
1077
+ }
1078
+
1079
+ if (!NIL_P(group))
1080
+ ATTRSET(attr, group, group);
1081
+ if (rb_block_given_p())
1082
+ ATTRSET(attr, click, rb_block_proc());
1083
+
1084
+ radio = shoes_control_new(cRadio, attr, self);
1085
+ shoes_add_ele(canvas, radio);
1086
+ return radio;
1087
+ }
1088
+
1089
+ VALUE
1090
+ shoes_canvas_check(int argc, VALUE *argv, VALUE self)
1091
+ {
1092
+ rb_arg_list args;
1093
+ VALUE check;
1094
+ SETUP();
1095
+
1096
+ rb_parse_args(argc, argv, "|h", &args);
1097
+
1098
+ if (rb_block_given_p())
1099
+ ATTRSET(args.a[0], click, rb_block_proc());
1100
+
1101
+ check = shoes_control_new(cCheck, args.a[0], self);
1102
+ shoes_add_ele(canvas, check);
1103
+ return check;
1104
+ }
1105
+
1106
+ VALUE
1107
+ shoes_canvas_contents(VALUE self)
1108
+ {
1109
+ GET_STRUCT(canvas, self_t);
1110
+ return self_t->contents;
1111
+ }
1112
+
1113
+ VALUE
1114
+ shoes_canvas_children(VALUE self)
1115
+ {
1116
+ GET_STRUCT(canvas, self_t);
1117
+ return self_t->contents;
1118
+ }
1119
+
1120
+ void
1121
+ shoes_canvas_remove_item(VALUE self, VALUE item, char c, char t)
1122
+ {
1123
+ long i;
1124
+ shoes_canvas *self_t;
1125
+ Data_Get_Struct(self, shoes_canvas, self_t);
1126
+ shoes_native_remove_item(self_t->slot, item, c);
1127
+ if (t)
1128
+ {
1129
+ i = rb_ary_index_of(self_t->app->extras, item);
1130
+ if (i >= 0)
1131
+ rb_ary_insert_at(self_t->app->extras, i, 1, Qnil);
1132
+ }
1133
+ rb_ary_delete(self_t->contents, item);
1134
+ }
1135
+
1136
+ static int
1137
+ shoes_canvas_inherits(VALUE ele, shoes_canvas *pc)
1138
+ {
1139
+ if (rb_obj_is_kind_of(ele, cCanvas))
1140
+ {
1141
+ shoes_canvas *c;
1142
+ Data_Get_Struct(ele, shoes_canvas, c);
1143
+ return (pc == c || DC(c->slot) == DC(pc->slot));
1144
+ }
1145
+
1146
+ return TRUE;
1147
+ }
1148
+
1149
+ int
1150
+ shoes_canvas_independent(shoes_canvas *c)
1151
+ {
1152
+ shoes_canvas *pc;
1153
+ if (NIL_P(c->parent)) return TRUE;
1154
+
1155
+ Data_Get_Struct(c->parent, shoes_canvas, pc);
1156
+ return !(pc == c || DC(c->slot) == DC(pc->slot));
1157
+ }
1158
+
1159
+ static void
1160
+ shoes_canvas_reflow(shoes_canvas *self_t, VALUE c)
1161
+ {
1162
+ shoes_canvas *parent;
1163
+ Data_Get_Struct(c, shoes_canvas, parent);
1164
+
1165
+ self_t->cr = parent->cr;
1166
+ shoes_place_decide(&self_t->place, c, self_t->attr, parent->place.iw, 0, REL_CANVAS, FALSE);
1167
+ self_t->width = self_t->place.w;
1168
+ self_t->height = self_t->place.h;
1169
+
1170
+ self_t->cx = self_t->place.ix;
1171
+ self_t->cy = self_t->place.iy;
1172
+ self_t->endx = self_t->place.ix;
1173
+ self_t->endy = self_t->place.iy;
1174
+ INFO("REFLOW: %d, %d (%d, %d) / %d, %d / %d, %d (%d, %d)\n", self_t->cx, self_t->cy,
1175
+ self_t->endx, self_t->endy, self_t->place.x, self_t->place.y, self_t->width, self_t->height,
1176
+ parent->cx, parent->cy);
1177
+ }
1178
+
1179
+ VALUE
1180
+ shoes_canvas_remove(VALUE self)
1181
+ {
1182
+ shoes_canvas *self_t;
1183
+ Data_Get_Struct(self, shoes_canvas, self_t);
1184
+ shoes_canvas_empty(self_t, TRUE);
1185
+ if (!NIL_P(self_t->parent))
1186
+ {
1187
+ shoes_canvas *pc;
1188
+ shoes_canvas_remove_item(self_t->parent, self, 0, 0);
1189
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
1190
+ if (pc != self_t && DC(self_t->slot) != DC(pc->slot))
1191
+ shoes_slot_destroy(self_t, pc);
1192
+ }
1193
+ shoes_canvas_send_finish(self);
1194
+ return self;
1195
+ }
1196
+
1197
+ static void
1198
+ shoes_canvas_place(shoes_canvas *self_t)
1199
+ {
1200
+ shoes_canvas *pc;
1201
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
1202
+ shoes_native_canvas_place(self_t, pc);
1203
+ }
1204
+
1205
+ VALUE
1206
+ shoes_canvas_draw(VALUE self, VALUE c, VALUE actual)
1207
+ {
1208
+ long i;
1209
+ shoes_canvas *self_t;
1210
+ shoes_canvas *canvas;
1211
+ VALUE ck = rb_obj_class(self);
1212
+ Data_Get_Struct(self, shoes_canvas, self_t);
1213
+ Data_Get_Struct(c, shoes_canvas, canvas);
1214
+
1215
+ #ifdef SHOES_GTK
1216
+ if (!RTEST(actual))
1217
+ canvas->group.radios = NULL;
1218
+ #endif
1219
+
1220
+ if (self_t->height > self_t->fully)
1221
+ self_t->fully = self_t->height;
1222
+ if (self_t != canvas)
1223
+ {
1224
+ shoes_canvas_reflow(self_t, c);
1225
+ }
1226
+ else
1227
+ {
1228
+ self_t->endx = self_t->cx = 0;
1229
+ self_t->topy = self_t->endy = self_t->cy = 0;
1230
+ }
1231
+
1232
+ if (ATTR(self_t->attr, hidden) != Qtrue)
1233
+ {
1234
+ VALUE masks = Qnil;
1235
+ cairo_t *cr = NULL, *crc = NULL, *crm = NULL;
1236
+ cairo_surface_t *surfc = NULL, *surfm = NULL;
1237
+
1238
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
1239
+ {
1240
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1241
+ if (rb_obj_class(ele) == cMask)
1242
+ {
1243
+ if (NIL_P(masks)) masks = rb_ary_new();
1244
+ rb_ary_push(masks, ele);
1245
+ }
1246
+ }
1247
+
1248
+ if (!NIL_P(masks) && RTEST(actual))
1249
+ {
1250
+ cr = self_t->cr;
1251
+ surfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
1252
+ surfm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
1253
+ crc = cairo_create(surfc);
1254
+ crm = cairo_create(surfm);
1255
+ }
1256
+
1257
+ self_t->topy = canvas->cy;
1258
+
1259
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
1260
+ {
1261
+ shoes_canvas *c1;
1262
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1263
+ Data_Get_Struct(ele, shoes_canvas, c1);
1264
+
1265
+ if (shoes_canvas_inherits(ele, self_t))
1266
+ {
1267
+ if (!NIL_P(masks) && RTEST(actual))
1268
+ {
1269
+ if (rb_obj_class(ele) == cMask)
1270
+ self_t->cr = crm;
1271
+ else
1272
+ self_t->cr = crc;
1273
+ }
1274
+
1275
+ rb_funcall(ele, s_draw, 2, self, actual);
1276
+
1277
+ if (rb_obj_is_kind_of(ele, cCanvas))
1278
+ {
1279
+ long j;
1280
+ //
1281
+ // update the height of all canvases in this row
1282
+ //
1283
+ for (j = i - 1; j >= 0; j--)
1284
+ {
1285
+ shoes_canvas *c2;
1286
+ VALUE ele2 = rb_ary_entry(self_t->contents, j);
1287
+ if (rb_obj_is_kind_of(ele2, cCanvas))
1288
+ {
1289
+ Data_Get_Struct(ele2, shoes_canvas, c2);
1290
+ if (c2->topy < c1->topy || ABSY(c2->place) || POS(c2->place) != REL_CANVAS)
1291
+ break;
1292
+ if (c1->fully > c2->fully)
1293
+ c2->fully = c1->fully;
1294
+ else
1295
+ c1->fully = c2->fully;
1296
+ }
1297
+ }
1298
+ }
1299
+ }
1300
+ else
1301
+ {
1302
+ shoes_place_decide(&c1->place, c1->parent, c1->attr, self_t->place.iw, 0, REL_CANVAS, FALSE);
1303
+ c1->height = c1->place.ih;
1304
+ c1->width = c1->place.iw;
1305
+ c1->place.flags |= FLAG_ORIGIN;
1306
+ if (!ABSY(c1->place)) {
1307
+ self_t->cx = c1->place.x + c1->place.w;
1308
+ self_t->cy = c1->place.y;
1309
+ self_t->endx = self_t->cx;
1310
+ self_t->endy = max(self_t->endy, c1->place.y + c1->place.h);
1311
+ }
1312
+ if (ck == cStack) {
1313
+ self_t->cx = self_t->place.x;
1314
+ self_t->cy = self_t->endy;
1315
+ }
1316
+ if (RTEST(actual))
1317
+ {
1318
+ shoes_canvas_place(c1);
1319
+ }
1320
+ }
1321
+ }
1322
+
1323
+ if (!NIL_P(masks) && RTEST(actual))
1324
+ {
1325
+ cairo_set_source_surface(cr, surfc, 0., 0.);
1326
+ cairo_mask_surface(cr, surfm, 0., 0.);
1327
+ cairo_surface_destroy(surfm);
1328
+ cairo_surface_destroy(surfc);
1329
+ cairo_destroy(crc);
1330
+ cairo_destroy(crm);
1331
+ self_t->cr = cr;
1332
+ }
1333
+ }
1334
+
1335
+ if (self_t == canvas)
1336
+ {
1337
+ for (i = 0; i < RARRAY_LEN(self_t->app->extras); i++)
1338
+ {
1339
+ VALUE ele = rb_ary_entry(self_t->app->extras, i);
1340
+ if (rb_respond_to(ele, s_draw))
1341
+ rb_funcall(ele, s_draw, 2, self, actual);
1342
+ }
1343
+ }
1344
+
1345
+ canvas->endx = canvas->cx = self_t->place.x + self_t->width;
1346
+ if (canvas->endy < self_t->endy)
1347
+ canvas->endy = self_t->endy;
1348
+
1349
+ if (self_t == canvas || DC(self_t->slot) != DC(canvas->slot))
1350
+ {
1351
+ int endy = (int)self_t->endy;
1352
+ if (endy < self_t->height) endy = self_t->height;
1353
+ self_t->fully = endy;
1354
+ if (RTEST(actual))
1355
+ {
1356
+ self_t->slot->scrolly = min(self_t->slot->scrolly, self_t->fully - self_t->height);
1357
+ if (NIL_P(self_t->parent) || RTEST(ATTR(self_t->attr, scroll)))
1358
+ shoes_native_slot_lengthen(self_t->slot, self_t->height, endy);
1359
+ }
1360
+ }
1361
+ else
1362
+ {
1363
+ int bmargin = CPB(self_t);
1364
+ self_t->fully = canvas->endy = max(canvas->endy, self_t->endy + bmargin);
1365
+ self_t->place.ih = (canvas->endy - self_t->place.iy) - bmargin;
1366
+ self_t->place.h = canvas->endy - self_t->place.y;
1367
+ }
1368
+
1369
+ if (self_t->cr == canvas->cr)
1370
+ self_t->cr = NULL;
1371
+
1372
+ return self;
1373
+ }
1374
+
1375
+ static void
1376
+ shoes_canvas_memdraw(VALUE self, VALUE block)
1377
+ {
1378
+ SETUP();
1379
+ DRAW(self, canvas->app, rb_funcall(block, s_call, 0));
1380
+ }
1381
+
1382
+ typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
1383
+
1384
+ static cairo_surface_function_t *
1385
+ shoes_get_snapshot_surface(VALUE _format)
1386
+ {
1387
+ ID format = SYM2ID (_format);
1388
+ if (format == rb_intern ("pdf")) return & cairo_pdf_surface_create;
1389
+ if (format == rb_intern ("ps")) return & cairo_ps_surface_create;
1390
+ if (format == rb_intern ("svg")) return & cairo_svg_surface_create;
1391
+ return NULL;
1392
+ }
1393
+
1394
+ VALUE
1395
+ shoes_canvas_snapshot(int argc, VALUE *argv, VALUE self)
1396
+ {
1397
+ SETUP();
1398
+ rb_arg_list args;
1399
+ ID s_filename = rb_intern ("filename");
1400
+ ID s_format = rb_intern ("format");
1401
+ VALUE _filename, _format;
1402
+ // rb_parse_args(argc, argv, "h&", &args);
1403
+ rb_parse_args(argc, argv, "h", &args);
1404
+
1405
+ _filename = ATTR(args.a[0], filename);
1406
+ _format = ATTR(args.a[0], format);
1407
+ if (NIL_P(args.a[1]) || NIL_P(_filename) || NIL_P(_format))
1408
+ {
1409
+ rb_raise(rb_eArgError, "wrong arguments for _snapshot({:filename=>'...',"
1410
+ ":format=>:pdf|:ps|:svg}, &block)\n");
1411
+ }
1412
+ else
1413
+ {
1414
+ const char * filename = RSTRING_PTR(_filename);
1415
+ cairo_surface_t * surface = shoes_get_snapshot_surface (_format)
1416
+ (filename, canvas->width, canvas->height);
1417
+ if (surface == NULL) {
1418
+ rb_raise(rb_eArgError, "Failed to create %s surface for file %s\n",
1419
+ RSTRING_PTR(rb_inspect(_format)),
1420
+ RSTRING_PTR(rb_inspect(_filename)));
1421
+ }
1422
+ else
1423
+ {
1424
+ cairo_t * waz_cr = canvas->cr;
1425
+ cairo_t * cr = canvas->cr = cairo_create (surface);
1426
+ // DRAW(self, canvas->app, rb_funcall(args.a[1], s_call, 0));
1427
+ // shoes_canvas_draw (self, self, Qfalse);
1428
+ shoes_canvas_draw (self, self, Qtrue);
1429
+ // canvas->cr = waz_cr;
1430
+ cairo_show_page (cr);
1431
+ cairo_destroy (cr);
1432
+ cairo_surface_destroy (surface);
1433
+ // TODO detect cairo outrages here
1434
+ }
1435
+ }
1436
+ return Qnil;
1437
+ }
1438
+
1439
+ void
1440
+ shoes_canvas_compute(VALUE self)
1441
+ {
1442
+ SETUP();
1443
+ if (!shoes_canvas_independent(canvas))
1444
+ return shoes_canvas_compute(canvas->parent);
1445
+
1446
+ cairo_save(cr);
1447
+ shoes_canvas_draw(self, self, Qfalse);
1448
+ cairo_restore(cr);
1449
+ }
1450
+
1451
+ static void
1452
+ shoes_canvas_insert(VALUE self, long i, VALUE ele, VALUE block)
1453
+ {
1454
+ SETUP();
1455
+
1456
+ if (canvas->insertion != -2)
1457
+ rb_raise(eInvMode, "this slot is already being modified by an append, clear, etc.");
1458
+
1459
+ if (!NIL_P(ele))
1460
+ i = rb_ary_index_of(canvas->contents, ele) - i;
1461
+
1462
+ canvas->insertion = i;
1463
+ if (rb_respond_to(block, s_widget))
1464
+ rb_funcall(block, s_widget, 1, self);
1465
+ else
1466
+ shoes_canvas_memdraw(self, block);
1467
+ canvas->insertion = -2;
1468
+ shoes_canvas_repaint_all(self);
1469
+ }
1470
+
1471
+ VALUE
1472
+ shoes_canvas_after(int argc, VALUE *argv, VALUE self)
1473
+ {
1474
+ rb_arg_list args;
1475
+ rb_parse_args(argc, argv, "eo,e&", &args);
1476
+ shoes_canvas_insert(self, -1, args.a[0], args.a[1]);
1477
+ return self;
1478
+ }
1479
+
1480
+ VALUE
1481
+ shoes_canvas_before(int argc, VALUE *argv, VALUE self)
1482
+ {
1483
+ rb_arg_list args;
1484
+ rb_parse_args(argc, argv, "eo,e&", &args);
1485
+ shoes_canvas_insert(self, 0, args.a[0], args.a[1]);
1486
+ return self;
1487
+ }
1488
+
1489
+ VALUE
1490
+ shoes_canvas_append(int argc, VALUE *argv, VALUE self)
1491
+ {
1492
+ rb_arg_list args;
1493
+ rb_parse_args(argc, argv, "o,&", &args);
1494
+ shoes_canvas_insert(self, -1, Qnil, args.a[0]);
1495
+ return self;
1496
+ }
1497
+
1498
+ VALUE
1499
+ shoes_canvas_prepend(int argc, VALUE *argv, VALUE self)
1500
+ {
1501
+ rb_arg_list args;
1502
+ rb_parse_args(argc, argv, "o,&", &args);
1503
+ shoes_canvas_insert(self, 0, Qnil, args.a[0]);
1504
+ return self;
1505
+ }
1506
+
1507
+ VALUE
1508
+ shoes_canvas_clear_contents(int argc, VALUE *argv, VALUE self)
1509
+ {
1510
+ VALUE block = Qnil;
1511
+ SETUP();
1512
+
1513
+ if (rb_block_given_p()) block = rb_block_proc();
1514
+ shoes_canvas_empty(canvas, FALSE);
1515
+ if (!NIL_P(block))
1516
+ shoes_canvas_memdraw(self, block);
1517
+ shoes_canvas_repaint_all(self);
1518
+ return self;
1519
+ }
1520
+
1521
+ VALUE
1522
+ shoes_canvas_flow(int argc, VALUE *argv, VALUE self)
1523
+ {
1524
+ rb_arg_list args;
1525
+ VALUE flow;
1526
+ SETUP();
1527
+
1528
+ rb_parse_args(argc, argv, "|h&", &args);
1529
+ flow = shoes_flow_new(args.a[0], self);
1530
+ if (!NIL_P(args.a[1]))
1531
+ {
1532
+ DRAW(flow, canvas->app, rb_funcall(args.a[1], s_call, 0));
1533
+ }
1534
+ shoes_add_ele(canvas, flow);
1535
+ return flow;
1536
+ }
1537
+
1538
+ VALUE
1539
+ shoes_canvas_stack(int argc, VALUE *argv, VALUE self)
1540
+ {
1541
+ rb_arg_list args;
1542
+ VALUE stack;
1543
+ SETUP();
1544
+
1545
+ rb_parse_args(argc, argv, "|h&", &args);
1546
+ stack = shoes_stack_new(args.a[0], self);
1547
+ if (!NIL_P(args.a[1]))
1548
+ {
1549
+ DRAW(stack, canvas->app, rb_funcall(args.a[1], s_call, 0));
1550
+ }
1551
+ shoes_add_ele(canvas, stack);
1552
+ return stack;
1553
+ }
1554
+
1555
+ VALUE
1556
+ shoes_canvas_mask(int argc, VALUE *argv, VALUE self)
1557
+ {
1558
+ rb_arg_list args;
1559
+ VALUE mask;
1560
+ SETUP();
1561
+
1562
+ rb_parse_args(argc, argv, "|h&", &args);
1563
+ mask = shoes_mask_new(args.a[0], self);
1564
+ if (!NIL_P(args.a[1]))
1565
+ {
1566
+ DRAW(mask, canvas->app, rb_funcall(args.a[1], s_call, 0));
1567
+ }
1568
+ shoes_add_ele(canvas, mask);
1569
+ return mask;
1570
+ }
1571
+
1572
+ VALUE
1573
+ shoes_canvas_widget(int argc, VALUE *argv, VALUE self)
1574
+ {
1575
+ rb_arg_list args;
1576
+ VALUE widget, attr = Qnil;
1577
+ SETUP();
1578
+
1579
+ rb_parse_args(argc, argv, "k|", &args);
1580
+ if (TYPE(argv[argc-1]) == T_HASH)
1581
+ attr = argv[argc-1];
1582
+ widget = shoes_widget_new(args.a[0], attr, self);
1583
+ DRAW(widget, canvas->app, ts_funcall2(widget, rb_intern("initialize"), argc - 1, argv + 1));
1584
+ shoes_add_ele(canvas, widget);
1585
+ return widget;
1586
+ }
1587
+
1588
+ VALUE
1589
+ shoes_canvas_download(int argc, VALUE *argv, VALUE self)
1590
+ {
1591
+ VALUE url, block, obj, attr = Qnil;
1592
+ SETUP();
1593
+
1594
+ rb_scan_args(argc, argv, "11&", &url, &attr, &block);
1595
+ CHECK_HASH(attr);
1596
+ if (!NIL_P(block))
1597
+ ATTRSET(attr, finish, block);
1598
+ obj = shoes_http_threaded(self, url, attr);
1599
+ rb_ary_push(canvas->app->extras, obj);
1600
+ return obj;
1601
+ }
1602
+
1603
+ void
1604
+ shoes_canvas_size(VALUE self, int w, int h)
1605
+ {
1606
+ SETUP();
1607
+ canvas->place.iw = canvas->place.w = canvas->width = w;
1608
+ canvas->place.ih = canvas->place.h = canvas->height = h;
1609
+ shoes_native_canvas_resize(canvas);
1610
+ }
1611
+
1612
+ VALUE
1613
+ shoes_find_canvas(VALUE self)
1614
+ {
1615
+ while (!NIL_P(self) && !rb_obj_is_kind_of(self, cCanvas))
1616
+ {
1617
+ SETUP_BASIC();
1618
+ self = basic->parent;
1619
+ }
1620
+ return self;
1621
+ }
1622
+
1623
+ VALUE
1624
+ shoes_canvas_get_app(VALUE self)
1625
+ {
1626
+ VALUE app = Qnil, c = shoes_find_canvas(self);
1627
+ if (rb_obj_is_kind_of(c, cCanvas))
1628
+ {
1629
+ shoes_canvas *canvas;
1630
+ Data_Get_Struct(c, shoes_canvas, canvas);
1631
+ app = canvas->app->self;
1632
+ if (rb_block_given_p())
1633
+ mfp_instance_eval(app, rb_block_proc());
1634
+ }
1635
+ return app;
1636
+ }
1637
+
1638
+ void
1639
+ shoes_canvas_repaint_all(VALUE self)
1640
+ {
1641
+ shoes_canvas *canvas;
1642
+ self = shoes_find_canvas(self);
1643
+ Data_Get_Struct(self, shoes_canvas, canvas);
1644
+ if (canvas->stage == CANVAS_EMPTY) return;
1645
+ shoes_canvas_compute(self);
1646
+ shoes_slot_repaint(canvas->slot);
1647
+ }
1648
+
1649
+ typedef VALUE (*ccallfunc)(VALUE);
1650
+ typedef void (*ccallfunc2)(SHOES_CONTROL_REF);
1651
+
1652
+ static void
1653
+ shoes_canvas_ccall(VALUE self, ccallfunc func, ccallfunc2 func2, unsigned char check)
1654
+ {
1655
+ shoes_canvas *self_t, *pc;
1656
+ Data_Get_Struct(self, shoes_canvas, self_t);
1657
+
1658
+ if (check)
1659
+ {
1660
+ pc = self_t;
1661
+ while (!NIL_P(pc->parent))
1662
+ {
1663
+ Data_Get_Struct(pc->parent, shoes_canvas, pc);
1664
+ if (RTEST(ATTR(pc->attr, hidden)))
1665
+ return;
1666
+ }
1667
+ }
1668
+
1669
+ if (!NIL_P(self_t->parent))
1670
+ {
1671
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
1672
+ if (DC(self_t->slot) != DC(pc->slot))
1673
+ func2(DC(self_t->slot));
1674
+ }
1675
+
1676
+ if (!NIL_P(self_t->contents))
1677
+ {
1678
+ long i;
1679
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
1680
+ {
1681
+ shoes_basic *basic;
1682
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1683
+ Data_Get_Struct(ele, shoes_basic, basic);
1684
+ if (!RTEST(ATTR(basic->attr, hidden)))
1685
+ {
1686
+ if (rb_obj_is_kind_of(ele, cNative))
1687
+ func(ele);
1688
+ else if (rb_obj_is_kind_of(ele, cCanvas))
1689
+ shoes_canvas_ccall(ele, func, func2, 0);
1690
+ }
1691
+ }
1692
+ }
1693
+ }
1694
+
1695
+ VALUE
1696
+ shoes_canvas_hide(VALUE self)
1697
+ {
1698
+ shoes_canvas *self_t;
1699
+ Data_Get_Struct(self, shoes_canvas, self_t);
1700
+ ATTRSET(self_t->attr, hidden, Qtrue);
1701
+ shoes_canvas_ccall(self, shoes_control_temporary_hide, shoes_native_control_hide, 1);
1702
+ shoes_canvas_repaint_all(self);
1703
+ return self;
1704
+ }
1705
+
1706
+ VALUE
1707
+ shoes_canvas_show(VALUE self)
1708
+ {
1709
+ shoes_canvas *self_t;
1710
+ Data_Get_Struct(self, shoes_canvas, self_t);
1711
+ ATTRSET(self_t->attr, hidden, Qfalse);
1712
+ shoes_canvas_ccall(self, shoes_control_temporary_show, shoes_native_control_show, 1);
1713
+ shoes_canvas_repaint_all(self);
1714
+ return self;
1715
+ }
1716
+
1717
+ VALUE
1718
+ shoes_canvas_toggle(VALUE self)
1719
+ {
1720
+ shoes_canvas *self_t;
1721
+ Data_Get_Struct(self, shoes_canvas, self_t);
1722
+ if (RTEST(ATTR(self_t->attr, hidden)))
1723
+ shoes_canvas_show(self);
1724
+ else
1725
+ shoes_canvas_hide(self);
1726
+ return self;
1727
+ }
1728
+
1729
+ #define EVENT_HANDLER(x) \
1730
+ VALUE \
1731
+ shoes_canvas_##x(int argc, VALUE *argv, VALUE self) \
1732
+ { \
1733
+ VALUE val, block; \
1734
+ SETUP(); \
1735
+ rb_scan_args(argc, argv, "01&", &val, &block); \
1736
+ ATTRSET(canvas->attr, x, NIL_P(block) ? val : block); \
1737
+ return self; \
1738
+ }
1739
+
1740
+ EVENT_HANDLER(click);
1741
+ EVENT_HANDLER(hover);
1742
+ EVENT_HANDLER(leave);
1743
+ EVENT_HANDLER(release);
1744
+ EVENT_HANDLER(motion);
1745
+ EVENT_HANDLER(keydown);
1746
+ EVENT_HANDLER(keypress);
1747
+ EVENT_HANDLER(keyup);
1748
+ EVENT_HANDLER(start);
1749
+ EVENT_HANDLER(finish);
1750
+
1751
+ static void
1752
+ shoes_canvas_send_start(VALUE self)
1753
+ {
1754
+ shoes_canvas *canvas;
1755
+ Data_Get_Struct(self, shoes_canvas, canvas);
1756
+
1757
+ if (canvas->stage == CANVAS_NADA)
1758
+ {
1759
+ int i;
1760
+ canvas->stage = CANVAS_STARTED;
1761
+
1762
+ for (i = RARRAY_LEN(canvas->contents) - 1; i >= 0; i--)
1763
+ {
1764
+ VALUE ele = rb_ary_entry(canvas->contents, i);
1765
+ if (rb_obj_is_kind_of(ele, cCanvas) && shoes_canvas_inherits(ele, canvas))
1766
+ shoes_canvas_send_start(ele);
1767
+ }
1768
+
1769
+ VALUE start = ATTR(canvas->attr, start);
1770
+ if (!NIL_P(start))
1771
+ {
1772
+ shoes_safe_block(self, start, rb_ary_new3(1, self));
1773
+ }
1774
+ }
1775
+ }
1776
+
1777
+ static void
1778
+ shoes_canvas_send_finish(VALUE self)
1779
+ {
1780
+ shoes_canvas *canvas;
1781
+ Data_Get_Struct(self, shoes_canvas, canvas);
1782
+ VALUE finish = ATTR(canvas->attr, finish);
1783
+ if (!NIL_P(finish))
1784
+ shoes_safe_block(self, finish, rb_ary_new3(1, self));
1785
+ }
1786
+
1787
+ static VALUE
1788
+ shoes_canvas_send_click2(VALUE self, int button, int x, int y, VALUE *clicked)
1789
+ {
1790
+ long i;
1791
+ int ox = x, oy = y;
1792
+ VALUE v = Qnil;
1793
+ shoes_canvas *self_t;
1794
+ Data_Get_Struct(self, shoes_canvas, self_t);
1795
+
1796
+ if (ORIGIN(self_t->place))
1797
+ {
1798
+ oy = y + self_t->slot->scrolly;
1799
+ ox = x - self_t->place.ix + self_t->place.dx;
1800
+ oy = oy - (self_t->place.iy + self_t->place.dy);
1801
+ if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
1802
+ return Qnil;
1803
+ }
1804
+
1805
+ if (ATTR(self_t->attr, hidden) != Qtrue)
1806
+ {
1807
+ if (IS_INSIDE(self_t, x, y))
1808
+ {
1809
+ VALUE click = ATTR(self_t->attr, click);
1810
+ if (!NIL_P(click))
1811
+ {
1812
+ if (ORIGIN(self_t->place))
1813
+ y += self_t->slot->scrolly;
1814
+ shoes_safe_block(self, click, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
1815
+ }
1816
+ }
1817
+
1818
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
1819
+ {
1820
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1821
+ if (rb_obj_is_kind_of(ele, cCanvas))
1822
+ {
1823
+ v = shoes_canvas_send_click(ele, button, ox, oy);
1824
+ *clicked = ele;
1825
+ }
1826
+ else if (rb_obj_is_kind_of(ele, cTextBlock))
1827
+ {
1828
+ v = shoes_textblock_send_click(ele, button, ox, oy, clicked);
1829
+ }
1830
+ else if (rb_obj_is_kind_of(ele, cImage))
1831
+ {
1832
+ v = shoes_image_send_click(ele, button, ox, oy);
1833
+ *clicked = ele;
1834
+ }
1835
+ else if (rb_obj_is_kind_of(ele, cShape))
1836
+ {
1837
+ v = shoes_shape_send_click(ele, button, ox, oy);
1838
+ *clicked = ele;
1839
+ }
1840
+
1841
+ if (!NIL_P(v))
1842
+ return v;
1843
+ }
1844
+ }
1845
+
1846
+ return Qnil;
1847
+ }
1848
+
1849
+ VALUE
1850
+ shoes_canvas_mouse(VALUE self)
1851
+ {
1852
+ shoes_canvas *self_t;
1853
+ Data_Get_Struct(self, shoes_canvas, self_t);
1854
+ return rb_ary_new3(3, INT2NUM(self_t->app->mouseb),
1855
+ INT2NUM(self_t->app->mousex), INT2NUM(self_t->app->mousey));
1856
+ }
1857
+
1858
+ VALUE
1859
+ shoes_canvas_goto(VALUE self, VALUE url)
1860
+ {
1861
+ shoes_canvas *self_t;
1862
+ Data_Get_Struct(self, shoes_canvas, self_t);
1863
+ shoes_app_goto(self_t->app, RSTRING_PTR(url));
1864
+ return self;
1865
+ }
1866
+
1867
+ VALUE
1868
+ shoes_canvas_send_click(VALUE self, int button, int x, int y)
1869
+ {
1870
+ // INFO("click(%d, %d, %d)\n", button, x, y);
1871
+ VALUE clicked = Qnil;
1872
+ VALUE url = shoes_canvas_send_click2(self, button, x, y, &clicked);
1873
+ if (!NIL_P(url))
1874
+ {
1875
+ if (rb_obj_is_kind_of(url, rb_cProc))
1876
+ shoes_safe_block(self, url, rb_ary_new3(1, clicked));
1877
+ else
1878
+ {
1879
+ shoes_canvas *self_t;
1880
+ Data_Get_Struct(self, shoes_canvas, self_t);
1881
+ shoes_app_goto(self_t->app, RSTRING_PTR(url));
1882
+ }
1883
+ }
1884
+ return Qnil;
1885
+ }
1886
+
1887
+ void
1888
+ shoes_canvas_send_release(VALUE self, int button, int x, int y)
1889
+ {
1890
+ long i;
1891
+ int ox = x, oy = y;
1892
+ shoes_canvas *self_t;
1893
+ Data_Get_Struct(self, shoes_canvas, self_t);
1894
+
1895
+ if (ORIGIN(self_t->place))
1896
+ {
1897
+ oy = y + self_t->slot->scrolly;
1898
+ ox = x - self_t->place.ix + self_t->place.dx;
1899
+ oy = oy - (self_t->place.iy + self_t->place.dy);
1900
+ if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
1901
+ return;
1902
+ }
1903
+
1904
+ // INFO("release(%d, %d, %d)\n", button, x, y);
1905
+
1906
+ if (ATTR(self_t->attr, hidden) != Qtrue)
1907
+ {
1908
+ if (IS_INSIDE(self_t, x, y))
1909
+ {
1910
+ VALUE release = ATTR(self_t->attr, release);
1911
+ if (!NIL_P(release))
1912
+ {
1913
+ if (ORIGIN(self_t->place))
1914
+ y += self_t->slot->scrolly;
1915
+ shoes_safe_block(self, release, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
1916
+ }
1917
+ }
1918
+
1919
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
1920
+ {
1921
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1922
+ if (rb_obj_is_kind_of(ele, cCanvas))
1923
+ {
1924
+ shoes_canvas_send_release(ele, button, ox, oy);
1925
+ }
1926
+ else if (rb_obj_is_kind_of(ele, cTextBlock))
1927
+ {
1928
+ shoes_textblock_send_release(ele, button, ox, oy);
1929
+ }
1930
+ else if (rb_obj_is_kind_of(ele, cImage))
1931
+ {
1932
+ shoes_image_send_release(ele, button, ox, oy);
1933
+ }
1934
+ else if (rb_obj_is_kind_of(ele, cShape))
1935
+ {
1936
+ shoes_shape_send_release(ele, button, ox, oy);
1937
+ }
1938
+ }
1939
+ }
1940
+ }
1941
+
1942
+ VALUE
1943
+ shoes_canvas_send_motion(VALUE self, int x, int y, VALUE url)
1944
+ {
1945
+ char oh, ch = 0, h = 0, *n = 0;
1946
+ long i;
1947
+ int ox = x, oy = y;
1948
+ shoes_canvas *self_t;
1949
+ Data_Get_Struct(self, shoes_canvas, self_t);
1950
+
1951
+ oh = self_t->hover;
1952
+ ch = h = IS_INSIDE(self_t, x, y);
1953
+ CHECK_HOVER(self_t, h, n);
1954
+
1955
+ if (ORIGIN(self_t->place))
1956
+ {
1957
+ y += self_t->slot->scrolly;
1958
+ ox = x - self_t->place.ix + self_t->place.dx;
1959
+ oy = y - (self_t->place.iy + self_t->place.dy);
1960
+ if (!oh && (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw))
1961
+ return Qnil;
1962
+ }
1963
+
1964
+ h = 0;
1965
+ if (ATTR(self_t->attr, hidden) != Qtrue)
1966
+ {
1967
+ VALUE motion = ATTR(self_t->attr, motion);
1968
+ if (!NIL_P(motion))
1969
+ {
1970
+ shoes_safe_block(self, motion, rb_ary_new3(2, INT2NUM(x), INT2NUM(y)));
1971
+ }
1972
+
1973
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
1974
+ {
1975
+ VALUE urll = Qnil;
1976
+ VALUE ele = rb_ary_entry(self_t->contents, i);
1977
+ if (rb_obj_is_kind_of(ele, cCanvas))
1978
+ {
1979
+ urll = shoes_canvas_send_motion(ele, ox, oy, url);
1980
+ }
1981
+ else if (rb_obj_is_kind_of(ele, cTextBlock))
1982
+ {
1983
+ urll = shoes_textblock_motion(ele, ox, oy, &h);
1984
+ }
1985
+ else if (rb_obj_is_kind_of(ele, cImage))
1986
+ {
1987
+ urll = shoes_image_motion(ele, ox, oy, NULL);
1988
+ }
1989
+ else if (rb_obj_is_kind_of(ele, cShape))
1990
+ {
1991
+ urll = shoes_shape_motion(ele, ox, oy, NULL);
1992
+ }
1993
+
1994
+ if (NIL_P(url)) url = urll;
1995
+ }
1996
+
1997
+ if (ch && NIL_P(url))
1998
+ {
1999
+ shoes_canvas *self_t;
2000
+ Data_Get_Struct(self, shoes_canvas, self_t);
2001
+ if (self_t->app->cursor == s_link)
2002
+ shoes_app_cursor(self_t->app, s_arrow);
2003
+ }
2004
+ }
2005
+
2006
+ if (h) shoes_canvas_repaint_all(self);
2007
+
2008
+ return url;
2009
+ }
2010
+
2011
+ void
2012
+ shoes_canvas_send_wheel(VALUE self, ID dir, int x, int y)
2013
+ {
2014
+ long i;
2015
+ shoes_canvas *self_t;
2016
+ Data_Get_Struct(self, shoes_canvas, self_t);
2017
+
2018
+ if (ATTR(self_t->attr, hidden) != Qtrue)
2019
+ {
2020
+ VALUE wheel = ATTR(self_t->attr, wheel);
2021
+ if (!NIL_P(wheel))
2022
+ {
2023
+ shoes_safe_block(self, wheel, rb_ary_new3(3, ID2SYM(dir), INT2NUM(x), INT2NUM(y)));
2024
+ }
2025
+
2026
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
2027
+ {
2028
+ VALUE ele = rb_ary_entry(self_t->contents, i);
2029
+ if (rb_obj_is_kind_of(ele, cCanvas))
2030
+ {
2031
+ shoes_canvas_send_wheel(ele, dir, x, y);
2032
+ }
2033
+ }
2034
+ }
2035
+ }
2036
+
2037
+ #define DEF_SEND_KEY_EVENT(event_name) \
2038
+ void \
2039
+ shoes_canvas_send_##event_name (VALUE self, VALUE key) \
2040
+ { \
2041
+ long i; \
2042
+ shoes_canvas *self_t; \
2043
+ Data_Get_Struct(self, shoes_canvas, self_t); \
2044
+ \
2045
+ if (ATTR(self_t->attr, hidden) != Qtrue) \
2046
+ { \
2047
+ VALUE handler = ATTR(self_t->attr, event_name); \
2048
+ if (!NIL_P(handler)) \
2049
+ { \
2050
+ shoes_safe_block(self, handler, rb_ary_new3(1, key)); \
2051
+ } \
2052
+ \
2053
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) \
2054
+ { \
2055
+ VALUE ele = rb_ary_entry(self_t->contents, i); \
2056
+ if (rb_obj_is_kind_of(ele, cCanvas)) \
2057
+ { \
2058
+ shoes_canvas_send_ ## event_name (ele, key); \
2059
+ } \
2060
+ } \
2061
+ } \
2062
+ }
2063
+ DEF_SEND_KEY_EVENT(keydown)
2064
+ DEF_SEND_KEY_EVENT(keypress)
2065
+ DEF_SEND_KEY_EVENT(keyup)
2066
+
2067
+ SHOES_SLOT_OS *
2068
+ shoes_slot_alloc(shoes_canvas *canvas, SHOES_SLOT_OS *parent, int toplevel)
2069
+ {
2070
+ canvas->slot = SHOE_ALLOC(SHOES_SLOT_OS);
2071
+ SHOE_MEMZERO(canvas->slot, SHOES_SLOT_OS, 1);
2072
+ canvas->slot->owner = canvas;
2073
+ return canvas->slot;
2074
+ }
2075
+
2076
+ VALUE
2077
+ shoes_slot_new(VALUE klass, VALUE attr, VALUE parent)
2078
+ {
2079
+ shoes_canvas *self_t, *pc;
2080
+ VALUE self = shoes_canvas_alloc(klass);
2081
+ shoes_canvas_clear(self);
2082
+ Data_Get_Struct(parent, shoes_canvas, pc);
2083
+ Data_Get_Struct(self, shoes_canvas, self_t);
2084
+ self_t->cr = pc->cr;
2085
+ self_t->slot = pc->slot;
2086
+ self_t->parent = parent;
2087
+ self_t->app = pc->app;
2088
+ self_t->attr = attr;
2089
+ COPY_PENS(self_t->attr, pc->attr);
2090
+ int scrolls = RTEST(ATTR(self_t->attr, scroll));
2091
+ if ((attr != ssNestSlot && RTEST(ATTR(self_t->attr, height))) || scrolls) {
2092
+ //
2093
+ // create the slot off-screen until it can be properly placed
2094
+ //
2095
+ shoes_slot_init(self, pc->slot, -99, -99, 100, 100, scrolls, FALSE);
2096
+ self_t->place.x = self_t->place.y = 0;
2097
+ self_t->place.ix = self_t->place.iy = 0;
2098
+ }
2099
+ return self;
2100
+ }
2101
+
2102
+ //
2103
+ // Shoes::Flow
2104
+ //
2105
+ VALUE
2106
+ shoes_flow_new(VALUE attr, VALUE parent)
2107
+ {
2108
+ return shoes_slot_new(cFlow, attr, parent);
2109
+ }
2110
+
2111
+ //
2112
+ // Shoes::Stack
2113
+ //
2114
+ VALUE
2115
+ shoes_stack_new(VALUE attr, VALUE parent)
2116
+ {
2117
+ return shoes_slot_new(cStack, attr, parent);
2118
+ }
2119
+
2120
+ //
2121
+ // Shoes::Mask
2122
+ //
2123
+ VALUE
2124
+ shoes_mask_new(VALUE attr, VALUE parent)
2125
+ {
2126
+ return shoes_slot_new(cMask, attr, parent);
2127
+ }
2128
+
2129
+ //
2130
+ // Shoes::Widget
2131
+ //
2132
+ VALUE
2133
+ shoes_widget_new(VALUE klass, VALUE attr, VALUE parent)
2134
+ {
2135
+ return shoes_slot_new(klass, attr, parent);
2136
+ }
2137
+
2138
+ VALUE
2139
+ shoes_canvas_get_cursor(VALUE self)
2140
+ {
2141
+ SETUP();
2142
+ return ID2SYM(canvas->app->cursor);
2143
+ }
2144
+
2145
+ VALUE
2146
+ shoes_canvas_set_cursor(VALUE self, VALUE name)
2147
+ {
2148
+ SETUP();
2149
+ shoes_app_cursor(canvas->app, SYM2ID(name));
2150
+ return name;
2151
+ }
2152
+
2153
+ //
2154
+ // Global clipboard getter and setter
2155
+ //
2156
+ VALUE
2157
+ shoes_canvas_get_clipboard(VALUE self)
2158
+ {
2159
+ shoes_canvas *self_t;
2160
+ Data_Get_Struct(self, shoes_canvas, self_t);
2161
+ return shoes_native_clipboard_get(self_t->app);
2162
+ }
2163
+
2164
+ VALUE
2165
+ shoes_canvas_set_clipboard(VALUE self, VALUE string)
2166
+ {
2167
+ shoes_canvas *self_t;
2168
+ Data_Get_Struct(self, shoes_canvas, self_t);
2169
+ string = shoes_native_to_s(string);
2170
+ shoes_native_clipboard_set(self_t->app, string);
2171
+ return string;
2172
+ }
2173
+
2174
+ //
2175
+ // Window creation
2176
+ //
2177
+ VALUE
2178
+ shoes_canvas_window(int argc, VALUE *argv, VALUE self)
2179
+ {
2180
+ SETUP();
2181
+ return shoes_app_window(argc, argv, cApp, canvas->app->self);
2182
+ }
2183
+
2184
+ VALUE
2185
+ shoes_canvas_dialog(int argc, VALUE *argv, VALUE self)
2186
+ {
2187
+ return shoes_app_window(argc, argv, cDialog, self);
2188
+ }
2189
+
2190
+ VALUE
2191
+ shoes_canvas_window_plain(VALUE self)
2192
+ {
2193
+ SETUP();
2194
+ return shoes_native_window_color(canvas->app);
2195
+ }
2196
+
2197
+ VALUE
2198
+ shoes_canvas_dialog_plain(VALUE self)
2199
+ {
2200
+ SETUP();
2201
+ return shoes_native_dialog_color(canvas->app);
2202
+ }