bash-visual 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +1 -1
- data/bash-visual-1.0.6.gem +0 -0
- data/example/hello_world.rb +3 -6
- data/example/painter.rb +36 -0
- data/example/scroll.rb +45 -0
- data/lib/bash-visual.rb +2 -0
- data/lib/bash-visual/builder.rb +6 -4
- data/lib/bash-visual/console.rb +12 -80
- data/lib/bash-visual/fixed_object.rb +16 -0
- data/lib/bash-visual/font.rb +81 -43
- data/lib/bash-visual/horizontal_scroll.rb +21 -34
- data/lib/bash-visual/painter.rb +110 -0
- data/lib/bash-visual/scroll.rb +65 -64
- data/lib/bash-visual/version.rb +1 -1
- data/lib/bash-visual/vertical_scroll.rb +19 -31
- data/test/console_test.rb +15 -0
- data/test/font_test.rb +38 -0
- data/test/helper.rb +1 -0
- data/test/painter_test.rb +32 -0
- data/test/scroll_test.rb +61 -0
- data/test/vertical_scroll_test.rb +16 -0
- metadata +11 -2
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
Bash visualisation library
|
4
4
|
|
5
5
|
## Description
|
6
|
-
**BashVisual** simplifies Unix-console operation (bash, csh etc). It uses _tput_ and standard Unix-terminal facilities. It is also thread-safe.
|
6
|
+
**BashVisual** simplifies Unix-console operation (sh, bash, csh etc). It uses _tput_ and standard Unix-terminal facilities. It is also thread-safe.
|
7
7
|
|
8
8
|
BashVisual allows:
|
9
9
|
- control position, colors and text's form
|
Binary file
|
data/example/hello_world.rb
CHANGED
@@ -3,12 +3,9 @@ $:.push File.expand_path('../../lib', __FILE__)
|
|
3
3
|
require 'bash-visual'
|
4
4
|
include Bash_Visual
|
5
5
|
|
6
|
-
|
7
|
-
main_color = Font.new(:bold, :green)
|
8
|
-
|
9
|
-
console = Console.new(main_color)
|
6
|
+
console = Console.new
|
10
7
|
console.clear
|
11
8
|
|
12
|
-
console.draw_window
|
13
|
-
console.write_to_position
|
9
|
+
console.draw_window [3, 3], [18, 5], 'Example', {font: Font.new(:std, :red)}
|
10
|
+
console.write_to_position 5, 4, 'Hello World!', Font.new(:bold)
|
14
11
|
console.position = [0, 8]
|
data/example/painter.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
$:.push File.expand_path('../../lib', __FILE__)
|
2
|
+
|
3
|
+
require 'bash-visual'
|
4
|
+
include Bash_Visual
|
5
|
+
|
6
|
+
console = Console.new
|
7
|
+
console.clear
|
8
|
+
Thread.new {
|
9
|
+
100.times {
|
10
|
+
x, y = 0, 0
|
11
|
+
width, height = 20, 12
|
12
|
+
5.times {
|
13
|
+
x, y = x+1, y+1
|
14
|
+
width, height = width-2, height-2
|
15
|
+
console.draw_border([x, y], [width, height], {font: Font::rand_font})
|
16
|
+
sleep 0.08
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
Thread.new {
|
22
|
+
100.times {
|
23
|
+
x, y = 22, 0
|
24
|
+
width, height = 20, 12
|
25
|
+
5.times {
|
26
|
+
x, y = x+1, y+1
|
27
|
+
width, height = width-2, height-2
|
28
|
+
console.draw_filled_rectangle([x, y], [width, height], Font::rand_color(:black))
|
29
|
+
sleep 0.09
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
}
|
34
|
+
|
35
|
+
sleep 10
|
36
|
+
console.position = [0, 12]
|
data/example/scroll.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../../lib', __FILE__)
|
3
|
+
require 'bash-visual'
|
4
|
+
include Bash_Visual
|
5
|
+
|
6
|
+
console = Console.new
|
7
|
+
console.clear
|
8
|
+
|
9
|
+
console.draw_window([32, 0] ,[42, 11], 'Vertical scroll')
|
10
|
+
console.draw_window([0, 12] ,[73, 6], 'Horizontal scroll')
|
11
|
+
|
12
|
+
v_scroll = VerticalScroll.new(
|
13
|
+
position: [33, 1],
|
14
|
+
size: [39, 9],
|
15
|
+
prefix: ->{Time.now.strftime('%H-%M-%S:%3N') + ' '}
|
16
|
+
)
|
17
|
+
|
18
|
+
h_scroll = HorizontalScroll.new(
|
19
|
+
position: [2, 12],
|
20
|
+
size: [70, 4],
|
21
|
+
fixed_message_block_size: 20,
|
22
|
+
separator: true
|
23
|
+
)
|
24
|
+
|
25
|
+
phrases =[
|
26
|
+
"Bash is a Unix shell",
|
27
|
+
"GNU’s Not UNIX",
|
28
|
+
"Answer to the Ultimate Question of Life, the Universe, and Everything"]
|
29
|
+
|
30
|
+
|
31
|
+
Thread.new {
|
32
|
+
10.times do
|
33
|
+
h_scroll.add phrases.sample
|
34
|
+
sleep 0.3
|
35
|
+
end
|
36
|
+
}
|
37
|
+
Thread.new {
|
38
|
+
10.times do
|
39
|
+
v_scroll.add phrases.sample
|
40
|
+
sleep 0.15
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
sleep 4
|
45
|
+
console.position = [1,18]
|
data/lib/bash-visual.rb
CHANGED
data/lib/bash-visual/builder.rb
CHANGED
@@ -42,7 +42,7 @@ module Bash_Visual
|
|
42
42
|
bash
|
43
43
|
end
|
44
44
|
|
45
|
-
def write_to_position(x, y, text, font =
|
45
|
+
def write_to_position(x, y, text, font = nil)
|
46
46
|
bash = ''
|
47
47
|
bash << save_position()
|
48
48
|
bash << move_position(x, y)
|
@@ -51,12 +51,14 @@ module Bash_Visual
|
|
51
51
|
bash
|
52
52
|
end
|
53
53
|
|
54
|
-
def write(text, font =
|
54
|
+
def write(text, font = nil)
|
55
|
+
return text if font.nil?
|
55
56
|
font.to_bash + text + Font::RESET
|
56
57
|
end
|
57
58
|
|
58
|
-
def write_ln(text, font =
|
59
|
-
|
59
|
+
def write_ln(text, font = nil)
|
60
|
+
return text + "\n" if font.nil?
|
61
|
+
font.to_bash + text.to_s + "\n" + Font::RESET
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
data/lib/bash-visual/console.rb
CHANGED
@@ -1,30 +1,22 @@
|
|
1
1
|
module Bash_Visual
|
2
2
|
class Console
|
3
|
+
include Painter
|
4
|
+
|
3
5
|
@@mutex = Mutex.new
|
4
6
|
|
5
7
|
OUTPUT_STRING = 0
|
6
8
|
OUTPUT_WITHOUT_BLOCK = 1
|
7
9
|
OUTPUT_WITH_BLOCK = 2
|
8
|
-
# see: http://en.wikipedia.org/wiki/Box-drawing_characters
|
9
|
-
BORDER_UTF = ["\u250C","\u2500","\u2510",
|
10
|
-
"\u2502", "\u2502",
|
11
|
-
"\u2514","\u2500","\u2518"]
|
12
|
-
|
13
|
-
BORDER_UTF_ROUND = ["\u256D","\u2500","\u256E",
|
14
|
-
"\u2502", "\u2502",
|
15
|
-
"\u2570","\u2500","\u256F"]
|
16
|
-
|
17
|
-
BORDER_UTF_DOUBLE = ["\u2554","\u2550","\u2557",
|
18
|
-
"\u2551", "\u2551",
|
19
|
-
"\u255A","\u2550","\u255D"]
|
20
|
-
|
21
10
|
attr_reader :current_x, :current_y, :font;
|
22
11
|
|
23
|
-
|
12
|
+
# @param [Bash_Visual::Font] font
|
13
|
+
# @param [Object] way_output
|
14
|
+
# @param [Bash_Visual::Builder] builder
|
15
|
+
def initialize (font = Font.new, way_output = OUTPUT_WITHOUT_BLOCK, builder = Builder.new)
|
24
16
|
@current_x = 0
|
25
17
|
@current_y = 0
|
26
|
-
@
|
27
|
-
@way_output =
|
18
|
+
@font = font
|
19
|
+
@way_output = way_output
|
28
20
|
@builder = builder
|
29
21
|
end
|
30
22
|
|
@@ -42,20 +34,15 @@ module Bash_Visual
|
|
42
34
|
# Записать что-то в определенной позиции, а потом вернуться на текущую
|
43
35
|
# Если необходимо сохранить позицию после записи - используйте связку
|
44
36
|
# move_position/position= и write
|
45
|
-
def write_to_position (x, y, text, font = @
|
37
|
+
def write_to_position (x, y, text, font = @font)
|
46
38
|
print @builder.write_to_position(x, y, text, font)
|
47
39
|
end
|
48
40
|
|
49
|
-
def write (text, font = @
|
41
|
+
def write (text, font = @font)
|
50
42
|
print @builder.write(text, font)
|
51
43
|
end
|
52
44
|
|
53
|
-
def write_ln (text =
|
54
|
-
if text.nil?
|
55
|
-
print $/
|
56
|
-
return
|
57
|
-
end
|
58
|
-
|
45
|
+
def write_ln (text = '', font = @font)
|
59
46
|
print @builder.write_ln(text, font)
|
60
47
|
end
|
61
48
|
|
@@ -63,61 +50,6 @@ module Bash_Visual
|
|
63
50
|
print @builder.erase_to_end_line
|
64
51
|
end
|
65
52
|
|
66
|
-
def draw_rectangle(x, y, width, height, font = nil)
|
67
|
-
bash = ''
|
68
|
-
bash << @builder.save_position()
|
69
|
-
bash << @builder.set_position(x,y)
|
70
|
-
height.times do
|
71
|
-
bash << @builder.write(' ' * width, font)
|
72
|
-
bash << @builder.move_position(-width, 1)
|
73
|
-
end
|
74
|
-
bash << @builder.restore_position()
|
75
|
-
print @builder.write(bash, font)
|
76
|
-
end
|
77
|
-
|
78
|
-
def draw_border(x, y, width, height, font = nil, border = BORDER_UTF)
|
79
|
-
raise 'width,height must be great than 1' if (width < 2 or height < 2)
|
80
|
-
|
81
|
-
bash = ''
|
82
|
-
bash << @builder.save_position()
|
83
|
-
bash << @builder.set_position(x,y)
|
84
|
-
|
85
|
-
bash << @builder.write(border[0] + border[1] * (width - 2) + border[2], font)
|
86
|
-
(height - 2).times do
|
87
|
-
bash << @builder.move_position(-width, 1)
|
88
|
-
bash << @builder.write(border[3] + ' ' * (width - 2) + border[4], font)
|
89
|
-
end
|
90
|
-
bash << @builder.move_position(-width, 1)
|
91
|
-
bash << @builder.write(border[5] + border[6] * (width - 2) + border[7], font)
|
92
|
-
|
93
|
-
bash << @builder.restore_position()
|
94
|
-
print @builder.write(bash, font)
|
95
|
-
end
|
96
|
-
|
97
|
-
def draw_window(x, y, width, height, text = '', font = nil, border = BORDER_UTF_DOUBLE, text_wrap = ["\u2561","\u255E"])
|
98
|
-
raise 'width,height must be great than 2' if (width < 3 or height < 3)
|
99
|
-
|
100
|
-
text = text.slice(0, width - 2)
|
101
|
-
if text.size < (width - 3) && (text_wrap.instance_of? Array)
|
102
|
-
text = text_wrap[0] + text + text_wrap[1]
|
103
|
-
end
|
104
|
-
text = text.center(width - 2, border[1])
|
105
|
-
bash = ''
|
106
|
-
bash << @builder.save_position()
|
107
|
-
bash << @builder.set_position(x,y)
|
108
|
-
|
109
|
-
bash << @builder.write(border[0] + text + border[2], font)
|
110
|
-
(height - 2).times do
|
111
|
-
bash << @builder.move_position(-width, 1)
|
112
|
-
bash << @builder.write(border[3] + ' ' * (width - 2) + border[4], font)
|
113
|
-
end
|
114
|
-
bash << @builder.move_position(-width, 1)
|
115
|
-
bash << @builder.write(border[5] + border[6] * (width - 2) + border[7], font)
|
116
|
-
|
117
|
-
bash << @builder.restore_position()
|
118
|
-
print @builder.write(bash, font)
|
119
|
-
end
|
120
|
-
|
121
53
|
# Clear the screen and move to (0,0)
|
122
54
|
def clear
|
123
55
|
@current_x = 0
|
@@ -126,7 +58,7 @@ module Bash_Visual
|
|
126
58
|
end
|
127
59
|
|
128
60
|
def font= font
|
129
|
-
@
|
61
|
+
@font = font
|
130
62
|
end
|
131
63
|
|
132
64
|
def lines
|
data/lib/bash-visual/font.rb
CHANGED
@@ -2,7 +2,7 @@ module Bash_Visual
|
|
2
2
|
class Font
|
3
3
|
|
4
4
|
COLORS = [:black, :dark_red, :dark_green, :dark_yellow, :dark_blue, :dark_magenta, :dark_cyan, :grey,
|
5
|
-
|
5
|
+
:dark_grey, :red, :green, :yellow, :blue, :magenta, :cyan, :white]
|
6
6
|
|
7
7
|
TYPES = [:std, :bold, :underline, :blink]
|
8
8
|
|
@@ -32,60 +32,33 @@ module Bash_Visual
|
|
32
32
|
blink: 5
|
33
33
|
}
|
34
34
|
|
35
|
-
RESET
|
35
|
+
RESET = "\e[0m"
|
36
36
|
|
37
37
|
attr_reader :types, :foreground, :background
|
38
38
|
|
39
39
|
def initialize(types = :std, foreground = :white, background = nil)
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
41
|
+
build(types, foreground, background)
|
42
|
+
end
|
44
43
|
|
45
|
-
|
44
|
+
def add_type(type)
|
45
|
+
return false if @types.include? type
|
46
46
|
|
47
|
-
@types
|
47
|
+
@types << type
|
48
|
+
build(@types, @foreground, @background)
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
sequence << @@types_map[type]
|
52
|
-
end
|
50
|
+
true
|
51
|
+
end
|
53
52
|
|
54
|
-
|
53
|
+
def remove_type(type)
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
else
|
59
|
-
"9#{color_index - 10}"
|
60
|
-
end
|
55
|
+
return false unless @types.include? type
|
56
|
+
return false if @types == [:std]
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
sequence << if color_index < 10
|
65
|
-
"4#{color_index}"
|
66
|
-
else
|
67
|
-
"10#{color_index - 10}"
|
68
|
-
end
|
69
|
-
end
|
58
|
+
@types.delete type
|
59
|
+
build(@types, @foreground, @background)
|
70
60
|
|
71
|
-
|
72
|
-
end
|
73
|
-
|
74
|
-
|
75
|
-
# @return [Array]
|
76
|
-
def prepare_types(types)
|
77
|
-
case types
|
78
|
-
when Symbol then
|
79
|
-
[types]
|
80
|
-
when Array then
|
81
|
-
if types.size > 2
|
82
|
-
types.delete_if { |type| type == :std }
|
83
|
-
else
|
84
|
-
types
|
85
|
-
end
|
86
|
-
else
|
87
|
-
raise "types must be Array or Symbol"
|
88
|
-
end
|
61
|
+
true
|
89
62
|
end
|
90
63
|
|
91
64
|
def inspect
|
@@ -116,6 +89,71 @@ module Bash_Visual
|
|
116
89
|
end
|
117
90
|
|
118
91
|
end
|
92
|
+
|
93
|
+
def rand_font
|
94
|
+
color = self.rand_color
|
95
|
+
Font.new :std, color
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def build(types, foreground, background)
|
102
|
+
|
103
|
+
unless COLORS.include?(foreground)
|
104
|
+
raise "Illegal color #{foreground}"
|
105
|
+
end
|
106
|
+
|
107
|
+
@foreground, @background = foreground, background
|
108
|
+
|
109
|
+
@types = prepare_types types
|
110
|
+
|
111
|
+
sequence = []
|
112
|
+
@types.each do |type|
|
113
|
+
sequence << @@types_map[type]
|
114
|
+
end
|
115
|
+
|
116
|
+
color_index = @@colors_map[@foreground]
|
117
|
+
|
118
|
+
sequence << if color_index < 10
|
119
|
+
"3#{color_index}"
|
120
|
+
else
|
121
|
+
"9#{color_index - 10}"
|
122
|
+
end
|
123
|
+
|
124
|
+
if @background
|
125
|
+
color_index = @@colors_map[@background]
|
126
|
+
sequence << if color_index < 10
|
127
|
+
"4#{color_index}"
|
128
|
+
else
|
129
|
+
"10#{color_index - 10}"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
@bash_command = "\e[#{sequence.join(';')}m"
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
# @return [Array]
|
138
|
+
def prepare_types(types)
|
139
|
+
types = case types
|
140
|
+
when Symbol then
|
141
|
+
[types]
|
142
|
+
when Array then
|
143
|
+
if types.size > 2
|
144
|
+
types.delete_if { |type| type == :std }
|
145
|
+
else
|
146
|
+
types
|
147
|
+
end
|
148
|
+
else
|
149
|
+
raise "types must be Array or Symbol"
|
150
|
+
end
|
151
|
+
|
152
|
+
if types.size > 1 && types.include?(:std)
|
153
|
+
types.delete :std
|
154
|
+
end
|
155
|
+
|
156
|
+
types
|
119
157
|
end
|
120
158
|
|
121
159
|
end
|
@@ -5,18 +5,17 @@ module Bash_Visual
|
|
5
5
|
|
6
6
|
def initialize options
|
7
7
|
super
|
8
|
-
@message_block_width = @message_block_size
|
9
8
|
|
10
9
|
@separator =
|
11
10
|
if @separator == true; DEFAULT_SEPARATOR
|
12
|
-
elsif @
|
11
|
+
elsif @s.instance_of? String; @separator[0]
|
13
12
|
else nil
|
14
13
|
end
|
15
14
|
end
|
16
15
|
|
17
16
|
def get_x_position available_area_width, message_width = 0
|
18
17
|
if (@start == BEGINNING)
|
19
|
-
@x + (@
|
18
|
+
@x + (@width - available_area_width)
|
20
19
|
else
|
21
20
|
@x + available_area_width - message_width
|
22
21
|
end
|
@@ -25,45 +24,33 @@ module Bash_Visual
|
|
25
24
|
def print_message message, font, available_area
|
26
25
|
|
27
26
|
available_area_width, available_area_height = available_area
|
28
|
-
avail_width = @message_block_width > available_area_width ? available_area_width : @message_block_width
|
29
27
|
|
28
|
+
msg_block_width =
|
29
|
+
case
|
30
|
+
when @fixed_message_block_size
|
31
|
+
@fixed_message_block_size
|
32
|
+
when @max_message_block_size
|
33
|
+
@max_message_block_size
|
34
|
+
else
|
35
|
+
available_area_width
|
36
|
+
end
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
}
|
38
|
+
msg_block_width -= 1 if @separator
|
39
|
+
msg_block_width = available_area_width if msg_block_width > available_area_width
|
34
40
|
|
35
|
-
|
36
|
-
message_width = rows_wrap! message, available_area_width
|
37
|
-
else
|
38
|
-
rows_wrap! message, avail_width
|
39
|
-
message_width = avail_width
|
40
|
-
end
|
41
|
+
#msg_block_height = @adapt ? available_area_height : 1
|
41
42
|
|
42
|
-
message =
|
43
|
-
|
44
|
-
|
45
|
-
row
|
46
|
-
end
|
47
|
-
|
48
|
-
if @separator and @separator.size.nonzero?
|
49
|
-
if @adapt_size_message
|
50
|
-
if message_width < available_area_width
|
51
|
-
message.map! do |row|
|
52
|
-
row << @separator
|
53
|
-
end
|
54
|
-
message_width += 1
|
55
|
-
end
|
56
|
-
else
|
57
|
-
message.each do |row|
|
58
|
-
row[message_width-1] = @separator
|
59
|
-
end
|
43
|
+
message = Scroll.form_block message, [msg_block_width, available_area_height], @fixed_message_block_size
|
44
|
+
if @separator
|
45
|
+
message.map! do |row|
|
46
|
+
row = row + DEFAULT_SEPARATOR
|
60
47
|
end
|
61
48
|
end
|
62
49
|
|
63
|
-
|
50
|
+
msg_block_width += 1
|
51
|
+
write(get_x_position(available_area_width, msg_block_width), @y, message, font)
|
64
52
|
|
65
|
-
[available_area_width -
|
53
|
+
[available_area_width - msg_block_width, available_area_height]
|
66
54
|
end
|
67
|
-
|
68
55
|
end
|
69
56
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module Bash_Visual
|
4
|
+
module Painter
|
5
|
+
|
6
|
+
@@default_window_wrap = ["\u257C ", " \u257E"]
|
7
|
+
#@@default_window_wrap = ["", ""]
|
8
|
+
|
9
|
+
# see: http://en.wikipedia.org/wiki/Box-drawing_characters
|
10
|
+
BORDER_UTF = ["\u250C", "\u2500", "\u2510",
|
11
|
+
"\u2502", "\u2502",
|
12
|
+
"\u2514", "\u2500", "\u2518"]
|
13
|
+
|
14
|
+
BORDER_UTF_ROUND = ["\u256D", "\u2500", "\u256E",
|
15
|
+
"\u2502", "\u2502",
|
16
|
+
"\u2570", "\u2500", "\u256F"]
|
17
|
+
|
18
|
+
BORDER_UTF_DOUBLE = ["\u2554", "\u2550", "\u2557",
|
19
|
+
"\u2551", "\u2551",
|
20
|
+
"\u255A", "\u2550", "\u255D"]
|
21
|
+
|
22
|
+
# @param [Array] position
|
23
|
+
# @param [Array] size
|
24
|
+
def draw_filled_rectangle(position, size, color = :white)
|
25
|
+
x, y = *position
|
26
|
+
width, height = *size
|
27
|
+
raise 'width,height must be great than 1' if (width < 1 or height < 1)
|
28
|
+
|
29
|
+
color = color.background if color.is_a? Font
|
30
|
+
font = Font.new :std, :white, color
|
31
|
+
|
32
|
+
bash = @builder.save_position
|
33
|
+
bash << @builder.set_position(x+1, y+1)
|
34
|
+
|
35
|
+
row = @builder.write(' ' * width)
|
36
|
+
row << @builder.move_position(-width, 1)
|
37
|
+
bash << row*height
|
38
|
+
|
39
|
+
bash << @builder.restore_position
|
40
|
+
print @builder.write(bash, font)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param [Array] position
|
44
|
+
# @param [Array] size
|
45
|
+
def draw_border(position, size, params = {})
|
46
|
+
x, y = *position
|
47
|
+
width, height = *size
|
48
|
+
raise 'width,height must be great than 1' if (width < 2 or height < 2)
|
49
|
+
|
50
|
+
border = params[:border] ? params[:border] : BORDER_UTF
|
51
|
+
font = params[:font] ? params[:font] : @font
|
52
|
+
|
53
|
+
bash = @builder.save_position
|
54
|
+
bash << @builder.set_position(x, y)
|
55
|
+
body_width = width - 2
|
56
|
+
|
57
|
+
bash << @builder.write(border[0] + border[1] * body_width + border[2])
|
58
|
+
|
59
|
+
row = @builder.move_position(-width, 1)
|
60
|
+
row << @builder.write(border[3] + ' ' * body_width + border[4])
|
61
|
+
bash << row*(height - 2)
|
62
|
+
|
63
|
+
bash << @builder.move_position(-width, 1)
|
64
|
+
bash << @builder.write(border[5] + border[6] * body_width + border[7])
|
65
|
+
|
66
|
+
bash << @builder.restore_position
|
67
|
+
print @builder.write(bash, font)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @param [Array] position
|
71
|
+
# @param [Array] size
|
72
|
+
# @param [String] text
|
73
|
+
# @param [Hash] params
|
74
|
+
def draw_window(position, size, text = '', params = {})
|
75
|
+
x, y = *position
|
76
|
+
width, height = *size
|
77
|
+
raise 'width,height must be great than 2' if (width < 3 or height < 3)
|
78
|
+
|
79
|
+
wrap = params[:wrap].nil? ? @@default_window_wrap : params[:wrap]
|
80
|
+
border = params[:border] ? params[:border] : BORDER_UTF
|
81
|
+
font = params[:font] ? params[:font] : @font
|
82
|
+
|
83
|
+
body_width = width - 2
|
84
|
+
text = if wrap
|
85
|
+
wrap_size = wrap[0].size + wrap[1].size
|
86
|
+
text_width = body_width - wrap_size
|
87
|
+
wrap[0] + text.to_s[0, text_width] + wrap[1]
|
88
|
+
else
|
89
|
+
text.to_s.slice(0, body_width)
|
90
|
+
end
|
91
|
+
|
92
|
+
text = text.center(body_width, border[1])
|
93
|
+
|
94
|
+
bash = @builder.save_position
|
95
|
+
bash << @builder.set_position(x, y)
|
96
|
+
|
97
|
+
bash << @builder.write(border[0] + text + border[2])
|
98
|
+
|
99
|
+
row = @builder.move_position(-width, 1)
|
100
|
+
row << @builder.write(border[3] + ' ' * body_width + border[4])
|
101
|
+
bash << row*(height - 2)
|
102
|
+
|
103
|
+
bash << @builder.move_position(-width, 1)
|
104
|
+
bash << @builder.write(border[5] + border[6] * body_width + border[7])
|
105
|
+
|
106
|
+
bash << @builder.restore_position
|
107
|
+
print @builder.write(bash, font)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/bash-visual/scroll.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Bash_Visual
|
2
|
-
|
2
|
+
class Scroll
|
3
|
+
|
4
|
+
include FixedObject
|
3
5
|
|
4
6
|
FORWARD = 1
|
5
7
|
BACKWARD = -1
|
@@ -7,15 +9,15 @@ module Bash_Visual
|
|
7
9
|
BEGINNING = false
|
8
10
|
ENDING = true
|
9
11
|
|
10
|
-
|
12
|
+
attr_reader :console
|
11
13
|
|
12
14
|
|
13
15
|
# @param [Hash] options
|
14
16
|
#
|
15
17
|
# options = {
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# font: Font.new
|
18
|
+
# position: [x, y],
|
19
|
+
# size: [width, height],
|
20
|
+
# font: Font.new (:bold)
|
19
21
|
# start: Scroll::ENDING,
|
20
22
|
# adapt_size_message: true,
|
21
23
|
# prefix: -> { '>' }
|
@@ -25,33 +27,28 @@ module Bash_Visual
|
|
25
27
|
#
|
26
28
|
def initialize(options)
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
30
|
+
unless options[:position] && options[:size]
|
31
|
+
raise "Minimum needs: :size and :position"
|
32
|
+
end
|
31
33
|
|
32
|
-
|
33
|
-
|
34
|
+
@width, @height = options[:size]
|
35
|
+
@x, @y = options[:position]
|
36
|
+
@prefix = options[:prefix]
|
37
|
+
@adapt = options[:adapt].nil? ? true : options[:adapt]
|
38
|
+
@separator = options[:separator]
|
34
39
|
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@area_height = @area_height.to_i
|
40
|
+
@max_message_block_size = options[:max_message_block_size]
|
41
|
+
@fixed_message_block_size = options[:fixed_message_block_size]
|
38
42
|
|
39
|
-
@
|
40
|
-
@
|
43
|
+
@start = options[:start] ? ENDING : BEGINNING
|
44
|
+
@font = options[:font] ? options[:font] : Font.new
|
41
45
|
|
42
|
-
@
|
46
|
+
@stack = []
|
47
|
+
@stateless = false
|
43
48
|
|
44
|
-
@
|
49
|
+
@console = Console.new @font, Console::OUTPUT_STRING
|
50
|
+
@mutex = Mutex.new
|
45
51
|
|
46
|
-
@is_wrap = true
|
47
|
-
@start = options[:start] ? ENDING : BEGINNING
|
48
|
-
@separator = options[:separator] ? options[:separator] : false
|
49
|
-
@type = options[:type] ? options[:type] : nil
|
50
|
-
|
51
|
-
@stack = []
|
52
|
-
@console = Console.new @type, Console::OUTPUT_STRING
|
53
|
-
@mutex = Mutex.new
|
54
|
-
nil
|
55
52
|
end
|
56
53
|
|
57
54
|
def scroll(positions = 1, direction = @direction * positions)
|
@@ -60,67 +57,64 @@ module Bash_Visual
|
|
60
57
|
|
61
58
|
# @param [String] message
|
62
59
|
# @param [Bash_Visual::Font] font
|
63
|
-
def add(message, font = @
|
60
|
+
def add(message, font = @font)
|
64
61
|
|
65
|
-
|
66
|
-
|
62
|
+
unless font.background
|
63
|
+
font = Font.new font.types, font.foreground, @font.background
|
67
64
|
end
|
68
65
|
|
69
|
-
@stack << {
|
70
|
-
|
71
|
-
|
72
|
-
|
66
|
+
@stack << {message: prefix() + message.to_s, font: font}
|
67
|
+
|
68
|
+
clear
|
69
|
+
redraw
|
73
70
|
|
74
|
-
redraw()
|
75
|
-
#@stack.slice!(-index, index)
|
76
71
|
nil
|
77
72
|
end
|
78
73
|
|
79
74
|
|
80
|
-
# @param [
|
75
|
+
# @param [Proc] prefix
|
81
76
|
def prefix= (prefix)
|
82
77
|
@prefix = prefix
|
83
78
|
end
|
84
79
|
|
85
80
|
def prefix
|
86
|
-
if (defined? @prefix.call)
|
87
|
-
|
88
|
-
|
89
|
-
|
81
|
+
return @prefix[].to_s if (defined? @prefix.call)
|
82
|
+
''
|
83
|
+
end
|
84
|
+
|
85
|
+
class << self
|
86
|
+
def form_block(text, size, fixate = false)
|
87
|
+
width, height = size
|
88
|
+
result = []
|
89
|
+
|
90
|
+
height.times do |i|
|
91
|
+
line = text[i * width, width]
|
92
|
+
|
93
|
+
unless line
|
94
|
+
break unless fixate
|
95
|
+
result.fill(' ' * width, i, height - i)
|
96
|
+
break
|
97
|
+
end
|
98
|
+
|
99
|
+
result << line.ljust(width)
|
100
|
+
end
|
101
|
+
|
102
|
+
result
|
90
103
|
end
|
91
104
|
end
|
92
105
|
|
93
106
|
private
|
94
107
|
|
95
108
|
def redraw
|
96
|
-
avail_area = [@
|
109
|
+
avail_area = [@width, @height]
|
97
110
|
@stack.reverse.each do |item|
|
98
111
|
|
99
|
-
message
|
100
|
-
font
|
101
|
-
unless font.background
|
102
|
-
font = Font.new font.type, font.foreground, @type.background
|
103
|
-
end
|
104
|
-
|
112
|
+
message = item[:message]
|
113
|
+
font = item[:font]
|
105
114
|
avail_area = print_message(message, font, avail_area)
|
106
|
-
# выходим если закончилось место в области
|
107
|
-
return nil if avail_area[0] <= 0 or avail_area[1] <= 0
|
108
|
-
end
|
109
|
-
end
|
110
115
|
|
111
|
-
|
112
|
-
# @param [String] arr
|
113
|
-
# @param [Integer] max_len
|
114
|
-
def rows_wrap!(arr, max_len)
|
115
|
-
max_used_len = 1
|
116
|
-
arr.each_with_index do |row, i|
|
117
|
-
len = row.size
|
118
|
-
max_used_len = len if len > max_used_len
|
119
|
-
next if len <= max_len
|
120
|
-
tail = row.slice!(max_len, len-max_len)
|
121
|
-
arr.insert(i+1, tail)
|
116
|
+
return nil if avail_area[0] <= 0 or avail_area[1] <= 0
|
122
117
|
end
|
123
|
-
max_used_len
|
124
118
|
end
|
125
119
|
|
126
120
|
# @param [Integer] x
|
@@ -130,12 +124,19 @@ module Bash_Visual
|
|
130
124
|
def write(x, y, message, font)
|
131
125
|
string = ''
|
132
126
|
message.each_with_index { |text, i|
|
133
|
-
|
127
|
+
string << @console.write_to_position(x, y + i, text, font)
|
134
128
|
}
|
135
129
|
|
136
130
|
@mutex.synchronize {
|
137
131
|
print string
|
138
132
|
}
|
139
133
|
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
# Clear scroll's area
|
138
|
+
def clear(font = @font)
|
139
|
+
print @console.draw_filled_rectangle([@x, @y], [@width, @height], font.background)
|
140
|
+
end
|
140
141
|
end
|
141
142
|
end
|
data/lib/bash-visual/version.rb
CHANGED
@@ -1,14 +1,9 @@
|
|
1
1
|
module Bash_Visual
|
2
2
|
class VerticalScroll < Scroll
|
3
3
|
|
4
|
-
def initialize options
|
5
|
-
super
|
6
|
-
@message_block_height = @message_block_size
|
7
|
-
end
|
8
|
-
|
9
4
|
def get_y_position available_area_height, message_size = 0
|
10
5
|
if (@start == BEGINNING)
|
11
|
-
@y + (@
|
6
|
+
@y + (@height - available_area_height)
|
12
7
|
else
|
13
8
|
@y + available_area_height - message_size
|
14
9
|
end
|
@@ -17,36 +12,29 @@ module Bash_Visual
|
|
17
12
|
def print_message message, font, available_area
|
18
13
|
|
19
14
|
available_area_width, available_area_height = available_area
|
20
|
-
avail_height = @message_block_height > available_area_height ? available_area_height : @message_block_height
|
21
|
-
|
22
|
-
rows_wrap!(message, available_area_width) if @is_wrap
|
23
|
-
|
24
|
-
if @adapt_size_message
|
25
|
-
message = message.slice(0, available_area_height) if message.size > available_area_height
|
26
|
-
else
|
27
|
-
message = message.slice(0, avail_height) if message.size > avail_height
|
28
|
-
end
|
29
15
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
16
|
+
msg_block_height =
|
17
|
+
case
|
18
|
+
when !@adapt
|
19
|
+
1
|
20
|
+
when @fixed_message_block_size
|
21
|
+
@fixed_message_block_size
|
22
|
+
when @max_message_block_size
|
23
|
+
@max_message_block_size
|
24
|
+
else
|
25
|
+
available_area_height
|
26
|
+
end
|
27
|
+
|
28
|
+
msg_block_height -= 1 if @separator
|
29
|
+
msg_block_height = available_area_height if msg_block_height > available_area_height
|
30
|
+
|
31
|
+
message = Scroll.form_block message, [available_area_width, msg_block_height]
|
32
|
+
if @separator
|
33
|
+
message << @separator * available_area_width
|
45
34
|
end
|
46
35
|
|
47
36
|
write(@x, get_y_position(available_area_height, message.size), message, font)
|
48
37
|
|
49
|
-
|
50
38
|
[available_area_width, available_area_height - message.size]
|
51
39
|
end
|
52
40
|
|
data/test/font_test.rb
CHANGED
@@ -71,6 +71,44 @@ class FontTest < Test::Unit::TestCase
|
|
71
71
|
|
72
72
|
end
|
73
73
|
|
74
|
+
def test_rand
|
75
|
+
assert_instance_of Font, Font::rand_font
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_illegal_color
|
79
|
+
assert_raise_message "Illegal color wrong_color" do
|
80
|
+
font = Font.new :std, :wrong_color
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_add_type
|
85
|
+
font = Font.new
|
86
|
+
|
87
|
+
assert_false(font.add_type :std)
|
88
|
+
|
89
|
+
assert_true(font.add_type :bold)
|
90
|
+
assert_equal [:bold], font.types
|
91
|
+
|
92
|
+
assert_true(font.add_type :underline)
|
93
|
+
assert_equal [:bold, :underline], font.types
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def test_remove_type
|
98
|
+
font = Font.new
|
99
|
+
|
100
|
+
assert_false(font.remove_type :std)
|
101
|
+
assert_equal [:std], font.types
|
102
|
+
|
103
|
+
font.add_type :underline
|
104
|
+
assert_false(font.remove_type :std)
|
105
|
+
|
106
|
+
assert_true(font.add_type :bold)
|
107
|
+
font.remove_type :underline
|
108
|
+
assert_equal [:bold], font.types
|
109
|
+
|
110
|
+
end
|
111
|
+
|
74
112
|
protected
|
75
113
|
|
76
114
|
def mock_class_method(class_name, eval_string)
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'helper'
|
5
|
+
|
6
|
+
|
7
|
+
class PainterTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include Bash_Visual
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@painter = Object.new
|
13
|
+
@painter.extend(Painter)
|
14
|
+
builder = Bash_Visual::Builder.new #mock('Bash_Visual::Builder')
|
15
|
+
@painter.instance_variable_set(:@builder, builder)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_draw_window
|
19
|
+
@painter.draw_window([1, 1], [10, 10], 'logs')
|
20
|
+
@painter.draw_window([1, 1], [10, 10], 'logs', {font: Font.new(:bold)})
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_draw_border
|
24
|
+
@painter.draw_border([1, 1], [10, 10])
|
25
|
+
@painter.draw_border([1, 1], [10, 10], {font: Font.new(:bold)})
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_draw_filled_rectangle
|
29
|
+
@painter.draw_filled_rectangle([1, 1], [10, 10])
|
30
|
+
@painter.draw_filled_rectangle([1, 1], [10, 10], :red)
|
31
|
+
end
|
32
|
+
end
|
data/test/scroll_test.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.unshift(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'helper'
|
5
|
+
|
6
|
+
class ScrollTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
include Bash_Visual
|
9
|
+
|
10
|
+
def test_empty_params
|
11
|
+
|
12
|
+
assert_raise_message "Minimum needs: :size and :position" do
|
13
|
+
scroll = Scroll.new :prefix => nil
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_raise_message "Minimum needs: :size and :position" do
|
17
|
+
scroll = Scroll.new :size => [1,1]
|
18
|
+
end
|
19
|
+
|
20
|
+
assert_raise_message "Minimum needs: :size and :position" do
|
21
|
+
scroll = Scroll.new :position => [1,1]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_rows_wrap__example
|
26
|
+
|
27
|
+
text = 'Hello world. Lot of words...'
|
28
|
+
expected = ['Hell', 'o wo', 'rld.', ' Lot']
|
29
|
+
result = Scroll::form_block(text, [4,4])
|
30
|
+
|
31
|
+
assert_equal expected, result
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_rows_wrap__min
|
35
|
+
|
36
|
+
text = 'Hello world. Lot of words...'
|
37
|
+
expected = ['H']
|
38
|
+
result = Scroll::form_block(text, [1,1])
|
39
|
+
|
40
|
+
assert_equal expected, result
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def test_rows_wrap__fill
|
45
|
+
|
46
|
+
text = 'Hell'
|
47
|
+
expected = ['Hell ']
|
48
|
+
result = Scroll::form_block(text, [5, 3])
|
49
|
+
|
50
|
+
assert_equal expected, result
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_rows_wrap__fixate_fill
|
54
|
+
|
55
|
+
text = 'Hell'
|
56
|
+
expected = ['Hell ', ' ' * 5, ' ' * 5]
|
57
|
+
result = Scroll::form_block(text, [5, 3], true)
|
58
|
+
|
59
|
+
assert_equal expected, result
|
60
|
+
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bash-visual
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-30 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Bash visualisation tools
|
15
15
|
email:
|
@@ -23,21 +23,30 @@ files:
|
|
23
23
|
- LICENSE
|
24
24
|
- README.md
|
25
25
|
- Rakefile
|
26
|
+
- bash-visual-1.0.6.gem
|
26
27
|
- bash-visual.gemspec
|
27
28
|
- example/hello_world.rb
|
29
|
+
- example/painter.rb
|
28
30
|
- example/random.rb
|
31
|
+
- example/scroll.rb
|
29
32
|
- example/spectrum.rb
|
30
33
|
- lib/bash-visual.rb
|
31
34
|
- lib/bash-visual/builder.rb
|
32
35
|
- lib/bash-visual/console.rb
|
36
|
+
- lib/bash-visual/fixed_object.rb
|
33
37
|
- lib/bash-visual/font.rb
|
34
38
|
- lib/bash-visual/horizontal_scroll.rb
|
39
|
+
- lib/bash-visual/painter.rb
|
35
40
|
- lib/bash-visual/scroll.rb
|
36
41
|
- lib/bash-visual/version.rb
|
37
42
|
- lib/bash-visual/vertical_scroll.rb
|
38
43
|
- test/builder_test.rb
|
44
|
+
- test/console_test.rb
|
39
45
|
- test/font_test.rb
|
40
46
|
- test/helper.rb
|
47
|
+
- test/painter_test.rb
|
48
|
+
- test/scroll_test.rb
|
49
|
+
- test/vertical_scroll_test.rb
|
41
50
|
homepage: https://github.com/AlmazKo/BashVisual
|
42
51
|
licenses:
|
43
52
|
- MIT
|