scarpe 0.1.0 → 0.2.0

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 (530) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +80 -9
  3. data/.ruby-version +1 -0
  4. data/.vscode/extensions.json +5 -0
  5. data/.yardopts +3 -0
  6. data/CHANGELOG.md +14 -0
  7. data/CONTRIBUTING.md +20 -0
  8. data/Gemfile +14 -2
  9. data/README.md +138 -18
  10. data/Rakefile +2 -3
  11. data/dev.yml +7 -0
  12. data/docs/static/PKGBUILD +47 -0
  13. data/docs/static/Shoes.icns +0 -0
  14. data/docs/static/avatar.png +0 -0
  15. data/docs/static/code_highlighter.js +188 -0
  16. data/docs/static/code_highlighter_ruby.js +26 -0
  17. data/docs/static/icon-debug.png +0 -0
  18. data/docs/static/icon-error.png +0 -0
  19. data/docs/static/icon-info.png +0 -0
  20. data/docs/static/icon-warn.png +0 -0
  21. data/docs/static/listbox_button1.png +0 -0
  22. data/docs/static/listbox_button2.png +0 -0
  23. data/docs/static/man-app.png +0 -0
  24. data/docs/static/man-builds.png +0 -0
  25. data/docs/static/man-builds1.png +0 -0
  26. data/docs/static/man-editor-notepad.png +0 -0
  27. data/docs/static/man-editor-osx.png +0 -0
  28. data/docs/static/man-ele-background.png +0 -0
  29. data/docs/static/man-ele-border.png +0 -0
  30. data/docs/static/man-ele-button.png +0 -0
  31. data/docs/static/man-ele-check.png +0 -0
  32. data/docs/static/man-ele-editbox.png +0 -0
  33. data/docs/static/man-ele-editline.png +0 -0
  34. data/docs/static/man-ele-image.png +0 -0
  35. data/docs/static/man-ele-listbox.png +0 -0
  36. data/docs/static/man-ele-progress.png +0 -0
  37. data/docs/static/man-ele-radio.png +0 -0
  38. data/docs/static/man-ele-shape.png +0 -0
  39. data/docs/static/man-ele-textblock.png +0 -0
  40. data/docs/static/man-ele-video.png +0 -0
  41. data/docs/static/man-intro-dmg.png +0 -0
  42. data/docs/static/man-intro-exe.png +0 -0
  43. data/docs/static/man-look-tiger.png +0 -0
  44. data/docs/static/man-look-ubuntu.png +0 -0
  45. data/docs/static/man-look-vista.png +0 -0
  46. data/docs/static/man-run-osx.png +0 -0
  47. data/docs/static/man-run-vista.png +0 -0
  48. data/docs/static/man-run-xp.png +0 -0
  49. data/docs/static/man-shot1.png +0 -0
  50. data/docs/static/manual-en.txt +3529 -0
  51. data/docs/static/manual-ja.txt +2829 -0
  52. data/docs/static/manual.css +171 -0
  53. data/docs/static/manual.md +3528 -0
  54. data/docs/static/menu-corner1.png +0 -0
  55. data/docs/static/menu-corner2.png +0 -0
  56. data/docs/static/menu-gray.png +0 -0
  57. data/docs/static/menu-left.png +0 -0
  58. data/docs/static/menu-right.png +0 -0
  59. data/docs/static/menu-top.png +0 -0
  60. data/docs/static/shoes-dmg.jpg +0 -0
  61. data/docs/static/shoes-icon-blue.png +0 -0
  62. data/docs/static/shoes-icon.png +0 -0
  63. data/docs/static/shoes-manual-apps.gif +0 -0
  64. data/docs/static/shoes_main_window.png +0 -0
  65. data/docs/static/stripe.png +0 -0
  66. data/docs/static/stubs/blank.exe +0 -0
  67. data/docs/static/stubs/blank.hfz +0 -0
  68. data/docs/static/stubs/blank.run +375 -0
  69. data/docs/static/stubs/cocoa-install +0 -0
  70. data/docs/static/stubs/sh-install +49 -0
  71. data/docs/static/stubs/shoes-stub-inject.exe +0 -0
  72. data/docs/static/stubs/shoes-stub.exe +0 -0
  73. data/docs/static/tutor-back.png +0 -0
  74. data/examples/bloopsaphone/working/1901_by_Aanand_Prasad.rb +478 -0
  75. data/examples/bloopsaphone/working/b1.rb +64 -0
  76. data/examples/bloopsaphone/working/b2.rb +36 -0
  77. data/examples/bloopsaphone/working/bloops_test.rb +41 -0
  78. data/examples/bloopsaphone/working/bloopsaphone_theme_song_by_why.rb +31 -0
  79. data/examples/bloopsaphone/working/feepogram.rb +67 -0
  80. data/examples/bloopsaphone/working/simpsons_theme_song_by_why.rb +14 -0
  81. data/examples/bloopsaphone/working/tune_cheeky_drat.rb +210 -0
  82. data/examples/button.rb +6 -5
  83. data/examples/button_alert.rb +6 -0
  84. data/examples/button_go_away.rb +6 -0
  85. data/examples/button_with_position_and_size.rb +7 -0
  86. data/examples/coffee.rb +14 -0
  87. data/examples/download.rb +5 -0
  88. data/examples/edit_box.rb +10 -0
  89. data/examples/edit_line.rb +8 -0
  90. data/examples/fill.rb +25 -0
  91. data/examples/flow.rb +11 -0
  92. data/examples/fonts.rb +6 -0
  93. data/examples/gen.rb +140 -0
  94. data/examples/hello_world.rb +2 -4
  95. data/examples/highlander.rb +87 -0
  96. data/examples/image/clickable_image.rb +5 -0
  97. data/examples/{image.rb → image/image.rb} +2 -4
  98. data/examples/image/image_size.rb +7 -0
  99. data/examples/image/image_with_position_and_size.rb +3 -0
  100. data/examples/info.rb +9 -0
  101. data/examples/legacy/not_checked/expert/colours.rb +105 -0
  102. data/examples/legacy/not_checked/expert/curve-animation.rb +31 -0
  103. data/examples/legacy/not_checked/expert/curve-control-point.rb +51 -0
  104. data/examples/legacy/not_checked/expert/custom-list-box.rb +53 -0
  105. data/examples/legacy/not_checked/expert/definr.rb +23 -0
  106. data/examples/legacy/not_checked/expert/funnies.rb +56 -0
  107. data/examples/legacy/not_checked/expert/minesweeper.rb +267 -0
  108. data/examples/legacy/not_checked/expert/othello.rb +318 -0
  109. data/examples/legacy/not_checked/expert/pong.rb +62 -0
  110. data/examples/legacy/not_checked/expert/tankspank.rb +385 -0
  111. data/examples/legacy/not_checked/expert/tooltips.rb +45 -0
  112. data/examples/legacy/not_checked/expert/url.rb +37 -0
  113. data/examples/legacy/not_checked/expert/video-player.rb +256 -0
  114. data/examples/legacy/not_checked/good/_why-stories.rb +44 -0
  115. data/examples/legacy/not_checked/good/_why-stories.yaml +387 -0
  116. data/examples/legacy/not_checked/good/arc.rb +37 -0
  117. data/examples/legacy/not_checked/good/cardflip.rb +141 -0
  118. data/examples/legacy/not_checked/good/clock.rb +51 -0
  119. data/examples/legacy/not_checked/good/console.rb +21 -0
  120. data/examples/legacy/not_checked/good/follow.rb +26 -0
  121. data/examples/legacy/not_checked/good/image-rotate.rb +14 -0
  122. data/examples/legacy/not_checked/good/paris.svg +7236 -0
  123. data/examples/legacy/not_checked/good/path-animation.rb +46 -0
  124. data/examples/legacy/not_checked/good/plots.rb +100 -0
  125. data/examples/legacy/not_checked/good/reminder.rb +174 -0
  126. data/examples/legacy/not_checked/good/svgview.rb +113 -0
  127. data/examples/legacy/not_checked/good/vjot.rb +56 -0
  128. data/examples/legacy/not_checked/shoes-contrib/.gitignore +2 -0
  129. data/examples/legacy/not_checked/shoes-contrib/README.md +34 -0
  130. data/examples/legacy/not_checked/shoes-contrib/animation/animate-ovals.rb +21 -0
  131. data/examples/legacy/not_checked/shoes-contrib/animation/flowers.rb +59 -0
  132. data/examples/legacy/not_checked/shoes-contrib/animation/happy-trails.rb +31 -0
  133. data/examples/legacy/not_checked/shoes-contrib/animation/mice-satellites.rb +27 -0
  134. data/examples/legacy/not_checked/shoes-contrib/animation/oval-motion.rb +12 -0
  135. data/examples/legacy/not_checked/shoes-contrib/animation/pink-bubbles.rb +34 -0
  136. data/examples/legacy/not_checked/shoes-contrib/animation/pulsate.rb +18 -0
  137. data/examples/legacy/not_checked/shoes-contrib/animation/rotating-star.rb +18 -0
  138. data/examples/legacy/not_checked/shoes-contrib/app/download-and-save.rb +11 -0
  139. data/examples/legacy/not_checked/shoes-contrib/app/download.rb +10 -0
  140. data/examples/legacy/not_checked/shoes-contrib/app/get-google.rb +11 -0
  141. data/examples/legacy/not_checked/shoes-contrib/app/mouse-detection.rb +7 -0
  142. data/examples/legacy/not_checked/shoes-contrib/app/resizeable-false.rb +6 -0
  143. data/examples/legacy/not_checked/shoes-contrib/art/bubble-bullseye.rb +23 -0
  144. data/examples/legacy/not_checked/shoes-contrib/art/faded.rb +17 -0
  145. data/examples/legacy/not_checked/shoes-contrib/art/fill-oval.rb +5 -0
  146. data/examples/legacy/not_checked/shoes-contrib/art/mask.rb +15 -0
  147. data/examples/legacy/not_checked/shoes-contrib/art/oval-gradient.rb +6 -0
  148. data/examples/legacy/not_checked/shoes-contrib/art/star-gradient.rb +4 -0
  149. data/examples/legacy/not_checked/shoes-contrib/basic/basic-edit-box.rb +8 -0
  150. data/examples/legacy/not_checked/shoes-contrib/basic/basic-new-window.rb +8 -0
  151. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval-image.rb +8 -0
  152. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval-shape.rb +8 -0
  153. data/examples/legacy/not_checked/shoes-contrib/basic/basic-oval.rb +6 -0
  154. data/examples/legacy/not_checked/shoes-contrib/basic/class-book.rb +43 -0
  155. data/examples/legacy/not_checked/shoes-contrib/basic/class-book.yaml +387 -0
  156. data/examples/legacy/not_checked/shoes-contrib/basic/clock.rb +6 -0
  157. data/examples/legacy/not_checked/shoes-contrib/basic/edit-stack +14 -0
  158. data/examples/legacy/not_checked/shoes-contrib/basic/gradient-shoes.rb +7 -0
  159. data/examples/legacy/not_checked/shoes-contrib/basic/list_box-shape-report.rb +19 -0
  160. data/examples/legacy/not_checked/shoes-contrib/basic/rect-arrow.rb +7 -0
  161. data/examples/legacy/not_checked/shoes-contrib/basic/scribble.rb +8 -0
  162. data/examples/legacy/not_checked/shoes-contrib/basic/search.rb +32 -0
  163. data/examples/legacy/not_checked/shoes-contrib/basic/shoes-notes.rb +16 -0
  164. data/examples/legacy/not_checked/shoes-contrib/basic/url-shoes-subclassing.rb +24 -0
  165. data/examples/legacy/not_checked/shoes-contrib/browser.rb +21 -0
  166. data/examples/legacy/not_checked/shoes-contrib/elements/background-column.rb +3 -0
  167. data/examples/legacy/not_checked/shoes-contrib/elements/background.rb +4 -0
  168. data/examples/legacy/not_checked/shoes-contrib/elements/basic-fps.rb +6 -0
  169. data/examples/legacy/not_checked/shoes-contrib/elements/border-cat.rb +6 -0
  170. data/examples/legacy/not_checked/shoes-contrib/elements/button-block.rb +8 -0
  171. data/examples/legacy/not_checked/shoes-contrib/elements/check-mate.rb +15 -0
  172. data/examples/legacy/not_checked/shoes-contrib/elements/common-styles.rb +13 -0
  173. data/examples/legacy/not_checked/shoes-contrib/elements/displace-animation.rb +13 -0
  174. data/examples/legacy/not_checked/shoes-contrib/elements/edit_box-character-count.rb +7 -0
  175. data/examples/legacy/not_checked/shoes-contrib/elements/edit_line-character-count.rb +7 -0
  176. data/examples/legacy/not_checked/shoes-contrib/elements/image-icon.rb +3 -0
  177. data/examples/legacy/not_checked/shoes-contrib/elements/list_box-select-class.rb +13 -0
  178. data/examples/legacy/not_checked/shoes-contrib/elements/list_box.rb +6 -0
  179. data/examples/legacy/not_checked/shoes-contrib/elements/move-flow-animate.rb +13 -0
  180. data/examples/legacy/not_checked/shoes-contrib/elements/phat-button.rb +7 -0
  181. data/examples/legacy/not_checked/shoes-contrib/elements/popup.rb +7 -0
  182. data/examples/legacy/not_checked/shoes-contrib/elements/progress-bar.rb +10 -0
  183. data/examples/legacy/not_checked/shoes-contrib/elements/radio-dreamcast-favs.rb +17 -0
  184. data/examples/legacy/not_checked/shoes-contrib/elements/timer.rb +6 -0
  185. data/examples/legacy/not_checked/shoes-contrib/elements/width-introspec.rb +8 -0
  186. data/examples/legacy/not_checked/shoes-contrib/events/background-hover.rb +11 -0
  187. data/examples/legacy/not_checked/shoes-contrib/events/motion-detect.rb +9 -0
  188. data/examples/legacy/not_checked/shoes-contrib/events/pressed-key.rb +6 -0
  189. data/examples/legacy/not_checked/shoes-contrib/expert/expert-funnies.rb +51 -0
  190. data/examples/legacy/not_checked/shoes-contrib/expert/expert-irb.rb +112 -0
  191. data/examples/legacy/not_checked/shoes-contrib/expert/expert-othello.rb +319 -0
  192. data/examples/legacy/not_checked/shoes-contrib/good/good-arc.rb +37 -0
  193. data/examples/legacy/not_checked/shoes-contrib/good/good-clock.rb +51 -0
  194. data/examples/legacy/not_checked/shoes-contrib/good/good-follow.rb +26 -0
  195. data/examples/legacy/not_checked/shoes-contrib/good/good-reminder.rb +174 -0
  196. data/examples/legacy/not_checked/shoes-contrib/good/good-vjot.rb +56 -0
  197. data/examples/legacy/not_checked/shoes-contrib/kernel/ask.rb +4 -0
  198. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_color.rb +4 -0
  199. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_open_file.rb +4 -0
  200. data/examples/legacy/not_checked/shoes-contrib/kernel/ask_save_file.rb +7 -0
  201. data/examples/legacy/not_checked/shoes-contrib/kernel/confirm.rb +3 -0
  202. data/examples/legacy/not_checked/shoes-contrib/kernel/debug.rb +4 -0
  203. data/examples/legacy/not_checked/shoes-contrib/kernel/exit.rb +5 -0
  204. data/examples/legacy/not_checked/shoes-contrib/kernel/font.rb +5 -0
  205. data/examples/legacy/not_checked/shoes-contrib/kernel/fonts.rb +3 -0
  206. data/examples/legacy/not_checked/shoes-contrib/manipulation/append-slot.rb +9 -0
  207. data/examples/legacy/not_checked/shoes-contrib/manipulation/clear-slot.rb +6 -0
  208. data/examples/legacy/not_checked/shoes-contrib/manipulation/prepend-slot.rb +6 -0
  209. data/examples/legacy/not_checked/shoes-contrib/manipulation/roll.rb +17 -0
  210. data/examples/legacy/not_checked/shoes-contrib/position/gutter-margin.rb +5 -0
  211. data/examples/legacy/not_checked/shoes-contrib/position/stack-width.rb +3 -0
  212. data/examples/legacy/not_checked/shoes-contrib/simple/simple-accordion.rb +75 -0
  213. data/examples/legacy/not_checked/shoes-contrib/simple/simple-anim-shapes.rb +17 -0
  214. data/examples/legacy/not_checked/shoes-contrib/simple/simple-anim-text.rb +13 -0
  215. data/examples/legacy/not_checked/shoes-contrib/simple/simple-arc.rb +23 -0
  216. data/examples/legacy/not_checked/shoes-contrib/simple/simple-bounce.rb +24 -0
  217. data/examples/legacy/not_checked/shoes-contrib/simple/simple-calc.rb +70 -0
  218. data/examples/legacy/not_checked/shoes-contrib/simple/simple-chipmunk.rb +26 -0
  219. data/examples/legacy/not_checked/shoes-contrib/simple/simple-control-sizes.rb +24 -0
  220. data/examples/legacy/not_checked/shoes-contrib/simple/simple-curve.rb +26 -0
  221. data/examples/legacy/not_checked/shoes-contrib/simple/simple-dialogs.rb +29 -0
  222. data/examples/legacy/not_checked/shoes-contrib/simple/simple-downloader.rb +27 -0
  223. data/examples/legacy/not_checked/shoes-contrib/simple/simple-draw.rb +13 -0
  224. data/examples/legacy/not_checked/shoes-contrib/simple/simple-editor.rb +28 -0
  225. data/examples/legacy/not_checked/shoes-contrib/simple/simple-form.rb +28 -0
  226. data/examples/legacy/not_checked/shoes-contrib/simple/simple-form.shy +0 -0
  227. data/examples/legacy/not_checked/shoes-contrib/simple/simple-mask.rb +21 -0
  228. data/examples/legacy/not_checked/shoes-contrib/simple/simple-menu.rb +31 -0
  229. data/examples/legacy/not_checked/shoes-contrib/simple/simple-menu1.rb +35 -0
  230. data/examples/legacy/not_checked/shoes-contrib/simple/simple-rubygems.rb +29 -0
  231. data/examples/legacy/not_checked/shoes-contrib/simple/simple-slide.rb +45 -0
  232. data/examples/legacy/not_checked/shoes-contrib/simple/simple-sphere.rb +28 -0
  233. data/examples/legacy/not_checked/shoes-contrib/simple/simple-sqlite3.rb +13 -0
  234. data/examples/legacy/not_checked/shoes-contrib/simple/simple-timer.rb +13 -0
  235. data/examples/legacy/not_checked/shoes-contrib/simple/simple-video.rb +13 -0
  236. data/examples/legacy/not_checked/shoes-contrib/styles/alignment.rb +4 -0
  237. data/examples/legacy/not_checked/shoes-contrib/styles/attachment.rb +5 -0
  238. data/examples/legacy/not_checked/shoes-contrib/styles/emphasis.rb +3 -0
  239. data/examples/legacy/not_checked/shoes-contrib/styles/gradient-angle.rb +3 -0
  240. data/examples/legacy/not_checked/shoes-contrib/styles/para-methods.rb +5 -0
  241. data/examples/legacy/not_checked/shoes-contrib/styles/para-red-underlined.rb +3 -0
  242. data/examples/legacy/not_checked/shoes-contrib/styles/para-style-method.rb +4 -0
  243. data/examples/legacy/not_checked/shoes-dep-samples/expert-game-of-life.rb +243 -0
  244. data/examples/legacy/not_checked/shoes-dep-samples/expert-othello.rb +319 -0
  245. data/examples/legacy/not_checked/shoes-dep-samples/good-clock.rb +51 -0
  246. data/examples/legacy/not_checked/shoes-dep-samples/good-follow.rb +26 -0
  247. data/examples/legacy/not_checked/shoes-dep-samples/good-reminder.rb +174 -0
  248. data/examples/legacy/not_checked/shoes-dep-samples/good-vjot.rb +56 -0
  249. data/examples/legacy/not_checked/shoes-dep-samples/simple-accordion.rb +75 -0
  250. data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-shapes.rb +17 -0
  251. data/examples/legacy/not_checked/shoes-dep-samples/simple-anim-text.rb +13 -0
  252. data/examples/legacy/not_checked/shoes-dep-samples/simple-arc.rb +23 -0
  253. data/examples/legacy/not_checked/shoes-dep-samples/simple-bounce.rb +24 -0
  254. data/examples/legacy/not_checked/shoes-dep-samples/simple-calc.rb +70 -0
  255. data/examples/legacy/not_checked/shoes-dep-samples/simple-chipmunk.rb +26 -0
  256. data/examples/legacy/not_checked/shoes-dep-samples/simple-control-sizes.rb +24 -0
  257. data/examples/legacy/not_checked/shoes-dep-samples/simple-curve.rb +26 -0
  258. data/examples/legacy/not_checked/shoes-dep-samples/simple-dialogs.rb +29 -0
  259. data/examples/legacy/not_checked/shoes-dep-samples/simple-draw.rb +13 -0
  260. data/examples/legacy/not_checked/shoes-dep-samples/simple-editor.rb +28 -0
  261. data/examples/legacy/not_checked/shoes-dep-samples/simple-form.rb +28 -0
  262. data/examples/legacy/not_checked/shoes-dep-samples/simple-form.shy +0 -0
  263. data/examples/legacy/not_checked/shoes-dep-samples/simple-mask.rb +21 -0
  264. data/examples/legacy/not_checked/shoes-dep-samples/simple-menu.rb +31 -0
  265. data/examples/legacy/not_checked/shoes-dep-samples/simple-menu1.rb +35 -0
  266. data/examples/legacy/not_checked/shoes-dep-samples/simple-rubygems.rb +29 -0
  267. data/examples/legacy/not_checked/shoes-dep-samples/simple-slide.rb +45 -0
  268. data/examples/legacy/not_checked/shoes-dep-samples/simple-sphere.rb +28 -0
  269. data/examples/legacy/not_checked/shoes-dep-samples/simple-sqlite3.rb +13 -0
  270. data/examples/legacy/not_checked/shoes-dep-samples/simple-timer.rb +13 -0
  271. data/examples/legacy/not_checked/shoes-dep-samples/simple-video.rb +13 -0
  272. data/examples/legacy/not_checked/shoes3-tests/AnemicCinema1926marcelDuchampCut.mp4 +0 -0
  273. data/examples/legacy/not_checked/shoes3-tests/button/button.rb +53 -0
  274. data/examples/legacy/not_checked/shoes3-tests/cache/cache.rb +41 -0
  275. data/examples/legacy/not_checked/shoes3-tests/combo/combo.rb +24 -0
  276. data/examples/legacy/not_checked/shoes3-tests/curl/bare.rb +34 -0
  277. data/examples/legacy/not_checked/shoes3-tests/curl/downloader.rb +40 -0
  278. data/examples/legacy/not_checked/shoes3-tests/curl/m1.rb +11 -0
  279. data/examples/legacy/not_checked/shoes3-tests/curl/m2.rb +12 -0
  280. data/examples/legacy/not_checked/shoes3-tests/curl/m3.rb +11 -0
  281. data/examples/legacy/not_checked/shoes3-tests/curl/m4.rb +5 -0
  282. data/examples/legacy/not_checked/shoes3-tests/curl/typ.rb +30 -0
  283. data/examples/legacy/not_checked/shoes3-tests/cursor/c1.rb +21 -0
  284. data/examples/legacy/not_checked/shoes3-tests/decoration.rb +14 -0
  285. data/examples/legacy/not_checked/shoes3-tests/dialogs/ask.rb +6 -0
  286. data/examples/legacy/not_checked/shoes3-tests/dialogs/confirm.rb +6 -0
  287. data/examples/legacy/not_checked/shoes3-tests/editbox/editbox.rb +36 -0
  288. data/examples/legacy/not_checked/shoes3-tests/editline/editline.rb +27 -0
  289. data/examples/legacy/not_checked/shoes3-tests/events/button.rb +32 -0
  290. data/examples/legacy/not_checked/shoes3-tests/events/button.yaml +40 -0
  291. data/examples/legacy/not_checked/shoes3-tests/events/capture.rb +57 -0
  292. data/examples/legacy/not_checked/shoes3-tests/events/chipmunk.yaml +47 -0
  293. data/examples/legacy/not_checked/shoes3-tests/events/event0.rb +8 -0
  294. data/examples/legacy/not_checked/shoes3-tests/events/event1.rb +51 -0
  295. data/examples/legacy/not_checked/shoes3-tests/events/event1.yaml +26 -0
  296. data/examples/legacy/not_checked/shoes3-tests/events/event2.rb +46 -0
  297. data/examples/legacy/not_checked/shoes3-tests/events/event3.rb +44 -0
  298. data/examples/legacy/not_checked/shoes3-tests/events/event4.rb +65 -0
  299. data/examples/legacy/not_checked/shoes3-tests/events/event5.rb +17 -0
  300. data/examples/legacy/not_checked/shoes3-tests/events/event6.rb +51 -0
  301. data/examples/legacy/not_checked/shoes3-tests/events/replay.rb +60 -0
  302. data/examples/legacy/not_checked/shoes3-tests/gapp/fullscreen.rb +38 -0
  303. data/examples/legacy/not_checked/shoes3-tests/gapp/icon.rb +56 -0
  304. data/examples/legacy/not_checked/shoes3-tests/gapp/mon1.rb +46 -0
  305. data/examples/legacy/not_checked/shoes3-tests/gapp/settings1.rb +22 -0
  306. data/examples/legacy/not_checked/shoes3-tests/gapp/title1.rb +34 -0
  307. data/examples/legacy/not_checked/shoes3-tests/indian.m4a +0 -0
  308. data/examples/legacy/not_checked/shoes3-tests/menus/event.rb +33 -0
  309. data/examples/legacy/not_checked/shoes3-tests/menus/menu1.rb +8 -0
  310. data/examples/legacy/not_checked/shoes3-tests/menus/menu2.rb +25 -0
  311. data/examples/legacy/not_checked/shoes3-tests/menus/menu3.rb +103 -0
  312. data/examples/legacy/not_checked/shoes3-tests/menus/menu4.rb +41 -0
  313. data/examples/legacy/not_checked/shoes3-tests/menus/tests.txt +42 -0
  314. data/examples/legacy/not_checked/shoes3-tests/opacity.rb +13 -0
  315. data/examples/legacy/not_checked/shoes3-tests/plot/^IRX.R +5219 -0
  316. data/examples/legacy/not_checked/shoes3-tests/plot/^SPX +5219 -0
  317. data/examples/legacy/not_checked/shoes3-tests/plot/cstest.rb +51 -0
  318. data/examples/legacy/not_checked/shoes3-tests/plot/gr1.rb +73 -0
  319. data/examples/legacy/not_checked/shoes3-tests/plot/gr2.rb +40 -0
  320. data/examples/legacy/not_checked/shoes3-tests/plot/gr3.rb +47 -0
  321. data/examples/legacy/not_checked/shoes3-tests/plot/gr4.rb +35 -0
  322. data/examples/legacy/not_checked/shoes3-tests/plot/gr5.rb +31 -0
  323. data/examples/legacy/not_checked/shoes3-tests/plot/gr6.rb +35 -0
  324. data/examples/legacy/not_checked/shoes3-tests/plot/gr7.rb +37 -0
  325. data/examples/legacy/not_checked/shoes3-tests/plot/grcsv.rb +219 -0
  326. data/examples/legacy/not_checked/shoes3-tests/plot/manual.rb +40 -0
  327. data/examples/legacy/not_checked/shoes3-tests/progress/progress.rb +29 -0
  328. data/examples/legacy/not_checked/shoes3-tests/radio/clear.rb +20 -0
  329. data/examples/legacy/not_checked/shoes3-tests/radio/group.rb +18 -0
  330. data/examples/legacy/not_checked/shoes3-tests/radio/multiple.rb +32 -0
  331. data/examples/legacy/not_checked/shoes3-tests/radio/nogroup.rb +9 -0
  332. data/examples/legacy/not_checked/shoes3-tests/simpletest.svg +14 -0
  333. data/examples/legacy/not_checked/shoes3-tests/spinner.rb +15 -0
  334. data/examples/legacy/not_checked/shoes3-tests/svg.rb +208 -0
  335. data/examples/legacy/not_checked/shoes3-tests/switch/switch.rb +28 -0
  336. data/examples/legacy/not_checked/shoes3-tests/systray/back.rb +20 -0
  337. data/examples/legacy/not_checked/shoes3-tests/systray/note.rb +17 -0
  338. data/examples/legacy/not_checked/shoes3-tests/terminal/cursor.rb +27 -0
  339. data/examples/legacy/not_checked/shoes3-tests/terminal/ed.rb +65 -0
  340. data/examples/legacy/not_checked/shoes3-tests/terminal/el.rb +50 -0
  341. data/examples/legacy/not_checked/shoes3-tests/terminal/logattr.rb +31 -0
  342. data/examples/legacy/not_checked/shoes3-tests/tests_color.rb +138 -0
  343. data/examples/legacy/not_checked/shoes3-tests/tests_svg.rb +228 -0
  344. data/examples/legacy/not_checked/shoes3-tests/tests_video_vlc.rb +186 -0
  345. data/examples/legacy/not_checked/shoes3-tests/tooltips.rb +20 -0
  346. data/examples/legacy/not_checked/shoes3-tests/video_vlc.rb +242 -0
  347. data/examples/legacy/not_checked/shoes3-tests/wheel/wheel1.rb +21 -0
  348. data/examples/legacy/not_checked/simple/accordion.rb +81 -0
  349. data/examples/legacy/not_checked/simple/anim-shapes.rb +17 -0
  350. data/examples/legacy/not_checked/simple/anim-text.rb +13 -0
  351. data/examples/legacy/not_checked/simple/arc.rb +23 -0
  352. data/examples/legacy/not_checked/simple/bounce.rb +24 -0
  353. data/examples/legacy/not_checked/simple/chipmunk.rb +26 -0
  354. data/examples/legacy/not_checked/simple/control-sizes.rb +24 -0
  355. data/examples/legacy/not_checked/simple/curve-control-points.rb +24 -0
  356. data/examples/legacy/not_checked/simple/curve.rb +26 -0
  357. data/examples/legacy/not_checked/simple/dialogs.rb +29 -0
  358. data/examples/legacy/not_checked/simple/downloader.rb +40 -0
  359. data/examples/legacy/not_checked/simple/downloader1.rb +31 -0
  360. data/examples/legacy/not_checked/simple/draw.rb +13 -0
  361. data/examples/legacy/not_checked/simple/editor.rb +28 -0
  362. data/examples/legacy/not_checked/simple/form.rb +30 -0
  363. data/examples/legacy/not_checked/simple/image.rb +21 -0
  364. data/examples/legacy/not_checked/simple/info.rb +78 -0
  365. data/examples/legacy/not_checked/simple/mask.rb +21 -0
  366. data/examples/legacy/not_checked/simple/mask2.rb +27 -0
  367. data/examples/legacy/not_checked/simple/menu.rb +31 -0
  368. data/examples/legacy/not_checked/simple/menu1.rb +35 -0
  369. data/examples/legacy/not_checked/simple/slide.rb +45 -0
  370. data/examples/legacy/not_checked/simple/sphere.rb +28 -0
  371. data/examples/legacy/not_checked/superleg.rb +244 -0
  372. data/examples/legacy/working/shoes-contrib/basic/a-poem.rb +24 -0
  373. data/examples/legacy/working/shoes-contrib/basic/basic-blocks-instances.rb +7 -0
  374. data/examples/legacy/working/shoes-contrib/basic/basic-blocks.rb +7 -0
  375. data/examples/legacy/working/shoes-contrib/basic/basic-slot.rb +8 -0
  376. data/examples/legacy/working/shoes-contrib/basic/intro.rb +20 -0
  377. data/examples/legacy/working/shoes-contrib/basic/two-column.rb +12 -0
  378. data/examples/legacy/working/shoes-contrib/elements/edit_box.rb +6 -0
  379. data/examples/legacy/working/shoes-contrib/kernel/alert.rb +3 -0
  380. data/examples/legacy/working/simple/calc.rb +71 -0
  381. data/examples/legacy/working/simple/sqlite3.rb +27 -0
  382. data/examples/legacy/working/simple/timer.rb +13 -0
  383. data/examples/line.rb +5 -0
  384. data/examples/link.rb +20 -0
  385. data/examples/list_box.rb +8 -0
  386. data/examples/para/collection_of_arguments.rb +9 -0
  387. data/examples/para/hello_world.rb +5 -0
  388. data/examples/para/hide_and_show.rb +9 -0
  389. data/examples/para/rainbow.rb +11 -0
  390. data/examples/para/rainbow_2.rb +11 -0
  391. data/examples/para/sizes.rb +11 -0
  392. data/examples/para/sizes_2.rb +12 -0
  393. data/examples/para/strong.rb +3 -0
  394. data/examples/para_text_widgets.rb +4 -0
  395. data/examples/pirate.png +0 -0
  396. data/examples/raw_flow.rb +11 -0
  397. data/examples/ruby_racer.rb +52 -0
  398. data/examples/shapes/arc.rb +8 -0
  399. data/examples/shapes/shapes.rb +8 -0
  400. data/examples/shapes/shapes_fill.rb +10 -0
  401. data/examples/shapes/star.rb +5 -0
  402. data/examples/shoes_school.rb +68 -0
  403. data/examples/shoes_splorer.rb +150 -0
  404. data/examples/simple_slides.rb +73 -0
  405. data/examples/skip_ci/parrot.rb +22 -0
  406. data/examples/skip_ci/say.rb +20 -0
  407. data/examples/sleepless.rb +26 -0
  408. data/examples/slots.rb +2 -4
  409. data/examples/spacing.rb +18 -0
  410. data/examples/span.rb +6 -0
  411. data/examples/stack/background.rb +35 -0
  412. data/examples/stack/border.rb +11 -0
  413. data/examples/stack/gradients.rb +6 -0
  414. data/examples/stack/raw_stack.rb +8 -0
  415. data/examples/stack/stack.rb +27 -0
  416. data/examples/text_change.rb +4 -0
  417. data/examples/text_sizes.rb +10 -0
  418. data/examples/timmy.rb +109 -0
  419. data/examples/title_and_resize.rb +3 -0
  420. data/exe/scarpe +108 -0
  421. data/lib/constants.rb +5 -0
  422. data/lib/scarpe/alert.rb +19 -0
  423. data/lib/scarpe/app.rb +78 -0
  424. data/lib/scarpe/arc.rb +49 -0
  425. data/lib/scarpe/background.rb +14 -0
  426. data/lib/scarpe/border.rb +16 -0
  427. data/lib/scarpe/button.rb +26 -18
  428. data/lib/scarpe/colors.rb +215 -0
  429. data/lib/scarpe/display_service.rb +189 -0
  430. data/lib/scarpe/document_root.rb +20 -0
  431. data/lib/scarpe/edit_box.rb +24 -0
  432. data/lib/scarpe/edit_line.rb +16 -30
  433. data/lib/scarpe/fill.rb +23 -0
  434. data/lib/scarpe/flow.rb +18 -15
  435. data/lib/scarpe/glibui/README.md +34 -0
  436. data/lib/scarpe/glibui/alert.rb +65 -0
  437. data/lib/scarpe/glibui/app.rb +27 -0
  438. data/lib/scarpe/glibui/background.rb +18 -0
  439. data/lib/scarpe/glibui/border.rb +22 -0
  440. data/lib/scarpe/glibui/button.rb +38 -0
  441. data/lib/scarpe/glibui/dimensions.rb +22 -0
  442. data/lib/scarpe/glibui/document_root.rb +33 -0
  443. data/lib/scarpe/glibui/edit_box.rb +44 -0
  444. data/lib/scarpe/glibui/edit_line.rb +43 -0
  445. data/lib/scarpe/glibui/flow.rb +33 -0
  446. data/lib/scarpe/glibui/html.rb +77 -0
  447. data/lib/scarpe/glibui/image.rb +36 -0
  448. data/lib/scarpe/glibui/link.rb +29 -0
  449. data/lib/scarpe/glibui/local_display.rb +62 -0
  450. data/lib/scarpe/glibui/para.rb +84 -0
  451. data/lib/scarpe/glibui/spacing.rb +41 -0
  452. data/lib/scarpe/glibui/stack.rb +33 -0
  453. data/lib/scarpe/glibui/text_widget.rb +30 -0
  454. data/lib/scarpe/glibui/widget.rb +81 -0
  455. data/lib/scarpe/glibui.rb +29 -0
  456. data/lib/scarpe/image.rb +28 -9
  457. data/lib/scarpe/libui/alert.rb +9 -0
  458. data/lib/scarpe/libui/button.rb +18 -0
  459. data/lib/scarpe/libui/colors.rb +157 -0
  460. data/lib/scarpe/libui/core.rb +66 -0
  461. data/lib/scarpe/libui/flow.rb +16 -0
  462. data/lib/scarpe/libui/libui.rb +45 -0
  463. data/lib/scarpe/libui/notepad.md +26 -0
  464. data/lib/scarpe/libui/para.rb +154 -0
  465. data/lib/scarpe/libui/stack.rb +34 -0
  466. data/lib/scarpe/line.rb +25 -0
  467. data/lib/scarpe/link.rb +25 -0
  468. data/lib/scarpe/list_box.rb +25 -0
  469. data/lib/scarpe/logger.rb +155 -0
  470. data/lib/scarpe/para.rb +84 -12
  471. data/lib/scarpe/promises.rb +387 -0
  472. data/lib/scarpe/shape.rb +19 -0
  473. data/lib/scarpe/spacing.rb +9 -0
  474. data/lib/scarpe/span.rb +26 -0
  475. data/lib/scarpe/stack.rb +66 -12
  476. data/lib/scarpe/star.rb +47 -0
  477. data/lib/scarpe/text_widget.rb +42 -0
  478. data/lib/scarpe/unit_test_helpers.rb +163 -0
  479. data/lib/scarpe/version.rb +2 -2
  480. data/lib/scarpe/widget.rb +198 -0
  481. data/lib/scarpe/widgets.rb +30 -0
  482. data/lib/scarpe/wv/alert.rb +65 -0
  483. data/lib/scarpe/wv/app.rb +85 -0
  484. data/lib/scarpe/wv/arc.rb +57 -0
  485. data/lib/scarpe/wv/background.rb +18 -0
  486. data/lib/scarpe/wv/border.rb +22 -0
  487. data/lib/scarpe/wv/button.rb +50 -0
  488. data/lib/scarpe/wv/control_interface.rb +153 -0
  489. data/lib/scarpe/wv/control_interface_test.rb +253 -0
  490. data/lib/scarpe/wv/dimensions.rb +22 -0
  491. data/lib/scarpe/wv/document_root.rb +50 -0
  492. data/lib/scarpe/wv/edit_box.rb +44 -0
  493. data/lib/scarpe/wv/edit_line.rb +43 -0
  494. data/lib/scarpe/wv/fill.rb +30 -0
  495. data/lib/scarpe/wv/flow.rb +32 -0
  496. data/lib/scarpe/wv/html.rb +107 -0
  497. data/lib/scarpe/wv/image.rb +36 -0
  498. data/lib/scarpe/wv/line.rb +38 -0
  499. data/lib/scarpe/wv/link.rb +29 -0
  500. data/lib/scarpe/wv/list_box.rb +50 -0
  501. data/lib/scarpe/wv/para.rb +90 -0
  502. data/lib/scarpe/wv/shape.rb +34 -0
  503. data/lib/scarpe/wv/shape_helper.rb +44 -0
  504. data/lib/scarpe/wv/spacing.rb +41 -0
  505. data/lib/scarpe/wv/span.rb +66 -0
  506. data/lib/scarpe/wv/stack.rb +42 -0
  507. data/lib/scarpe/wv/star.rb +64 -0
  508. data/lib/scarpe/wv/text_widget.rb +30 -0
  509. data/lib/scarpe/wv/web_wrangler.rb +679 -0
  510. data/lib/scarpe/wv/webview_local_display.rb +72 -0
  511. data/lib/scarpe/wv/webview_relay_display.rb +185 -0
  512. data/lib/scarpe/wv/widget.rb +181 -0
  513. data/lib/scarpe/wv/wv_display_worker.rb +65 -0
  514. data/lib/scarpe/wv.rb +39 -0
  515. data/lib/scarpe/wv_local.rb +6 -0
  516. data/lib/scarpe/wv_relay.rb +6 -0
  517. data/lib/scarpe.rb +35 -27
  518. data/logger/debug_web_wrangler.json +4 -0
  519. data/logger/scarpe_wv_test.json +4 -0
  520. data/scarpegen.rb +193 -0
  521. data/sig/scarpe.rbs +1 -1
  522. data/templates/basic_class_template.erb +38 -0
  523. data/templates/class_template_with_event_bind.erb +27 -0
  524. data/templates/class_template_with_shapes.erb +43 -0
  525. data/templates/example_template.erb +3 -0
  526. data/templates/module_template.erb +12 -0
  527. data/templates/webview_template.erb +30 -0
  528. metadata +586 -9
  529. data/lib/scarpe/container.rb +0 -10
  530. data/lib/scarpe/internal_app.rb +0 -46
