scarpe 0.2.2 → 0.3.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 (223) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/CHANGELOG.md +16 -2
  4. data/Gemfile.lock +7 -3
  5. data/README.md +24 -8
  6. data/Rakefile +1 -1
  7. data/examples/animate.rb +20 -0
  8. data/examples/arrow.rb +10 -0
  9. data/examples/btn_tooltip.rb +7 -0
  10. data/examples/button_style_changed.rb +7 -0
  11. data/examples/button_styles_default.rb +6 -0
  12. data/examples/gen.rb +8 -8
  13. data/examples/highlander.rb +3 -3
  14. data/examples/legacy/README.md +6 -0
  15. data/examples/legacy/not_checked/shoes-contrib/basic/shoes-notes.rb +1 -1
  16. data/examples/legacy/not_checked/simple/anim-shapes.rb +1 -1
  17. data/examples/legacy/not_checked/speedometer_app.rb +55 -0
  18. data/examples/legacy/working/simple/image-icon.rb +3 -0
  19. data/examples/legacy/{not_checked → working}/simple/image.rb +1 -1
  20. data/examples/list_box_choose.rb +17 -0
  21. data/examples/local_assets/local_file_server.rb +82 -0
  22. data/examples/local_assets/sample.gif +0 -0
  23. data/examples/local_assets/sample.mp4 +0 -0
  24. data/examples/local_fonts.rb +2 -2
  25. data/examples/local_images.rb +2 -3
  26. data/examples/para/para_text.rb +14 -0
  27. data/examples/progress.rb +31 -0
  28. data/examples/radio/radio_groups.rb +2 -2
  29. data/examples/rect.rb +4 -0
  30. data/examples/rotate_shapes.rb +17 -0
  31. data/examples/simpler-menu.rb +21 -0
  32. data/exe/scarpe +2 -1
  33. data/lacci/Gemfile +2 -0
  34. data/lacci/Gemfile.lock +8 -1
  35. data/lacci/lacci.gemspec +1 -1
  36. data/lacci/lib/lacci/scarpe_cli.rb +2 -1
  37. data/lacci/lib/lacci/scarpe_core.rb +2 -1
  38. data/lacci/lib/lacci/version.rb +1 -1
  39. data/lacci/lib/scarpe/niente/app.rb +23 -0
  40. data/lacci/lib/scarpe/niente/display_service.rb +62 -0
  41. data/lacci/lib/scarpe/niente/drawable.rb +57 -0
  42. data/lacci/lib/scarpe/niente/logger.rb +29 -0
  43. data/lacci/lib/scarpe/niente/shoes_spec.rb +87 -0
  44. data/lacci/lib/scarpe/niente.rb +20 -0
  45. data/lacci/lib/shoes/app.rb +88 -43
  46. data/lacci/lib/shoes/background.rb +2 -2
  47. data/lacci/lib/shoes/border.rb +2 -2
  48. data/lacci/lib/shoes/builtins.rb +63 -0
  49. data/lacci/lib/shoes/changelog.rb +52 -0
  50. data/lacci/lib/shoes/colors.rb +3 -1
  51. data/lacci/lib/shoes/constants.rb +19 -1
  52. data/lacci/lib/shoes/display_service.rb +39 -16
  53. data/lacci/lib/shoes/download.rb +2 -2
  54. data/lacci/lib/shoes/drawable.rb +380 -0
  55. data/lacci/lib/shoes/drawables/arc.rb +49 -0
  56. data/lacci/lib/shoes/drawables/arrow.rb +41 -0
  57. data/lacci/lib/shoes/drawables/button.rb +73 -0
  58. data/lacci/lib/shoes/{widgets → drawables}/check.rb +5 -4
  59. data/lacci/lib/shoes/{widgets → drawables}/document_root.rb +3 -3
  60. data/lacci/lib/shoes/{widgets → drawables}/edit_box.rb +6 -6
  61. data/lacci/lib/shoes/{widgets → drawables}/edit_line.rb +6 -6
  62. data/lacci/lib/shoes/{widgets → drawables}/flow.rb +6 -6
  63. data/lacci/lib/shoes/{widgets → drawables}/image.rb +6 -6
  64. data/lacci/lib/shoes/{widgets → drawables}/line.rb +7 -5
  65. data/lacci/lib/shoes/drawables/link.rb +34 -0
  66. data/lacci/lib/shoes/drawables/list_box.rb +56 -0
  67. data/lacci/lib/shoes/drawables/para.rb +118 -0
  68. data/lacci/lib/shoes/drawables/progress.rb +14 -0
  69. data/lacci/lib/shoes/drawables/radio.rb +33 -0
  70. data/lacci/lib/shoes/drawables/rect.rb +17 -0
  71. data/lacci/lib/shoes/{widgets → drawables}/shape.rb +6 -7
  72. data/lacci/lib/shoes/{widgets → drawables}/slot.rb +32 -20
  73. data/lacci/lib/shoes/{widgets → drawables}/span.rb +8 -7
  74. data/lacci/lib/shoes/{widgets → drawables}/stack.rb +6 -4
  75. data/lacci/lib/shoes/drawables/star.rb +50 -0
  76. data/lacci/lib/shoes/drawables/subscription_item.rb +93 -0
  77. data/lacci/lib/shoes/drawables/text_drawable.rb +63 -0
  78. data/lacci/lib/shoes/drawables/video.rb +16 -0
  79. data/lacci/lib/shoes/drawables/widget.rb +69 -0
  80. data/lacci/lib/shoes/drawables.rb +31 -0
  81. data/lacci/lib/shoes/errors.rb +28 -0
  82. data/lacci/lib/shoes/log.rb +2 -2
  83. data/lacci/lib/shoes/ruby_extensions.rb +15 -0
  84. data/lacci/lib/shoes/spacing.rb +2 -2
  85. data/lacci/lib/shoes-spec.rb +93 -0
  86. data/lacci/lib/shoes.rb +27 -7
  87. data/lacci/test/test_helper.rb +54 -0
  88. data/lacci/test/test_lacci.rb +12 -3
  89. data/lacci/test/test_shoes_errors.rb +49 -0
  90. data/lib/scarpe/cats_cradle.rb +81 -59
  91. data/lib/scarpe/errors.rb +77 -0
  92. data/lib/scarpe/evented_assertions.rb +50 -17
  93. data/lib/scarpe/shoes_spec.rb +181 -0
  94. data/lib/scarpe/version.rb +2 -2
  95. data/lib/scarpe/wv/app.rb +20 -20
  96. data/lib/scarpe/wv/arc.rb +4 -47
  97. data/lib/scarpe/wv/arrow.rb +9 -0
  98. data/lib/scarpe/wv/button.rb +7 -35
  99. data/lib/scarpe/wv/check.rb +3 -5
  100. data/lib/scarpe/wv/control_interface.rb +18 -20
  101. data/lib/scarpe/wv/document_root.rb +81 -4
  102. data/lib/scarpe/wv/{widget.rb → drawable.rb} +66 -43
  103. data/lib/scarpe/wv/edit_box.rb +4 -17
  104. data/lib/scarpe/wv/edit_line.rb +4 -18
  105. data/lib/scarpe/wv/flow.rb +2 -18
  106. data/lib/scarpe/wv/image.rb +8 -28
  107. data/lib/scarpe/wv/line.rb +3 -25
  108. data/lib/scarpe/wv/link.rb +3 -16
  109. data/lib/scarpe/wv/list_box.rb +6 -29
  110. data/lib/scarpe/wv/para.rb +11 -30
  111. data/lib/scarpe/wv/progress.rb +19 -0
  112. data/lib/scarpe/wv/radio.rb +9 -10
  113. data/lib/scarpe/wv/rect.rb +13 -0
  114. data/lib/scarpe/wv/shape.rb +3 -8
  115. data/lib/scarpe/wv/slot.rb +8 -25
  116. data/lib/scarpe/wv/span.rb +3 -27
  117. data/lib/scarpe/wv/stack.rb +2 -18
  118. data/lib/scarpe/wv/star.rb +3 -53
  119. data/lib/scarpe/wv/subscription_item.rb +38 -4
  120. data/lib/scarpe/wv/text_drawable.rb +32 -0
  121. data/lib/scarpe/wv/video.rb +15 -15
  122. data/lib/scarpe/wv/web_wrangler.rb +299 -329
  123. data/lib/scarpe/wv/webview_local_display.rb +48 -33
  124. data/lib/scarpe/wv/webview_relay_display.rb +12 -12
  125. data/lib/scarpe/wv/webview_relay_util.rb +7 -10
  126. data/lib/scarpe/wv/wv_display_worker.rb +2 -2
  127. data/lib/scarpe/wv.rb +45 -12
  128. data/lib/scarpe/wv_local.rb +1 -1
  129. data/lib/scarpe/wv_relay.rb +1 -1
  130. data/lib/scarpe.rb +1 -0
  131. data/logger/debug_web_wrangler.json +1 -1
  132. data/logger/scarpe_wv_test.json +1 -1
  133. data/scarpe-components/Gemfile.lock +86 -0
  134. data/scarpe-components/lib/scarpe/components/base64.rb +3 -7
  135. data/scarpe-components/lib/scarpe/components/calzini/alert.rb +49 -0
  136. data/scarpe-components/lib/scarpe/components/calzini/art_widgets.rb +203 -0
  137. data/scarpe-components/lib/scarpe/components/calzini/button.rb +39 -0
  138. data/scarpe-components/lib/scarpe/components/calzini/misc.rb +146 -0
  139. data/scarpe-components/lib/scarpe/components/calzini/para.rb +35 -0
  140. data/scarpe-components/lib/scarpe/components/calzini/slots.rb +155 -0
  141. data/scarpe-components/lib/scarpe/components/calzini/text_widgets.rb +65 -0
  142. data/scarpe-components/lib/scarpe/components/calzini.rb +149 -0
  143. data/scarpe-components/lib/scarpe/components/errors.rb +20 -0
  144. data/scarpe-components/lib/scarpe/components/file_helpers.rb +1 -0
  145. data/scarpe-components/lib/scarpe/components/html.rb +131 -0
  146. data/scarpe-components/lib/scarpe/components/minitest_export_reporter.rb +75 -0
  147. data/scarpe-components/lib/scarpe/components/minitest_import_runnable.rb +98 -0
  148. data/scarpe-components/lib/scarpe/components/minitest_result.rb +86 -0
  149. data/scarpe-components/lib/scarpe/components/modular_logger.rb +5 -5
  150. data/scarpe-components/lib/scarpe/components/print_logger.rb +9 -5
  151. data/scarpe-components/lib/scarpe/components/promises.rb +14 -14
  152. data/scarpe-components/lib/scarpe/components/segmented_file_loader.rb +36 -17
  153. data/scarpe-components/lib/scarpe/components/string_helpers.rb +10 -0
  154. data/scarpe-components/lib/scarpe/components/tiranti.rb +225 -0
  155. data/scarpe-components/lib/scarpe/components/unit_test_helpers.rb +45 -5
  156. data/scarpe-components/lib/scarpe/components/version.rb +2 -2
  157. data/scarpe-components/test/calzini/test_calzini_alert.rb +30 -0
  158. data/scarpe-components/test/calzini/test_calzini_art_drawables.rb +105 -0
  159. data/scarpe-components/test/calzini/test_calzini_button.rb +52 -0
  160. data/scarpe-components/test/calzini/test_calzini_misc.rb +115 -0
  161. data/scarpe-components/test/calzini/test_calzini_para.rb +37 -0
  162. data/scarpe-components/test/calzini/test_calzini_slots.rb +130 -0
  163. data/scarpe-components/test/calzini/test_calzini_text_drawables.rb +41 -0
  164. data/scarpe-components/test/mtr_data/exception.json +1 -0
  165. data/scarpe-components/test/mtr_data/fail_with_message.json +1 -0
  166. data/scarpe-components/test/mtr_data/skipped_no_message.json +1 -0
  167. data/scarpe-components/test/mtr_data/skipped_w_msg.json +1 -0
  168. data/scarpe-components/test/mtr_data/succeed_2_asserts.json +1 -0
  169. data/scarpe-components/test/test_dimensions.rb +26 -0
  170. data/scarpe-components/test/test_helper.rb +20 -0
  171. data/scarpe-components/test/test_html.rb +65 -0
  172. data/scarpe-components/test/test_minitest_result.rb +61 -0
  173. data/scarpe-components/test/test_promises.rb +5 -4
  174. data/scarpe-components/test/test_segmented_app_files.rb +8 -6
  175. data/scarpegen.rb +14 -14
  176. data/sig/scarpe.rbs +1 -1
  177. data/templates/basic_class_template.erb +13 -14
  178. data/templates/class_template_with_event_bind.erb +4 -4
  179. data/templates/class_template_with_shapes.erb +8 -17
  180. data/templates/example_template.erb +1 -1
  181. data/templates/module_template.erb +4 -4
  182. data/templates/webview_template.erb +3 -2
  183. metadata +113 -55
  184. data/examples/legacy/not_checked/shoes-contrib/elements/image-icon.rb +0 -3
  185. data/lacci/lib/shoes/widget.rb +0 -218
  186. data/lacci/lib/shoes/widgets/alert.rb +0 -19
  187. data/lacci/lib/shoes/widgets/arc.rb +0 -51
  188. data/lacci/lib/shoes/widgets/button.rb +0 -35
  189. data/lacci/lib/shoes/widgets/font.rb +0 -14
  190. data/lacci/lib/shoes/widgets/link.rb +0 -25
  191. data/lacci/lib/shoes/widgets/list_box.rb +0 -25
  192. data/lacci/lib/shoes/widgets/para.rb +0 -68
  193. data/lacci/lib/shoes/widgets/radio.rb +0 -35
  194. data/lacci/lib/shoes/widgets/star.rb +0 -44
  195. data/lacci/lib/shoes/widgets/subscription_item.rb +0 -60
  196. data/lacci/lib/shoes/widgets/text_widget.rb +0 -51
  197. data/lacci/lib/shoes/widgets/video.rb +0 -15
  198. data/lacci/lib/shoes/widgets.rb +0 -29
  199. data/lib/scarpe/wv/alert.rb +0 -66
  200. data/lib/scarpe/wv/background.rb +0 -27
  201. data/lib/scarpe/wv/border.rb +0 -24
  202. data/lib/scarpe/wv/control_interface_test.rb +0 -238
  203. data/lib/scarpe/wv/dimensions.rb +0 -22
  204. data/lib/scarpe/wv/font.rb +0 -36
  205. data/lib/scarpe/wv/html.rb +0 -108
  206. data/lib/scarpe/wv/spacing.rb +0 -41
  207. data/lib/scarpe/wv/text_widget.rb +0 -30
  208. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/definr.rb +0 -0
  209. /data/examples/legacy/not_checked/{expert → shoes-contrib/basic}/funnies.rb +0 -0
  210. /data/examples/legacy/not_checked/shoes-contrib/{elements → basic}/list_box-select-class.rb +0 -0
  211. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/basic-edit-box.rb +0 -0
  212. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/basic-fps.rb +0 -0
  213. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/border-cat.rb +0 -0
  214. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/check-mate.rb +0 -0
  215. /data/examples/legacy/{not_checked/shoes-contrib/manipulation → working/simple}/clear-slot.rb +0 -0
  216. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/clock.rb +0 -0
  217. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/gradient-shoes.rb +0 -0
  218. /data/examples/legacy/{not_checked/shoes-contrib/basic → working/simple}/list_box-shape-report.rb +0 -0
  219. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/list_box.rb +0 -0
  220. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/phat-button.rb +0 -0
  221. /data/examples/legacy/{not_checked/shoes-contrib → working}/simple/simple-calc.rb +0 -0
  222. /data/examples/legacy/{not_checked/shoes-contrib/position → working/simple}/stack-width.rb +0 -0
  223. /data/examples/legacy/{not_checked/shoes-contrib/elements → working/simple}/width-introspec.rb +0 -0
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class Button < Shoes::Drawable
5
+ include Shoes::Log
6
+ shoes_styles :text, :width, :height, :top, :left, :color, :padding_top, :padding_bottom, :text_color, :size, :font_size, :tooltip
7
+ shoes_events :click, :hover
8
+
9
+ # Creates a new Button object.
10
+ #
11
+ # @param text [String] The text displayed on the button.
12
+ # @param width [Integer] The requested width of the button in pixels.
13
+ # @param height [Integer] The requested height of the button in pixels.
14
+ # @param top [Integer] The position of the top edge of the button relative to its parent widget.
15
+ # @param left [Integer] The position of the left edge of the button relative to its parent widget.
16
+ # @param size [Integer] The font size of the button text.
17
+ # @param color [String] The background color of the button.
18
+ # @param padding_top [Integer] The padding above the button text.
19
+ # @param padding_bottom [Integer] The padding below the button text.
20
+ # @param text_color [String] The color of the button text.
21
+ # @yield A block of code to be executed when the button is clicked.
22
+ # @return [Shoes::Button] the button object
23
+ #
24
+ # @example
25
+ # Shoes.app do
26
+ # @push = button "Push me"
27
+ # @note = para "Nothing pushed so far"
28
+ # @push.click {
29
+ # @note.replace(
30
+ # "Aha! Click! ",
31
+ # link("Go back") { @note.replace("Nothing pushed so far") }
32
+ # )
33
+ # }
34
+ # end
35
+ def initialize(text, width: nil, height: nil, top: nil, left: nil, color: nil, padding_top: nil, padding_bottom: nil, size: 12, text_color: nil,
36
+ font_size: nil, tooltip: nil, &block)
37
+
38
+ log_init("Button")
39
+
40
+ # Properties passed as positional args, not keywords, don't get auto-set
41
+ @text = text
42
+ @block = block
43
+
44
+ super
45
+
46
+ # Bind to a handler named "click"
47
+ bind_self_event("click") do
48
+ @log.debug("Button clicked, calling handler") if @block
49
+ @block&.call
50
+ end
51
+
52
+ bind_self_event("hover") do
53
+ @hover&.call
54
+ end
55
+
56
+ create_display_drawable
57
+ end
58
+
59
+ # Set the click handler
60
+ #
61
+ # @yield A block to be called when the button is clicked.
62
+ def click(&block)
63
+ @block = block
64
+ end
65
+
66
+ # Set the hover handler
67
+ #
68
+ # @yield A block to be called when the cursor moves to be over the button.
69
+ def hover(&block)
70
+ @hover = block
71
+ end
72
+ end
73
+ end
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class Check < Shoes::Widget
5
- display_properties :checked
3
+ class Shoes
4
+ class Check < Shoes::Drawable
5
+ shoes_styles :checked
6
+ shoes_events :click
6
7
 
