MINT-core 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +69 -0
- data/History.txt +3 -0
- data/MINT-core.gemspec +58 -0
- data/Manifest.txt +77 -0
- data/PostInstall.txt +7 -0
- data/README.rdoc +63 -0
- data/Rakefile +29 -0
- data/bin/mint-aui +40 -0
- data/bin/mint-cui-gfx +47 -0
- data/bin/mint-juggernaut.sh +4 -0
- data/bin/mint-tuplespace +12 -0
- data/lib/MINT-core.rb +42 -0
- data/lib/MINT-core/agent/agent.rb +28 -0
- data/lib/MINT-core/agent/aui.rb +52 -0
- data/lib/MINT-core/agent/auicontrol.rb +135 -0
- data/lib/MINT-core/agent/cui-gfx.rb +160 -0
- data/lib/MINT-core/agent/cuicontrol.rb +46 -0
- data/lib/MINT-core/mapping/complementary.rb +100 -0
- data/lib/MINT-core/mapping/mapping.rb +47 -0
- data/lib/MINT-core/mapping/on_state_change.rb +65 -0
- data/lib/MINT-core/mapping/sequential.rb +87 -0
- data/lib/MINT-core/model/aui/AIC.rb +86 -0
- data/lib/MINT-core/model/aui/AIChoice.rb +65 -0
- data/lib/MINT-core/model/aui/AIINChoose.rb +54 -0
- data/lib/MINT-core/model/aui/AIMultiChoice.rb +5 -0
- data/lib/MINT-core/model/aui/AIMultiChoiceElement.rb +56 -0
- data/lib/MINT-core/model/aui/AIO.rb +170 -0
- data/lib/MINT-core/model/aui/AIOUTDiscrete.rb +43 -0
- data/lib/MINT-core/model/aui/AISingleChoice.rb +9 -0
- data/lib/MINT-core/model/aui/AISingleChoiceElement.rb +69 -0
- data/lib/MINT-core/model/aui/AISinglePresence.rb +100 -0
- data/lib/MINT-core/model/aui/aic.png +0 -0
- data/lib/MINT-core/model/aui/aic.scxml +50 -0
- data/lib/MINT-core/model/aui/aichoice.png +0 -0
- data/lib/MINT-core/model/aui/aichoice.scxml +60 -0
- data/lib/MINT-core/model/aui/aio.png +0 -0
- data/lib/MINT-core/model/aui/aio.scxml +43 -0
- data/lib/MINT-core/model/aui/aisinglechoiceelement.png +0 -0
- data/lib/MINT-core/model/aui/aisinglechoiceelement.scxml +71 -0
- data/lib/MINT-core/model/aui/aisinglepresence.png +0 -0
- data/lib/MINT-core/model/aui/aisinglepresence.scxml +58 -0
- data/lib/MINT-core/model/aui/model.rb +50 -0
- data/lib/MINT-core/model/body/gesture_button.rb +26 -0
- data/lib/MINT-core/model/body/handgesture.rb +279 -0
- data/lib/MINT-core/model/body/head.png +0 -0
- data/lib/MINT-core/model/body/head.rb +51 -0
- data/lib/MINT-core/model/body/head.scxml +28 -0
- data/lib/MINT-core/model/cui/gfx/CIC.rb +266 -0
- data/lib/MINT-core/model/cui/gfx/CIO.rb +381 -0
- data/lib/MINT-core/model/cui/gfx/model.rb +204 -0
- data/lib/MINT-core/model/cui/gfx/screen.rb +18 -0
- data/lib/MINT-core/model/device/button.rb +20 -0
- data/lib/MINT-core/model/device/joypad.rb +30 -0
- data/lib/MINT-core/model/device/mouse.rb +171 -0
- data/lib/MINT-core/model/device/pointer.rb +85 -0
- data/lib/MINT-core/model/device/wheel.rb +51 -0
- data/lib/MINT-core/model/interactor.rb +167 -0
- data/lib/MINT-core/model/task.rb +71 -0
- data/lib/MINT-core/overrides/rinda.rb +34 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/AIC_spec.rb +69 -0
- data/spec/AISinglePresence_spec.rb +94 -0
- data/spec/MINT-core_spec.rb +11 -0
- data/spec/aio_agent_spec.rb +234 -0
- data/spec/aio_spec.rb +144 -0
- data/spec/aisinglechoice_spec.rb +152 -0
- data/spec/aisinglechoiceelement_spec.rb +106 -0
- data/spec/cio_spec.rb +369 -0
- data/spec/core_spec.rb +29 -0
- data/spec/music_spec.rb +179 -0
- data/spec/rcov.opts +2 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +7 -0
- data/tasks/rspec.rake +21 -0
- metadata +227 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
module MINT
|
2
|
+
|
3
|
+
|
4
|
+
class ComplementaryCallMethod < ExecuteOnStateChange
|
5
|
+
def initialize(source_model,state,conditions,execute)
|
6
|
+
super(source_model,state,self.method(:executeWithConditions),nil)
|
7
|
+
@original_execute = execute
|
8
|
+
@conditions = conditions
|
9
|
+
p "initialized #{conditions.inspect}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# TODO basic condition checker still without consideration of time span :-(
|
13
|
+
def checkConditions
|
14
|
+
p "in check AND cond #{@conditions.inspect}"
|
15
|
+
result = nil
|
16
|
+
@conditions.each do |model,state|
|
17
|
+
result=model.first( :abstract_states=> /(^|\|)#{Regexp.quote(state)}/)
|
18
|
+
if result.nil?
|
19
|
+
puts "Received #{@state} notify for model #{@source_model} but condition state #{state} of model #{model} not true"
|
20
|
+
return false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return result
|
24
|
+
end
|
25
|
+
|
26
|
+
def executeWithConditions(result)
|
27
|
+
p "Catched "
|
28
|
+
result = checkConditions
|
29
|
+
if result
|
30
|
+
p "executing #{@original_execute} on #{result.inspect}"
|
31
|
+
@original_execute.call result
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
class ComplementarySendEvent< ComplementaryCallMethod
|
38
|
+
def initialize(source_model,state,conditions,execute)
|
39
|
+
super(source_model,state,conditions,execute)
|
40
|
+
end
|
41
|
+
|
42
|
+
def executeWithConditions(result)
|
43
|
+
p "Catched "
|
44
|
+
result = checkConditions
|
45
|
+
if result
|
46
|
+
p "executing #{@original_execute} on #{result.inspect}"
|
47
|
+
p result.process_event(@original_execute)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class ComplementarySendEvents< ComplementaryCallMethod
|
53
|
+
def initialize(source_model,state,conditions,execute)
|
54
|
+
super(source_model,state,conditions,execute)
|
55
|
+
end
|
56
|
+
|
57
|
+
def executeWithConditions(result)
|
58
|
+
publish_events(@original_execute)
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
class ComplementaryOR<ComplementarySendEvent
|
64
|
+
def initialize(source_model,state,conditions,execute)
|
65
|
+
super(source_model,state,conditions,execute)
|
66
|
+
end
|
67
|
+
|
68
|
+
def checkConditions
|
69
|
+
p "in check OR cond #{@conditions.inspect}"
|
70
|
+
result = nil
|
71
|
+
@conditions.each do |model,state|
|
72
|
+
state.each do |s|
|
73
|
+
result=model.first( :abstract_states=> /(^|\|)#{Regexp.quote(s)}/)
|
74
|
+
if not result.nil?
|
75
|
+
return result
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
return false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class ComplementaryMethodCall < ComplementarySendEvent
|
85
|
+
def initialize(source_model,state,conditions,execute,callback)
|
86
|
+
super(source_model,state,conditions,execute)
|
87
|
+
@callback= callback
|
88
|
+
end
|
89
|
+
def executeWithConditions(result)
|
90
|
+
p "Catched "
|
91
|
+
result = checkConditions
|
92
|
+
if result
|
93
|
+
p "executing #{@orginal_execute} on #{result.inspect}"
|
94
|
+
r = result.process_event(@orginal_execute)
|
95
|
+
@callback.call r
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MINT
|
2
|
+
|
3
|
+
# Basic abstract class to define a mapping, which specifies a communication between model agents.
|
4
|
+
# Therefore ia mapping listens to a source model of another agents' model for actions like e.g. new elements,
|
5
|
+
# updates to elements or element removals.
|
6
|
+
#
|
7
|
+
class Mapping
|
8
|
+
attr_accessor :source_model, :on_action, :execute
|
9
|
+
|
10
|
+
# A mapping is initialized with
|
11
|
+
# @param [Class] source_model the other agents' model to listen to for events
|
12
|
+
# @param [String] action to the tuple space that should be listened to. This is one of "take", "read", "write"
|
13
|
+
# @param [Method] execute this method of the agent that runs the mapping, the specified action has happened.
|
14
|
+
# @param [Method] inital method to call upon initialization of the mapping without the action to be happened, but scans the model for already happened events (write) and executes the method with these data.
|
15
|
+
#
|
16
|
+
def initialize (source_model,action,execute,initial=nil)
|
17
|
+
@source_model = source_model
|
18
|
+
@execute = execute
|
19
|
+
@initial = initial
|
20
|
+
@on_action = action
|
21
|
+
end
|
22
|
+
|
23
|
+
# Starts the mapping thread to listen to events
|
24
|
+
#
|
25
|
+
def execute
|
26
|
+
raise NotImplementedError, "#{self.class}#execute not implemented"
|
27
|
+
end
|
28
|
+
|
29
|
+
def publish_events(events)
|
30
|
+
# p "in check OR cond #{@conditions.inspect}"
|
31
|
+
|
32
|
+
events.each do |c,event|
|
33
|
+
c.each do |model,state|
|
34
|
+
state.each do |s|
|
35
|
+
result=model.first( :abstract_states=> /(^|\|)#{Regexp.quote(s)}/)
|
36
|
+
if not result.nil?
|
37
|
+
p "Sending #{event} to #{result.name}"
|
38
|
+
p result.inspect
|
39
|
+
p result.process_event(event)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
module MINT
|
3
|
+
|
4
|
+
# Basic mapping that observes state changes of elements in a model agents model.
|
5
|
+
#
|
6
|
+
class ExecuteOnStateChange < Mapping
|
7
|
+
attr_reader :state
|
8
|
+
|
9
|
+
def initialize(source_model,state,execute, initial=nil)
|
10
|
+
super(source_model,"write",execute,initial)
|
11
|
+
if (not state.is_a? Array)
|
12
|
+
@state = [state.to_s]
|
13
|
+
else
|
14
|
+
@state = state.map &:to_s
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute
|
19
|
+
# query existing state
|
20
|
+
if @initial
|
21
|
+
results = @source_model.all({ :abstract_states=> /(^|\|)#{Regexp.quote(@state.first)}/})
|
22
|
+
p "Found results by read: #{results.inspect}"
|
23
|
+
results.each do |result|
|
24
|
+
call_if_result_matches result, @initial
|
25
|
+
end
|
26
|
+
end
|
27
|
+
#register for further events
|
28
|
+
#observer = agent.storage.notify 'write', {"_model_"=> @source_model.to_s} + @conditions
|
29
|
+
|
30
|
+
p "registered for model #{@source_model} writes on state #{@state}"
|
31
|
+
@source_model.notify("write", { :new_states=> /(^|\|)#{Regexp.quote(@state.first)}/},self.method(:check_cond))
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_cond(result)
|
36
|
+
call_if_result_matches(result,@execute)
|
37
|
+
end
|
38
|
+
|
39
|
+
def call_if_result_matches(result,method)
|
40
|
+
return if not result
|
41
|
+
states_to_check = Array.new @state
|
42
|
+
states_to_check.shift # we already hav checked for the first state
|
43
|
+
states_to_check.each do |state|
|
44
|
+
return false if not result.abstract_states =~/(^|\|)#{Regexp.quote(state)}/
|
45
|
+
end
|
46
|
+
method.call result
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
class ExecuteEventOnStateChange < ExecuteOnStateChange
|
53
|
+
def initialize(source_model,state,selector,event)
|
54
|
+
super(source_model,state,self.method(:process_event),nil)
|
55
|
+
@selector = selector
|
56
|
+
@event = event
|
57
|
+
end
|
58
|
+
|
59
|
+
def process_event(result)
|
60
|
+
@selector.each do |element|
|
61
|
+
element.process_event(@event)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module MINT
|
2
|
+
|
3
|
+
# click_select_mapping = Sequential.new(HWButton,:pressed,HWButton,:released, 300, { AIINChoose =>"focused"},:choose)
|
4
|
+
|
5
|
+
class Sequential < Mapping
|
6
|
+
def initialize(source_model_1,state_1,source_model_2,state_2, state_2_conditions, min_time, max_time, conditions, error_recovery = nil)
|
7
|
+
super(source_model_1,"write",nil,nil)
|
8
|
+
@source_model_1= source_model_1
|
9
|
+
@state_1= state_1
|
10
|
+
@source_model_2= source_model_2
|
11
|
+
@state_2= state_2
|
12
|
+
@max_time = max_time
|
13
|
+
@min_time = min_time
|
14
|
+
@conditions = conditions
|
15
|
+
@time_state_1_happened = nil
|
16
|
+
@state_2_conditions = state_2_conditions
|
17
|
+
@error_recovery = error_recovery
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
t1 = @source_model_1.notify("write", { :new_states=> /(^|\|)#{Regexp.quote(@state_1)}/},self.method(:save_state_1_happened))
|
22
|
+
p "registered for model #{@source_model_1} writes on state #{@state_1}"
|
23
|
+
# t2 = @source_model_2.notify("write", { :abstract_states=> /#{Regexp.quote(@state_2)}/},self.method(:check_sequence))
|
24
|
+
# p "registered for model #{@source_model_2} writes on state #{@state_2}"
|
25
|
+
return t1
|
26
|
+
#,t2
|
27
|
+
end
|
28
|
+
|
29
|
+
def check_sequence(result)
|
30
|
+
ms = ((Time.now-@time_state_1_happened)*1000).to_i
|
31
|
+
if @time_state_1_happened and ((@min_time<=ms and ms <=@max_time) or (@min_time == 0 and @max_time==0))
|
32
|
+
if (check_state_2_conditions)
|
33
|
+
p "Sequence #{@source_model_1}=#{@state_1} --> #{@source_model_2}= #{@state_2} PROCEEDED in #{ms} ms"
|
34
|
+
|
35
|
+
publish_events @conditions
|
36
|
+
|
37
|
+
else
|
38
|
+
p "Sequence #{@source_model_1}=#{@state_1} --> #{@source_model_2}= #{@state_2} FAILED #{ms}ms because of state 2 conditions "
|
39
|
+
|
40
|
+
publish_events @error_recovery if @error_recovery
|
41
|
+
|
42
|
+
end
|
43
|
+
else
|
44
|
+
p "Sequence #{@source_model_1}=#{@state_1} --> #{@source_model_2}= #{@state_2} FAILED #{ms}ms instead of min/max #{@min_time}/#{@max_time}ms"
|
45
|
+
|
46
|
+
publish_events @error_recovery if @error_recovery
|
47
|
+
|
48
|
+
end
|
49
|
+
@time_state_1_happened = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_state_2_conditions
|
53
|
+
return true if not @state_2_conditions
|
54
|
+
@state_2_conditions.each do |model,state|
|
55
|
+
# state.each do |s|
|
56
|
+
result=model.first( :abstract_states=> /(^|\|)#{Regexp.quote(state)}/)
|
57
|
+
if result.nil?
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
# end
|
61
|
+
end
|
62
|
+
true
|
63
|
+
end
|
64
|
+
|
65
|
+
def save_state_1_happened(result)
|
66
|
+
p "Sequence #{@source_model_1}=#{@state_1} OK! --> #{@source_model_2}= #{@state_2} "
|
67
|
+
|
68
|
+
@time_state_1_happened = Time.now
|
69
|
+
# p "State #{@state_1} of #{@source_model_1} occurred!"
|
70
|
+
if @max_time >0
|
71
|
+
@source_model_2.wait("write", { :new_states=> /(^|\|)#{Regexp.quote(@state_2)}/},self.method(:check_sequence))
|
72
|
+
p "registered for model #{@source_model_2} writes on state #{@state_2}"
|
73
|
+
else
|
74
|
+
result = @source_model_2.first(:abstract_states=> /(^|\|)#{Regexp.quote(@state_2)}/)
|
75
|
+
if (result)
|
76
|
+
p "check seq"
|
77
|
+
check_sequence(result)
|
78
|
+
else
|
79
|
+
p "Sequence #{@source_model_1}=#{@state_1} --> #{@source_model_2}= #{@state_2} without time slot FAILED because of state 2 conditions"
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module MINT
|
2
|
+
class AIC < AIOUTDiscrete
|
3
|
+
# belongs_to :task @TODO - Mappings unklar
|
4
|
+
has n, :childs, 'AIO',
|
5
|
+
:parent_key => [ :id ], # local to this model (Blog)
|
6
|
+
:child_key => [ :aic_id ] # in the remote model (Post)
|
7
|
+
has 1, :entry, 'AIO'
|
8
|
+
|
9
|
+
def initialize_statemachine
|
10
|
+
super
|
11
|
+
parser = StatemachineParser.new(self)
|
12
|
+
@statemachine = parser.build_from_scxml "#{File.dirname(__FILE__)}/aic.scxml"
|
13
|
+
=begin
|
14
|
+
@statemachine = Statemachine.build do
|
15
|
+
superstate :AIC do
|
16
|
+
trans :initialized,:organize, :organized
|
17
|
+
trans :organized, :present, :presenting
|
18
|
+
trans :organized, :suspend, :suspended
|
19
|
+
trans :suspended, :present, :presenting
|
20
|
+
trans :suspended, :organize, :organized
|
21
|
+
|
22
|
+
state :suspended do
|
23
|
+
on_entry :sync_cio_to_hidden
|
24
|
+
end
|
25
|
+
|
26
|
+
superstate :presenting do
|
27
|
+
on_entry [:inform_parent_presenting, :present_children]
|
28
|
+
on_exit :hide_children
|
29
|
+
event :suspend, :suspended
|
30
|
+
|
31
|
+
state :defocused do
|
32
|
+
on_entry :sync_cio_to_displayed
|
33
|
+
end
|
34
|
+
state :focused do
|
35
|
+
on_entry :sync_cio_to_highlighted
|
36
|
+
end
|
37
|
+
trans :defocused,:focus,:focused
|
38
|
+
trans :focused,:defocus, :defocused
|
39
|
+
trans :focused, :next, :defocused, :focus_next, Proc.new { exists_next}
|
40
|
+
trans :focused, :prev, :defocused, :focus_previous, Proc.new { exists_prev}
|
41
|
+
trans :focused, :parent, :defocused, :focus_parent
|
42
|
+
trans :focused, :child, :defocused, :focus_child
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
=end
|
48
|
+
end
|
49
|
+
|
50
|
+
def hide_children
|
51
|
+
if (self.childs)
|
52
|
+
self.childs.each do |c|
|
53
|
+
c.process_event("suspend")
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def present_children
|
60
|
+
if (self.childs)
|
61
|
+
self.childs.each do |c|
|
62
|
+
c.process_event("present")
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def focus_child
|
70
|
+
if (self.childs && self.childs.first)
|
71
|
+
self.childs.first.process_event("focus")
|
72
|
+
else
|
73
|
+
return nil # TODO not working, find abbruchbedingung!!!
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# hook that is called from a child if it enters presenting state
|
79
|
+
def child_to_presenting(child)
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module MINT
|
2
|
+
class AIChoice < AIC
|
3
|
+
def initialize_statemachine
|
4
|
+
if @statemachine.blank?
|
5
|
+
parser = StatemachineParser.new(self)
|
6
|
+
@statemachine = parser.build_from_scxml "#{File.dirname(__FILE__)}/aichoice.scxml"
|
7
|
+
=begin
|
8
|
+
@statemachine = Statemachine.build do
|
9
|
+
trans :initialized,:organize, :organized
|
10
|
+
trans :organized, :present, :p_t
|
11
|
+
trans :organized, :suspend, :suspended
|
12
|
+
trans :suspended, :present, :p_t
|
13
|
+
trans :suspended, :organize, :organized
|
14
|
+
state :suspended do
|
15
|
+
on_entry :sync_cio_to_hidden
|
16
|
+
end
|
17
|
+
|
18
|
+
superstate :p_t do # TODO artificial superstate required to get following event working!
|
19
|
+
event :suspend, :suspended
|
20
|
+
parallel :p do
|
21
|
+
statemachine :s1 do
|
22
|
+
superstate :presenting do
|
23
|
+
on_entry :present_children
|
24
|
+
on_exit :hide_children
|
25
|
+
state :defocused do
|
26
|
+
on_entry :sync_cio_to_displayed
|
27
|
+
end
|
28
|
+
state :focused do
|
29
|
+
on_entry :sync_cio_to_highlighted
|
30
|
+
end
|
31
|
+
trans :defocused,:focus,:focused
|
32
|
+
trans :focused,:defocus, :defocused
|
33
|
+
trans :focused, :next, :defocused, :focus_next, Proc.new { exists_next}
|
34
|
+
trans :focused, :prev, :defocused, :focus_previous, Proc.new { exists_prev}
|
35
|
+
trans :focused, :parent, :defocused, :focus_parent
|
36
|
+
trans :focused, :child, :defocused, :focus_child
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
statemachine :s2 do
|
41
|
+
superstate :l do
|
42
|
+
trans :listing, :drop, :listing, :add_element, "In(:focused)"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
=end
|
49
|
+
@statemachine.reset
|
50
|
+
end
|
51
|
+
end
|
52
|
+
def add_element
|
53
|
+
#if self.is_in? :focused
|
54
|
+
f = AISingleChoiceElement.first(:new_states=> /#{Regexp.quote("dragging")}/)
|
55
|
+
self.childs << f
|
56
|
+
self.childs.save
|
57
|
+
f.process_event(:drop)
|
58
|
+
f.process_event(:focus)
|
59
|
+
self.process_event(:defocus)
|
60
|
+
f.destroy
|
61
|
+
#end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|