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,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
+ }