vedeu 0.2.0 → 0.2.1

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -9
  3. data/docs/api.md +70 -42
  4. data/elements.txt +118 -0
  5. data/lib/vedeu.rb +14 -4
  6. data/lib/vedeu/api/api.rb +67 -24
  7. data/lib/vedeu/api/composition.rb +19 -0
  8. data/lib/vedeu/api/defined.rb +7 -0
  9. data/lib/vedeu/api/interface.rb +103 -75
  10. data/lib/vedeu/api/keymap.rb +62 -0
  11. data/lib/vedeu/api/menu.rb +3 -1
  12. data/lib/vedeu/configuration.rb +24 -6
  13. data/lib/vedeu/models/attributes/coercions.rb +18 -26
  14. data/lib/vedeu/models/attributes/colour_translator.rb +7 -7
  15. data/lib/vedeu/models/attributes/presentation.rb +12 -1
  16. data/lib/vedeu/models/geometry.rb +5 -1
  17. data/lib/vedeu/models/interface.rb +6 -47
  18. data/lib/vedeu/models/keymap.rb +66 -0
  19. data/lib/vedeu/models/line.rb +3 -1
  20. data/lib/vedeu/models/stream.rb +10 -1
  21. data/lib/vedeu/models/style.rb +10 -1
  22. data/lib/vedeu/output/compositor.rb +3 -0
  23. data/lib/vedeu/output/refresh.rb +16 -74
  24. data/lib/vedeu/output/render.rb +44 -17
  25. data/lib/vedeu/output/view.rb +3 -0
  26. data/lib/vedeu/repositories/buffers.rb +32 -42
  27. data/lib/vedeu/repositories/events.rb +8 -11
  28. data/lib/vedeu/repositories/focus.rb +15 -13
  29. data/lib/vedeu/repositories/groups.rb +20 -2
  30. data/lib/vedeu/repositories/interfaces.rb +22 -2
  31. data/lib/vedeu/repositories/keymap_validator.rb +104 -0
  32. data/lib/vedeu/repositories/keymaps.rb +239 -0
  33. data/lib/vedeu/repositories/menus.rb +12 -3
  34. data/lib/vedeu/support/common.rb +2 -2
  35. data/lib/vedeu/support/cursor.rb +3 -0
  36. data/lib/vedeu/support/event.rb +48 -7
  37. data/lib/vedeu/support/grid.rb +1 -1
  38. data/lib/vedeu/support/registrar.rb +66 -0
  39. data/lib/vedeu/support/trace.rb +71 -12
  40. data/test/lib/vedeu/api/api_test.rb +27 -9
  41. data/test/lib/vedeu/api/composition_test.rb +10 -0
  42. data/test/lib/vedeu/api/defined_test.rb +14 -0
  43. data/test/lib/vedeu/api/interface_test.rb +86 -85
  44. data/test/lib/vedeu/api/keymap_test.rb +61 -0
  45. data/test/lib/vedeu/configuration_test.rb +12 -0
  46. data/test/lib/vedeu/models/attributes/coercions_test.rb +3 -4
  47. data/test/lib/vedeu/models/interface_test.rb +0 -43
  48. data/test/lib/vedeu/models/keymap_test.rb +19 -0
  49. data/test/lib/vedeu/models/style_test.rb +10 -0
  50. data/test/lib/vedeu/output/refresh_test.rb +0 -12
  51. data/test/lib/vedeu/output/render_test.rb +51 -0
  52. data/test/lib/vedeu/repositories/buffers_test.rb +39 -12
  53. data/test/lib/vedeu/repositories/events_test.rb +6 -0
  54. data/test/lib/vedeu/repositories/focus_test.rb +12 -0
  55. data/test/lib/vedeu/repositories/keymap_validator_test.rb +81 -0
  56. data/test/lib/vedeu/repositories/keymaps_test.rb +254 -0
  57. data/test/lib/vedeu/support/common_test.rb +26 -0
  58. data/test/lib/vedeu/support/registrar_test.rb +68 -0
  59. data/vedeu.gemspec +1 -1
  60. metadata +18 -2
