vedeu 0.1.18 → 0.1.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +5 -0
  3. data/Dockerfile +40 -0
  4. data/README.md +7 -30
  5. data/docs/api.md +79 -0
  6. data/docs/events.md +121 -0
  7. data/lib/vedeu.rb +61 -18
  8. data/lib/vedeu/api/api.rb +73 -53
  9. data/lib/vedeu/api/composition.rb +4 -1
  10. data/lib/vedeu/api/defined.rb +35 -0
  11. data/lib/vedeu/api/helpers.rb +20 -15
  12. data/lib/vedeu/api/interface.rb +17 -12
  13. data/lib/vedeu/api/line.rb +20 -12
  14. data/lib/vedeu/api/stream.rb +3 -0
  15. data/lib/vedeu/application.rb +34 -1
  16. data/lib/vedeu/configuration.rb +15 -3
  17. data/lib/vedeu/input/input.rb +77 -0
  18. data/lib/vedeu/launcher.rb +7 -0
  19. data/lib/vedeu/models/attributes/background.rb +15 -2
  20. data/lib/vedeu/models/attributes/coercions.rb +18 -3
  21. data/lib/vedeu/models/attributes/colour_translator.rb +23 -17
  22. data/lib/vedeu/models/attributes/foreground.rb +10 -2
  23. data/lib/vedeu/models/attributes/presentation.rb +62 -0
  24. data/lib/vedeu/models/colour.rb +7 -3
  25. data/lib/vedeu/models/composition.rb +17 -19
  26. data/lib/vedeu/models/geometry.rb +13 -5
  27. data/lib/vedeu/models/interface.rb +35 -19
  28. data/lib/vedeu/models/line.rb +24 -8
  29. data/lib/vedeu/models/stream.rb +13 -7
  30. data/lib/vedeu/models/style.rb +17 -7
  31. data/lib/vedeu/{support → output}/clear.rb +14 -0
  32. data/lib/vedeu/output/compositor.rb +77 -0
  33. data/lib/vedeu/output/refresh.rb +129 -0
  34. data/lib/vedeu/{support → output}/render.rb +49 -13
  35. data/lib/vedeu/{support → output}/view.rb +15 -8
  36. data/lib/vedeu/repositories/buffers.rb +181 -0
  37. data/lib/vedeu/{support → repositories}/events.rb +16 -6
  38. data/lib/vedeu/repositories/focus.rb +109 -0
  39. data/lib/vedeu/repositories/groups.rb +76 -0
  40. data/lib/vedeu/repositories/interfaces.rb +74 -0
  41. data/lib/vedeu/support/common.rb +20 -0
  42. data/lib/vedeu/support/cursor.rb +77 -0
  43. data/lib/vedeu/support/esc.rb +181 -46
  44. data/lib/vedeu/support/event.rb +22 -4
  45. data/lib/vedeu/support/grid.rb +10 -3
  46. data/lib/vedeu/support/log.rb +14 -1
  47. data/lib/vedeu/support/menu.rb +51 -12
  48. data/lib/vedeu/support/position.rb +9 -0
  49. data/lib/vedeu/support/terminal.rb +49 -15
  50. data/lib/vedeu/support/trace.rb +11 -4
  51. data/test/integration/defining_interfaces_test.rb +27 -0
  52. data/test/integration/views/basic_view_test.rb +767 -0
  53. data/test/lib/vedeu/api/api_test.rb +32 -37
  54. data/test/lib/vedeu/api/composition_test.rb +23 -61
  55. data/test/lib/vedeu/api/defined_test.rb +49 -0
  56. data/test/lib/vedeu/api/helpers_test.rb +91 -0
  57. data/test/lib/vedeu/api/interface_test.rb +136 -688
  58. data/test/lib/vedeu/api/line_test.rb +28 -32
  59. data/test/lib/vedeu/application_test.rb +6 -0
  60. data/test/lib/vedeu/configuration_test.rb +8 -4
  61. data/test/lib/vedeu/{support → input}/input_test.rb +9 -0
  62. data/test/lib/vedeu/launcher_test.rb +6 -0
  63. data/test/lib/vedeu/models/attributes/{coercer_test.rb → coercions_test.rb} +11 -10
  64. data/test/lib/vedeu/models/attributes/colour_translator_test.rb +13 -0
  65. data/test/lib/vedeu/models/attributes/presentation_test.rb +30 -0
  66. data/test/lib/vedeu/models/colour_test.rb +8 -0
  67. data/test/lib/vedeu/models/composition_test.rb +208 -200
  68. data/test/lib/vedeu/models/geometry_test.rb +39 -0
  69. data/test/lib/vedeu/models/interface_test.rb +11 -1
  70. data/test/lib/vedeu/models/line_test.rb +8 -1
  71. data/test/lib/vedeu/models/stream_test.rb +35 -0
  72. data/test/lib/vedeu/models/style_test.rb +8 -0
  73. data/test/lib/vedeu/{support → output}/clear_test.rb +1 -1
  74. data/test/lib/vedeu/output/compositor_test.rb +64 -0
  75. data/test/lib/vedeu/output/refresh_test.rb +48 -0
  76. data/test/lib/vedeu/{support → output}/render_test.rb +36 -0
  77. data/test/lib/vedeu/{support → output}/view_test.rb +0 -0
  78. data/test/lib/vedeu/repositories/buffers_test.rb +48 -0
  79. data/test/lib/vedeu/{support → repositories}/events_test.rb +0 -0
  80. data/test/lib/vedeu/repositories/focus_test.rb +74 -0
  81. data/test/lib/vedeu/repositories/groups_test.rb +66 -0
  82. data/test/lib/vedeu/repositories/interfaces_test.rb +6 -0
  83. data/test/lib/vedeu/support/common_test.rb +6 -0
  84. data/test/lib/vedeu/support/cursor_test.rb +79 -0
  85. data/test/lib/vedeu/support/log_test.rb +6 -0
  86. data/test/lib/vedeu/support/terminal_test.rb +6 -28
  87. data/test/lib/vedeu/support/trace_test.rb +6 -0
  88. data/test/test_helper.rb +37 -0
  89. data/vedeu.gemspec +1 -1
  90. metadata +65 -33
  91. data/bin/log +0 -13
  92. data/lib/vedeu/support/buffer.rb +0 -69
  93. data/lib/vedeu/support/buffers.rb +0 -106
  94. data/lib/vedeu/support/focus.rb +0 -83
  95. data/lib/vedeu/support/groups.rb +0 -61
  96. data/lib/vedeu/support/input.rb +0 -67
  97. data/test/lib/vedeu/support/buffer_test.rb +0 -83
  98. data/test/lib/vedeu/support/buffers_test.rb +0 -15
  99. data/test/lib/vedeu/support/focus_test.rb +0 -114
  100. data/test/lib/vedeu/support/groups_test.rb +0 -65
