MINT-core 1.0.0
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.
- 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
Binary file
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
module MINT
|
3
|
+
class Head < Element
|
4
|
+
attr_accessor :mode
|
5
|
+
#property :angle, Integer, :default => -1
|
6
|
+
#property :distance, Integer, :default => -1
|
7
|
+
property :mode, Enum[ :nodding, :turning, :tilting ], :default => :tilting
|
8
|
+
|
9
|
+
def initialize_statemachine
|
10
|
+
|
11
|
+
if @statemachine.blank?
|
12
|
+
|
13
|
+
parser = StatemachineParser.new(self)
|
14
|
+
@statemachine = parser.build_from_scxml "#{File.dirname(__FILE__)}/head.scxml"
|
15
|
+
@statemachine.reset
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
def angle=(angle)
|
22
|
+
if @publish_angle
|
23
|
+
Juggernaut.publish("head/angle", "#{angle}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def start_publish_angle
|
28
|
+
@publish_angle=true
|
29
|
+
end
|
30
|
+
|
31
|
+
def stop_publish_angle
|
32
|
+
@publish_angle=false
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def in_nodding_mode
|
37
|
+
return true if self.mode.eql? :nodding
|
38
|
+
false
|
39
|
+
end
|
40
|
+
|
41
|
+
def in_turning_mode
|
42
|
+
return true if self.mode.eql? :turning
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def in_tilting_mode
|
47
|
+
return true if self.mode.eql? :tilting
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<scxml initial="disconnected" name="Head" version="0.9" xmlns="http://www.w3.org/2005/07/scxml"><!-- node-size-and-position x=0.0 y=0.0 w=800.0 h=470.0 -->
|
2
|
+
<state id="disconnected"><!-- node-size-and-position x=380.0 y=30.0 w=100.0 h=50.0 -->
|
3
|
+
<transition event="connect" target="connected"><!-- edge-path [connected] x=520.0 y=100.0 pointx=0.0 pointy=13.0 offsetx=24.0 offsety=12.0 --></transition>
|
4
|
+
</state>
|
5
|
+
<state id="connected"><!-- node-size-and-position x=20.0 y=140.0 w=760.0 h=310.0 -->
|
6
|
+
<transition event="disconnect" target="disconnected"><!-- edge-path [disconnected] x=340.0 y=100.0 pointx=0.0 pointy=37.0 offsetx=-24.0 offsety=33.0 --></transition>
|
7
|
+
<state id="nodding"><!-- node-size-and-position x=50.0 y=30.0 w=200.0 h=130.0 -->
|
8
|
+
<state id="looking_down"><!-- node-size-and-position x=60.0 y=40.0 w=100.0 h=50.0 -->
|
9
|
+
<transition event="center" target="centered"><!-- edge-path [centered] pointx=0.0 pointy=-24.0 offsetx=-8.0 offsety=-5.0 --></transition>
|
10
|
+
</state>
|
11
|
+
</state>
|
12
|
+
<state id="tilting"><!-- node-size-and-position x=290.0 y=30.0 w=230.0 h=130.0 -->
|
13
|
+
<state id="tilting_right"><!-- node-size-and-position x=60.0 y=40.0 w=100.0 h=50.0 -->
|
14
|
+
<transition event="center" target="centered"><!-- edge-path [centered] x=440.0 y=170.0 pointx=0.0 pointy=8.0 offsetx=15.0 offsety=13.0 --></transition>
|
15
|
+
</state>
|
16
|
+
</state>
|
17
|
+
<state id="centered"><!-- node-size-and-position x=350.0 y=230.0 w=100.0 h=60.0 -->
|
18
|
+
<transition cond="in_tilting_mode" event="tilt_right" target="tilting_right"><!-- edge-path [tilting_right] x=70.0 y=140.0 pointx=0.0 pointy=19.0 offsetx=-14.0 offsety=-32.0 --></transition>
|
19
|
+
<transition cond="in_nodding_mode" event="look_down" target="looking_down"><!-- edge-path [looking_down] x=160.0 y=260.0 pointx=0.0 pointy=-10.0 offsetx=10.0 offsety=0.0 --></transition>
|
20
|
+
<transition cond="in_turning_mode" event="turn_right" target="looking_right"><!-- edge-path [looking_right] x=650.0 y=260.0 pointx=0.0 pointy=10.0 offsetx=-20.0 offsety=0.0 --></transition>
|
21
|
+
</state>
|
22
|
+
<state id="turning"><!-- node-size-and-position x=540.0 y=30.0 w=190.0 h=130.0 -->
|
23
|
+
<state id="looking_right"><!-- node-size-and-position x=60.0 y=40.0 w=100.0 h=50.0 -->
|
24
|
+
<transition event="center" target="centered"><!-- edge-path [centered] pointx=0.0 pointy=24.0 offsetx=8.0 offsety=-5.0 --></transition>
|
25
|
+
</state>
|
26
|
+
</state>
|
27
|
+
</state>
|
28
|
+
</scxml>
|
@@ -0,0 +1,266 @@
|
|
1
|
+
module MINT
|
2
|
+
class CIC < CIO
|
3
|
+
property :rows, Integer
|
4
|
+
property :cols, Integer
|
5
|
+
|
6
|
+
def calculate_position(parent_cic,elements,solver,i,b,layer=0)
|
7
|
+
p "container #{self.name} #{b}"
|
8
|
+
aic = AIC.first(:name=>self.name)
|
9
|
+
elements = []
|
10
|
+
|
11
|
+
|
12
|
+
if aic.childs && aic.childs.length>0
|
13
|
+
|
14
|
+
calculateColsAndRows(aic.childs.length)
|
15
|
+
grid_hash= mda(self.rows,self.cols)
|
16
|
+
|
17
|
+
aic.childs.each_with_index do |e,i|
|
18
|
+
cio = CIO.first(:name=>e.name)
|
19
|
+
elements << cio
|
20
|
+
if (not cio)
|
21
|
+
cio = CIO.createCIOfromAIO(e,layer)
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
# Save the actual row,column, and layer to the element
|
27
|
+
cio.col = i % self.cols
|
28
|
+
cio.row = i / self.cols
|
29
|
+
cio.layer = layer+1
|
30
|
+
|
31
|
+
|
32
|
+
cio.calculate_position(self,elements,solver,i,b,layer+1)
|
33
|
+
grid_hash[cio.row][cio.col] = cio
|
34
|
+
p "child #{cio.name} 1.positioning step"
|
35
|
+
end
|
36
|
+
|
37
|
+
if self.process_event("position")
|
38
|
+
if parent_cic
|
39
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.Y,ClLinearExpression.new(parent_cic.pos.Y.Value).Plus(ClLinearExpression.new(b))))
|
40
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.X,ClLinearExpression.new(parent_cic.pos.X.Value).Plus(ClLinearExpression.new(b))))
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# parent(height) = SUM(AllElementsOfColumn(c)(height))+((self.rows+1)*b)
|
45
|
+
if (self.rows >0)
|
46
|
+
self.cols.times do |c|
|
47
|
+
solver.AddConstraint(ClLinearInequality.new(size.Y,CnGEQ,iterate_rows_of_column(grid_hash,c,self.rows-1).Plus(ClLinearExpression.new((self.rows+1)*b)),Cassowary.ClsStrong))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# parent(width) = SUM(AllElementsOfRow(r)(width))+((self.cols+1)*b)
|
52
|
+
if (self.cols>0)
|
53
|
+
self.rows.times do |r|
|
54
|
+
solver.AddConstraint(ClLinearInequality.new(size.X,CnGEQ,iterate_cols_of_row(grid_hash,r,self.cols-1).Plus(ClLinearExpression.new((self.cols+1)*b)),Cassowary.ClsStrong))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
else
|
58
|
+
# fixed position
|
59
|
+
p "CIC fixed#{self.inspect}"
|
60
|
+
setFixedPositionConstraints(solver)
|
61
|
+
setFixedSizeConstraints(solver)
|
62
|
+
end
|
63
|
+
|
64
|
+
else
|
65
|
+
self.cio_calculate_position(parent_cic,elements,solver,i,b,layer)
|
66
|
+
end
|
67
|
+
|
68
|
+
self.process_event("calculated")
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
# elements array of elements from left to right and first to last row
|
74
|
+
# cx, cy container position
|
75
|
+
# ch,cw container size
|
76
|
+
# rows and columns
|
77
|
+
# b minimal border space between elements
|
78
|
+
def calculate_container(solver,b,layer=0)
|
79
|
+
|
80
|
+
#handle special cases where nr(elements) < self.cols * rows by overwriting rows and self.cols properties to fit elemnt amounts
|
81
|
+
|
82
|
+
if self.process_event!("position")
|
83
|
+
# p "in positionion #{self.name}"
|
84
|
+
self.layer = layer
|
85
|
+
aic = AIC.first(:name=>self.name)
|
86
|
+
|
87
|
+
elements_count = aic.childs.length
|
88
|
+
|
89
|
+
calculateColsAndRows(elements_count)
|
90
|
+
|
91
|
+
# create grid with helper method
|
92
|
+
self.rows= elements_count if (self.rows == nil)
|
93
|
+
self.cols= 1 if (self.cols == nil)
|
94
|
+
|
95
|
+
grid_hash= mda(self.rows,self.cols)
|
96
|
+
# p "hash #{ self.name} rows #{self.rows} cols #{self.cols}"
|
97
|
+
|
98
|
+
ai_childs = aic.childs.all(:abstract_states=> /#{Regexp.quote("organized")}/)
|
99
|
+
# p aic.name
|
100
|
+
elements=[]
|
101
|
+
ai_childs.each_with_index do |e,i|
|
102
|
+
cio = CIO.first(:name=>e.name)
|
103
|
+
|
104
|
+
if (not cio)
|
105
|
+
cio = CIO.createCIOfromAIO(e,layer)
|
106
|
+
else
|
107
|
+
cio.layer=layer+1
|
108
|
+
end
|
109
|
+
|
110
|
+
if (not cio.kind_of? MINT::CIC)
|
111
|
+
cio.process_event!("position")
|
112
|
+
end
|
113
|
+
|
114
|
+
elements << cio
|
115
|
+
|
116
|
+
cio.setMinimumSizeConstraints(solver)
|
117
|
+
|
118
|
+
act_col = i % self.cols
|
119
|
+
act_row = i / self.cols
|
120
|
+
|
121
|
+
# p "#{e.name} parent #{act_row} #{act_col}"
|
122
|
+
|
123
|
+
grid_hash[act_row][act_col] = cio
|
124
|
+
|
125
|
+
# Save the actual row and column of the element
|
126
|
+
cio.col = act_col
|
127
|
+
cio.row = act_row
|
128
|
+
|
129
|
+
cio.setTableElementConstraints(solver,elements, self,act_col,act_row,i,b)
|
130
|
+
|
131
|
+
if (cio.kind_of? MINT::CIC)
|
132
|
+
cio.calculate_container(solver,b,layer+1)
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
# calculate navigation
|
138
|
+
# calculate_gfx__navigation(grid_hash)
|
139
|
+
save_grid(grid_hash)
|
140
|
+
|
141
|
+
# Specify the parent container minimal width and height by summing ab all children widths and heights resp.
|
142
|
+
|
143
|
+
# parent(height) = SUM(AllElementsOfColumn(c)(height))+((self.rows+1)*b)
|
144
|
+
if (self.rows >0)
|
145
|
+
self.cols.times do |c|
|
146
|
+
solver.AddConstraint(ClLinearInequality.new(size.Y,CnGEQ,iterate_rows_of_column(grid_hash,c,self.rows-1).Plus(ClLinearExpression.new((self.rows+1)*b)),Cassowary.ClsStrong))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
# parent(width) = SUM(AllElementsOfRow(r)(width))+((self.cols+1)*b)
|
151
|
+
if (self.cols>0)
|
152
|
+
self.rows.times do |r|
|
153
|
+
solver.AddConstraint(ClLinearInequality.new(size.X,CnGEQ,iterate_cols_of_row(grid_hash,r,self.cols-1).Plus(ClLinearExpression.new((self.cols+1)*b)),Cassowary.ClsStrong))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
elements.each { |e|
|
158
|
+
# e.print
|
159
|
+
if (not e.kind_of? MINT::CIC)
|
160
|
+
e.process_event!("calculated")
|
161
|
+
end
|
162
|
+
e.save
|
163
|
+
}
|
164
|
+
self.process_event("calculated")
|
165
|
+
else
|
166
|
+
aic = AIC.first(:name=>name)
|
167
|
+
elements = []
|
168
|
+
aic.childs.each_with_index do |e,i|
|
169
|
+
cio = CIO.first(:name=>e.name)
|
170
|
+
elements << cio
|
171
|
+
if (not cio)
|
172
|
+
cio = CIO.createCIOfromAIO(e,layer)
|
173
|
+
end
|
174
|
+
|
175
|
+
calculateColsAndRows(aic.childs.length)
|
176
|
+
|
177
|
+
# Save the actual row,column, and layer to the element
|
178
|
+
cio.col = i % self.cols
|
179
|
+
cio.row = i / self.cols
|
180
|
+
cio.layer = layer+1
|
181
|
+
|
182
|
+
cio.calculate_position(self,elements,solver,i,b)
|
183
|
+
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def mda(width, height)
|
189
|
+
return Array.new(width){Array.new(height)}
|
190
|
+
end
|
191
|
+
|
192
|
+
def calculateColsAndRows(elements_count)
|
193
|
+
if not self.cols and not self.rows
|
194
|
+
self.rows = elements_count
|
195
|
+
self.cols = 1
|
196
|
+
end
|
197
|
+
|
198
|
+
if (elements_count < self.cols*self.rows)
|
199
|
+
if self.cols == 1
|
200
|
+
self.rows = elements_count
|
201
|
+
elsif self.rows ==1
|
202
|
+
self.cols = elements_count
|
203
|
+
else
|
204
|
+
factor = elements_count / self.cols*self.rows
|
205
|
+
self.cols = (self.cols*factor).round
|
206
|
+
self.rows = (self.cols*factor).round
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def calculate_gfx__navigation(array)
|
212
|
+
array.each_with_index do |row,r|
|
213
|
+
row.each_with_index do |column,c|
|
214
|
+
if not c==0
|
215
|
+
# left and right in a table
|
216
|
+
array[r][c-1].right = array[r][c]
|
217
|
+
array[r][c].left = array[r][c-1]
|
218
|
+
# puts "left<>right: #{array[r][c-1].name} <> #{array[r][c].name}"
|
219
|
+
end
|
220
|
+
if not r ==0
|
221
|
+
# up and down in a table
|
222
|
+
array[r-1][c].down = array[r][c]
|
223
|
+
array[r][c].up = array[r-1][c]
|
224
|
+
# puts "up<>down: #{array[r-1][c].name} <> #{array[r][c].name}"
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def save_grid(array)
|
231
|
+
array.each_with_index do |row,r|
|
232
|
+
row.each_with_index do |column,c|
|
233
|
+
array[r][c].save
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
# Iterates over all columns of one row that is set by #row_nr
|
239
|
+
#
|
240
|
+
# @param array the two dimensional array that should be iterated
|
241
|
+
# @param row_nr the index of the row that should be used for iteration
|
242
|
+
# @param index the highest index of a column that shoul be iterated (the iteration starts with this index and iterates backwards until 0.
|
243
|
+
# @return [CLinearExpression] a Plus composed linear expressions with all variables
|
244
|
+
#
|
245
|
+
def iterate_cols_of_row(array,row_nr,index)
|
246
|
+
if (index>0)
|
247
|
+
return ClLinearExpression.new(array[row_nr][index].size.X).Plus(iterate_cols_of_row(array,row_nr,index-1))
|
248
|
+
else
|
249
|
+
return ClLinearExpression.new(array[row_nr][index].size.X)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def iterate_rows_of_column(array,col_nr,index)
|
254
|
+
begin
|
255
|
+
|
256
|
+
if (index>0)
|
257
|
+
return ClLinearExpression.new(array[index][col_nr].size.Y).Plus(iterate_rows_of_column(array,col_nr,index-1))
|
258
|
+
else
|
259
|
+
return ClLinearExpression.new(array[index][col_nr].size.Y)
|
260
|
+
end
|
261
|
+
rescue NoMethodError
|
262
|
+
p "rescue with index #{index} and col_nr #{col_nr}"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
@@ -0,0 +1,381 @@
|
|
1
|
+
module MINT
|
2
|
+
class CIO_sync_callback
|
3
|
+
def sync_aio_to_focused
|
4
|
+
true
|
5
|
+
end
|
6
|
+
|
7
|
+
def sync_aio_to_presented
|
8
|
+
true
|
9
|
+
end
|
10
|
+
def sync_aio_to_defocus
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def sync_aio_to_suspended
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class CIO < Element
|
21
|
+
include Cassowary
|
22
|
+
|
23
|
+
has 1, :up, self,
|
24
|
+
:parent_key => [ :id ], # in the remote model (Blog)
|
25
|
+
:child_key => [ :up_id ] # local to this model (Post)
|
26
|
+
has 1, :down, self,
|
27
|
+
:parent_key => [ :id ], # in the remote model (Blog)
|
28
|
+
:child_key => [ :down_id ] # local to this model (Post)
|
29
|
+
has 1, :left, self,
|
30
|
+
:parent_key => [ :id ], # in the remote model (Blog)
|
31
|
+
:child_key => [ :left_id ] # local to this model (Post)
|
32
|
+
has 1, :right, self,
|
33
|
+
:parent_key => [ :id ], # in the remote model (Blog)
|
34
|
+
:child_key => [ :right_id ] # local to this model (Post)
|
35
|
+
|
36
|
+
property :text, Text, :lazy => false
|
37
|
+
property :fontname, String, :default => "Helvetica"
|
38
|
+
property :fontsize, Integer, :default => 13
|
39
|
+
property :minwidth, Integer
|
40
|
+
property :minheight, Integer
|
41
|
+
property :minspace, Integer
|
42
|
+
property :optspace, Integer
|
43
|
+
property :width, Integer
|
44
|
+
property :height, Integer
|
45
|
+
property :x, Integer
|
46
|
+
property :y, Integer
|
47
|
+
property :layer, Integer
|
48
|
+
property :row, Integer
|
49
|
+
property :col,Integer
|
50
|
+
|
51
|
+
|
52
|
+
# before :create, :recover_statemachine
|
53
|
+
|
54
|
+
before :create, :initialize_points
|
55
|
+
# before :update, :initialize_points
|
56
|
+
# before :save!, :store_calculated_values_in_model
|
57
|
+
# before :save, :store_calculated_values_in_model
|
58
|
+
|
59
|
+
before :update!, :initialize_points
|
60
|
+
public
|
61
|
+
def initialize_points
|
62
|
+
@pos = Cassowary::ClPoint.new()
|
63
|
+
if (self.x and self.y)
|
64
|
+
@pos = Cassowary::ClPoint.new(self.x,self.y)
|
65
|
+
end
|
66
|
+
@size = Cassowary::ClPoint.new()
|
67
|
+
if (self.width and self.height)
|
68
|
+
@size = Cassowary::ClPoint.new(self.width, self.height)
|
69
|
+
elsif (self.minwidth and self.minheight)
|
70
|
+
@size = Cassowary::ClPoint.new(self.minwidth, self.minheight)
|
71
|
+
end
|
72
|
+
true
|
73
|
+
end
|
74
|
+
|
75
|
+
def store_calculated_values_in_model
|
76
|
+
|
77
|
+
attribute_set(:x,pos.Xvalue)
|
78
|
+
attribute_set(:y,pos.Yvalue)
|
79
|
+
attribute_set(:width,size.Xvalue)
|
80
|
+
attribute_set(:height,size.Yvalue)
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def pos(x=-1,y=-1)
|
85
|
+
if (x > -1 and y> -1)
|
86
|
+
@pos = Cassowary::ClPoint.new(x,y)
|
87
|
+
elsif not @pos
|
88
|
+
#if not @pos
|
89
|
+
@pos = Cassowary::ClPoint.new
|
90
|
+
|
91
|
+
if (attribute_get(:x) and attribute_get(:y))
|
92
|
+
@pos = Cassowary::ClPoint.new(attribute_get(:x),attribute_get(:y))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
return @pos
|
96
|
+
end
|
97
|
+
|
98
|
+
def size(width=-1,height=-1)
|
99
|
+
if (width > -1 and height> -1)
|
100
|
+
@size = Cassowary::ClPoint.new(with,height)
|
101
|
+
elsif not @size
|
102
|
+
#if not @size
|
103
|
+
@size = Cassowary::ClPoint.new
|
104
|
+
if (attribute_get(:width) and attribute_get(:height))
|
105
|
+
@size = Cassowary::ClPoint.new(attribute_get(:width), attribute_get(:height))
|
106
|
+
elsif (attribute_get(:minwidth) and attribute_get(:minheight))
|
107
|
+
@size = Cassowary::ClPoint.new(attribute_get(:minwidth), attribute_get(:minheight))
|
108
|
+
end
|
109
|
+
end
|
110
|
+
return @size
|
111
|
+
end
|
112
|
+
|
113
|
+
def calculateMinimumSize(border = 5)
|
114
|
+
if text
|
115
|
+
|
116
|
+
label = Magick::Draw.new
|
117
|
+
label.font = fontname
|
118
|
+
label.text_antialias(true)
|
119
|
+
label.font_style=Magick::NormalStyle
|
120
|
+
label.font_weight=Magick::NormalWeight
|
121
|
+
label.gravity=Magick::CenterGravity
|
122
|
+
label.text(0,0,text)
|
123
|
+
label.pointsize = fontsize
|
124
|
+
metrics = label.get_type_metrics(text)
|
125
|
+
|
126
|
+
self.minheight=metrics.height+2*border
|
127
|
+
self.minwidth=metrics.width+2*border
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def calculate_position(parent_cic,elements,solver,i,b,layer =0)
|
132
|
+
if self.process_event("position")
|
133
|
+
p "cio #{self.inspect} parent #{parent_cic.inspect}"
|
134
|
+
self.layer=layer
|
135
|
+
setMinimumSizeConstraints(solver)
|
136
|
+
|
137
|
+
setTableElementConstraints(solver,elements,parent_cic,self.col,self.row,i,b) if elements and elements.length>0
|
138
|
+
self.process_event("calculated")
|
139
|
+
else
|
140
|
+
p "cio fixed#{self.inspect}"
|
141
|
+
setFixedPositionConstraints(solver)
|
142
|
+
setFixedSizeConstraints(solver)
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
alias :cio_calculate_position :calculate_position
|
148
|
+
|
149
|
+
def setFixedPositionConstraints(solver)
|
150
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.X,ClLinearExpression.new(self.pos.X.Value),Cassowary.ClsStrong))
|
151
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.Y,ClLinearExpression.new(self.pos.Y.Value),Cassowary.ClsStrong))
|
152
|
+
end
|
153
|
+
|
154
|
+
def setFixedSizeConstraints(solver)
|
155
|
+
solver.AddConstraint(ClLinearEquation.new(self.size.X,ClLinearExpression.new(self.size.X.Value),Cassowary.ClsStrong))
|
156
|
+
solver.AddConstraint(ClLinearEquation.new(self.size.Y,ClLinearExpression.new(self.size.Y.Value),Cassowary.ClsStrong))
|
157
|
+
end
|
158
|
+
|
159
|
+
def setMinimumSizeConstraints(solver)
|
160
|
+
# p "l11"
|
161
|
+
# take care of generate only positive values for height,width, x,y
|
162
|
+
# p "#{name} -calculating>#{self.name}"
|
163
|
+
# Consider minimum Sizes
|
164
|
+
if self.minwidth
|
165
|
+
solver.AddConstraint(ClLinearInequality.new(self.size.X,CnGEQ,ClLinearExpression.new(self.minwidth),Cassowary.ClsStrong))
|
166
|
+
else
|
167
|
+
solver.AddConstraint(ClLinearInequality.new(self.size.X,CnGEQ,ClLinearExpression.new(0),Cassowary.ClsStrong))
|
168
|
+
end
|
169
|
+
if self.minheight
|
170
|
+
solver.AddConstraint(ClLinearInequality.new(self.size.Y,CnGEQ,ClLinearExpression.new(self.minheight),Cassowary.ClsStrong))
|
171
|
+
else
|
172
|
+
solver.AddConstraint(ClLinearInequality.new(self.size.Y,CnGEQ,ClLinearExpression.new(0),Cassowary.ClsStrong))
|
173
|
+
end
|
174
|
+
|
175
|
+
# solver.AddConstraint(ClLinearInequality.new(self.pos.X,CnGEQ,ClLinearExpression.new(parent.pos.X),Cassowary.ClsStrong))
|
176
|
+
# solver.AddConstraint(ClLinearInequality.new(self.pos.Y,CnGEQ,ClLinearExpression.new(parent.pos.Y),Cassowary.ClsStrong))
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
def setTableElementConstraints(solver,elements, cic,act_col,act_row,i,b)
|
181
|
+
total_cols = cic.cols
|
182
|
+
total_rows = cic.rows
|
183
|
+
|
184
|
+
if (act_col == 0)
|
185
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.X,ClLinearExpression.new(cic.pos.X.Value).Plus(ClLinearExpression.new(b)),Cassowary.ClsStrong))
|
186
|
+
else
|
187
|
+
# e(x) = e-1(x)+e-1(width)+b
|
188
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.X,ClLinearExpression.new(elements[i-1].pos.X.Value).Plus(ClLinearExpression.new(elements[i-1].size.X)).Plus(ClLinearExpression.new(b))))
|
189
|
+
end
|
190
|
+
|
191
|
+
# Y coordinate handling for first row
|
192
|
+
if (i<total_cols)
|
193
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.Y,ClLinearExpression.new(cic.pos.Y.Value).Plus(ClLinearExpression.new(b))))
|
194
|
+
else
|
195
|
+
solver.AddConstraint(ClLinearEquation.new(self.pos.Y,ClLinearExpression.new(elements[i-total_cols].pos.Y.Value).Plus(ClLinearExpression.new(elements[i-total_cols].size.Y)).Plus(ClLinearExpression.new(b))))
|
196
|
+
end
|
197
|
+
|
198
|
+
|
199
|
+
# maximize sizes
|
200
|
+
#e(width)=c(width)/total_cols - ((total_cols+1)*b)/total_cols
|
201
|
+
solver.AddConstraint(ClLinearEquation.new(self.size.X,ClLinearExpression.new(
|
202
|
+
cic.size.X.Value).Divide(total_cols).Minus(ClLinearExpression.new(((total_cols+1)*b)/total_cols)),Cassowary.ClsWeak
|
203
|
+
))
|
204
|
+
|
205
|
+
# solver.AddConstraint(ClLinearInequality.new(self.size.X,CnLEQ,ClLinearExpression.new(parent.size.X),Cassowary.ClsStrong))
|
206
|
+
#e(height)= c(height)/total_rows - ((total_rows+1)*b)/total_rows
|
207
|
+
solver.AddConstraint(ClLinearEquation.new(self.size.Y,ClLinearExpression.new(
|
208
|
+
cic.size.Y.Value).Divide(total_rows).Minus(ClLinearExpression.new(((total_rows+1)*b)/total_rows)),Cassowary.ClsWeak
|
209
|
+
))
|
210
|
+
# solver.AddConstraint(ClLinearInequality.new(e.size.Y,CnLEQ,ClLinearExpression.new(),Cassowary.ClsStrong))
|
211
|
+
|
212
|
+
# relative size to the parent: e.size.X*e.size.Y/parent.size.X*parent.size.Y=e.minspace/parent.minspace
|
213
|
+
# if (parent.minspace and e.minspace and parent.minspace>0 and e.minspace>0)
|
214
|
+
# solver.AddConstraint(ClLinearEquation.new(e.size.Y,ClLinearExpression.new(parent.size.Y).Times(e.minspace/parent.minspace),Cassowary.ClsWeak
|
215
|
+
# ))
|
216
|
+
|
217
|
+
# solver.AddConstraint(ClLinearEquation.new(e.size.X,ClLinearExpression.new(parent.size.X).Times(e.minspace/parent.minspace),Cassowary.ClsWeak
|
218
|
+
### ))
|
219
|
+
# end
|
220
|
+
|
221
|
+
end
|
222
|
+
def CIO.createCIOfromAIO(e,layer)
|
223
|
+
p "creating CIO for #{e.class}"
|
224
|
+
case e.class.name
|
225
|
+
when "MINT::AIC","MINT::AISinglePresence"
|
226
|
+
aic = AIC.first(:name=>e.name) # TODO: if its not retrieved again, childs.length returns 0!
|
227
|
+
|
228
|
+
elements_count = aic.childs.length
|
229
|
+
elements_count = 1 if elements_count== 0
|
230
|
+
cio = CIC.create(:name=>e.name,:cols=>1,:rows=>elements_count,:layer =>layer+1)
|
231
|
+
|
232
|
+
|
233
|
+
p "create #{e.name} rows: #{elements_count}"
|
234
|
+
when "MINT::AIMultiChoice"
|
235
|
+
cio = CheckBoxGroup.create(:name=>e.name,:layer =>layer+1)
|
236
|
+
when "MINT::AISingleChoice"
|
237
|
+
cio = RadioButtonGroup.create(:name=>e.name,:layer =>layer+1)
|
238
|
+
when "MINT::AIMultiChoiceElement"
|
239
|
+
cio = CheckBox.create(:name=>e.name,:layer =>layer+1)
|
240
|
+
when "MINT::AISingleChoiceElement"
|
241
|
+
cio = RadioButton.create(:name=>e.name,:layer =>layer+1)
|
242
|
+
when "MINT::AIOUTContext"
|
243
|
+
cio = BasicText.create(:name=>e.name,:layer =>layer+1)
|
244
|
+
when "MINT::AIINReference"
|
245
|
+
cio = Label.create(:name=>e.name,:layer =>layer+1)
|
246
|
+
when "MINT::AICommand"
|
247
|
+
cio = Button.create(:name=>e.name,:layer =>layer+1)
|
248
|
+
else
|
249
|
+
cio = CIO.create(:name=>e.name,:layer =>layer+1)
|
250
|
+
|
251
|
+
end
|
252
|
+
p "Created #{cio.inspect}"
|
253
|
+
return cio
|
254
|
+
end
|
255
|
+
|
256
|
+
def initialize_statemachine
|
257
|
+
if @statemachine.blank?
|
258
|
+
|
259
|
+
@statemachine = Statemachine.build do
|
260
|
+
|
261
|
+
superstate :CIO do
|
262
|
+
trans :initialized,:position,:positioning
|
263
|
+
trans :positioning,:calculated,:positioned, :store_calculated_values_in_model
|
264
|
+
trans :positioned, :display, :presenting
|
265
|
+
trans :disabled, :hide, :hidden
|
266
|
+
trans :hidden,:display, :presenting
|
267
|
+
|
268
|
+
state :hidden do
|
269
|
+
on_entry :sync_aio_to_suspended
|
270
|
+
end
|
271
|
+
|
272
|
+
superstate :presenting do
|
273
|
+
on_entry :sync_aio_to_presented
|
274
|
+
|
275
|
+
state :displayed do
|
276
|
+
on_entry :sync_aio_to_defocus
|
277
|
+
end
|
278
|
+
|
279
|
+
state :highlighted do
|
280
|
+
on_entry :sync_aio_to_focused
|
281
|
+
end
|
282
|
+
|
283
|
+
trans :displayed, :highlight, :highlighted
|
284
|
+
#trans :displayed, :display, :displayed # a display request can be issued several times even if the object is already displayed (in case of refresh or multimple presentations
|
285
|
+
#trans :highlighted, :display, :highlighted # this is because display requests should not change the highlighting
|
286
|
+
trans :highlighted,:unhighlight, :displayed
|
287
|
+
trans :highlighted, :up, :displayed, :highlight_up
|
288
|
+
trans :highlighted, :down, :displayed, :highlight_down
|
289
|
+
trans :highlighted, :left, :displayed, :highlight_left
|
290
|
+
trans :highlighted, :right, :displayed, :highlight_right
|
291
|
+
|
292
|
+
event :disable, :disabled
|
293
|
+
event :hide, :hidden
|
294
|
+
|
295
|
+
end
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
def sync_event(event)
|
303
|
+
process_event(event, CIO_sync_callback.new)
|
304
|
+
end
|
305
|
+
|
306
|
+
# callbacks
|
307
|
+
|
308
|
+
def highlight_up
|
309
|
+
if (self.up)
|
310
|
+
self.up.process_event("highlight")
|
311
|
+
else
|
312
|
+
return nil # TODO not working, find abbruchbedingung!!!
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def highlight_down
|
317
|
+
if (self.down)
|
318
|
+
self.down.process_event("highlight")
|
319
|
+
else
|
320
|
+
return nil # TODO not working, find abbruchbedingung!!!
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def highlight_left
|
325
|
+
if (self.left)
|
326
|
+
self.left.process_event("highlight")
|
327
|
+
else
|
328
|
+
return nil # TODO not working, find abbruchbedingung!!!
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
def highlight_right
|
333
|
+
if (self.right)
|
334
|
+
self.right.process_event("highlight")
|
335
|
+
else
|
336
|
+
return nil # TODO not working, find abbruchbedingung!!!
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
def sync_aio_to_presented
|
342
|
+
aio = MINT::AIO.first(:name=>self.name)
|
343
|
+
if (aio and not aio.is_in? :presenting)
|
344
|
+
aio.sync_event(:present)
|
345
|
+
end
|
346
|
+
true
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
def sync_aio_to_defocus
|
351
|
+
aio = MINT::AIO.first(:name=>self.name)
|
352
|
+
if (aio and not aio.is_in? :defocused)
|
353
|
+
aio.sync_event(:defocus)
|
354
|
+
end
|
355
|
+
true
|
356
|
+
end
|
357
|
+
|
358
|
+
def sync_aio_to_focused
|
359
|
+
aio = MINT::AIO.first(:name=>self.name)
|
360
|
+
if (aio and not aio.is_in? :focused)
|
361
|
+
aio.sync_event(:focus)
|
362
|
+
end
|
363
|
+
true
|
364
|
+
end
|
365
|
+
|
366
|
+
def sync_aio_to_suspended
|
367
|
+
aio = MINT::AIO.first(:name=>self.name)
|
368
|
+
if (aio and not aio.is_in? :suspended)
|
369
|
+
aio.sync_event(:suspend)
|
370
|
+
end
|
371
|
+
true
|
372
|
+
end
|
373
|
+
|
374
|
+
|
375
|
+
|
376
|
+
def print
|
377
|
+
puts "\"#{self.name}\",#{pos.Xvalue}, #{pos.Yvalue}, #{size.Xvalue}, #{size.Yvalue}"
|
378
|
+
end
|
379
|
+
|
380
|
+
end
|
381
|
+
end
|