lacci 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/lacci/scarpe_cli.rb +0 -1
  3. data/lib/lacci/version.rb +1 -1
  4. data/lib/scarpe/niente/display_service.rb +5 -1
  5. data/lib/scarpe/niente/drawable.rb +2 -0
  6. data/lib/scarpe/niente/shoes_spec.rb +7 -1
  7. data/lib/scarpe/niente.rb +14 -2
  8. data/lib/shoes/app.rb +44 -50
  9. data/lib/shoes/constants.rb +23 -2
  10. data/lib/shoes/display_service.rb +43 -4
  11. data/lib/shoes/drawable.rb +309 -35
  12. data/lib/shoes/drawables/arc.rb +2 -24
  13. data/lib/shoes/drawables/arrow.rb +2 -22
  14. data/lib/shoes/drawables/border.rb +28 -0
  15. data/lib/shoes/drawables/button.rb +4 -20
  16. data/lib/shoes/drawables/check.rb +7 -3
  17. data/lib/shoes/drawables/document_root.rb +4 -4
  18. data/lib/shoes/drawables/edit_box.rb +6 -5
  19. data/lib/shoes/drawables/edit_line.rb +5 -4
  20. data/lib/shoes/drawables/flow.rb +3 -5
  21. data/lib/shoes/drawables/font_helper.rb +62 -0
  22. data/lib/shoes/drawables/image.rb +2 -2
  23. data/lib/shoes/drawables/line.rb +4 -7
  24. data/lib/shoes/drawables/link.rb +5 -8
  25. data/lib/shoes/drawables/list_box.rb +8 -5
  26. data/lib/shoes/drawables/oval.rb +48 -0
  27. data/lib/shoes/drawables/para.rb +106 -18
  28. data/lib/shoes/drawables/progress.rb +2 -1
  29. data/lib/shoes/drawables/radio.rb +5 -3
  30. data/lib/shoes/drawables/rect.rb +5 -4
  31. data/lib/shoes/drawables/shape.rb +2 -1
  32. data/lib/shoes/drawables/slot.rb +99 -8
  33. data/lib/shoes/drawables/stack.rb +6 -11
  34. data/lib/shoes/drawables/star.rb +8 -30
  35. data/lib/shoes/drawables/text_drawable.rb +93 -34
  36. data/lib/shoes/drawables/video.rb +3 -2
  37. data/lib/shoes/drawables/widget.rb +8 -3
  38. data/lib/shoes/drawables.rb +2 -1
  39. data/lib/shoes/errors.rb +13 -3
  40. data/lib/shoes/margin_helper.rb +79 -0
  41. data/lib/shoes.rb +4 -3
  42. metadata +11 -11
  43. data/lib/scarpe/niente/logger.rb +0 -29
  44. data/lib/shoes/drawables/span.rb +0 -27
  45. data/lib/shoes/spacing.rb +0 -9
@@ -2,13 +2,14 @@
2
2
 
3
3
  class Shoes
4
4
  class EditBox < Shoes::Drawable
5
- shoes_styles :text, :height, :width
5
+ shoes_styles :text, :height, :width ,:tooltip, :font
6
6
  shoes_events :change
7
7
 
8
- def initialize(text = "", height: nil, width: nil, &block)
9
- super
10
- @text = text
8
+ init_args
9
+ opt_init_args :text
10
+ def initialize(*args, **kwargs, &block)
11
11
  @callback = block
12
+ super
12
13
 
13
14
  bind_self_event("change") do |new_text|
14
15
  self.text = new_text
@@ -23,7 +24,7 @@ class Shoes
23
24
  end
24
25
 
25
26
  def append(new_text)
26
- self.text = self.text + new_text
27
+ self.text = (self.text || "") + new_text
27
28
  end
28
29
  end
29
30
  end
@@ -2,13 +2,14 @@
2
2
 
3
3
  class Shoes
4
4
  class EditLine < Shoes::Drawable
5
- shoes_styles :text, :width
5
+ shoes_styles :text, :width, :font, :tooltip, :stroke
6
6
  shoes_events :change
7
7
 
8
- def initialize(text = "", width: nil, &block)
9
- super
8
+ init_args
9
+ opt_init_args :text
10
+ def initialize(*args, **kwargs, &block)
10
11
  @block = block
11
- @text = text
12
+ super
12
13
 
13
14
  bind_self_event("change") do |new_text|
14
15
  self.text = new_text
@@ -3,15 +3,13 @@
3
3
  class Shoes
