vedeu 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/README.md +1 -2
  4. data/Rakefile +5 -5
  5. data/bin/vedeu +8 -4
  6. data/docs/api.md +3 -1
  7. data/docs/events.md +43 -29
  8. data/docs/getting_started.md +2 -0
  9. data/examples/cursor_app/cursor_app.rb +85 -0
  10. data/examples/lines_app/lines_app.rb +60 -0
  11. data/lib/vedeu.rb +9 -3
  12. data/lib/vedeu/api/api.rb +28 -7
  13. data/lib/vedeu/api/composition.rb +2 -0
  14. data/lib/vedeu/api/helpers.rb +2 -0
  15. data/lib/vedeu/api/interface.rb +2 -20
  16. data/lib/vedeu/api/keymap.rb +2 -0
  17. data/lib/vedeu/api/line.rb +2 -0
  18. data/lib/vedeu/api/menu.rb +3 -1
  19. data/lib/vedeu/api/stream.rb +25 -2
  20. data/lib/vedeu/application.rb +4 -4
  21. data/lib/vedeu/configuration/api.rb +327 -0
  22. data/lib/vedeu/configuration/cli.rb +110 -0
  23. data/lib/vedeu/{configuration.rb → configuration/configuration.rb} +49 -99
  24. data/lib/vedeu/launcher.rb +0 -1
  25. data/lib/vedeu/models/attributes/colour_translator.rb +2 -2
  26. data/lib/vedeu/models/colour.rb +0 -1
  27. data/lib/vedeu/models/composition.rb +2 -8
  28. data/lib/vedeu/models/cursor.rb +261 -0
  29. data/lib/vedeu/models/geometry.rb +11 -19
  30. data/lib/vedeu/models/interface.rb +2 -12
  31. data/lib/vedeu/models/keymap.rb +2 -0
  32. data/lib/vedeu/models/line.rb +2 -0
  33. data/lib/vedeu/models/stream.rb +2 -0
  34. data/lib/vedeu/models/style.rb +2 -0
  35. data/lib/vedeu/output/clear.rb +0 -1
  36. data/lib/vedeu/output/compositor.rb +0 -1
  37. data/lib/vedeu/output/refresh.rb +3 -0
  38. data/lib/vedeu/output/render.rb +12 -6
  39. data/lib/vedeu/output/view.rb +1 -0
  40. data/lib/vedeu/repositories/cursors.rb +98 -0
  41. data/lib/vedeu/repositories/events.rb +0 -1
  42. data/lib/vedeu/repositories/focus.rb +18 -0
  43. data/lib/vedeu/repositories/menus.rb +4 -4
  44. data/lib/vedeu/support/common.rb +2 -1
  45. data/lib/vedeu/support/event.rb +1 -10
  46. data/lib/vedeu/support/grid.rb +1 -2
  47. data/lib/vedeu/{repositories → support}/keymap_validator.rb +5 -4
  48. data/lib/vedeu/support/log.rb +3 -0
  49. data/lib/vedeu/support/menu.rb +4 -1
  50. data/lib/vedeu/support/registrar.rb +2 -1
  51. data/test/integration/defining_interfaces_test.rb +0 -1
  52. data/test/integration/views/basic_view_test.rb +741 -739
  53. data/test/lib/vedeu/api/api_test.rb +14 -3
  54. data/test/lib/vedeu/api/helpers_test.rb +3 -3
  55. data/test/lib/vedeu/api/interface_test.rb +17 -70
  56. data/test/lib/vedeu/api/keymap_test.rb +2 -0
  57. data/test/lib/vedeu/api/line_test.rb +4 -4
  58. data/test/lib/vedeu/api/menu_test.rb +6 -5
  59. data/test/lib/vedeu/api/stream_test.rb +18 -0
  60. data/test/lib/vedeu/configuration/api_test.rb +248 -0
  61. data/test/lib/vedeu/configuration/cli_test.rb +88 -0
  62. data/test/lib/vedeu/configuration/configuration_test.rb +67 -0
  63. data/test/lib/vedeu/input/input_test.rb +2 -2
  64. data/test/lib/vedeu/models/attributes/background_test.rb +3 -3
  65. data/test/lib/vedeu/models/attributes/foreground_test.rb +3 -3
  66. data/test/lib/vedeu/models/composition_test.rb +0 -222
  67. data/test/lib/vedeu/models/cursor_test.rb +164 -0
  68. data/test/lib/vedeu/models/interface_test.rb +0 -11
  69. data/test/lib/vedeu/output/compositor_test.rb +2 -4
  70. data/test/lib/vedeu/output/render_test.rb +4 -41
  71. data/test/lib/vedeu/repositories/cursors_test.rb +13 -0
  72. data/test/lib/vedeu/repositories/focus_test.rb +14 -4
  73. data/test/lib/vedeu/repositories/menus_test.rb +36 -29
  74. data/test/lib/vedeu/{repositories → support}/keymap_validator_test.rb +0 -0
  75. data/test/lib/vedeu/support/menu_test.rb +3 -3
  76. data/test/lib/vedeu/support/registrar_test.rb +6 -0
  77. data/test/lib/vedeu/support/terminal_test.rb +2 -2
  78. data/test/test_helper.rb +1 -1
  79. data/vedeu.gemspec +1 -1
  80. metadata +23 -14
  81. data/elements.txt +0 -118
  82. data/lib/vedeu/support/cursor.rb +0 -96
  83. data/test/lib/vedeu/configuration_test.rb +0 -154
  84. data/test/lib/vedeu/support/cursor_test.rb +0 -79
  85. data/test/support/model_test_data.json +0 -437
