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,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ # This is an in-process Webview-based display service, with all the limitations that
5
+ # entails. Slow handlers will crash, ending this display service will end the
6
+ # process, too many or too large evals can crash the process, etc.
7
+ # Normally the intention is to use a RelayDisplayService to a second
8
+ # process containing one of these.
9
+ class WebviewDisplayService < Scarpe::DisplayService
10
+ include Scarpe::Log
11
+
12
+ class << self
13
+ attr_accessor :instance
14
+ end
15
+
16
+ # TODO: re-think the list of top-level singleton objects.
17
+ attr_reader :control_interface
18
+ attr_reader :doc_root
19
+ attr_reader :wrangler
20
+
21
+ # This is called before any of the various WebviewWidgets are created.
22
+ def initialize
23
+ if WebviewDisplayService.instance
24
+ raise "ERROR! This is meant to be a singleton!"
25
+ end
26
+
27
+ WebviewDisplayService.instance = self
28
+
29
+ super()
30
+ log_init("WV::WebviewDisplayService")
31
+
32
+ @display_widget_for = {}
33
+ end
34
+
35
+ def create_display_widget_for(widget_class_name, widget_id, properties)
36
+ if widget_class_name == "App"
37
+ unless @doc_root
38
+ raise "WebviewDocumentRoot is supposed to be created before WebviewApp!"
39
+ end
40
+
41
+ display_app = Scarpe::WebviewApp.new(properties)
42
+ display_app.document_root = @doc_root
43
+ @control_interface = display_app.control_interface
44
+ @control_interface.doc_root = @doc_root
45
+ @app = @control_interface.app
46
+ @wrangler = @control_interface.wrangler
47
+
48
+ set_widget_pairing(widget_id, display_app)
49
+
50
+ return display_app
51
+ end
52
+
53
+ # Create a corresponding display widget
54
+ display_class = Scarpe::WebviewWidget.display_class_for(widget_class_name)
55
+ display_widget = display_class.new(properties)
56
+ set_widget_pairing(widget_id, display_widget)
57
+
58
+ if widget_class_name == "DocumentRoot"
59
+ # WebviewDocumentRoot is created before WebviewApp. Mostly doc_root is just like any other widget,
60
+ # but we'll want a reference to it when we create WebviewApp.
61
+ @doc_root = display_widget
62
+ end
63
+
64
+ display_widget
65
+ end
66
+
67
+ def destroy
68
+ @app.destroy
69
+ WebviewDisplayService.instance = nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,185 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+ require "rbconfig"
5
+
6
+ class Scarpe
7
+ class AppShutdownError < Scarpe::Error; end
8
+
9
+ module WVRelayUtil # Make sure the including class also includes Scarpe::Log
10
+ def ready_to_read?(timeout = 0.0)
11
+ r, _, e = IO.select [@from], [], [@from, @to].uniq, timeout
12
+
13
+ # On timeout, select returns nil instead of arrays.
14
+ return if r.nil?
15
+
16
+ unless e.empty?
17
+ raise "#{@i_am}: Got error on connection(s) from IO.select! Dying!"
18
+ end
19
+
20
+ !r.empty?
21
+ end
22
+
23
+ def send_datagram(contents)
24
+ str_data = JSON.dump contents
25
+ dgram_str = (str_data.length.to_s + "a" + str_data).encode(Encoding::BINARY)
26
+ to_write = dgram_str.bytesize
27
+ written = 0
28
+
29
+ until written == to_write
30
+ count = @to.write(dgram_str.byteslice(written..-1))
31
+ if count.nil? || count == 0
32
+ raise "Something was wrong in send_datagram! Write returned #{count.inspect}!"
33
+ end
34
+
35
+ written += count
36
+ end
37
+
38
+ nil
39
+ end
40
+
41
+ def receive_datagram
42
+ @readbuf ||= String.new.encode(Encoding::BINARY)
43
+ to_read = nil
44
+
45
+ loop do
46
+ # Have we read a packet length already, sitting in @readbuf?
47
+ a_idx = @readbuf.index("a")
48
+ if a_idx
49
+ to_read = @readbuf[0..a_idx].to_i
50
+ @readbuf = @readbuf[(a_idx + 1)..-1]
51
+ break
52
+ end
53
+
54
+ # If not, read more bytes
55
+ new_bytes = @from.read(10)
56
+ if new_bytes.nil?
57
+ # This is perfectly normal, if the connection closed
58
+ raise AppShutdownError, "Got an unexpected EOF reading datagram! " +
59
+ "Did the #{@i_am == :child ? "parent" : "child"} process die?"
60
+ end
61
+ @readbuf << new_bytes
62
+ end
63
+
64
+ loop do
65
+ if @readbuf.bytesize >= to_read
66
+ out = @readbuf.byteslice(0, to_read)
67
+ @readbuf = @readbuf.byteslice(to_read, -1)
68
+ return out
69
+ end
70
+
71
+ new_bytes = @from.read(to_read - @readbuf.bytesize)
72
+ @readbuf << new_bytes
73
+ end
74
+ rescue
75
+ raise AppShutdownError, "Got exception #{$!.class} when receiving datagram... #{$!.inspect}"
76
+ end
77
+
78
+ def respond_to_datagram
79
+ message = receive_datagram
80
+ m_data = JSON.parse(message)
81
+
82
+ if m_data["type"] == "event"
83
+ kwargs_hash = {}
84
+ m_data["kwargs"].each { |k, v| kwargs_hash[k.to_sym] = v }
85
+ send_shoes_event(
86
+ *m_data["args"],
87
+ event_name: m_data["kwargs"]["event_name"],
88
+ target: m_data["kwargs"]["event_target"],
89
+ **kwargs_hash,
90
+ )
91
+ elsif m_data["type"] == "create"
92
+ raise "Parent process should never receive :create datagram!" if @i_am == :parent
93
+
94
+ @wv_display.create_display_widget_for(m_data["class_name"], m_data["id"], m_data["properties"])
95
+ elsif m_data["type"] == "destroy"
96
+ if @i_am == :parent
97
+ @shutdown = true
98
+ else
99
+ @log.info("Shutting down...")
100
+ exit 0
101
+ end
102
+ else
103
+ @log.error("Unrecognized datagram type:event: #{m_data.inspect}!")
104
+ end
105
+ end
106
+
107
+ def event_loop_for(t = 1.5)
108
+ t_start = Time.now
109
+ delay_time = t
110
+
111
+ while Time.now - t_start < delay_time
112
+ if ready_to_read?(0.1)
113
+ respond_to_datagram
114
+ else
115
+ sleep 0.1
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ # This "display service" actually creates a child process and sends events
122
+ # back and forth, but creates no widgets of its own.
123
+ class WVRelayDisplayService < Scarpe::DisplayService
124
+ include Scarpe::Log
125
+ include WVRelayUtil # Needs Scarpe::Log
126
+
127
+ attr_accessor :shutdown
128
+
129
+ def initialize
130
+ super()
131
+ log_init("WV::RelayDisplayService")
132
+
133
+ @event_subs = []
134
+ @shutdown = false
135
+ @i_am = :parent
136
+
137
+ server = TCPServer.new("127.0.0.1", 0)
138
+ port = server.addr[1]
139
+
140
+ @pid = spawn(RbConfig.ruby, File.join(__dir__, "wv_display_worker.rb"), port.to_s)
141
+ @from = @to = server.accept
142
+
143
+ # Subscribe to all event notifications and relay them to the worker
144
+ @event_subs << bind_shoes_event(event_name: :any, target: :any) do |*args, **kwargs|
145
+ unless kwargs[:relayed]
146
+ kwargs[:relayed] = true
147
+ send_datagram({ type: :event, args:, kwargs: })
148
+ end
149
+
150
+ # Forward the run event to the child process before doing this
151
+ if event_name == "run"
152
+ run_event_loop
153
+ end
154
+ rescue AppShutdownError
155
+ @shutdown = true
156
+ @log.info("Attempting to shut down...")
157
+ self.destroy
158
+ end
159
+ end
160
+
161
+ def run_event_loop
162
+ until @shutdown
163
+ respond_to_datagram while ready_to_read?
164
+ sleep 0.1
165
+ end
166
+ rescue AppShutdownError
167
+ @shutdown = true
168
+ @log.info("Attempting to shut down...")
169
+ self.destroy
170
+ end
171
+
172
+ def create_display_widget_for(widget_class_name, widget_id, properties)
173
+ send_datagram({ type: :create, class_name: widget_class_name, id: widget_id, properties: })
174
+ # Don't need to return anything. It wouldn't be used anyway.
175
+ end
176
+
177
+ def destroy
178
+ unless @shutdown
179
+ send_datagram({ type: :destroy })
180
+ end
181
+ @shutdown = true
182
+ (@events_subs || []).each { |unsub_id| DisplayService.unsub_from_events(unsub_id) }
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Scarpe
4
+ class WebviewWidget < DisplayService::Linkable
5
+ include Scarpe::Log
6
+
7
+ class << self
8
+ def display_class_for(scarpe_class_name)
9
+ scarpe_class = Scarpe.const_get(scarpe_class_name)
10
+ unless scarpe_class.ancestors.include?(Scarpe::DisplayService::Linkable)
11
+ raise "Scarpe Webview can only get display classes for Scarpe " +
12
+ "linkable widgets, not #{scarpe_class_name.inspect}!"
13
+ end
14
+
15
+ klass = Scarpe.const_get("Webview" + scarpe_class_name.split("::")[-1])
16
+ if klass.nil?
17
+ raise "Couldn't find corresponding Scarpe Webview class for #{scarpe_class_name.inspect}!"
18
+ end
19
+
20
+ klass
21
+ end
22
+ end
23
+
24
+ attr_reader :shoes_linkable_id
25
+ attr_reader :parent
26
+ attr_reader :children
27
+
28
+ def initialize(properties)
29
+ log_init("WV::Widget")
30
+
31
+ # Call method, which looks up the parent
32
+ @shoes_linkable_id = properties["shoes_linkable_id"] || properties[:shoes_linkable_id]
33
+ unless @shoes_linkable_id
34
+ raise "Could not find property shoes_linkable_id in #{properties.inspect}!"
35
+ end
36
+
37
+ # Set the display properties
38
+ properties.each do |k, v|
39
+ next if k == "shoes_linkable_id"
40
+
41
+ instance_variable_set("@" + k.to_s, v)
42
+ end
43
+
44
+ # The parent field is *almost* simple enough that a typed display property would handle it.
45
+ bind_shoes_event(event_name: "parent", target: shoes_linkable_id) do |new_parent_id|
46
+ display_parent = WebviewDisplayService.instance.query_display_widget_for(new_parent_id)
47
+ if @parent != display_parent
48
+ set_parent(display_parent)
49
+ end
50
+ end
51
+
52
+ # When Shoes widgets change properties, we get a change notification here
53
+ bind_shoes_event(event_name: "prop_change", target: shoes_linkable_id) do |prop_changes|
54
+ prop_changes.each do |k, v|
55
+ instance_variable_set("@" + k, v)
56
+ end
57
+ properties_changed(prop_changes)
58
+ end
59
+
60
+ bind_shoes_event(event_name: "destroy", target: shoes_linkable_id) do
61
+ destroy_self
62
+ end
63
+
64
+ super(linkable_id: @shoes_linkable_id)
65
+ end
66
+
67
+ # This exists to be overridden by children watching for changes
68
+ def properties_changed(changes)
69
+ needs_update! unless changes.empty?
70
+ end
71
+
72
+ def set_parent(new_parent)
73
+ @parent&.remove_child(self)
74
+ new_parent&.add_child(self)
75
+ @parent = new_parent
76
+ end
77
+
78
+ protected
79
+
80
+ # Do not call directly, use set_parent
81
+ def remove_child(child)
82
+ @children ||= []
83
+ unless @children.include?(child)
84
+ @log.error("remove_child: no such child(#{child.inspect}) for"\
85
+ " parent(#{parent.inspect})!")
86
+ end
87
+ @children.delete(child)
88
+ end
89
+
90
+ # Do not call directly, use set_parent
91
+ def add_child(child)
92
+ @children ||= []
93
+ @children << child
94
+
95
+ # If we add a child, we should redraw ourselves
96
+ needs_update!
97
+ end
98
+
99
+ # Convert an [r, g, b, a] array to an HTML hex color code
100
+ # Arrays support alpha. HTML hex does not. So premultiply.
101
+ def rgb_to_hex(color)
102
+ return color if color.nil?
103
+
104
+ r, g, b, a = *color
105
+ if r.is_a?(Float)
106
+ a ||= 1.0
107
+ r_float = r * a
108
+ g_float = g * a
109
+ b_float = b * a
110
+ else
111
+ a ||= 255
112
+ a_float = (a / 255.0)
113
+ r_float = (r.to_f / 255.0) * a_float
114
+ g_float = (g.to_f / 255.0) * a_float
115
+ b_float = (b.to_f / 255.0) * a_float
116
+ end
117
+
118
+ r_int = (r_float * 255.0).to_i.clamp(0, 255)
119
+ g_int = (g_float * 255.0).to_i.clamp(0, 255)
120
+ b_int = (b_float * 255.0).to_i.clamp(0, 255)
121
+
122
+ "#%0.2X%0.2X%0.2X" % [r_int, g_int, b_int]
123
+ end
124
+
125
+ public
126
+
127
+ # This gets a mini-webview for just this element and its children, if any
128
+ def html_element
129
+ @elt_wrangler ||= WebviewDisplayService.instance.doc_root.get_element_wrangler(html_id)
130
+ end
131
+
132
+ # Return a promise that guarantees all currently-requested changes have completed
133
+ def promise_update
134
+ html_element.promise_update
135
+ end
136
+
137
+ def html_id
138
+ object_id.to_s
139
+ end
140
+
141
+ # to_html is intended to get the HTML DOM rendering of this object and its children.
142
+ # Calling it should be side-effect-free and NOT update the webview.
143
+ def to_html
144
+ @children ||= []
145
+ child_markup = @children.map(&:to_html).join
146
+ if respond_to?(:element)
147
+ element { child_markup }
148
+ else
149
+ child_markup
150
+ end
151
+ end
152
+
153
+ # This binds a Scarpe JS callback, handled via a single dispatch point in the document root
154
+ def bind(event, &block)
155
+ raise("Widget has no linkable_id! #{inspect}") unless linkable_id
156
+
157
+ WebviewDisplayService.instance.doc_root.bind("#{linkable_id}-#{event}", &block)
158
+ end
159
+
160
+ # Removes the element from both the Ruby Widget tree and the HTML DOM.
161
+ # Return a promise for when that HTML change will be visible.
162
+ def destroy_self
163
+ @parent&.remove_child(self)
164
+ html_element.remove
165
+ end
166
+
167
+ # It's really hard to do dirty-tracking here because the redraws are fully asynchronous.
168
+ # And so we can't easily cancel one "in flight," and we can't easily pick up the latest
169
+ # changes... And we probably don't want to, because we may be halfway through a batch.
170
+ def needs_update!
171
+ WebviewDisplayService.instance.doc_root.request_redraw!
172
+ end
173
+
174
+ def handler_js_code(handler_function_name, *args)
175
+ raise("Widget has no linkable_id! #{inspect}") unless linkable_id
176
+
177
+ js_args = ["'#{linkable_id}-#{handler_function_name}'", *args].join(", ")
178
+ "scarpeHandler(#{js_args})"
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "socket"
5
+
6
+ # Wherever this file is installed, locate Scarpe relative to it. This could be an installed gem or a dev repo.
7
+ SCARPE_DIR = File.join(__dir__, "../..")
8
+
9
+ $LOAD_PATH.prepend(SCARPE_DIR)
10
+ require "scarpe"
11
+ require "scarpe/wv_local"
12
+
13
+ # This script exists to create a WebviewDisplayService that can be operated remotely over a socket.
14
+
15
+ if ARGV.length != 1
16
+ $stderr.puts("Usage: wv_display_worker.rb tcp_port_num")
17
+ exit(-1)
18
+ end
19
+
20
+ class WebviewContainedService < Scarpe::DisplayService::Linkable
21
+ include Scarpe::Log
22
+ include Scarpe::WVRelayUtil # Needs Scarpe::Log
23
+
24
+ attr_reader :log
25
+
26
+ def initialize(from, to)
27
+ super()
28
+ log_init("WV::DisplayWorker")
29
+
30
+ @i_am = :child
31
+ @event_subs = []
32
+ @wv_display = Scarpe::WebviewDisplayService.new
33
+
34
+ @from = from
35
+ @to = to
36
+
37
+ @init_done = false
38
+
39
+ # Wait to register our periodic_code until the wrangler exists
40
+ @event_subs << bind_shoes_event(event_name: "init") do
41
+ @wv_display.wrangler.periodic_code("datagramProcessor", 0.1) do
42
+ respond_to_datagram while ready_to_read?(0.0)
43
+ end
44
+ @init_done = true
45
+ end
46
+
47
+ # Subscribe to all event notifications and relay them to the opposite side
48
+ @event_subs << bind_shoes_event(event_name: :any, target: :any) do |*args, **kwargs|
49
+ unless kwargs[:relayed] || kwargs["relayed"]
50
+ kwargs[:relayed] = true
51
+ send_datagram({ type: :event, args:, kwargs: })
52
+ end
53
+ end
54
+
55
+ # Run for 2.5 seconds to let the app be created and "run" to get called.
56
+ # Once that happens, Webview will take over the event loop.
57
+ event_loop_for(2.5)
58
+ end
59
+ end
60
+
61
+ s = TCPSocket.new("localhost", ARGV[0].to_i)
62
+
63
+ SERVICE = WebviewContainedService.new(s, s)
64
+
65
+ SERVICE.log.info("Finished event loop. Exiting!")
data/lib/scarpe/wv.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Scarpe Webview Display Services
4
+
5
+ require_relative "wv/web_wrangler"
6
+ require_relative "wv/control_interface"
7
+
8
+ require_relative "wv/widget"
9
+ require_relative "wv/webview_local_display"
10
+ require_relative "wv/webview_relay_display"
11
+
12
+ require_relative "wv/dimensions"
13
+ require_relative "wv/html"
14
+
15
+ require_relative "wv/spacing"
16
+ require_relative "wv/star"
17
+ require_relative "wv/background"
18
+ require_relative "wv/border"
19
+
20
+ require_relative "wv/fill"
21
+ require_relative "wv/arc"
22
+
23
+ require_relative "wv/app"
24
+ require_relative "wv/document_root"
25
+ require_relative "wv/para"
26
+ require_relative "wv/stack"
27
+ require_relative "wv/flow"
28
+ require_relative "wv/button"
29
+ require_relative "wv/image"
30
+ require_relative "wv/edit_box"
31
+ require_relative "wv/edit_line"
32
+ require_relative "wv/list_box"
33
+ require_relative "wv/alert"
34
+ require_relative "wv/span"
35
+ require_relative "wv/shape"
36
+
37
+ require_relative "wv/text_widget"
38
+ require_relative "wv/link"
39
+ require_relative "wv/line"
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv"
4
+ require_relative "wv/webview_local_display"
5
+
6
+ Scarpe::DisplayService.set_display_service_class(Scarpe::WebviewDisplayService)
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "wv"
4
+ require_relative "wv/webview_relay_display"
5
+
6
+ Scarpe::DisplayService.set_display_service_class(Scarpe::WVRelayDisplayService)
data/lib/scarpe.rb CHANGED
@@ -1,34 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "webview_ruby"
4
- require 'securerandom'
3
+ require_relative "scarpe/logger"
4
+
5
+ # This will never be triggered -- we use the (...) feature below, which means this
6
+ # file won't even parse in old Rubies.
7
+ if RUBY_VERSION[0..2] < "3.2"
8
+ Scarpe::Logger.logger("Scarpe").error("Scarpe requires Ruby 3.2 or higher!")
9
+ exit(-1)
10
+ end
11
+
12
+ require "securerandom"
13
+ require "json"
14
+
15
+ require_relative "constants"
16
+
17
+ class Scarpe::Error < StandardError; end
5
18
 
