whirled_peas 0.9.1 → 0.13.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/.gitignore +0 -2
- data/CHANGELOG.md +23 -0
- data/README.md +9 -1049
- data/doc/application.md +92 -0
- data/doc/cli.md +115 -0
- data/doc/components.md +51 -0
- data/doc/easing.md +257 -0
- data/doc/elements.md +69 -0
- data/doc/screen_test.md +22 -0
- data/doc/settings.md +466 -0
- data/doc/template_factory.md +53 -0
- data/doc/themes.md +50 -0
- data/examples/components.rb +33 -0
- data/examples/graph.rb +1 -1
- data/examples/scrolling.rb +8 -19
- data/lib/data/themes.yaml +15 -0
- data/lib/whirled_peas.rb +31 -9
- data/lib/whirled_peas/animator/debug_consumer.rb +2 -2
- data/lib/whirled_peas/animator/easing.rb +57 -0
- data/lib/whirled_peas/animator/frameset.rb +13 -8
- data/lib/whirled_peas/animator/producer.rb +7 -8
- data/lib/whirled_peas/animator/renderer_consumer.rb +10 -5
- data/lib/whirled_peas/command/config_command.rb +3 -3
- data/lib/whirled_peas/command/frames.rb +1 -3
- data/lib/whirled_peas/command/play.rb +9 -7
- data/lib/whirled_peas/command/record.rb +1 -3
- data/lib/whirled_peas/command/still.rb +6 -2
- data/lib/whirled_peas/command/themes.rb +78 -0
- data/lib/whirled_peas/command_line.rb +3 -1
- data/lib/whirled_peas/component.rb +35 -0
- data/lib/whirled_peas/component/list_with_active.rb +89 -0
- data/lib/whirled_peas/config.rb +1 -8
- data/lib/whirled_peas/device/null_device.rb +1 -1
- data/lib/whirled_peas/device/output_file.rb +2 -2
- data/lib/whirled_peas/device/rendered_frame.rb +12 -0
- data/lib/whirled_peas/device/screen.rb +7 -8
- data/lib/whirled_peas/graphics/box_painter.rb +4 -4
- data/lib/whirled_peas/graphics/composer.rb +9 -2
- data/lib/whirled_peas/graphics/container_coords.rb +23 -25
- data/lib/whirled_peas/graphics/container_dimensions.rb +24 -0
- data/lib/whirled_peas/graphics/container_painter.rb +27 -139
- data/lib/whirled_peas/graphics/debugger.rb +2 -7
- data/lib/whirled_peas/graphics/graph_painter.rb +31 -24
- data/lib/whirled_peas/graphics/pixel_grid.rb +81 -0
- data/lib/whirled_peas/graphics/renderer.rb +4 -5
- data/lib/whirled_peas/graphics/scrollbar_helper.rb +126 -0
- data/lib/whirled_peas/null_logger.rb +0 -1
- data/lib/whirled_peas/settings/bg_color.rb +5 -1
- data/lib/whirled_peas/settings/border.rb +26 -5
- data/lib/whirled_peas/settings/color.rb +8 -4
- data/lib/whirled_peas/settings/container_settings.rb +14 -7
- data/lib/whirled_peas/settings/debugger.rb +3 -1
- data/lib/whirled_peas/settings/element_settings.rb +18 -6
- data/lib/whirled_peas/settings/graph_settings.rb +1 -1
- data/lib/whirled_peas/settings/position.rb +17 -5
- data/lib/whirled_peas/settings/text_color.rb +5 -0
- data/lib/whirled_peas/settings/text_settings.rb +1 -0
- data/lib/whirled_peas/settings/theme.rb +61 -0
- data/lib/whirled_peas/settings/theme_library.rb +69 -0
- data/lib/whirled_peas/utils/ansi.rb +4 -2
- data/lib/whirled_peas/utils/file_handler.rb +14 -9
- data/lib/whirled_peas/utils/formatted_string.rb +5 -3
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/components/list_with_active/l2r_position_end.frame +1 -0
- data/screen_test/components/list_with_active/l2r_position_end.rb +16 -0
- data/screen_test/components/list_with_active/l2r_position_middle.frame +1 -0
- data/screen_test/components/list_with_active/l2r_position_middle.rb +16 -0
- data/screen_test/components/list_with_active/l2r_position_start.frame +1 -0
- data/screen_test/components/list_with_active/l2r_position_start.rb +16 -0
- data/screen_test/components/list_with_active/l2r_separator.frame +1 -0
- data/screen_test/components/list_with_active/l2r_separator.rb +17 -0
- data/screen_test/components/list_with_active/t2b_position_end.frame +1 -0
- data/screen_test/components/list_with_active/t2b_position_end.rb +17 -0
- data/screen_test/components/list_with_active/t2b_position_middle.frame +1 -0
- data/screen_test/components/list_with_active/t2b_position_middle.rb +17 -0
- data/screen_test/components/list_with_active/t2b_position_start.frame +1 -0
- data/screen_test/components/list_with_active/t2b_position_start.rb +17 -0
- data/screen_test/components/list_with_active/t2b_separator.frame +1 -0
- data/screen_test/components/list_with_active/t2b_separator.rb +18 -0
- data/screen_test/elements/box.frame +1 -1
- data/screen_test/elements/box.rb +1 -1
- data/screen_test/elements/graph_asc.frame +1 -0
- data/screen_test/elements/{graph.rb → graph_asc.rb} +1 -1
- data/screen_test/elements/graph_desc.frame +1 -0
- data/screen_test/elements/graph_desc.rb +12 -0
- data/screen_test/elements/graph_horiz.frame +1 -0
- data/screen_test/elements/graph_horiz.rb +12 -0
- data/screen_test/elements/graph_sin.frame +1 -0
- data/screen_test/elements/graph_sin.rb +12 -0
- data/screen_test/elements/grid.frame +1 -1
- data/screen_test/elements/grid.rb +1 -1
- data/screen_test/elements/screen_overflow_x.frame +1 -1
- data/screen_test/elements/screen_overflow_x.rb +1 -1
- data/screen_test/elements/screen_overflow_y.frame +1 -1
- data/screen_test/elements/screen_overflow_y.rb +1 -1
- data/screen_test/elements/text.frame +1 -1
- data/screen_test/elements/text.rb +1 -1
- data/screen_test/elements/text_multiline.frame +1 -1
- data/screen_test/elements/text_multiline.rb +1 -1
- data/screen_test/elements/theme.frame +1 -0
- data/screen_test/elements/theme.rb +27 -0
- data/screen_test/settings/align/box_around.frame +1 -1
- data/screen_test/settings/align/box_around.rb +1 -1
- data/screen_test/settings/align/box_between.frame +1 -1
- data/screen_test/settings/align/box_between.rb +1 -1
- data/screen_test/settings/align/box_center.frame +1 -1
- data/screen_test/settings/align/box_center.rb +1 -1
- data/screen_test/settings/align/box_default.frame +1 -1
- data/screen_test/settings/align/box_default.rb +1 -1
- data/screen_test/settings/align/box_evenly.frame +1 -1
- data/screen_test/settings/align/box_evenly.rb +1 -1
- data/screen_test/settings/align/box_left.frame +1 -1
- data/screen_test/settings/align/box_left.rb +1 -1
- data/screen_test/settings/align/box_right.frame +1 -1
- data/screen_test/settings/align/box_right.rb +1 -1
- data/screen_test/settings/align/children_center.frame +1 -1
- data/screen_test/settings/align/children_center.rb +1 -1
- data/screen_test/settings/align/children_left.frame +1 -1
- data/screen_test/settings/align/children_left.rb +1 -1
- data/screen_test/settings/align/children_right.frame +1 -1
- data/screen_test/settings/align/children_right.rb +1 -1
- data/screen_test/settings/align/grid_center.frame +1 -1
- data/screen_test/settings/align/grid_center.rb +1 -1
- data/screen_test/settings/align/grid_default.frame +1 -1
- data/screen_test/settings/align/grid_default.rb +1 -1
- data/screen_test/settings/align/grid_left.frame +1 -1
- data/screen_test/settings/align/grid_left.rb +1 -1
- data/screen_test/settings/align/grid_right.frame +1 -1
- data/screen_test/settings/align/grid_right.rb +1 -1
- data/screen_test/settings/ansi/bold.frame +1 -1
- data/screen_test/settings/ansi/bold.rb +1 -1
- data/screen_test/settings/ansi/color.frame +1 -1
- data/screen_test/settings/ansi/color.rb +1 -1
- data/screen_test/settings/ansi/underline.frame +1 -1
- data/screen_test/settings/ansi/underline.rb +1 -1
- data/screen_test/settings/border.frame +1 -1
- data/screen_test/settings/border.rb +1 -1
- data/screen_test/settings/content_start/box_bottom.frame +1 -0
- data/screen_test/settings/content_start/box_bottom.rb +17 -0
- data/screen_test/settings/content_start/box_left.frame +1 -0
- data/screen_test/settings/{position → content_start}/box_left.rb +2 -2
- data/screen_test/settings/content_start/box_left_negative.frame +1 -0
- data/screen_test/settings/{position → content_start}/box_left_negative.rb +2 -2
- data/screen_test/settings/content_start/box_right.frame +1 -0
- data/screen_test/settings/content_start/box_right.rb +17 -0
- data/screen_test/settings/content_start/box_top.frame +1 -0
- data/screen_test/settings/{position → content_start}/box_top.rb +2 -2
- data/screen_test/settings/content_start/box_top_negative.frame +1 -0
- data/screen_test/settings/{position → content_start}/box_top_negative.rb +2 -2
- data/screen_test/settings/content_start/grid_left.frame +1 -0
- data/screen_test/settings/{position → content_start}/grid_left.rb +2 -2
- data/screen_test/settings/content_start/grid_left_negative.frame +1 -0
- data/screen_test/settings/{position → content_start}/grid_left_negative.rb +2 -2
- data/screen_test/settings/content_start/grid_top.frame +1 -0
- data/screen_test/settings/{position → content_start}/grid_top.rb +2 -2
- data/screen_test/settings/content_start/grid_top_negative.frame +1 -0
- data/screen_test/settings/{position → content_start}/grid_top_negative.rb +2 -2
- data/screen_test/settings/flow/box_b2t.frame +1 -1
- data/screen_test/settings/flow/box_b2t.rb +1 -1
- data/screen_test/settings/flow/box_l2r.frame +1 -1
- data/screen_test/settings/flow/box_l2r.rb +1 -1
- data/screen_test/settings/flow/box_r2l.frame +1 -1
- data/screen_test/settings/flow/box_r2l.rb +1 -1
- data/screen_test/settings/flow/box_t2b.frame +1 -1
- data/screen_test/settings/flow/box_t2b.rb +1 -1
- data/screen_test/settings/flow/grid_b2t.frame +1 -1
- data/screen_test/settings/flow/grid_b2t.rb +1 -1
- data/screen_test/settings/flow/grid_l2r.frame +1 -1
- data/screen_test/settings/flow/grid_l2r.rb +1 -1
- data/screen_test/settings/flow/grid_r2l.frame +1 -1
- data/screen_test/settings/flow/grid_r2l.rb +1 -1
- data/screen_test/settings/flow/grid_t2b.frame +1 -1
- data/screen_test/settings/flow/grid_t2b.rb +1 -1
- data/screen_test/settings/height/box.frame +1 -1
- data/screen_test/settings/height/box.rb +1 -1
- data/screen_test/settings/height/box_border_sizing.frame +1 -1
- data/screen_test/settings/height/box_border_sizing.rb +1 -1
- data/screen_test/settings/height/grid.frame +1 -1
- data/screen_test/settings/height/grid.rb +1 -1
- data/screen_test/settings/height/overflow_box.frame +1 -1
- data/screen_test/settings/height/overflow_box.rb +1 -1
- data/screen_test/settings/height/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/height/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/height/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/height/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/height/overflow_grid.frame +1 -1
- data/screen_test/settings/height/overflow_grid.rb +1 -1
- data/screen_test/settings/margin.frame +1 -1
- data/screen_test/settings/margin.rb +1 -1
- data/screen_test/settings/padding.frame +1 -1
- data/screen_test/settings/padding.rb +1 -1
- data/screen_test/settings/scroll/horiz_box.frame +1 -1
- data/screen_test/settings/scroll/horiz_box.rb +3 -5
- data/screen_test/settings/scroll/horiz_box_align_center.rb +3 -5
- data/screen_test/settings/scroll/horiz_box_align_right.rb +3 -5
- data/screen_test/settings/scroll/vert_box.frame +1 -1
- data/screen_test/settings/scroll/vert_box.rb +6 -8
- data/screen_test/settings/title_font.frame +1 -1
- data/screen_test/settings/title_font.rb +1 -1
- data/screen_test/settings/valign/box_around.frame +1 -1
- data/screen_test/settings/valign/box_around.rb +1 -1
- data/screen_test/settings/valign/box_between.frame +1 -1
- data/screen_test/settings/valign/box_between.rb +1 -1
- data/screen_test/settings/valign/box_bottom.frame +1 -1
- data/screen_test/settings/valign/box_bottom.rb +1 -1
- data/screen_test/settings/valign/box_default.frame +1 -1
- data/screen_test/settings/valign/box_default.rb +1 -1
- data/screen_test/settings/valign/box_evenly.frame +1 -1
- data/screen_test/settings/valign/box_evenly.rb +1 -1
- data/screen_test/settings/valign/box_middle.frame +1 -1
- data/screen_test/settings/valign/box_middle.rb +1 -1
- data/screen_test/settings/valign/box_top.frame +1 -1
- data/screen_test/settings/valign/box_top.rb +1 -1
- data/screen_test/settings/valign/grid_bottom.frame +1 -1
- data/screen_test/settings/valign/grid_bottom.rb +1 -1
- data/screen_test/settings/valign/grid_default.frame +1 -1
- data/screen_test/settings/valign/grid_default.rb +1 -1
- data/screen_test/settings/valign/grid_middle.frame +1 -1
- data/screen_test/settings/valign/grid_middle.rb +1 -1
- data/screen_test/settings/valign/grid_top.frame +1 -1
- data/screen_test/settings/valign/grid_top.rb +1 -1
- data/screen_test/settings/width/box_border_sizing.frame +1 -1
- data/screen_test/settings/width/box_border_sizing.rb +1 -1
- data/screen_test/settings/width/box_content.frame +1 -1
- data/screen_test/settings/width/box_content.rb +1 -1
- data/screen_test/settings/width/box_default.frame +1 -1
- data/screen_test/settings/width/box_default.rb +1 -1
- data/screen_test/settings/width/grid.frame +1 -1
- data/screen_test/settings/width/grid.rb +1 -1
- data/screen_test/settings/width/overflow_align_center.frame +1 -1
- data/screen_test/settings/width/overflow_align_center.rb +1 -1
- data/screen_test/settings/width/overflow_align_right.frame +1 -1
- data/screen_test/settings/width/overflow_align_right.rb +1 -1
- data/screen_test/settings/width/overflow_box.frame +1 -1
- data/screen_test/settings/width/overflow_box.rb +1 -1
- data/screen_test/settings/width/overflow_box_l2r.frame +1 -1
- data/screen_test/settings/width/overflow_box_l2r.rb +1 -1
- data/screen_test/settings/width/overflow_box_t2b.frame +1 -1
- data/screen_test/settings/width/overflow_box_t2b.rb +1 -1
- data/screen_test/settings/width/overflow_grid.frame +1 -1
- data/screen_test/settings/width/overflow_grid.rb +1 -1
- data/tools/whirled_peas/tools/screen_tester.rb +21 -3
- metadata +67 -22
- data/bin/easing +0 -33
- data/lib/whirled_peas/graphics/mock_screen.rb +0 -26
- data/screen_test/elements/graph.frame +0 -1
- data/screen_test/settings/position/box_left.frame +0 -1
- data/screen_test/settings/position/box_left_negative.frame +0 -1
- data/screen_test/settings/position/box_top.frame +0 -1
- data/screen_test/settings/position/box_top_negative.frame +0 -1
- data/screen_test/settings/position/grid_left.frame +0 -1
- data/screen_test/settings/position/grid_left_negative.frame +0 -1
- data/screen_test/settings/position/grid_top.frame +0 -1
- data/screen_test/settings/position/grid_top_negative.frame +0 -1
@@ -0,0 +1,81 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Graphics
|
3
|
+
class PixelGrid
|
4
|
+
Pixel = Struct.new(:char, :formatting)
|
5
|
+
|
6
|
+
def initialize(width, height)
|
7
|
+
@pixels = Array.new(height) { Array.new(width) { Pixel.new } }
|
8
|
+
end
|
9
|
+
|
10
|
+
def add_stroke(left, top, fstring)
|
11
|
+
fstring.each_char.with_index do |char, offset|
|
12
|
+
pixels[top][left + offset].char = char
|
13
|
+
pixels[top][left + offset].formatting = fstring.formatting
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def pixel_at(col, row)
|
18
|
+
pixels[row][col]
|
19
|
+
end
|
20
|
+
|
21
|
+
def diff(other)
|
22
|
+
str = ''
|
23
|
+
formatting = nil
|
24
|
+
chars = ''
|
25
|
+
pixels.each.with_index do |row, row_index|
|
26
|
+
row.each.with_index do |pixel, col_index|
|
27
|
+
if pixel == other.pixel_at(col_index, row_index)
|
28
|
+
if chars != ''
|
29
|
+
str += Utils::FormattedString.new(chars, formatting).to_s
|
30
|
+
chars = ''
|
31
|
+
formatting = nil
|
32
|
+
end
|
33
|
+
elsif chars == ''
|
34
|
+
str += Utils::Ansi.cursor_pos(left: col_index, top: row_index)
|
35
|
+
chars = pixel.char
|
36
|
+
formatting = pixel.formatting
|
37
|
+
elsif formatting != pixel.formatting
|
38
|
+
str += Utils::FormattedString.new(chars, formatting).to_s
|
39
|
+
chars = pixel.char
|
40
|
+
formatting = pixel.formatting
|
41
|
+
else
|
42
|
+
chars += pixel.char
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
if chars != ''
|
47
|
+
str += chars
|
48
|
+
chars = ''
|
49
|
+
formatting = nil
|
50
|
+
end
|
51
|
+
str
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
str = Utils::Ansi.cursor_pos(left: 0, top: 0) + Utils::Ansi.clear_down
|
56
|
+
formatting = nil
|
57
|
+
chars = ''
|
58
|
+
pixels.each.with_index do |row, row_offset|
|
59
|
+
str += Utils::Ansi.cursor_pos(left: 0, top: row_offset) if row_offset > 0
|
60
|
+
row.each do |pixel|
|
61
|
+
if pixel.formatting != formatting
|
62
|
+
str += Utils::FormattedString.new(chars, formatting).to_s if chars != ''
|
63
|
+
chars = ''
|
64
|
+
formatting = pixel.formatting
|
65
|
+
end
|
66
|
+
chars << pixel.char
|
67
|
+
end
|
68
|
+
if chars != ''
|
69
|
+
str += Utils::FormattedString.new(chars, formatting).to_s
|
70
|
+
chars = ''
|
71
|
+
end
|
72
|
+
end
|
73
|
+
str
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
attr_reader :pixels
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'canvas'
|
2
|
+
require_relative 'pixel_grid'
|
2
3
|
|
3
4
|
module WhirledPeas
|
4
5
|
module Graphics
|
@@ -15,13 +16,11 @@ module WhirledPeas
|
|
15
16
|
template.settings.height = height
|
16
17
|
template.settings.sizing = :border
|
17
18
|
template.settings.set_margin(left: 0, top: 0, right: 0, bottom: 0)
|
18
|
-
|
19
|
+
pixel_grid = PixelGrid.new(width, height)
|
19
20
|
template.paint(Canvas.new(0, 0, width, height), 0, 0) do |left, top, fstring|
|
20
|
-
|
21
|
-
strokes << Utils::Ansi.cursor_pos(left: left, top: top)
|
22
|
-
strokes << fstring
|
21
|
+
pixel_grid.add_stroke(left, top, fstring)
|
23
22
|
end
|
24
|
-
|
23
|
+
pixel_grid
|
25
24
|
end
|
26
25
|
|
27
26
|
private
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module WhirledPeas
|
2
|
+
module Graphics
|
3
|
+
module ScrollbarHelper
|
4
|
+
# Contants to paint scrollbars
|
5
|
+
HORIZONTAL = [' ', '▗', '▖', '▄']
|
6
|
+
VERTICAL = [
|
7
|
+
' ',
|
8
|
+
'▗',
|
9
|
+
'▝',
|
10
|
+
'▐'
|
11
|
+
]
|
12
|
+
|
13
|
+
# The number of units of scrollbar a single character can be divided into
|
14
|
+
SCROLL_HANDLE_SCALE = 2
|
15
|
+
private_constant :SCROLL_HANDLE_SCALE
|
16
|
+
|
17
|
+
class << self
|
18
|
+
# Return the characters to paint the horizontal scroll bar with for the given column
|
19
|
+
#
|
20
|
+
# @see #scroll_chars for more details
|
21
|
+
def horiz(col_count, viewable_col_count, first_visible_col)
|
22
|
+
scroll_chars(col_count, viewable_col_count, first_visible_col, HORIZONTAL)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Return the characters to paint the vertical scroll bar with for the given row
|
26
|
+
#
|
27
|
+
# @see #scroll_chars for more details
|
28
|
+
def vert(row_count, viewable_row_count, first_visible_row)
|
29
|
+
scroll_chars(row_count, viewable_row_count, first_visible_row, VERTICAL)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# Determine which character to paint a for a scrollbar
|
35
|
+
#
|
36
|
+
# @param total_count [Integer] total number of rows/columns in the content
|
37
|
+
# @param viewable_count [Integer] number of rows/columns visible in the viewport
|
38
|
+
# @param first_visible [Integer] zero-based index of the first row/column that is visible
|
39
|
+
# in the viewport
|
40
|
+
# @param chars [Array<String>] an array with four 1-character strings, the frist is the
|
41
|
+
# gutter (i.e. no scrolbar handle visible), then the "second half" scrollbar character,
|
42
|
+
# then second is the "first half" scrollbar character, and finally the "full"
|
43
|
+
def scroll_chars(total_count, viewable_count, first_visible, chars)
|
44
|
+
# Start by initializing the scroll back to to all gutters
|
45
|
+
scrollbar = Array.new(viewable_count) { chars[0] }
|
46
|
+
|
47
|
+
return scrollbar if total_count == 0
|
48
|
+
return scrollbar if viewable_count == 0
|
49
|
+
return scrollbar if viewable_count >= total_count
|
50
|
+
|
51
|
+
# The scroll handle has the exact same relative size and position in the scroll gutter
|
52
|
+
# that the viewable content has in the total content area. For example, a content area
|
53
|
+
# that is 50 columns wide with a view port that is 20 columns wide might look like
|
54
|
+
#
|
55
|
+
# +---------1-----****2*********3******---4---------+
|
56
|
+
# | * * |
|
57
|
+
# | hidden * viewable * hidden |
|
58
|
+
# | * * |
|
59
|
+
# +---------1-----****2*********3******---4---------+
|
60
|
+
#
|
61
|
+
# The scoll gutter, would look like
|
62
|
+
#
|
63
|
+
# |......********.....|
|
64
|
+
#
|
65
|
+
# Scrolling all the way to the right results in
|
66
|
+
#
|
67
|
+
# +---------1---------2---------3*********4*********+
|
68
|
+
# | * *
|
69
|
+
# | hidden * viewable *
|
70
|
+
# | * *
|
71
|
+
# +---------1---------2---------3*********4*********+
|
72
|
+
# |...........********|
|
73
|
+
#
|
74
|
+
# Returning to the first example, we can match up the arguments to this method to the
|
75
|
+
# diagram
|
76
|
+
#
|
77
|
+
# total_count = 50
|
78
|
+
# |<----------------------------------------------->|
|
79
|
+
# | |
|
80
|
+
# | veiwable_count = 20 |
|
81
|
+
# | |<----------------->| |
|
82
|
+
# ↓ ↓ ↓ ↓
|
83
|
+
# +---------1-----****2*********3******---4---------+
|
84
|
+
# | * * |
|
85
|
+
# | hidden * viewable * hidden |
|
86
|
+
# | * * |
|
87
|
+
# +---------1-----****2*********3******---4---------+
|
88
|
+
# |......****?***.....|
|
89
|
+
# ↑ ↑
|
90
|
+
# first_visible = 16 |
|
91
|
+
# curr = 11
|
92
|
+
|
93
|
+
# Always use the same length for the scrollbar so it does not give an inchworm effect
|
94
|
+
# as it scrolls along. This will calculate the "ideal" length of the scroll bar if we
|
95
|
+
# could infinitely divide a character.
|
96
|
+
length = (viewable_count ** 2).to_f / total_count
|
97
|
+
|
98
|
+
# Round the length to the nearst "scaled" value
|
99
|
+
length = (SCROLL_HANDLE_SCALE * length).round.to_f / SCROLL_HANDLE_SCALE
|
100
|
+
|
101
|
+
# Ensure we have a scrollbar!
|
102
|
+
length = 1.0 / SCROLL_HANDLE_SCALE if length == 0
|
103
|
+
|
104
|
+
# Find the "ideal" position of where the scrollbar should start.
|
105
|
+
start = first_visible * viewable_count.to_f / total_count
|
106
|
+
|
107
|
+
# Round the start to the nearest "scaled" value
|
108
|
+
start = (SCROLL_HANDLE_SCALE * start).round.to_f / SCROLL_HANDLE_SCALE
|
109
|
+
|
110
|
+
# Make sure we didn't scroll off the page!
|
111
|
+
start -= length if start == viewable_count
|
112
|
+
|
113
|
+
(start.floor..[(start + length).floor, viewable_count - 1].min).each do |curr_0|
|
114
|
+
curr_1 = curr_0 + 1.0 / SCROLL_HANDLE_SCALE
|
115
|
+
|
116
|
+
first_half = start <= curr_0 && curr_0 < start + length ? 2 : 0
|
117
|
+
second_half = start <= curr_1 && curr_1 < start + length ? 1 : 0
|
118
|
+
|
119
|
+
scrollbar[curr_0] = chars[second_half | first_half]
|
120
|
+
end
|
121
|
+
scrollbar
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'whirled_peas/utils/ansi'
|
2
2
|
|
3
3
|
require_relative 'color'
|
4
|
+
require_relative 'text_color'
|
4
5
|
|
5
6
|
module WhirledPeas
|
6
7
|
module Settings
|
7
8
|
class BgColor < Color
|
8
9
|
BG_OFFSET = 10
|
9
|
-
private_constant :BG_OFFSET
|
10
10
|
|
11
11
|
BLACK = new(Utils::Ansi::BLACK + BG_OFFSET)
|
12
12
|
RED = new(Utils::Ansi::RED + BG_OFFSET)
|
@@ -19,6 +19,10 @@ module WhirledPeas
|
|
19
19
|
GRAY = BLACK.bright
|
20
20
|
|
21
21
|
DEFAULT = nil # Use system defined default
|
22
|
+
|
23
|
+
def as_text_color
|
24
|
+
TextColor.new(code - BG_OFFSET, bright?)
|
25
|
+
end
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -34,7 +34,7 @@ module WhirledPeas
|
|
34
34
|
'╚', '═', '╩', '╝'
|
35
35
|
)
|
36
36
|
|
37
|
-
DEFAULT =
|
37
|
+
DEFAULT = SOFT
|
38
38
|
|
39
39
|
def self.validate!(style)
|
40
40
|
return if style.nil?
|
@@ -51,8 +51,20 @@ module WhirledPeas
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
def self.inherit(parent)
|
55
|
+
border = new(parent.theme)
|
56
|
+
border.inherit(parent)
|
57
|
+
border
|
58
|
+
end
|
59
|
+
|
60
|
+
attr_reader :theme
|
61
|
+
|
54
62
|
attr_writer :left, :top, :right, :bottom, :inner_horiz, :inner_vert
|
55
63
|
|
64
|
+
def initialize(theme)
|
65
|
+
@theme = theme
|
66
|
+
end
|
67
|
+
|
56
68
|
def left?
|
57
69
|
@left == true
|
58
70
|
end
|
@@ -82,20 +94,29 @@ module WhirledPeas
|
|
82
94
|
end
|
83
95
|
|
84
96
|
def style
|
85
|
-
@
|
97
|
+
@_style || theme.border_style || Styles::DEFAULT
|
86
98
|
end
|
87
99
|
|
88
100
|
def style=(val)
|
89
|
-
@
|
101
|
+
@_style = Styles.validate!(val)
|
90
102
|
end
|
91
103
|
|
92
104
|
def color=(val)
|
93
|
-
@
|
105
|
+
@_color = TextColor.validate!(val)
|
94
106
|
end
|
95
107
|
|
96
108
|
def color
|
97
|
-
@
|
109
|
+
@_color || theme.border_color
|
98
110
|
end
|
111
|
+
|
112
|
+
def inherit(parent)
|
113
|
+
@_style = parent._style
|
114
|
+
@_color = parent._color
|
115
|
+
end
|
116
|
+
|
117
|
+
protected
|
118
|
+
|
119
|
+
attr_reader :_style, :_color
|
99
120
|
end
|
100
121
|
end
|
101
122
|
end
|
@@ -43,11 +43,11 @@ module WhirledPeas
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def bright
|
46
|
-
bright? ? self : self.class.new(
|
46
|
+
bright? ? self : self.class.new(code + Utils::Ansi::BRIGHT_OFFSET, true)
|
47
47
|
end
|
48
48
|
|
49
49
|
def hash
|
50
|
-
[
|
50
|
+
[code, bright].hash
|
51
51
|
end
|
52
52
|
|
53
53
|
def ==(other)
|
@@ -56,12 +56,16 @@ module WhirledPeas
|
|
56
56
|
alias_method :eq?, :==
|
57
57
|
|
58
58
|
def to_s
|
59
|
-
|
59
|
+
code.to_s
|
60
60
|
end
|
61
61
|
|
62
62
|
def inspect
|
63
|
-
"#{self.class.name.split('::').last}(code=#{
|
63
|
+
"#{self.class.name.split('::').last}(code=#{code}, bright=#{bright?})"
|
64
64
|
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
attr_reader :code
|
65
69
|
end
|
66
70
|
private_constant :Color
|
67
71
|
end
|
@@ -96,7 +96,7 @@ module WhirledPeas
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def border
|
99
|
-
@_border ||= Border.new
|
99
|
+
@_border ||= Border.new(theme)
|
100
100
|
end
|
101
101
|
|
102
102
|
def flow=(flow)
|
@@ -175,13 +175,20 @@ module WhirledPeas
|
|
175
175
|
@_padding ||= Padding.new
|
176
176
|
end
|
177
177
|
|
178
|
-
def
|
179
|
-
|
180
|
-
|
178
|
+
def set_content_start(left: nil, top: nil, right: nil, bottom: nil)
|
179
|
+
if left && right
|
180
|
+
raise ArgumentError, 'Setting left and right content_start is not supported'
|
181
|
+
elsif top && bottom
|
182
|
+
raise ArgumentError, 'Setting top and bottom content_start is not supported'
|
183
|
+
end
|
184
|
+
content_start.left = left if left
|
185
|
+
content_start.top = top if top
|
186
|
+
content_start.right = right if right
|
187
|
+
content_start.bottom = bottom if bottom
|
181
188
|
end
|
182
189
|
|
183
|
-
def
|
184
|
-
@
|
190
|
+
def content_start
|
191
|
+
@_content_start ||= Position.new
|
185
192
|
end
|
186
193
|
|
187
194
|
def set_scrollbar(horiz: nil, vert: nil)
|
@@ -212,7 +219,7 @@ module WhirledPeas
|
|
212
219
|
def inherit(parent)
|
213
220
|
super
|
214
221
|
return unless parent.is_a?(ContainerSettings)
|
215
|
-
|
222
|
+
@_border = Border.inherit(parent.border)
|
216
223
|
end
|
217
224
|
|
218
225
|
protected
|
@@ -34,6 +34,8 @@ module WhirledPeas
|
|
34
34
|
def debug_value(value)
|
35
35
|
return if value.nil?
|
36
36
|
case value
|
37
|
+
when Theme
|
38
|
+
nil
|
37
39
|
when Position
|
38
40
|
position_value(value)
|
39
41
|
when Margin
|
@@ -73,7 +75,7 @@ module WhirledPeas
|
|
73
75
|
def border_value(border)
|
74
76
|
values = non_defaults(
|
75
77
|
border,
|
76
|
-
Border.new,
|
78
|
+
Border.new(settings.theme),
|
77
79
|
%i[left? top? right? bottom? inner_horiz? inner_vert? style color]
|
78
80
|
)
|
79
81
|
return if values == ''
|
@@ -8,22 +8,30 @@ module WhirledPeas
|
|
8
8
|
module Settings
|
9
9
|
class ElementSettings
|
10
10
|
def self.inherit(parent)
|
11
|
-
child = self.new
|
11
|
+
child = self.new(parent.theme)
|
12
12
|
child.inherit(parent)
|
13
13
|
child
|
14
14
|
end
|
15
15
|
|
16
|
-
attr_accessor :width, :height
|
16
|
+
attr_accessor :theme, :width, :height
|
17
|
+
|
18
|
+
def initialize(theme)
|
19
|
+
@theme = theme
|
20
|
+
end
|
17
21
|
|
18
22
|
def validate!
|
19
23
|
end
|
20
24
|
|
21
25
|
def bg_color
|
22
|
-
@_bg_color ||
|
26
|
+
@_bg_color || theme.bg_color
|
23
27
|
end
|
24
28
|
|
25
29
|
def bg_color=(color)
|
26
|
-
|
30
|
+
if color == :highlight
|
31
|
+
@_bg_color = theme.highlight_bg_color
|
32
|
+
else
|
33
|
+
@_bg_color = BgColor.validate!(color)
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
37
|
def bold?
|
@@ -35,11 +43,15 @@ module WhirledPeas
|
|
35
43
|
end
|
36
44
|
|
37
45
|
def color
|
38
|
-
@_color ||
|
46
|
+
@_color || theme.color
|
39
47
|
end
|
40
48
|
|
41
49
|
def color=(color)
|
42
|
-
|
50
|
+
if color == :highlight
|
51
|
+
@_color = theme.highlight_color
|
52
|
+
else
|
53
|
+
@_color = TextColor.validate!(color)
|
54
|
+
end
|
43
55
|
end
|
44
56
|
|
45
57
|
def underline?
|