vedeu 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/LICENSE.txt +5 -0
- data/bin/vedeu +3 -1
- data/docs/api.md +2 -0
- data/examples/cursor_app/cursor_app.rb +22 -7
- data/examples/hello_world.rb +42 -0
- data/lib/vedeu.rb +5 -5
- data/lib/vedeu/api/api.rb +16 -33
- data/lib/vedeu/api/helpers.rb +86 -0
- data/lib/vedeu/api/interface.rb +60 -17
- data/lib/vedeu/api/keymap.rb +5 -0
- data/lib/vedeu/api/line.rb +52 -34
- data/lib/vedeu/api/menu.rb +1 -1
- data/lib/vedeu/api/stream.rb +0 -34
- data/lib/vedeu/configuration/api.rb +10 -10
- data/lib/vedeu/configuration/cli.rb +1 -1
- data/lib/vedeu/launcher.rb +21 -6
- data/lib/vedeu/models/background.rb +1 -1
- data/lib/vedeu/models/composition.rb +1 -1
- data/lib/vedeu/models/cursor.rb +25 -35
- data/lib/vedeu/models/foreground.rb +1 -1
- data/lib/vedeu/models/geometry.rb +216 -6
- data/lib/vedeu/models/interface.rb +14 -16
- data/lib/vedeu/models/keymap.rb +38 -6
- data/lib/vedeu/models/line.rb +1 -1
- data/lib/vedeu/models/stream.rb +1 -1
- data/lib/vedeu/output/compositor.rb +1 -1
- data/lib/vedeu/output/render.rb +1 -5
- data/lib/vedeu/output/viewport.rb +37 -2
- data/lib/vedeu/repositories/buffers.rb +21 -27
- data/lib/vedeu/repositories/cursors.rb +3 -15
- data/lib/vedeu/repositories/focus.rb +2 -6
- data/lib/vedeu/repositories/groups.rb +1 -1
- data/lib/vedeu/repositories/interfaces.rb +1 -1
- data/lib/vedeu/repositories/keymaps.rb +26 -22
- data/lib/vedeu/repositories/menus.rb +1 -1
- data/lib/vedeu/repositories/offsets.rb +30 -12
- data/lib/vedeu/repositories/positional.rb +23 -0
- data/lib/vedeu/support/colour_translator.rb +1 -16
- data/lib/vedeu/support/esc.rb +23 -28
- data/lib/vedeu/support/event.rb +6 -14
- data/lib/vedeu/{output → support}/refresh.rb +0 -0
- data/lib/vedeu/support/registrar.rb +6 -14
- data/lib/vedeu/support/repository.rb +3 -2
- data/lib/vedeu/support/terminal.rb +9 -13
- data/lib/vedeu/support/trace.rb +2 -3
- data/test/integration/cursors_test.rb +9 -0
- data/test/integration/views/basic_view_test.rb +19 -0
- data/test/lib/vedeu/api/api_test.rb +28 -5
- data/test/lib/vedeu/api/composition_test.rb +7 -3
- data/test/lib/vedeu/api/defined_test.rb +9 -3
- data/test/lib/vedeu/api/helpers_test.rb +39 -5
- data/test/lib/vedeu/api/interface_test.rb +88 -8
- data/test/lib/vedeu/api/keymap_test.rb +5 -3
- data/test/lib/vedeu/api/line_test.rb +9 -3
- data/test/lib/vedeu/api/menu_test.rb +11 -7
- data/test/lib/vedeu/api/stream_test.rb +9 -31
- data/test/lib/vedeu/application_test.rb +25 -2
- data/test/lib/vedeu/configuration/api_test.rb +5 -3
- data/test/lib/vedeu/configuration/cli_test.rb +5 -3
- data/test/lib/vedeu/configuration/configuration_test.rb +5 -2
- data/test/lib/vedeu/input/input_test.rb +5 -2
- data/test/lib/vedeu/launcher_test.rb +37 -2
- data/test/lib/vedeu/models/background_test.rb +6 -2
- data/test/lib/vedeu/models/char_test.rb +9 -6
- data/test/lib/vedeu/models/colour_test.rb +6 -2
- data/test/lib/vedeu/models/composition_test.rb +4 -2
- data/test/lib/vedeu/models/cursor_test.rb +27 -16
- data/test/lib/vedeu/models/foreground_test.rb +6 -2
- data/test/lib/vedeu/models/geometry_test.rb +6 -2
- data/test/lib/vedeu/models/interface_test.rb +5 -2
- data/test/lib/vedeu/models/keymap_test.rb +6 -4
- data/test/lib/vedeu/models/line_test.rb +5 -2
- data/test/lib/vedeu/models/offset_test.rb +7 -3
- data/test/lib/vedeu/models/stream_test.rb +4 -2
- data/test/lib/vedeu/models/style_test.rb +5 -2
- data/test/lib/vedeu/output/clear_test.rb +6 -2
- data/test/lib/vedeu/output/compositor_test.rb +8 -4
- data/test/lib/vedeu/output/render_test.rb +9 -6
- data/test/lib/vedeu/output/view_test.rb +7 -3
- data/test/lib/vedeu/output/viewport_test.rb +42 -9
- data/test/lib/vedeu/repositories/buffers_test.rb +52 -12
- data/test/lib/vedeu/repositories/cursors_test.rb +4 -26
- data/test/lib/vedeu/repositories/events_test.rb +6 -2
- data/test/lib/vedeu/repositories/focus_test.rb +5 -2
- data/test/lib/vedeu/repositories/groups_test.rb +5 -2
- data/test/lib/vedeu/repositories/interfaces_test.rb +4 -2
- data/test/lib/vedeu/repositories/keymaps_test.rb +8 -2
- data/test/lib/vedeu/repositories/menus_test.rb +3 -2
- data/test/lib/vedeu/repositories/offsets_test.rb +26 -19
- data/test/lib/vedeu/repositories/positional_test.rb +50 -0
- data/test/lib/vedeu/support/coercions_test.rb +7 -3
- data/test/lib/vedeu/support/colour_translator_test.rb +6 -2
- data/test/lib/vedeu/support/common_test.rb +5 -3
- data/test/lib/vedeu/support/esc_test.rb +6 -2
- data/test/lib/vedeu/support/event_test.rb +6 -2
- data/test/lib/vedeu/support/grid_test.rb +9 -3
- data/test/lib/vedeu/support/keymap_validator_test.rb +5 -2
- data/test/lib/vedeu/support/log_test.rb +4 -2
- data/test/lib/vedeu/support/menu_test.rb +10 -2
- data/test/lib/vedeu/support/position_test.rb +10 -2
- data/test/lib/vedeu/support/presentation_test.rb +6 -3
- data/test/lib/vedeu/{output → support}/refresh_test.rb +6 -2
- data/test/lib/vedeu/support/registrar_test.rb +2 -2
- data/test/lib/vedeu/support/repository_test.rb +4 -3
- data/test/lib/vedeu/support/terminal_test.rb +6 -2
- data/test/lib/vedeu/support/trace_test.rb +17 -2
- data/test/lib/vedeu_test.rb +1 -1
- data/vedeu.gemspec +2 -2
- metadata +13 -13
- data/lib/vedeu/output/area.rb +0 -284
- data/lib/vedeu/support/move.rb +0 -50
- data/test/lib/vedeu/output/area_test.rb +0 -242
- data/test/lib/vedeu/support/move_test.rb +0 -35
data/lib/vedeu/output/render.rb
CHANGED
@@ -7,10 +7,6 @@ module Vedeu
|
|
7
7
|
# @api private
|
8
8
|
class Render
|
9
9
|
|
10
|
-
extend Forwardable
|
11
|
-
|
12
|
-
def_delegators :interface, :viewport
|
13
|
-
|
14
10
|
# Create a new instance of Render with the provided {Vedeu::Interface} and
|
15
11
|
# then convert the interface into a single string of content and escape
|
16
12
|
# sequences.
|
@@ -38,7 +34,7 @@ module Vedeu
|
|
38
34
|
|
39
35
|
Vedeu.log("Rendering view: '#{interface.name}'")
|
40
36
|
|
41
|
-
viewport.each_with_index do |line, index|
|
37
|
+
interface.viewport.each_with_index do |line, index|
|
42
38
|
out << interface.origin(index)
|
43
39
|
out << line.join
|
44
40
|
end
|
@@ -29,6 +29,11 @@ module Vedeu
|
|
29
29
|
|
30
30
|
# Returns the visible content for the interface.
|
31
31
|
#
|
32
|
+
# @note If there are no lines of content, we return an empty array. If there
|
33
|
+
# are no more columns of content we return a space enclosed in an array;
|
34
|
+
# this prevents a weird line hopping bug which occurs when the current
|
35
|
+
# line has no more content, but subsequent lines do.
|
36
|
+
#
|
32
37
|
# @return [Array]
|
33
38
|
def show
|
34
39
|
line_adjustment
|
@@ -36,13 +41,18 @@ module Vedeu
|
|
36
41
|
|
37
42
|
return [] unless content?
|
38
43
|
|
39
|
-
content[lines].map
|
44
|
+
(content[lines] || []).map do |line|
|
45
|
+
line.chars[columns] || [" "]
|
46
|
+
end.compact
|
40
47
|
end
|
41
48
|
|
42
49
|
private
|
43
50
|
|
44
51
|
attr_reader :interface
|
45
52
|
|
53
|
+
# Scrolls the content vertically when the stored y offset for the interface
|
54
|
+
# is outside of the visible area.
|
55
|
+
#
|
46
56
|
# @return [Fixnum]
|
47
57
|
def line_adjustment
|
48
58
|
if offset.y < lines.min
|
@@ -57,6 +67,9 @@ module Vedeu
|
|
57
67
|
end
|
58
68
|
end
|
59
69
|
|
70
|
+
# Scrolls the content horizontally when the stored x offset for the
|
71
|
+
# interface is outside of the visible area.
|
72
|
+
#
|
60
73
|
# @return [Fixnum]
|
61
74
|
def column_adjustment
|
62
75
|
if offset.x < columns.min
|
@@ -71,23 +84,45 @@ module Vedeu
|
|
71
84
|
end
|
72
85
|
end
|
73
86
|
|
87
|
+
#
|
88
|
+
# @note
|
89
|
+
# @top = [value, 0].max # this allows us to set a top that is greater than
|
90
|
+
# # the content height.
|
91
|
+
#
|
92
|
+
# @top = [[value, (content_height - height)].min, 0].max
|
93
|
+
# # this does not allow us to have an offset greater
|
94
|
+
# # than the content height.
|
95
|
+
#
|
74
96
|
# @param value [Fixnum]
|
75
97
|
# @return [Fixnum]
|
76
98
|
def set_top(value)
|
77
|
-
@top = [
|
99
|
+
@top = [value, 0].max
|
78
100
|
end
|
79
101
|
|
102
|
+
#
|
103
|
+
# @note
|
104
|
+
# @left = [value, 0].max # this allows us to set a left that is greater
|
105
|
+
# # than the content width.
|
106
|
+
#
|
107
|
+
# @left = [[value, (content_width - width)].min, 0].max
|
108
|
+
# # this does not allow us to have an offset greater
|
109
|
+
# # than the content width.
|
110
|
+
#
|
80
111
|
# @param value [Fixnum]
|
81
112
|
# @return [Fixnum]
|
82
113
|
def set_left(value)
|
83
114
|
@left = [value, 0].max
|
84
115
|
end
|
85
116
|
|
117
|
+
# Using the current x offset, return a range of visible lines.
|
118
|
+
#
|
86
119
|
# @return [Range]
|
87
120
|
def lines
|
88
121
|
@top..(@top + height - 1)
|
89
122
|
end
|
90
123
|
|
124
|
+
# Using the current y offset, return a range of visible columns.
|
125
|
+
#
|
91
126
|
# @return [Range]
|
92
127
|
def columns
|
93
128
|
@left..(@left + width - 1)
|
@@ -35,6 +35,24 @@ module Vedeu
|
|
35
35
|
attributes[:name]
|
36
36
|
end
|
37
37
|
|
38
|
+
# Return the named back buffer.
|
39
|
+
#
|
40
|
+
# @param name [String]
|
41
|
+
# @raise [BufferNotFound] When the named buffer cannot be found.
|
42
|
+
# @return [Hash|Nil]
|
43
|
+
def back(name)
|
44
|
+
find(name)[:back_buffer]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return the named front buffer.
|
48
|
+
#
|
49
|
+
# @param name [String]
|
50
|
+
# @raise [BufferNotFound] When the named buffer cannot be found.
|
51
|
+
# @return [Hash|Nil]
|
52
|
+
def front(name)
|
53
|
+
find(name)[:front_buffer]
|
54
|
+
end
|
55
|
+
|
38
56
|
# Returns the latest content for the named buffer. The latest content always
|
39
57
|
# goes on to the back buffer. The content which was last output is on the
|
40
58
|
# front buffer.
|
@@ -53,7 +71,7 @@ module Vedeu
|
|
53
71
|
def latest(name)
|
54
72
|
swap_buffers(name) if new_content?(name)
|
55
73
|
|
56
|
-
|
74
|
+
front(name)
|
57
75
|
end
|
58
76
|
|
59
77
|
private
|
@@ -80,31 +98,7 @@ module Vedeu
|
|
80
98
|
# @param name [String]
|
81
99
|
# @return [Boolean]
|
82
100
|
def new_content?(name)
|
83
|
-
defined_value?(
|
84
|
-
end
|
85
|
-
|
86
|
-
# Return a boolean indicating whether the named front buffer has content.
|
87
|
-
#
|
88
|
-
# @param name [String]
|
89
|
-
# @return [Boolean]
|
90
|
-
# def old_content?(name)
|
91
|
-
# defined_value?(front_buffer(name))
|
92
|
-
# end
|
93
|
-
|
94
|
-
# Return the named back buffer.
|
95
|
-
#
|
96
|
-
# @param name [String]
|
97
|
-
# @return [Hash|Nil]
|
98
|
-
def back_buffer(name)
|
99
|
-
find(name)[:back_buffer]
|
100
|
-
end
|
101
|
-
|
102
|
-
# Return the named front buffer.
|
103
|
-
#
|
104
|
-
# @param name [String]
|
105
|
-
# @return [Hash|Nil]
|
106
|
-
def front_buffer(name)
|
107
|
-
find(name)[:front_buffer]
|
101
|
+
defined_value?(back(name))
|
108
102
|
end
|
109
103
|
|
110
104
|
# @return [Hash]
|
@@ -121,7 +115,7 @@ module Vedeu
|
|
121
115
|
# @raise [BufferNotFound] When the entity cannot be found with this name.
|
122
116
|
# @return [BufferNotFound]
|
123
117
|
def not_found(name)
|
124
|
-
fail BufferNotFound, "Cannot find buffer with this name: #{name
|
118
|
+
fail BufferNotFound, "Cannot find buffer with this name: #{name}."
|
125
119
|
end
|
126
120
|
|
127
121
|
end # Buffers
|
@@ -8,25 +8,13 @@ module Vedeu
|
|
8
8
|
|
9
9
|
include Common
|
10
10
|
include Repository
|
11
|
+
include Positional
|
11
12
|
extend self
|
12
13
|
|
13
14
|
# System events which when called will update the cursor visibility
|
14
15
|
# accordingly for the interface in focus.
|
15
|
-
Vedeu.event(:_cursor_hide_)
|
16
|
-
Vedeu.event(:_cursor_show_)
|
17
|
-
|
18
|
-
# Adds an interface to the cursors repository.
|
19
|
-
#
|
20
|
-
# @param attributes [Hash]
|
21
|
-
# @return [Hash]
|
22
|
-
def add(attributes)
|
23
|
-
validate_attributes!(attributes)
|
24
|
-
|
25
|
-
Vedeu.log("#{action(__callee__)} cursor: '#{attributes[:name]}'")
|
26
|
-
|
27
|
-
storage.store(attributes[:name], Cursor.new(attributes))
|
28
|
-
end
|
29
|
-
alias_method :update, :add
|
16
|
+
Vedeu.event(:_cursor_hide_) { Cursors.hide }
|
17
|
+
Vedeu.event(:_cursor_show_) { Cursors.show }
|
30
18
|
|
31
19
|
# Make the cursor of this interface invisible.
|
32
20
|
#
|
@@ -25,13 +25,9 @@ module Vedeu
|
|
25
25
|
def add(attributes)
|
26
26
|
validate_attributes!(attributes)
|
27
27
|
|
28
|
-
|
29
|
-
storage
|
28
|
+
return storage << attributes[:name] unless registered?(attributes[:name])
|
30
29
|
|
31
|
-
|
32
|
-
storage << attributes[:name]
|
33
|
-
|
34
|
-
end
|
30
|
+
storage
|
35
31
|
end
|
36
32
|
|
37
33
|
# Focus an interface by name.
|
@@ -12,6 +12,9 @@ module Vedeu
|
|
12
12
|
# Stores the keymap attributes defined by the API.
|
13
13
|
#
|
14
14
|
# @param attributes [Hash]
|
15
|
+
# @option attributes :interfaces [Array] A list of the names of interfaces for which the
|
16
|
+
# keys are active for.
|
17
|
+
# @option attributes :keys [Array] A collection of key/action pairs.
|
15
18
|
# @return [TrueClass|KeyInUse|FalseClass]
|
16
19
|
def add(attributes)
|
17
20
|
return false unless defined_value?(attributes[:keys])
|
@@ -72,10 +75,15 @@ module Vedeu
|
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
|
-
# Return a collection of interface keys.
|
78
|
+
# Return a collection of interface keys. When the optional 'name' parameter
|
79
|
+
# is provided, then only the keys associated with that interface are
|
80
|
+
# returned.
|
76
81
|
#
|
82
|
+
# @param interface [String]
|
77
83
|
# @return [Hash]
|
78
|
-
def interface_keys
|
84
|
+
def interface_keys(interface = nil)
|
85
|
+
return find(interface).keys if interface
|
86
|
+
|
79
87
|
storage.reject do |k, _|
|
80
88
|
k == '_global_keymap_'
|
81
89
|
end.map { |_, v| v.keys }.flatten.uniq
|
@@ -89,7 +97,7 @@ module Vedeu
|
|
89
97
|
system_keys.include?(key)
|
90
98
|
end
|
91
99
|
|
92
|
-
# Return
|
100
|
+
# Return the collection of system keys.
|
93
101
|
#
|
94
102
|
# @return [Array]
|
95
103
|
def system_keys
|
@@ -121,10 +129,10 @@ module Vedeu
|
|
121
129
|
focussed_interface = Vedeu::Focus.current
|
122
130
|
|
123
131
|
if interface_key?(key, focussed_interface)
|
124
|
-
find(focussed_interface).fetch(key, noop).call
|
132
|
+
find(focussed_interface).fetch(key, noop).call(:noop_interface)
|
125
133
|
|
126
134
|
elsif global_key?(key)
|
127
|
-
find('_global_keymap_').fetch(key, noop).call
|
135
|
+
find('_global_keymap_').fetch(key, noop).call(:noop_global)
|
128
136
|
|
129
137
|
elsif system_key?(key)
|
130
138
|
system_key(key)
|
@@ -134,13 +142,14 @@ module Vedeu
|
|
134
142
|
|
135
143
|
end
|
136
144
|
end
|
145
|
+
alias_method :keypress, :use
|
137
146
|
|
138
147
|
private
|
139
148
|
|
140
149
|
# Triggers the system event defined for this key.
|
141
150
|
#
|
142
151
|
# @param key [String|Symbol]
|
143
|
-
# @return []
|
152
|
+
# @return [] The result(s) of triggering the event.
|
144
153
|
def system_key(key)
|
145
154
|
action = Vedeu::Configuration.system_keys.key(key)
|
146
155
|
event = ['_', action, '_'].join.to_sym
|
@@ -153,34 +162,29 @@ module Vedeu
|
|
153
162
|
# @param attributes [Hash]
|
154
163
|
# @param interface [String]
|
155
164
|
# @return []
|
156
|
-
def register(attributes, interface = '')
|
165
|
+
def register(attributes, interface = '_global_keymap_')
|
157
166
|
attributes[:keys].map do |keymap|
|
158
167
|
KeymapValidator.check(storage, keymap[:key], interface)
|
159
168
|
|
160
|
-
Vedeu.log("Registering key: '#{keymap[:key]}' with '#{
|
169
|
+
Vedeu.log("Registering key: '#{keymap[:key]}' with '#{interface}'")
|
161
170
|
|
162
|
-
storage[
|
171
|
+
storage[interface].merge!({ keymap[:key] => keymap[:action] })
|
163
172
|
end
|
164
173
|
end
|
165
174
|
|
166
|
-
#
|
167
|
-
#
|
168
|
-
# @param interface [String]
|
169
|
-
# @return [String]
|
170
|
-
def namespace(interface = '')
|
171
|
-
return defined_value?(interface) ? interface : '_global_keymap_'
|
172
|
-
end
|
173
|
-
|
174
|
-
# Returns a noop proc which when called returns :noop.
|
175
|
+
# Returns a noop proc which when called returns the argument or :noop.
|
175
176
|
#
|
177
|
+
# @param value [Symbol]
|
176
178
|
# @return [Proc]
|
177
|
-
def noop
|
178
|
-
proc {
|
179
|
+
def noop(value = :noop)
|
180
|
+
proc { value }
|
179
181
|
end
|
180
182
|
|
181
|
-
# @return [
|
183
|
+
# @return [Hash]
|
182
184
|
def in_memory
|
183
|
-
{
|
185
|
+
{
|
186
|
+
'_global_keymap_' => {}
|
187
|
+
}
|
184
188
|
end
|
185
189
|
|
186
190
|
end # Keymaps
|
@@ -70,7 +70,7 @@ module Vedeu
|
|
70
70
|
# @raise [MenuNotFound] When the entity cannot be found with this name.
|
71
71
|
# @return [MenuNotFound]
|
72
72
|
def not_found(name)
|
73
|
-
fail MenuNotFound, "Menu was not found with this name: #{name
|
73
|
+
fail MenuNotFound, "Menu was not found with this name: #{name}."
|
74
74
|
end
|
75
75
|
|
76
76
|
end # Menus
|
@@ -8,29 +8,39 @@ module Vedeu
|
|
8
8
|
|
9
9
|
include Common
|
10
10
|
include Repository
|
11
|
+
include Positional
|
11
12
|
extend self
|
12
13
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def add(attributes)
|
18
|
-
validate_attributes!(attributes)
|
14
|
+
# @return [Array]
|
15
|
+
def down
|
16
|
+
move(1, 0)
|
17
|
+
end
|
19
18
|
|
20
|
-
|
19
|
+
# @return [Array]
|
20
|
+
def up
|
21
|
+
move(-1, 0)
|
22
|
+
end
|
21
23
|
|
22
|
-
|
24
|
+
# @return [Array]
|
25
|
+
def right
|
26
|
+
move(0, 1)
|
23
27
|
end
|
24
|
-
|
28
|
+
|
29
|
+
# @return [Array]
|
30
|
+
def left
|
31
|
+
move(0, -1)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
25
35
|
|
26
36
|
# @param y [Fixnum]
|
27
37
|
# @param x [Fixnum]
|
28
|
-
# @return [
|
38
|
+
# @return [Array]
|
29
39
|
def move(y, x)
|
30
40
|
find_or_create(Focus.current).move(y, x)
|
31
|
-
end
|
32
41
|
|
33
|
-
|
42
|
+
Focus.refresh
|
43
|
+
end
|
34
44
|
|
35
45
|
# @return [Class]
|
36
46
|
def entity
|
@@ -42,6 +52,14 @@ module Vedeu
|
|
42
52
|
{}
|
43
53
|
end
|
44
54
|
|
55
|
+
# System events which when called will move in the direction specified;
|
56
|
+
# these will update the cursor position or content offset (scrolling)
|
57
|
+
# according to the interface in focus.
|
58
|
+
Vedeu.event(:_cursor_up_) { up }
|
59
|
+
Vedeu.event(:_cursor_right_) { right }
|
60
|
+
Vedeu.event(:_cursor_down_) { down }
|
61
|
+
Vedeu.event(:_cursor_left_) { left }
|
62
|
+
|
45
63
|
end # Offsets
|
46
64
|
|
47
65
|
end # Vedeu
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Vedeu
|
2
|
+
|
3
|
+
# Repository helper module which reduces duplication in Offsets and Cursors.
|
4
|
+
#
|
5
|
+
module Positional
|
6
|
+
|
7
|
+
# Add or update the offset or cursor coordinates.
|
8
|
+
#
|
9
|
+
# @param attributes [Hash]
|
10
|
+
# @return [Offset]
|
11
|
+
def add(attributes)
|
12
|
+
validate_attributes!(attributes)
|
13
|
+
|
14
|
+
Vedeu.log("#{action(__callee__)} positional (#{entity}): " \
|
15
|
+
"'#{attributes[:name]}'")
|
16
|
+
|
17
|
+
storage.store(attributes[:name], entity.new(attributes))
|
18
|
+
end
|
19
|
+
alias_method :update, :add
|
20
|
+
|
21
|
+
end # Positional
|
22
|
+
|
23
|
+
end # Vedeu
|