whirled_peas 0.4.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|