4
4
  class Flow < Shoes::Slot
5
5
  include Shoes::Background
6
- include Shoes::Border
7
- include Shoes::Spacing
8
6
 
9
- shoes_styles :width, :height, :margin, :padding
7
+ Shoes::Drawable.drawable_default_styles[Shoes::Flow][:width] = "100%"
8
+
10
9
  shoes_events
11
10
 
12
- def initialize(width: "100%", height: nil, margin: nil, padding: nil, **options, &block)
11
+ def initialize(*args, **kwargs, &block)
13
12
  super
14
- @options = options
15
13
 
16
14
  # Create the display-side drawable *before* instance_eval, which will add child drawables with their display drawables
17
15
  create_display_drawable
@@ -0,0 +1,62 @@
1
+ module FontHelper
2
+
3
+ def parse_font(font)
4
+
5
+ input = font
6
+ regex = /\s+(?=(?:[^']*'[^']*')*[^']*$)(?![^']*,[^']*')/
7
+ result = input.split(regex)
8
+
9
+ fs = nil
10
+ fv = nil
11
+ fw = nil
12
+ fss = nil
13
+ ff = ""
14
+
15
+ fos = ["italic", "oblique"]
16
+ fov = ["small-caps", "initial", "inherit"]
17
+ fow = ["bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"]
18
+ foss = ["xx-small", "x-small", "small","large", "x-large", "xx-large", "smaller", "larger"]
19
+
20
+ result.each do |i|
21
+ if fos.include?(i)
22
+ fs = i
23
+ next
24
+ elsif fov.include?(i)
25
+ fv = i
26
+ next
27
+ elsif fow.include?(i)
28
+ fw = i
29
+ next
30
+ elsif foss.include?(i)
31
+ fss = i
32
+ next
33
+ else
34
+ if contains_number?(i)
35
+
36
+ fss=i;
37
+
38
+ elsif i != "normal" && i != "medium" && i.strip != ""
39
+
40
+ if ff == "Arial"
41
+
42
+ ff = i
43
+
44
+ else
45
+
46
+ ff = ff+" "+i
47
+
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ [fs, fv , fw , fss , ff.strip]
55
+ end
56
+
57
+ def contains_number?(str)
58
+
59
+ !!(str =~ /\d/)
60
+
61
+ end
62
+ end
@@ -5,9 +5,9 @@ class Shoes
5
5
  shoes_styles :url, :width, :height, :top, :left, :click
6
6
  shoes_events # No Image-specific events yet
7
7
 
8
- def initialize(url, width: nil, height: nil, top: nil, left: nil, click: nil)
8
+ init_args :url
9
+ def initialize(*args, **kwargs)
9
10
  super
10
- @url = url
11
11
 
12
12
  # Get the image dimensions
13
13
  # @width, @height = size
@@ -5,15 +5,12 @@ class Shoes
5
5
  shoes_styles :left, :top, :x2, :y2, :draw_context
6
6
  shoes_events # No Line-specific events yet
7
7
 
8
- def initialize(left, top, x2, y2)
9
- super
10
-
11
- @left = left
12
- @top = top
13
- @x2 = x2
14
- @y2 = y2
8
+ init_args :left, :top, :x2, :y2
9
+ def initialize(*args, **kwargs)
15
10
  @draw_context = Shoes::App.instance.current_draw_context
16
11
 
12
+ super
13
+
17
14
  create_display_drawable
18
15
  end
19
16
  end
@@ -5,22 +5,19 @@ class Shoes
5
5
  shoes_styles :text, :click, :has_block
6
6
  shoes_events :click
7
7
 
8
- def initialize(text, click: nil, &block)
9
- super
8
+ #Shoes::Drawable.drawable_default_styles[Shoes::Link][:click] = "#"
10
9
 
11
- @text = text
10
+ init_args # Empty by the time it reaches Drawable#initialize
11
+ def initialize(*args, **kwargs, &block)
12
12
  @block = block
13
13
  # We can't send a block to the display drawable, but we can send a boolean
14
14
  @has_block = !block.nil?
15
15
 
16
- # The click property should be changed before it gets sent to the display drawable
17
- @click ||= "#"
16
+ super
18
17
 
19
18
  bind_self_event("click") do
20
19
  @block&.call
21
20
  end
22
-
23
- create_display_drawable
24
21
  end
25
22
  end
26
23
 
@@ -28,7 +25,7 @@ class Shoes
28
25
  # hovered over. The functionality isn't present in Lacci yet.
29
26
  class LinkHover < Link
30
27
  def initialize
31
- raise "This class should never be instantiated! Use link, not link_hover!"
28
+ raise "This class should never be instantiated directly! Use link, not link_hover!"
32
29
  end
33
30
  end
34
31
  end
@@ -11,11 +11,14 @@ class Shoes
11
11
 
12
12
  shoes_events :change
13
13
 
14
- def initialize(**args, &block)
15
- super
16
-
17
- @items = args[:items] || []
18
- @chosen = args[:choose] || args[:items]&.first
14
+ init_args # No positional args
15
+ def initialize(**kwargs, &block)
16
+ # These aren't being set as styles -- remove them from kwargs before calling super
17
+ # TODO: set [] as default value for items?
18
+ @items = kwargs.delete(:items) || []
19
+ @chosen = kwargs.delete(:choose) || @items&.first
20
+
21
+ super(**kwargs, &block)
19
22
 
20
23
  bind_self_event("change") do |new_item|
21
24
  self.chosen = new_item
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Shoes
4
+ # Docs: https://github.com/scarpe-team/scarpe/blob/main/docs/static/manual.md#ovalleft-top-radius--shoesshape
5
+ class Oval < Shoes::Drawable
6
+ shoes_styles :center, :draw_context, :stroke, :fill
7
+
8
+ shoes_style(:left) { |val| convert_to_integer(val, "left") }
9
+ shoes_style(:top) { |val| convert_to_integer(val, "top") }
10
+ shoes_style(:radius) { |val| convert_to_integer(val, "radius") }
11
+ shoes_style(:height) { |val| convert_to_integer(val, "height") }
12
+ shoes_style(:width) { |val| convert_to_integer(val, "width") }
13
+ shoes_style(:strokewidth) { |val| convert_to_integer(val, "strokewidth") }
14
+
15
+ Shoes::Drawable.drawable_default_styles[Shoes::Oval][:fill] = "black"
16
+ Shoes::Drawable.drawable_default_styles[Shoes::Oval][:stroke] = "black"
17
+
18
+ init_args :left, :top
19
+ opt_init_args :radius, :height
20
+ def initialize(*args, **options)
21
+ @draw_context = Shoes::App.instance.current_draw_context
22
+
23
+ super # Parse any positional or keyword args
24
+
25
+ unless @left && @top && (@width || @height || @radius)
26
+ raise Shoes::Errors::InvalidAttributeValueError, "Oval requires left, top and one of (width, height, radius) to be specified!"
27
+ end
28
+
29
+ # Calzini expects "radius" to mean the x-axis-aligned radius, not y-axis-aligned.
30
+ # For an axis-aligned oval the two may be different.
31
+
32
+ # If we have no width, but a radius, default the width to be the radius * 2
33
+ @width ||= @radius * 2 if @radius
34
+
35
+ # We now know we have width or height, but maybe not both.
36
+
37
+ # Default to a circle - set height from width or vice-versa
38
+ @width ||= @height
39
+ @height ||= @width
40
+
41
+ # If we don't have radius yet, set it from width
42
+ @radius ||= @width / 2
43
+
44
+ create_display_drawable
45
+ end
46
+
47
+ end
48
+ end
@@ -1,24 +1,34 @@
1
1
  # frozen_string_literal: true
2
-
2
+ require_relative 'font_helper.rb'
3
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) }
4
+ class Para < Shoes::Drawable
5
+ include FontHelper
6
+ shoes_styles :text_items, :size, :family, :font_weight, :font, :font_variant, :emphasis, :kerning
7
+ shoes_style(:stroke) { |val, _name| Shoes::Colors.to_rgb(val) }
8
+ shoes_style(:fill) { |val, _name| Shoes::Colors.to_rgb(val) }
9
+
10
+ shoes_style(:align) do |val|
11
+ unless ["left", "center", "right"].include?(val)
12
+ raise(Shoes::Errors::InvalidAttributeValueError, "Align must be one of left, center or right!")
13
+ end
14
+ val
15
+ end
16
+
17
+ Shoes::Drawable.drawable_default_styles[Shoes::Para][:size] = :para
7
18
 
8
19
  shoes_events # No Para-specific events yet
9
20
 
10
- # Initializes a new instance of the `Para` widget.
21
+ # Initializes a new instance of the `Para` drawable. There are different
22
+ # methods to instantiate slightly different styles of Para, such as
23
+ # `tagline`, `caption` and `subtitle`. These will always be different
24
+ # sizes, but may be generally styled differently for some display services.
11
25
  #
12
26
  # @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.
27
+ # @param kwargs [Hash] the various Shoes styles for this paragraph.
18
28
  #
19
29
  # @example
20
30
  # Shoes.app do
21
- # p = para "Hello, This is at the top!", stroke: "red", size: :title, font: "Arial"
31
+ # p = para "Hello, This is at the top!", stroke: red, size: :title, font: "Arial"
22
32
  #
23
33
  # banner("Welcome to Shoes!")
24
34
  # title("Shoes Examples")
@@ -29,22 +39,60 @@ class Shoes
29
39
  #
30
40
  # p.replace "On top we'll switch to ", strong("bold"), "!"
31
41
  # end
32
- def initialize(*args, stroke: nil, size: :para, font: nil, **html_attributes)
33
- super
42
+
43
+ def initialize(*args, **kwargs)
44
+
45
+ if kwargs[:font]
46
+ arr= parse_font(kwargs[:font])
47
+
48
+ if arr[0] != nil
49
+
50
+ kwargs[:emphasis] = arr[0]
51
+
52
+ end
53
+
54
+ if arr[1] != nil
55
+
56
+ kwargs[:font_variant] = arr[1]
57
+
58
+ end
59
+
60
+ if arr[2] != nil
61
+
62
+ kwargs[:font_weight] = arr[2]
63
+
64
+ end
65
+
66
+ if arr[3] != nil
67
+
68
+ kwargs[:size] = arr[3]
69
+
70
+ end
34
71
 
72
+ if arr[4] != ""
73
+
74
+ kwargs[:family] = arr[4]
75
+
76
+ end
77
+
78
+ end
79
+
80
+ # Don't pass text_children args to Drawable#initialize
81
+ super(*[], **kwargs)
82
+
35
83
  # Text_children alternates strings and TextDrawables, so we can't just pass
36
84
  # it as a Shoes style. It won't serialize.
37
85
  update_text_children(args)
38
86
 
39
- @html_attributes = html_attributes || {}
40
-
41
87
  create_display_drawable
42
88
  end
43
89
 
90
+
91
+
44
92
  private
45
93
 
46
94
  def text_children_to_items(text_children)
47
- text_children.map { |arg| arg.is_a?(String) ? arg : arg.linkable_id }
95
+ text_children.map { |arg| arg.is_a?(TextDrawable) ? arg.linkable_id : arg.to_s }
48
96
  end
49
97
 
50
98
  public
@@ -67,10 +115,20 @@ class Shoes
67
115
  update_text_children(children)
68
116
  end
69
117
 
118
+ # Return the text, but not the styling, of the para's
119
+ # contents. For example, if the contents had strong
120
+ # and emphasized text, the bold and emphasized would
121
+ # be removed but the text would be returned.
122
+ #
123
+ # @return [String] the text from this para
70
124
  def text
71
125
  @text_children.map(&:to_s).join
72
126
  end
73
127
 
128
+ # Return the text but not styling from the para. This
129
+ # is the same as #text.
130
+ #
131
+ # @return [String] the text from this para
74
132
  def to_s
75
133
  self.text
76
134
  end
@@ -84,35 +142,65 @@ class Shoes
84
142
  # This should signal the display drawable to change
85
143
  self.text_items = text_children_to_items(@text_children)
86
144
  end
145
+
146
+
87
147
  end
88
148
  end
89
149
 
90
150
  class Shoes
91
151
  class Drawable
152
+ # Return a banner-sized para. This can use all the normal
153
+ # Para styles and arguments. See {Para#initialize} for
154
+ # details.
155
+ #
156
+ # @return [Shoes::Para] the new para drawable
92
157
  def banner(*args, **kwargs)
93
158
  para(*args, **{ size: :banner }.merge(kwargs))
94
159
  end
95
160
 
161
+ # Return a title-sized para. This can use all the normal
162
+ # Para styles and arguments. See {Para#initialize} for
163
+ # details.
164
+ #
165
+ # @return [Shoes::Para] the new para drawable
96
166
  def title(*args, **kwargs)
97
167
  para(*args, **{ size: :title }.merge(kwargs))
98
168
  end
99
169
 
170
+ # Return a subtitle-sized para. This can use all the normal
171
+ # Para styles and arguments. See {Para#initialize} for
172
+ # details.
173
+ #
174
+ # @return [Shoes::Para] the new para drawable
100
175
  def subtitle(*args, **kwargs)
101
176
  para(*args, **{ size: :subtitle }.merge(kwargs))
102
177
  end
103
178
 
179
+ # Return a tagline-sized para. This can use all the normal
180
+ # Para styles and arguments. See {Para#initialize} for
181
+ # details.
182
+ #
183
+ # @return [Shoes::Para] the new para drawable
104
184
  def tagline(*args, **kwargs)
105
185
  para(*args, **{ size: :tagline }.merge(kwargs))
106
186
  end
107
187
 
188
+ # Return a caption-sized para. This can use all the normal
189
+ # Para styles and arguments. See {Para#initialize} for
190
+ # details.
191
+ #
192
+ # @return [Shoes::Para] the new para drawable
108
193
  def caption(*args, **kwargs)
109
194
  para(*args, **{ size: :caption }.merge(kwargs))
110
195
  end
111
196
 
197
+ # Return an inscription-sized para. This can use all the normal
198
+ # Para styles and arguments. See {Para#initialize} for
199
+ # details.
200
+ #
201
+ # @return [Shoes::Para] the new para drawable
112
202
  def inscription(*args, **kwargs)
113
203
  para(*args, **{ size: :inscription }.merge(kwargs))
114
204
  end
115
-
116
- alias_method :ins, :inscription
117
205
  end
118
206
  end
@@ -5,7 +5,8 @@ class Shoes
5
5
  shoes_styles :fraction
6
6
  shoes_events # No Progress-specific events yet
7
7
 
8
- def initialize(fraction: nil)
8
+ init_args # No positional args
9
+ def initialize(**kwargs)
9
10
  super
10
11
 
11
12
  create_display_drawable
@@ -8,11 +8,13 @@ class Shoes
8
8
  shoes_styles :group, :checked
9
9
  shoes_events :click
10
10
 
11
- def initialize(group = nil, checked: nil, &block)
12
- super
13
- @group = group
11
+ init_args
12
+ opt_init_args :group
13
+ def initialize(*args, **kwargs, &block)
14
14
  @block = block
15
15
 
16
+ super
17
+
16
18
  bind_self_event("click") { click }
17
19
  create_display_drawable
18
20
  end
@@ -2,14 +2,15 @@
2
2
 
3
3
  class Shoes
4
4
  class Rect < Shoes::Drawable
5
- shoes_styles :left, :top, :width, :height, :draw_context, :curve
6
- shoes_events # No Rect-specific events yet
5
+ shoes_styles :draw_context, :curve, :stroke, :fill
6
+ shoes_events # No Rect-specific events
7
7
 
8
- def initialize(*args)
8
+ init_args :left, :top, :width, :height
9
+ opt_init_args :curve
10
+ def initialize(*args, **kwargs)
9
11
  @draw_context = Shoes::App.instance.current_draw_context
10
12
 
11
13
  super
12
- self.left, self.top, self.width, self.height, self.curve = args
13
14
 
14
15
  create_display_drawable
15
16
  end
@@ -13,7 +13,8 @@ class Shoes
13
13
  shoes_styles :left, :top, :shape_commands, :draw_context
14
14
  shoes_events # No Shape-specific events yet
15
15
 
16
- def initialize(left: nil, top: nil, &block)
16
+ init_args # No positional args
17
+ def initialize(**kwargs, &block)
17
18
  @shape_commands = []
18
19
  @draw_context = Shoes::App.instance.current_draw_context
19
20
 
@@ -1,10 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Shoes::Slot < Shoes::Drawable
4
- # @incompatibility Shoes uses #content, not #children, for this
4
+ # @incompatibility Shoes uses #content, not #children, for this. Scarpe does both.
5
5
  attr_reader :children
6
6
 
7
- shoes_events # No Slot-specific events yet
7
+ shoes_events # No Slot-specific events
8
+
9
+ # This only shows this specific slot's settings, not its parent's.
10
+ # Use current_draw_context to allow inheritance.
11
+ attr_reader :draw_context
12
+
13
+
14
+ def initialize(...)
15
+ # The draw context tracks current settings like fill and stroke,
16
+ # plus potentially other current state that changes from drawable
17
+ # to drawable and slot to slot.
18
+ @draw_context = {
19
+ "fill" => nil,
20
+ "stroke" => nil,
21
+ "strokewidth" => nil,
22
+ "rotate" => nil,
23
+ # "transform" => nil, # "corner",
24
+ # "translate" => nil, # [0, 0],
25
+ }
26
+
27
+ super
28
+ end
8
29
 
9
30
  # Do not call directly, use set_parent
10
31
  def remove_child(child)
@@ -29,30 +50,99 @@ class Shoes::Slot < Shoes::Drawable
29
50
 
30
51
  # We use method_missing for drawable-creating methods like "button".
31
52
  # The parent's method_missing will auto-create Shoes style getters and setters.
53
+ # This is similar to the method_missing in Shoes::App, but differs in where
54
+ # the new drawable will appear.
32
55
  def method_missing(name, *args, **kwargs, &block)
33
56
  klass = ::Shoes::Drawable.drawable_class_by_name(name)
34
57
  return super unless klass
35
58
 
36
59
  ::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)