@@ -1,10 +1,14 @@
1
1
  module Vedeu
2
+
3
+ # Calculates and provides interface geometry determined by both the client's
4
+ # requirements and the terminal's current viewing area.
5
+ #
6
+ # @api private
2
7
  class Geometry
3
8
 
4
9
  attr_reader :attributes, :centred, :height, :width
5
10
 
6
- # Calculate and provide interface geometry determined by both the client's
7
- # requirements and the terminal's current viewing area.
11
+ # Returns a new instance of Geometry.
8
12
  #
9
13
  # @param attributes [Hash]
10
14
  # @return [Geometry]
@@ -55,7 +59,8 @@ module Vedeu
55
59
  # @return [Fixnum]
56
60
  def viewport_width
57
61
  if (x + width) > Terminal.width
58
- width - ((x + width) - Terminal.width)
62
+ new_width = width - ((x + width) - Terminal.width)
63
+ return new_width < 1 ? 1 : new_width
59
64
 
60
65
  else
61
66
  width
@@ -75,7 +80,8 @@ module Vedeu
75
80
  # @return [Fixnum]
76
81
  def viewport_height
77
82
  if (y + height) > Terminal.height
78
- height - ((y + height) - Terminal.height)
83
+ new_height = height - ((y + height) - Terminal.height)
84
+ return new_height < 1 ? 1 : new_height
79
85
 
80
86
  else
81
87
  height
@@ -94,7 +100,7 @@ module Vedeu
94
100
 
95
101
  # Returns a fixed or dynamic value depending on whether the interface is
96
102
  # centred or not.
97
- #
103
+ #
98
104
  # @return [Fixnum]
99
105
  def top
100
106
  if centred
@@ -209,6 +215,8 @@ module Vedeu
209
215
  (left..right).to_a
210
216
  end
