· 6 years ago · Mar 05, 2019, 11:20 AM
1# ===================================================================
2#
3# Script: UIManager
4#
5# $$COPYRIGHT$$
6#
7# ===================================================================
8
9class Formula
10 ###*
11 * Encapsulates a UI formula. A formula can be used in UI layouts to define
12 * property-bindings or to implement a specific behavior.
13 *
14 * @module ui
15 * @class Formula
16 * @memberof ui
17 * @constructor
18 * @param {Function} f - The formula-function. Defines the logic of the formula.
19 * @param {Object} data - An optional data-object which can be accessed inside the formula-function.
20 * @param {string} event - An optional event-name to define when the formula should be executed.
21 ###
22 constructor: (f, data, event) ->
23 ###*
24 * Indicates if its the first time the formula is called.
25 * @property onInitialize
26 * @type boolean
27 ###
28 @onInitialize = yes
29
30 ###*
31 * The formula-function.
32 * @property exec_
33 * @type Function
34 ###
35 @exec_ = f
36
37 ###*
38 * An optional data-object which can bes accessed inside the formula-function.
39 * @property data
40 * @type Object
41 ###
42 @data = data
43
44 ###*
45 * An optional event-name to define when the formula should be executed.
46 * @property event
47 * @type string
48 ###
49 @event = event
50
51 ###*
52 * An array of custom number-data which can be used for different purposes. The first element
53 * is also used in onChange method to store the old value and check against the new one to detect a change.
54 * @property numbers
55 * @type number[]
56 ###
57 @numbers = new Array(10)
58 @numbers[i] = 0 for i in [0..@numbers.length]
59
60 ###*
61 * An array of custom string-data which can be used for different purposes. The first element
62 * is also used in onTextChange method to store the old value and check against the new one to detect a change.
63 * @property strings
64 * @type string[]
65 ###
66 @strings = new Array(10)
67 @strings[i] = "" for i in [0..@strings.length]
68
69
70 ###*
71 * The formula-function. Its a wrapper-function before the first-time call was made.
72 * @method exec
73 ###
74 exec: ->
75 @exec = @exec_
76 r = @exec_.apply(this, arguments)
77 @onInitialize = no
78
79 return r
80
81 ###*
82 * Checks if the specified number-value has changed since the last check. It uses
83 * the first entry of the numbers-array to store the value and check against the new one.
84 *
85 * @method onChange
86 * @param {number} numberValue - Number value to check.
87 ###
88 onChange: (numberValue) ->
89 result = @numbers[0] != numberValue
90 @numbers[0] = numberValue
91
92 return result
93
94 ###*
95 * Checks if the specified text-value has changed since the last check. It uses
96 * the first entry of the strings-array to store the value and check against the new one.
97 *
98 * @method onTextChange
99 * @param {string} textValue - Text value to check.
100 ###
101 onTextChange: (textValue) ->
102 result = @strings[0] != textValue
103 @strings[0] = textValue
104
105 return result
106
107ui.Formula = Formula
108
109class Space
110 ###*
111 * Describes a space inside or around something like a margin or padding.
112 *
113 * @module ui
114 * @class Space
115 * @memberof ui
116 * @constructor
117 * @param {number} left - Space at the left in pixels.
118 * @param {number} top - Space at the top in pixels.
119 * @param {number} right - Space at the right in pixels.
120 * @param {number} bottom - Space at the bottom in pixels.
121 ###
122 constructor: (left, top, right, bottom) ->
123 ###*
124 * Space at the left in pixels.
125 * @property left
126 * @type number
127 ###
128 @left = left
129
130 ###*
131 * Space at the top in pixels.
132 * @property top
133 * @type number
134 ###
135 @top = top
136
137 ###*
138 * Space at the right in pixels.
139 * @property right
140 * @type number
141 ###
142 @right = right
143
144 ###*
145 * Space at the bottom in pixels.
146 * @property bottom
147 * @type number
148 ###
149 @bottom = bottom
150
151 ###*
152 * Sets the coordinates of the space by copying them from a specified space.
153 *
154 * @method setFromObject
155 * @param {Object} space - A space to copy.
156 ###
157 setFromObject: (space) ->
158 @left = space.left
159 @top = space.top
160 @right = space.right
161 @bottom = space.bottom
162
163 ###*
164 * Sets the coordinates of the space.
165 *
166 * @method set
167 * @param {number} left - Space at the left in pixels.
168 * @param {number} top - Space at the top in pixels.
169 * @param {number} right - Space at the right in pixels.
170 * @param {number} bottom - Space at the bottom in pixels.
171 ###
172 set: (left, top, right, bottom) ->
173 @left = left
174 @top = top
175 @right = right
176 @bottom = bottom
177
178 ###*
179 * Creates a new space object from an array of coordinates.
180 *
181 * @method fromArray
182 * @static
183 * @param {number[]} array - An array of coordinates (left, top right, bottom).
184 ###
185 @fromArray: (array) -> new ui.Space(array[0], array[1], array[2], array[3])
186
187ui.Space = Space
188
189class Style
190 ###*
191 * A UI style can applied to a UI object to modify it properties like color, image, etc. to give a certain "style" to it.
192 *
193 * @module ui
194 * @class Style
195 * @memberof ui
196 * @constructor
197 * @param {Object} descriptor - A style-descriptor to initialize the style from.
198 * @param {number} id - A unique numeric ID to access the style through UIManager.stylesById collection.
199 * @param {number} selector - A selector ID which controls under which conditions the styles will be applied.
200 ###
201 constructor: (descriptor, id, selector) ->
202 ###*
203 * ID number to quickly access this style and link to this style.
204 * @property id
205 * @type number
206 ###
207 @id = id
208
209 ###*
210 * Style-ID of target object. This style will only be applied on UI objects with that style ID which are
211 * children of UI objects where this style is applied.
212 * @property target
213 * @type number
214 ###
215 @target = -1
216
217 ###*
218 * Selector-ID which controls under which conditions the style becomes active.
219 * @property selector
220 * @type number
221 ###
222 @selector = selector
223
224 ###*
225 * The font used for the text-display.
226 * @default null
227 * @property font
228 * @type gs.Font
229 ###
230 @font = null
231
232 ###*
233 * The UI object's image used for visual presentation.
234 * @property image
235 * @type string
236 ###
237 @image = null
238
239 ###*
240 * The UI object's animations used for visual presentation.
241 * @default null
242 * @property animations
243 * @type Object[]
244 ###
245 @animations = null
246
247 ###*
248 * The UI object's color.
249 * @property color
250 * @type gs.Color
251 ###
252 @color = null
253
254 ###*
255 * The UI object's tone.
256 * @property tone
257 * @type gs.Tone
258 ###
259 @tone = null
260
261 ###*
262 * The UI object's anchor-point. For example: An anchor-point with 0,0 places the object with its top-left corner
263 * at its position but with an 0.5, 0.5 anchor-point the object is placed with its center. An anchor-point of 1,1
264 * places the object with its lower-right corner.
265 * @property anchor
266 * @type gs.Point
267 ###
268 @anchor = null
269
270 ###*
271 * The UI object's zoom-setting for x and y axis.
272 * @default new gs.Point(1.0, 1.0)
273 * @property zoom
274 * @type gs.Point
275 ###
276 @zoom = null
277
278 ###*
279 * The UI object's margin. The margin defines an extra space around the UI object.
280 * The default is { left: 0, top: 0, right: 0, bottom: 0 }.
281 * @property margin
282 * @type Object
283 ###
284 @margin = null
285
286 ###*
287 * The UI object's padding. The default is { left: 0, top: 0, right: 0, bottom: 0 }.
288 * @property padding
289 * @type Object
290 ###
291 @padding = null
292
293 ###*
294 * The UI object's mask for masking-effects.
295 * @property mask
296 * @type gs.Mask
297 ###
298 @mask = null
299
300 ###*
301 * The UI object's alignment.
302 * @property alignment
303 * @type ui.Alignment
304 ###
305 @alignment = -1
306
307 ###*
308 * The UI object's opacity to control transparency. For example: 0 = Transparent, 255 = Opaque, 128 = Semi-Transparent.
309 * @property opacity
310 * @type number
311 ###
312 @opacity = -1
313
314 ###*
315 * The object's clip-rect for visual presentation.
316 * @default null
317 * @property clipRect
318 * @type gs.Rect
319 * @protected
320 ###
321 @clipRect = null
322
323 ###*
324 * The corner-size of the frame.
325 * @property frameCornerSize
326 * @type number
327 ###
328 @frameCornerSize = -1
329
330 ###*
331 * The thickness of the frame.
332 * @property frameThickness
333 * @type number
334 ###
335 @frameThickness = -1
336
337 ###*
338 * The looping of the image.
339 * @property looping
340 * @type ui.Orientation
341 ###
342 @looping = null
343
344 ###*
345 * The object's z-index controls rendering-order/image-overlapping. An object with a smaller z-index is rendered
346 * before an object with a larger index. For example: To make sure a game object is always on top of the screen, it
347 * should have the largest z-index of all game objects.
348 * @property zIndex
349 * @type number
350 ###
351 @zIndex = -1
352
353 ###*
354 * The object's alignment on x-axis. Needs to be supported by layout.
355 * @property alignmentX
356 * @type number
357 ###
358 @alignmentX = -1
359
360 ###*
361 * The object's alignment on y-axis. Needs to be supported by layout.
362 * @property alignmentY
363 * @type number
364 ###
365 @alignmentY = -1
366
367 ###*
368 * The object's resize behavior.
369 * @property resizable
370 * @type boolean
371 ###
372 @resizable = null
373
374 ###*
375 * The original style descriptor.
376 * @property descriptor
377 * @type Object
378 ###
379 @descriptor = descriptor
380
381 if descriptor
382 @setFromDescriptor(descriptor)
383
384 ###*
385 * Initializes the style from a style-descriptor.
386 *
387 * @method setFromDescriptor
388 * @param {Object} descriptor - The style-descriptor.
389 ###
390 setFromDescriptor: (descriptor) ->
391 @descriptor = descriptor
392 @image = descriptor.image
393 @color = gs.Color.fromArray(descriptor.color) if descriptor.color
394 @tone = gs.Tone.fromArray(descriptor.tone) if descriptor.tone
395 @anchor = new gs.Point(descriptor.anchor[0], descriptor.anchor[1]) if descriptor.anchor
396 @zoom = new gs.Point(descriptor.zoom[0], descriptor.zoom[1]) if descriptor.zoom
397
398 if descriptor.font
399 @setupFont(descriptor)
400
401 if descriptor.clipRect
402 @clipRect = gs.Rect.fromArray(descriptor.clipRect)
403
404 @opacity = descriptor.opacity if descriptor.opacity >= 0
405 @alignment = descriptor.alignment if descriptor.alignment >= 0
406 @margin = ui.Space.fromArray(descriptor.margin) if descriptor.margin
407 @padding = ui.Space.fromArray(descriptor.padding) if descriptor.padding
408 @animations = descriptor.animations
409 @frameCornerSize = descriptor.frameCornerSize if descriptor.frameCornerSize
410 @frameThickness = descriptor.frameThickness if descriptor.frameThickness
411 @frame = descriptor.frame if descriptor.frame
412 @looping = descriptor.looping if descriptor.looping
413 @resizable = descriptor.resizable if descriptor.resizable?
414 @zIndex = descriptor.zIndex if descriptor.zIndex
415 @alignmentX = ui.UIManager.alignments[descriptor.alignmentX] if descriptor.alignmentX
416 @alignmentY = ui.UIManager.alignments[descriptor.alignmentY] if descriptor.alignmentY
417
418 set: (style) ->
419 @image = style.image
420 @color.setFromObject(style.color)
421 @tone.setFromObject(style.tone)
422 @anchor.set(style.anchor.x, style.anchor.y)
423 @zoom.set(style.zoom.x, style.zoom.y)
424
425 if style.font
426 if !@font then @font = new gs.Font(style.font.name, style.font.size)
427 @font.set(style.font)
428
429 if style.clipRect
430 if !@clipRect then @clipRect = new gs.Rect()
431 @clipRect.setFromObject(style.clipRect)
432
433 @opacity = style.opacitz
434 @alignment = style.alignment
435 @margin.setFromObject(style.margin)
436 @padding.setFromObject(style.padding)
437
438 ###*
439 * Initializes font-data from a style-descriptor.
440 *
441 * @method setupFont
442 * @param {Object} descriptor - The style-descriptor.
443 * @protected
444 ###
445 setupFont: (descriptor) ->
446 if descriptor.font
447 if !@font
448 @font = new Font(descriptor.font.name, descriptor.font.size ? 0)
449 else
450 @font.name = descriptor.font.name
451 @font.size = descriptor.font.size ? 0
452
453 @font.bold = descriptor.font.bold ? @font.bold
454 @font.italic = descriptor.font.italic ? @font.italic
455 @font.smallCaps = descriptor.font.smallCaps ? @font.smallCaps
456 @font.underline = descriptor.font.underline ? @font.underline
457 @font.strikeThrough = descriptor.font.strikeThrough ? @font.strikeThrough
458
459 if descriptor.font.color?
460 @font.color.setFromArray(descriptor.font.color)
461
462 if descriptor.font.border?
463 @font.border = descriptor.font.border ? no
464 @font.borderSize = descriptor.font.borderSize ? 4
465 @font.borderColor.set(0, 0, 0, 255)
466 if descriptor.font.shadow?
467 @font.shadow = descriptor.font.shadow ? no
468 @font.shadowOffsetX = descriptor.font.shadowOffsetX ? 2
469 @font.shadowOffsetY = descriptor.font.shadowOffsetY ? 2
470 @font.shadowColor.setFromArray(descriptor.font.shadowColor)
471
472 if descriptor.font.outline?
473 @font.border = descriptor.font.outline ? no
474 @font.borderSize = descriptor.font.outline.size ? 4
475
476 if descriptor.font.outline.color?
477 @font.borderColor.setFromArray(descriptor.font.outline.color)
478 else
479 @font.borderColor.set(0, 0, 0, 255)
480
481
482 ###*
483 * Applies the style to a UI object.
484 *
485 * @method apply
486 * @param {ui.Object_UIElement} object - The UI object where the style should be applied to.
487 ###
488 apply: (object) ->
489 if not object.activeStyles.contains(this)
490 object.activeStyles.push(this)
491 if @font then object.font?.set(@font)
492 if @color then object.color.set(@color)
493 if @tone then object.tone?.set(@tone)
494 if @image then object.image = @image
495 if @anchor then object.anchor.set(@anchor.x, @anchor.y)
496 if @zoom then object.zoom.set(@zoom.x, @zoom.y)
497 if @padding then object.padding.setFromObject(@padding)
498 if @margin then object.margin.setFromObject(@margin)
499 if @opacity >= 0 then object.opacity = @opacity
500 if @alignment >= 0 then object.alignment = @alignment
501 if @frameThickness >= 0 then object.frameThickness = @frameThickness
502 if @frameCornerSize >= 0 then object.frameCornerSize = @frameCornerSize
503 if @mask then object.mask.set(@mask)
504 if @zIndex >= 0 then object.zIndex = @zIndex
505 if @alignmentX >= 0 then object.alignmentX = @alignmentX
506 if @alignmentY >= 0 then object.alignmentY = @alignmentY
507 if @resizable? then object.resizable = @resizable
508
509 @applyLooping(object)
510 @applyAnimations(object)
511
512 ###*
513 * Applies the looping-data of the style to a UI object.
514 *
515 * @method applyLooping
516 * @param {ui.Object_UIElement} object - The UI object where the looping-data should be applied to.
517 * @protected
518 ###
519 applyLooping: (object) ->
520 if @looping
521 if !object.visual.looping
522 object.visual.dispose()
523 object.removeComponent(object.visual)
524 object.visual = new gs.Component_TilingSprite()
525 object.addComponent(object.visual)
526
527 object.visual.looping.vertical = @looping.vertical
528 object.visual.looping.horizontal = @looping.horizontal
529
530 ###*
531 * Applies the animation-data of the style to a UI object. This automatically adds an animation-handler
532 * component(ui.Component_AnimationHandler) with the id "animationHandler" to the UI object if not already exists.
533 *
534 * @method applyAnimations
535 * @param {ui.Object_UIElement} object - The UI object where the animation-data should be applied to.
536 * @protected
537 ###
538 applyAnimations: (object) ->
539 if @animations
540 object.animations = Object.deepCopy(@animations)
541 if !object.findComponentById("animationHandler")
542 object.animationExecutor = new ui.Component_AnimationExecutor()
543 object.addComponent(new ui.Component_AnimationHandler(), "animationHandler")
544 object.addComponent(object.animationExecutor, "animationExecutor")
545
546
547 ###*
548 * Reverts the changes from a UI object made by this style. However, this resets all styleable properties
549 * were set by this style. So it is necessary to apply all other styles again, but that is already handles in
550 * ui.Component_UIBehavior.
551 *
552 * @method revert
553 * @param {ui.Object_UIElement} object - The UI object where the style should be reverted.
554 ###
555 revert: (object) ->
556 activeStyles = object.activeStyles
557 if object.activeStyles.contains(this)
558 object.activeStyles.remove(this)
559
560 if @font then object.font.set(gs.Fonts.TEXT); (if s.font then object.font.set(s.font); break) for s in activeStyles by -1
561 if @color then object.color.set(Color.WHITE); (if s.color then object.color.set(s.color); break) for s in activeStyles by -1
562 if @tone then object.tone?.set(0, 0, 0, 0); (if s.tone then object.tone?.set(s.tone); break) for s in activeStyles by -1
563 if @image then object.image = null; (if s.image then object.image = s.image; break) for s in activeStyles by -1
564 if @anchor then object.anchor.set(0, 0); (if s.anchor then object.anchor.setFromObject(s.anchor); break) for s in activeStyles by -1
565 if @zoom then object.zoom.set(1.0, 1.0); (if s.zoom then object.zoom.setFromObject(s.zoom); break) for s in activeStyles by -1
566 if @padding then object.padding.set(0, 0, 0, 0); (if s.padding then object.padding.setFromObject(s.padding); break) for s in activeStyles by -1
567 if @margin then object.margin.set(0, 0, 0, 0); (if s.margin then object.margin.setFromObject(s.margin); break) for s in activeStyles by -1
568 if @opacity >= 0 then object.opacity = 255; (if s.opacity >= 0 then object.opacity = s.opacity; break) for s in activeStyles by -1
569 if @alignment >= 0 then object.alignment = 0; (if s.alignment >= 0 then object.alignment = s.alignment; break) for s in activeStyles by -1
570 if @frameCornerSize >= 0 then object.frameCornerSize = 16; (if s.frameCornerSize >= 0 then object.frameCornerSize = s.frameCornerSize; break) for s in activeStyles by -1
571 if @frameThickness >= 0 then object.frameThickness = 16; (if s.frameThickness >= 0 then object.frameThickness = s.frameThickness; break) for s in activeStyles by -1
572 if @mask then object.mask.set(null); (if s.mask then object.mask.set(s.font); break) for s in activeStyles by -1
573 if @zIndex >= 0 then object.zIndex = 0; (if s.zIndex >= 0 then object.zIndex = s.zIndex; break) for s in activeStyles by -1
574 if @alignmentX >= 0 then object.alignmentX = 0; (if s.alignmentX >= 0 then object.alignmentX = s.alignmentX; break) for s in activeStyles by -1
575 if @alignmentY >= 0 then object.alignmentY = 0; (if s.alignmentY >= 0 then object.alignmentY = s.alignmentY; break) for s in activeStyles by -1
576 if @resizable? then object.resizable = no; (if s.resizable? then object.resizable = s.resizable; break) for s in activeStyles by -1
577
578 @revertAnimations(object)
579 @revertLooping(object)
580
581 ###*
582 * Reverts the animation-data changes applied to a UI object by this style.
583 *
584 * @method revertAnimations
585 * @param {ui.Object_UIElement} object - The UI object where the animation-data changes should be reverted.
586 ###
587 revertAnimations: (object) ->
588 activeStyles = object.activeStyles
589 if @animations
590 object.animations = null;
591 for s in activeStyles by -1
592 if s.animations
593 object.animations = Object.deepCopy(s.animations)
594 if !object.findComponentById("animationHandler")
595 object.addComponent(new ui.Component_AnimationHandler(), "animationHandler")
596
597 ###*
598 * Reverts the looping-data changes applied to a UI object by this style.
599 *
600 * @method revertLooping
601 * @param {ui.Object_UIElement} object - The UI object where the looping-data changes should be reverted.
602 ###
603 revertLooping: (object) ->
604 activeStyles = object.activeStyles
605 if @looping
606 object.visual.looping.vertical = no
607 object.visual.looping.horizontal = no
608 for s in activeStyles by -1
609 if s.looping
610 if !object.visual.looping
611 object.visual.dispose()
612 object.removeComponent(object.visual)
613 object.visual = new gs.Component_TilingSprite()
614 object.addComponent(object.visual)
615
616 object.visual.looping.vertical = s.looping.vertical
617 object.visual.looping.horizontal = s.looping.horizontal
618
619ui.Style = Style
620
621class UIManager
622 ###*
623 * Handles the creation of In Game UI elements. For more information about
624 * In-Game UI see help file.
625 *
626 * @module ui
627 * @class UIManager
628 * @memberof ui
629 * @constructor
630 ###
631 constructor: ->
632 ###*
633 * Stores all registered UI layouts by name/id.
634 * @property layouts
635 * @type Object
636 ###
637 @layouts = {}
638
639 ###*
640 * Stores all registered UI styles by name/id.
641 * @property styles
642 * @type Object
643 ###
644 @styles = {}
645
646 ###*
647 * Stores all UI styles by number id.
648 * @property stylesById
649 * @type ui.Style[]
650 ###
651 @stylesById = new Array()
652
653 ###*
654 * Stores all UI styles by style-name.
655 * @property stylesByName
656 * @type Object
657 ###
658 @stylesByName = {}
659
660 ###*
661 * Stores all registered custom UI types/templates by name/id.
662 * @property customTypes
663 * @type Object
664 ###
665 @customTypes = {}
666
667 ###*
668 * Stores all registered UI controllers by name/id.
669 * @property customTypes
670 * @type Object
671 ###
672 @controllers = {}
673
674 ###*
675 * Stores all registered UI data sources by name/id.
676 * @property customTypes
677 * @type Object
678 ###
679 @dataSources = {}
680
681 ###*
682 * Mapping to table to map alignment names to number values.
683 * @property alignments
684 * @type Object
685 * @protected
686 ###
687 @alignments = { "left": 0, "top": 0, "center": 1, "bottom": 2, "right": 2, "0": 0, "1": 1, "2": 2 }
688
689 ###*
690 * Mapping to table to map blend-mode names to number values.
691 * @property blendModes
692 * @type Object
693 * @protected
694 ###
695 @blendModes = { "normal": 0, "add": 1, "sub": 2 }
696
697 ###*
698 * Mapping to table to map selector names to number values.
699 * @property selectors
700 * @type Object
701 ###
702 @selectors = { normal: 0, hover: 1, selected: 2, enabled: 3, focused: 4 }
703 @defaultPlaceholderParams = {}
704
705 ###*
706 * Sets up UI Manager, optimizes styles, etc.
707 *
708 * @method setup
709 ###
710 setup: ->
711 @setupStyles()
712
713 ###*
714 * Sets up the UI styles by wrapping them into ui.Style objects and optimizing the access.
715 *
716 * @method setupStyles
717 * @protected
718 ###
719 setupStyles: ->
720 id = 0
721 selectorMap = @selectors
722 for k of @styles
723 subs = k.split(" ")
724 selector = subs[0].split(":")
725
726 if selectorMap[selector[1]]
727 @stylesById[id] = new ui.Style(@styles[k], id, selectorMap[selector[1]])
728 else
729 @stylesById[id] = new ui.Style(@styles[k], id, 0)
730
731 if !@stylesByName[selector[0]]
732 @stylesByName[selector[0]] = []
733
734 @stylesByName[selector[0]].push(@stylesById[id])
735 @styles[k] = @stylesById[id]
736
737 id++
738
739 for k of @styles
740 subs = k.split(" ")
741 if subs.length > 1
742 @stylesByName[subs[1]].push(@styles[k])
743 @styles[k].target = @styles[k.split(":")[0]]?.id
744 #@styles[subs[1]].target = @styles[k].id
745 #@styles[k].target = @styles[subs[1]].id
746
747 return null
748
749 ###*
750 * Executes all placeholder formulas in the specified descriptor. The descriptor will be changed
751 * and placeholder formulas are replaced with their evaluated result value.
752 *
753 * @method executePlaceholderFormulas
754 * @param {Object} descriptor - The descriptor.
755 * @param {Object} params - Object containing the placeholder params.
756 * @protected
757 ###
758 executePlaceholderFormulas: (descriptor, id, params) ->
759 return if not descriptor?
760 keys = Object.keys(descriptor)
761
762 for k in keys
763 v = descriptor[k]
764 if v?
765 if v instanceof Array
766 for i, c in v
767 if i?
768 if typeof i == "object"
769 @executePlaceholderFormulas(i, id, params)
770 else if c != "exec" and typeof i == "function"
771 window.p = params || @defaultPlaceholderParams
772 window.d = descriptor
773 v[c] = i()
774 else if typeof v == "object"
775 @executePlaceholderFormulas(v, id, params)
776 else if k != "exec_" and typeof v == "function"
777 window.p = params || @defaultPlaceholderParams
778 window.d = descriptor
779 descriptor[k] = v()
780 return null
781
782 ###*
783 * Creates a calculation for a specified expression.
784 *
785 * @method createCalcFunction
786 * @param {String} expression - The expression to create a calculation function for.
787 * @return {Function} The calculation function.
788 * @protected
789 ###
790 createCalcFunction: (expression) ->
791 expression = expression.replace(/([0-9]+)%/gm, "($1 / 100 * v)")
792 return eval("(function(v){ return " + expression + "})")
793
794 ###*
795 * Creates an object from the specified object type. The type has the format
796 * <namespace>.<typename> like vn.Component_Hotspot.
797 *
798 * @method createObject
799 * @param {String} type - The type name.
800 * @return {Object} The created object.
801 * @protected
802 ###
803 createObject: (type) ->
804 subs = type.split(".")
805 return new window[subs[0]][subs[1]]()
806
807 ###*
808 * Creates an UI object from a specified UI descriptor.
809 *
810 * @method createFromDescriptor
811 * @param {Object} descriptor - The UI object descriptor.
812 * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).
813 * @return {gs.Object_UIElement} The created UI object.
814 ###
815 createFromDescriptor: (descriptor, parent) ->
816 control = null
817
818 for k of @controllers
819 if @controllers[k].type?
820 @controllers[k] = @createObject(@controllers[k].type)
821
822 @_createFromDescriptor(descriptor, parent)
823
824
825 ###*
826 * Creates an image button UI object.
827 *
828 * @method createImageButton
829 * @param {Object} descriptor - The UI object descriptor.
830 * @return {gs.Object_UIElement} The created image button UI object.
831 ###
832 createImageButton: (descriptor) ->
833 control = new ui.Object_Hotspot(descriptor.image, descriptor.imageHandling)
834
835 control.behavior.sound = descriptor.sound
836 control.behavior.sounds = descriptor.sounds
837 control.image = descriptor.image
838 control.images = descriptor.images
839 if descriptor.imageFolder?
840 control.imageFolder = descriptor.imageFolder
841
842 if descriptor.looping?
843 control.visual.dispose()
844 control.removeComponent(control.visual)
845 control.visual = new gs.Component_TilingSprite()
846 control.addComponent(control.visual)
847
848 control.visual.looping.vertical = descriptor.looping.vertical
849 control.visual.looping.horizontal = descriptor.looping.horizontal
850 if descriptor.color?
851 control.color = Color.fromArray(descriptor.color)
852
853 return control
854
855 ###*
856 * Creates an image UI object.
857 *
858 * @method createImage
859 * @param {Object} descriptor - The UI object descriptor.
860 * @return {gs.Object_UIElement} The created image button UI object.
861 ###
862 createImage: (descriptor) ->
863 control = new ui.Object_Image(descriptor.image, descriptor.imageHandling)
864
865 if descriptor.imageFolder?
866 control.imageFolder = descriptor.imageFolder
867
868 if descriptor.looping?
869 control.visual.dispose()
870 control.removeComponent(control.visual)
871 control.visual = new gs.Component_TilingSprite()
872 control.addComponent(control.visual)
873
874 control.visual.looping.vertical = descriptor.looping.vertical
875 control.visual.looping.horizontal = descriptor.looping.horizontal
876 if descriptor.color?
877 control.color = Color.fromArray(descriptor.color)
878
879 return control
880
881 ###*
882 * Creates an image map UI object.
883 *
884 * @method createImageMap
885 * @param {Object} descriptor - The UI object descriptor.
886 * @return {gs.Object_UIElement} The created image button UI object.
887 ###
888 createImageMap: (descriptor) ->
889 control = new ui.Object_ImageMap()
890 control.hotspots = (descriptor.hotspots||[]).select (h) ->
891 { x: h.rect[0], y: h.rect[1], size: { width: h.rect[2], height: h.rect[3] }, data: { action: 3, actions: h.actions } }
892 control.images = descriptor.images
893 control.insertComponent(new ui.Component_ActionHandler(), 1, "actionHandler")
894 control.target = SceneManager.scene.behavior
895 control.visual.variableContext = new gs.InterpreterContext(SceneManager.scene.layoutName, SceneManager.scene)
896
897 return control
898
899 ###*
900 * Creates a video UI object.
901 *
902 * @method createVideo
903 * @param {Object} descriptor - The UI object descriptor.
904 * @return {gs.Object_UIElement} The created image button UI object.
905 ###
906 createVideo: (descriptor) ->
907 control = new ui.Object_Video()
908 control.video = descriptor.video
909 control.loop = descriptor.loop ? yes
910
911 return control
912
913
914 ###*
915 * Creates a panel UI object.
916 *
917 * @method createPanel
918 * @param {Object} descriptor - The UI object descriptor.
919 * @return {gs.Object_UIElement} The created image button UI object.
920 ###
921 createPanel: (descriptor) ->
922 control = new ui.Object_Panel()
923 control.modal = descriptor.modal ? no
924 if descriptor.color?
925 control.color = Color.fromArray(descriptor.color)
926
927 return control
928
929 ###*
930 * Creates a frame UI object.
931 *
932 * @method createFrame
933 * @param {Object} descriptor - The UI object descriptor.
934 * @return {gs.Object_UIElement} The created image button UI object.
935 ###
936 createFrame: (descriptor) ->
937 control = new ui.Object_Frame(descriptor.frameSkin)
938 control.frameThickness = descriptor.frameThickness || 16
939 control.frameCornerSize = descriptor.frameCornerSize || 16
940 control.image = descriptor.image
941 control.images = descriptor.images
942
943 return control
944
945 ###*
946 * Creates a three-part image UI object.
947 *
948 * @method createThreePartImage
949 * @param {Object} descriptor - The UI object descriptor.
950 * @return {gs.Object_UIElement} The created image button UI object.
951 ###
952 createThreePartImage: (descriptor) ->
953 control = new ui.Object_ThreePartImage(descriptor.frameSkin)
954 control.firstPartSize = descriptor.firstPartSize || 16
955 control.middlePartSize = descriptor.middlePartSize || 1
956 control.lastPartSize = descriptor.lastPartSize || 16
957 control.image = descriptor.image
958 control.images = descriptor.images
959
960 return control
961
962 ###*
963 * Creates a text UI object.
964 *
965 * @method createText
966 * @param {Object} descriptor - The UI object descriptor.
967 * @return {gs.Object_UIElement} The created image button UI object.
968 ###
969 createText: (descriptor) ->
970 control = new ui.Object_Text()
971 control.text = lcs(descriptor.text)
972 control.sizeToFit = descriptor.sizeToFit
973 control.formatting = descriptor.formatting
974 control.wordWrap = descriptor.wordWrap ? no
975 control.behavior.format = descriptor.format
976 if descriptor.textPadding
977 control.behavior.padding = ui.Space.fromArray(descriptor.textPadding)
978 if descriptor.resolvePlaceholders?
979 control.resolvePlaceholders = descriptor.resolvePlaceholders
980 if descriptor.color?
981 control.color = Color.fromArray(descriptor.color)
982
983 return control
984
985 ###*
986 * Creates a free-layout UI object.
987 *
988 * @method createFreeLayout
989 * @param {Object} descriptor - The UI object descriptor.
990 * @return {gs.Object_UIElement} The created image button UI object.
991 ###
992 createFreeLayout: (descriptor) ->
993 if descriptor.frame?
994 control = new ui.Object_FreeLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1)
995 else
996 control = new ui.Object_FreeLayout(0, 0, 1, 1)
997 control.sizeToFit = descriptor.sizeToFit
998
999 return control
1000
1001 ###*
1002 * Creates a stack-layout UI object.
1003 *
1004 * @method createStackLayout
1005 * @param {Object} descriptor - The UI object descriptor.
1006 * @return {gs.Object_UIElement} The created image button UI object.
1007 ###
1008 createStackLayout: (descriptor) ->
1009 if descriptor.frame?
1010 control = new ui.Object_StackLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)
1011 else
1012 control = new ui.Object_StackLayout(0, 0, 1, 1, descriptor.orientation)
1013 control.sizeToFit = descriptor.sizeToFit
1014
1015 return control
1016
1017 ###*
1018 * Creates a spread-layout UI object.
1019 *
1020 * @method createSpreadLayout
1021 * @param {Object} descriptor - The UI object descriptor.
1022 * @return {gs.Object_UIElement} The created image button UI object.
1023 ###
1024 createSpreadLayout: (descriptor) ->
1025 if descriptor.frame?
1026 control = new ui.Object_SpreadLayout(descriptor.frame[0] || 0, descriptor.frame[1] || 0, descriptor.frame[2] || 1, descriptor.frame[3] || 1, descriptor.orientation)
1027 else
1028 control = new ui.Object_SpreadLayout(0, 0, 1, 1, descriptor.orientation)
1029
1030 return control
1031
1032 ###*
1033 * Creates a grid-layout UI object.
1034 *
1035 * @method createGridLayout
1036 * @param {Object} descriptor - The UI object descriptor.
1037 * @return {gs.Object_UIElement} The created image button UI object.
1038 ###
1039 createGridLayout: (descriptor) ->
1040 if descriptor.frame?
1041 control = new ui.Object_GridLayout(descriptor.frame[0], descriptor.frame[1], descriptor.frame[2], descriptor.frame[3], descriptor.rows, descriptor.columns, descriptor.template)
1042 else
1043 control = new ui.Object_GridLayout(0, 0, 1, 1, descriptor.rows, descriptor.columns, descriptor.template)
1044 control.cellSpacing = descriptor.cellSpacing || [0, 0, 0, 0]
1045 control.sizeToFit = descriptor.sizeToFit
1046
1047 return control
1048
1049 ###*
1050 * Creates a message UI object.
1051 *
1052 * @method createMessage
1053 * @param {Object} descriptor - The UI object descriptor.
1054 * @return {gs.Object_UIElement} The created image button UI object.
1055 ###
1056 createMessage: (descriptor) ->
1057 control = new ui.Object_Message()
1058
1059 return control
1060
1061 ###*
1062 * Creates a data-grid UI object.
1063 *
1064 * @method createDataGrid
1065 * @param {Object} descriptor - The UI object descriptor.
1066 * @return {gs.Object_UIElement} The created image button UI object.
1067 ###
1068 createDataGrid: (descriptor) ->
1069 control = new ui.Object_DataGrid(descriptor)
1070
1071 return control
1072
1073 ###*
1074 * Creates an UI object depending on the object-type of the specified UI descriptor.
1075 *
1076 * @method createControl
1077 * @param {Object} descriptor - The UI object descriptor.
1078 * @return {gs.Object_UIElement} The created UI object.
1079 * @protected
1080 ###
1081 createControl: (descriptor) ->
1082 control = null
1083
1084 switch descriptor.type
1085 when "ui.ImageButton"
1086 control = @createImageButton(descriptor)
1087 when "ui.Image"
1088 control = @createImage(descriptor)
1089 when "ui.ImageMap"
1090 control = @createImageMap(descriptor)
1091 when "ui.Video"
1092 control = @createVideo(descriptor)
1093 when "ui.Panel"
1094 control = @createPanel(descriptor)
1095 when "ui.Frame"
1096 control = @createFrame(descriptor)
1097 when "ui.ThreePartImage"
1098 control = @createThreePartImage(descriptor)
1099 when "ui.Text"
1100 control = @createText(descriptor)
1101 when "ui.Message"
1102 control = @createMessage(descriptor)
1103 when "ui.DataGrid"
1104 control = @createDataGrid(descriptor)
1105 when "ui.FreeLayout"
1106 control = @createFreeLayout(descriptor)
1107 when "ui.StackLayout"
1108 control = @createStackLayout(descriptor)
1109 when "ui.SpreadLayout"
1110 control = @createSpreadLayout(descriptor)
1111 when "ui.GridLayout"
1112 control = @createGridLayout(descriptor)
1113
1114 return control
1115
1116
1117 createLayoutRect: (frame, control) ->
1118 if !control.layoutRect
1119 control.layoutRect = new ui.LayoutRect()
1120 control.layoutRect.set(0, 0, 0, 0)
1121
1122 if frame?
1123 if frame[0]?.length?
1124 control.layoutRect.x = @createCalcFunction(frame[0])
1125 control.dstRect.x = 0
1126 else
1127 control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)
1128
1129 if frame[1]?.length?
1130 control.layoutRect.y = @createCalcFunction(frame[1])
1131 control.dstRect.y = 0
1132 else
1133 control.dstRect.y = (frame[1] ? control.dstRect.y)
1134
1135 if frame[2]?.length?
1136 control.layoutRect.width = @createCalcFunction(frame[2])
1137 control.dstRect.width = 1
1138 else
1139 control.dstRect.width = (frame[2] ? control.dstRect.width)
1140
1141 if frame[3]?.length?
1142 control.layoutRect.height = @createCalcFunction(frame[3])
1143 control.dstRect.height = 1
1144 else
1145 control.dstRect.height = (frame[3] ? control.dstRect.height)
1146
1147
1148 ###*
1149 * Adds the styles defined in an array of style-names to the specified control.
1150 *
1151 * @method addControlStyles
1152 * @param {Object} control - The control to add the styles to.
1153 * @param {string[]} styles - Array of style-names to add.
1154 ###
1155 addControlStyles: (control, styles) ->
1156 for styleName in styles
1157 if @stylesByName[styleName]?
1158 for style in @stylesByName[styleName]
1159 control.styles.push(style)
1160 if style.target == -1 and style.selector == 0
1161 style.apply(control)
1162 ###*
1163 * Creates an UI object from a specified UI descriptor. This method is called
1164 * recursively for all child-descriptors.
1165 *
1166 * @method createControlFromDescriptor
1167 * @param {Object} descriptor - The UI object descriptor.
1168 * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).
1169 * @param {number} index - The index.
1170 * @return {gs.Object_UIElement} The created UI object.
1171 * @protected
1172 ###
1173 createControlFromDescriptor: (descriptor, parent, index) ->
1174 control = null
1175
1176 if descriptor.style?
1177 descriptor.styles = [descriptor.style]
1178 delete descriptor.style
1179
1180 descriptor = Object.deepCopy(descriptor)
1181 @executePlaceholderFormulas(descriptor, descriptor.id, descriptor.params)
1182
1183 control = @createControl(descriptor)
1184
1185 if not control?
1186 type = Object.deepCopy(@customTypes[descriptor.type])
1187
1188 @executePlaceholderFormulas(type, descriptor.id, descriptor.params)
1189
1190 typeName = type.type
1191 customFields = type.customFields
1192 bindings = type.bindings
1193 formulas = type.formulas
1194 actions = type.actions
1195 if type.style?
1196 type.styles = [type.style]
1197 type.style = null
1198
1199 Object.mixin(type, descriptor)
1200 if customFields? then Object.mixin(type.customFields, customFields)
1201 if bindings? and bindings != type.bindings then type.bindings = type.bindings.concat(bindings)
1202 if formulas? and formulas != type.formulas then type.formulas = type.formulas.concat(formulas)
1203 if actions? and actions != type.actions then type.actions = actions.concat(type.actions)
1204 type.type = typeName
1205
1206 return @createControlFromDescriptor(type, parent)
1207 else if parent?
1208 parent.addObject(control)
1209 control.index = index
1210 else
1211 gs.ObjectManager.current.addObject(control)
1212
1213 control.ui = new ui.Component_UIBehavior()
1214 control.addComponent(control.ui)
1215
1216
1217
1218 control.params = descriptor.params
1219
1220 if descriptor.updateBehavior == "continuous"
1221 control.updateBehavior = ui.UpdateBehavior.CONTINUOUS
1222
1223 if descriptor.inheritProperties
1224 control.inheritProperties = yes
1225
1226 if descriptor.font?
1227 control.font = new Font(descriptor.font.name, descriptor.font.size)
1228 control.font.bold = descriptor.font.bold ? control.font.bold
1229 control.font.italic = descriptor.font.italic ? control.font.italic
1230 control.font.smallCaps = descriptor.font.smallCaps ? control.font.smallCaps
1231 control.font.underline = descriptor.font.underline ? control.font.underline
1232 control.font.strikeThrough = descriptor.font.strikeThrough ? control.font.strikeThrough
1233
1234 if descriptor.font.color?
1235 control.font.color = Color.fromArray(descriptor.font.color)
1236 if descriptor.font.border?
1237 control.font.border = descriptor.font.border ? no
1238 control.font.borderSize = descriptor.font.borderSize ? 4
1239 #if descriptor.font.border.color
1240 # control.font.borderColor = Color.fromArray(descriptor.font.border.color)
1241 control.font.borderColor = new Color(0, 0, 0)
1242
1243 if descriptor.font.outline?
1244 control.font.border = descriptor.font.outline ? no
1245 control.font.borderSize = descriptor.font.outline.size ? 4
1246
1247 if descriptor.font.outline.color?
1248 control.font.borderColor = Color.fromArray(descriptor.font.outline.color)
1249 else
1250 control.font.borderColor = new Color(0, 0, 0)
1251
1252 if descriptor.components?
1253 for c in descriptor.components
1254 m = c.module || "gs"
1255 component = new window[m][c.type](c.params)
1256 control.addComponent(component, c.id)
1257 control[c.id] = component
1258 #component.setup?()
1259
1260 control.focusable = descriptor.focusable ? control.focusable
1261 if descriptor.nextKeyObject
1262 control.ui.nextKeyObjectId = descriptor.nextKeyObject
1263
1264 if descriptor.initialFocus
1265 control.ui.focus()
1266
1267 actions = Object.deepCopy(if descriptor.action? then [descriptor.action] else descriptor.actions)
1268 if actions?
1269 for action in actions
1270 if action?
1271 action.event = action.event ? "onAccept"
1272 if not action.target?
1273 target = if @controllers? then @controllers[descriptor.target] else controller
1274 action.target = target || SceneManager.scene.behavior
1275
1276 control.actions = actions
1277
1278 if(!control.findComponentById("actionHandler"))
1279 control.insertComponent(new ui.Component_ActionHandler(), 1, "actionHandler")
1280
1281 if descriptor.id?
1282 control.id = descriptor.id
1283 gs.ObjectManager.current.setObjectById(control, control.id)
1284
1285 control.descriptor = descriptor
1286 control.layoutRect = new Rect()
1287 control.layoutRect.set(0, 0, 0, 0)
1288 if descriptor.frame?
1289 if descriptor.frame[0]?.length?
1290 control.layoutRect.x = @createCalcFunction(descriptor.frame[0])
1291 control.dstRect.x = 0
1292 else
1293 control.dstRect.x = (descriptor.frame[0] ? control.dstRect.x)
1294
1295 if descriptor.frame[1]?.length?
1296 control.layoutRect.y = @createCalcFunction(descriptor.frame[1])
1297 control.dstRect.y = 0
1298 else
1299 control.dstRect.y = (descriptor.frame[1] ? control.dstRect.y)
1300
1301 if descriptor.frame[2]?.length?
1302 control.layoutRect.width = @createCalcFunction(descriptor.frame[2])
1303 control.dstRect.width = 1
1304 else
1305 control.dstRect.width = (descriptor.frame[2] ? control.dstRect.width)
1306
1307 if descriptor.frame[3]?.length?
1308 control.layoutRect.height = @createCalcFunction(descriptor.frame[3]) #parseInt(descriptor.frame[3].split("%")[0])
1309 control.dstRect.height = 1
1310 else
1311 control.dstRect.height = (descriptor.frame[3] ? control.dstRect.height)
1312
1313 if descriptor.sizeToParent?
1314 control.sizeToParent = descriptor.sizeToParent
1315
1316 if descriptor.blendMode?
1317 control.blendMode = @blendModes[descriptor.blendMode]
1318
1319 if descriptor.anchor?
1320 control.anchor.set(descriptor.anchor[0], descriptor.anchor[1])
1321
1322
1323 control.opacity = descriptor.opacity ? 255
1324 if descriptor.minimumSize?
1325 control.minimumSize = { width: descriptor.minimumSize[0], height: descriptor.minimumSize[1] }
1326
1327 if descriptor.resizable? then control.resizable = descriptor.resizable
1328 if descriptor.scrollable? then control.scrollable = descriptor.scrollable
1329 if descriptor.fixedSize? then control.fixedSize = descriptor.fixedSize
1330 if descriptor.draggable?
1331 control.draggable = descriptor.draggable
1332 control.draggable.step = 0
1333 if control.draggable.rect?
1334 control.draggable.rect = Rect.fromArray(control.draggable.rect)
1335 control.addComponent(new ui.Component_Draggable())
1336
1337 if descriptor.bindings?
1338 control.bindings = descriptor.bindings
1339 control.insertComponent(new ui.Component_BindingHandler(), 0)
1340
1341 if descriptor.formulas?
1342 control.formulas = descriptor.formulas
1343 control.insertComponent(new ui.Component_FormulaHandler(), 0)
1344
1345 control.dataField = descriptor.dataField
1346 control.enabled = descriptor.enabled ? yes
1347 if descriptor.selectable? then control.selectable = descriptor.selectable
1348 if descriptor.group?
1349 control.group = descriptor.group
1350 gs.ObjectManager.current.addToGroup(control, control.group)
1351
1352 if descriptor.customFields?
1353 control.customFields = Object.deepCopy(descriptor.customFields)
1354
1355 if descriptor.margin?
1356 control.margin.left = descriptor.margin[0]
1357 control.margin.top = descriptor.margin[1]
1358 control.margin.right = descriptor.margin[2]
1359 control.margin.bottom = descriptor.margin[3]
1360
1361 if descriptor.padding?
1362 control.padding.left = descriptor.padding[0]
1363 control.padding.top = descriptor.padding[1]
1364 control.padding.right = descriptor.padding[2]
1365 control.padding.bottom = descriptor.padding[3]
1366
1367 if descriptor.alignment?
1368 control.alignment = @alignments[descriptor.alignment]
1369
1370 control.alignmentY = @alignments[descriptor.alignmentY || 0]
1371 control.alignmentX = @alignments[descriptor.alignmentX || 0]
1372 control.zIndex = descriptor.zIndex || 0
1373 control.order = descriptor.order || 0
1374 control.chainOrder = (descriptor.chainOrder ? descriptor.zOrder) + (parent?.chainOrder || 0)
1375 if descriptor.zoom?
1376 control.zoom = x: descriptor.zoom[0] / 100, y: descriptor.zoom[1] / 100
1377 #control.dataFields = dataFields
1378 #control.controllers = @controllers
1379 #control.controller = controller
1380
1381 if descriptor.visible?
1382 control.visible = descriptor.visible
1383 if descriptor.clipRect
1384 control.clipRect = new Rect(control.dstRect.x, control.dstRect.y, control.dstRect.width, control.dstRect.height)
1385
1386 if descriptor.styles?
1387 @addControlStyles(control, descriptor.styles)
1388
1389
1390 if descriptor.template?
1391 control.behavior.managementMode = ui.LayoutManagementMode.fromString(descriptor.managementMode)
1392 data = ui.Component_FormulaHandler.fieldValue(control, control.dataField) #control.dataFields[control.dataField]
1393 isNumber = typeof data == "number"
1394 if data?
1395 for i in [0...(data.length ? data)]
1396 if data[i]? or isNumber
1397 valid = yes
1398 if descriptor.dataFilter? and not isNumber
1399 valid = ui.Component_Handler.checkCondition(data[i], descriptor.dataFilter)
1400 if valid or isNumber
1401 child = @createControlFromDescriptor(descriptor.template, control, i)
1402 #child.dataFields = control.dataFields
1403
1404 if data[i]?.dstRect
1405 child.dstRect = ui.UIElementRectangle.fromRect(child, data[i].dstRect)
1406 if (not child.clipRect?) and control.clipRect?
1407 child.clipRect = control.clipRect
1408 #child.parent = control
1409 control.addObject(child)
1410 child.index = i
1411 child.order = (data.length ? data) - i
1412 control.controls.push(child)
1413
1414
1415 if descriptor.controls and descriptor.controls.exec
1416 controls = ui.Component_FormulaHandler.fieldValue(descriptor, descriptor.controls)
1417 else
1418 controls = descriptor.controls
1419
1420 if controls?
1421 for item, i in controls
1422 childControl = @_createFromDescriptor(item, control, i)
1423 if (not childControl.clipRect?) and control.clipRect?
1424 childControl.clipRect = control.clipRect
1425 childControl.index = i
1426 childControl.origin.x = control.origin.x + control.dstRect.x
1427 childControl.origin.y = control.origin.y + control.dstRect.y
1428 #childControl.parent = control
1429 control.addObject(childControl)
1430 control.controls.push(childControl)
1431
1432 if control.styles and control.parentsByStyle
1433 #for style in control.styles
1434
1435 parent = control.parent
1436 while parent
1437 if parent.styles
1438 for style in parent.styles
1439 if !control.parentsByStyle[style.id]
1440 control.parentsByStyle[style.id] = []
1441 control.parentsByStyle[style.id].push(parent)
1442
1443 #while parent
1444 #if parent.controlsByStyle
1445 # if(!parent.controlsByStyle[style.id])
1446 # parent.controlsByStyle[style.id] = []
1447 # parent.controlsByStyle[style.id].push(control)
1448 # if control.parentsByStyle
1449 # if !control.parentsByStyle[style.id]
1450 # control.parentsByStyle[style.id] = []
1451 # control.parentsByStyle[style.id].push(parent)
1452 parent = parent.parent
1453
1454 if descriptor.animations?
1455 control.animations = Object.deepCopy(descriptor.animations)
1456 control.animationExecutor = new ui.Component_AnimationExecutor()
1457 control.addComponent(control.animationExecutor)
1458 control.addComponent(new ui.Component_AnimationHandler())
1459
1460 control.ui.updateStyle()
1461 control.setup()
1462
1463 return control
1464
1465 ###*
1466 * Creates an UI object from a specified UI descriptor.
1467 *
1468 * @method _createFromDescriptor
1469 * @param {Object} descriptor - The UI object descriptor.
1470 * @param {gs.Object_UIElement} parent - The UI parent object. (A layout for example).
1471 * @return {gs.Object_UIElement} The created UI object.
1472 * @protected
1473 ###
1474 _createFromDescriptor: (descriptor, parent, index) ->
1475 control = @createControlFromDescriptor(descriptor, parent, index)
1476
1477 if descriptor.controller?
1478 controller = @controllers[descriptor.controller]
1479 control.controller = controller
1480 control.addComponent(controller)
1481
1482 return control
1483
1484 createLayoutFromDescriptor: (descriptor, parent, index) ->
1485 @_createFromDescriptor(descriptor, parent, index)
1486
1487
1488
1489Graphics.width = $PARAMS.resolution.width
1490Graphics.height = $PARAMS.resolution.height
1491ui.UiFactory = new UIManager()
1492ui.UIManager = ui.UiFactory