@@ -64,13 +64,13 @@ module Vedeu
64
64
  attr_reader :colour
65
65
 
66
66
  # @api private
67
- # @return [TrueClass|FalseClass]
67
+ # @return [Boolean]
68
68
  def no_colour?
69
69
  colour.nil? || colour.to_s.empty?
70
70
  end
71
71
 
72
72
  # @api private
73
- # @return [TrueClass|FalseClass]
73
+ # @return [Boolean]
74
74
  def named?
75
75
  colour.is_a?(Symbol) && valid_name?
76
76
  end
@@ -82,13 +82,13 @@ module Vedeu
82
82
  end
83
83
 
84
84
  # @api private
85
- # @return [TrueClass|FalseClass]
85
+ # @return [Boolean]
86
86
  def valid_name?
87
87
  codes.keys.include?(colour)
88
88
  end
89
89
 
90
90
  # @api private
91
- # @return [TrueClass|FalseClass]
91
+ # @return [Boolean]
92
92
  def numbered?
93
93
  colour.is_a?(Fixnum) && valid_range?
94
94
  end
@@ -100,13 +100,13 @@ module Vedeu
100
100
  end
101
101
 
102
102
  # @api private
103
- # @return [TrueClass|FalseClass]
103
+ # @return [Boolean]
104
104
  def valid_range?
105
105
  colour >= 0 && colour <= 255
106
106
  end
107
107
 
108
108
  # @api private
109
- # @return [TrueClass|FalseClass]
109
+ # @return [Boolean]
110
110
  def rgb?
111
111
  colour.is_a?(String) && valid_rgb?
112
112
  end
@@ -118,7 +118,7 @@ module Vedeu
118
118
  end
119
119
 
120
120
  # @api private
121
- # @return [TrueClass|FalseClass]
121
+ # @return [Boolean]
122
122
  def valid_rgb?
