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
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
|