lacci 0.2.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 (559) hide show
  1. checksums.yaml +7 -0
  2. data/.rubocop.yml +85 -0
  3. data/.ruby-version +1 -0
  4. data/.vscode/extensions.json +5 -0
  5. data/.yardopts +12 -0
  6. data/CHANGELOG.md +19 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/CONTRIBUTING.md +20 -0
  9. data/Gemfile +24 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +178 -0
  12. data/Rakefile +15 -0
  13. data/bin/console +15 -0
  14. data/bin/setup +8 -0
  15. data/dev.yml +7 -0
  16. data/docs/static/PKGBUILD +47 -0
  17. data/docs/static/Shoes.icns +0 -0
  18. data/docs/static/avatar.png +0 -0
  19. data/docs/static/code_highlighter.js +188 -0
  20. data/docs/static/code_highlighter_ruby.js +26 -0
  21. data/docs/static/icon-debug.png +0 -0
  22. data/docs/static/icon-error.png +0 -0
  23. data/docs/static/icon-info.png +0 -0
  24. data/docs/static/icon-warn.png +0 -0
  25. data/docs/static/listbox_button1.png +0 -0
  26. data/docs/static/listbox_button2.png +0 -0
  27. data/docs/static/man-app.png +0 -0
  28. data/docs/static/man-builds.png +0 -0
  29. data/docs/static/man-builds1.png +0 -0
  30. data/docs/static/man-editor-notepad.png +0 -0
  31. data/docs/static/man-editor-osx.png +0 -0
  32. data/docs/static/man-ele-background.png +0 -0
  33. data/docs/static/man-ele-border.png +0 -0
  34. data/docs/static/man-ele-button.png +0 -0
  35. data/docs/static/man-ele-check.png +0 -0
  36. data/docs/static/man-ele-editbox.png +0 -0
  37. data/docs/static/man-ele-editline.png +0 -0
  38. data/docs/static/man-ele-image.png +0 -0
  39. data/docs/static/man-ele-listbox.png +0 -0
  40. data/docs/static/man-ele-progress.png +0 -0
  41. data/docs/static/man-ele-radio.png +0 -0
  42. data/docs/static/man-ele-shape.png +0 -0
  43. data/docs/static/man-ele-textblock.png +0 -0
  44. data/docs/static/man-ele-video.png +0 -0
  45. data/docs/static/man-intro-dmg.png +0 -0
  46. data/docs/static/man-intro-exe.png +0 -0
  47. data/docs/static/man-look-tiger.png +0 -0
  48. data/docs/static/man-look-ubuntu.png +0 -0
  49. data/docs/static/man-look-vista.png +0 -0
  50. data/docs/static/man-run-osx.png +0 -0
  51. data/docs/static/man-run-vista.png +0 -0
  52. data/docs/static/man-run-xp.png +0 -0
  53. data/docs/static/man-shot1.png +0 -0
  54. data/docs/static/manual-en.txt +3529 -0
  55. data/docs/static/manual-ja.txt +2829 -0
  56. data/docs/static/manual.css +171 -0
  57. data/docs/static/manual.md +3528 -0
  58. data/docs/static/menu-corner1.png +0 -0
  59. data/docs/static/menu-corner2.png +0 -0
  60. data/docs/static/menu-gray.png +0 -0
  61. data/docs/static/menu-left.png +0 -0
  62. data/docs/static/menu-right.png +0 -0
  63. data/docs/static/menu-top.png +0 -0
  64. data/docs/static/shoes-dmg.jpg +0 -0
  65. data/docs/static/shoes-icon-blue.png +0 -0
  66. data/docs/static/shoes-icon.png +0 -0
  67. data/docs/static/shoes-manual-apps.gif +0 -0
  68. data/docs/static/shoes_main_window.png +0 -0
  69. data/docs/static/stripe.png +0 -0
  70. data/docs/static/stubs/blank.exe +0 -0
  71. data/docs/static/stubs/blank.hfz +0 -0
  72. data/docs/static/stubs/blank.run +375 -0
  73. data/docs/static/stubs/cocoa-install +0 -0
  74. data/docs/static/stubs/sh-install +49 -0
  75. data/docs/static/stubs/shoes-stub-inject.exe +0 -0
  76. data/docs/static/stubs/shoes-stub.exe +0 -0
  77. data/docs/static/tutor-back.png +0 -0
  78. data/docs/yard/catscradle.md +44 -0
  79. data/docs/yard/template/default/fulldoc/html/setup.rb +13 -0
  80. data/docs/yard/template/default/layout/html/setup.rb +9 -0
  81. data/examples/backdround_with_image.rb +16 -0
  82. data/examples/bloopsaphone/working/1901_by_Aanand_Prasad.rb +478 -0
  83. data/examples/bloopsaphone/working/b1.rb +64 -0
  84. data/examples/bloopsaphone/working/b2.rb +36 -0
  85. data/examples/bloopsaphone/working/bloops_test.rb +41 -0
  86. data/examples/bloopsaphone/working/bloopsaphone_theme_song_by_why.rb +31 -0
  87. data/examples/bloopsaphone/working/feepogram.rb +67 -0
  88. data/examples/bloopsaphone/working/simpsons_theme_song_by_why.rb +14 -0
  89. data/examples/bloopsaphone/working/tune_cheeky_drat.rb +210 -0
  90. data/examples/button.rb +10 -0
  91. data/examples/button_alert.rb +6 -0
  92. data/examples/button_go_away.rb +6 -0
  93. data/examples/button_with_position_and_size.rb +7 -0
  94. data/examples/coffee.rb +14 -0
  95. data/examples/download.rb +5 -0
  96. data/examples/download_and_show_image.rb +28 -0
  97. data/examples/edit_box.rb +8 -0
  98. data/examples/edit_line.rb +8 -0
  99. data/examples/fill.rb +25 -0
  100. data/examples/flow.rb +11 -0
  101. data/examples/fonts.rb +6 -0
  102. data/examples/gen.rb +140 -0
  103. data/examples/get_headers.rb +10 -0
  104. data/examples/hello_world.rb +3 -0
  105. data/examples/highlander.rb +87 -0
  106. data/examples/image/clickable_image.rb +5 -0
  107. data/examples/image/image.rb +3 -0
  108. data/examples/image/image_size.rb +7 -0
  109. data/examples/image/image_with_position_and_size.rb +3 -0
  110. data/examples/info.rb +9 -0
  111. data/examples/legacy/not_checked/expert/colours.rb +105 -0
  112. data/examples/legacy/not_checked/expert/curve-animation.rb +31 -0
  113. data/examples/legacy/not_checked/expert/curve-control-point.rb +51 -0
  114. data/examples/legacy/not_checked/expert/custom-list-box.rb +53 -0
  115. data/examples/legacy/not_checked/expert/definr.rb +23 -0
  116. data/examples/legacy/not_checked/expert/funnies.rb +56 -0
  117. data/examples/legacy/not_checked/expert/minesweeper.rb +267 -0
  118. data/examples/legacy/not_checked/expert/othello.rb +318 -0
  119. data/examples/legacy/not_checked/expert/pong.rb +62 -0
  120. data/examples/legacy/not_checked/expert/tankspank.rb +385 -0
  121. data/examples/legacy/not_checked/expert/tooltips.rb +45 -0
  122. data/examples/legacy/not_checked/expert/url.rb +37 -0
  123. data/examples/legacy/not_checked/expert/video-player.rb +256 -0
  124. data/examples/legacy/not_checked/good/_why-stories.rb +44 -0
  125. data/examples/legacy/not_checked/good/_why-stories.yaml +387 -0
  126. data/examples/legacy/not_checked/good/arc.rb +37 -0
  127. data/examples/legacy/not_checked/good/cardflip.rb +141 -0
  128. data/examples/legacy/not_checked/good/clock.rb +51 -0
  129. data/examples/legacy/not_checked/good/console.rb +21 -0
  130. data/examples/legacy/not_checked/good/follow.rb +26 -0
  131. data/examples/legacy/not_checked/good/image-rotate.rb +14 -0
  132. data/examples/legacy/not_checked/good/paris.svg +7236 -0
  133. data/examples/legacy/not_checked/good/path-animation.rb +46 -0
  134. data/examples/legacy/not_checked/good/plots.rb +100 -0
  135. data/examples/legacy/not_checked/good/reminder.rb +174 -0
  136. data/examples/legacy/not_checked/good/svgview.rb +113 -0
  137. data/examples/legacy/not_checked/good/vjot.rb +56 -0
  138. data/examples/legacy/not_checked/shoes-contrib/.gitignore +2 -0
  139. data/examples/legacy/not_checked/shoes-contrib/README.md +34 -0
  140. data/examples/legacy/not_checked/shoes-contrib/animation/animate-ovals.rb +21 -0
  141. data/examples/legacy/not_checked/shoes-contrib/animation/flowers.rb +59 -0
  142. data/examples/legacy/not_checked/shoes-contrib/animation/happy-trails.rb +31 -0
  143. data/examples/legacy/not_checked/shoes-contrib/animation/mice-satellites.rb +27 -0
  144. data/examples/legacy/not_checked/shoes-contrib/animation/oval-motion.rb +12 -0
  145. data/examples/legacy/not_checked/shoes-contrib/animation/pink-bubbles.rb +34 -0
  146. data/examples/legacy/not_checked/shoes-contrib/animation/pulsate.rb +18 -0
  147. data/examples/legacy/not_checked/shoes-contrib/animation/rotating-star.rb +18 -0
  148. data/examples/legacy/not_checked/shoes-contrib/app/download-and-save.rb +11 -0
  149. data/examples/legacy/not_checked/shoes-contrib/app/download.rb +10 -0
  150. data/examples/legacy/not_checked/shoes-contrib/app/get-google.rb +11 -0
  151. data/examples/legacy/not_checked/shoes-contrib/app/mouse-detection.rb +7 -0
  152. data/examples/legacy/not_checked/shoes-contrib/app/resizeable-false.rb +6 -0
  153. data/examples/legacy/not_checked/shoes-contrib/art/bubble-bullseye.rb +23 -0
  154. data/examples/legacy/not_checked/shoes-contrib/art/faded.rb +17 -0
  155. data/examples/legacy/not_checked/shoes-contrib/art/fill-oval.rb +5 -0
  156. data/examples/legacy/not_checked/shoes-contrib/art/mask.rb +15 -0
  157. data/examples/legacy/not_checked/shoes-contrib/art/oval-gradient.rb +6 -0
  158. data/examples/legacy/not_checked/shoes-contrib/art/star-gradient.rb +4 -0
  159. data/examples/legacy/not_checked/shoes-contrib/basic/basic-edit-box.rb +8 -0
  160. data/examples/legacy/not_checked/shoes-contrib/basic/basic-new-window.rb +8 -0
  161. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval-image.rb +8 -0
  162. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval-shape.rb +8 -0
  163. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval.rb +6 -0
  164. data/examples/legacy/not_checked/shoes-contrib/basic/class-book.rb +43 -0
  165. data/examples/legacy/not_checked/shoes-contrib/basic/class-book.yaml +387 -0
  166. data/examples/legacy/not_checked/shoes-contrib/basic/clock.rb +6 -0
  167. data/examples/legacy/not_checked/shoes-contrib/basic/edit-stack +14 -0
  168. data/examples/legacy/not_checked/shoes-contrib/basic/gradient-shoes.rb +7 -0
  169. data/examples/legacy/not_checked/shoes-contrib/basic/list_box-shape-report.rb +19 -0
  170. data/examples/legacy/not_checked/shoes-contrib/basic/rect-arrow.rb +7 -0
  171. data/examples/legacy/not_checked/shoes-contrib/basic/scribble.rb +8 -0
  172. data/examples/legacy/not_checked/shoes-contrib/basic/search.rb +32 -0
  173. data/examples/legacy/not_checked/shoes-contrib/basic/shoes-notes.rb +16 -0
  174. data/examples/legacy/not_checked/shoes-contrib/basic/url-shoes-subclassing.rb +24 -0
  175. data/examples/legacy/not_checked/shoes-contrib/browser.rb +21 -0
  176. data/examples/legacy/not_checked/shoes-contrib/elements/background-column.rb +3 -0
  177. data/examples/legacy/not_checked/shoes-contrib/elements/background.rb +4 -0
  178. data/examples/legacy/not_checked/shoes-contrib/elements/basic-fps.rb +6 -0
  179. data/examples/legacy/not_checked/shoes-contrib/elements/border-cat.rb +6 -0
  180. data/examples/legacy/not_checked/shoes-contrib/elements/button-block.rb +8 -0
  181. data/examples/legacy/not_checked/shoes-contrib/elements/check-mate.rb +15 -0
  182. data/examples/legacy/not_checked/shoes-contrib/elements/common-styles.rb +13 -0
  183. data/examples/legacy/not_checked/shoes-contrib/elements/displace-animation.rb +13 -0
  184. data/examples/legacy/not_checked/shoes-contrib/elements/edit_box-character-count.rb +7 -0
  185. data/examples/legacy/not_checked/shoes-contrib/elements/edit_line-character-count.rb +7 -0
  186. data/examples/legacy/not_checked/shoes-contrib/elements/image-icon.rb +3 -0
  187. data/examples/legacy/not_checked/shoes-contrib/elements/list_box-select-class.rb +13 -0
  188. data/examples/legacy/not_checked/shoes-contrib/elements/list_box.rb +6 -0
  189. data/examples/legacy/not_checked/shoes-contrib/elements/move-flow-animate.rb +13 -0
  190. data/examples/legacy/not_checked/shoes-contrib/elements/phat-button.rb +7 -0
  191. data/examples/legacy/not_checked/shoes-contrib/elements/popup.rb +7 -0
  192. data/examples/legacy/not_checked/shoes-contrib/elements/progress-bar.rb +10 -0
  193. data/examples/legacy/not_checked/shoes-contrib/elements/radio-dreamcast-favs.rb +17 -0
  194. data/examples/legacy/not_checked/shoes-contrib/elements/timer.rb +6 -0
  195. data/examples/legacy/not_checked/shoes-contrib/elements/width-introspec.rb +8 -0
  196. data/examples/legacy/not_checked/shoes-contrib/events/background-hover.rb +11 -0
  197. data/examples/legacy/not_checked/shoes-contrib/events/motion-detect.rb +9 -0
  198. data/examples/legacy/not_checked/shoes-contrib/events/pressed-key.rb +6 -0
  199. data/examples/legacy/not_checked/shoes-contrib/expert/expert-funnies.rb +51 -0
  200. data/examples/legacy/not_checked/shoes-contrib/expert/expert-irb.rb +112 -0
  201. data/examples/legacy/not_checked/shoes-contrib/expert/expert-othello.rb +319 -0
  202. data/examples/legacy/not_checked/shoes-contrib/good/good-arc.rb +37 -0
  203. data/examples/legacy/not_checked/shoes-contrib/good/good-clock.rb +51 -0
  204. data/examples/legacy/not_checked/shoes-contrib/good/good-follow.rb +26 -0
  205. data/examples/legacy/not_checked/shoes-contrib/good/good-reminder.rb +174 -0
  206. data/examples/legacy/not_checked/shoes-contrib/good/good-vjot.rb +56 -0
  207. data/examples/legacy/not_checked/shoes-contrib/kernel/ask.rb +4 -0
  208. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_color.rb +4 -0
  209. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_open_file.rb +4 -0
  210. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_save_file.rb +7 -0
  211. data/examples/legacy/not_checked/shoes-contrib/kernel/confirm.rb +3 -0
  212. data/examples/legacy/not_checked/shoes-contrib/kernel/debug.rb +4 -0
  213. data/examples/legacy/not_checked/shoes-contrib/kernel/exit.rb +5 -0
  214. data/examples/legacy/not_checked/shoes-contrib/kernel/font.rb +5 -0
  215. data/examples/legacy/not_checked/shoes-contrib/kernel/fonts.rb +3 -0
  216. data/examples/legacy/not_checked/shoes-contrib/manipulation/append-slot.rb +9 -0
  217. data/examples/legacy/not_checked/shoes-contrib/manipulation/clear-slot.rb +6 -0
  218. data/examples/legacy/not_checked/shoes-contrib/manipulation/prepend-slot.rb +6 -0
  219. data/examples/legacy/not_checked/shoes-contrib/manipulation/roll.rb +17 -0
  220. data/examples/legacy/not_checked/shoes-contrib/position/gutter-margin.rb +5 -0
  221. data/examples/legacy/not_checked/shoes-contrib/position/stack-width.rb +3 -0
  222. data/examples/legacy/not_checked/shoes-contrib/simple/simple-accordion.rb +75 -0
  223. data/examples/legacy/not_checked/shoes-contrib/simple/simple-anim-shapes.rb +17 -0
  224. data/examples/legacy/not_checked/shoes-contrib/simple/simple-anim-text.rb +13 -0
  225. data/examples/legacy/not_checked/shoes-contrib/simple/simple-arc.rb +23 -0
  226. data/examples/legacy/not_checked/shoes-contrib/simple/simple-bounce.rb +24 -0
  227. data/examples/legacy/not_checked/shoes-contrib/simple/simple-calc.rb +70 -0
  228. data/examples/legacy/not_checked/shoes-contrib/simple/simple-chipmunk.rb +26 -0
  229. data/examples/legacy/not_checked/shoes-contrib/simple/simple-control-sizes.rb +24 -0
  230. data/examples/legacy/not_checked/shoes-contrib/simple/simple-curve.rb +26 -0
  231. data/examples/legacy/not_checked/shoes-contrib/simple/simple-dialogs.rb +29 -0
  232. data/examples/legacy/not_checked/shoes-contrib/simple/simple-downloader.rb +27 -0
  233. data/examples/legacy/not_checked/shoes-contrib/simple/simple-draw.rb +13 -0
  234. data/examples/legacy/not_checked/shoes-contrib/simple/simple-editor.rb +28 -0
  235. data/examples/legacy/not_checked/shoes-contrib/simple/simple-form.rb +28 -0
  236. data/examples/legacy/not_checked/shoes-contrib/simple/simple-form.shy +0 -0
  237. data/examples/legacy/not_checked/shoes-contrib/simple/simple-mask.rb +21 -0
  238. data/examples/legacy/not_checked/shoes-contrib/simple/simple-menu.rb +31 -0
  239. data/examples/legacy/not_checked/shoes-contrib/simple/simple-menu1.rb +35 -0
  240. data/examples/legacy/not_checked/shoes-contrib/simple/simple-rubygems.rb +29 -0
  241. data/examples/legacy/not_checked/shoes-contrib/simple/simple-slide.rb +45 -0
  242. data/examples/legacy/not_checked/shoes-contrib/simple/simple-sphere.rb +28 -0
  243. data/examples/legacy/not_checked/shoes-contrib/simple/simple-sqlite3.rb +13 -0
  244. data/examples/legacy/not_checked/shoes-contrib/simple/simple-timer.rb +13 -0
  245. data/examples/legacy/not_checked/shoes-contrib/simple/simple-video.rb +13 -0
  246. data/examples/legacy/not_checked/shoes-contrib/styles/alignment.rb +4 -0
  247. data/examples/legacy/not_checked/shoes-contrib/styles/attachment.rb +5 -0
  248. data/examples/legacy/not_checked/shoes-contrib/styles/emphasis.rb +3 -0
  249. data/examples/legacy/not_checked/shoes-contrib/styles/gradient-angle.rb +3 -0
  250. data/examples/legacy/not_checked/shoes-contrib/styles/para-methods.rb +5 -0
  251. data/examples/legacy/not_checked/shoes-contrib/styles/para-red-underlined.rb +3 -0
  252. data/examples/legacy/not_checked/shoes-contrib/styles/para-style-method.rb +4 -0
  253. data/examples/legacy/not_checked/shoes-dep-samples/expert-game-of-life.rb +243 -0
  254. data/examples/legacy/not_checked/shoes-dep-samples/expert-othello.rb +319 -0
  255. data/examples/legacy/not_checked/shoes-dep-samples/good-clock.rb +51 -0
  256. data/examples/legacy/not_checked/shoes-dep-samples/good-follow.rb +26 -0
  257. data/examples/legacy/not_checked/shoes-dep-samples/good-reminder.rb +174 -0
  258. data/examples/legacy/not_checked/shoes-dep-samples/good-vjot.rb +56 -0
  259. data/examples/legacy/not_checked/shoes-dep-samples/simple-accordion.rb +75 -0
  260. data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-shapes.rb +17 -0
  261. data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-text.rb +13 -0
  262. data/examples/legacy/not_checked/shoes-dep-samples/simple-arc.rb +23 -0
  263. data/examples/legacy/not_checked/shoes-dep-samples/simple-bounce.rb +24 -0
  264. data/examples/legacy/not_checked/shoes-dep-samples/simple-calc.rb +70 -0
  265. data/examples/legacy/not_checked/shoes-dep-samples/simple-chipmunk.rb +26 -0
  266. data/examples/legacy/not_checked/shoes-dep-samples/simple-control-sizes.rb +24 -0
  267. data/examples/legacy/not_checked/shoes-dep-samples/simple-curve.rb +26 -0
  268. data/examples/legacy/not_checked/shoes-dep-samples/simple-dialogs.rb +29 -0
  269. data/examples/legacy/not_checked/shoes-dep-samples/simple-draw.rb +13 -0
  270. data/examples/legacy/not_checked/shoes-dep-samples/simple-editor.rb +28 -0
  271. data/examples/legacy/not_checked/shoes-dep-samples/simple-form.rb +28 -0
  272. data/examples/legacy/not_checked/shoes-dep-samples/simple-form.shy +0 -0
  273. data/examples/legacy/not_checked/shoes-dep-samples/simple-mask.rb +21 -0
  274. data/examples/legacy/not_checked/shoes-dep-samples/simple-menu.rb +31 -0
  275. data/examples/legacy/not_checked/shoes-dep-samples/simple-menu1.rb +35 -0
  276. data/examples/legacy/not_checked/shoes-dep-samples/simple-rubygems.rb +29 -0
  277. data/examples/legacy/not_checked/shoes-dep-samples/simple-slide.rb +45 -0
  278. data/examples/legacy/not_checked/shoes-dep-samples/simple-sphere.rb +28 -0
  279. data/examples/legacy/not_checked/shoes-dep-samples/simple-sqlite3.rb +13 -0
  280. data/examples/legacy/not_checked/shoes-dep-samples/simple-timer.rb +13 -0
  281. data/examples/legacy/not_checked/shoes-dep-samples/simple-video.rb +13 -0
  282. data/examples/legacy/not_checked/shoes3-tests/AnemicCinema1926marcelDuchampCut.mp4 +0 -0
  283. data/examples/legacy/not_checked/shoes3-tests/button/button.rb +53 -0
  284. data/examples/legacy/not_checked/shoes3-tests/cache/cache.rb +41 -0
  285. data/examples/legacy/not_checked/shoes3-tests/combo/combo.rb +24 -0
  286. data/examples/legacy/not_checked/shoes3-tests/curl/bare.rb +34 -0
  287. data/examples/legacy/not_checked/shoes3-tests/curl/downloader.rb +40 -0
  288. data/examples/legacy/not_checked/shoes3-tests/curl/m1.rb +11 -0
  289. data/examples/legacy/not_checked/shoes3-tests/curl/m2.rb +12 -0
  290. data/examples/legacy/not_checked/shoes3-tests/curl/m3.rb +11 -0
  291. data/examples/legacy/not_checked/shoes3-tests/curl/m4.rb +5 -0
  292. data/examples/legacy/not_checked/shoes3-tests/curl/typ.rb +30 -0
  293. data/examples/legacy/not_checked/shoes3-tests/cursor/c1.rb +21 -0
  294. data/examples/legacy/not_checked/shoes3-tests/decoration.rb +14 -0
  295. data/examples/legacy/not_checked/shoes3-tests/dialogs/ask.rb +6 -0
  296. data/examples/legacy/not_checked/shoes3-tests/dialogs/confirm.rb +6 -0
  297. data/examples/legacy/not_checked/shoes3-tests/editbox/editbox.rb +36 -0
  298. data/examples/legacy/not_checked/shoes3-tests/editline/editline.rb +27 -0
  299. data/examples/legacy/not_checked/shoes3-tests/events/button.rb +32 -0
  300. data/examples/legacy/not_checked/shoes3-tests/events/button.yaml +40 -0
  301. data/examples/legacy/not_checked/shoes3-tests/events/capture.rb +57 -0
  302. data/examples/legacy/not_checked/shoes3-tests/events/chipmunk.yaml +47 -0
  303. data/examples/legacy/not_checked/shoes3-tests/events/event0.rb +8 -0
  304. data/examples/legacy/not_checked/shoes3-tests/events/event1.rb +51 -0
  305. data/examples/legacy/not_checked/shoes3-tests/events/event1.yaml +26 -0
  306. data/examples/legacy/not_checked/shoes3-tests/events/event2.rb +46 -0
  307. data/examples/legacy/not_checked/shoes3-tests/events/event3.rb +44 -0
  308. data/examples/legacy/not_checked/shoes3-tests/events/event4.rb +65 -0
  309. data/examples/legacy/not_checked/shoes3-tests/events/event5.rb +17 -0
  310. data/examples/legacy/not_checked/shoes3-tests/events/event6.rb +51 -0
  311. data/examples/legacy/not_checked/shoes3-tests/events/replay.rb +60 -0
  312. data/examples/legacy/not_checked/shoes3-tests/gapp/fullscreen.rb +38 -0
  313. data/examples/legacy/not_checked/shoes3-tests/gapp/icon.rb +56 -0
  314. data/examples/legacy/not_checked/shoes3-tests/gapp/mon1.rb +46 -0
  315. data/examples/legacy/not_checked/shoes3-tests/gapp/settings1.rb +22 -0
  316. data/examples/legacy/not_checked/shoes3-tests/gapp/title1.rb +34 -0
  317. data/examples/legacy/not_checked/shoes3-tests/indian.m4a +0 -0
  318. data/examples/legacy/not_checked/shoes3-tests/menus/event.rb +33 -0
  319. data/examples/legacy/not_checked/shoes3-tests/menus/menu1.rb +8 -0
  320. data/examples/legacy/not_checked/shoes3-tests/menus/menu2.rb +25 -0
  321. data/examples/legacy/not_checked/shoes3-tests/menus/menu3.rb +103 -0
  322. data/examples/legacy/not_checked/shoes3-tests/menus/menu4.rb +41 -0
  323. data/examples/legacy/not_checked/shoes3-tests/menus/tests.txt +42 -0
  324. data/examples/legacy/not_checked/shoes3-tests/opacity.rb +13 -0
  325. data/examples/legacy/not_checked/shoes3-tests/plot/^IRX.R +5219 -0
  326. data/examples/legacy/not_checked/shoes3-tests/plot/^SPX +5219 -0
  327. data/examples/legacy/not_checked/shoes3-tests/plot/cstest.rb +51 -0
  328. data/examples/legacy/not_checked/shoes3-tests/plot/gr1.rb +73 -0
  329. data/examples/legacy/not_checked/shoes3-tests/plot/gr2.rb +40 -0
  330. data/examples/legacy/not_checked/shoes3-tests/plot/gr3.rb +47 -0
  331. data/examples/legacy/not_checked/shoes3-tests/plot/gr4.rb +35 -0
  332. data/examples/legacy/not_checked/shoes3-tests/plot/gr5.rb +31 -0
  333. data/examples/legacy/not_checked/shoes3-tests/plot/gr6.rb +35 -0
  334. data/examples/legacy/not_checked/shoes3-tests/plot/gr7.rb +37 -0
  335. data/examples/legacy/not_checked/shoes3-tests/plot/grcsv.rb +219 -0
  336. data/examples/legacy/not_checked/shoes3-tests/plot/manual.rb +40 -0
  337. data/examples/legacy/not_checked/shoes3-tests/progress/progress.rb +29 -0
  338. data/examples/legacy/not_checked/shoes3-tests/radio/clear.rb +20 -0
  339. data/examples/legacy/not_checked/shoes3-tests/radio/group.rb +18 -0
  340. data/examples/legacy/not_checked/shoes3-tests/radio/multiple.rb +32 -0
  341. data/examples/legacy/not_checked/shoes3-tests/radio/nogroup.rb +9 -0
  342. data/examples/legacy/not_checked/shoes3-tests/simpletest.svg +14 -0
  343. data/examples/legacy/not_checked/shoes3-tests/spinner.rb +15 -0
  344. data/examples/legacy/not_checked/shoes3-tests/svg.rb +208 -0
  345. data/examples/legacy/not_checked/shoes3-tests/switch/switch.rb +28 -0
  346. data/examples/legacy/not_checked/shoes3-tests/systray/back.rb +20 -0
  347. data/examples/legacy/not_checked/shoes3-tests/systray/note.rb +17 -0
  348. data/examples/legacy/not_checked/shoes3-tests/terminal/cursor.rb +27 -0
  349. data/examples/legacy/not_checked/shoes3-tests/terminal/ed.rb +65 -0
  350. data/examples/legacy/not_checked/shoes3-tests/terminal/el.rb +50 -0
  351. data/examples/legacy/not_checked/shoes3-tests/terminal/logattr.rb +31 -0
  352. data/examples/legacy/not_checked/shoes3-tests/tests_color.rb +138 -0
  353. data/examples/legacy/not_checked/shoes3-tests/tests_svg.rb +228 -0
  354. data/examples/legacy/not_checked/shoes3-tests/tests_video_vlc.rb +186 -0
  355. data/examples/legacy/not_checked/shoes3-tests/tooltips.rb +20 -0
  356. data/examples/legacy/not_checked/shoes3-tests/video_vlc.rb +242 -0
  357. data/examples/legacy/not_checked/shoes3-tests/wheel/wheel1.rb +21 -0
  358. data/examples/legacy/not_checked/simple/accordion.rb +81 -0
  359. data/examples/legacy/not_checked/simple/anim-shapes.rb +17 -0
  360. data/examples/legacy/not_checked/simple/anim-text.rb +13 -0
  361. data/examples/legacy/not_checked/simple/arc.rb +23 -0
  362. data/examples/legacy/not_checked/simple/bounce.rb +24 -0
  363. data/examples/legacy/not_checked/simple/chipmunk.rb +26 -0
  364. data/examples/legacy/not_checked/simple/control-sizes.rb +24 -0
  365. data/examples/legacy/not_checked/simple/curve-control-points.rb +24 -0
  366. data/examples/legacy/not_checked/simple/curve.rb +26 -0
  367. data/examples/legacy/not_checked/simple/dialogs.rb +29 -0
  368. data/examples/legacy/not_checked/simple/downloader.rb +40 -0
  369. data/examples/legacy/not_checked/simple/downloader1.rb +31 -0
  370. data/examples/legacy/not_checked/simple/draw.rb +13 -0
  371. data/examples/legacy/not_checked/simple/editor.rb +28 -0
  372. data/examples/legacy/not_checked/simple/form.rb +30 -0
  373. data/examples/legacy/not_checked/simple/image.rb +21 -0
  374. data/examples/legacy/not_checked/simple/info.rb +78 -0
  375. data/examples/legacy/not_checked/simple/mask.rb +21 -0
  376. data/examples/legacy/not_checked/simple/mask2.rb +27 -0
  377. data/examples/legacy/not_checked/simple/menu.rb +31 -0
  378. data/examples/legacy/not_checked/simple/menu1.rb +35 -0
  379. data/examples/legacy/not_checked/simple/slide.rb +45 -0
  380. data/examples/legacy/not_checked/simple/sphere.rb +28 -0
  381. data/examples/legacy/not_checked/superleg.rb +244 -0
  382. data/examples/legacy/working/shoes-contrib/basic/a-poem.rb +24 -0
  383. data/examples/legacy/working/shoes-contrib/basic/basic-blocks-instances.rb +7 -0
  384. data/examples/legacy/working/shoes-contrib/basic/basic-blocks.rb +7 -0
  385. data/examples/legacy/working/shoes-contrib/basic/basic-slot.rb +8 -0
  386. data/examples/legacy/working/shoes-contrib/basic/intro.rb +20 -0
  387. data/examples/legacy/working/shoes-contrib/basic/two-column.rb +12 -0
  388. data/examples/legacy/working/shoes-contrib/elements/edit_box.rb +6 -0
  389. data/examples/legacy/working/shoes-contrib/kernel/alert.rb +3 -0
  390. data/examples/legacy/working/simple/calc.rb +71 -0
  391. data/examples/legacy/working/simple/sqlite3.rb +27 -0
  392. data/examples/legacy/working/simple/timer.rb +13 -0
  393. data/examples/line.rb +5 -0
  394. data/examples/link.rb +20 -0
  395. data/examples/list_box.rb +8 -0
  396. data/examples/local_fonts.rb +4 -0
  397. data/examples/local_images.rb +4 -0
  398. data/examples/motion_events.rb +20 -0
  399. data/examples/para/collection_of_arguments.rb +9 -0
  400. data/examples/para/hello_world.rb +5 -0
  401. data/examples/para/hide_and_show.rb +9 -0
  402. data/examples/para/rainbow.rb +11 -0
  403. data/examples/para/rainbow_2.rb +11 -0
  404. data/examples/para/sizes.rb +11 -0
  405. data/examples/para/sizes_2.rb +12 -0
  406. data/examples/para/strong.rb +3 -0
  407. data/examples/para_text_widgets.rb +4 -0
  408. data/examples/parse_xl_funnies.rb +58 -0
  409. data/examples/pirate.png +0 -0
  410. data/examples/raw_flow.rb +11 -0
  411. data/examples/ruby_racer.rb +50 -0
  412. data/examples/selfitude.rb +18 -0
  413. data/examples/shapes/arc.rb +8 -0
  414. data/examples/shapes/shapes.rb +8 -0
  415. data/examples/shapes/shapes_fill.rb +10 -0
  416. data/examples/shapes/star.rb +5 -0
  417. data/examples/shoes_school.rb +66 -0
  418. data/examples/shoes_splorer.rb +150 -0
  419. data/examples/simple_slides.rb +73 -0
  420. data/examples/skip_ci/parrot.rb +22 -0
  421. data/examples/skip_ci/say.rb +20 -0
  422. data/examples/sleepless.rb +26 -0
  423. data/examples/slots.rb +10 -0
  424. data/examples/spacing.rb +18 -0
  425. data/examples/span.rb +6 -0
  426. data/examples/stack/background.rb +35 -0
  427. data/examples/stack/border.rb +11 -0
  428. data/examples/stack/gradients.rb +6 -0
  429. data/examples/stack/raw_stack.rb +8 -0
  430. data/examples/stack/stack.rb +27 -0
  431. data/examples/text_change.rb +4 -0
  432. data/examples/text_sizes.rb +10 -0
  433. data/examples/timmy.rb +109 -0
  434. data/examples/title_and_resize.rb +3 -0
  435. data/examples/video.rb +10 -0
  436. data/exe/scarpe +107 -0
  437. data/fonts/Pacifico.ttf +0 -0
  438. data/lib/scarpe/alert.rb +19 -0
  439. data/lib/scarpe/arc.rb +49 -0
  440. data/lib/scarpe/background.rb +14 -0
  441. data/lib/scarpe/base64.rb +27 -0
  442. data/lib/scarpe/border.rb +16 -0
  443. data/lib/scarpe/button.rb +35 -0
  444. data/lib/scarpe/cats_cradle.rb +255 -0
  445. data/lib/scarpe/colors.rb +215 -0
  446. data/lib/scarpe/display_service.rb +185 -0
  447. data/lib/scarpe/document_root.rb +20 -0
  448. data/lib/scarpe/download.rb +123 -0
  449. data/lib/scarpe/edit_box.rb +29 -0
  450. data/lib/scarpe/edit_line.rb +25 -0
  451. data/lib/scarpe/fill.rb +23 -0
  452. data/lib/scarpe/flow.rb +18 -0
  453. data/lib/scarpe/font.rb +14 -0
  454. data/lib/scarpe/glibui/README.md +34 -0
  455. data/lib/scarpe/glibui/alert.rb +65 -0
  456. data/lib/scarpe/glibui/app.rb +27 -0
  457. data/lib/scarpe/glibui/background.rb +18 -0
  458. data/lib/scarpe/glibui/border.rb +22 -0
  459. data/lib/scarpe/glibui/button.rb +38 -0
  460. data/lib/scarpe/glibui/dimensions.rb +22 -0
  461. data/lib/scarpe/glibui/document_root.rb +33 -0
  462. data/lib/scarpe/glibui/edit_box.rb +44 -0
  463. data/lib/scarpe/glibui/edit_line.rb +43 -0
  464. data/lib/scarpe/glibui/flow.rb +33 -0
  465. data/lib/scarpe/glibui/html.rb +77 -0
  466. data/lib/scarpe/glibui/image.rb +36 -0
  467. data/lib/scarpe/glibui/link.rb +29 -0
  468. data/lib/scarpe/glibui/local_display.rb +62 -0
  469. data/lib/scarpe/glibui/para.rb +84 -0
  470. data/lib/scarpe/glibui/spacing.rb +41 -0
  471. data/lib/scarpe/glibui/stack.rb +33 -0
  472. data/lib/scarpe/glibui/text_widget.rb +30 -0
  473. data/lib/scarpe/glibui/widget.rb +81 -0
  474. data/lib/scarpe/glibui.rb +29 -0
  475. data/lib/scarpe/image.rb +35 -0
  476. data/lib/scarpe/libui/alert.rb +9 -0
  477. data/lib/scarpe/libui/button.rb +18 -0
  478. data/lib/scarpe/libui/colors.rb +157 -0
  479. data/lib/scarpe/libui/core.rb +66 -0
  480. data/lib/scarpe/libui/flow.rb +16 -0
  481. data/lib/scarpe/libui/libui.rb +45 -0
  482. data/lib/scarpe/libui/notepad.md +26 -0
  483. data/lib/scarpe/libui/para.rb +154 -0
  484. data/lib/scarpe/libui/stack.rb +34 -0
  485. data/lib/scarpe/line.rb +25 -0
  486. data/lib/scarpe/link.rb +25 -0
  487. data/lib/scarpe/list_box.rb +25 -0
  488. data/lib/scarpe/logger.rb +159 -0
  489. data/lib/scarpe/para.rb +92 -0
  490. data/lib/scarpe/promises.rb +405 -0
  491. data/lib/scarpe/shape.rb +20 -0
  492. data/lib/scarpe/slot.rb +7 -0
  493. data/lib/scarpe/spacing.rb +9 -0
  494. data/lib/scarpe/span.rb +26 -0
  495. data/lib/scarpe/stack.rb +20 -0
  496. data/lib/scarpe/star.rb +47 -0
  497. data/lib/scarpe/subscription_item.rb +60 -0
  498. data/lib/scarpe/unit_test_helpers.rb +236 -0
  499. data/lib/scarpe/version.rb +5 -0
  500. data/lib/scarpe/video.rb +15 -0
  501. data/lib/scarpe/widgets.rb +35 -0
  502. data/lib/scarpe/wv/alert.rb +65 -0
  503. data/lib/scarpe/wv/app.rb +104 -0
  504. data/lib/scarpe/wv/arc.rb +57 -0
  505. data/lib/scarpe/wv/background.rb +27 -0
  506. data/lib/scarpe/wv/border.rb +24 -0
  507. data/lib/scarpe/wv/button.rb +50 -0
  508. data/lib/scarpe/wv/control_interface.rb +147 -0
  509. data/lib/scarpe/wv/control_interface_test.rb +234 -0
  510. data/lib/scarpe/wv/dimensions.rb +22 -0
  511. data/lib/scarpe/wv/document_root.rb +8 -0
  512. data/lib/scarpe/wv/edit_box.rb +44 -0
  513. data/lib/scarpe/wv/edit_line.rb +43 -0
  514. data/lib/scarpe/wv/fill.rb +30 -0
  515. data/lib/scarpe/wv/flow.rb +24 -0
  516. data/lib/scarpe/wv/font.rb +36 -0
  517. data/lib/scarpe/wv/html.rb +108 -0
  518. data/lib/scarpe/wv/image.rb +41 -0
  519. data/lib/scarpe/wv/line.rb +38 -0
  520. data/lib/scarpe/wv/link.rb +29 -0
  521. data/lib/scarpe/wv/list_box.rb +50 -0
  522. data/lib/scarpe/wv/para.rb +90 -0
  523. data/lib/scarpe/wv/shape.rb +35 -0
  524. data/lib/scarpe/wv/shape_helper.rb +44 -0
  525. data/lib/scarpe/wv/slot.rb +81 -0
  526. data/lib/scarpe/wv/spacing.rb +41 -0
  527. data/lib/scarpe/wv/span.rb +66 -0
  528. data/lib/scarpe/wv/stack.rb +24 -0
  529. data/lib/scarpe/wv/star.rb +64 -0
  530. data/lib/scarpe/wv/subscription_item.rb +50 -0
  531. data/lib/scarpe/wv/text_widget.rb +30 -0
  532. data/lib/scarpe/wv/video.rb +42 -0
  533. data/lib/scarpe/wv/web_wrangler.rb +683 -0
  534. data/lib/scarpe/wv/webview_local_display.rb +73 -0
  535. data/lib/scarpe/wv/webview_relay_display.rb +185 -0
  536. data/lib/scarpe/wv/widget.rb +185 -0
  537. data/lib/scarpe/wv/wv_display_worker.rb +65 -0
  538. data/lib/scarpe/wv.rb +43 -0
  539. data/lib/scarpe/wv_local.rb +6 -0
  540. data/lib/scarpe/wv_relay.rb +6 -0
  541. data/lib/scarpe.rb +29 -0
  542. data/lib/shoes/app.rb +187 -0
  543. data/lib/shoes/constants.rb +26 -0
  544. data/lib/shoes/text_widget.rb +52 -0
  545. data/lib/shoes/widget.rb +209 -0
  546. data/lib/shoes.rb +65 -0
  547. data/logger/debug_web_wrangler.json +4 -0
  548. data/logger/scarpe_wv_test.json +4 -0
  549. data/scarpe-0.2.0.gem +0 -0
  550. data/scarpe.gemspec +44 -0
  551. data/scarpegen.rb +193 -0
  552. data/sig/scarpe.rbs +4 -0
  553. data/templates/basic_class_template.erb +38 -0
  554. data/templates/class_template_with_event_bind.erb +27 -0
  555. data/templates/class_template_with_shapes.erb +43 -0
  556. data/templates/example_template.erb +3 -0
  557. data/templates/module_template.erb +12 -0
  558. data/templates/webview_template.erb +27 -0
  559. metadata +606 -0
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ # This is an in-process Webview-based display service, with all the limitations that
5
+ # entails. Slow handlers will crash, ending this display service will end the
6
+ # process, too many or too large evals can crash the process, etc.
7
+ # Normally the intention is to use a RelayDisplayService to a second
8
+ # process containing one of these.
9
+ class WebviewDisplayService < Shoes::DisplayService
10
+ include Scarpe::Log
11
+
12
+ class << self
13
+ attr_accessor :instance
14
+ end
15
+
16
+ # TODO: re-think the list of top-level singleton objects.
17
+ attr_reader :control_interface
18
+ attr_reader :doc_root
19
+ attr_reader :app
20
+ attr_reader :wrangler
21
+
22
+ # This is called before any of the various WebviewWidgets are created.
23
+ def initialize
24
+ if WebviewDisplayService.instance
25
+ raise "ERROR! This is meant to be a singleton!"
26
+ end
27
+
28
+ WebviewDisplayService.instance = self
29
+
30
+ super()
31
+ log_init("WV::WebviewDisplayService")
32
+
33
+ @display_widget_for = {}
34
+ end
35
+
36
+ def create_display_widget_for(widget_class_name, widget_id, properties)
37
+ if widget_class_name == "App"
38
+ unless @doc_root
39
+ raise "WebviewDocumentRoot is supposed to be created before WebviewApp!"
40
+ end
41
+
42
+ display_app = Scarpe::WebviewApp.new(properties)
43
+ display_app.document_root = @doc_root
44
+ @control_interface = display_app.control_interface
45
+ @control_interface.doc_root = @doc_root
46
+ @app = @control_interface.app
47
+ @wrangler = @control_interface.wrangler
48
+
49
+ set_widget_pairing(widget_id, display_app)
50
+
51
+ return display_app
52
+ end
53
+
54
+ # Create a corresponding display widget
55
+ display_class = Scarpe::WebviewWidget.display_class_for(widget_class_name)
56
+ display_widget = display_class.new(properties)
57
+ set_widget_pairing(widget_id, display_widget)
58
+
59
+ if widget_class_name == "DocumentRoot"
60
+ # WebviewDocumentRoot is created before WebviewApp. Mostly doc_root is just like any other widget,
61
+ # but we'll want a reference to it when we create WebviewApp.
62
+ @doc_root = display_widget
63
+ end
64
+
65
+ display_widget
66
+ end
67
+
68
+ def destroy
69
+ @app.destroy
70
+ WebviewDisplayService.instance = nil
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "rbconfig"
5
+
6
+ class Scarpe
7
+ class AppShutdownError < Scarpe::Error; end
8
+
9
+ module WVRelayUtil # Make sure the including class also includes Scarpe::Log
10
+ def ready_to_read?(timeout = 0.0)
11
+ r, _, e = IO.select [@from], [], [@from, @to].uniq, timeout
12
+
13
+ # On timeout, select returns nil instead of arrays.
14
+ return if r.nil?
15
+
16
+ unless e.empty?
17
+ raise "#{@i_am}: Got error on connection(s) from IO.select! Dying!"
18
+ end
19
+
20
+ !r.empty?
21
+ end
22
+
23
+ def send_datagram(contents)
24
+ str_data = JSON.dump contents
25
+ dgram_str = (str_data.length.to_s + "a" + str_data).encode(Encoding::BINARY)
26
+ to_write = dgram_str.bytesize
27
+ written = 0
28
+
29
+ until written == to_write
30
+ count = @to.write(dgram_str.byteslice(written..-1))
31
+ if count.nil? || count == 0
32
+ raise "Something was wrong in send_datagram! Write returned #{count.inspect}!"
33
+ end
34
+
35
+ written += count
36
+ end
37
+
38
+ nil
39
+ end
40
+
41
+ def receive_datagram
42
+ @readbuf ||= String.new.encode(Encoding::BINARY)
43
+ to_read = nil
44
+
45
+ loop do
46
+ # Have we read a packet length already, sitting in @readbuf?
47
+ a_idx = @readbuf.index("a")
48
+ if a_idx
49
+ to_read = @readbuf[0..a_idx].to_i
50
+ @readbuf = @readbuf[(a_idx + 1)..-1]
51
+ break
52
+ end
53
+
54
+ # If not, read more bytes
55
+ new_bytes = @from.read(10)
56
+ if new_bytes.nil?
57
+ # This is perfectly normal, if the connection closed
58
+ raise AppShutdownError, "Got an unexpected EOF reading datagram! " +
59
+ "Did the #{@i_am == :child ? "parent" : "child"} process die?"
60
+ end
61
+ @readbuf << new_bytes
62
+ end
63
+
64
+ loop do
65
+ if @readbuf.bytesize >= to_read
66
+ out = @readbuf.byteslice(0, to_read)
67
+ @readbuf = @readbuf.byteslice(to_read, -1)
68
+ return out
69
+ end
70
+
71
+ new_bytes = @from.read(to_read - @readbuf.bytesize)
72
+ @readbuf << new_bytes
73
+ end
74
+ rescue
75
+ raise AppShutdownError, "Got exception #{$!.class} when receiving datagram... #{$!.inspect}"
76
+ end
77
+
78
+ def respond_to_datagram
79
+ message = receive_datagram
80
+ m_data = JSON.parse(message)
81
+
82
+ if m_data["type"] == "event"
83
+ kwargs_hash = {}
84
+ m_data["kwargs"].each { |k, v| kwargs_hash[k.to_sym] = v }
85
+ send_shoes_event(
86
+ *m_data["args"],
87
+ event_name: m_data["kwargs"]["event_name"],
88
+ target: m_data["kwargs"]["event_target"],
89
+ **kwargs_hash,
90
+ )
91
+ elsif m_data["type"] == "create"
92
+ raise "Parent process should never receive :create datagram!" if @i_am == :parent
93
+
94
+ @wv_display.create_display_widget_for(m_data["class_name"], m_data["id"], m_data["properties"])
95
+ elsif m_data["type"] == "destroy"
96
+ if @i_am == :parent
97
+ @shutdown = true
98
+ else
99
+ @log.info("Shutting down...")
100
+ exit 0
101
+ end
102
+ else
103
+ @log.error("Unrecognized datagram type:event: #{m_data.inspect}!")
104
+ end
105
+ end
106
+
107
+ def event_loop_for(t = 1.5)
108
+ t_start = Time.now
109
+ delay_time = t
110
+
111
+ while Time.now - t_start < delay_time
112
+ if ready_to_read?(0.1)
113
+ respond_to_datagram
114
+ else
115
+ sleep 0.1
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ # This "display service" actually creates a child process and sends events
122
+ # back and forth, but creates no widgets of its own.
123
+ class WVRelayDisplayService < Shoes::DisplayService
124
+ include Scarpe::Log
125
+ include WVRelayUtil # Needs Scarpe::Log
126
+
127
+ attr_accessor :shutdown
128
+
129
+ def initialize
130
+ super()
131
+ log_init("WV::RelayDisplayService")
132
+
133
+ @event_subs = []
134
+ @shutdown = false
135
+ @i_am = :parent
136
+
137
+ server = TCPServer.new("127.0.0.1", 0)
138
+ port = server.addr[1]
139
+
140
+ @pid = spawn(RbConfig.ruby, File.join(__dir__, "wv_display_worker.rb"), port.to_s)
141
+ @from = @to = server.accept
142
+
143
+ # Subscribe to all event notifications and relay them to the worker
144
+ @event_subs << bind_shoes_event(event_name: :any, target: :any) do |*args, **kwargs|
145
+ unless kwargs[:relayed]
146
+ kwargs[:relayed] = true
147
+ send_datagram({ type: :event, args:, kwargs: })
148
+ end
149
+
150
+ # Forward the run event to the child process before doing this
151
+ if event_name == "run"
152
+ run_event_loop
153
+ end
154
+ rescue AppShutdownError
155
+ @shutdown = true
156
+ @log.info("Attempting to shut down...")
157
+ self.destroy
158
+ end
159
+ end
160
+
161
+ def run_event_loop
162
+ until @shutdown
163
+ respond_to_datagram while ready_to_read?
164
+ sleep 0.1
165
+ end
166
+ rescue AppShutdownError
167
+ @shutdown = true
168
+ @log.info("Attempting to shut down...")
169
+ self.destroy
170
+ end
171
+
172
+ def create_display_widget_for(widget_class_name, widget_id, properties)
173
+ send_datagram({ type: :create, class_name: widget_class_name, id: widget_id, properties: })
174
+ # Don't need to return anything. It wouldn't be used anyway.
175
+ end
176
+
177
+ def destroy
178
+ unless @shutdown
179
+ send_datagram({ type: :destroy })
180
+ end
181
+ @shutdown = true
182
+ (@events_subs || []).each { |unsub_id| DisplayService.unsub_from_events(unsub_id) }
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewWidget < Shoes::Linkable
5
+ include Scarpe::Log
6
+
7
+ class << self
8
+ def display_class_for(scarpe_class_name)
9
+ scarpe_class = Scarpe.const_get(scarpe_class_name)
10
+ unless scarpe_class.ancestors.include?(Shoes::Linkable)
11
+ raise "Scarpe Webview can only get display classes for Scarpe " +
12
+ "linkable widgets, not #{scarpe_class_name.inspect}!"
13
+ end
14
+
15
+ klass = Scarpe.const_get("Webview" + scarpe_class_name.split("::")[-1])
16
+ if klass.nil?
17
+ raise "Couldn't find corresponding Scarpe Webview class for #{scarpe_class_name.inspect}!"
18
+ end
19
+
20
+ klass
21
+ end
22
+ end
23
+
24
+ attr_reader :shoes_linkable_id
25
+ attr_reader :parent
26
+ attr_reader :children
27
+
28
+ def initialize(properties)
29
+ log_init("WV::Widget")
30
+
31
+ # Call method, which looks up the parent
32
+ @shoes_linkable_id = properties["shoes_linkable_id"] || properties[:shoes_linkable_id]
33
+ unless @shoes_linkable_id
34
+ raise "Could not find property shoes_linkable_id in #{properties.inspect}!"
35
+ end
36
+
37
+ # Set the display properties
38
+ properties.each do |k, v|
39
+ next if k == "shoes_linkable_id"
40
+
41
+ instance_variable_set("@" + k.to_s, v)
42
+ end
43
+
44
+ # The parent field is *almost* simple enough that a typed display property would handle it.
45
+ bind_shoes_event(event_name: "parent", target: shoes_linkable_id) do |new_parent_id|
46
+ display_parent = WebviewDisplayService.instance.query_display_widget_for(new_parent_id)
47
+ if @parent != display_parent
48
+ set_parent(display_parent)
49
+ end
50
+ end
51
+
52
+ # When Shoes widgets change properties, we get a change notification here
53
+ bind_shoes_event(event_name: "prop_change", target: shoes_linkable_id) do |prop_changes|
54
+ prop_changes.each do |k, v|
55
+ instance_variable_set("@" + k, v)
56
+ end
57
+ properties_changed(prop_changes)
58
+ end
59
+
60
+ bind_shoes_event(event_name: "destroy", target: shoes_linkable_id) do
61
+ destroy_self
62
+ end
63
+
64
+ super(linkable_id: @shoes_linkable_id)
65
+ end
66
+
67
+ # This exists to be overridden by children watching for changes
68
+ def properties_changed(changes)
69
+ needs_update! unless changes.empty?
70
+ end
71
+
72
+ def set_parent(new_parent)
73
+ @parent&.remove_child(self)
74
+ new_parent&.add_child(self)
75
+ @parent = new_parent
76
+ end
77
+
78
+ def inspect
79
+ "#<#{self.class}:#{self.object_id} @shoes_linkable_id=#{@shoes_linkable_id} @parent=#{@parent.inspect} @children=#{@children.inspect}>"
80
+ end
81
+
82
+ protected
83
+
84
+ # Do not call directly, use set_parent
85
+ def remove_child(child)
86
+ @children ||= []
87
+ unless @children.include?(child)
88
+ @log.error("remove_child: no such child(#{child.inspect}) for"\
89
+ " parent(#{parent.inspect})!")
90
+ end
91
+ @children.delete(child)
92
+ end
93
+
94
+ # Do not call directly, use set_parent
95
+ def add_child(child)
96
+ @children ||= []
97
+ @children << child
98
+
99
+ # If we add a child, we should redraw ourselves
100
+ needs_update!
101
+ end
102
+
103
+ # Convert an [r, g, b, a] array to an HTML hex color code
104
+ # Arrays support alpha. HTML hex does not. So premultiply.
105
+ def rgb_to_hex(color)
106
+ return color if color.nil?
107
+
108
+ r, g, b, a = *color
109
+ if r.is_a?(Float)
110
+ a ||= 1.0
111
+ r_float = r * a
112
+ g_float = g * a
113
+ b_float = b * a
114
+ else
115
+ a ||= 255
116
+ a_float = (a / 255.0)
117
+ r_float = (r.to_f / 255.0) * a_float
118
+ g_float = (g.to_f / 255.0) * a_float
119
+ b_float = (b.to_f / 255.0) * a_float
120
+ end
121
+
122
+ r_int = (r_float * 255.0).to_i.clamp(0, 255)
123
+ g_int = (g_float * 255.0).to_i.clamp(0, 255)
124
+ b_int = (b_float * 255.0).to_i.clamp(0, 255)
125
+
126
+ "#%0.2X%0.2X%0.2X" % [r_int, g_int, b_int]
127
+ end
128
+
129
+ public
130
+
131
+ # This gets a mini-webview for just this element and its children, if any
132
+ def html_element
133
+ @elt_wrangler ||= Scarpe::WebWrangler::ElementWrangler.new(html_id)
134
+ end
135
+
136
+ # Return a promise that guarantees all currently-requested changes have completed
137
+ def promise_update
138
+ html_element.promise_update
139
+ end
140
+
141
+ def html_id
142
+ object_id.to_s
143
+ end
144
+
145
+ # to_html is intended to get the HTML DOM rendering of this object and its children.
146
+ # Calling it should be side-effect-free and NOT update the webview.
147
+ def to_html
148
+ @children ||= []
149
+ child_markup = @children.map(&:to_html).join
150
+ if respond_to?(:element)
151
+ element { child_markup }
152
+ else
153
+ child_markup
154
+ end
155
+ end
156
+
157
+ # This binds a Scarpe JS callback, handled via a single dispatch point in the document root
158
+ def bind(event, &block)
159
+ raise("Widget has no linkable_id! #{inspect}") unless linkable_id
160
+
161
+ WebviewDisplayService.instance.app.bind("#{linkable_id}-#{event}", &block)
162
+ end
163
+
164
+ # Removes the element from both the Ruby Widget tree and the HTML DOM.
165
+ # Return a promise for when that HTML change will be visible.
166
+ def destroy_self
167
+ @parent&.remove_child(self)
168
+ html_element.remove
169
+ end
170
+
171
+ # It's really hard to do dirty-tracking here because the redraws are fully asynchronous.
172
+ # And so we can't easily cancel one "in flight," and we can't easily pick up the latest
173
+ # changes... And we probably don't want to, because we may be halfway through a batch.
174
+ def needs_update!
175
+ WebviewDisplayService.instance.app.request_redraw!
176
+ end
177
+
178
+ def handler_js_code(handler_function_name, *args)
179
+ raise("Widget has no linkable_id! #{inspect}") unless linkable_id
180
+
181
+ js_args = ["'#{linkable_id}-#{handler_function_name}'", *args].join(", ")
182
+ "scarpeHandler(#{js_args})"
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "socket"
5
+
6
+ # Wherever this file is installed, locate Scarpe relative to it. This could be an installed gem or a dev repo.
7
+ SCARPE_DIR = File.join(__dir__, "../..")
8
+
9
+ $LOAD_PATH.prepend(SCARPE_DIR)
10
+ require "scarpe"
11
+ require "scarpe/wv_local"
12
+
13
+ # This script exists to create a WebviewDisplayService that can be operated remotely over a socket.
14
+
15
+ if ARGV.length != 1
16
+ $stderr.puts("Usage: wv_display_worker.rb tcp_port_num")
17
+ exit(-1)
18
+ end
19
+
20
+ class WebviewContainedService < Shoes::Linkable
21
+ include Scarpe::Log
22
+ include Scarpe::WVRelayUtil # Needs Scarpe::Log
23
+
24
+ attr_reader :log
25
+
26
+ def initialize(from, to)
27
+ super()
28
+ log_init("WV::DisplayWorker")
29
+
30
+ @i_am = :child
31
+ @event_subs = []
32
+ @wv_display = Scarpe::WebviewDisplayService.new
33
+
34
+ @from = from
35
+ @to = to
36
+
37
+ @init_done = false
38
+
39
+ # Wait to register our periodic_code until the wrangler exists
40
+ @event_subs << bind_shoes_event(event_name: "init") do
41
+ @wv_display.wrangler.periodic_code("datagramProcessor", 0.1) do
42
+ respond_to_datagram while ready_to_read?(0.0)
43
+ end
44
+ @init_done = true
45
+ end
46
+
47
+ # Subscribe to all event notifications and relay them to the opposite side
48
+ @event_subs << bind_shoes_event(event_name: :any, target: :any) do |*args, **kwargs|
49
+ unless kwargs[:relayed] || kwargs["relayed"]
50
+ kwargs[:relayed] = true
51
+ send_datagram({ type: :event, args:, kwargs: })
52
+ end
53
+ end
54
+
55
+ # Run for 2.5 seconds to let the app be created and "run" to get called.
56
+ # Once that happens, Webview will take over the event loop.
57
+ event_loop_for(2.5)
58
+ end
59
+ end
60
+
61
+ s = TCPSocket.new("localhost", ARGV[0].to_i)
62
+
63
+ SERVICE = WebviewContainedService.new(s, s)
64
+
65
+ SERVICE.log.info("Finished event loop. Exiting!")
data/lib/scarpe/wv.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Scarpe Webview Display Services
4
+
5
+ require_relative "wv/web_wrangler"
6
+ require_relative "wv/control_interface"
7
+
8
+ require_relative "wv/widget"
9
+ require_relative "wv/webview_local_display"
10
+ require_relative "wv/webview_relay_display"
11
+
12
+ require_relative "wv/dimensions"
13
+ require_relative "wv/html"
14
+
15
+ require_relative "wv/spacing"
16
+ require_relative "wv/star"
17
+ require_relative "wv/background"
18
+ require_relative "wv/border"
19
+
20
+ require_relative "wv/fill"
21
+ require_relative "wv/arc"
22
+ require_relative "wv/font"
23
+
24
+ require_relative "wv/app"
25
+ require_relative "wv/para"
26
+ require_relative "wv/slot"
27
+ require_relative "wv/stack"
28
+ require_relative "wv/flow"
29
+ require_relative "wv/document_root"
30
+ require_relative "wv/subscription_item"
31
+ require_relative "wv/button"
32
+ require_relative "wv/image"
33
+ require_relative "wv/edit_box"
34
+ require_relative "wv/edit_line"
35
+ require_relative "wv/list_box"
36
+ require_relative "wv/alert"
37
+ require_relative "wv/span"
38
+ require_relative "wv/shape"
39
+
40
+ require_relative "wv/text_widget"
41
+ require_relative "wv/link"
42
+ require_relative "wv/line"
43
+ require_relative "wv/video"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv"
4
+ require_relative "wv/webview_local_display"
5
+
6
+ Shoes::DisplayService.set_display_service_class(Scarpe::WebviewDisplayService)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv"
4
+ require_relative "wv/webview_relay_display"
5
+
6
+ Shoes::DisplayService.set_display_service_class(Scarpe::WVRelayDisplayService)
data/lib/scarpe.rb ADDED
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "shoes"
4
+
5
+ require_relative "scarpe/logger"
6
+
7
+ # This will never be triggered -- we use the (...) feature below, which means this
8
+ # file won't even parse in old Rubies.
9
+ if RUBY_VERSION[0..2] < "3.2"
10
+ Scarpe::Logger.logger("Scarpe").error("Scarpe requires Ruby 3.2 or higher!")
11
+ exit(-1)
12
+ end
13
+
14
+ require "securerandom"
15
+ require "json"
16
+
17
+ # Is there a Shoes::Error class? Should this be two different error classes?
18
+ class Scarpe::Error < StandardError; end
19
+
20
+ require_relative "scarpe/version"
21
+ require_relative "scarpe/promises"
22
+ require_relative "scarpe/display_service"
23
+ require_relative "scarpe/widgets"
24
+
25
+ require "bloops"
26
+
27
+ d_s = ENV["SCARPE_DISPLAY_SERVICE"] || "wv_local"
28
+ # This is require, not require_relative, to allow gems to supply a new display service
29
+ require "scarpe/#{d_s}"