123
123
  !!(colour =~ /^#([A-Fa-f0-9]{6})$/)
124
124
  end
@@ -6,7 +6,7 @@ module Vedeu
6
6
  # @api private
7
7
  module Presentation
8
8
 
9
- # Returns the colour attributes of the receiving class.
9
+ # Returns the colour and style attributes of the receiving class.
10
10
  #
11
11
  # @return [Hash]
12
12
  def view_attributes
@@ -45,18 +45,28 @@ module Vedeu
45
45
 
46
46
  private
47
47
 
48
+ # Renders the colour attributes of the receiver, yields (to then render the
49
+ # the styles) and once returned, attempts to set the colours back to the
50
+ # those of the receiver's parent.
51
+ #
48
52
  # @api private
49
53
  # @return [String]
50
54
  def render_colour(&block)
51
55
  [ colour.to_s, yield, parent_colour ].join
52
56
  end
53
57
 
58
+ # Renders the style attributes of the receiver, yields (to then render the
59
+ # next model, or finally, the content) and once returned, attempts to set
60
+ # the colours back to those of the receiver's parent.
61
+ #
54
62
  # @api private
55
63
  # @return [String]
56
64
  def render_style(&block)
57
65
  [ style.to_s, yield, parent_style ].join
58
66
  end
59
67
 
68
+ # Returns the parent colour as an escape sequence if set.
69
+ #
60
70
  # @api private
61
71
  # @return [String]
62
72
  def parent_colour
@@ -65,6 +75,7 @@ module Vedeu
65
75
  Colour.new(parent[:colour]).to_s
66
76
  end
67
77
 
78
+ # Returns the parent style as an escape sequence if set.
68
79
  # @api private
69
80
  # @return [String]
70
81
  def parent_style
@@ -3,13 +3,15 @@ module Vedeu
3
3
  # Calculates and provides interface geometry determined by both the client's
4
4
  # requirements and the terminal's current viewing area.
5
5
  #
6
+ # With terminal geometry, the origin is top-left, y = 1, x = 1.
7
+ #
6
8
  # @api private
7
9
  class Geometry
8
10
 
9
11
  # @return [Hash]
10
12
  attr_reader :attributes
11
13
 
12
- # @return [TrueClass|FalseClass]
14
+ # @return [Boolean]
13
15
  attr_reader :centred
14
16
 
15
17
  # @return [Fixnum]
@@ -166,6 +168,8 @@ module Vedeu
166
168
  left - value
167
169
  end
168
170
 
171
+ # Returns a fixed or dynamic value depending on the value of {#top}.
172
+ #
169
173
  # @return [Fixnum]
170
174
  def bottom
171
175
  top + height
@@ -17,6 +17,8 @@ module Vedeu
17
17
 
18
18
  attr_reader :attributes, :delay, :group, :name, :parent
19
19
 
20
+ # Builds up a new Interface object and returns the attributes.
21
+ #
20
22
  # @param attributes [Hash]
21
23
  # @param block [Proc]
22
24
  # @return [Hash]
@@ -58,9 +60,7 @@ module Vedeu
58
60
  def define(&block)
59
61
  instance_eval(&block) if block_given?
60
62
 
61
- validate_attributes!
62
-
63
- Vedeu::Buffers.create(attributes)
63
+ Registrar.record(attributes)
64
64
 
65
65
  self
66
66
  end
@@ -69,9 +69,11 @@ module Vedeu
69
69
  #
70
70
  # @return [Array]
71
71
  def lines
72
- @lines ||= Line.coercer(attributes[:lines], parent)
72
+ @lines ||= Line.coercer(attributes[:lines])
73
73
  end
74
74
 
75
+ # Returns the position and size of the interface.
76
+ #
75
77
  # @return [Geometry]
76
78
  def geometry
77
79
  @geometry ||= Geometry.new(attributes[:geometry])
@@ -88,22 +90,6 @@ module Vedeu
88
90
  end
89
91
  end
90
92
 
91
- # @return [String]
92
- def to_s
93
- Render.call(self)
94
- end
95
-
96
- # @param options [Hash]
97
- # @return [String]
98
- def render(options = {})
99
- Render.call(self, options)
100
- end
101
-
102
- # @return [String]
103
- def clear
104
- Clear.call(self)
105
- end
106
-
107
93
  private
108
94
 
109
95
  # The default values for a new instance of Interface.
@@ -124,33 +110,6 @@ module Vedeu
124
110
  }
125
111
  end
126
112
 
127
- # @api private
128
- # @return [TrueClass|FalseClass]
129
- def validate_attributes!
130
- unless defined_value?(attributes[:name])
131
- fail InvalidSyntax, 'Interfaces and views must have a `name`.'
132
- end
133
- end
134
-
135
- # @api private
136
- # @return [String]
137
- def out_of_bounds(name)
138
- "Note: For this terminal, the value of '#{name}' may lead to content " \
139
- "that is outside the viewable area."
140
- end
141
-
142
- # @api private
143
- # @return [TrueClass|FalseClass]
144
- def y_out_of_bounds?(value)
145
- value < 1 || value > Terminal.height
146
- end
147
-
148
- # @api private
149
- # @return [TrueClass|FalseClass]
150
- def x_out_of_bounds?(value)
151
- value < 1 || value > Terminal.width
152
- end
153
-
154
113
  # @api private
155
114
  # @return []
156
115
  def method_missing(method, *args, &block)
