whirled_peas 0.5.0 → 0.6.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/.travis.yml +1 -0
- data/CHANGELOG.md +6 -0
- data/README.md +62 -29
- data/Rakefile +3 -2
- data/examples/intro.rb +52 -0
- data/examples/scrolling.rb +53 -0
- data/lib/whirled_peas.rb +2 -8
- data/lib/whirled_peas/command_line.rb +25 -33
- data/lib/whirled_peas/graphics/box_painter.rb +9 -1
- data/lib/whirled_peas/graphics/composer.rb +80 -0
- data/lib/whirled_peas/graphics/container_coords.rb +18 -8
- data/lib/whirled_peas/graphics/container_dimensions.rb +17 -7
- data/lib/whirled_peas/graphics/container_painter.rb +151 -33
- data/lib/whirled_peas/graphics/debugger.rb +10 -1
- data/lib/whirled_peas/graphics/grid_painter.rb +14 -2
- data/lib/whirled_peas/graphics/mock_screen.rb +1 -1
- data/lib/whirled_peas/graphics/painter.rb +1 -6
- data/lib/whirled_peas/graphics/renderer.rb +1 -29
- data/lib/whirled_peas/graphics/screen.rb +8 -3
- data/lib/whirled_peas/graphics/text_painter.rb +6 -4
- data/lib/whirled_peas/settings/container_settings.rb +11 -0
- data/lib/whirled_peas/settings/debugger.rb +9 -0
- data/lib/whirled_peas/settings/grid_settings.rb +4 -0
- data/lib/whirled_peas/settings/scrollbar.rb +15 -0
- data/lib/whirled_peas/version.rb +1 -1
- data/screen_test/rendered/elements/box.frame +1 -1
- data/screen_test/rendered/elements/grid.frame +1 -1
- data/screen_test/rendered/elements/screen_overflow.frame +1 -0
- data/screen_test/rendered/elements/text.frame +1 -1
- data/screen_test/rendered/elements/text_multiline.frame +1 -1
- data/screen_test/rendered/settings/align/box.frame +1 -1
- data/screen_test/rendered/settings/align/box.rb +14 -10
- data/screen_test/rendered/settings/align/children_center.frame +1 -1
- data/screen_test/rendered/settings/align/children_left.frame +1 -1
- data/screen_test/rendered/settings/align/children_right.frame +1 -1
- data/screen_test/rendered/settings/align/grid.frame +1 -1
- data/screen_test/rendered/settings/ansi/bold.frame +1 -1
- data/screen_test/rendered/settings/ansi/color.frame +1 -1
- data/screen_test/rendered/settings/ansi/underline.frame +1 -1
- data/screen_test/rendered/settings/border.frame +1 -1
- data/screen_test/rendered/settings/flow/box_b2t.frame +1 -0
- data/screen_test/rendered/settings/flow/box_b2t.rb +24 -0
- data/screen_test/rendered/settings/flow/{l2r.frame → box_l2r.frame} +1 -1
- data/screen_test/rendered/settings/flow/{l2r.rb → box_l2r.rb} +0 -0
- data/screen_test/rendered/settings/flow/box_r2l.frame +1 -0
- data/screen_test/rendered/settings/flow/box_r2l.rb +24 -0
- data/screen_test/rendered/settings/flow/{t2b.frame → box_t2b.frame} +1 -1
- data/screen_test/rendered/settings/flow/{t2b.rb → box_t2b.rb} +0 -0
- data/screen_test/rendered/settings/flow/grid_b2t.frame +1 -0
- data/screen_test/rendered/settings/flow/grid_b2t.rb +14 -0
- data/screen_test/rendered/settings/flow/grid_l2r.frame +1 -0
- data/screen_test/rendered/settings/flow/grid_l2r.rb +14 -0
- data/screen_test/rendered/settings/flow/grid_r2l.frame +1 -0
- data/screen_test/rendered/settings/flow/grid_r2l.rb +14 -0
- data/screen_test/rendered/settings/flow/grid_t2b.frame +1 -0
- data/screen_test/rendered/settings/flow/grid_t2b.rb +14 -0
- data/screen_test/rendered/settings/height/box.frame +1 -1
- data/screen_test/rendered/settings/height/grid.frame +1 -1
- data/screen_test/rendered/settings/height/overflow_box.frame +1 -1
- data/screen_test/rendered/settings/height/overflow_box_l2r.frame +1 -1
- data/screen_test/rendered/settings/height/overflow_box_t2b.frame +1 -1
- data/screen_test/rendered/settings/height/overflow_grid.frame +1 -1
- data/screen_test/rendered/settings/margin.frame +1 -1
- data/screen_test/rendered/settings/padding.frame +1 -1
- data/screen_test/rendered/settings/position/box_left.frame +1 -1
- data/screen_test/rendered/settings/position/box_left_negative.frame +1 -1
- data/screen_test/rendered/settings/position/box_top.frame +1 -1
- data/screen_test/rendered/settings/position/box_top_negative.frame +1 -1
- data/screen_test/rendered/settings/position/grid_left.frame +1 -1
- data/screen_test/rendered/settings/position/grid_left_negative.frame +1 -1
- data/screen_test/rendered/settings/position/grid_top.frame +1 -1
- data/screen_test/rendered/settings/position/grid_top_negative.frame +1 -1
- data/screen_test/rendered/settings/scroll/horiz_box.frame +1 -0
- data/screen_test/rendered/settings/scroll/horiz_box.rb +15 -0
- data/screen_test/rendered/settings/scroll/vert_box.frame +1 -0
- data/screen_test/rendered/settings/scroll/vert_box.rb +18 -0
- data/screen_test/rendered/settings/title_font.frame +1 -1
- data/screen_test/rendered/settings/width/box.frame +1 -1
- data/screen_test/rendered/settings/width/grid.frame +1 -1
- data/screen_test/rendered/settings/width/overflow_box.frame +1 -1
- data/screen_test/rendered/settings/width/overflow_box_l2r.frame +1 -1
- data/screen_test/rendered/settings/width/overflow_box_t2b.frame +1 -1
- data/screen_test/rendered/settings/width/overflow_grid.frame +1 -1
- data/screen_test/screen_tester.rb +13 -3
- metadata +27 -16
- data/bin/debug +0 -35
- data/lib/whirled_peas/debugger.rb +0 -80
- data/lib/whirled_peas/template.rb +0 -5
- data/lib/whirled_peas/template/box_element.rb +0 -8
- data/lib/whirled_peas/template/composer.rb +0 -68
- data/lib/whirled_peas/template/container.rb +0 -28
- data/lib/whirled_peas/template/debugger.rb +0 -34
- data/lib/whirled_peas/template/element.rb +0 -13
- data/lib/whirled_peas/template/grid_element.rb +0 -8
- data/lib/whirled_peas/template/text_element.rb +0 -24
@@ -7,7 +7,7 @@ module WhirledPeas
|
|
7
7
|
def paint(canvas, &block)
|
8
8
|
super
|
9
9
|
return unless canvas.writable?
|
10
|
-
if
|
10
|
+
if settings.horizontal_flow?
|
11
11
|
paint_horizontally(canvas, &block)
|
12
12
|
else
|
13
13
|
paint_vertically(canvas, &block)
|
@@ -37,6 +37,14 @@ module WhirledPeas
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
+
def each_child(&block)
|
41
|
+
if settings.reverse_flow?
|
42
|
+
children.reverse.each(&block)
|
43
|
+
else
|
44
|
+
super
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
40
48
|
private
|
41
49
|
|
42
50
|
def paint_horizontally(canvas, &block)
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'whirled_peas/settings/box_settings'
|
2
|
+
require 'whirled_peas/settings/grid_settings'
|
3
|
+
require 'whirled_peas/settings/text_settings'
|
4
|
+
|
5
|
+
require_relative 'box_painter'
|
6
|
+
require_relative 'grid_painter'
|
7
|
+
require_relative 'text_painter'
|
8
|
+
|
9
|
+
module WhirledPeas
|
10
|
+
module Graphics
|
11
|
+
class Composer
|
12
|
+
# List of classes that convert nicely to a string
|
13
|
+
STRINGALBE_CLASSES = [FalseClass, Float, Integer, NilClass, String, Symbol, TrueClass]
|
14
|
+
private_constant :STRINGALBE_CLASSES
|
15
|
+
|
16
|
+
def self.stringable?(value)
|
17
|
+
STRINGALBE_CLASSES.include?(value.class)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.next_name
|
21
|
+
@counter ||= 0
|
22
|
+
@counter += 1
|
23
|
+
"Element-#{@counter}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.build
|
27
|
+
settings = Settings::BoxSettings.new
|
28
|
+
template = BoxPainter.new('TEMPLATE', settings)
|
29
|
+
composer = Composer.new(template)
|
30
|
+
value = yield composer, settings
|
31
|
+
if !template.children? && stringable?(value)
|
32
|
+
composer.add_text { value.to_s }
|
33
|
+
end
|
34
|
+
template
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_reader :painter
|
38
|
+
|
39
|
+
def initialize(painter)
|
40
|
+
@painter = painter
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_text(name=self.class.next_name, &block)
|
44
|
+
child_settings = Settings::TextSettings.inherit(painter.settings)
|
45
|
+
child = TextPainter.new(name, child_settings)
|
46
|
+
# TextPainters are not composable, so yield nil
|
47
|
+
content = yield nil, child_settings
|
48
|
+
unless self.class.stringable?(content)
|
49
|
+
raise ArgumentError, "Unsupported type for text: #{content.class}"
|
50
|
+
end
|
51
|
+
child.content = content.to_s
|
52
|
+
painter.add_child(child)
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_box(name=self.class.next_name, &block)
|
56
|
+
child_settings = Settings::BoxSettings.inherit(painter.settings)
|
57
|
+
child = BoxPainter.new(name, child_settings)
|
58
|
+
composer = self.class.new(child)
|
59
|
+
value = yield composer, child.settings
|
60
|
+
painter.add_child(child)
|
61
|
+
if !child.children? && self.class.stringable?(value)
|
62
|
+
composer.add_text("#{name}-Text") { value.to_s }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def add_grid(name=self.class.next_name, &block)
|
67
|
+
child_settings = Settings::GridSettings.inherit(painter.settings)
|
68
|
+
child = GridPainter.new(name, child_settings)
|
69
|
+
composer = self.class.new(child)
|
70
|
+
values = yield composer, child.settings
|
71
|
+
painter.add_child(child)
|
72
|
+
if !child.children? && values.is_a?(Array)
|
73
|
+
values.each.with_index do |value, index|
|
74
|
+
composer.add_text("#{name}-Text-#{index}") { value.to_s }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -32,27 +32,37 @@ module WhirledPeas
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def content_left(col_index=0)
|
35
|
-
padding_left + settings.padding.left + col_index * grid_width
|
35
|
+
padding_left + settings.padding.left + col_index * grid_width
|
36
36
|
end
|
37
37
|
|
38
38
|
def content_top(row_index=0)
|
39
|
-
padding_top + settings.padding.top + row_index * grid_height
|
39
|
+
padding_top + settings.padding.top + row_index * grid_height
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
44
|
-
settings.padding.left +
|
42
|
+
def inner_grid_width
|
43
|
+
settings.padding.left +
|
45
44
|
dimensions.content_width +
|
46
45
|
settings.padding.right
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
(
|
51
|
-
|
48
|
+
def grid_width
|
49
|
+
(settings.border.inner_vert? ? 1 : 0) +
|
50
|
+
inner_grid_width +
|
51
|
+
(settings.scrollbar.vert? ? 1 : 0)
|
52
|
+
end
|
53
|
+
|
54
|
+
def inner_grid_height
|
55
|
+
settings.padding.top +
|
52
56
|
dimensions.content_height +
|
53
57
|
settings.padding.bottom
|
54
58
|
end
|
55
59
|
|
60
|
+
def grid_height
|
61
|
+
(settings.border.inner_horiz? ? 1 : 0) +
|
62
|
+
inner_grid_height +
|
63
|
+
(settings.scrollbar.horiz? ? 1 : 0)
|
64
|
+
end
|
65
|
+
|
56
66
|
private
|
57
67
|
|
58
68
|
attr_reader :canvas, :settings, :dimensions
|
@@ -1,11 +1,13 @@
|
|
1
1
|
module WhirledPeas
|
2
2
|
module Graphics
|
3
3
|
class ContainerDimensions
|
4
|
-
attr_reader :content_width, :content_height, :num_cols, :num_rows
|
4
|
+
attr_reader :content_width, :content_height, :children_width, :children_height, :num_cols, :num_rows
|
5
5
|
|
6
6
|
def initialize(settings, content_width, content_height, num_cols=1, num_rows=1)
|
7
7
|
@content_width = settings.width || content_width
|
8
8
|
@content_height = settings.height || content_height
|
9
|
+
@children_width = content_width
|
10
|
+
@children_height = content_height
|
9
11
|
@num_cols = num_cols
|
10
12
|
@num_rows = num_rows
|
11
13
|
@settings = settings
|
@@ -14,21 +16,17 @@ module WhirledPeas
|
|
14
16
|
def outer_width
|
15
17
|
@outer_width ||= margin_width +
|
16
18
|
outer_border_width +
|
17
|
-
num_cols * (padding_width + content_width) +
|
19
|
+
num_cols * (padding_width + content_width + vert_scroll_width) +
|
18
20
|
(num_cols - 1) * inner_border_width
|
19
21
|
end
|
20
22
|
|
21
23
|
def outer_height
|
22
24
|
@outer_height ||= margin_height +
|
23
25
|
outer_border_height +
|
24
|
-
num_rows * (padding_height + content_height) +
|
26
|
+
num_rows * (padding_height + content_height + horiz_scroll_height) +
|
25
27
|
(num_rows - 1) * inner_border_height
|
26
28
|
end
|
27
29
|
|
28
|
-
private
|
29
|
-
|
30
|
-
attr_reader :settings
|
31
|
-
|
32
30
|
def margin_width
|
33
31
|
settings.margin.left + settings.margin.right
|
34
32
|
end
|
@@ -60,6 +58,18 @@ module WhirledPeas
|
|
60
58
|
def padding_height
|
61
59
|
settings.padding.top + settings.padding.bottom
|
62
60
|
end
|
61
|
+
|
62
|
+
def vert_scroll_width
|
63
|
+
settings.scrollbar.vert? ? 1 : 0
|
64
|
+
end
|
65
|
+
|
66
|
+
def horiz_scroll_height
|
67
|
+
settings.scrollbar.horiz? ? 1 : 0
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
attr_reader :settings
|
63
73
|
end
|
64
74
|
end
|
65
75
|
end
|
@@ -8,38 +8,39 @@ module WhirledPeas
|
|
8
8
|
class ContainerPainter < Painter
|
9
9
|
PADDING = ' '
|
10
10
|
|
11
|
-
def initialize(
|
11
|
+
def initialize(name, settings)
|
12
12
|
super
|
13
13
|
@children = []
|
14
14
|
end
|
15
15
|
|
16
16
|
def paint(canvas, &block)
|
17
17
|
return unless canvas.writable?
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
stroke_left = coords(canvas).border_left
|
23
|
-
stroke_top = coords(canvas).border_top
|
18
|
+
return unless needs_printing?
|
19
|
+
canvas_coords = coords(canvas)
|
20
|
+
stroke_left = canvas_coords.border_left
|
21
|
+
stroke_top = canvas_coords.border_top
|
24
22
|
formatting = [*settings.border.color, *settings.bg_color]
|
25
23
|
if settings.border.top?
|
26
|
-
canvas.stroke(stroke_left, stroke_top, top_border_stroke, formatting, &block)
|
24
|
+
canvas.stroke(stroke_left, stroke_top, top_border_stroke(canvas_coords), formatting, &block)
|
27
25
|
stroke_top += 1
|
28
26
|
end
|
29
|
-
|
30
|
-
middle_border = dimensions.num_rows > 1 ? middle_border_stroke : ''
|
27
|
+
middle_border = dimensions.num_rows > 1 ? middle_border_stroke(canvas_coords) : ''
|
31
28
|
dimensions.num_rows.times do |row_num|
|
32
29
|
if row_num > 0 && settings.border.inner_horiz?
|
33
30
|
canvas.stroke(stroke_left, stroke_top, middle_border, formatting, &block)
|
34
31
|
stroke_top += 1
|
35
32
|
end
|
36
|
-
|
37
|
-
canvas.stroke(stroke_left, stroke_top,
|
33
|
+
canvas_coords.inner_grid_height.times do |row_within_cell|
|
34
|
+
canvas.stroke(stroke_left, stroke_top, content_line_stroke(canvas_coords, row_within_cell), formatting, &block)
|
35
|
+
stroke_top += 1
|
36
|
+
end
|
37
|
+
if settings.scrollbar.horiz?
|
38
|
+
canvas.stroke(stroke_left, stroke_top, bottom_scroll_stroke(canvas_coords), formatting, &block)
|
38
39
|
stroke_top += 1
|
39
40
|
end
|
40
41
|
end
|
41
42
|
if settings.border.bottom?
|
42
|
-
canvas.stroke(stroke_left, stroke_top, bottom_border_stroke, formatting, &block)
|
43
|
+
canvas.stroke(stroke_left, stroke_top, bottom_border_stroke(canvas_coords), formatting, &block)
|
43
44
|
stroke_top += 1
|
44
45
|
end
|
45
46
|
end
|
@@ -52,6 +53,10 @@ module WhirledPeas
|
|
52
53
|
children.length
|
53
54
|
end
|
54
55
|
|
56
|
+
def children?
|
57
|
+
num_children > 0
|
58
|
+
end
|
59
|
+
|
55
60
|
def each_child(&block)
|
56
61
|
children.each(&block)
|
57
62
|
end
|
@@ -60,55 +65,168 @@ module WhirledPeas
|
|
60
65
|
|
61
66
|
attr_reader :children
|
62
67
|
|
68
|
+
def needs_printing?
|
69
|
+
return true if settings.bg_color
|
70
|
+
return true if settings.border.outer?
|
71
|
+
return true if dimensions.num_cols > 1 && settings.border.inner_vert?
|
72
|
+
return true if dimensions.num_rows > 1 && settings.border.inner_horiz?
|
73
|
+
settings.scrollbar.horiz? || settings.scrollbar.vert?
|
74
|
+
end
|
75
|
+
|
63
76
|
def coords(canvas)
|
64
77
|
ContainerCoords.new(canvas, dimensions, settings)
|
65
78
|
end
|
66
79
|
|
67
|
-
def line_stroke(left_border,
|
80
|
+
def line_stroke(left_border, junc_border, right_border, &block)
|
68
81
|
stroke = ''
|
69
82
|
stroke += left_border if settings.border.left?
|
70
83
|
dimensions.num_cols.times do |col_num|
|
71
84
|
stroke += junc_border if col_num > 0 && settings.border.inner_vert?
|
72
|
-
stroke +=
|
85
|
+
stroke += yield
|
73
86
|
end
|
74
87
|
stroke += right_border if settings.border.right?
|
75
88
|
stroke
|
76
89
|
end
|
77
90
|
|
78
|
-
def top_border_stroke
|
91
|
+
def top_border_stroke(canvas_coords)
|
79
92
|
line_stroke(
|
80
93
|
settings.border.style.top_left,
|
81
|
-
settings.border.style.top_horiz,
|
82
94
|
settings.border.style.top_junc,
|
83
95
|
settings.border.style.top_right
|
84
|
-
)
|
85
|
-
|
86
|
-
|
87
|
-
def content_line_stroke
|
88
|
-
line_stroke(
|
89
|
-
settings.border.style.left_vert,
|
90
|
-
PADDING,
|
91
|
-
settings.border.style.middle_vert,
|
92
|
-
settings.border.style.right_vert
|
93
|
-
)
|
96
|
+
) do
|
97
|
+
settings.border.style.top_horiz * (canvas_coords.inner_grid_width + (settings.scrollbar.vert? ? 1 : 0))
|
98
|
+
end
|
94
99
|
end
|
95
100
|
|
96
|
-
def middle_border_stroke
|
101
|
+
def middle_border_stroke(canvas_coords)
|
97
102
|
line_stroke(
|
98
103
|
settings.border.style.left_junc,
|
99
|
-
settings.border.style.middle_horiz,
|
100
104
|
settings.border.style.cross_junc,
|
101
105
|
settings.border.style.right_junc
|
102
|
-
)
|
106
|
+
) do
|
107
|
+
settings.border.style.middle_horiz * (canvas_coords.inner_grid_width + (settings.scrollbar.vert? ? 1 : 0))
|
108
|
+
end
|
103
109
|
end
|
104
110
|
|
105
|
-
def bottom_border_stroke
|
111
|
+
def bottom_border_stroke(canvas_coords)
|
106
112
|
line_stroke(
|
107
113
|
settings.border.style.bottom_left,
|
108
|
-
settings.border.style.bottom_horiz,
|
109
114
|
settings.border.style.bottom_junc,
|
110
115
|
settings.border.style.bottom_right
|
111
|
-
)
|
116
|
+
) do
|
117
|
+
settings.border.style.bottom_horiz * (canvas_coords.inner_grid_width + (settings.scrollbar.vert? ? 1 : 0))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def content_line_stroke(canvas_coords, row_within_cell)
|
122
|
+
line_stroke(
|
123
|
+
settings.border.style.left_vert,
|
124
|
+
settings.border.style.middle_vert,
|
125
|
+
settings.border.style.right_vert,
|
126
|
+
) do
|
127
|
+
if settings.scrollbar.vert?
|
128
|
+
if dimensions.children_height <= canvas_coords.grid_height || children.first.settings.position.top > 0
|
129
|
+
scrollbar_char = GUTTER
|
130
|
+
else
|
131
|
+
scrollbar_char = vert_scroll_char(
|
132
|
+
dimensions.children_height + dimensions.padding_height,
|
133
|
+
canvas_coords.inner_grid_height,
|
134
|
+
-children.first.settings.position.top,
|
135
|
+
row_within_cell
|
136
|
+
)
|
137
|
+
end
|
138
|
+
PADDING * canvas_coords.inner_grid_width + scrollbar_char
|
139
|
+
else
|
140
|
+
PADDING * canvas_coords.inner_grid_width
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def bottom_scroll_stroke(canvas_coords)
|
146
|
+
line_stroke(
|
147
|
+
settings.border.style.left_vert,
|
148
|
+
settings.border.style.middle_vert,
|
149
|
+
settings.border.style.right_vert,
|
150
|
+
) do
|
151
|
+
canvas_coords.inner_grid_width.times.map do |col_within_cell|
|
152
|
+
horiz_scroll_char(
|
153
|
+
dimensions.children_width + dimensions.padding_width,
|
154
|
+
canvas_coords.inner_grid_width,
|
155
|
+
-children.first.settings.position.left,
|
156
|
+
col_within_cell
|
157
|
+
)
|
158
|
+
end.join
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
GUTTER = ' '
|
163
|
+
HORIZONTAL = %w[▗ ▄ ▖]
|
164
|
+
VERTICAL = %w[
|
165
|
+
▗
|
166
|
+
▐
|
167
|
+
▝
|
168
|
+
]
|
169
|
+
|
170
|
+
def horiz_scroll_char(col_count, viewable_col_count, first_visible_col, curr_col)
|
171
|
+
scroll_char(col_count, viewable_col_count, first_visible_col, curr_col, HORIZONTAL)
|
172
|
+
end
|
173
|
+
|
174
|
+
def vert_scroll_char(row_count, viewable_row_count, first_visible_row, curr_row)
|
175
|
+
scroll_char(row_count, viewable_row_count, first_visible_row, curr_row, VERTICAL)
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
|
180
|
+
def scroll_char(total_count, viewable_count, first_visible, curr, chars)
|
181
|
+
return GUTTER unless total_count > 0 && viewable_count > 0
|
182
|
+
# The scroll handle has the exact same relative size and position in the scroll gutter
|
183
|
+
# that the viewable content has in the total content area. For example, a content area
|
184
|
+
# that is 50 columns wide with a view port that is 20 columns wide might look like
|
185
|
+
#
|
186
|
+
# +---------1-----****2*********3******---4---------+
|
187
|
+
# | * * |
|
188
|
+
# | hidden * viewable * hidden |
|
189
|
+
# | * * |
|
190
|
+
# +---------1-----****2*********3******---4---------+
|
191
|
+
#
|
192
|
+
# The scoll gutter, would look like
|
193
|
+
#
|
194
|
+
# |......********.....|
|
195
|
+
#
|
196
|
+
# Scrolling all the way to the right results in
|
197
|
+
#
|
198
|
+
# +---------1---------2---------3*********4*********+
|
199
|
+
# | * *
|
200
|
+
# | hidden * viewable *
|
201
|
+
# | * *
|
202
|
+
# +---------1---------2---------3*********4*********+
|
203
|
+
# |...........********|
|
204
|
+
|
205
|
+
# The first task of determining how much of the handle is visible in a row/column is to
|
206
|
+
# calculate the range (as a precentage of the total) of viewable items
|
207
|
+
viewable_start = first_visible.to_f / total_count
|
208
|
+
viewable_end = (first_visible + viewable_count).to_f / total_count
|
209
|
+
|
210
|
+
# Always use the same length for the scroll bar so it does not give an inchworm effect
|
211
|
+
# as it scrolls along.
|
212
|
+
#
|
213
|
+
# Also, double the value now to get granularity for half width
|
214
|
+
# scrollbar characters.
|
215
|
+
scrollbar_length = ((2 * viewable_count ** 2).to_f / total_count).ceil
|
216
|
+
scrollbar_start = ((2 * first_visible * viewable_count).to_f / total_count).floor
|
217
|
+
|
218
|
+
first_half = (scrollbar_start...scrollbar_start + scrollbar_length).include?(2 * curr)
|
219
|
+
second_half = (scrollbar_start...scrollbar_start + scrollbar_length).include?(2 * curr + 1)
|
220
|
+
|
221
|
+
if first_half && second_half
|
222
|
+
chars[1]
|
223
|
+
elsif first_half
|
224
|
+
chars[2]
|
225
|
+
elsif second_half
|
226
|
+
chars[0]
|
227
|
+
else
|
228
|
+
GUTTER
|
229
|
+
end
|
112
230
|
end
|
113
231
|
end
|
114
232
|
private_constant :ContainerPainter
|