211
217
 
218
+ # The default geometry of an interface- full screen.
219
+ #
212
220
  # @return [Hash]
213
221
  def defaults
214
222
  {
@@ -1,16 +1,21 @@
1
1
  module Vedeu
2
+
3
+ # An Interface represents a portion of the terminal defined by
4
+ # {Vedeu::Geometry}. It is a container for {Vedeu::Line} and {Vedeu::Stream}
5
+ # objects.
2
6
  class Interface
7
+
3
8
  include Coercions
9
+ include Common
4
10
  include Presentation
5
11
 
6
12
  extend Forwardable
7
13
 
8
- def_delegators :geometry, :north, :east, :south, :west,
9
- :top, :right, :bottom, :left,
10
- :width, :height, :origin,
14
+ def_delegators :geometry, :north, :east, :south, :west, :top, :right,
15
+ :bottom, :left, :width, :height, :origin,
11
16
  :viewport_width, :viewport_height
12
17
 
13
- attr_reader :attributes, :delay, :group, :name
18
+ attr_reader :attributes, :delay, :group, :name, :parent
14
19
 
15
20
  # @param attributes [Hash]
16
21
  # @param block [Proc]
@@ -27,6 +32,8 @@ module Vedeu
27
32
  new(attributes).define(&block)
28
33
  end
29
34
 
35
+ # Return a new instance of Interface.
36
+ #
30
37
  # @param attributes [Hash]
31
38
  # @param block [Proc]
32
39
  # @return [Interface]
@@ -36,6 +43,7 @@ module Vedeu
36
43
  @name = @attributes[:name]
37
44
  @group = @attributes[:group]
38
45
  @delay = @attributes[:delay]
46
+ @parent = @attributes[:parent]
39
47
 
40
48
  if block_given?
41
49
  @self_before_instance_eval = eval('self', block.binding)
@@ -46,31 +54,22 @@ module Vedeu
46
54
 
47
55
  # @see Vedeu::API#interface
48
56
  # @param block [Proc]
49
- #
50
- # @example
51
- # TODO
52
- #
53
- # @return []
57
+ # @return [Interface]
54
58
  def define(&block)
55
59
  instance_eval(&block) if block_given?
56
60
 
57
- if attributes[:name].nil? || attributes[:name].empty?
58
- fail InvalidSyntax, 'Interfaces and views must have a `name`.'
59
- end
61
+ validate_attributes!
60
62
 
61
63
  Vedeu::Buffers.create(attributes)
62
64
 
63
- Vedeu.event("_refresh_#{attributes[:name]}_".to_sym,
64
- { delay: attributes[:delay] }) do
65
- Vedeu::Buffers.refresh(attributes[:name])
66
- end
67
-
68
65
  self
69
66
  end
70
67
 
68
+ # Returns a collection of lines associated with this interface.
69
+ #
71
70
  # @return [Array]
72
71
  def lines
73
- @lines ||= Line.coercer(attributes[:lines])
72
+ @lines ||= Line.coercer(attributes[:lines], parent)
74
73
  end
75
74
 
76
75
  # @return [Geometry]
@@ -94,6 +93,12 @@ module Vedeu
94
93
  Render.call(self)
95
94
  end
96
95
 
96
+ # @param options [Hash]
97
+ # @return [String]
98
+ def render(options = {})
99
+ Render.call(self, options)
100
+ end
101
+
97
102
  # @return [String]
98
103
  def clear
99
104
  Clear.call(self)
@@ -101,6 +106,8 @@ module Vedeu
101
106
 
102
107
  private
103
108
 
109
+ # The default values for a new instance of Interface.
110
+ #
104
111
  # @api private
105
112
  # @return [Hash]
106
113
  def defaults
@@ -112,10 +119,19 @@ module Vedeu
112
119
  style: '',
113
120
  geometry: {},
114
121
  cursor: true,
115
- delay: 0.0
122
+ delay: 0.0,
123
+ parent: nil,
116
124
  }
117
125
  end
118
126
 
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
+
119
135
  # @api private
120
136
  # @return [String]
121
137
  def out_of_bounds(name)
@@ -1,9 +1,14 @@
1
1
  module Vedeu
2
+
3
+ # A Line represents a single row of the terminal. It is a container for
4
+ # {Vedeu::Stream} objects. A line's width is determined by the
5
+ # {Vedeu::Interface} it belongs to.
2
6
  class Line
