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.
Files changed (79) hide show
  1. data/.gemtest +0 -0
  2. data/Gemfile +17 -0
  3. data/Gemfile.lock +69 -0
  4. data/History.txt +3 -0
  5. data/MINT-core.gemspec +58 -0
  6. data/Manifest.txt +77 -0
  7. data/PostInstall.txt +7 -0
  8. data/README.rdoc +63 -0
  9. data/Rakefile +29 -0
  10. data/bin/mint-aui +40 -0
  11. data/bin/mint-cui-gfx +47 -0
  12. data/bin/mint-juggernaut.sh +4 -0
  13. data/bin/mint-tuplespace +12 -0
  14. data/lib/MINT-core.rb +42 -0
  15. data/lib/MINT-core/agent/agent.rb +28 -0
  16. data/lib/MINT-core/agent/aui.rb +52 -0
  17. data/lib/MINT-core/agent/auicontrol.rb +135 -0
  18. data/lib/MINT-core/agent/cui-gfx.rb +160 -0
  19. data/lib/MINT-core/agent/cuicontrol.rb +46 -0
  20. data/lib/MINT-core/mapping/complementary.rb +100 -0
  21. data/lib/MINT-core/mapping/mapping.rb +47 -0
  22. data/lib/MINT-core/mapping/on_state_change.rb +65 -0
  23. data/lib/MINT-core/mapping/sequential.rb +87 -0
  24. data/lib/MINT-core/model/aui/AIC.rb +86 -0
  25. data/lib/MINT-core/model/aui/AIChoice.rb +65 -0
  26. data/lib/MINT-core/model/aui/AIINChoose.rb +54 -0
  27. data/lib/MINT-core/model/aui/AIMultiChoice.rb +5 -0
  28. data/lib/MINT-core/model/aui/AIMultiChoiceElement.rb +56 -0
  29. data/lib/MINT-core/model/aui/AIO.rb +170 -0
  30. data/lib/MINT-core/model/aui/AIOUTDiscrete.rb +43 -0
  31. data/lib/MINT-core/model/aui/AISingleChoice.rb +9 -0
  32. data/lib/MINT-core/model/aui/AISingleChoiceElement.rb +69 -0
  33. data/lib/MINT-core/model/aui/AISinglePresence.rb +100 -0
  34. data/lib/MINT-core/model/aui/aic.png +0 -0
  35. data/lib/MINT-core/model/aui/aic.scxml +50 -0
  36. data/lib/MINT-core/model/aui/aichoice.png +0 -0
  37. data/lib/MINT-core/model/aui/aichoice.scxml +60 -0
  38. data/lib/MINT-core/model/aui/aio.png +0 -0
  39. data/lib/MINT-core/model/aui/aio.scxml +43 -0
  40. data/lib/MINT-core/model/aui/aisinglechoiceelement.png +0 -0
  41. data/lib/MINT-core/model/aui/aisinglechoiceelement.scxml +71 -0
  42. data/lib/MINT-core/model/aui/aisinglepresence.png +0 -0
  43. data/lib/MINT-core/model/aui/aisinglepresence.scxml +58 -0
  44. data/lib/MINT-core/model/aui/model.rb +50 -0
  45. data/lib/MINT-core/model/body/gesture_button.rb +26 -0
  46. data/lib/MINT-core/model/body/handgesture.rb +279 -0
  47. data/lib/MINT-core/model/body/head.png +0 -0
  48. data/lib/MINT-core/model/body/head.rb +51 -0
  49. data/lib/MINT-core/model/body/head.scxml +28 -0
  50. data/lib/MINT-core/model/cui/gfx/CIC.rb +266 -0
  51. data/lib/MINT-core/model/cui/gfx/CIO.rb +381 -0
  52. data/lib/MINT-core/model/cui/gfx/model.rb +204 -0
  53. data/lib/MINT-core/model/cui/gfx/screen.rb +18 -0
  54. data/lib/MINT-core/model/device/button.rb +20 -0
  55. data/lib/MINT-core/model/device/joypad.rb +30 -0
  56. data/lib/MINT-core/model/device/mouse.rb +171 -0
  57. data/lib/MINT-core/model/device/pointer.rb +85 -0
  58. data/lib/MINT-core/model/device/wheel.rb +51 -0
  59. data/lib/MINT-core/model/interactor.rb +167 -0
  60. data/lib/MINT-core/model/task.rb +71 -0
  61. data/lib/MINT-core/overrides/rinda.rb +34 -0
  62. data/script/console +10 -0
  63. data/script/destroy +14 -0
  64. data/script/generate +14 -0
  65. data/spec/AIC_spec.rb +69 -0
  66. data/spec/AISinglePresence_spec.rb +94 -0
  67. data/spec/MINT-core_spec.rb +11 -0
  68. data/spec/aio_agent_spec.rb +234 -0
  69. data/spec/aio_spec.rb +144 -0
  70. data/spec/aisinglechoice_spec.rb +152 -0
  71. data/spec/aisinglechoiceelement_spec.rb +106 -0
  72. data/spec/cio_spec.rb +369 -0
  73. data/spec/core_spec.rb +29 -0
  74. data/spec/music_spec.rb +179 -0
  75. data/spec/rcov.opts +2 -0
  76. data/spec/spec.opts +4 -0
  77. data/spec/spec_helper.rb +7 -0
  78. data/tasks/rspec.rake +21 -0
  79. 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