7
8
  def initialize(checked = nil, &block)
8
9
  @block = block
9
10
  super
10
11
 
11
12
  bind_self_event("click") { click }
12
- create_display_widget
13
+ create_display_drawable
13
14
  end
14
15
 
15
16
  def click(&block)
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
3
+ class Shoes
4
4
  class DocumentRoot < Shoes::Flow
5
+ shoes_events # No DocumentRoot-specific events yet
6
+
5
7
  def initialize
6
8
  @height = "100%"
7
9
  @width = @margin = @padding = nil
8
10
  @options = {}
9
11
 
10
12
  super
11
-
12
- create_display_widget
13
13
  end
14
14
 
15
15
  # The default inspect string can be absolutely huge in console output, and it's frequently printed.
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class EditBox < Shoes::Widget
5
- display_properties :text, :height, :width
3
+ class Shoes
4
+ class EditBox < Shoes::Drawable
5
+ shoes_styles :text, :height, :width
6
+ shoes_events :change
6
7
 
7
8
  def initialize(text = "", height: nil, width: nil, &block)
9
+ super
8
10
  @text = text
9
11
  @callback = block
10
12
 
11
- super
12
-
13
13
  bind_self_event("change") do |new_text|
14
14
  self.text = new_text
15
15
  @callback&.call(self)