7
+
3
8
  include Coercions
4
9
  include Presentation
5
10
 
6
- attr_reader :attributes
11
+ attr_reader :attributes, :parent
7
12
 
8
13
  # @param attributes [Hash]
9
14
  # @param block [Proc]
@@ -12,11 +17,14 @@ module Vedeu
12
17
  new(attributes, &block).attributes
13
18
  end
14
19
 
20
+ # Returns a new instance of Line.
21
+ #
15
22
  # @param attributes [Hash]
16
23
  # @param block [Proc]
17
24
  # @return [Line]
18
25
  def initialize(attributes = {}, &block)
19
26
  @attributes = defaults.merge!(attributes)
27
+ @parent = @attributes[:parent]
20
28
 
21
29
  if block_given?
22
30
  @self_before_instance_eval = eval('self', block.binding)
@@ -25,25 +33,33 @@ module Vedeu
25
33
  end
26
34
  end
27
35
 
36
+ # Returns a collection of streams associated with this line.
37
+ #
28
38
  # @return [Array]
29
39
  def streams
30
- @streams ||= Stream.coercer(attributes[:streams])
31
- end
32
-
33
- # @return [String]
34
- def to_s
35
- [ colour, style, streams ].join
40
+ @streams ||= Stream.coercer(attributes[:streams], parent)
36
41
  end
37
42
 
38
43
  private
39
44
 
45
+ # Convenience method to provide Presentation with a consistent interface.
46
+ #
47
+ # @api private
48
+ # @return [Array]
49
+ def data
50
+ streams
51
+ end
52
+
53
+ # The default values for a new instance of Line.
54
+ #
40
55
  # @api private
41
56
  # @return [Hash]
42
57
  def defaults
43
58
  {
44
59
  colour: {},
45
60
  streams: [],
46
- style: []
61
+ style: [],
62
+ parent: nil,
47
63
  }
48
64
  end
49
65
 
@@ -1,9 +1,14 @@
1
1
  module Vedeu
2
+
3
+ # A Stream can represent a character or collection of characters as part of a
4
+ # {Vedeu::Line} which you wish to colour and style independently of the other
5
+ # characters in that line.
2
6
  class Stream
7
+
3
8
  include Coercions
4
9
  include Presentation
5
10
 
6
- attr_reader :attributes, :align, :text, :width
11
+ attr_reader :attributes, :align, :text, :width, :parent
7
12
 
8
13
  # @param attributes [Hash]
9
14
  # @param block [Proc]
@@ -12,6 +17,8 @@ module Vedeu
12
17
  new(attributes, &block).attributes
13
18
  end
14
19
 
20
+ # Returns a new instance of Stream.
21
+ #
15
22
  # @param attributes [Hash]
16
23
  # @param block [Proc]
17
24
  # @return [Stream]
@@ -20,6 +27,7 @@ module Vedeu
20
27
  @align = @attributes[:align]
21
28
  @text = @attributes[:text]
22
29
  @width = @attributes[:width]
30
+ @parent = @attributes[:parent]
23
31
 
24
32
  if block_given?
25
33
  @self_before_instance_eval = eval('self', block.binding)
@@ -28,11 +36,6 @@ module Vedeu
28
36
  end
29
37
  end
30
38
 
31
- # @return [String]
32
- def to_s
33
- [ colour, style, data ].join
34
- end
35
-
36
39
  private
37
40
 
38
41
  # @api private
@@ -57,6 +60,8 @@ module Vedeu
57
60
  !!width
58
61
  end
59
62
 
63
+ # The default values for a new instance of Stream.
64
+ #
60
65
  # @api private
61
66
  # @return [Hash]
62
67
  def defaults
@@ -65,7 +70,8 @@ module Vedeu
65
70
  style: [],
66
71
  text: '',
67
72
  width: nil,
68
- align: :left
73
+ align: :left,
74
+ parent: nil,
69
75
  }
70
76
  end
71
77
 
@@ -1,14 +1,23 @@
1
1
  module Vedeu
2
+
3
+ # Converts the style value or value collection into a terminal escape
4
+ # sequence. Unrecognised values are discarded- an empty string is returned.
2
5
  class Style
3
6
 
7
+ include Vedeu::Common
8
+
4
9
  attr_reader :values
5
10
 
