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,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "logging"
4
+ require "json"
5
+
6
+ class Scarpe
7
+ LOG_LEVELS = [:debug, :info, :warning, :error, :fatal].freeze
8
+
9
+ # Include this module to get a @log instance variable to log as your
10
+ # configured component.
11
+ module Log
12
+ DEFAULT_LOG_CONFIG = {
13
+ "default" => "info",
14
+ }
15
+ DEFAULT_DEBUG_LOG_CONFIG = {
16
+ "default" => "debug",
17
+ }
18
+
19
+ def log_init(component = self)
20
+ @log = Logging.logger[component]
21
+ end
22
+ end
23
+
24
+ class Logger
25
+ DEFAULT_COMPONENT = "default"
26
+
27
+ class << self
28
+ attr_reader :current_log_config
29
+
30
+ def logger(component = self)
31
+ Logging.logger[component]
32
+ end
33
+
34
+ private
35
+
36
+ def name_to_severity(data)
37
+ case data
38
+ when "debug"
39
+ :debug
40
+ when "info"
41
+ :info
42
+ when "warn", "warning"
43
+ :warn
44
+ when "err", "error"
45
+ :error
46
+ when "fatal"
47
+ :fatal
48
+ else
49
+ raise "Don't know how to treat #{data.inspect} as a logger severity!"
50
+ end
51
+ end
52
+
53
+ def json_to_appender(data)
54
+ case data.downcase
55
+ when "stdout"
56
+ Logging.appenders.stdout layout: @custom_log_layout
57
+ when "stderr"
58
+ Logging.appenders.stderr layout: @custom_log_layout
59
+ when String
60
+ Logging.appenders.file data, layout: @custom_log_layout
61
+ else
62
+ raise "Don't know how to convert #{data.inspect} to an appender!"
63
+ end
64
+ end
65
+
66
+ def json_configure_logger(logger, data)
67
+ case data
68
+ in String
69
+ sev = name_to_severity(data)
70
+ logger.level = sev
71
+ in [level, *locations]
72
+ if logger.name != "root"
73
+ # The Logging gem doesn't have an additive property on the root logger
74
+ logger.additive = false # Don't also log to parent/root loggers
75
+ end
76
+
77
+ logger.appenders = locations.map { |where| json_to_appender(where) }
78
+
79
+ logger.level = name_to_severity(level)
80
+ else
81
+ raise "Don't know how to use #{data.inspect} to specify a logger!"
82
+ end
83
+ end
84
+
85
+ def freeze_log_config(log_config)
86
+ log_config.each do |k, v|
87
+ k.freeze
88
+ v.freeze
89
+ v.each(&:freeze) if v.is_a?(Array)
90
+ end
91
+ log_config.freeze
92
+ end
93
+
94
+ public
95
+
96
+ def configure_logger(log_config)
97
+ # TODO: custom coloring? https://github.com/TwP/logging/blob/master/examples/colorization.rb
98
+ @custom_log_layout = Logging.layouts.pattern pattern: '[%r] %-5l %c: %m\n'
99
+
100
+ if log_config.is_a?(String) && File.exist?(log_config)
101
+ log_config = JSON.load_file(log_config)
102
+ end
103
+
104
+ log_config = freeze_log_config(log_config) unless log_config.nil?
105
+ @current_log_config = log_config # Save a copy for later
106
+
107
+ Logging.reset # Reset all Logging settings to defaults
108
+ Logging.reopen # For log-reconfig (e.g. test failures), often important to *not* store an open handle to a moved file
109
+ return if log_config.nil?
110
+
111
+ Logging.logger.root.appenders = [Logging.appenders.stdout]
112
+
113
+ default_logger = log_config[DEFAULT_COMPONENT] || "info"
114
+ json_configure_logger(Logging.logger.root, default_logger)
115
+
116
+ log_config.each do |component, logger_data|
117
+ next if component == DEFAULT_COMPONENT
118
+
119
+ sublogger = Logging.logger[component]
120
+ json_configure_logger(sublogger, logger_data)
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ class LoggedWrapper
127
+ include ::Scarpe::Log
128
+ def initialize(instance, component = instance)
129
+ log_init(component)
130
+
131
+ @instance = instance
132
+ end
133
+
134
+ def method_missing(method, ...)
135
+ self.singleton_class.define_method(method) do |*args, **kwargs, &block|
136
+ ret = @instance.send(method, *args, **kwargs, &block)
137
+ @log.info("Method: #{method} Args: #{args.inspect} KWargs: #{kwargs.inspect} Block: #{block ? "y" : "n"} Return: #{ret.inspect}")
138
+ ret
139
+ end
140
+ send(method, ...)
141
+ end
142
+
143
+ def respond_to_missing?(method_name, include_private = false)
144
+ @instance.respond_to_missing?(method_name, include_private)
145
+ end
146
+ end
147
+ end
148
+
149
+ class Logging::Logger
150
+ alias_method :warning, :warn
151
+ end
152
+
153
+ log_config = if ENV["SCARPE_LOG_CONFIG"]
154
+ JSON.load_file(ENV["SCARPE_LOG_CONFIG"])
155
+ else
156
+ ENV["SCARPE_DEBUG"] ? Scarpe::Log::DEFAULT_DEBUG_LOG_CONFIG : Scarpe::Log::DEFAULT_LOG_CONFIG
157
+ end
158
+
159
+ Scarpe::Logger.configure_logger(log_config)
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class Para < Shoes::Widget
5
+ class << self
6
+ def inherited(subclass)
7
+ Scarpe::Widget.widget_classes ||= []
8
+ Scarpe::Widget.widget_classes << subclass
9
+ super
10
+ end
11
+ end
12
+
13
+ display_properties :text_items, :stroke, :size, :font, :html_attributes, :hidden
14
+
15
+ def initialize(*args, stroke: nil, size: :para, font: nil, hidden: false, **html_attributes)
16
+ @text_children = args || []
17
+ if hidden
18
+ @hidden_text_items = text_children_to_items(@text_children)
19
+ @text_items = []
20
+ else
21
+ # Text_children alternates strings and TextWidgets, so we can't just pass
22
+ # it as a display property. It won't serialize.
23
+ @text_items = text_children_to_items(@text_children)
24
+ @hidden_text_items = []
25
+ end
26
+ stroke = to_rgb(stroke)
27
+
28
+ @html_attributes = html_attributes || {}
29
+
30
+ super
31
+
32
+ create_display_widget
33
+ end
34
+
35
+ def text_children_to_items(text_children)
36
+ text_children.map { |arg| arg.is_a?(String) ? arg : arg.linkable_id }
37
+ end
38
+
39
+ def replace(*children)
40
+ @text_children = children
41
+
42
+ # This should signal the display widget to change
43
+ self.text_items = text_children_to_items(@text_children)
44
+ end
45
+
46
+ def hide
47
+ # idempotent
48
+ return unless @hidden_text_items.empty?
49
+
50
+ @hidden_text_items = self.text_items
51
+ self.text_items = []
52
+ end
53
+
54
+ def show
55
+ # idempotent
56
+ return unless self.text_items.empty?
57
+
58
+ self.text_items = @hidden_text_items
59
+ @hidden_text_items = []
60
+ end
61
+ end
62
+ end
63
+
64
+ module Shoes
65
+ class Widget
66
+ def banner(*args, **kwargs)
67
+ para(*args, **{ size: :banner }.merge(kwargs))
68
+ end
69
+
70
+ def title(*args, **kwargs)
71
+ para(*args, **{ size: :title }.merge(kwargs))
72
+ end
73
+
74
+ def subtitle(*args, **kwargs)
75
+ para(*args, **{ size: :subtitle }.merge(kwargs))
76
+ end
77
+
78
+ def tagline(*args, **kwargs)
79
+ para(*args, **{ size: :tagline }.merge(kwargs))
80
+ end
81
+
82
+ def caption(*args, **kwargs)
83
+ para(*args, **{ size: :caption }.merge(kwargs))
84
+ end
85
+
86
+ def inscription(*args, **kwargs)
87
+ para(*args, **{ size: :inscription }.merge(kwargs))
88
+ end
89
+
90
+ alias_method :ins, :inscription
91
+ end
92
+ end
@@ -0,0 +1,405 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Funny thing... We need promises as an API concept since we have a JS event
4
+ # loop doing its thing, and we need to respond to actions that it takes.
5
+ # But there's not really a Ruby implementation of Promises *without* an
6
+ # attached form of concurrency. So here we are, writing our own :-/
7
+ #
8
+ # In theory you could probably write some kind of "no-op thread pool"
9
+ # for the ruby-concurrency gem, pass it manually to every promise we
10
+ # created and then raise an exception any time we tried to do something
11
+ # in the background. That's probably more code than writing our own, though,
12
+ # and we'd be fighting it constantly.
13
+ #
14
+ # This class is inspired by concurrent-ruby [Promise](https://ruby-concurrency.github.io/concurrent-ruby/1.1.5/Concurrent/Promise.html)
15
+ # which is inspired by Javascript Promises, which is what we actually need
16
+ # for our use case. We can't easily tell when our WebView begins processing
17
+ # our request, which removes the :processing state. This can be used for
18
+ # executing JS, but also generally waiting on events.
19
+ #
20
+ # We don't fully control ordering here, so it *is* conceivable that a
21
+ # child waiting on a parent can be randomly fulfilled, even if we didn't
22
+ # expect it. We don't consider that an error. Similarly, we'll call
23
+ # on_scheduled callbacks if a promise is fulfilled, even though we
24
+ # never explicitly scheduled it. If a promise is *rejected* without
25
+ # ever being scheduled, we won't call those callbacks.
26
+
27
+ class Scarpe
28
+ class Promise
29
+ include Scarpe::Log
30
+
31
+ PROMISE_STATES = [:unscheduled, :pending, :fulfilled, :rejected]
32
+
33
+ attr_reader :state
34
+ attr_reader :parents
35
+ attr_reader :returned_value
36
+ attr_reader :reason
37
+
38
+ # These methods are meant to be a prettier interface to promises,
39
+ # suitable for day-to-day usage.
40
+
41
+ # Create a promise and then instantly fulfill it.
42
+ def self.fulfilled(return_val = nil, parents: [], &block)
43
+ p = Promise.new(parents: parents, &block)
44
+ p.fulfilled!(return_val)
45
+ p
46
+ end
47
+
48
+ # Create a promise and then instantly reject it.
49
+ def self.rejected(reason = nil, parents: [])
50
+ p = Promise.new(parents: parents)
51
+ p.rejected!(reason)
52
+ p
53
+ end
54
+
55
+ # Instance methods
56
+
57
+ def fulfilled!(value = nil)
58
+ set_state(:fulfilled, value)
59
+ end
60
+
61
+ def rejected!(reason = nil)
62
+ set_state(:rejected, reason)
63
+ end
64
+
65
+ def then(&block)
66
+ # Create a new promise. It's waiting on us. It runs the
67
+ # specified code when scheduled.
68
+ Promise.new(parents: [self], &block)
69
+ end
70
+
71
+ # The Promise.new method, along with all the various handlers,
72
+ # are pretty raw. They'll do what promises do, but they're not
73
+ # the prettiest. However, they ensure that guarantees are made
74
+ # and so on, so they're great as plumbing under the syntactic
75
+ # sugar above.
76
+
77
+ def initialize(state: nil, parents: [], &scheduler)
78
+ log_init("Promise")
79
+
80
+ # These are as initially specified, and effectively immutable
81
+ @state = state
82
+ @parents = parents
83
+
84
+ # These are what we're waiting on, and will be
85
+ # removed as time goes forward.
86
+ @waiting_on = parents.select { |p| !p.complete? }
87
+ @on_fulfilled = []
88
+ @on_rejected = []
89
+ @on_scheduled = []
90
+ @scheduler = scheduler
91
+ @executor = nil
92
+ @returned_value = nil
93
+ @reason = nil
94
+
95
+ if complete?
96
+ # Did we start out already fulfilled or rejected?
97
+ # If so, we can skip a lot of fiddly checking.
98
+ # Don't need a scheduler or to care about parents
99
+ # or anything.
100
+ @waiting_on = []
101
+ @scheduler = nil
102
+ elsif @parents.any? { |p| p.state == :rejected }
103
+ @state = :rejected
104
+ @waiting_on = []
105
+ @scheduler = nil
106
+ elsif @state == :pending
107
+ # Did we get an explicit :pending? Then we don't need
108
+ # to schedule ourselves, or care about the scheduler
109
+ # in general.
110
+ @scheduler = nil
111
+ elsif @state.nil? || @state == :unscheduled
112
+ # If no state was given or we're unscheduled, we'll
113
+ # wait until our parents have all completed to
114
+ # schedule ourselves.
115
+
116
+ if @waiting_on.empty?
117
+ # No further dependencies, we can schedule ourselves
118
+ @state = :pending
119
+
120
+ # We have no on_scheduled handlers yet, but this will
121
+ # call and clear the scheduler.
122
+ call_handlers_for(:pending)
123
+ else
124
+ # We're still waiting on somebody, no scheduling yet
125
+ @state = :unscheduled
126
+ @waiting_on.each do |dep|
127
+ dep.on_fulfilled { parent_fulfilled!(dep) }
128
+ dep.on_rejected { parent_rejected!(dep) }
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ def complete?
135
+ @state == :fulfilled || @state == :rejected
136
+ end
137
+
138
+ def fulfilled?
139
+ @state == :fulfilled
140
+ end
141
+
142
+ def rejected?
143
+ @state == :rejected
144
+ end
145
+
146
+ def inspect
147
+ "#<Scarpe::Promise:#{object_id} " +
148
+ "@state=#{@state.inspect} @parents=#{@parents.inspect} " +
149
+ "@waiting_on=#{@waiting_on.inspect} @on_fulfilled=#{@on_fulfilled.size} " +
150
+ "@on_rejected=#{@on_rejected.size} @on_scheduled=#{@on_scheduled.size} " +
151
+ "@scheduler=#{@scheduler ? "Y" : "N"} @executor=#{@executor ? "Y" : "N"} " +
152
+ "@returned_value=#{@returned_value.inspect} @reason=#{@reason.inspect}" +
153
+ ">"
154
+ end
155
+
156
+ # These promises are mostly designed for external execution.
157
+ # You could put together your own thread-pool, or use RPC,
158
+ # a WebView, a database or similar source of external calculation.
159
+ # But in some cases, sure, it's reasonable to execute locally.
160
+ # In those cases, you can register an executor, which will be
161
+ # called when the promise is ready to execute but has not yet
162
+ # done so. Registering an executor on a promise that is
163
+ # already fulfilled is an error. Registering an executor on
164
+ # a promise that has already rejected is a no-op.
165
+ def to_execute(&block)
166
+ case @state
167
+ when :fulfilled
168
+ # Should this be a no-op instead?
169
+ raise "Registering an executor on an already fulfilled promise means it will never run!"
170
+ when :rejected
171
+ return
172
+ when :unscheduled
173
+ @executor = block # save for later
174
+ when :pending
175
+ @executor = block
176
+ call_executor
177
+ else
178
+ raise "Internal error, illegal state!"
179
+ end
180
+
181
+ self
182
+ end
183
+
184
+ private
185
+
186
+ # set_state looks at the old and new states of the promise. It calls handlers and updates tracking
187
+ # data accordingly.
188
+ def set_state(new_state, value_or_reason = nil)
189
+ old_state = @state
190
+
191
+ # First, filter out illegal input
192
+ unless PROMISE_STATES.include?(old_state)
193
+ raise "Internal Promise error! Internal state was #{old_state.inspect}! Legal states: #{PROMISE_STATES.inspect}"
194
+ end
195
+
196
+ unless PROMISE_STATES.include?(new_state)
197
+ raise "Internal Promise error! Internal state was set to #{new_state.inspect}! " +
198
+ "Legal states: #{PROMISE_STATES.inspect}"
199
+ end
200
+
201
+ if new_state != :fulfilled && new_state != :rejected && !value_or_reason.nil?
202
+ raise "Internal promise error! Non-completed state transitions should not specify a value or reason!"
203
+ end
204
+
205
+ # Here's our state-transition grid for what we're doing here.
206
+ # "From" state is on the left, "to" state is on top.
207
+ #
208
+ # U P F R
209
+ #
210
+ # U - 1 . .
211
+ # P X - . .
212
+ # F X X - X
213
+ # R X X X -
214
+ #
215
+ # - Change from same to same, no effect
216
+ # X Illegal for one reason or another, raise error
217
+ # . Great, no problem, run handlers but not @scheduler or @executor
218
+ # 1 Interesting case - if we have an executor, actually change to a *different* state instead
219
+
220
+ # Transitioning from our state to our same state? No-op.
221
+ return if new_state == old_state
222
+
223
+ # Transitioning to any *different* state after being fulfilled or rejected? Nope. Those states are final.
224
+ if complete?
225
+ raise "Internal Promise error! Trying to change state from #{old_state.inspect} to #{new_state.inspect}!"
226
+ end
227
+
228
+ if old_state == :pending && new_state == :unscheduled
229
+ raise "Can't change state from :pending to :unscheduled! Scheduling is not reversible!"
230
+ end
231
+
232
+ # The next three checks should all be followed by calling handlers for the newly-changed state.
233
+ # See call_handlers_for below.
234
+
235
+ # Okay, we're getting scheduled.
236
+ if old_state == :unscheduled && new_state == :pending
237
+ @state = new_state
238
+ call_handlers_for(new_state)
239
+
240
+ # It's not impossible for the scheduler to do something that fulfills or rejects the promise.
241
+ # In that case it *also* called the appropriate handlers. Let's get out of here.
242
+ return if @state == :fulfilled || @state == :rejected
243
+
244
+ if @executor
245
+ # In this case we're still pending, but we have a synchronous executor. Let's do it.
246
+ call_executor
247
+ end
248
+
249
+ return
250
+ end
251
+
252
+ # Setting to rejected calls the rejected handlers. But no scheduling ever occurs, so on_scheduled handlers
253
+ # will never be called.
254
+ if new_state == :rejected
255
+ @state = :rejected
256
+ @reason = value_or_reason
257
+ call_handlers_for(new_state)
258
+ end
259
+
260
+ # If we go straight from :unscheduled to :fulfilled we *will* run the on_scheduled callbacks,
261
+ # because we pretend the scheduling *did* occur at some point. Normally that'll be no callbacks,
262
+ # of course.
263
+ #
264
+ # Fun-but-unfortunate trivia: you *can* fulfill a promise before all its parents are fulfilled.
265
+ # If you do, the unfinished parents will result in nil arguments to the on_fulfilled handler,
266
+ # because we have no other value to provide. The scheduler callback will never be called, but
267
+ # the on_scheduled callbacks, if any, will be.
268
+ if new_state == :fulfilled
269
+ @state = :fulfilled
270
+ @returned_value = value_or_reason
271
+ call_handlers_for(new_state)
272
+ end
273
+ end
274
+
275
+ # This private method calls handlers for a new state, removing those handlers
276
+ # since they have now been called. This interacts subtly with set_state()
277
+ # above, particularly in the case of fulfilling a promise without it ever being
278
+ # properly scheduled.
279
+ #
280
+ # The rejected handlers will be cleared if the promise is fulfilled and vice-versa.
281
+ # After rejection, no on_fulfilled handler should ever be called and vice-versa.
282
+ #
283
+ # When we go from :unscheduled to :pending, the scheduler, if any, should be
284
+ # called and cleared. That should *not* happen when going from :unscheduled to
285
+ # :fulfilled.
286
+ def call_handlers_for(state)
287
+ case state
288
+ when :fulfilled
289
+ @on_scheduled.each { |h| h.call(*@parents.map(&:returned_value)) }
290
+ @on_fulfilled.each { |h| h.call(*@parents.map(&:returned_value)) }
291
+ @on_scheduled = @on_rejected = @on_fulfilled = []
292
+ @scheduler = @executor = nil
293
+ when :rejected
294
+ @on_rejected.each { |h| h.call(*@parents.map(&:returned_value)) }
295
+ @on_fulfilled = @on_scheduled = @on_rejected = []
296
+ @scheduler = @executor = nil
297
+ when :pending
298
+ # A scheduler can get an exception. If so, treat it as rejection
299
+ # and the exception as the provided reason.
300
+ if @scheduler
301
+ begin
302
+ @scheduler.call(*@parents.map(&:returned_value))
303
+ rescue => e
304
+ @log.error("Error while running scheduler! #{e.full_message}")
305
+ rejected!(e)
306
+ end
307
+ @scheduler = nil
308
+ end
309
+ @on_scheduled.each { |h| h.call(*@parents.map(&:returned_value)) }
310
+ @on_scheduled = []
311
+ else
312
+ raise "Internal error! Trying to call handlers for #{state.inspect}!"
313
+ end
314
+ end
315
+
316
+ def parent_fulfilled!(parent)
317
+ @waiting_on.delete(parent)
318
+
319
+ # Last parent? If so, schedule ourselves.
320
+ if @waiting_on.empty? && !self.complete?
321
+ # This will result in :pending if there's no executor,
322
+ # or fulfilled/rejected if there is an executor.
323
+ set_state(:pending)
324
+ end
325
+ end
326
+
327
+ def parent_rejected!(parent)
328
+ @waiting_on = []
329
+
330
+ unless self.complete?
331
+ # If our parent was rejected and we were waiting on them,
332
+ # now we're rejected too.
333
+ set_state(:rejected)
334
+ end
335
+ end
336
+
337
+ def call_executor
338
+ raise("Internal error! Should not call_executor with no executor!") unless @executor
339
+
340
+ begin
341
+ result = @executor.call(*@parents.map(&:returned_value))
342
+ fulfilled!(result)
343
+ rescue => e
344
+ @log.error("Error running executor! #{e.full_message}")
345
+ rejected!(e)
346
+ end
347
+ ensure
348
+ @executor = nil
349
+ end
350
+
351
+ public
352
+
353
+ def on_fulfilled(&handler)
354
+ unless handler
355
+ raise "You must pass a block to on_fulfilled!"
356
+ end
357
+
358
+ case @state
359
+ when :fulfilled
360
+ handler.call(*@parents.map(&:returned_value))
361
+ when :pending, :unscheduled
362
+ @on_fulfilled << handler
363
+ when :rejected
364
+ # Do nothing
365
+ end
366
+
367
+ self
368
+ end
369
+
370
+ def on_rejected(&handler)
371
+ unless handler
372
+ raise "You must pass a block to on_rejected!"
373
+ end
374
+
375
+ case @state
376
+ when :rejected
377
+ handler.call(*@parents.map(&:returned_value))
378
+ when :pending, :unscheduled
379
+ @on_rejected << handler
380
+ when :fulfilled
381
+ # Do nothing
382
+ end
383
+
384
+ self
385
+ end
386
+
387
+ def on_scheduled(&handler)
388
+ unless handler
389
+ raise "You must pass a block to on_scheduled!"
390
+ end
391
+
392
+ # Add a pending handler or call it now
393
+ case @state
394
+ when :fulfilled, :pending
395
+ handler.call(*@parents.map(&:returned_value))
396
+ when :unscheduled
397
+ @on_scheduled << handler
398
+ when :rejected
399
+ # Do nothing
400
+ end
401
+
402
+ self
403
+ end
404
+ end
405
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv/shape_helper"
4
+
5
+ class Scarpe
6
+ class Shape < Shoes::Widget
7
+ include ShapeHelper
8
+ display_properties :left, :top
9
+
10
+ def initialize(left: nil, top: nil, path_commands: nil, &block)
11
+ @left = left
12
+ @top = top
13
+
14
+ super()
15
+ create_display_widget
16
+
17
+ instance_eval(&block) if block_given?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes::Slot < Shoes::Widget
4
+ include Scarpe::Background
5
+ include Scarpe::Border
6
+ include Scarpe::Spacing
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ module Spacing
5
+ def self.included(includer)
6
+ includer.display_properties :margin, :padding, :margin_top, :margin_left, :margin_right, :margin_bottom, :options
7
+ end
8
+ end
9
+ end