16
16
  end
17
17
 
18
- create_display_widget
18
+ create_display_drawable
19
19
  end
20
20
 
21
21
  def change(&block)
@@ -1,21 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class EditLine < Shoes::Widget
5
- display_properties :text, :width
3
+ class Shoes
4
+ class EditLine < Shoes::Drawable
5
+ shoes_styles :text, :width
6
+ shoes_events :change
6
7
 
7
8
  def initialize(text = "", width: nil, &block)
9
+ super
8
10
  @block = block
9
11
  @text = text
10
12
 
11
- super
12
-
13
13
  bind_self_event("change") do |new_text|
14
14
  self.text = new_text
15
15
  @block&.call(new_text)
16
16
  end
17
17
 
18
- create_display_widget
18
+ create_display_drawable
19
19
  end
20
20
 
21
21
  def change(&block)
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
3
+ class Shoes
4
4
  class Flow < Shoes::Slot
5
5
  include Shoes::Background
6
6
  include Shoes::Border
7
7
  include Shoes::Spacing
8
8
 
9
- display_properties :width, :height, :margin, :padding
9
+ shoes_styles :width, :height, :margin, :padding
10
+ shoes_events
10
11
 
11
12
  def initialize(width: "100%", height: nil, margin: nil, padding: nil, **options, &block)