6
- # @param values [String|Array]
11
+ # Return a new instance of Style.
12
+ #
13
+ # @param values [String|Array] The style value or values collection.
7
14
  # @return [Style]
8
15
  def initialize(values)
9
16
  @values = values
10
17
  end
11
18
 
19
+ # Return the terminal escape sequences for the values provided.
20
+ #
12
21
  # @return [String]
13
22
  def to_s
14
23
  escape_sequences
@@ -16,16 +25,17 @@ module Vedeu
16
25
 
17
26
  private
18
27
 
28
+ # Converts the style or styles into terminal escape sequences.
29
+ #
19
30
  # @api private
20
31
  # @return [String]
21
32
  def escape_sequences
22
- @_sequences ||= if values.nil? || values.empty?
23
- ''
33
+ return '' unless defined_value?(values)
24
34
 
25
- else
26
- Array(values).flatten.map { |value| Esc.string(value) }.join
27
-
28
- end
35
+ @_sequences ||= Array(values).flatten.map do |value|
36
+ Esc.string(value)
37
+ end.join
29
38
  end
39
+
30
40
  end
31
41
  end
@@ -1,18 +1,32 @@
1
1
  module Vedeu
2
+
3
+ # Clears all the character data for the area defined by an interface. This
4
+ # class is called every time an interface is rendered to prepare the area
5
+ # for new data.
6
+ #
7
+ # @api private
2
8
  class Clear
3
9
 
10
+ # Blanks the area defined by the interface.
11
+ #
4
12
  # @param interface [Interface]
5
13
  # @return [String]
6
14
  def self.call(interface)
7
15
  new(interface).clear
8
16
  end
9
17
 
18
+ # Returns a new instance of Clear.
19
+ #
10
20
  # @param interface [Interface]
11
21
  # @return [Clear]
12
22
  def initialize(interface)
13
23
  @interface = interface
14
24
  end
15
25
 
26
+ # For each visible line of the interface, set the foreground and background
27
+ # colours to those specified when the interface was defined, then starting
28
+ # write space characters over the area which the interface occupies.
29
+ #
16
30
  # @return [String]
17
31
  def clear
18
32
  rows.inject([colours]) do |line, index|
@@ -0,0 +1,77 @@
1
+ module Vedeu
2
+
3
+ # Combines stored interface layout/geometry with an interface view/buffer
4
+ # to create a single view to be sent to the terminal for output.
5
+ #
6
+ # @api private
7
+ class Compositor
8
+
9
+ include Common
10
+
11
+ # @param name [String] The name of the interface/buffer.
12
+ # @return [Compositor]
13
+ def self.render(name)
14
+ new(name).render
15
+ end
16
+
17
+ # Initialize a new Compositor.
18
+ #
19
+ # @param name [String] The name of the interface/buffer.
20
+ # @return [Compositor]
21
+ def initialize(name)
22
+ @name = name
23
+ end
24
+
25
+ # Send the view to the terminal.
26
+ #
27
+ # @return [Array]
28
+ def render
29
+ Terminal.output(view)
30
+ end
31
+
32
+ private
33
+
34
+ attr_reader :name
35
+
36
+ # @api private
37
+ # @return [String]
38
+ def view
39
+ if buffer
40
+ Render.call(Interface.new(new_interface))
41
+
42
+ else
43
+ Clear.call(Interface.new(interface))
44
+
45
+ end
46
+ end
47
+
48
+ # Combine the buffer attributes with the interface attributes. Buffer
49
+ # presentation attributes will override interface defaults.
50
+ #
51
+ # @api private
52
+ # @return [Hash]
53
+ def new_interface
54
+ combined = interface
55
+ combined[:lines] = buffer[:lines]
56
+ combined[:colour] = buffer[:colour] if defined_value?(buffer[:colour])
57
+ combined[:style] = buffer[:style] if defined_value?(buffer[:style])
58
+ combined
59
+ end
60
+
61
+ # Returns the attributes of the named interface (layout).
62
+ #
63
+ # @api private
64
+ # @return [Hash]
65
+ def interface
66
+ @_interface ||= Vedeu::Interfaces.find(name)
67
+ end
68
+
69
+ # Returns the attributes of the latest buffer (view).
70
+ #
71
+ # @api private
72
+ # @return [Hash]
73
+ def buffer
74
+ @_buffer ||= Vedeu::Buffers.latest(name)
75
+ end
76
+ end
77
+ end