lacci 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lacci/scarpe_cli.rb +0 -1
- data/lib/lacci/version.rb +1 -1
- data/lib/scarpe/niente/display_service.rb +5 -1
- data/lib/scarpe/niente/drawable.rb +2 -0
- data/lib/scarpe/niente/shoes_spec.rb +7 -1
- data/lib/scarpe/niente.rb +14 -2
- data/lib/shoes/app.rb +44 -50
- data/lib/shoes/constants.rb +23 -2
- data/lib/shoes/display_service.rb +43 -4
- data/lib/shoes/drawable.rb +309 -35
- data/lib/shoes/drawables/arc.rb +2 -24
- data/lib/shoes/drawables/arrow.rb +2 -22
- data/lib/shoes/drawables/border.rb +28 -0
- data/lib/shoes/drawables/button.rb +4 -20
- data/lib/shoes/drawables/check.rb +7 -3
- data/lib/shoes/drawables/document_root.rb +4 -4
- data/lib/shoes/drawables/edit_box.rb +6 -5
- data/lib/shoes/drawables/edit_line.rb +5 -4
- data/lib/shoes/drawables/flow.rb +3 -5
- data/lib/shoes/drawables/font_helper.rb +62 -0
- data/lib/shoes/drawables/image.rb +2 -2
- data/lib/shoes/drawables/line.rb +4 -7
- data/lib/shoes/drawables/link.rb +5 -8
- data/lib/shoes/drawables/list_box.rb +8 -5
- data/lib/shoes/drawables/oval.rb +48 -0
- data/lib/shoes/drawables/para.rb +106 -18
- data/lib/shoes/drawables/progress.rb +2 -1
- data/lib/shoes/drawables/radio.rb +5 -3
- data/lib/shoes/drawables/rect.rb +5 -4
- data/lib/shoes/drawables/shape.rb +2 -1
- data/lib/shoes/drawables/slot.rb +99 -8
- data/lib/shoes/drawables/stack.rb +6 -11
- data/lib/shoes/drawables/star.rb +8 -30
- data/lib/shoes/drawables/text_drawable.rb +93 -34
- data/lib/shoes/drawables/video.rb +3 -2
- data/lib/shoes/drawables/widget.rb +8 -3
- data/lib/shoes/drawables.rb +2 -1
- data/lib/shoes/errors.rb +13 -3
- data/lib/shoes/margin_helper.rb +79 -0
- data/lib/shoes.rb +4 -3
- metadata +11 -11
- data/lib/scarpe/niente/logger.rb +0 -29
- data/lib/shoes/drawables/span.rb +0 -27
- 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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
9
|
-
|
8
|
+
init_args
|
9
|
+
opt_init_args :text
|
10
|
+
def initialize(*args, **kwargs, &block)
|
10
11
|
@block = block
|
11
|
-
|
12
|
+
super
|
12
13
|
|
13
14
|
bind_self_event("change") do |new_text|
|
14
15
|
self.text = new_text
|
data/lib/shoes/drawables/flow.rb
CHANGED
@@ -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
|
-
|
7
|
+
Shoes::Drawable.drawable_default_styles[Shoes::Flow][:width] = "100%"
|
8
|
+
|
10
9
|
shoes_events
|
11
10
|
|
12
|
-
def initialize(
|
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
|
-
|
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
|
data/lib/shoes/drawables/line.rb
CHANGED
@@ -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
|
-
|
9
|
-
|
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
|
data/lib/shoes/drawables/link.rb
CHANGED
@@ -5,22 +5,19 @@ class Shoes
|
|
5
5
|
shoes_styles :text, :click, :has_block
|
6
6
|
shoes_events :click
|
7
7
|
|
8
|
-
|
9
|
-
super
|
8
|
+
#Shoes::Drawable.drawable_default_styles[Shoes::Link][:click] = "#"
|
10
9
|
|
11
|
-
|
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
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@
|
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
|
data/lib/shoes/drawables/para.rb
CHANGED
@@ -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
|
-
|
6
|
-
|
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`
|
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
|
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:
|
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
|
-
|
33
|
-
|
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?(
|
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
|
@@ -8,11 +8,13 @@ class Shoes
|
|
8
8
|
shoes_styles :group, :checked
|
9
9
|
shoes_events :click
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
data/lib/shoes/drawables/rect.rb
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
|
3
3
|
class Shoes
|
4
4
|
class Rect < Shoes::Drawable
|
5
|
-
shoes_styles :
|
6
|
-
shoes_events # No Rect-specific events
|
5
|
+
shoes_styles :draw_context, :curve, :stroke, :fill
|
6
|
+
shoes_events # No Rect-specific events
|
7
7
|
|
8
|
-
|
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
|
-
|
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
|
|
data/lib/shoes/drawables/slot.rb
CHANGED
@@ -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
|
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
|
-
|
38
|
-
drawable_instance = klass.new(*args, **kwargs, &block)
|
60
|
+
instance = nil
|
39
61
|
|
40
|
-
|
41
|
-
|
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
|
-
|
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
|