6
- require_relative "scarpe/container"
7
19
  require_relative "scarpe/version"
8
- require_relative "scarpe/para"
9
- require_relative "scarpe/stack"
10
- require_relative "scarpe/flow"
11
- require_relative "scarpe/button"
12
- require_relative "scarpe/image"
13
- require_relative "scarpe/edit_line"
14
- require_relative "scarpe/internal_app"
15
-
16
-
17
- module Scarpe
18
- def self.app(opts = {}, &blk)
19
- w = WebviewRuby::Webview.new(debug: true)
20
- internal_app = Scarpe::InternalApp.new(w)
21
- w.bind("scarpeInit") do
22
- internal_app.render(&blk)
23
- end
24
- w.bind("scarpeHandler") do |*args|
25
- internal_app.handle_callback(*args)
20
+ require_relative "scarpe/promises"
21
+ require_relative "scarpe/display_service"
22
+ require_relative "scarpe/widgets"
23
+
24
+ require "bloops"
25
+
26
+ d_s = ENV["SCARPE_DISPLAY_SERVICE"] || "wv_local"
27
+ # This is require, not require_relative, to allow gems to supply a new display service
28
+ require "scarpe/#{d_s}"
29
+
30
+ #Constants Module
31
+ include Constants
32
+
33
+ class Scarpe
34
+ class << self
35
+ def app(...)
36
+ app = Scarpe::App.new(...)
37
+ app.init
38
+ app.run
39
+ app.destroy
26
40
  end
27
- w.init("scarpeInit();")
28
- w.set_title("example")
29
- w.set_size(480, 320)
30
- w.navigate("data:text/html, <body id=#{internal_app.object_id}></body>")
31
- w.run
32
- w.destroy
33
41
  end
34
42
  end
@@ -0,0 +1,4 @@
1
+ {
2
+ "default": "warn",
3
+ "WV::WebWrangler": ["debug", "logger/web_wrangler.log"]
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "default": ["debug", "logger/test_failure.log"],
3
+ "WebviewAPI": ["debug", "logger/test_failure_wv_api.log"]
4
+ }