vedeu 0.2.1 → 0.2.2
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/.yardopts +1 -0
- data/README.md +1 -2
- data/Rakefile +5 -5
- data/bin/vedeu +8 -4
- data/docs/api.md +3 -1
- data/docs/events.md +43 -29
- data/docs/getting_started.md +2 -0
- data/examples/cursor_app/cursor_app.rb +85 -0
- data/examples/lines_app/lines_app.rb +60 -0
- data/lib/vedeu.rb +9 -3
- data/lib/vedeu/api/api.rb +28 -7
- data/lib/vedeu/api/composition.rb +2 -0
- data/lib/vedeu/api/helpers.rb +2 -0
- data/lib/vedeu/api/interface.rb +2 -20
- data/lib/vedeu/api/keymap.rb +2 -0
- data/lib/vedeu/api/line.rb +2 -0
- data/lib/vedeu/api/menu.rb +3 -1
- data/lib/vedeu/api/stream.rb +25 -2
- data/lib/vedeu/application.rb +4 -4
- data/lib/vedeu/configuration/api.rb +327 -0
- data/lib/vedeu/configuration/cli.rb +110 -0
- data/lib/vedeu/{configuration.rb → configuration/configuration.rb} +49 -99
- data/lib/vedeu/launcher.rb +0 -1
- data/lib/vedeu/models/attributes/colour_translator.rb +2 -2
- data/lib/vedeu/models/colour.rb +0 -1
- data/lib/vedeu/models/composition.rb +2 -8
- data/lib/vedeu/models/cursor.rb +261 -0
- data/lib/vedeu/models/geometry.rb +11 -19
- data/lib/vedeu/models/interface.rb +2 -12
- data/lib/vedeu/models/keymap.rb +2 -0
- data/lib/vedeu/models/line.rb +2 -0
- data/lib/vedeu/models/stream.rb +2 -0
- data/lib/vedeu/models/style.rb +2 -0
- data/lib/vedeu/output/clear.rb +0 -1
- data/lib/vedeu/output/compositor.rb +0 -1
- data/lib/vedeu/output/refresh.rb +3 -0
- data/lib/vedeu/output/render.rb +12 -6
- data/lib/vedeu/output/view.rb +1 -0
- data/lib/vedeu/repositories/cursors.rb +98 -0
- data/lib/vedeu/repositories/events.rb +0 -1
- data/lib/vedeu/repositories/focus.rb +18 -0
- data/lib/vedeu/repositories/menus.rb +4 -4
- data/lib/vedeu/support/common.rb +2 -1
- data/lib/vedeu/support/event.rb +1 -10
- data/lib/vedeu/support/grid.rb +1 -2
- data/lib/vedeu/{repositories → support}/keymap_validator.rb +5 -4
- data/lib/vedeu/support/log.rb +3 -0
- data/lib/vedeu/support/menu.rb +4 -1
- data/lib/vedeu/support/registrar.rb +2 -1
- data/test/integration/defining_interfaces_test.rb +0 -1
- data/test/integration/views/basic_view_test.rb +741 -739
- data/test/lib/vedeu/api/api_test.rb +14 -3
- data/test/lib/vedeu/api/helpers_test.rb +3 -3
- data/test/lib/vedeu/api/interface_test.rb +17 -70
- data/test/lib/vedeu/api/keymap_test.rb +2 -0
- data/test/lib/vedeu/api/line_test.rb +4 -4
- data/test/lib/vedeu/api/menu_test.rb +6 -5
- data/test/lib/vedeu/api/stream_test.rb +18 -0
- data/test/lib/vedeu/configuration/api_test.rb +248 -0
- data/test/lib/vedeu/configuration/cli_test.rb +88 -0
- data/test/lib/vedeu/configuration/configuration_test.rb +67 -0
- data/test/lib/vedeu/input/input_test.rb +2 -2
- data/test/lib/vedeu/models/attributes/background_test.rb +3 -3
- data/test/lib/vedeu/models/attributes/foreground_test.rb +3 -3
- data/test/lib/vedeu/models/composition_test.rb +0 -222
- data/test/lib/vedeu/models/cursor_test.rb +164 -0
- data/test/lib/vedeu/models/interface_test.rb +0 -11
- data/test/lib/vedeu/output/compositor_test.rb +2 -4
- data/test/lib/vedeu/output/render_test.rb +4 -41
- data/test/lib/vedeu/repositories/cursors_test.rb +13 -0
- data/test/lib/vedeu/repositories/focus_test.rb +14 -4
- data/test/lib/vedeu/repositories/menus_test.rb +36 -29
- data/test/lib/vedeu/{repositories → support}/keymap_validator_test.rb +0 -0
- data/test/lib/vedeu/support/menu_test.rb +3 -3
- data/test/lib/vedeu/support/registrar_test.rb +6 -0
- data/test/lib/vedeu/support/terminal_test.rb +2 -2
- data/test/test_helper.rb +1 -1
- data/vedeu.gemspec +1 -1
- metadata +23 -14
- data/elements.txt +0 -118
- data/lib/vedeu/support/cursor.rb +0 -96
- data/test/lib/vedeu/configuration_test.rb +0 -154
- data/test/lib/vedeu/support/cursor_test.rb +0 -79
- data/test/support/model_test_data.json +0 -437
@@ -0,0 +1,110 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
module Configuration
|
4
|
+
|
5
|
+
# The Configuration::CLI class parses command-line arguments using
|
6
|
+
# OptionParser into options used by Vedeu to affect certain behaviours.
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class CLI
|
10
|
+
|
11
|
+
# Configure Vedeu via command-line arguments. Options set here via
|
12
|
+
# arguments override the client application configuration set via
|
13
|
+
# {Vedeu::API#configure}.
|
14
|
+
#
|
15
|
+
# @param args [Array]
|
16
|
+
# @return [Hash]
|
17
|
+
def self.configure(args = [])
|
18
|
+
new(args = []).configuration
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns an instance of Configuration::CLI.
|
22
|
+
#
|
23
|
+
# @param args [Array]
|
24
|
+
# @return [Configuration::CLI]
|
25
|
+
def initialize(args = [])
|
26
|
+
@args = args
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the configuration options set up by parsing the command-line
|
30
|
+
# arguments passed to the client application.
|
31
|
+
#
|
32
|
+
# @return [Hash]
|
33
|
+
def configuration
|
34
|
+
parser = OptionParser.new do |opts|
|
35
|
+
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
36
|
+
|
37
|
+
opts.on('-i', '--interactive',
|
38
|
+
'Run the application in interactive mode (default).') do
|
39
|
+
options[:interactive] = true
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on('-I', '--noninteractive', '--standalone',
|
43
|
+
'Run the application non-interactively; i.e. not requiring ' \
|
44
|
+
'intervention from the user.') do
|
45
|
+
options[:interactive] = false
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on('-1', '--run-once',
|
49
|
+
'Run the application loop once.') do
|
50
|
+
options[:once] = true
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on('-n', '--run-many',
|
54
|
+
'Run the application loop continuously (default).') do
|
55
|
+
options[:once] = false
|
56
|
+
end
|
57
|
+
|
58
|
+
opts.on('-c', '--cooked', 'Run application in cooked mode.') do
|
59
|
+
options[:terminal_mode] = :cooked
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on('-r', '--raw', 'Run application in raw mode (default).') do
|
63
|
+
options[:terminal_mode] = :raw
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on('-d', '--debug', 'Run application with debugging on.') do
|
67
|
+
options[:debug] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on('-D', '--trace', 'Run application with debugging on with ' \
|
71
|
+
'method and event tracing (noisy!).') do
|
72
|
+
options[:debug] = true
|
73
|
+
options[:trace] = true
|
74
|
+
end
|
75
|
+
|
76
|
+
opts.on('-C', '--colour-mode [COLOURS]', Integer,
|
77
|
+
'Run application in either `8`, `16`, `256` or `16777216` ' \
|
78
|
+
'colour mode.') do |colours|
|
79
|
+
if [8, 16, 256, 16777216].include?(colours)
|
80
|
+
options[:colour_mode] = colours
|
81
|
+
|
82
|
+
else
|
83
|
+
options[:colour_mode] = 8
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
parser.parse!(args)
|
89
|
+
|
90
|
+
options
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
attr_reader :args
|
96
|
+
|
97
|
+
# Returns the options set via command-line arguments parsed by
|
98
|
+
# OptionParser, or an empty Hash if none were set or parsed.
|
99
|
+
#
|
100
|
+
# @api private
|
101
|
+
# @return [Hash]
|
102
|
+
def options
|
103
|
+
@_options ||= {}
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
@@ -1,74 +1,30 @@
|
|
1
1
|
module Vedeu
|
2
2
|
|
3
|
-
# Allows the customisation of Vedeu's behaviour through
|
4
|
-
# arguments.
|
3
|
+
# Allows the customisation of Vedeu's behaviour through the configuration API
|
4
|
+
# or command-line arguments.
|
5
|
+
|
6
|
+
# Provides access to Vedeu's configuration, which was set with sensible
|
7
|
+
# defaults (influenced by environment variables), overridden by client
|
8
|
+
# application settings (via the configuration API), or any command-line
|
9
|
+
# arguments provided.
|
5
10
|
#
|
6
|
-
# @api
|
11
|
+
# @api private
|
7
12
|
module Configuration
|
8
13
|
|
9
14
|
extend self
|
10
15
|
|
11
|
-
#
|
12
|
-
# options
|
16
|
+
# Configure Vedeu with sensible defaults. If the client application sets
|
17
|
+
# options, override the defaults with those, and if command-line arguments
|
18
|
+
# are provided at application invocation, override any options with the
|
19
|
+
# arguments provided.
|
13
20
|
#
|
14
21
|
# @param args [Array]
|
22
|
+
# @param block [Proc]
|
15
23
|
# @return [Hash]
|
16
|
-
def configure(args = [])
|
17
|
-
|
18
|
-
opts.banner = "Usage: #{$PROGRAM_NAME} [options]"
|
19
|
-
|
20
|
-
opts.on('-i', '--interactive',
|
21
|
-
'Run the application in interactive mode (default).') do
|
22
|
-
options[:interactive] = true
|
23
|
-
end
|
24
|
-
|
25
|
-
opts.on('-I', '--noninteractive', '--standalone',
|
26
|
-
'Run the application non-interactively; i.e. not requiring ' \
|
27
|
-
'intervention from the user.') do
|
28
|
-
options[:interactive] = false
|
29
|
-
end
|
30
|
-
|
31
|
-
opts.on('-1', '--run-once',
|
32
|
-
'Run the application loop once.') do
|
33
|
-
options[:once] = true
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.on('-n', '--run-many',
|
37
|
-
'Run the application loop continuously (default).') do
|
38
|
-
options[:once] = false
|
39
|
-
end
|
40
|
-
|
41
|
-
opts.on('-c', '--cooked', 'Run application in cooked mode.') do
|
42
|
-
options[:terminal_mode] = :cooked
|
43
|
-
end
|
44
|
-
|
45
|
-
opts.on('-r', '--raw', 'Run application in raw mode (default).') do
|
46
|
-
options[:terminal_mode] = :raw
|
47
|
-
end
|
48
|
-
|
49
|
-
opts.on('-d', '--debug', 'Run application with debugging on.') do
|
50
|
-
options[:debug] = true
|
51
|
-
end
|
24
|
+
def configure(args = [], &block)
|
25
|
+
options.merge!(API.configure(&block)) if block_given?
|
52
26
|
|
53
|
-
|
54
|
-
'method and event tracing (noisy!).') do
|
55
|
-
options[:debug] = true
|
56
|
-
options[:trace] = true
|
57
|
-
end
|
58
|
-
|
59
|
-
opts.on('-C', '--colour-mode [COLOURS]', Integer,
|
60
|
-
'Run application in either `8`, `16`, `256` or `16777216` ' \
|
61
|
-
'colour mode.') do |colours|
|
62
|
-
if [8, 16, 256, 16777216].include?(colours)
|
63
|
-
options[:colour_mode] = colours
|
64
|
-
|
65
|
-
else
|
66
|
-
options[:colour_mode] = 8
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
parser.parse!(args)
|
27
|
+
options.merge!(CLI.configure(args)) if args.any?
|
72
28
|
|
73
29
|
options
|
74
30
|
end
|
@@ -133,23 +89,37 @@ module Vedeu
|
|
133
89
|
end
|
134
90
|
alias_method :trace, :trace?
|
135
91
|
|
136
|
-
#
|
92
|
+
# Resets all options to Vedeu defaults.
|
137
93
|
#
|
138
94
|
# @return [Hash]
|
139
|
-
def
|
140
|
-
@options
|
95
|
+
def reset
|
96
|
+
@options = defaults
|
141
97
|
end
|
142
98
|
|
143
|
-
#
|
99
|
+
# Vedeu's default system keys. Use {#system_keys}.
|
144
100
|
#
|
101
|
+
# @api private
|
145
102
|
# @return [Hash]
|
146
|
-
def
|
147
|
-
|
103
|
+
def default_system_keys
|
104
|
+
{
|
105
|
+
exit: 'q',
|
106
|
+
focus_next: :tab,
|
107
|
+
focus_prev: :shift_tab,
|
108
|
+
mode_switch: :escape,
|
109
|
+
}
|
148
110
|
end
|
149
111
|
|
150
112
|
private
|
151
113
|
|
152
|
-
#
|
114
|
+
# Returns all the options current configured.
|
115
|
+
#
|
116
|
+
# @api private
|
117
|
+
# @return [Hash]
|
118
|
+
def options
|
119
|
+
@options ||= defaults
|
120
|
+
end
|
121
|
+
|
122
|
+
# The Vedeu default options, which of course are influenced by environment
|
153
123
|
# variables also.
|
154
124
|
#
|
155
125
|
# @api private
|
@@ -161,28 +131,20 @@ module Vedeu
|
|
161
131
|
interactive: true,
|
162
132
|
once: false,
|
163
133
|
system_keys: default_system_keys,
|
164
|
-
terminal_mode: :raw,
|
134
|
+
terminal_mode: :raw,
|
165
135
|
trace: detect_trace_mode,
|
166
136
|
}
|
167
137
|
end
|
168
138
|
|
169
|
-
#
|
170
|
-
|
171
|
-
{
|
172
|
-
exit: 'q',
|
173
|
-
focus_next: :tab,
|
174
|
-
focus_prev: :shift_tab,
|
175
|
-
mode_switch: :escape,
|
176
|
-
}
|
177
|
-
end
|
178
|
-
|
179
|
-
# Determine the terminal colour mode via enviroment variables, or be
|
180
|
-
# optimistic and settle for 256 colours.
|
139
|
+
# Attempt to determine the terminal colour mode via environment variables,
|
140
|
+
# or be optimistic and settle for 256 colours.
|
181
141
|
#
|
182
142
|
# @api private
|
183
143
|
# @return [Fixnum]
|
184
144
|
# :nocov:
|
185
145
|
def detect_colour_mode
|
146
|
+
return 16777216 if ENV['VEDEU_TESTMODE']
|
147
|
+
|
186
148
|
if ENV['VEDEU_TERM']
|
187
149
|
case ENV['VEDEU_TERM']
|
188
150
|
when /-256color$/ then 256
|
@@ -204,23 +166,17 @@ module Vedeu
|
|
204
166
|
end
|
205
167
|
# :nocov:
|
206
168
|
|
207
|
-
# Determine the debug mode via an
|
169
|
+
# Determine the debug mode via an environment variable.
|
208
170
|
#
|
209
171
|
# @api private
|
210
172
|
# @return [Boolean]
|
211
173
|
# :nocov:
|
212
174
|
def detect_debug_mode
|
213
|
-
if ENV['
|
214
|
-
case ENV['VEDEU_DEBUG']
|
215
|
-
when 'true' then true
|
216
|
-
when 'false' then false
|
217
|
-
else false
|
218
|
-
end
|
175
|
+
return false if ENV['VEDEU_TESTMODE']
|
219
176
|
|
220
|
-
|
221
|
-
false
|
177
|
+
return true if ENV['VEDEU_DEBUG']
|
222
178
|
|
223
|
-
|
179
|
+
false
|
224
180
|
end
|
225
181
|
# :nocov:
|
226
182
|
|
@@ -230,17 +186,11 @@ module Vedeu
|
|
230
186
|
# @return [Boolean]
|
231
187
|
# :nocov:
|
232
188
|
def detect_trace_mode
|
233
|
-
if ENV['
|
234
|
-
case ENV['VEDEU_TRACE']
|
235
|
-
when 'true' then true
|
236
|
-
when 'false' then false
|
237
|
-
else false
|
238
|
-
end
|
189
|
+
return false if ENV['VEDEU_TESTMODE']
|
239
190
|
|
240
|
-
|
241
|
-
false
|
191
|
+
return true if ENV['VEDEU_TRACE']
|
242
192
|
|
243
|
-
|
193
|
+
false
|
244
194
|
end
|
245
195
|
# :nocov:
|
246
196
|
|
data/lib/vedeu/launcher.rb
CHANGED
@@ -11,13 +11,14 @@ module Vedeu
|
|
11
11
|
# :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :default.
|
12
12
|
#
|
13
13
|
# When a number between 0 and 255 is provided, Vedeu will use the terminal
|
14
|
-
# colour corresponding with that colour.
|
14
|
+
# colour corresponding with that colour.
|
15
15
|
#
|
16
16
|
# Finally, when provided a CSS/HTML colour string e.g. '#ff0000', Vedeu will
|
17
17
|
# translate that to the 8-bit escape sequence or if you have a capable
|
18
18
|
# terminal and the `VEDEU_TERM=xterm-truecolor` environment variable set,
|
19
19
|
# a 24-bit representation.
|
20
20
|
#
|
21
|
+
# @todo More documentation required (create a fancy chart!)
|
21
22
|
# @api private
|
22
23
|
class ColourTranslator
|
23
24
|
|
@@ -60,7 +61,6 @@ module Vedeu
|
|
60
61
|
|
61
62
|
private
|
62
63
|
|
63
|
-
# @return [Fixnum|NilClass|Symbol|String]
|
64
64
|
attr_reader :colour
|
65
65
|
|
66
66
|
# @api private
|
data/lib/vedeu/models/colour.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Vedeu
|
2
2
|
|
3
3
|
# A composition is a collection of interfaces.
|
4
|
+
#
|
5
|
+
# @api private
|
4
6
|
class Composition
|
5
7
|
|
6
8
|
attr_reader :attributes
|
@@ -44,14 +46,6 @@ module Vedeu
|
|
44
46
|
{}
|
45
47
|
end
|
46
48
|
|
47
|
-
# Returns the complete escape sequence which this composition renders to.
|
48
|
-
# This is used by {Vedeu::Terminal.output} to draw the view.
|
49
|
-
#
|
50
|
-
# @return [String]
|
51
|
-
def to_s
|
52
|
-
interfaces.map(&:to_s).join
|
53
|
-
end
|
54
|
-
|
55
49
|
private
|
56
50
|
|
57
51
|
# The default values for a new instance of Composition.
|
@@ -0,0 +1,261 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# Each interface has its own Cursor which maintains the position and
|
4
|
+
# visibility of the cursor within that interface.
|
5
|
+
#
|
6
|
+
# @api private
|
7
|
+
class Cursor
|
8
|
+
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :geometry, :top, :right, :bottom, :left
|
12
|
+
|
13
|
+
# Provides a new instance of Cursor.
|
14
|
+
#
|
15
|
+
# @param attributes [Hash] The stored attributes for a cursor.
|
16
|
+
# @return [Cursor]
|
17
|
+
def initialize(attributes = {})
|
18
|
+
@attributes = defaults.merge!(attributes)
|
19
|
+
|
20
|
+
@name = @attributes[:name]
|
21
|
+
@state = @attributes[:state]
|
22
|
+
@x = @attributes[:x]
|
23
|
+
@y = @attributes[:y]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an attribute hash for the current position and visibility of the
|
27
|
+
# cursor.
|
28
|
+
#
|
29
|
+
# @return [Hash]
|
30
|
+
def attributes
|
31
|
+
{
|
32
|
+
name: name,
|
33
|
+
state: state,
|
34
|
+
x: x,
|
35
|
+
y: y,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
alias_method :refresh, :attributes
|
39
|
+
|
40
|
+
# Move the cursor up one row.
|
41
|
+
#
|
42
|
+
# @return [Cursor]
|
43
|
+
def move_up
|
44
|
+
unless y == top || y - 1 < top
|
45
|
+
@y -= 1
|
46
|
+
end
|
47
|
+
|
48
|
+
attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
# Move the cursor down one row.
|
52
|
+
#
|
53
|
+
# @return [Cursor]
|
54
|
+
def move_down
|
55
|
+
unless y == bottom || y + 1 >= bottom
|
56
|
+
@y += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
# Move the cursor left one column.
|
63
|
+
#
|
64
|
+
# @return [Cursor]
|
65
|
+
def move_left
|
66
|
+
unless x == left || x - 1 < left
|
67
|
+
@x -= 1
|
68
|
+
end
|
69
|
+
|
70
|
+
attributes
|
71
|
+
end
|
72
|
+
|
73
|
+
# Move the cursor right one column.
|
74
|
+
#
|
75
|
+
# @return [Cursor]
|
76
|
+
def move_right
|
77
|
+
unless x == right || x + 1 >= right
|
78
|
+
@x += 1
|
79
|
+
end
|
80
|
+
|
81
|
+
attributes
|
82
|
+
end
|
83
|
+
|
84
|
+
# Make the cursor visible if it is not already.
|
85
|
+
#
|
86
|
+
# @return [Symbol]
|
87
|
+
def show
|
88
|
+
@state = :show
|
89
|
+
|
90
|
+
attributes
|
91
|
+
end
|
92
|
+
|
93
|
+
# Make the cursor invisible if it is not already.
|
94
|
+
#
|
95
|
+
# @return [Symbol]
|
96
|
+
def hide
|
97
|
+
@state = :hide
|
98
|
+
|
99
|
+
attributes
|
100
|
+
end
|
101
|
+
|
102
|
+
# Toggle the visibility of the cursor.
|
103
|
+
#
|
104
|
+
# @return [Symbol]
|
105
|
+
def toggle
|
106
|
+
if visible?
|
107
|
+
@state = :hide
|
108
|
+
|
109
|
+
else
|
110
|
+
@state = :show
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
attributes
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns an escape sequence to position the cursor and set its visibility.
|
118
|
+
# When passed a block, will position the cursor, yield and return the
|
119
|
+
# original position.
|
120
|
+
#
|
121
|
+
# @param block [Proc]
|
122
|
+
# @return [String]
|
123
|
+
def to_s(&block)
|
124
|
+
if block_given?
|
125
|
+
[ sequence, yield, sequence ].join
|
126
|
+
|
127
|
+
else
|
128
|
+
sequence
|
129
|
+
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
attr_reader :name, :state
|
136
|
+
|
137
|
+
# Returns the escape sequence to position the cursor and set its visibility.
|
138
|
+
#
|
139
|
+
# @api private
|
140
|
+
# @return [String]
|
141
|
+
def sequence
|
142
|
+
[ position, visibility ].join
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the escape sequence to position the cursor.
|
146
|
+
#
|
147
|
+
# @api private
|
148
|
+
# @return [String]
|
149
|
+
def position
|
150
|
+
["\e[", y, ';', x, 'H'].join
|
151
|
+
end
|
152
|
+
|
153
|
+
# Returns the escape sequence for setting the visibility of the cursor.
|
154
|
+
#
|
155
|
+
# @api private
|
156
|
+
# @return [String]
|
157
|
+
def visibility
|
158
|
+
return Esc.string('show_cursor') if visible?
|
159
|
+
|
160
|
+
Esc.string('hide_cursor')
|
161
|
+
end
|
162
|
+
|
163
|
+
# Return a boolean indicating the visibility of the cursor, invisible if
|
164
|
+
# the state is not defined.
|
165
|
+
#
|
166
|
+
# @api private
|
167
|
+
# @return [Boolean]
|
168
|
+
def visible?
|
169
|
+
return false unless states.include?(state)
|
170
|
+
return false if state == :hide
|
171
|
+
|
172
|
+
true
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns the y coordinate of the cursor, unless out of range, in which case
|
176
|
+
# sets y to the first row (top) of the interface.
|
177
|
+
#
|
178
|
+
# @api private
|
179
|
+
# @return [Fixnum]
|
180
|
+
def y
|
181
|
+
if y_out_of_range?
|
182
|
+
@y = top
|
183
|
+
|
184
|
+
else
|
185
|
+
@y
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Returns the x coordinate of the cursor, unless out of range, in which case
|
191
|
+
# sets x to the first column (left) of the interface.
|
192
|
+
#
|
193
|
+
# @api private
|
194
|
+
# @return [Fixnum]
|
195
|
+
def x
|
196
|
+
if x_out_of_range?
|
197
|
+
@x = left
|
198
|
+
|
199
|
+
else
|
200
|
+
@x
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Returns a boolean indicating whether the previous y coordinate is still
|
206
|
+
# inside the interface or terminal.
|
207
|
+
#
|
208
|
+
# @api private
|
209
|
+
# @return [Boolean]
|
210
|
+
def y_out_of_range?
|
211
|
+
@y < top || @y > bottom
|
212
|
+
end
|
213
|
+
|
214
|
+
# Returns a boolean indicating whether the previous x coordinate is still
|
215
|
+
# inside the interface or terminal.
|
216
|
+
#
|
217
|
+
# @api private
|
218
|
+
# @return [Boolean]
|
219
|
+
def x_out_of_range?
|
220
|
+
@x < left || @x > right
|
221
|
+
end
|
222
|
+
|
223
|
+
# Returns the position and size of the interface.
|
224
|
+
#
|
225
|
+
# @api private
|
226
|
+
# @return [Geometry]
|
227
|
+
def geometry
|
228
|
+
@geometry ||= Vedeu::Geometry.new(interface[:geometry])
|
229
|
+
end
|
230
|
+
|
231
|
+
# Returns the attributes of a named interface.
|
232
|
+
#
|
233
|
+
# @api private
|
234
|
+
# @return [Hash]
|
235
|
+
def interface
|
236
|
+
Vedeu::Interfaces.find(name)
|
237
|
+
end
|
238
|
+
|
239
|
+
# The valid visibility states for the cursor.
|
240
|
+
#
|
241
|
+
# @api private
|
242
|
+
# @return [Array]
|
243
|
+
def states
|
244
|
+
[:show, :hide]
|
245
|
+
end
|
246
|
+
|
247
|
+
# The default values for a new instance of Cursor.
|
248
|
+
#
|
249
|
+
# @api private
|
250
|
+
# @return [Hash]
|
251
|
+
def defaults
|
252
|
+
{
|
253
|
+
name: '',
|
254
|
+
x: 1,
|
255
|
+
y: 1,
|
256
|
+
state: :hide,
|
257
|
+
}
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|