12
- @options = options
13
-
14
13
  super
14
+ @options = options
15
15
 
16
- # Create the display-side widget *before* instance_eval, which will add child widgets with their display widgets
17
- create_display_widget
16
+ # Create the display-side drawable *before* instance_eval, which will add child drawables with their display drawables
17
+ create_display_drawable
18
18
 
19
19
  Shoes::App.instance.with_slot(self, &block) if block_given?
20
20
  end
@@ -1,18 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class Image < Shoes::Widget
5
- display_properties :url, :width, :height, :top, :left, :click
3
+ class Shoes
4
+ class Image < Shoes::Drawable
5
+ shoes_styles :url, :width, :height, :top, :left, :click
6
+ shoes_events # No Image-specific events yet
6
7
 
7
8
  def initialize(url, width: nil, height: nil, top: nil, left: nil, click: nil)
8
- @url = url
9
-
10
9
  super
10
+ @url = url
11
11
 
12
12
  # Get the image dimensions
13
13
  # @width, @height = size
14
14
 
15
- create_display_widget
15
+ create_display_drawable
16
16
  end
17
17
 
18
18
  def replace(url)
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class Line < Shoes::Widget
5
- display_properties :left, :top, :x2, :y2, :draw_context
3
+ class Shoes
4
+ class Line < Shoes::Drawable
5
+ shoes_styles :left, :top, :x2, :y2, :draw_context
6
+ shoes_events # No Line-specific events yet
6
7
 