@@ -0,0 +1,155 @@
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
+ end
143
+ end
144
+
145
+ class Logging::Logger
146
+ alias_method :warning, :warn
147
+ end
148
+
149
+ log_config = if ENV["SCARPE_LOG_CONFIG"]
150
+ JSON.load_file(ENV["SCARPE_LOG_CONFIG"])
151
+ else
152
+ ENV["SCARPE_DEBUG"] ? Scarpe::Log::DEFAULT_DEBUG_LOG_CONFIG : Scarpe::Log::DEFAULT_LOG_CONFIG
153
+ end
154
+
155
+ Scarpe::Logger.configure_logger(log_config)
data/lib/scarpe/para.rb CHANGED
@@ -1,18 +1,90 @@
1
- module Scarpe
2
- class Para
3
- def initialize(app, text)
4
- @app = app
5
- @text = text
6
- @app.append(render)
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class Para < Scarpe::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
+
63
+ class Widget
64
+ def banner(*args, **kwargs)
65
+ para(*args, **{ size: :banner }.merge(kwargs))
7
66
  end
8
67
 
9
- def render
10
- "<p id=#{object_id}>#{@text}</p>"
68
+ def title(*args, **kwargs)
69
+ para(*args, **{ size: :title }.merge(kwargs))
11
70
  end