@@ -6,6 +6,17 @@ module Vedeu
6
6
  # module expose Vedeu's core functionality.
7
7
  module API
8
8
 
9
+ # Configure Vedeu using a simple configuration DSL.
10
+ #
11
+ # @api public
12
+ # @see Vedeu::Configuration
13
+ # @return []
14
+ def configure(&block)
15
+ fail InvalidSyntax, '`configure` requires a block.' unless block_given?
16
+
17
+ Vedeu::Configuration.configure(&block)
18
+ end
19
+
9
20
  # Returns information about various registered subsystems when used with
10
21
  # a defined method within {Vedeu::API::Defined}.
11
22
  #
@@ -74,17 +85,22 @@ module Vedeu
74
85
  @events ||= Vedeu::Events.new do
75
86
  event(:_clear_) { Terminal.clear_screen }
76
87
  event(:_exit_) { Vedeu::Application.stop }
77
- event(:_focus_by_name_) { |name| Vedeu::Focus.by_name(name) }
78
- event(:_focus_next_) { Vedeu::Focus.next_item }
79
- event(:_focus_prev_) { Vedeu::Focus.prev_item }
80
88
  event(:_keypress_) { |key| Vedeu.keypress(key) }
81
89
  event(:_log_) { |msg| Vedeu.log(msg) }
82
90
  event(:_mode_switch_) { fail ModeSwitch }
83
- event(:_refresh_) { Vedeu::Refresh.all }
84
91
  event(:_resize_, { delay: 0.25 }) { Vedeu.resize }
85
92
  end
86
93
  end
87
94
 
95
+ # Used after defining an interface or interfaces to set the initially
96
+ # focussed interface.
97
+ #
98
+ # @param name [String] The interface to focus; must be defined.
99
+ # @return []
100
+ def focus(name)
101
+ Vedeu.trigger(:_focus_by_name, name)
102
+ end
103
+
88
104
  # Find out how many lines the current terminal is able to display.
89
105
  #
90
106
  # @api public
@@ -100,11 +116,12 @@ module Vedeu
100
116
  # command. This provides the means for you to define your application's
101
117
  # views without their content.
102
118
  #
119
+ # @todo More documentation required.
103
120
  # @api public
104
121
  # @param name [String] The name of the interface. Used to reference the
105
122
  # interface throughout your application's execution lifetime.
106
123
  # @param block [Proc] A set of attributes which define the features of the
107
- # interface. TODO: More help.
124
+ # interface.
108
125
  #
109
126
  # @example
110
127
  # Vedeu.interface 'my_interface' do
@@ -234,6 +251,8 @@ module Vedeu
234
251
 
235
252
  trigger(:_refresh_)
236
253
 
254
+ trigger(:_cursor_refresh_)
255
+
237
256
  true
238
257
  end
239
258
  # :nocov:
@@ -264,8 +283,9 @@ module Vedeu
264
283
  Vedeu.events.unevent(name)
265
284
  end
266
285
 
267
- # Use attributes of another interface whilst defining one. TODO: More help.
286
+ # Use attributes of another interface whilst defining one.
268
287
  #
288
+ # @todo More documentation required.
269
289
  # @api public
270
290
  # @param name [String] The name of the interface you wish to use. Typically
271
291
  # used when defining interfaces to share geometry.
@@ -281,8 +301,9 @@ module Vedeu
281
301
  Vedeu::Interface.new(Vedeu::Interfaces.find(name))
282
302
  end
283
303
 
284
- # Define a view (content) for an interface. TODO: More help.
304
+ # Define a view (content) for an interface.
285
305
  #
306
+ # @todo More documentation required.
286
307
  # @api public
287
308
  # @param name [String] The name of the interface you are targetting for this
288
309
  # view.
@@ -2,6 +2,8 @@ module Vedeu
2
2
  module API
3
3
 
4
4
  # @see Vedeu::Composition
5
+ #
6
+ # @api public
5
7
  class Composition < Vedeu::Composition
6
8
 
7
9
  # Directly write a view buffer to the terminal.
@@ -3,6 +3,8 @@ module Vedeu
3
3
 
4
4
  # Provides colour and style helpers for use in the {API::Interface},
5
5
  # {API::Line} and {API::Stream} classes.
6
+ #
7
+ # @api public
6
8
  module Helpers
7
9
 
8
10
  # Define either or both foreground and background colours for an
@@ -2,6 +2,8 @@ module Vedeu
2
2
  module API
3
3
 
4
4
  # Provides methods to be used to define interfaces or views.
5
+ #
6
+ # @api public
5
7
  class Interface < Vedeu::Interface
6
8
 
7
9
  include Helpers
@@ -26,26 +28,6 @@ module Vedeu
26
28
  attributes[:geometry][:centred] = value
27
29
  end
28
30
 
29
- # Define the cursor visibility for an interface. A `true` value will show
30
- # the cursor, whilst `false` will hide it.
31
- #
32
- # @api public
33
- # @param value [Boolean]
34
- #
35
- # @example
36
- # interface 'my_interface' do
37
- # cursor true
38
- # ...
39
- #
40
- # @return [API::Interface]
41
- def cursor(value)
42
- unless value.is_a?(TrueClass) || value.is_a?(FalseClass)
43
- fail InvalidSyntax, 'Argument must be `true` or `false` for cursor.'
44
- end
45
-
46
- attributes[:cursor] = value
47
- end
48
-
49
31
  # To maintain performance interfaces can be delayed from refreshing too
50
32
  # often, the reduces artefacts particularly when resizing the terminal
51
33
  # screen.
@@ -2,6 +2,8 @@ module Vedeu
2
2
  module API
3
3
 
4
4
  # Provides methods to be used to define keypress mapped to actions.
5
+ #
6
+ # @api public
5
7
  class Keymap < Vedeu::Keymap
6
8
 
7
9
  # Define keypress(es) to perform an action.
@@ -2,6 +2,8 @@ module Vedeu
2
2
  module API
3
3
 
4
4
  # Provides methods to be used to define views.
5
+ #
6
+ # @api public
5
7
  class Line < Vedeu::Line
6
8
 
7
9
  include Helpers
@@ -3,6 +3,8 @@ module Vedeu
3
3
 
4
4
  # Provides the mechanism to create menus within client applications and use
5
5
  # events to drive them.
6
+ #
7
+ # @api public
6
8
  class Menu
7
9
 
8
10
  include Common
@@ -60,7 +62,7 @@ module Vedeu
60
62
  #
61
63
  # @return [Vedeu::Menu]
62
64
  def items(collection = [])
63
- attributes[:items] = Vedeu::Menu.new(collection)
65
+ attributes[:items] = collection
64
66
  end
65
67
 
66
68
  # The name of the menu. Used to reference the menu throughout your
@@ -2,12 +2,14 @@ module Vedeu
2
2
  module API
3
3
 
4
4
  # Provides methods to be used to define views.
5
+ #
6
+ # @api public
5
7
  class Stream < Vedeu::Stream
6
8
 
7
9
  include Helpers
8
10
 