7
8
  def initialize(left, top, x2, y2)
9
+ super
10
+
8
11
  @left = left
9
12
  @top = top
10
13
  @x2 = x2
11
14
  @y2 = y2
12
15
  @draw_context = Shoes::App.instance.current_draw_context
13
16
 
14
- super
15
- create_display_widget
17
+ create_display_drawable
16
18
  end
17
19
  end
18
20
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class Link < Shoes::TextDrawable
5
+ shoes_styles :text, :click, :has_block
6
+ shoes_events :click
7
+
8
+ def initialize(text, click: nil, &block)
9
+ super
10
+
11
+ @text = text
12
+ @block = block
13
+ # We can't send a block to the display drawable, but we can send a boolean
14
+ @has_block = !block.nil?
15
+
16
+ # The click property should be changed before it gets sent to the display drawable
17
+ @click ||= "#"
18
+
19
+ bind_self_event("click") do
20
+ @block&.call
21
+ end
22
+
23
+ create_display_drawable
24
+ end
25
+ end
26
+
27
+ # In Shoes, the LinkHover pseudo-class is used to set default styles for links when
28
+ # hovered over. The functionality isn't present in Lacci yet.
29
+ class LinkHover < Link
30
+ def initialize
31
+ raise "This class should never be instantiated! Use link, not link_hover!"
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class ListBox < Shoes::Drawable
5
+ shoes_styles :items, :height, :width
6
+
7
+ # Shoes3 uses choose as the initialize arg, and .choose(item) as the setter here,
8
+ # but queries it with .text. So this is an unusual style, and we've chosen this
9
+ # name not to conflict with Shoes3.
10
+ shoes_style :chosen
11
+
12
+ shoes_events :change
13
+
14
+ def initialize(**args, &block)
15
+ super
16
+
17
+ @items = args[:items] || []
18
+ @chosen = args[:choose] || args[:items]&.first
19
+
20
+ bind_self_event("change") do |new_item|
21
+ self.chosen = new_item
22
+ @callback&.call(self)
23
+ end
24
+
25
+ create_display_drawable
26
+ end
27
+
28
+ # Select an item. `item` should be a text entry from `items`.
29
+ #
30
+ # @param item [String] the item to choose
31
+ # @return [void]
32
+ def choose(item)
33
+ unless self.items.include?(item)
34
+ raise Shoes::Errors::NoSuchListItemError, "List items (#{self.items.inspect}) do not contain item #{item.inspect}!"
35
+ end
36
+
37
+ @chosen = item
38
+ end
39
+
40
+ # The currently chosen text item or nil.
41
+ #
42
+ # @return [String|NilClass] the current text item or nil.
43
+ def text
44
+ @chosen
45
+ end
46
+
47
+ # Register a block to be called when the selection changes.
48
+ #
49
+ # @yield the block to be called when selection changes
50
+ # @return [Shoes::ListBox] self
51
+ def change(&block)
52
+ @callback = block
53
+ self # Allow chaining calls
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class Para < Shoes::Drawable
5
+ shoes_styles :text_items, :size, :font, :html_attributes, :hidden
6
+ shoes_style(:stroke) { |val| Shoes::Colors.to_rgb(val) }
7
+
8
+ shoes_events # No Para-specific events yet
9
+
10
+ # Initializes a new instance of the `Para` widget.
11
+ #
12
+ # @param args The text content of the paragraph.
13
+ # @param stroke [String, nil] The color of the text stroke.
14
+ # @param size [Symbol] The size of the paragraph text.
15
+ # @param font [String, nil] The font of the paragraph text.
16
+ # @param hidden [Boolean] Determines if the paragraph is initially hidden.
17
+ # @param html_attributes [Hash] Additional HTML attributes for the paragraph.
18
+ #
19
+ # @example
20
+ # Shoes.app do
21
+ # p = para "Hello, This is at the top!", stroke: "red", size: :title, font: "Arial"
22
+ #
23
+ # banner("Welcome to Shoes!")
24
+ # title("Shoes Examples")
25
+ # subtitle("Explore the Features")
26
+ # tagline("Step into a World of Shoes")
27
+ # caption("A GUI Framework for Ruby")
28
+ # inscription("Designed for Easy Development")
29
+ #
30
+ # p.replace "On top we'll switch to ", strong("bold"), "!"
31
+ # end
32
+ def initialize(*args, stroke: nil, size: :para, font: nil, **html_attributes)
33
+ super
34
+
35
+ # Text_children alternates strings and TextDrawables, so we can't just pass
36
+ # it as a Shoes style. It won't serialize.
37
+ update_text_children(args)
38
+
39
+ @html_attributes = html_attributes || {}
40
+
41
+ create_display_drawable
42
+ end
43
+
44
+ private
45
+
46
+ def text_children_to_items(text_children)
47
+ text_children.map { |arg| arg.is_a?(String) ? arg : arg.linkable_id }
48
+ end
49
+
50
+ public
51
+
52
+ # Sets the paragraph text to a new value, which can
53
+ # include {TextDrawable}s like em(), strong(), etc.
54
+ #
55
+ # @param children [Array] the arguments can be Strings and/or TextDrawables
56
+ # @return [void]
57
+ def replace(*children)
58
+ update_text_children(children)
59
+ end
60
+
61
+ # Set the paragraph text to a single String.
62
+ # To use bold, italics, etc. use {Para#replace} instead.
63
+ #
64
+ # @param child [String] the new text to use for this Para
65
+ # @return [void]
66
+ def text=(*children)
67
+ update_text_children(children)
68
+ end
69
+
70
+ def text
71
+ @text_children.map(&:to_s).join
72
+ end
73
+
74
+ def to_s
75
+ self.text
76
+ end
77
+
78
+ private
79
+
80
+ # Text_children alternates strings and TextDrawables, so we can't just pass
81
+ # it as a Shoes style. It won't serialize.
82
+ def update_text_children(children)
83
+ @text_children = children.flatten
84
+ # This should signal the display drawable to change
85
+ self.text_items = text_children_to_items(@text_children)
86
+ end
87
+ end
88
+ end
89
+
90
+ class Shoes
91
+ class Drawable
92
+ def banner(*args, **kwargs)
93
+ para(*args, **{ size: :banner }.merge(kwargs))
94
+ end
95
+
96
+ def title(*args, **kwargs)
97
+ para(*args, **{ size: :title }.merge(kwargs))
98
+ end
99
+
100
+ def subtitle(*args, **kwargs)
101
+ para(*args, **{ size: :subtitle }.merge(kwargs))
102
+ end
103
+
104
+ def tagline(*args, **kwargs)
105
+ para(*args, **{ size: :tagline }.merge(kwargs))
106
+ end
107
+
108
+ def caption(*args, **kwargs)
109
+ para(*args, **{ size: :caption }.merge(kwargs))
110
+ end
111
+
112
+ def inscription(*args, **kwargs)
113
+ para(*args, **{ size: :inscription }.merge(kwargs))
114
+ end
115
+
116
+ alias_method :ins, :inscription
117
+ end
118
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class Progress < Shoes::Drawable
5
+ shoes_styles :fraction
6
+ shoes_events # No Progress-specific events yet
7
+
8
+ def initialize(fraction: nil)
9
+ super
10
+
11
+ create_display_drawable
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ # A Radio button drawable. Only a single radio button may be checked in each
5
+ # group. If no group is specified, or the group is nil, default to all
6
+ # radio buttons in the same slot being treated as being in the same group.
7
+ class Radio < Shoes::Drawable
8
+ shoes_styles :group, :checked
9
+ shoes_events :click
10
+
11
+ def initialize(group = nil, checked: nil, &block)
12
+ super
13
+ @group = group
14
+ @block = block
15
+
16
+ bind_self_event("click") { click }
17
+ create_display_drawable
18
+ end
19
+
20
+ def click(&block)
21
+ @block = block
22
+ self.checked = !checked?
23
+ end
24
+
25
+ def checked?
26
+ @checked ? true : false
27
+ end
28
+
29
+ def checked(value)
30
+ self.checked = value
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ class Rect < Shoes::Drawable
5
+ shoes_styles :left, :top, :width, :height, :draw_context, :curve
6
+ shoes_events # No Rect-specific events yet
7
+
8
+ def initialize(*args)
9
+ @draw_context = Shoes::App.instance.current_draw_context
10
+
11
+ super
12
+ self.left, self.top, self.width, self.height, self.curve = args
13
+
14
+ create_display_drawable
15
+ end
16
+ end
17
+ end
@@ -1,25 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
3
+ class Shoes
4
4
  # A Shape acts as a sort of union type for drawn shapes. In Shoes you can use it to merge multiple