@@ -0,0 +1,66 @@
1
+ module Vedeu
2
+
3
+ # A Keymap is the binding of a keypress to one or more interfaces; or globally
4
+ # to perform a client application defined action.
5
+ class Keymap
6
+
7
+ include Common
8
+
9
+ attr_reader :attributes
10
+
11
+ # Define a keymap for an interface or interfaces to perform an action when
12
+ # a key is pressed whilst an aforementioned interface is in focus.
13
+ #
14
+ # @param attributes [Hash]
15
+ # @param block [Proc]
16
+ # @return [Keymap]
17
+ def self.define(attributes = {}, &block)
18
+ new(attributes).define(&block)
19
+ end
20
+
21
+ # Instantiate a new instance of the Keymap model.
22
+ #
23
+ # @param attributes [Hash]
24
+ # @return [Keymap]
25
+ def initialize(attributes = {})
26
+ @attributes = defaults.merge!(attributes)
27
+ end
28
+
29
+ # Adds the attributes to the Keymaps repository.
30
+ #
31
+ # @param block [Proc]
32
+ # @return [Interface]
33
+ def define(&block)
34
+ if block_given?
35
+ @self_before_instance_eval = eval('self', block.binding)
36
+
37
+ instance_eval(&block)
38
+ end
39
+
40
+ Keymaps.add(attributes)
41
+
42
+ self
43
+ end
44
+
45
+ private
46
+
47
+ # The default attributes of the Keymap model.
48
+ #
49
+ # @api private
50
+ # @return [Hash]
51
+ def defaults
52
+ {
53
+ interfaces: [], # the interface(s) which will respond to the keypress(es)
54
+ keys: [], # the keypress/action pairs for this keymap
55
+ }
56
+ end
57
+
58
+ # @api private
59
+ # @return []
60
+ def method_missing(method, *args, &block)
61
+ @self_before_instance_eval.send(method, *args, &block)
62
+ end
63
+
64
+ end
65
+
66
+ end
@@ -10,6 +10,8 @@ module Vedeu
10
10
 
11
11
  attr_reader :attributes, :parent
12
12
 
13
+ # Builds up a new Line object and returns the attributes.
14
+ #
13
15
  # @param attributes [Hash]
14
16
  # @param block [Proc]
15
17
  # @return [Hash]
@@ -37,7 +39,7 @@ module Vedeu
37
39
  #
38
40
  # @return [Array]
39
41
  def streams
40
- @streams ||= Stream.coercer(attributes[:streams], parent)
42
+ @streams ||= Stream.coercer(attributes[:streams])
41
43
  end
42
44
 
43
45
  private
@@ -10,6 +10,8 @@ module Vedeu
10
10
 
11
11
  attr_reader :attributes, :align, :text, :width, :parent
12
12
 
13
+ # Builds up a new Stream object and returns the attributes.
14
+ #
13
15
  # @param attributes [Hash]
14
16
  # @param block [Proc]
15
17
  # @return [Hash]
@@ -38,12 +40,17 @@ module Vedeu
38
40
 
39
41
  private
40
42
 
43
+ # Returns the text aligned if a width was set, otherwise just the text.
44
+ #
41
45
  # @api private
42
46
  # @return [String]
43
47
  def data
44
48
  width? ? aligned : text
45
49
  end
46
50
 
51
+ # Returns an aligned string if the string is shorter than the specified
52
+ # width; the excess area being padded by spaces.
53
+ #
47
54
  # @api private
48
55
  # @return [String]
49
56
  def aligned
@@ -54,8 +61,10 @@ module Vedeu
54
61
  end
55
62
  end
56
63
 
64
+ # Returns a boolean to indicate whether this stream has a width set.
65
+ #
57
66
  # @api private
58
- # @return [TrueClass|FalseClass]
67
+ # @return [Boolean]
59
68
  def width?
60
69
  !!width
61
70
  end
@@ -6,7 +6,7 @@ module Vedeu
6
6
 
7
7
  include Vedeu::Common
8
8
 
9
- attr_reader :values
9
+ attr_reader :attributes, :values
10
10
 
11
11
  # Return a new instance of Style.
12
12
  #
@@ -16,6 +16,15 @@ module Vedeu
16
16
  @values = values
17
17
  end
18
18
 
19
+ # Return an attributes hash for this class.
20
+ #
21
+ # @return [Hash]
22
+ def attributes
23
+ {
24
+ style: values
25
+ }
26
+ end
27
+
19
28
  # Return the terminal escape sequences for the values provided.
20
29
  #
21
30
  # @return [String]
@@ -34,6 +34,9 @@ module Vedeu
34
34
  # @return [String]
35
35
  attr_reader :name
36
36
 