12
71
 
13
- def replace(text)
14
- @text = text
15
- @app.window.eval("document.getElementById(#{object_id}).innerText = \"#{text}\"")
72
+ def subtitle(*args, **kwargs)
73
+ para(*args, **{ size: :subtitle }.merge(kwargs))
16
74
  end
75
+
76
+ def tagline(*args, **kwargs)
77
+ para(*args, **{ size: :tagline }.merge(kwargs))
78
+ end
79
+
80
+ def caption(*args, **kwargs)
81
+ para(*args, **{ size: :caption }.merge(kwargs))
82
+ end
83
+
84
+ def inscription(*args, **kwargs)
85
+ para(*args, **{ size: :inscription }.merge(kwargs))
86
+ end
87
+
88
+ alias_method :ins, :inscription
17
89
  end
18
- end
90
+ end
@@ -0,0 +1,387 @@
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
+ # These promises are mostly designed for external execution.
139
+ # You could put together your own thread-pool, or use RPC,
140
+ # a WebView, a database or similar source of external calculation.
141
+ # But in some cases, sure, it's reasonable to execute locally.
142
+ # In those cases, you can register an executor, which will be
143
+ # called when the promise is ready to execute but has not yet
144
+ # done so. Registering an executor on a promise that is
145
+ # already fulfilled is an error. Registering an executor on
146
+ # a promise that has already rejected is a no-op.
147
+ def to_execute(&block)
148
+ case @state
149
+ when :fulfilled
150
+ # Should this be a no-op instead?
151
+ raise "Registering an executor on an already fulfilled promise means it will never run!"
152
+ when :rejected
153
+ return
154
+ when :unscheduled
155
+ @executor = block # save for later
156
+ when :pending
157
+ @executor = block
158
+ call_executor
159
+ else
160
+ raise "Internal error, illegal state!"
161
+ end
162
+
163
+ self
164
+ end
165
+
166
+ private
167
+
168
+ # set_state looks at the old and new states of the promise. It calls handlers and updates tracking
169
+ # data accordingly.
170
+ def set_state(new_state, value_or_reason = nil)
171
+ old_state = @state
172
+
173
+ # First, filter out illegal input
174
+ unless PROMISE_STATES.include?(old_state)
175
+ raise "Internal Promise error! Internal state was #{old_state.inspect}! Legal states: #{PROMISE_STATES.inspect}"
176
+ end
177
+
178
+ unless PROMISE_STATES.include?(new_state)
179
+ raise "Internal Promise error! Internal state was set to #{new_state.inspect}! " +
180
+ "Legal states: #{PROMISE_STATES.inspect}"
181
+ end
182
+
183
+ if new_state != :fulfilled && new_state != :rejected && !value_or_reason.nil?
184
+ raise "Internal promise error! Non-completed state transitions should not specify a value or reason!"
185
+ end
186
+
187
+ # Here's our state-transition grid for what we're doing here.
188
+ # "From" state is on the left, "to" state is on top.
189
+ #
190
+ # U P F R
191
+ #
192
+ # U - 1 . .
193
+ # P X - . .
194
+ # F X X - X
195
+ # R X X X -
196
+ #
197
+ # - Change from same to same, no effect
198
+ # X Illegal for one reason or another, raise error
199
+ # . Great, no problem, run handlers but not @scheduler or @executor
200
+ # 1 Interesting case - if we have an executor, actually change to a *different* state instead
201
+
202
+ # Transitioning from our state to our same state? No-op.
203
+ return if new_state == old_state
204
+
205
+ # Transitioning to any *different* state after being fulfilled or rejected? Nope. Those states are final.
206
+ if complete?
207
+ raise "Internal Promise error! Trying to change state from #{old_state.inspect} to #{new_state.inspect}!"
208
+ end
209
+
210
+ if old_state == :pending && new_state == :unscheduled
211
+ raise "Can't change state from :pending to :unscheduled! Scheduling is not reversible!"
212
+ end
213
+
214
+ # The next three checks should all be followed by calling handlers for the newly-changed state.
215
+ # See call_handlers_for below.
216
+
217
+ # Okay, we're getting scheduled.
218
+ if old_state == :unscheduled && new_state == :pending
219
+ @state = new_state
220
+ call_handlers_for(new_state)
221
+
222
+ # It's not impossible for the scheduler to do something that fulfills or rejects the promise.
223
+ # In that case it *also* called the appropriate handlers. Let's get out of here.
224
+ return if @state == :fulfilled || @state == :rejected
225
+
226
+ if @executor
227
+ # In this case we're still pending, but we have a synchronous executor. Let's do it.
228
+ call_executor
229
+ end
230
+
231
+ return
232
+ end
233
+
234
+ # Setting to rejected calls the rejected handlers. But no scheduling ever occurs, so on_scheduled handlers
235
+ # will never be called.
236
+ if new_state == :rejected
237
+ @state = :rejected
238
+ @reason = value_or_reason
239
+ call_handlers_for(new_state)
240
+ end
241
+
242
+ # If we go straight from :unscheduled to :fulfilled we *will* run the on_scheduled callbacks,
243
+ # because we pretend the scheduling *did* occur at some point. Normally that'll be no callbacks,
244
+ # of course.
245
+ #
246
+ # Fun-but-unfortunate trivia: you *can* fulfill a promise before all its parents are fulfilled.
247
+ # If you do, the unfinished parents will result in nil arguments to the on_fulfilled handler,
248
+ # because we have no other value to provide. The scheduler callback will never be called, but
249
+ # the on_scheduled callbacks, if any, will be.
250
+ if new_state == :fulfilled
251
+ @state = :fulfilled
252
+ @returned_value = value_or_reason
253
+ call_handlers_for(new_state)
254
+ end
255
+ end
256
+
257
+ # This private method calls handlers for a new state, removing those handlers
258
+ # since they have now been called. This interacts subtly with set_state()
259
+ # above, particularly in the case of fulfilling a promise without it ever being
260
+ # properly scheduled.
261
+ #
262
+ # The rejected handlers will be cleared if the promise is fulfilled and vice-versa.
263
+ # After rejection, no on_fulfilled handler should ever be called and vice-versa.
264
+ #
265
+ # When we go from :unscheduled to :pending, the scheduler, if any, should be
266
+ # called and cleared. That should *not* happen when going from :unscheduled to
267
+ # :fulfilled.
268
+ def call_handlers_for(state)
269
+ case state
270
+ when :fulfilled
271
+ @on_scheduled.each { |h| h.call(*@parents.map(&:returned_value)) }
272
+ @on_fulfilled.each { |h| h.call(*@parents.map(&:returned_value)) }
273
+ @on_scheduled = @on_rejected = @on_fulfilled = []
274
+ @scheduler = @executor = nil
275
+ when :rejected
276
+ @on_rejected.each { |h| h.call(*@parents.map(&:returned_value)) }
277
+ @on_fulfilled = @on_scheduled = @on_rejected = []
278
+ @scheduler = @executor = nil
279
+ when :pending
280
+ # A scheduler can get an exception. If so, treat it as rejection
281
+ # and the exception as the provided reason.
282
+ if @scheduler
283
+ begin
284
+ @scheduler.call(*@parents.map(&:returned_value))
285
+ rescue => e
286
+ @log.error("Error while running scheduler! #{e.full_message}")
287
+ rejected!(e)
288
+ end
289
+ @scheduler = nil
290
+ end
291
+ @on_scheduled.each { |h| h.call(*@parents.map(&:returned_value)) }
292
+ @on_scheduled = []
293
+ else
294
+ raise "Internal error! Trying to call handlers for #{state.inspect}!"
295
+ end
296
+ end
297
+
298
+ def parent_fulfilled!(parent)
299
+ @waiting_on.delete(parent)
300
+
301
+ # Last parent? If so, schedule ourselves.
302
+ if @waiting_on.empty? && !self.complete?
303
+ # This will result in :pending if there's no executor,
304
+ # or fulfilled/rejected if there is an executor.
305
+ set_state(:pending)
306
+ end
307
+ end
308
+
309
+ def parent_rejected!(parent)
310
+ @waiting_on = []
311
+
312
+ unless self.complete?
313
+ # If our parent was rejected and we were waiting on them,
314
+ # now we're rejected too.
315
+ set_state(:rejected)
316
+ end
317
+ end
318
+
319
+ def call_executor
320
+ raise("Internal error! Should not call_executor with no executor!") unless @executor
321
+
322
+ begin
323
+ result = @executor.call(*@parents.map(&:returned_value))
324
+ fulfilled!(result)
325
+ rescue => e
326
+ @log.error("Error running executor! #{e.full_message}")
327
+ rejected!(e)
328
+ end
329
+ ensure
330
+ @executor = nil
331
+ end
332
+
333
+ public
334
+
335
+ def on_fulfilled(&handler)
336
+ unless handler
337
+ raise "You must pass a block to on_fulfilled!"
338
+ end
339
+
340
+ case @state
341
+ when :fulfilled
342
+ handler.call(*@parents.map(&:returned_value))
343
+ when :pending, :unscheduled
344
+ @on_fulfilled << handler
345
+ when :rejected
346
+ # Do nothing
347
+ end
348
+
349
+ self
350
+ end
351
+
352
+ def on_rejected(&handler)
353
+ unless handler
354
+ raise "You must pass a block to on_rejected!"
355
+ end
356
+
357
+ case @state
358
+ when :rejected
359
+ handler.call(*@parents.map(&:returned_value))
360
+ when :pending, :unscheduled
361
+ @on_rejected << handler
362
+ when :fulfilled
363
+ # Do nothing
364
+ end
365
+
366
+ self
367
+ end
368
+
369
+ def on_scheduled(&handler)
370
+ unless handler
371
+ raise "You must pass a block to on_scheduled!"
372
+ end
373
+
374
+ # Add a pending handler or call it now
375
+ case @state
376
+ when :fulfilled, :pending
377
+ handler.call(*@parents.map(&:returned_value))
378
+ when :unscheduled
379
+ @on_scheduled << handler
380
+ when :rejected
381
+ # Do nothing
382
+ end
383
+
384
+ self
385
+ end
386
+ end
387
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv/shape_helper"
4
+
5
+ class Scarpe
6
+ class Shape < Scarpe::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
+ instance_eval(&block) if block_given?
17
+ end
18
+ end
19
+ 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
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class Span < Scarpe::Widget
5
+ display_properties :text, :stroke, :size, :font, :html_attributes
6
+
7
+ def initialize(text, stroke: nil, size: :span, font: nil, **html_attributes)
8
+ @text = text
9
+ @stroke = stroke
10
+ @size = size
11
+ @font = font
12
+ @html_attributes = html_attributes
13
+
14
+ super
15
+
16
+ create_display_widget
17
+ end
18
+
19
+ def replace(text)
20
+ @text = text
21
+
22
+ # This should signal the display widget to change
23
+ self.text = @text
24
+ end
25
+ end
26
+ end