5
5
  # ovals, arcs, stars, etc. into a single drawn shape.
6
6
  #
7
7
  # In Shoes3, a Shape isn't really a Slot. It's a kind of DSL with drawing commands that happen
8
- # to have the same name as the Art widgets like star, arc, etc. Here we're treating it as
9
- # a slot containing those widgets, which is wrong but not *too* wrong.
8
+ # to have the same name as the Art drawables like star, arc, etc. Here we're treating it as
9
+ # a slot containing those drawables, which is wrong but not *too* wrong.
10
10
  #
11
11
  # @incompatibility A Shoes3 Shape is *not* a slot; Scarpe does *not* do union shapes
12
12
  class Shape < Shoes::Slot
13
- display_properties :left, :top, :shape_commands, :draw_context
13
+ shoes_styles :left, :top, :shape_commands, :draw_context
14
+ shoes_events # No Shape-specific events yet
14
15
 
15
16
  def initialize(left: nil, top: nil, &block)
16
- @left = left
17
- @top = top
18
17
  @shape_commands = []
19
18
  @draw_context = Shoes::App.instance.current_draw_context
20
19
 
21
20
  super
22
- create_display_widget
21
+ create_display_drawable
23
22
 
24
23
  Shoes::App.instance.with_slot(self, &block) if block_given?
