whirled_peas 0.4.0 → 0.7.1
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/.travis.yml +1 -0
- data/CHANGELOG.md +38 -0
- data/README.md +450 -103
- data/Rakefile +28 -3
- data/examples/intro.rb +52 -0
- data/examples/scrolling.rb +53 -0
- data/lib/whirled_peas.rb +4 -8
- data/lib/whirled_peas/command_line.rb +44 -55
- 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 +28 -29
- data/lib/whirled_peas/frame/producer.rb +11 -5
- data/lib/whirled_peas/graphics.rb +19 -0
- data/lib/whirled_peas/graphics/box_painter.rb +101 -0
- data/lib/whirled_peas/graphics/canvas.rb +118 -0
- data/lib/whirled_peas/graphics/composer.rb +80 -0
- data/lib/whirled_peas/graphics/container_coords.rb +72 -0
- data/lib/whirled_peas/graphics/container_dimensions.rb +93 -0
- data/lib/whirled_peas/graphics/container_painter.rb +272 -0
- data/lib/whirled_peas/graphics/debugger.rb +52 -0
- data/lib/whirled_peas/graphics/grid_painter.rb +69 -0
- data/lib/whirled_peas/graphics/mock_screen.rb +26 -0
- data/lib/whirled_peas/graphics/painter.rb +23 -0
- data/lib/whirled_peas/graphics/renderer.rb +26 -0
- data/lib/whirled_peas/graphics/screen.rb +70 -0
- data/lib/whirled_peas/graphics/text_dimensions.rb +15 -0
- data/lib/whirled_peas/graphics/text_painter.rb +40 -0
- data/lib/whirled_peas/settings.rb +5 -0
- data/lib/whirled_peas/settings/alignment.rb +24 -0
- data/lib/whirled_peas/settings/bg_color.rb +24 -0
- data/lib/whirled_peas/settings/border.rb +101 -0
- data/lib/whirled_peas/settings/box_settings.rb +8 -0
- data/lib/whirled_peas/settings/color.rb +68 -0
- data/lib/whirled_peas/settings/container_settings.rb +223 -0
- data/lib/whirled_peas/settings/debugger.rb +96 -0
- data/lib/whirled_peas/settings/display_flow.rb +27 -0
- data/lib/whirled_peas/settings/element_settings.rb +61 -0
- data/lib/whirled_peas/settings/grid_settings.rb +19 -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/scrollbar.rb +15 -0
- data/lib/whirled_peas/settings/sizing.rb +19 -0
- data/lib/whirled_peas/settings/spacing.rb +58 -0
- data/lib/whirled_peas/settings/text_color.rb +21 -0
- data/lib/whirled_peas/settings/text_settings.rb +15 -0
- data/lib/whirled_peas/settings/vert_alignment.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/utils/title_font.rb +1 -1
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/elements/box.frame +1 -0
- data/screen_test/elements/box.rb +20 -0
- data/screen_test/elements/grid.frame +1 -0
- data/screen_test/elements/grid.rb +13 -0
- data/screen_test/elements/screen_overflow_x.frame +1 -0
- data/screen_test/elements/screen_overflow_x.rb +9 -0
- data/screen_test/elements/screen_overflow_y.frame +1 -0
- data/screen_test/elements/screen_overflow_y.rb +9 -0
- data/screen_test/elements/text.frame +1 -0
- data/screen_test/elements/text.rb +9 -0
- data/screen_test/elements/text_multiline.frame +1 -0
- data/screen_test/elements/text_multiline.rb +9 -0
- data/screen_test/settings/align/box_around.frame +1 -0
- data/screen_test/settings/align/box_around.rb +16 -0
- data/screen_test/settings/align/box_between.frame +1 -0
- data/screen_test/settings/align/box_between.rb +16 -0
- data/screen_test/settings/align/box_center.frame +1 -0
- data/screen_test/settings/align/box_center.rb +21 -0
- data/screen_test/settings/align/box_default.frame +1 -0
- data/screen_test/settings/align/box_default.rb +20 -0
- data/screen_test/settings/align/box_evenly.frame +1 -0
- data/screen_test/settings/align/box_evenly.rb +16 -0
- data/screen_test/settings/align/box_left.frame +1 -0
- data/screen_test/settings/align/box_left.rb +21 -0
- data/screen_test/settings/align/box_right.frame +1 -0
- data/screen_test/settings/align/box_right.rb +21 -0
- data/screen_test/settings/align/children_center.frame +1 -0
- data/screen_test/settings/align/children_center.rb +15 -0
- data/screen_test/settings/align/children_left.frame +1 -0
- data/screen_test/settings/align/children_left.rb +15 -0
- data/screen_test/settings/align/children_right.frame +1 -0
- data/screen_test/settings/align/children_right.rb +15 -0
- data/screen_test/settings/align/grid_center.frame +1 -0
- data/screen_test/settings/align/grid_center.rb +18 -0
- data/screen_test/settings/align/grid_default.frame +1 -0
- data/screen_test/settings/align/grid_default.rb +17 -0
- data/screen_test/settings/align/grid_left.frame +1 -0
- data/screen_test/settings/align/grid_left.rb +18 -0
- data/screen_test/settings/align/grid_right.frame +1 -0
- data/screen_test/settings/align/grid_right.rb +18 -0
- data/screen_test/settings/ansi/bold.frame +1 -0
- data/screen_test/settings/ansi/bold.rb +14 -0
- data/screen_test/settings/ansi/color.frame +1 -0
- data/screen_test/settings/ansi/color.rb +37 -0
- data/screen_test/settings/ansi/underline.frame +1 -0
- data/screen_test/settings/ansi/underline.rb +14 -0
- data/screen_test/settings/border.frame +1 -0
- data/screen_test/settings/border.rb +13 -0
- data/screen_test/settings/flow/box_b2t.frame +1 -0
- data/screen_test/settings/flow/box_b2t.rb +26 -0
- data/screen_test/settings/flow/box_l2r.frame +1 -0
- data/screen_test/settings/flow/box_l2r.rb +26 -0
- data/screen_test/settings/flow/box_r2l.frame +1 -0
- data/screen_test/settings/flow/box_r2l.rb +26 -0
- data/screen_test/settings/flow/box_t2b.frame +1 -0
- data/screen_test/settings/flow/box_t2b.rb +26 -0
- data/screen_test/settings/flow/grid_b2t.frame +1 -0
- data/screen_test/settings/flow/grid_b2t.rb +14 -0
- data/screen_test/settings/flow/grid_l2r.frame +1 -0
- data/screen_test/settings/flow/grid_l2r.rb +14 -0
- data/screen_test/settings/flow/grid_r2l.frame +1 -0
- data/screen_test/settings/flow/grid_r2l.rb +14 -0
- data/screen_test/settings/flow/grid_t2b.frame +1 -0
- data/screen_test/settings/flow/grid_t2b.rb +14 -0
- data/screen_test/settings/height/box.frame +1 -0
- data/screen_test/settings/height/box.rb +13 -0
- data/screen_test/settings/height/box_border_sizing.frame +1 -0
- data/screen_test/settings/height/box_border_sizing.rb +15 -0
- data/screen_test/settings/height/grid.frame +1 -0
- data/screen_test/settings/height/grid.rb +14 -0
- data/screen_test/settings/height/overflow_box.frame +1 -0
- data/screen_test/settings/height/overflow_box.rb +13 -0
- data/screen_test/settings/height/overflow_box_l2r.frame +1 -0
- data/screen_test/settings/height/overflow_box_l2r.rb +17 -0
- data/screen_test/settings/height/overflow_box_t2b.frame +1 -0
- data/screen_test/settings/height/overflow_box_t2b.rb +16 -0
- data/screen_test/settings/height/overflow_grid.frame +1 -0
- data/screen_test/settings/height/overflow_grid.rb +16 -0
- data/screen_test/settings/margin.frame +1 -0
- data/screen_test/settings/margin.rb +16 -0
- data/screen_test/settings/padding.frame +1 -0
- data/screen_test/settings/padding.rb +13 -0
- data/screen_test/settings/position/box_left.frame +1 -0
- data/screen_test/settings/position/box_left.rb +17 -0
- data/screen_test/settings/position/box_left_negative.frame +1 -0
- data/screen_test/settings/position/box_left_negative.rb +17 -0
- data/screen_test/settings/position/box_top.frame +1 -0
- data/screen_test/settings/position/box_top.rb +17 -0
- data/screen_test/settings/position/box_top_negative.frame +1 -0
- data/screen_test/settings/position/box_top_negative.rb +17 -0
- data/screen_test/settings/position/grid_left.frame +1 -0
- data/screen_test/settings/position/grid_left.rb +18 -0
- data/screen_test/settings/position/grid_left_negative.frame +1 -0
- data/screen_test/settings/position/grid_left_negative.rb +18 -0
- data/screen_test/settings/position/grid_top.frame +1 -0
- data/screen_test/settings/position/grid_top.rb +18 -0
- data/screen_test/settings/position/grid_top_negative.frame +1 -0
- data/screen_test/settings/position/grid_top_negative.rb +18 -0
- data/screen_test/settings/scroll/horiz_box.frame +1 -0
- data/screen_test/settings/scroll/horiz_box.rb +17 -0
- data/screen_test/settings/scroll/horiz_box_align_center.rb +18 -0
- data/screen_test/settings/scroll/horiz_box_align_right.rb +18 -0
- data/screen_test/settings/scroll/vert_box.frame +1 -0
- data/screen_test/settings/scroll/vert_box.rb +20 -0
- data/screen_test/settings/title_font.frame +1 -0
- data/screen_test/settings/title_font.rb +12 -0
- data/screen_test/settings/valign/box_around.frame +1 -0
- data/screen_test/settings/valign/box_around.rb +17 -0
- data/screen_test/settings/valign/box_between.frame +1 -0
- data/screen_test/settings/valign/box_between.rb +17 -0
- data/screen_test/settings/valign/box_bottom.frame +1 -0
- data/screen_test/settings/valign/box_bottom.rb +17 -0
- data/screen_test/settings/valign/box_default.frame +1 -0
- data/screen_test/settings/valign/box_default.rb +16 -0
- data/screen_test/settings/valign/box_evenly.frame +1 -0
- data/screen_test/settings/valign/box_evenly.rb +17 -0
- data/screen_test/settings/valign/box_middle.frame +1 -0
- data/screen_test/settings/valign/box_middle.rb +17 -0
- data/screen_test/settings/valign/box_top.frame +1 -0
- data/screen_test/settings/valign/box_top.rb +17 -0
- data/screen_test/settings/valign/grid_bottom.frame +1 -0
- data/screen_test/settings/valign/grid_bottom.rb +15 -0
- data/screen_test/settings/valign/grid_default.frame +1 -0
- data/screen_test/settings/valign/grid_default.rb +14 -0
- data/screen_test/settings/valign/grid_middle.frame +1 -0
- data/screen_test/settings/valign/grid_middle.rb +15 -0
- data/screen_test/settings/valign/grid_top.frame +1 -0
- data/screen_test/settings/valign/grid_top.rb +15 -0
- data/screen_test/settings/width/box_border_sizing.frame +1 -0
- data/screen_test/settings/width/box_border_sizing.rb +15 -0
- data/screen_test/settings/width/box_content.frame +1 -0
- data/screen_test/settings/width/box_content.rb +15 -0
- data/screen_test/settings/width/box_default.frame +1 -0
- data/screen_test/settings/width/box_default.rb +14 -0
- data/screen_test/settings/width/grid.frame +1 -0
- data/screen_test/settings/width/grid.rb +14 -0
- data/screen_test/settings/width/overflow_align_center.frame +1 -0
- data/screen_test/settings/width/overflow_align_center.rb +14 -0
- data/screen_test/settings/width/overflow_align_right.frame +1 -0
- data/screen_test/settings/width/overflow_align_right.rb +14 -0
- data/screen_test/settings/width/overflow_box.frame +1 -0
- data/screen_test/settings/width/overflow_box.rb +13 -0
- data/screen_test/settings/width/overflow_box_l2r.frame +1 -0
- data/screen_test/settings/width/overflow_box_l2r.rb +16 -0
- data/screen_test/settings/width/overflow_box_t2b.frame +1 -0
- data/screen_test/settings/width/overflow_box_t2b.rb +17 -0
- data/screen_test/settings/width/overflow_grid.frame +1 -0
- data/screen_test/settings/width/overflow_grid.rb +14 -0
- data/tools/whirled_peas/tools/screen_tester.rb +233 -0
- metadata +191 -12
- data/bin/title_fonts +0 -6
- data/lib/whirled_peas/frame/print_consumer.rb +0 -33
- data/lib/whirled_peas/template.rb +0 -5
- data/lib/whirled_peas/template/element.rb +0 -230
- 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
- data/lib/whirled_peas/utils/color.rb +0 -101
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'highline'
|
2
|
+
|
3
|
+
require 'whirled_peas/utils/ansi'
|
4
|
+
|
5
|
+
require_relative 'renderer'
|
6
|
+
|
7
|
+
module WhirledPeas
|
8
|
+
module Graphics
|
9
|
+
class Screen
|
10
|
+
def self.current_dimensions
|
11
|
+
width, height = HighLine.new.terminal.terminal_size
|
12
|
+
[width || 0, height || 0]
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(width: nil, height: nil, output: STDOUT)
|
16
|
+
@output = output
|
17
|
+
@terminal = HighLine.new.terminal
|
18
|
+
@strokes = []
|
19
|
+
if width && height
|
20
|
+
@width = width
|
21
|
+
@height = height
|
22
|
+
else
|
23
|
+
refresh_size!
|
24
|
+
Signal.trap('SIGWINCH', proc { self.refresh_size! })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def paint(template)
|
29
|
+
@template = template
|
30
|
+
draw
|
31
|
+
end
|
32
|
+
|
33
|
+
def refresh
|
34
|
+
# No need to refresh if the screen dimensions have not changed
|
35
|
+
return if @refreshed_width == width || @refreshed_height == height
|
36
|
+
draw
|
37
|
+
end
|
38
|
+
|
39
|
+
def finalize
|
40
|
+
output.print Utils::Ansi.clear
|
41
|
+
output.print Utils::Ansi.cursor_pos(top: height - 1)
|
42
|
+
output.print Utils::Ansi.cursor_visible(true)
|
43
|
+
output.flush
|
44
|
+
end
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def refresh_size!
|
49
|
+
@width, @height = self.class.current_dimensions
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :output, :cursor, :terminal, :width, :height
|
55
|
+
|
56
|
+
def draw
|
57
|
+
strokes = [Utils::Ansi.cursor_visible(false), Utils::Ansi.cursor_pos, Utils::Ansi.clear_down]
|
58
|
+
Renderer.new(@template, width, height).paint do |left, top, fstring|
|
59
|
+
next unless fstring.length > 0
|
60
|
+
strokes << Utils::Ansi.cursor_pos(left: left, top: top)
|
61
|
+
strokes << fstring
|
62
|
+
end
|
63
|
+
strokes.each { |stroke| output.print(stroke) }
|
64
|
+
output.flush
|
65
|
+
@refreshed_width = width
|
66
|
+
@refreshed_height = height
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Graphics
|
3
|
+
class TextDimensions
|
4
|
+
attr_reader :outer_width, :outer_height
|
5
|
+
|
6
|
+
def initialize(content)
|
7
|
+
@outer_width = 0
|
8
|
+
content.each do |line|
|
9
|
+
@outer_width = line.length if line.length > @outer_width
|
10
|
+
end
|
11
|
+
@outer_height = content.length
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'whirled_peas/utils/formatted_string'
|
2
|
+
require 'whirled_peas/utils/title_font'
|
3
|
+
|
4
|
+
require_relative 'painter'
|
5
|
+
require_relative 'text_dimensions'
|
6
|
+
|
7
|
+
module WhirledPeas
|
8
|
+
module Graphics
|
9
|
+
class TextPainter < Painter
|
10
|
+
attr_reader :content
|
11
|
+
|
12
|
+
def paint(canvas, left, top, &block)
|
13
|
+
return unless canvas.writable?
|
14
|
+
formatting = [*settings.color, *settings.bg_color]
|
15
|
+
formatting << Utils::Ansi::BOLD if settings.bold?
|
16
|
+
if settings.underline? && settings.title_font.nil?
|
17
|
+
formatting << Utils::Ansi::UNDERLINE
|
18
|
+
end
|
19
|
+
content.each.with_index do |line, index|
|
20
|
+
canvas.stroke(left, top + index, line, formatting, &block)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def dimensions
|
25
|
+
TextDimensions.new(content)
|
26
|
+
end
|
27
|
+
|
28
|
+
def content=(content)
|
29
|
+
@content = if settings.title_font
|
30
|
+
Utils::TitleFont.to_s(
|
31
|
+
content, settings.title_font
|
32
|
+
).split("\n")
|
33
|
+
else
|
34
|
+
content.split("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
private_constant :TextPainter
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Settings
|
3
|
+
module Alignment
|
4
|
+
LEFT = :left
|
5
|
+
CENTER = :center
|
6
|
+
RIGHT = :right
|
7
|
+
BETWEEN = :between
|
8
|
+
AROUND = :around
|
9
|
+
EVENLY = :evenly
|
10
|
+
|
11
|
+
DEFAULT = LEFT
|
12
|
+
|
13
|
+
VALID = [LEFT, CENTER, RIGHT, BETWEEN, AROUND, EVENLY]
|
14
|
+
private_constant :VALID
|
15
|
+
|
16
|
+
def self.validate!(align)
|
17
|
+
return if align.nil?
|
18
|
+
return align if VALID.include?(align)
|
19
|
+
raise ArgumentError, "Unsupported alignment: #{align.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
private_constant :Alignment
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'whirled_peas/utils/ansi'
|
2
|
+
|
3
|
+
require_relative 'color'
|
4
|
+
|
5
|
+
module WhirledPeas
|
6
|
+
module Settings
|
7
|
+
class BgColor < Color
|
8
|
+
BG_OFFSET = 10
|
9
|
+
private_constant :BG_OFFSET
|
10
|
+
|
11
|
+
BLACK = new(Utils::Ansi::BLACK + BG_OFFSET)
|
12
|
+
RED = new(Utils::Ansi::RED + BG_OFFSET)
|
13
|
+
GREEN = new(Utils::Ansi::GREEN + BG_OFFSET)
|
14
|
+
YELLOW = new(Utils::Ansi::YELLOW + BG_OFFSET)
|
15
|
+
BLUE = new(Utils::Ansi::BLUE + BG_OFFSET)
|
16
|
+
MAGENTA = new(Utils::Ansi::MAGENTA + BG_OFFSET)
|
17
|
+
CYAN = new(Utils::Ansi::CYAN + BG_OFFSET)
|
18
|
+
WHITE = new(Utils::Ansi::WHITE + BG_OFFSET)
|
19
|
+
GRAY = BLACK.bright
|
20
|
+
|
21
|
+
DEFAULT = nil # Use system defined default
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require_relative 'text_color'
|
2
|
+
|
3
|
+
module WhirledPeas
|
4
|
+
module Settings
|
5
|
+
class Border
|
6
|
+
Style = Struct.new(
|
7
|
+
:top_left, :top_horiz, :top_junc, :top_right,
|
8
|
+
:left_vert, :left_junc,
|
9
|
+
:middle_vert, :cross_junc, :middle_horiz,
|
10
|
+
:right_vert, :right_junc,
|
11
|
+
:bottom_left, :bottom_horiz, :bottom_junc, :bottom_right
|
12
|
+
)
|
13
|
+
|
14
|
+
module Styles
|
15
|
+
BOLD = Style.new(
|
16
|
+
'┏', '━', '┳', '┓',
|
17
|
+
'┃', '┣',
|
18
|
+
'┃', '╋', '━',
|
19
|
+
'┃', '┫',
|
20
|
+
'┗', '━', '┻', '┛'
|
21
|
+
)
|
22
|
+
SOFT = Style.new(
|
23
|
+
'╭', '─', '┬', '╮',
|
24
|
+
'│', '├',
|
25
|
+
'│', '┼', '─',
|
26
|
+
'│', '┤',
|
27
|
+
'╰', '─', '┴', '╯'
|
28
|
+
)
|
29
|
+
DOUBLE = Style.new(
|
30
|
+
'╔', '═', '╦', '╗',
|
31
|
+
'║', '╠',
|
32
|
+
'║', '╬', '═',
|
33
|
+
'║', '╣',
|
34
|
+
'╚', '═', '╩', '╝'
|
35
|
+
)
|
36
|
+
|
37
|
+
DEFAULT = BOLD
|
38
|
+
|
39
|
+
def self.validate!(style)
|
40
|
+
return if style.nil?
|
41
|
+
return style if style.is_a?(Border::Style)
|
42
|
+
if style.is_a?(Symbol)
|
43
|
+
style_class = self.const_get(style.upcase)
|
44
|
+
return style_class if style_class.is_a?(Border::Style)
|
45
|
+
end
|
46
|
+
error_message = "Unsupported border style: #{style.inspect}"
|
47
|
+
raise ArgumentError, error_message
|
48
|
+
rescue NameError
|
49
|
+
error_message = "Unsupported border style: #{style.inspect}"
|
50
|
+
raise ArgumentError, error_message
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_writer :left, :top, :right, :bottom, :inner_horiz, :inner_vert
|
55
|
+
|
56
|
+
def left?
|
57
|
+
@left == true
|
58
|
+
end
|
59
|
+
|
60
|
+
def top?
|
61
|
+
@top == true
|
62
|
+
end
|
63
|
+
|
64
|
+
def right?
|
65
|
+
@right == true
|
66
|
+
end
|
67
|
+
|
68
|
+
def bottom?
|
69
|
+
@bottom == true
|
70
|
+
end
|
71
|
+
|
72
|
+
def inner_horiz?
|
73
|
+
@inner_horiz == true
|
74
|
+
end
|
75
|
+
|
76
|
+
def inner_vert?
|
77
|
+
@inner_vert == true
|
78
|
+
end
|
79
|
+
|
80
|
+
def outer?
|
81
|
+
left? || top? || right? || bottom?
|
82
|
+
end
|
83
|
+
|
84
|
+
def style
|
85
|
+
@style || Styles::DEFAULT
|
86
|
+
end
|
87
|
+
|
88
|
+
def style=(val)
|
89
|
+
@style = Styles.validate!(val)
|
90
|
+
end
|
91
|
+
|
92
|
+
def color=(val)
|
93
|
+
@color = TextColor.validate!(val)
|
94
|
+
end
|
95
|
+
|
96
|
+
def color
|
97
|
+
@color || TextColor::DEFAULT
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'whirled_peas/utils/ansi'
|
2
|
+
|
3
|
+
module WhirledPeas
|
4
|
+
module Settings
|
5
|
+
# An abstract class that encapsulates colors for a specific use case
|
6
|
+
class Color
|
7
|
+
# Validate the `color` argument is either (1) nil, (2) a valid Color constant in
|
8
|
+
# this class or (3) a symbol that maps to valid Color constant. E.g. if there
|
9
|
+
# is a RED constant in an implementing class, then :red or :bright_red are
|
10
|
+
# valid values for `color`
|
11
|
+
#
|
12
|
+
# @param color [Color|Symbol]
|
13
|
+
# @return [Color|Symbol] the value passed in if valid, otherwise an ArgumentError
|
14
|
+
# is raised.
|
15
|
+
def self.validate!(color)
|
16
|
+
return if color.nil?
|
17
|
+
return color if color.is_a?(self)
|
18
|
+
if color.is_a?(Symbol)
|
19
|
+
match = color.to_s.match(/^(bright_)?(\w+)$/)
|
20
|
+
color_class = self.const_get(match[2].upcase)
|
21
|
+
if color_class.is_a?(self)
|
22
|
+
if !match[1]
|
23
|
+
return color_class
|
24
|
+
elsif !color_class.bright?
|
25
|
+
return color_class.bright
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
error_message = "Unsupported #{self.name.split('::').last}: #{color.inspect}"
|
30
|
+
raise ArgumentError, error_message
|
31
|
+
rescue NameError
|
32
|
+
error_message = "Unsupported #{self.name.split('::').last}: #{color.inspect}"
|
33
|
+
raise ArgumentError, error_message
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize(code, bright=false)
|
37
|
+
@code = code
|
38
|
+
@bright = bright
|
39
|
+
end
|
40
|
+
|
41
|
+
def bright?
|
42
|
+
@bright
|
43
|
+
end
|
44
|
+
|
45
|
+
def bright
|
46
|
+
bright? ? self : self.class.new(@code + Utils::Ansi::BRIGHT_OFFSET, true)
|
47
|
+
end
|
48
|
+
|
49
|
+
def hash
|
50
|
+
[@code, @bright].hash
|
51
|
+
end
|
52
|
+
|
53
|
+
def ==(other)
|
54
|
+
other.is_a?(self.class) && self.hash == other.hash
|
55
|
+
end
|
56
|
+
alias_method :eq?, :==
|
57
|
+
|
58
|
+
def to_s
|
59
|
+
@code.to_s
|
60
|
+
end
|
61
|
+
|
62
|
+
def inspect
|
63
|
+
"#{self.class.name.split('::').last}(code=#{@code}, bright=#{@bright})"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
private_constant :Color
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
require_relative 'alignment'
|
2
|
+
require_relative 'border'
|
3
|
+
require_relative 'display_flow'
|
4
|
+
require_relative 'element_settings'
|
5
|
+
require_relative 'margin'
|
6
|
+
require_relative 'padding'
|
7
|
+
require_relative 'position'
|
8
|
+
require_relative 'scrollbar'
|
9
|
+
require_relative 'sizing'
|
10
|
+
require_relative 'vert_alignment'
|
11
|
+
|
12
|
+
module WhirledPeas
|
13
|
+
module Settings
|
14
|
+
class ContainerSettings < ElementSettings
|
15
|
+
attr_accessor :width, :height
|
16
|
+
|
17
|
+
def align
|
18
|
+
@_align || Alignment::DEFAULT
|
19
|
+
end
|
20
|
+
|
21
|
+
def align_left?
|
22
|
+
align == Alignment::LEFT
|
23
|
+
end
|
24
|
+
|
25
|
+
def align_center?
|
26
|
+
align == Alignment::CENTER
|
27
|
+
end
|
28
|
+
|
29
|
+
def align_right?
|
30
|
+
align == Alignment::RIGHT
|
31
|
+
end
|
32
|
+
|
33
|
+
def align_between?
|
34
|
+
align == Alignment::BETWEEN
|
35
|
+
end
|
36
|
+
|
37
|
+
def align_around?
|
38
|
+
align == Alignment::AROUND
|
39
|
+
end
|
40
|
+
|
41
|
+
def align_evenly?
|
42
|
+
align == Alignment::EVENLY
|
43
|
+
end
|
44
|
+
|
45
|
+
def align=(align)
|
46
|
+
@_align = Alignment.validate!(align)
|
47
|
+
end
|
48
|
+
|
49
|
+
def valign
|
50
|
+
@_valign || VertAlignment::DEFAULT
|
51
|
+
end
|
52
|
+
|
53
|
+
def valign_top?
|
54
|
+
valign == VertAlignment::TOP
|
55
|
+
end
|
56
|
+
|
57
|
+
def valign_middle?
|
58
|
+
valign == VertAlignment::MIDDLE
|
59
|
+
end
|
60
|
+
|
61
|
+
def valign_bottom?
|
62
|
+
valign == VertAlignment::BOTTOM
|
63
|
+
end
|
64
|
+
|
65
|
+
def valign_between?
|
66
|
+
valign == VertAlignment::BETWEEN
|
67
|
+
end
|
68
|
+
|
69
|
+
def valign_around?
|
70
|
+
valign == VertAlignment::AROUND
|
71
|
+
end
|
72
|
+
|
73
|
+
def valign_evenly?
|
74
|
+
valign == VertAlignment::EVENLY
|
75
|
+
end
|
76
|
+
|
77
|
+
def valign=(valign)
|
78
|
+
@_valign = VertAlignment.validate!(valign)
|
79
|
+
end
|
80
|
+
|
81
|
+
def set_border(
|
82
|
+
left: nil, top: nil, right: nil, bottom: nil, inner_horiz: nil, inner_vert: nil, style: nil, color: nil
|
83
|
+
)
|
84
|
+
border.left = left unless left.nil?
|
85
|
+
border.top = top unless top.nil?
|
86
|
+
border.right = right unless right.nil?
|
87
|
+
border.bottom = bottom unless bottom.nil?
|
88
|
+
border.inner_horiz = inner_horiz unless inner_horiz.nil?
|
89
|
+
border.inner_vert = inner_vert unless inner_vert.nil?
|
90
|
+
border.style = style unless style.nil?
|
91
|
+
border.color = color unless color.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
def full_border(style: nil, color: nil)
|
95
|
+
set_border(
|
96
|
+
left: true, top: true, right: true, bottom: true, inner_horiz: true, inner_vert: true, style: style, color: color
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
def border
|
101
|
+
@_border ||= Border.new
|
102
|
+
end
|
103
|
+
|
104
|
+
def flow=(flow)
|
105
|
+
@_flow = DisplayFlow.validate!(flow)
|
106
|
+
end
|
107
|
+
|
108
|
+
def flow
|
109
|
+
@_flow || DisplayFlow::DEFAULT
|
110
|
+
end
|
111
|
+
|
112
|
+
def horizontal_flow?
|
113
|
+
%i[l2r r2l].include?(flow)
|
114
|
+
end
|
115
|
+
|
116
|
+
def vertical_flow?
|
117
|
+
!horizontal_flow?
|
118
|
+
end
|
119
|
+
|
120
|
+
def forward_flow?
|
121
|
+
%i[l2r t2b].include?(flow)
|
122
|
+
end
|
123
|
+
|
124
|
+
def reverse_flow?
|
125
|
+
!forward_flow?
|
126
|
+
end
|
127
|
+
|
128
|
+
def set_margin(left: nil, top: nil, right: nil, bottom: nil, horiz: nil, vert: nil)
|
129
|
+
if horiz && (left || right)
|
130
|
+
raise ArgumentError, 'Cannot set horizontal margin when setting left/right'
|
131
|
+
elsif vert && (top || bottom)
|
132
|
+
raise ArgumentError, 'Cannot set vertical margin when setting top/bottom'
|
133
|
+
end
|
134
|
+
|
135
|
+
if horiz
|
136
|
+
margin.horiz = horiz
|
137
|
+
else
|
138
|
+
margin.left = left if left
|
139
|
+
margin.right = right if right
|
140
|
+
end
|
141
|
+
|
142
|
+
if vert
|
143
|
+
margin.vert = vert
|
144
|
+
else
|
145
|
+
margin.top = top if top
|
146
|
+
margin.bottom = bottom if bottom
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def margin
|
151
|
+
@_margin ||= Margin.new
|
152
|
+
end
|
153
|
+
|
154
|
+
def set_padding(left: nil, top: nil, right: nil, bottom: nil, horiz: nil, vert: nil)
|
155
|
+
if horiz && (left || right)
|
156
|
+
raise ArgumentError, 'Cannot set horizontal padding when setting left/right'
|
157
|
+
elsif vert && (top || bottom)
|
158
|
+
raise ArgumentError, 'Cannot set vertical padding when setting top/bottom'
|
159
|
+
end
|
160
|
+
|
161
|
+
if horiz
|
162
|
+
padding.horiz = horiz
|
163
|
+
else
|
164
|
+
padding.left = left if left
|
165
|
+
padding.right = right if right
|
166
|
+
end
|
167
|
+
|
168
|
+
if vert
|
169
|
+
padding.vert = vert
|
170
|
+
else
|
171
|
+
padding.top = top if top
|
172
|
+
padding.bottom = bottom if bottom
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def padding
|
177
|
+
@_padding ||= Padding.new
|
178
|
+
end
|
179
|
+
|
180
|
+
def set_position(left: nil, top: nil)
|
181
|
+
position.left = left if left
|
182
|
+
position.top = top if top
|
183
|
+
end
|
184
|
+
|
185
|
+
def position
|
186
|
+
@_position ||= Position.new
|
187
|
+
end
|
188
|
+
|
189
|
+
def set_scrollbar(horiz: nil, vert: nil)
|
190
|
+
scrollbar.horiz = horiz unless horiz.nil?
|
191
|
+
scrollbar.vert = vert unless vert.nil?
|
192
|
+
end
|
193
|
+
|
194
|
+
def scrollbar
|
195
|
+
@_scrollbar ||= Scrollbar.new
|
196
|
+
end
|
197
|
+
|
198
|
+
def sizing
|
199
|
+
@_sizing || Sizing::DEFAULT
|
200
|
+
end
|
201
|
+
|
202
|
+
def border_sizing?
|
203
|
+
@_sizing == Sizing::BORDER
|
204
|
+
end
|
205
|
+
|
206
|
+
def content_sizing?
|
207
|
+
@_sizing == Sizing::CONTENT
|
208
|
+
end
|
209
|
+
|
210
|
+
def sizing=(sizing)
|
211
|
+
@_sizing = Sizing.validate!(sizing)
|
212
|
+
end
|
213
|
+
|
214
|
+
def inherit(parent)
|
215
|
+
super
|
216
|
+
return unless parent.is_a?(ContainerSettings)
|
217
|
+
set_border(color: parent.border.color, style: parent.border.style)
|
218
|
+
end
|
219
|
+
|
220
|
+
protected
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|