37
+ # Renders the buffer unless empty, otherwise clears the area which the
38
+ # interface occupies.
39
+ #
37
40
  # @api private
38
41
  # @return [String]
39
42
  def view
@@ -8,22 +8,6 @@ module Vedeu
8
8
  include Vedeu::Common
9
9
  extend self
10
10
 
11
- # Add a refresh event for the interface.
12
- #
13
- # @param attributes [Hash]
14
- # @return [TrueClass|FalseClass]
15
- def add_interface(attributes)
16
- register_by_name(attributes[:name], attributes[:delay])
17
- end
18
-
19
- # Add a refresh event for the group.
20
- #
21
- # @param attributes [Hash]
22
- # @return [TrueClass|FalseClass]
23
- def add_group(attributes)
24
- register_by_group(attributes[:group], attributes[:delay])
25
- end
26
-
27
11
  # Refresh all registered interfaces.
28
12
  #
29
13
  # @return [Array]
@@ -55,75 +39,33 @@ module Vedeu
55
39
  Vedeu::Compositor.render(name)
56
40
  end
57
41
 
58
- private
59
-
60
- # Register a refresh event for an interface by name. When the event is
61
- # called, the interface with this name will be refreshed.
42
+ # Register a refresh event for an interface or group of interfaces by name.
43
+ # When the event is called, the interface, or all interfaces belonging to
44
+ # the group with this name will be refreshed.
62
45
  #
63
46
  # @api private
64
- # @param name [String] The name of the interface to be refreshed.
65
- # @param delay [Float] The throttle for how often this interface can be
66
- # refreshed.
67
- # @return []
68
- def register_by_name(name, delay)
69
- return false unless defined_value?(name)
70
- return false if event_registered?(event_name(name))
47
+ # @param type [Symbol]
48
+ # @param name [String]
49
+ # @param delay [Float]
50
+ # @return [Boolean]
51
+ def register_event(type, name, delay = 0.0)
52
+ event = if type == :by_group
53
+ "_refresh_group_#{name}_".to_sym
71
54
 
72
- Vedeu.event(event_name(name), { delay: delay }) do
73
- Vedeu::Refresh.by_name(name)
74
- end
55
+ else
56
+ "_refresh_#{name}_".to_sym
75
57
 
76
- true
77
- end
58
+ end
78
59
 
79
- # Register a refresh event for a group of interfaces by name. When the event
80
- # is called, all interfaces belonging to the group with this name will be
81
- # refreshed.
82
- #
83
- # @api private
84
- # @param name [String] The name of the group to be refreshed.
85
- # @param delay [Float] The throttle for how often this group can be
86
- # refreshed.
87
- # @return []
88
- def register_by_group(name, delay)
89
- return false unless defined_value?(name)
90
- return false if event_registered?(group_event_name(name))
60
+ return false if Vedeu.events.registered?(event)
91
61
 
92
- Vedeu.event(group_event_name(name), { delay: delay }) do
93
- Vedeu::Refresh.by_group(name)
62
+ Vedeu.event(event, { delay: delay }) do
63
+ Vedeu::Refresh.send(type, name)
94
64
  end
95
65
 
96
66
  true
97
67
  end
98
68
 
99
- # Returns the event name for refreshing the named interface.
100
- #
101
- # @api private
102
- # @param name [String] The name of the interface.
103
- # @return [Symbol]
104
- def event_name(name)
105
- "_refresh_#{name}_".to_sym
106
- end
107
-
108
- # Returns the event name for refreshing the named group of interfaces.
109
- #
110
- # @api private
111
- # @param name [String] The name of the group.
112
- # @return [Symbol]
113
- def group_event_name(name)
114
- "_refresh_group_#{name}_".to_sym
115
- end
116
-
117
- # Returns a boolean indicating that an event by name has already been
118
- # registered.
119
- #
120
- # @api private
121
- # @param name [Symbol] The event name to check.
122
- # @return [TrueClass|FalseClass]
123
- def event_registered?(name)
124
- Vedeu.events.registered?(name)
125
- end
126
-
127
69
  end
128
70
 
129
71
  end