25
24
  end
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class Shoes::Slot < Shoes::Widget
3
+ class Shoes::Slot < Shoes::Drawable
4
4
  # @incompatibility Shoes uses #content, not #children, for this
5
5
  attr_reader :children
6
6
 
7
+ shoes_events # No Slot-specific events yet
8
+
7
9
  # Do not call directly, use set_parent
8
10
  def remove_child(child)
9
11
  @children ||= []
@@ -19,29 +21,39 @@ class Shoes::Slot < Shoes::Widget
19
21
  @children << child
20
22
  end
21
23
 
22
- # Get a list of child widgets
24
+ # Get a list of child drawables
23
25
  def contents
24
26
  @children ||= []
25
27
  @children.dup
26
28
  end
27
29
 
28
- # Calling stack.app or flow.app will execute the block
29
- # with the Shoes::App as self, and with that stack or
30
- # flow as the current slot.
31
- #
32
- # @incompatibility Shoes Classic will only change self
33
- # via this method, while Scarpe will also change self
34
- # with the other Slot Manipulation methods: #clear,
35
- # #append, #prepend, #before and #after.
36
- #
37
- # @return [Shoes::App] the Shoes app
38
- # @yield the block to call with the Shoes App as self
39
- def app(&block)
40
- Shoes::App.instance.with_slot(self, &block) if block_given?
41
- Shoes::App.instance
30
+ # We use method_missing for drawable-creating methods like "button".
31
+ # The parent's method_missing will auto-create Shoes style getters and setters.
32
+ def method_missing(name, *args, **kwargs, &block)
33
+ klass = ::Shoes::Drawable.drawable_class_by_name(name)
34
+ return super unless klass
35
+
36
+ ::Shoes::Slot.define_method(name) do |*args, **kwargs, &block|
37
+ # Look up the Shoes drawable and create it...
38
+ drawable_instance = klass.new(*args, **kwargs, &block)
39
+
40
+ unless klass.ancestors.include?(::Shoes::TextDrawable)
41
+ drawable_instance.set_parent self # Create drawable in THIS SLOT, not current app slot
42
+ end
43
+
44
+ drawable_instance
45
+ end
46
+
47
+ send(name, *args, **kwargs, &block)
48
+ end
49
+
50
+ def respond_to_missing?(name, include_private = false)
51
+ return true if Drawable.drawable_class_by_name(name.to_s)
52
+
53
+ false
42
54
  end
