vedeu 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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