9
11
  # Specify the alignment of the stream within the line. Useful in
10
- # combination with #width to provide simple formatting effects.
12
+ # combination with {#width} to provide simple formatting effects.
11
13
  #
12
14
  # @api public
13
15
  # @param value [Symbol] `:left`, `:centre` and `right` are valid values
@@ -23,13 +25,34 @@ module Vedeu
23
25
  # @return [Symbol]
24
26
  def align(value)
25
27
  unless [:left, :right, :centre].include?(value.to_sym)
26
- fail InvalidSyntax, '`align` requires a value of `:left`, `:right` ' \
28
+ fail InvalidSyntax, '`align` requires a value of `left`, `right` ' \
27
29
  'or `centre`.'
28
30
  end
29
31
 
30
32
  attributes[:align] = value.to_sym
31
33
  end
32
34
 
35
+ # Syntactic sugar used with {#align} to left align content.
36
+ #
37
+ # @return [Symbol]
38
+ def left
39
+ :left
40
+ end
41
+
42
+ # Syntactic sugar used with {#align} to right align content.
43
+ #
44
+ # @return [Symbol]
45
+ def right
46
+ :right
47
+ end
48
+
49
+ # Syntactic sugar used with {#align} to centre align content.
50
+ #
51
+ # @return [Symbol]
52
+ def centre
53
+ :centre
54
+ end
55
+
33
56
  # Add textual data to the stream via this method.
34
57
  #
35
58
  # @api public
@@ -2,7 +2,7 @@ module Vedeu
2
2
 
3
3
  # Orchestrates the running of the main application loop.
4
4
  #
5
- # @api public
5
+ # @api private
6
6
  class Application
7
7
  # :nocov:
8
8
  class << self
@@ -75,8 +75,8 @@ module Vedeu
75
75
  # For an interactive application we capture input, (usually from the user),
76
76
  # and continue the main loop.
77
77
  #
78
- # TODO: It appears for non-interactive applications, we do nothing. Must
79
- # investigate.
78
+ # @todo It appears for non-interactive applications, we do nothing. Must
79
+ # investigate.
80
80
  #
81
81
  # @api private
82
82
  # @return []
@@ -85,7 +85,7 @@ module Vedeu
85
85
  Input.capture
86
86
 
87
87
  else
88
- # TODO: What should happen here?
88
+
89
89
 
90
90
  end
91
91
  end