43
55
 
44
- # Remove all children from this widget. If a block
56
+ # Remove all children from this drawable. If a block
45
57
  # is given, call the block to replace the children with
46
58
  # new contents from that block.
47
59
  #
@@ -50,7 +62,7 @@ class Shoes::Slot < Shoes::Widget
50
62
  #
51
63
  # @incompatibility Shoes Classic calls the clear block with current self, while Scarpe uses the Shoes::App as self
52
64
  #
53
- # @yield The block to call to replace the contents of the widget (optional)
65
+ # @yield The block to call to replace the contents of the drawable (optional)
54
66
  # @return [void]
55
67
  def clear(&block)
56
68
  @children.dup.each(&:destroy)
@@ -67,8 +79,8 @@ class Shoes::Slot < Shoes::Widget
67
79
  # @yield the block to call to replace children; will be called on the Shoes::App, appending to the called Slot as the current slot
68
80
  # @return [void]
69
81
  def append(&block)
70
- raise("append requires a block!") unless block_given?
71
- raise("Don't append to something that isn't a slot!") unless self.is_a?(Shoes::Slot)
82
+ raise(Shoes::Errors::InvalidAttributeValueError, "append requires a block!") unless block_given?
83
+ raise(Shoes::Errors::InvalidAttributeValueError, "Don't append to something that isn't a slot!") unless self.is_a?(Shoes::Slot)
72
84
 
73
85
  Shoes::App.instance.with_slot(self, &block)
74
86
  end
@@ -1,25 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Shoes
4
- class Span < Shoes::Widget
5
- display_properties :text, :stroke, :size, :font, :html_attributes
3
+ class Shoes
4
+ class Span < Shoes::Drawable
5
+ shoes_styles :text, :stroke, :size, :font, :html_attributes
6
+ shoes_events # No Span-specific events yet
6
7
 
7
8
  def initialize(text, stroke: nil, size: :span, font: nil, **html_attributes)
9
+ super
10
+
8
11
  @text = text
9
12
  @stroke = stroke
10
13
  @size = size
11
14
  @font = font
12
15
  @html_attributes = html_attributes
13
16
 
14
- super
15
-
16
- create_display_widget
17
+ create_display_drawable
17
18
  end
18
19
 
19
20
  def replace(text)
20
21
  @text = text
21
22
 
22
- # This should signal the display widget to change
23
+ # This should signal the display drawable to change
23
24
  self.text = @text
24
25
  end
25
26
  end