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,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "scarpe/base64"
4
+
5
+ class Scarpe
6
+ module WebviewBackground
7
+ include Base64
8
+
9
+ def style
10
+ styles = (super if defined?(super)) || {}
11
+ return styles unless @background_color
12
+
13
+ color = case @background_color
14
+ when Array
15
+ "rgba(#{@background_color.join(", ")})"
16
+ when Range
17
+ "linear-gradient(45deg, #{@background_color.first}, #{@background_color.last})"
18
+ when ->(value) { File.exist?(value) }
19
+ "url(data:image/png;base64,#{encode_file_to_base64(@background_color)})"
20
+ else
21
+ @background_color
22
+ end
23
+
24
+ styles.merge(background: color)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ module WebviewBorder
5
+ def style
6
+ styles = (super if defined?(super)) || {}
7
+ return styles unless @border_color
8
+
9
+ border_color = case @border_color
10
+ when Range
11
+ { "border-image": "linear-gradient(45deg, #{@border_color.first}, #{@border_color.last})" }
12
+ when Array
13
+ { "border-color": "rgba(#{@border_color.join(", ")})" }
14
+ else
15
+ { "border-color": @border_color }
16
+ end
17
+ styles.merge(
18
+ "border-style": "solid",
19
+ "border-width": "#{@options[:strokewidth] || 1}px",
20
+ "border-radius": "#{@options[:curve] || 0}px",
21
+ ).merge(border_color)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewButton < WebviewWidget
5
+ def initialize(properties)
6
+ super
7
+
8
+ # Bind to display-side handler for "click"
9
+ bind("click") do
10
+ # This will be sent to the bind_self_event in Button
11
+ send_self_event(event_name: "click")
12
+ end
13
+ end
14
+
15
+ def element
16
+ HTML.render do |h|
17
+ h.button(id: html_id, onclick: handler_js_code("click"), style: style) do
18
+ @text
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def style
26
+ styles = {}
27
+ styles["background-color"] = @color
28
+ styles["padding-top"] = @padding_top
29
+ styles["padding-bottom"] = @padding_bottom
30
+ styles[:color] = @text_color
31
+ styles[:width] = Dimensions.length(@width) if @width
32
+ styles[:height] = Dimensions.length(@height) if @height
33
+ styles["font-size"] = @font_size
34
+
35
+ styles[:top] = Dimensions.length(@top) if @top
36
+ styles[:left] = Dimensions.length(@left) if @left
37
+ styles[:position] = "absolute" if @top || @left
38
+ styles["font-size"] = Dimensions.length(font_size) if @size
39
+ styles["font-family"] = @font if @font
40
+ styles["color"] = rgb_to_hex(@stroke) if @stroke
41
+ styles
42
+ end
43
+
44
+ def font_size
45
+ font_size = @size.is_a?(Symbol) ? SIZES[@size] : @size
46
+
47
+ Dimensions.length(font_size)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The ControlInterface is used for testing. It's a way to register interest
4
+ # in important events like redraw, init and shutdown, and to configure a
5
+ # Shoes app for testing. Note that no part of the Scarpe framework should
6
+ # ever *depend* on ControlInterface. It's for testing, not normal operation.
7
+ # If no ControlInterface were ever created or called, Scarpe apps should run
8
+ # fine with no modifications.
9
+ #
10
+ # And if you depend on this from the framework, I'll add a check-mode that
11
+ # never dispatches any events to any handlers. Do NOT test me on this.
12
+
13
+ class Scarpe
14
+ class ControlInterface
15
+ include Scarpe::Log
16
+
17
+ SUBSCRIBE_EVENTS = [:init, :shutdown, :next_redraw, :every_redraw, :next_heartbeat, :every_heartbeat]
18
+ DISPATCH_EVENTS = [:init, :shutdown, :redraw, :heartbeat]
19
+
20
+ attr_writer :doc_root
21
+ attr_reader :do_shutdown
22
+
23
+ # The control interface needs to see major system components to hook into their events
24
+ def initialize
25
+ log_init("WV::ControlInterface")
26
+
27
+ @do_shutdown = false
28
+ @event_handlers = {}
29
+ (SUBSCRIBE_EVENTS | DISPATCH_EVENTS).each { |e| @event_handlers[e] = [] }
30
+ end
31
+
32
+ def inspect
33
+ "<#ControlInterface>"
34
+ end
35
+
36
+ # This should get called once, from Shoes::App
37
+ def set_system_components(app:, doc_root:, wrangler:)
38
+ unless app && wrangler
39
+ @log.error("False app passed to set_system_components!") unless app
40
+ @log.error("False wrangler passed to set_system_components!") unless wrangler
41
+ raise "Must pass non-nil app and wrangler to ControlInterface#set_system_components!"
42
+ end
43
+ @app = app
44
+ @doc_root = doc_root # May be nil at this point
45
+ @wrangler = wrangler
46
+
47
+ @wrangler.control_interface = self
48
+
49
+ @wrangler.on_every_redraw { self.dispatch_event(:redraw) }
50
+ end
51
+
52
+ def app
53
+ unless @app
54
+ raise "ControlInterface code needs to be wrapped in handlers like on_event(:init) " +
55
+ "to make sure they have access to app, doc_root, wrangler, etc!"
56
+ end
57
+
58
+ @app
59
+ end
60
+
61
+ def doc_root
62
+ unless @doc_root
63
+ raise "ControlInterface code needs to be wrapped in handlers like on_event(:init) " +
64
+ "to make sure they have access to app, doc_root, wrangler, etc!"
65
+ end
66
+
67
+ @doc_root
68
+ end
69
+
70
+ def wrangler
71
+ unless @wrangler
72
+ raise "ControlInterface code needs to be wrapped in handlers like on_event(:init) " +
73
+ "to make sure they have access to app, doc_root, wrangler, etc!"
74
+ end
75
+
76
+ @wrangler
77
+ end
78
+
79
+ # The control interface has overrides for certain settings. If the override has been specified,
80
+ # those settings will be overridden.
81
+
82
+ # On recognised events, this sets a handler for that event
83
+ def on_event(event, &block)
84
+ unless SUBSCRIBE_EVENTS.include?(event)
85
+ raise "Illegal subscribe to event #{event.inspect}! Valid values are: #{SUBSCRIBE_EVENTS.inspect}"
86
+ end
87
+
88
+ @unsub_id ||= 0
89
+ @unsub_id += 1
90
+
91
+ @event_handlers[event] << { handler: block, unsub: @unsub_id }
92
+ @unsub_id
93
+ end
94
+
95
+ # Send out the specified event
96
+ def dispatch_event(event, *args, **keywords)
97
+ @log.debug("CTL event #{event.inspect} #{args.inspect} #{keywords.inspect}")
98
+
99
+ unless DISPATCH_EVENTS.include?(event)
100
+ raise "Illegal dispatch of event #{event.inspect}! Valid values are: #{DISPATCH_EVENTS.inspect}"
101
+ end
102
+
103
+ if @do_shutdown
104
+ @log.debug("CTL: Shutting down - not dispatching #{event}!")
105
+ return
106
+ end
107
+
108
+ if event == :redraw
109
+ dumb_dispatch_event(:every_redraw, *args, **keywords)
110
+
111
+ # Next redraw is interesting. We can add new handlers
112
+ # when dispatching a next_redraw handler. But we want
113
+ # each handler to run only once.
114
+ handlers = @event_handlers[:next_redraw]
115
+ dumb_dispatch_event(:next_redraw, *args, **keywords)
116
+ @event_handlers[:next_redraw] -= handlers
117
+ return
118
+ end
119
+
120
+ if event == :heartbeat
121
+ dumb_dispatch_event(:every_heartbeat, *args, **keywords)
122
+
123
+ # Next heartbeat is interesting. We can add new handlers
124
+ # when dispatching a next_heartbeat handler. But we want
125
+ # each handler to run only once.
126
+ handlers = @event_handlers[:next_heartbeat]
127
+ dumb_dispatch_event(:next_heartbeat, *args, **keywords)
128
+ @event_handlers[:next_heartbeat] -= handlers
129
+ return
130
+ end
131
+
132
+ if event == :shutdown
133
+ @do_shutdown = true
134
+ end
135
+
136
+ dumb_dispatch_event(event, *args, **keywords)
137
+ end
138
+
139
+ private
140
+
141
+ def dumb_dispatch_event(event, *args, **keywords)
142
+ @event_handlers[event].each do |data|
143
+ instance_eval(*args, **keywords, &data[:handler])
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,234 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The ControlInterface doesn't, by default, include much of a test framework.
4
+ # But writing a test framework in heredocs in test_helper.rb seems bad.
5
+ # So we write a test framework here, but don't include it by default.
6
+ # A running shoes app won't normally include it, but unit tests will.
7
+
8
+ require "json"
9
+
10
+ class Scarpe
11
+ DEFAULT_ASSERTION_TIMEOUT = 1.0
12
+
13
+ class ControlInterface
14
+ include Scarpe::Test::Helpers
15
+
16
+ def timed_out?
17
+ @did_time_out
18
+ end
19
+
20
+ def die_after(time)
21
+ t_start = Time.now
22
+ @die_after = [t_start, time]
23
+
24
+ wrangler.periodic_code("scarpeTestTimeout") do |*_args|
25
+ t_delta = (Time.now - t_start).to_f
26
+ if t_delta > time
27
+ @did_time_out = true
28
+ @log.warn("die_after - timed out after #{t_delta.inspect} (threshold: #{time.inspect})")
29
+ return_results(false, "Timed out!")
30
+ app.destroy
31
+ end
32
+ end
33
+ end
34
+
35
+ # This is returned alongside the actual results automatically
36
+ def test_metadata
37
+ data = {}
38
+ if @die_after
39
+ t_delta = (Time.now - @die_after[0]).to_f
40
+ data["die_after"] = {
41
+ t_start: @die_after[0].to_s,
42
+ threshold: @die_after[1],
43
+ passed: t_delta,
44
+ }
45
+ end
46
+ data
47
+ end
48
+
49
+ # Need to be able to query widgets in test code
50
+
51
+ def all_wv_widgets
52
+ known = [doc_root]
53
+ to_check = [doc_root]
54
+
55
+ until to_check.empty?
56
+ next_layer = to_check.flat_map(&:children)
57
+ known += next_layer
58
+ to_check = next_layer
59
+ end
60
+
61
+ # I don't *think* we'll ever have widget trees that merge back together, but just in case we'll de-dup
62
+ known.uniq
63
+ end
64
+
65
+ # Shoes doesn't name widgets. We aren't guaranteed that the Shoes widgets are even in the same
66
+ # process, since we have the Relay display service for Webview. So mostly we can look by
67
+ # display service class.
68
+ def find_wv_widgets(*specifiers)
69
+ widgets = all_wv_widgets
70
+
71
+ specifiers.each do |spec|
72
+ if spec.is_a?(Class)
73
+ widgets.select! { |w| spec === w }
74
+ else
75
+ raise "I don't know how to search for widgets by #{spec.inspect}!"
76
+ end
77
+ end
78
+
79
+ widgets
80
+ end
81
+
82
+ # We want an assertions library, but one that runs inside the spawned
83
+ # Webview sub-process.
84
+
85
+ # Note that we do *not* extract this assertions library to use elsewhere
86
+ # because it's very focused on evented assertions that start and stop
87
+ # over a period of time. Instantaneous procedural asserts don't want to
88
+ # use this API.
89
+
90
+ def return_when_assertions_done
91
+ assertions_may_exist
92
+
93
+ wrangler.periodic_code("scarpeReturnWhenAssertionsDone") do |*_args|
94
+ if @assertions_pending.empty?
95
+ success = @assertions_failed.empty?
96
+ return_results success, "Assertions #{success ? "succeeded" : "failed"}", assertion_data_as_a_struct
97
+ app.destroy
98
+ end
99
+ end
100
+ end
101
+
102
+ def assertions_may_exist
103
+ @assertions_pending ||= {}
104
+ @assertions_failed ||= {}
105
+ @assertions_passed ||= 0
106
+ @assertion_counter ||= 0
107
+ end
108
+
109
+ def start_assertion(code)
110
+ assertions_may_exist
111
+
112
+ this_assertion = @assertion_counter
113
+ @assertion_counter += 1
114
+
115
+ @assertions_pending[this_assertion] = {
116
+ id: this_assertion,
117
+ code: code,
118
+ }
119
+
120
+ this_assertion
121
+ end
122
+
123
+ def pass_assertion(id)
124
+ @assertions_pending.delete(id)
125
+ @assertions_passed += 1
126
+ end
127
+
128
+ def fail_assertion(id, fail_message)
129
+ item = @assertions_pending.delete(id)
130
+ item[:fail_message] = fail_message
131
+ @assertions_failed[id] = item
132
+ end
133
+
134
+ def assertions_pending?
135
+ !@assertions_pending.empty?
136
+ end
137
+
138
+ def assertion_data_as_a_struct
139
+ {
140
+ still_pending: @assertions_pending.size,
141
+ succeeded: @assertions_passed,
142
+ failed: @assertions_failed.size,
143
+ failures: @assertions_failed.values.map { |item| [item[:code], item[:failure_reason]] },
144
+ }
145
+ end
146
+
147
+ # Create a promise to do a JS assertion, normally after other ops have finished.
148
+ def assert_js(js_code, wait_for: [], timeout: DEFAULT_ASSERTION_TIMEOUT)
149
+ id = start_assertion(js_code)
150
+
151
+ # this isn't a TestPromise, so it doesn't have the additional DSL entries
152
+ promise = wrangler.eval_js_async(js_code, wait_for: wait_for, timeout: timeout)
153
+ promise.on_rejected do
154
+ fail_assertion(id, "JS Eval failed: #{promise.reason.inspect}")
155
+ end
156
+ promise.on_fulfilled do
157
+ ret_val = promise.returned_value
158
+ if ret_val
159
+ pass_assertion(id)
160
+ else
161
+ fail_assertion(id, "Expected true JS value: #{ret_val.inspect}")
162
+ end
163
+ end
164
+
165
+ # So we wrap it in a no-op TestPromise, to get the DSL entries.
166
+ TestPromise.new(iface: self, wait_for: [promise]).to_execute {}
167
+ end
168
+
169
+ def assert(value, msg = nil)
170
+ id = start_assertion("#{caller[0]}: #{msg || "Value should be true!"}")
171
+
172
+ if value
173
+ pass_assertion(id)
174
+ else
175
+ fail_assertion(id, "Expected true Ruby value: #{value.inspect}")
176
+ end
177
+ end
178
+
179
+ def assert_equal(val1, val2, msg = nil)
180
+ assert val1 == val2, (msg || "Expected #{val2.inspect} to equal #{val1.inspect}!")
181
+ end
182
+
183
+ # How do we signal an error?
184
+ def with_js_value(js_code, wait_for: [], timeout: DEFAULT_ASSERTION_TIMEOUT, &block)
185
+ raise "Must give a block to with_js_value!" unless block
186
+
187
+ js_promise = wrangler.eval_js_async(js_code, wait_for: wait_for, timeout: timeout)
188
+ ruby_promise = TestPromise.new(iface: self, wait_for: [js_promise])
189
+ ruby_promise.to_execute(&block)
190
+ ruby_promise
191
+ end
192
+
193
+ def with_js_dom_html(wait_for: [], timeout: DEFAULT_ASSERTION_TIMEOUT, &block)
194
+ with_js_value("document.getElementById('wrapper-wvroot').innerHTML", wait_for: wait_for, timeout: timeout, &block)
195
+ end
196
+
197
+ def fully_updated(wait_for: [])
198
+ wrangler.promise_dom_fully_updated
199
+ end
200
+ end
201
+
202
+ # A Promise but with helper functions
203
+ class TestPromise < Promise
204
+ def initialize(iface:, state: nil, wait_for: [], &scheduler)
205
+ @iface = iface
206
+ super(state: state, parents: wait_for, &scheduler)
207
+ end
208
+
209
+ def inspect
210
+ "<#TestPromise::#{object_id} state=#{state.inspect} parents=#{parents.inspect} value=#{returned_value.inspect} reason=#{reason.inspect}>"
211
+ end
212
+
213
+ # This method expects to wait for the parent TestPromise and then run a block of Ruby that returns
214
+ # another promise. This is useful for wrapping Promises like those from replace() that don't have
215
+ # the test DSL built in. The block will execute when this outer promise is scheduled -- so we don't do
216
+ # a replace() too early, for instance. And then the outer promise will fulfill when the inner one does.
217
+ def then_ruby_promise(wait_for: [], &block)
218
+ ruby_wrapper_promise = TestPromise.new iface: @iface, wait_for: ([self] + wait_for)
219
+
220
+ ruby_wrapper_promise.on_scheduled do
221
+ inner_ruby_promise = block.call
222
+ inner_ruby_promise.on_fulfilled { ruby_wrapper_promise.fulfilled!(inner_ruby_promise.returned_value) }
223
+ end
224
+ end
225
+
226
+ def then_with_js_value(js_code, wait_for: [], timeout: DEFAULT_ASSERTION_TIMEOUT, &block)
227
+ @iface.with_js_value(js_code, wait_for: (wait_for + [self]), timeout:, &block)
228
+ end
229
+
230
+ def then_with_js_dom_html(wait_for: [], timeout: DEFAULT_ASSERTION_TIMEOUT, &block)
231
+ @iface.with_js_dom_html(wait_for: (wait_for + [self]), timeout:, &block)
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class Dimensions
5
+ class << self
6
+ def length(value)
7
+ case value
8
+ when Integer
9
+ if value < 0
10
+ "calc(100% - #{value.abs}px)"
11
+ else
12
+ "#{value}px"
13
+ end
14
+ when Float
15
+ "#{value * 100}%"
16
+ else
17
+ value
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ # A WebviewDocumentRoot is a WebviewFlow, with all the same properties
5
+ # and basic behavior.
6
+ class WebviewDocumentRoot < Scarpe::WebviewFlow
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewEditBox < Scarpe::WebviewWidget
5
+ attr_reader :text, :height, :width
6
+
7
+ def initialize(properties)
8
+ super
9
+
10
+ # The JS handler sends a "change" event, which we forward to the Shoes widget tree
11
+ bind("change") do |new_text|
12
+ send_self_event(new_text, event_name: "change")
13
+ end
14
+ end
15
+
16
+ def properties_changed(changes)
17
+ t = changes.delete("text")
18
+ if t
19
+ html_element.value = t
20
+ end
21
+
22
+ super
23
+ end
24
+
25
+ def element
26
+ oninput = handler_js_code("change", "this.value")
27
+
28
+ HTML.render do |h|
29
+ h.textarea(id: html_id, oninput: oninput, style: style) { text }
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def style
36
+ styles = {}
37
+
38
+ styles[:height] = Dimensions.length(height)
39
+ styles[:width] = Dimensions.length(width)
40
+
41
+ styles.compact
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewEditLine < WebviewWidget
5
+ attr_reader :text, :width
6
+
7
+ def initialize(properties)
8
+ super
9
+
10
+ # The JS handler sends a "change" event, which we forward to the Shoes widget tree
11
+ bind("change") do |new_text|
12
+ send_self_event(new_text, event_name: "change")
13
+ end
14
+ end
15
+
16
+ def properties_changed(changes)
17
+ t = changes.delete("text")
18
+ if t
19
+ html_element.value = t
20
+ end
21
+
22
+ super
23
+ end
24
+
25
+ def element
26
+ oninput = handler_js_code("change", "this.value")
27
+
28
+ HTML.render do |h|
29
+ h.input(id: html_id, oninput: oninput, value: @text, style: style)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def style
36
+ styles = {}
37
+
38
+ styles[:width] = Dimensions.length(@width) if @width
39
+
40
+ styles
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewFill < WebviewWidget
5
+ def initialize(properties)
6
+ super(properties)
7
+ end
8
+
9
+ def element
10
+ width = @parent.get_style[:width]
11
+ height = @parent.get_style[:height]
12
+
13
+ HTML.render do |h|
14
+ h.div(id: html_id, style: style(width, height)) do
15
+ @text
16
+ end
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def style(width, height)
23
+ styles = {}
24
+ styles[:width] = width
25
+ styles[:height] = height
26
+ styles[:background] = @color if @color
27
+ styles
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewFlow < Scarpe::WebviewSlot
5
+ def initialize(properties)
6
+ super
7
+ end
8
+
9
+ protected
10
+
11
+ def style
12
+ styles = super
13
+
14
+ styles[:display] = "flex"
15
+ styles["flex-direction"] = "row"
16
+ styles["flex-wrap"] = "wrap"
17
+ styles["align-content"] = "flex-start"
18
+ styles["justify-content"] = "flex-start"
19
+ styles["align-items"] = "flex-start"
20
+
21
+ styles
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "scarpe/base64"
4
+
5
+ class Scarpe
6
+ class WebviewFont < WebviewWidget
7
+ include Base64
8
+ attr_accessor :font
9
+
10
+ def initialize(properties)
11
+ @font = properties[:font]
12
+ super
13
+ end
14
+
15
+ def font_name
16
+ File.basename(@font, ".*")
17
+ end
18
+
19
+ def element
20
+ HTML.render do |h|
21
+ h.link(href: @font, rel: "stylesheet")
22
+ h.style do
23
+ <<~CSS
24
+ @font-face {
25
+ font-family: #{font_name};
26
+ src: url("data:font/truetype;base64,#{encode_file_to_base64(@font)}") format('truetype');
27
+ }
28
+ * {
29
+ font-family: #{font_name};
30
+ }
31
+ CSS
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end