@@ -0,0 +1,327 @@
1
+ module Vedeu
2
+
3
+ module Configuration
4
+
5
+ # The Configuration::API class parses client application configuration into
6
+ # options used by Vedeu to affect certain behaviours.
7
+ #
8
+ # @api private
9
+ class API
10
+
11
+ include Vedeu::Common
12
+
13
+ # Configure Vedeu via a simple configuration API DSL. Options set here
14
+ # override the default Vedeu configuration set in
15
+ # {Vedeu::Configuration#defaults}.
16
+ #
17
+ # @example
18
+ # Vedeu.configure do
19
+ # ...
20
+ #
21
+ # @param block [Proc]
22
+ # @return [Hash]
23
+ def self.configure(&block)
24
+ new(&block).configuration
25
+ end
26
+
27
+ # Returns an instance of Configuration::API.
28
+ #
29
+ # @param block [Proc]
30
+ # @return [Configuration::API]
31
+ def initialize(&block)
32
+ instance_eval(&block) if block_given?
33
+ end
34
+
35
+ # Returns the configuration options set up by the API DSL.
36
+ #
37
+ # @return [Hash]
38
+ def configuration
39
+ if system_key_options.any?
40
+ options.merge({ system_keys: system_key_options })
41
+
42
+ else
43
+ options
44
+
45
+ end
46
+ end
47
+
48
+ # Sets boolean to allow user input. The default behaviour of Vedeu is to
49
+ # be interactive.
50
+ #
51
+ # @example
52
+ # Vedeu.configure do
53
+ # interactive!
54
+ # ...
55
+ #
56
+ # Vedeu.configure do
57
+ # interactive false
58
+ # ...
59
+ #
60
+ # @param value [Boolean]
61
+ # @return [Boolean]
62
+ def interactive!(value = true)
63
+ options[:interactive] = value
64
+ end
65
+ alias_method :interactive, :interactive!
66
+
67
+ # Sets boolean to prevent user intervention. This is the same as setting
68
+ # {#interactive!} to false.
69
+ #
70
+ # @example
71
+ # Vedeu.configure do
72
+ # standalone!
73
+ # ...
74
+ #
75
+ # @param value [Boolean]
76
+ # @return [Boolean]
77
+ def standalone!(value = true)
78
+ options[:interactive] = !value
79
+ end
80
+ alias_method :standalone, :standalone!
81
+
82
+ # Sets boolean to run the Vedeu main application loop once. In effect,
83
+ # using `run_once!` or setting `run_once` to true will allow Vedeu to
84
+ # initialize, run any client application code, cleanup, then terminate.
85
+ #
86
+ # @example
87
+ # Vedeu.configure do
88
+ # run_once!
89
+ # ...
90
+ #
91
+ # @param value [Boolean]
92
+ # @return [Boolean]
93
+ def run_once!(value = true)
94
+ options[:once] = value
95
+ end
96
+ alias_method :run_once, :run_once!
97
+
98
+ # Sets the terminal mode to `cooked`. Default terminal mode is `raw`.
99
+ #
100
+ # @example
101
+ # Vedeu.configure do
102
+ # cooked!
103
+ # ...
104
+ #
105
+ # @return [Boolean]
106
+ def cooked!
107
+ options[:terminal_mode] = :cooked
108
+ end
109
+ alias_method :cooked, :cooked!
110
+
111
+ # Sets the terminal mode to `raw`. Default terminal mode is `raw`.
112
+ #
113
+ # @example
114
+ # Vedeu.configure do
115
+ # raw!
116
+ # ...
117
+ #
118
+ # @return [Boolean]
119
+ def raw!
120
+ options[:terminal_mode] = :raw
121
+ end
122
+ alias_method :raw, :raw!
123
+
124
+ # Sets boolean to enable/disable debugging. Vedeu's default setting is
125
+ # for debugging to be disabled. Using `debug!` or setting `debug` to true
126
+ # will enable debugging. If `trace!` is used, or `trace` is set to true,
127
+ # debugging will be enabled, overriding any setting here.
128
+ #
129
+ # @example
130
+ # Vedeu.configure do
131
+ # debug!
132
+ # ...
133
+ #
134
+ # Vedeu.configure do
135
+ # debug false
136
+ # ...
137
+ #
138
+ # @param value [Boolean]
139
+ # @return [Boolean]
140
+ def debug!(value = true)
141
+ if options.key?(:trace) && options[:trace] != false
142
+ options[:debug] = true
143
+
144
+ else
145
+ options[:debug] = value
146
+
147
+ end
148
+ end
149
+ alias_method :debug, :debug!
150
+
151
+ # Sets boolean to enable/disable tracing. Vedeu's default setting is for
152
+ # tracing to be disabled. Using `trace!` or setting `trace` to true will
153
+ # enable tracing and debugging.
154
+ #
155
+ # @example
156
+ # Vedeu.configure do
157
+ # trace!
158
+ # ...
159
+ #
160
+ # Vedeu.configure do
161
+ # trace false
162
+ # ...
163
+ #
164
+ # @param value [Boolean]
165
+ # @return [Boolean]
166
+ def trace!(value = true)
167
+ options[:debug] = true if value === true
168
+
169
+ options[:trace] = value
170
+ end
171
+ alias_method :trace, :trace!
172
+
173
+ # Sets the colour mode of the terminal.
174
+ #
175
+ # @example
176
+ # Vedeu.configure do
177
+ # colour_mode 256
178
+ # ...
179
+ #
180
+ # @param value [Fixnum]
181
+ # @return [Boolean]
182
+ def colour_mode(value = nil)
183
+ fail InvalidSyntax, '`colour_mode` must be `8`, `16`, `256`, ' \
184
+ '`16777216`.' unless valid_colour_mode?(value)
185
+
186
+ options[:colour_mode] = value
187
+ end
188
+
189
+ # Sets the key used to exit the client application. The default is `q`.
190
+ #
191
+ # @example
192
+ # Vedeu.configure do
193
+ # exit_key 'x'
194
+ # ...
195
+ #
196
+ # Vedeu.configure do
197
+ # exit_key :f4
198
+ # ...
199
+ #
200
+ # @param value [String|Symbol]
201
+ # @return [String|Symbol]
202
+ def exit_key(value)
203
+ return invalid_key('exit_key') unless valid_key?(value)
204
+
205
+ system_key_options[:exit] = value
206
+ end
207
+
208
+ # Sets the key used to switch focus to the next defined interface. The
209
+ # default is `:tab`.
210
+ #
211
+ # @example
212
+ # Vedeu.configure do
213
+ # focus_next_key 'n'
214
+ # ...
215
+ #
216
+ # Vedeu.configure do
217
+ # focus_next_key :right
218
+ # ...
219
+ #
220
+ # @param value [String|Symbol]
221
+ # @return [String|Symbol]
222
+ def focus_next_key(value)
223
+ return invalid_key('exit_key') unless valid_key?(value)
224
+
225
+ system_key_options[:focus_next] = value
226
+ end
227
+
228
+ # Sets the key used to switch focus to the previous interface. The default
229
+ # is `:shift_tab`.
230
+ #
231
+ # @example
232
+ # Vedeu.configure do
233
+ # focus_prev_key 'p'
234
+ # ...
235
+ #
236
+ # Vedeu.configure do
237
+ # focus_prev_key :left
238
+ # ...
239
+ #
240
+ # @param value [String|Symbol]
241
+ # @return [String|Symbol]
242
+ def focus_prev_key(value)
243
+ return invalid_key('exit_key') unless valid_key?(value)
244
+
245
+ system_key_options[:focus_prev] = value
246
+ end
247
+
248
+ # Sets the key used to switch between raw and cooked mode in Vedeu. The
249
+ # default is `:escape`.
250
+ #
251
+ # @example
252
+ # Vedeu.configure do
253
+ # mode_switch_key 'm'
254
+ # ...
255
+ #
256
+ # Vedeu.configure do
257
+ # mode_switch_key :f1
258
+ # ...
259
+ #
260
+ # @param value [String|Symbol]
261
+ # @return [String|Symbol]
262
+ def mode_switch_key(value)
263
+ return invalid_key('exit_key') unless valid_key?(value)
264
+
265
+ system_key_options[:mode_switch] = value
266
+ end
267
+
268
+ private
269
+
270
+ # Returns the options set via the configuration API DSL or an empty Hash
271
+ # if none were set.
272
+ #
273
+ # @api private
274
+ # @return [Hash]
275
+ def options
276
+ @_options ||= {}
277
+ end
278
+
279
+ # Returns the system keys set via the configuration API DSL or an empty
280
+ # hash if none were redefined.
281
+ #
282
+ # @api private
283
+ # @return [Hash]
284
+ def system_key_options
285
+ @_system_key_options ||= Configuration.default_system_keys
286
+ end
287
+
288
+ # Checks that the value provided to {#colour_mode} is valid.
289
+ #
290
+ # @api private
291
+ # @param value [Fixnum]
292
+ # @return [Boolean]
293
+ def valid_colour_mode?(value)
294
+ value.is_a?(Fixnum) && [8, 16, 256, 16777216].include?(value)
295
+ end
296
+
297
+ # Checks that the value provided to {#exit_key}, {#focus_next_key},
298
+ # {#focus_prev_key} and {#mode_switch_key} is valid. Must be a Symbol or a
299
+ # non-empty String.
300
+ #
301
+ # @api private
302
+ # @param value [String|Symbol]
303
+ # @return [Boolean]
304
+ def valid_key?(value)
305
+ return false unless value.is_a?(String) || value.is_a?(Symbol)
306
+
307
+ return false if value.is_a?(String) && value.size != 1
308
+
309
+ (value.is_a?(String) || value.is_a?(Symbol)) && defined_value?(value)
310
+ end
311
+
312
+ # Raises an exception on behalf of the calling method to report that the
313
+ # value provided is not valid.
314
+ #
315
+ # @api private
316
+ # @param system_key [String] The calling method wishing to raise an
317
+ # exception.
318
+ # @return [InvalidSyntax]
319
+ def invalid_key(system_key)
320
+ fail InvalidSyntax, "`#{system_key}` must be a String or a Symbol."
321
+ end
322
+
323
+ end
324
+
325
+ end
326
+
327
+ end