whirled_peas 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +111 -73
- data/Rakefile +37 -3
- data/bin/debug +35 -0
- data/lib/whirled_peas.rb +9 -7
- data/lib/whirled_peas/command_line.rb +25 -32
- data/lib/whirled_peas/debugger.rb +80 -0
- data/lib/whirled_peas/errors.rb +2 -0
- data/lib/whirled_peas/frame.rb +0 -1
- data/lib/whirled_peas/frame/consumer.rb +30 -0
- data/lib/whirled_peas/frame/debug_consumer.rb +30 -0
- data/lib/whirled_peas/frame/event_loop.rb +29 -30
- data/lib/whirled_peas/frame/producer.rb +11 -5
- data/lib/whirled_peas/graphics.rb +5 -0
- data/lib/whirled_peas/graphics/box_painter.rb +100 -0
- data/lib/whirled_peas/graphics/canvas.rb +107 -0
- data/lib/whirled_peas/graphics/container_coords.rb +61 -0
- data/lib/whirled_peas/graphics/container_dimensions.rb +65 -0
- data/lib/whirled_peas/graphics/container_painter.rb +116 -0
- data/lib/whirled_peas/graphics/debugger.rb +43 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +56 -0
- data/lib/whirled_peas/graphics/mock_screen.rb +26 -0
- data/lib/whirled_peas/graphics/painter.rb +24 -0
- data/lib/whirled_peas/graphics/renderer.rb +49 -0
- data/lib/whirled_peas/graphics/screen.rb +65 -0
- data/lib/whirled_peas/graphics/text_dimensions.rb +15 -0
- data/lib/whirled_peas/graphics/text_painter.rb +38 -0
- data/lib/whirled_peas/settings.rb +5 -0
- data/lib/whirled_peas/settings/bg_color.rb +22 -0
- data/lib/whirled_peas/settings/border.rb +101 -0
- data/lib/whirled_peas/settings/box_settings.rb +8 -0
- data/lib/whirled_peas/{utils → settings}/color.rb +3 -35
- data/lib/whirled_peas/settings/container_settings.rb +128 -0
- data/lib/whirled_peas/settings/debugger.rb +87 -0
- data/lib/whirled_peas/settings/display_flow.rb +25 -0
- data/lib/whirled_peas/settings/element_settings.rb +61 -0
- data/lib/whirled_peas/settings/grid_settings.rb +11 -0
- data/lib/whirled_peas/settings/margin.rb +8 -0
- data/lib/whirled_peas/settings/padding.rb +8 -0
- data/lib/whirled_peas/settings/position.rb +15 -0
- data/lib/whirled_peas/settings/spacing.rb +24 -0
- data/lib/whirled_peas/settings/text_align.rb +19 -0
- data/lib/whirled_peas/settings/text_color.rb +19 -0
- data/lib/whirled_peas/settings/text_settings.rb +15 -0
- data/lib/whirled_peas/template/box_element.rb +8 -0
- data/lib/whirled_peas/template/composer.rb +68 -0
- data/lib/whirled_peas/template/container.rb +28 -0
- data/lib/whirled_peas/template/debugger.rb +34 -0
- data/lib/whirled_peas/template/element.rb +1 -218
- data/lib/whirled_peas/template/grid_element.rb +8 -0
- data/lib/whirled_peas/template/text_element.rb +24 -0
- data/lib/whirled_peas/utils/ansi.rb +6 -56
- data/lib/whirled_peas/utils/formatted_string.rb +64 -0
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/rendered/elements/box.frame +1 -0
- data/screen_test/rendered/elements/box.rb +20 -0
- data/screen_test/rendered/elements/grid.frame +1 -0
- data/screen_test/rendered/elements/grid.rb +13 -0
- data/screen_test/rendered/elements/screen_overflow.rb +9 -0
- data/screen_test/rendered/elements/text.frame +1 -0
- data/screen_test/rendered/elements/text.rb +9 -0
- data/screen_test/rendered/elements/text_multiline.frame +1 -0
- data/screen_test/rendered/elements/text_multiline.rb +9 -0
- data/screen_test/rendered/settings/align/box.frame +1 -0
- data/screen_test/rendered/settings/align/box.rb +20 -0
- data/screen_test/rendered/settings/align/children_center.frame +1 -0
- data/screen_test/rendered/settings/align/children_center.rb +13 -0
- data/screen_test/rendered/settings/align/children_left.frame +1 -0
- data/screen_test/rendered/settings/align/children_left.rb +13 -0
- data/screen_test/rendered/settings/align/children_right.frame +1 -0
- data/screen_test/rendered/settings/align/children_right.rb +13 -0
- data/screen_test/rendered/settings/align/grid.frame +1 -0
- data/screen_test/rendered/settings/align/grid.rb +20 -0
- data/screen_test/rendered/settings/ansi/bold.frame +1 -0
- data/screen_test/rendered/settings/ansi/bold.rb +15 -0
- data/screen_test/rendered/settings/ansi/color.frame +1 -0
- data/screen_test/rendered/settings/ansi/color.rb +37 -0
- data/screen_test/rendered/settings/ansi/underline.frame +1 -0
- data/screen_test/rendered/settings/ansi/underline.rb +15 -0
- data/screen_test/rendered/settings/border.frame +1 -0
- data/screen_test/rendered/settings/border.rb +13 -0
- data/screen_test/rendered/settings/flow/l2r.frame +1 -0
- data/screen_test/rendered/settings/flow/l2r.rb +24 -0
- data/screen_test/rendered/settings/flow/t2b.frame +1 -0
- data/screen_test/rendered/settings/flow/t2b.rb +24 -0
- data/screen_test/rendered/settings/height/box.frame +1 -0
- data/screen_test/rendered/settings/height/box.rb +13 -0
- data/screen_test/rendered/settings/height/grid.frame +1 -0
- data/screen_test/rendered/settings/height/grid.rb +14 -0
- data/screen_test/rendered/settings/height/overflow_box.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box.rb +13 -0
- data/screen_test/rendered/settings/height/overflow_box_l2r.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box_l2r.rb +15 -0
- data/screen_test/rendered/settings/height/overflow_box_t2b.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_box_t2b.rb +14 -0
- data/screen_test/rendered/settings/height/overflow_grid.frame +1 -0
- data/screen_test/rendered/settings/height/overflow_grid.rb +16 -0
- data/screen_test/rendered/settings/margin.frame +1 -0
- data/screen_test/rendered/settings/margin.rb +14 -0
- data/screen_test/rendered/settings/padding.frame +1 -0
- data/screen_test/rendered/settings/padding.rb +11 -0
- data/screen_test/rendered/settings/position/box_left.frame +1 -0
- data/screen_test/rendered/settings/position/box_left.rb +17 -0
- data/screen_test/rendered/settings/position/box_left_negative.frame +1 -0
- data/screen_test/rendered/settings/position/box_left_negative.rb +17 -0
- data/screen_test/rendered/settings/position/box_top.frame +1 -0
- data/screen_test/rendered/settings/position/box_top.rb +17 -0
- data/screen_test/rendered/settings/position/box_top_negative.frame +1 -0
- data/screen_test/rendered/settings/position/box_top_negative.rb +17 -0
- data/screen_test/rendered/settings/position/grid_left.frame +1 -0
- data/screen_test/rendered/settings/position/grid_left.rb +18 -0
- data/screen_test/rendered/settings/position/grid_left_negative.frame +1 -0
- data/screen_test/rendered/settings/position/grid_left_negative.rb +18 -0
- data/screen_test/rendered/settings/position/grid_top.frame +1 -0
- data/screen_test/rendered/settings/position/grid_top.rb +18 -0
- data/screen_test/rendered/settings/position/grid_top_negative.frame +1 -0
- data/screen_test/rendered/settings/position/grid_top_negative.rb +18 -0
- data/screen_test/rendered/settings/title_font.frame +1 -0
- data/screen_test/rendered/settings/title_font.rb +12 -0
- data/screen_test/rendered/settings/width/box.frame +1 -0
- data/screen_test/rendered/settings/width/box.rb +13 -0
- data/screen_test/rendered/settings/width/grid.frame +1 -0
- data/screen_test/rendered/settings/width/grid.rb +14 -0
- data/screen_test/rendered/settings/width/overflow_box.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box.rb +11 -0
- data/screen_test/rendered/settings/width/overflow_box_l2r.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box_l2r.rb +14 -0
- data/screen_test/rendered/settings/width/overflow_box_t2b.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_box_t2b.rb +15 -0
- data/screen_test/rendered/settings/width/overflow_grid.frame +1 -0
- data/screen_test/rendered/settings/width/overflow_grid.rb +14 -0
- data/screen_test/screen_tester.rb +191 -0
- metadata +122 -10
- data/bin/title_fonts +0 -6
- data/lib/whirled_peas/frame/print_consumer.rb +0 -33
- data/lib/whirled_peas/template/settings.rb +0 -530
- data/lib/whirled_peas/ui.rb +0 -5
- data/lib/whirled_peas/ui/canvas.rb +0 -68
- data/lib/whirled_peas/ui/painter.rb +0 -287
- data/lib/whirled_peas/ui/screen.rb +0 -63
@@ -1,13 +1,6 @@
|
|
1
|
-
require_relative '../utils/title_font'
|
2
|
-
|
3
|
-
require_relative 'settings'
|
4
|
-
|
5
1
|
module WhirledPeas
|
6
|
-
module
|
7
|
-
STRINGALBE_CLASSES = [FalseClass, Float, Integer, NilClass, String, Symbol, TrueClass]
|
8
|
-
|
2
|
+
module Template
|
9
3
|
class Element
|
10
|
-
attr_accessor :preferred_width, :preferred_height
|
11
4
|
attr_reader :name, :settings
|
12
5
|
|
13
6
|
def initialize(name, settings)
|
@@ -16,215 +9,5 @@ module WhirledPeas
|
|
16
9
|
end
|
17
10
|
end
|
18
11
|
private_constant :Element
|
19
|
-
|
20
|
-
class TextElement < Element
|
21
|
-
attr_reader :lines
|
22
|
-
|
23
|
-
def initialize(name, settings)
|
24
|
-
super(name, TextSettings.merge(settings))
|
25
|
-
end
|
26
|
-
|
27
|
-
def lines=(val)
|
28
|
-
unless STRINGALBE_CLASSES.include?(val.class)
|
29
|
-
raise ArgmentError, "Unsupported type for TextElement: #{val.class}"
|
30
|
-
end
|
31
|
-
if settings.title_font
|
32
|
-
@lines = Utils::TitleFont.to_s(val.to_s, settings.title_font).split("\n")
|
33
|
-
else
|
34
|
-
@lines = [val.to_s]
|
35
|
-
end
|
36
|
-
@preferred_width = settings.width || @lines.first.length
|
37
|
-
@preferred_height = @lines.length
|
38
|
-
end
|
39
|
-
|
40
|
-
def inspect(indent='')
|
41
|
-
dims = unless preferred_width.nil?
|
42
|
-
"#{indent + ' '}- Dimensions: #{preferred_width}x#{preferred_height}"
|
43
|
-
end
|
44
|
-
[
|
45
|
-
"#{indent}+ #{name} [#{self.class.name}]",
|
46
|
-
dims,
|
47
|
-
"#{indent + ' '}- Settings",
|
48
|
-
settings.inspect(indent + ' ')
|
49
|
-
].compact.join("\n")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
class ComposableElement < Element
|
54
|
-
class << self
|
55
|
-
def next_name
|
56
|
-
@counter ||= 0
|
57
|
-
@counter += 1
|
58
|
-
"Element-#{@counter}"
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def initialize(name, settings)
|
63
|
-
super
|
64
|
-
end
|
65
|
-
|
66
|
-
def children
|
67
|
-
@children ||= []
|
68
|
-
end
|
69
|
-
|
70
|
-
def add_text(name=self.class.next_name, &block)
|
71
|
-
element = TextElement.new(name, settings)
|
72
|
-
element.lines = yield nil, element.settings
|
73
|
-
children << element
|
74
|
-
end
|
75
|
-
|
76
|
-
def add_box(name=self.class.next_name, &block)
|
77
|
-
element = BoxElement.new(name, settings)
|
78
|
-
value = yield element, element.settings
|
79
|
-
children << element
|
80
|
-
if element.children.empty? && STRINGALBE_CLASSES.include?(value.class)
|
81
|
-
element.add_text { value.to_s }
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def add_grid(name=self.class.next_name, &block)
|
86
|
-
element = GridElement.new(name, settings)
|
87
|
-
values = yield element, element.settings
|
88
|
-
children << element
|
89
|
-
if element.children.empty? && values.is_a?(Array)
|
90
|
-
values.each { |v| element.add_text { v.to_s } }
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def inspect(indent='')
|
95
|
-
kids = children.map { |c| c.inspect(indent + ' ') }.join("\n")
|
96
|
-
dims = unless preferred_width.nil?
|
97
|
-
"#{indent + ' '}- Dimensions: #{preferred_width}x#{preferred_height}"
|
98
|
-
end
|
99
|
-
[
|
100
|
-
"#{indent}+ #{name} [#{self.class.name}]",
|
101
|
-
dims,
|
102
|
-
"#{indent + ' '}- Settings",
|
103
|
-
settings.inspect(indent + ' '),
|
104
|
-
"#{indent + ' '}- Children",
|
105
|
-
kids
|
106
|
-
].compact.join("\n")
|
107
|
-
end
|
108
|
-
|
109
|
-
private
|
110
|
-
|
111
|
-
def margin_width
|
112
|
-
settings.margin.left + settings.margin.right
|
113
|
-
end
|
114
|
-
|
115
|
-
def margin_height
|
116
|
-
settings.margin.top + settings.margin.bottom
|
117
|
-
end
|
118
|
-
|
119
|
-
def outer_border_width
|
120
|
-
(settings.border.left? ? 1 : 0) + (settings.border.right? ? 1 : 0)
|
121
|
-
end
|
122
|
-
|
123
|
-
def outer_border_height
|
124
|
-
(settings.border.top? ? 1 : 0) + (settings.border.bottom? ? 1 : 0)
|
125
|
-
end
|
126
|
-
|
127
|
-
def inner_border_width
|
128
|
-
settings.border.inner_vert? ? 1 : 0
|
129
|
-
end
|
130
|
-
|
131
|
-
def inner_border_height
|
132
|
-
settings.border.inner_horiz? ? 1 : 0
|
133
|
-
end
|
134
|
-
|
135
|
-
def padding_width
|
136
|
-
settings.padding.left + settings.padding.right
|
137
|
-
end
|
138
|
-
|
139
|
-
def padding_height
|
140
|
-
settings.padding.top + settings.padding.bottom
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
class Template < ComposableElement
|
145
|
-
def initialize(settings=TemplateSettings.new)
|
146
|
-
super('TEMPLATE', settings)
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
class BoxElement < ComposableElement
|
151
|
-
attr_writer :content_width, :content_height
|
152
|
-
|
153
|
-
def initialize(name, settings)
|
154
|
-
super(name, BoxSettings.merge(settings))
|
155
|
-
end
|
156
|
-
|
157
|
-
def self.from_template(template, width, height)
|
158
|
-
box = new(template.name, template.settings)
|
159
|
-
template.children.each { |c| box.children << c }
|
160
|
-
box.content_width = box.preferred_width = width
|
161
|
-
box.content_height = box.preferred_height = height
|
162
|
-
box
|
163
|
-
end
|
164
|
-
|
165
|
-
def content_width
|
166
|
-
@content_width ||= begin
|
167
|
-
child_widths = children.map(&:preferred_width)
|
168
|
-
width = settings.horizontal_flow? ? child_widths.sum : (child_widths.max || 0)
|
169
|
-
[width, *settings.width].max
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def preferred_width
|
174
|
-
@preferred_width ||=
|
175
|
-
margin_width + outer_border_width + padding_width + content_width
|
176
|
-
end
|
177
|
-
|
178
|
-
def content_height
|
179
|
-
@content_height ||= begin
|
180
|
-
child_heights = children.map(&:preferred_height)
|
181
|
-
settings.vertical_flow? ? child_heights.sum : (child_heights.max || 0)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def preferred_height
|
186
|
-
@preferred_height ||=
|
187
|
-
margin_height + outer_border_height + padding_height + content_height
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
class GridElement < ComposableElement
|
192
|
-
def initialize(name, settings)
|
193
|
-
super(name, GridSettings.merge(settings))
|
194
|
-
end
|
195
|
-
|
196
|
-
def col_width
|
197
|
-
return @col_width if @col_width
|
198
|
-
@col_width = 0
|
199
|
-
children.each do |child|
|
200
|
-
@col_width = child.preferred_width if child.preferred_width > @col_width
|
201
|
-
end
|
202
|
-
@col_width
|
203
|
-
end
|
204
|
-
|
205
|
-
def row_height
|
206
|
-
return @row_height if @row_height
|
207
|
-
@row_height = 0
|
208
|
-
children.each do |child|
|
209
|
-
@row_height = child.preferred_height if child.preferred_height > @row_height
|
210
|
-
end
|
211
|
-
@row_height
|
212
|
-
end
|
213
|
-
|
214
|
-
def preferred_width
|
215
|
-
margin_width +
|
216
|
-
outer_border_width +
|
217
|
-
settings.num_cols * (padding_width + col_width) +
|
218
|
-
(settings.num_cols - 1) * inner_border_width
|
219
|
-
end
|
220
|
-
|
221
|
-
def preferred_height
|
222
|
-
num_rows = (children.length / settings.num_cols).ceil
|
223
|
-
margin_height +
|
224
|
-
outer_border_height +
|
225
|
-
num_rows * (padding_height + row_height) +
|
226
|
-
(num_rows - 1) * inner_border_height
|
227
|
-
end
|
228
|
-
end
|
229
12
|
end
|
230
13
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'element'
|
2
|
+
|
3
|
+
module WhirledPeas
|
4
|
+
module Template
|
5
|
+
class TextElement < Element
|
6
|
+
# List of classes that convert nicely to a string
|
7
|
+
STRINGALBE_CLASSES = [FalseClass, Float, Integer, NilClass, String, Symbol, TrueClass]
|
8
|
+
private_constant :STRINGALBE_CLASSES
|
9
|
+
|
10
|
+
def self.stringable?(value)
|
11
|
+
STRINGALBE_CLASSES.include?(value.class)
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :content
|
15
|
+
|
16
|
+
def content=(val)
|
17
|
+
unless self.class.stringable?(val)
|
18
|
+
raise ArgumentError, "Unsupported type for TextElement: #{val.class}"
|
19
|
+
end
|
20
|
+
@content = val.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module WhirledPeas
|
2
|
-
module
|
2
|
+
module Utils
|
3
3
|
# Helper module for working with ANSI escape codes. The most useful ANSI escape codes
|
4
4
|
# relate to text formatting.
|
5
5
|
#
|
@@ -7,6 +7,9 @@ module WhirledPeas
|
|
7
7
|
module Ansi
|
8
8
|
ESC = "\033"
|
9
9
|
|
10
|
+
END_FORMATTING = 0
|
11
|
+
private_constant :END_FORMATTING
|
12
|
+
|
10
13
|
# Text formatting constants
|
11
14
|
BOLD = 1
|
12
15
|
UNDERLINE = 4
|
@@ -21,8 +24,8 @@ module WhirledPeas
|
|
21
24
|
CYAN = 36
|
22
25
|
WHITE = 37
|
23
26
|
|
24
|
-
|
25
|
-
|
27
|
+
# Bright colors are offset by this much from their standard versions
|
28
|
+
BRIGHT_OFFSET = 60
|
26
29
|
|
27
30
|
class << self
|
28
31
|
def cursor_pos(top: 0, left: 0)
|
@@ -37,63 +40,10 @@ module WhirledPeas
|
|
37
40
|
"#{ESC}[J"
|
38
41
|
end
|
39
42
|
|
40
|
-
# Format the string with the ANSI escapes codes for the given integer codes
|
41
|
-
#
|
42
|
-
# @param str [String] the string to format
|
43
|
-
# @param codes [Array<Integer>] the integer part of the ANSI escape code (see
|
44
|
-
# constants in this module for codes and meanings)
|
45
|
-
def format(str, codes)
|
46
|
-
if str.empty? || codes.length == 0
|
47
|
-
str
|
48
|
-
else
|
49
|
-
start_formatting = codes.map(&method(:esc_seq)).join
|
50
|
-
"#{start_formatting}#{str}#{esc_seq(END_FORMATTING)}"
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
43
|
def clear
|
55
44
|
esc_seq(END_FORMATTING)
|
56
45
|
end
|
57
46
|
|
58
|
-
# If the string has unclosed formatting, add the end formatting characters to
|
59
|
-
# the end of the string
|
60
|
-
def close_formatting(str)
|
61
|
-
codes = str.scan(/#{ESC}\[(\d+)m/)
|
62
|
-
if codes.length > 0 && codes.last[0] != END_FORMATTING.to_s
|
63
|
-
"#{str}#{esc_seq(END_FORMATTING)}"
|
64
|
-
else
|
65
|
-
str
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Return a substring of the input string that preservse the formatting
|
70
|
-
#
|
71
|
-
# @param str [String] the (possibly formatted) string
|
72
|
-
# @param first_visible_character [Integer] the index of the first character to
|
73
|
-
# include in the substring (ignoring all hidden formatting characters)
|
74
|
-
# @param num_visible_chars [Integer] the maximum number of visible characters to
|
75
|
-
# include in the substring (ignoring all hidden formatting characters)
|
76
|
-
def substring(str, first_visible_character, num_visible_chars)
|
77
|
-
substr = ''
|
78
|
-
is_visible = true
|
79
|
-
visible_index = 0
|
80
|
-
substr_visible_len = 0
|
81
|
-
str.chars.each do |char|
|
82
|
-
in_substring = (visible_index >= first_visible_character)
|
83
|
-
is_visible = false if is_visible && char == ESC
|
84
|
-
visible_index += 1 if is_visible
|
85
|
-
if !is_visible || in_substring
|
86
|
-
substr += char
|
87
|
-
substr_visible_len += 1 if is_visible
|
88
|
-
end
|
89
|
-
is_visible = true if !is_visible && char == 'm'
|
90
|
-
break if substr_visible_len == num_visible_chars
|
91
|
-
end
|
92
|
-
close_formatting(substr)
|
93
|
-
end
|
94
|
-
|
95
|
-
private
|
96
|
-
|
97
47
|
def esc_seq(code)
|
98
48
|
"#{ESC}[#{code}m"
|
99
49
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative 'ansi'
|
2
|
+
|
3
|
+
module WhirledPeas
|
4
|
+
module Utils
|
5
|
+
class FormattedString
|
6
|
+
def self.blank
|
7
|
+
new('')
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(raw, formatting=nil)
|
11
|
+
@raw = raw
|
12
|
+
@formatting = [*formatting]
|
13
|
+
end
|
14
|
+
|
15
|
+
def length
|
16
|
+
raw.length
|
17
|
+
end
|
18
|
+
|
19
|
+
def [](index_or_range)
|
20
|
+
self.class.new(raw[index_or_range], foramtting)
|
21
|
+
end
|
22
|
+
|
23
|
+
def blank?
|
24
|
+
raw.empty?
|
25
|
+
end
|
26
|
+
|
27
|
+
def hash
|
28
|
+
[raw, formatting].hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def ==(other)
|
32
|
+
case other
|
33
|
+
when self.class
|
34
|
+
hash == other.hash
|
35
|
+
when String
|
36
|
+
formatting.empty? && raw == other
|
37
|
+
else
|
38
|
+
false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
if raw.empty? || formatting.length == 0
|
44
|
+
raw
|
45
|
+
else
|
46
|
+
start_formatting = formatting.map { |code| Ansi.esc_seq(code) }.join
|
47
|
+
"#{start_formatting}#{raw}#{Ansi.clear}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def inspect
|
52
|
+
if raw.empty? || formatting.length == 0
|
53
|
+
raw.inspect
|
54
|
+
else
|
55
|
+
"<#{formatting.join(', ')}>#{raw}<0>".inspect
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
attr_reader :raw, :formatting
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/lib/whirled_peas/version.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
[?25l[1;1H[J[1;1HTOP LEFT[2;1HBOTTOM LEFT[1;12H TOP RIGHT [2;12H BOTTOM RIGHT[0m[48;1H[?25h
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'whirled_peas'
|
2
|
+
|
3
|
+
class TemplateFactory
|
4
|
+
def build(*)
|
5
|
+
WhirledPeas.template do |composer|
|
6
|
+
composer.add_box('Container') do |composer, settings|
|
7
|
+
composer.add_box do |composer, settings|
|
8
|
+
settings.flow = :t2b
|
9
|
+
composer.add_box('TopLeft') { "TOP LEFT" }
|
10
|
+
composer.add_box('BottomLeft') { "BOTTOM LEFT" }
|
11
|
+
end
|
12
|
+
composer.add_box do |composer, settings|
|
13
|
+
settings.flow = :t2b
|
14
|
+
composer.add_box('TopRight') { " TOP RIGHT " }
|
15
|
+
composer.add_box('BottomRight') { " BOTTOM RIGHT" }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|