60
+ instance = nil
39
61
 
40
- unless klass.ancestors.include?(::Shoes::TextDrawable)
41
- drawable_instance.set_parent self # Create drawable in THIS SLOT, not current app slot
62
+ # Look up the Shoes drawable and create it. But first set
63
+ # this slot as the current one so that draw context
64
+ # is handled properly.
65
+ Shoes::App.instance.with_slot(self) do
66
+ instance = klass.new(*args, **kwargs, &block)
42
67
  end
43
68
 
44
- drawable_instance
69
+ instance
45
70
  end
46
71
 
47
72
  send(name, *args, **kwargs, &block)
48
73
  end
49
74
 
50
75
  def respond_to_missing?(name, include_private = false)
51
- return true if Drawable.drawable_class_by_name(name.to_s)
76
+ return true if ::Shoes::Drawable.drawable_class_by_name(name.to_s)
52
77
 
53
78
  false
54
79
  end
55
80
 
81
+ # Draw context methods
82
+
83
+ # Set the default fill color in this slot and child slots.
84
+ # Pass nil for "no setting", so that it can inherit defaults.
85
+ #
86
+ # @param color [Nil,Color] a Shoes color for the fill color or nil to use parent setting
87
+ # @return [void]
88
+ def fill(color)
89
+ @draw_context["fill"] = color
90
+ end
91
+
92
+ # Set the default fill in this slot and child slots to transparent.
93
+ #
94
+ # @return [void]
95
+ def nofill
96
+ @draw_context["fill"] = rgb(0, 0, 0, 0)
97
+ end
98
+
99
+ # Set the default stroke color in this slot and child slots.
100
+ # Pass nil for "no setting" so it can inherit defaults.
101
+ #
102
+ # @param color [Nil,Color] a Shoes color for the stroke color or nil to use parent setting
103
+ # @return [void]
104
+ def stroke(color)
105
+ @draw_context["stroke"] = color
106
+ end
107
+
108
+ # Set the default strokewidth in this slot and child slots.
109
+ # Pass nil for "no setting".
110
+ #
111
+ # @param width [Numeric,Nil] the new width, or nil to use parent setting
112
+ # @return [void]
113
+ def strokewidth(width)
114
+ @draw_context["strokewidth"] = width
115
+ end
116
+
117
+ # Set the default stroke in this slot and child slots
118
+ # to transparent.
119
+ #
120
+ # @return [void]
121
+ def nostroke
122
+ @draw_context["stroke"] = rgb(0, 0, 0, 0)
123
+ end
124
+
125
+ # Set the current rotation in this slot and any child slots.
126
+ # Pass nil to reset the angle to default.
127
+ #
128
+ # @param angle [Numeric,Nil] the new default rotation for shapes or nil to use parent setting
129
+ # @return [void]
130
+ def rotate(angle)
131
+ @draw_context["rotate"] = angle
132
+ end
133
+
134
+ # Get the current draw context styles, based on this slot and its parent slots.
135
+ #
136
+ # @return [Hash] a hash of Shoes styles for the context
137
+ def current_draw_context
138
+ s = @parent ? @parent.current_draw_context : {}
139
+ @draw_context.each { |k, v| s[k] = v unless v.nil? }
140
+
141
+ s
142
+ end
143
+
144
+ # Methods to add or remove children
145
+
56
146
  # Remove all children from this drawable. If a block
57
147
  # is given, call the block to replace the children with
58
148
  # new contents from that block.
@@ -65,6 +155,7 @@ class Shoes::Slot < Shoes::Drawable
65
155
  # @yield The block to call to replace the contents of the drawable (optional)
66
156
  # @return [void]
67
157
  def clear(&block)
158
+ @children ||= []
68
159
  @children.dup.each(&:destroy)
69
160
  append(&block) if block_given?
70
161
  nil