Ext.ux.Accordion extension class code:
1 // vim: ts=2:sw=2:nu:fdc=4:nospell
2
3 // Create user extensions namespace (Ext.ux)
4 Ext.namespace('Ext.ux');
5
6 /**
7 * Ext.ux.Accordion Extension Class
8 *
9 * @author Ing. Jozef Sakalos
10 * @version $Id: Ext.ux.Accordion.js 152 2007-08-21 17:46:03Z jozo $
11 *
12 * @class Ext.ux.Accordion
13 * @extends Ext.ContentPanel
14 * @constructor
15 * @param {String/HTMLElement/Element} el The container element for this panel
16 * @param {String/Object} config A string to set only the title or a config object
17 * @cfg {Boolean} animate global animation flag for all panels. (defaults to true)
18 * @cfg {Boolean} boxWrap set to true to wrap wrapEl the body is child of (defaults to false)
19 * @cfg {Boolean} draggable set to false to disallow panels dragging (defaults to true)
20 * @cfg {Boolean} fitHeight set to true if you use fixed height dock
21 * @cfg {Boolean} forceOrder set to true if to disable reordering of panels (defaults to false)
22 * @cfg {Boolean} independent true to make panels independent (defaults to false)
23 * @cfg {Integer} initialHeight Initial height to set box to (defaults to 0)
24 * @cfg {Boolean} keepState Set to false to exclude this accordion from state management (defaults to true)
25 * @cfg {Boolean} monitorWindowResize if true panels are moved to
26 * viewport if window is small (defaults to true)
27 * @cfg {Boolean} resizable global resizable flag for all panels (defaults to true)
28 * @cfg {Boolean} undockable true to allow undocking of panels (defaults to true)
29 * @cfg {Boolean} useShadow global useShadow flag for all panels. (defaults to true)
30 * @cfg {Element/HTMLElement/String} wrapEl Element to wrap with nice surrounding
31 */
32 Ext.ux.Accordion = function(el, config) {
33
34 // call parent constructor
35 Ext.ux.Accordion.superclass.constructor.call(this, el, config);
36
37 // create collection for panels
38 this.items = new Ext.util.MixedCollection();
39
40 // assume no panel is expanded
41 this.expanded = null;
42
43 // {{{
44 // install event handlers
45 this.on({
46
47 // {{{
48 // runs before expansion. Triggered by panel's beforeexpand event
49 beforeexpand: {
50 scope: this
51 , fn: function(panel) {
52 // raise panel above others
53 if(!panel.docked) {
54 this.raise(panel);
55 }
56
57 // set fixed height
58 panel.autoSize();
59 // var panelBodyHeight;
60 // if(this.fitHeight && panel.docked) {
61 // panelBodyHeight = this.getPanelBodyHeight();
62 // if(panelBodyHeight) {
63 // panel.body.setHeight(panelBodyHeight);
64 // }
65 // }
66
67 if(panel.docked) {
68 this.expandCount++;
69 this.expanding = true;
70 // this.setDockScroll(false);
71 }
72
73 // don't collapse others if independent or not docked
74 if(this.independent || !panel.docked) {
75 return this;
76 }
77
78 // collapse expanded panel
79 if(this.expanded && this.expanded.docked) {
80 this.expanded.collapse();
81 }
82
83 // remember this panel as expanded
84 this.expanded = panel;
85 }}
86 // }}}
87 // {{{
88 // runs before panel collapses. Triggered by panel's beforecollapse event
89 , beforecollapse: {
90 scope: this
91 , fn: function(panel) {
92
93 // raise panel if not docked
94 if(!panel.docked) {
95 this.raise(panel);
96 }
97 return this;
98 }}
99 // }}}
100 // {{{
101 // runs on when panel expands (before animation). Triggered by panel's expand event
102 , expand: {
103 scope: this
104 , fn: function(panel) {
105 if(this.hideOtherOnExpand) {
106 this.hideOther(panel);
107 }
108 this.fireEvent('panelexpand', panel);
109 }}
110 // }}}
111 // {{{
112 // runs on when panel collapses (before animation). Triggered by panel's collapse event
113 , collapse: {
114 scope: this
115 , fn: function(panel) {
116 this.fireEvent('panelcollapse', panel);
117 }}
118 // }}}
119 // {{{
120 // runs on when animation is completed. Triggered by panel's animationcompleted event
121 , animationcompleted: {
122 scope: this
123 , fn: function(panel) {
124 var box = panel.el.getBox();
125 this.expandCount = (this.expandCount && this.expanding) ? --this.expandCount : 0;
126 if((0 === this.expandCount) && this.expanding) {
127 // this.setDockScroll(true);
128 this.expanding = false;
129 }
130 if(this.hideOtherOnExpand) {
131 if(panel.collapsed && panel.docked) {
132 this.showOther(panel);
133 }
134 // else if(panel.docked) {
135 // this.hideOther(panel);
136 // }
137 }
138 // this.fireEvent('panelbox', panel, box);
139 }}
140 // }}}
141 // {{{
142 // runs when panel is pinned. Triggered by panel's pinned event
143 , pinned: {
144 scope: this
145 , fn: function(panel, pinned) {
146 if(!pinned) {
147 if(panel.collapseOnUnpin) {
148 panel.collapse();
149 }
150 else if(!this.independent) {
151 this.items.each(function(p) {
152 if(p !== panel && p.docked && !p.pinned) {
153 p.collapse();
154 }
155 });
156 this.expanded = panel;
157 }
158 }
159 if(this.hideOtherOnExpand) {
160 if(panel.docked && pinned) {
161 this.showOther(panel);
162 }
163 }
164 this.fireEvent('panelpinned', panel, pinned);
165 }}
166 // }}}
167
168 , destroy: {
169 scope:this
170 , fn: function(panel) {
171 this.items.removeKey(panel.id);
172 this.updateOrder();
173 }}
174 });
175 // }}}
176 // {{{
177 // add events
178 this.addEvents({
179 /**
180 * Fires when a panel of the dock is collapsed
181 * @event panelcollapse
182 * @param {Ext.ux.InfoPanel} panel
183 */
184 panelcollapse: true
185
186 /**
187 * Fires when a panel of the dock is expanded
188 * @event panelexpand
189 * @param {Ext.ux.InfoPanel} panel
190 */
191 , panelexpand: true
192
193 /**
194 * Fires when a panel of the dock is pinned
195 * @event panelpinned
196 * @param {Ext.ux.InfoPanel} panel
197 * @param {Boolean} pinned true if panel was pinned false if unpinned
198 */
199 , panelpinned: true
200
201 /**
202 * Fires when the independent state of dock changes
203 * @event independent
204 * @param {Ext.ux.Accordion} this
205 * @param {Boolean} independent New independent state
206 */
207 , independent: true
208
209 /**
210 * Fires when the order of panel is changed
211 * @event orderchange
212 * @param {Ext.ux.Accordion} this
213 * @param {Array} order New order array
214 */
215 , orderchange: true
216
217 /**
218 * Fires when the undockable state of dock changes
219 * @event undockable
220 * @param {Ext.ux.Accordion} this
221 * @param {Array} undockable New undockable state
222 */
223 , undockable: true
224
225 /**
226 * Fires when a panel is undocked
227 * @event panelundock
228 * @param {Ext.ux.InfoPanel} panel
229 * @param {Object} box Position and size object
230 */
231 , panelundock: true
232
233 /**
234 * Fires when a panel is undocked
235 * @event paneldock
236 * @param {Ext.ux.InfoPanel} panel
237 */
238 , paneldock: true
239
240 /**
241 * Fires when a panel box is changed, e.g. after dragging
242 * @event panelbox
243 * @param {Ext.ux.InfoPanel} panel
244 * @param {Object} box Position and size object
245 */
246 , panelbox: true
247
248 /**
249 * Fires when useShadow status changes
250 * @event useshadow
251 * @param {Ext.ux.Accordion} this
252 * @param {Boolean} shadow Use shadow (for undocked panels) flag
253 */
254 , useshadow: true
255
256 /**
257 * Fires before the panel is detached from this accordion. Return false to cancel the detach
258 * @event beforedetach
259 * @param {Ext.ux.Accordion} this
260 * @param {Ext.ux.InfoPanel} panel being detached
261 */
262 , beforedetach: true
263
264 /**
265 * Fires after the panel has been detached from this accordion
266 * @event detach
267 * @param {Ext.ux.Accordion} this
268 * @param {Ext.ux.InfoPanel} panel detached panel
269 */
270 , detach: true
271
272 /**
273 * Fires before the panel is attached from this accordion. Return false to cancel the attach
274 * @event beforeattach
275 * @param {Ext.ux.Accordion} this
276 * @param {Ext.ux.InfoPanel} panel being attached
277 */
278 , beforeattach: true
279
280 /**
281 * Fires after the panel is attached to this accordion
282 * @event attach
283 * @param {Ext.ux.Accordion} this
284 * @param {Ext.ux.InfoPanel} panel attached panel
285 */
286 , attach: true
287
288 });
289 // }}}
290
291 // setup body
292 this.body = Ext.get(this.body) || this.el;
293 this.resizeEl = this.body;
294 this.id = this.id || this.body.id;
295 this.body.addClass('x-dock-body');
296
297 // setup desktop
298 this.desktop = Ext.get(this.desktop || document.body);
299 //this.desktop = this.desktop.dom || this.desktop;
300
301 // setup fixed hight
302 this.wrapEl = Ext.get(this.wrapEl);
303 if(this.fitHeight) {
304 this.body.setStyle('overflow', 'hidden');
305 // this.bodyHeight = this.initialHeight || this.body.getHeight();
306 this.body.setHeight(this.initialHeight || this.body.getHeight());
307 if(this.boxWrap && this.wrapEl) {
308 this.wrapEl.boxWrap();
309 }
310 }
311
312 // watch window resize
313 if(this.monitorWindowResize) {
314 Ext.EventManager.onWindowResize(this.adjustViewport, this);
315 }
316
317 // create drop zone for panels
318 this.dd = new Ext.dd.DropZone(this.body.dom, {
319 ddGroup: this.ddGroup || 'dock-' + this.id
320 });
321
322 Ext.ux.AccordionManager.add(this);
323
324 }; // end of constructor
325
326 // extend
327 Ext.extend(Ext.ux.Accordion, Ext.ContentPanel, {
328
329 // {{{
330 // defaults
331 independent: false
332 , undockable: true
333 , useShadow: true
334 , boxWrap: false
335 , fitHeight: false
336 , initialHeight: 0
337 , animate: true // global animation flag
338 , expandCount: 0
339 , expanding: false
340 , monitorWindowResize: true
341 , resizable: true // global resizable flag
342 , draggable: true // global draggable flag
343 , forceOrder: false
344 , keepState: true
345 , hideOtherOnExpand: false
346 // }}}
347 // {{{
348 /**
349 * Adds the panel to Accordion
350 * @param {Ext.ux.InfoPanel} panel Panel to add
351 * @return {Ext.ux.InfoPanel} added panel
352 */
353 , add: function(panel) {
354
355 // append panel to body
356 this.body.appendChild(panel.el);
357
358 this.attach(panel);
359
360 // panel dragging
361 if(undefined === panel.draggable && this.draggable) {
362 panel.draggable = true;
363 panel.dd = new Ext.ux.Accordion.DDDock(panel, this.ddGroup || 'dock-' + this.id, this);
364 }
365
366 // panel resizing
367 if(undefined === panel.resizable && this.resizable) {
368 panel.resizable = true;
369 // panel.setResizable(true);
370 }
371
372 // panel shadow
373 panel.useShadow = undefined === panel.useShadow ? this.useShadow : panel.useShadow;
374 panel.setShadow(panel.useShadow);
375 if(panel.shadow) {
376 panel.shadow.hide();
377 }
378
379 // panel animation
380 panel.animate = undefined === panel.animate ? this.animate : panel.animate;
381
382 // z-index for panel
383 panel.zindex = Ext.ux.AccordionManager.getNextZindex();
384
385 panel.docked = true;
386 panel.desktop = this.desktop;
387
388 if(false === panel.collapsed) {
389 panel.collapsed = true;
390 panel.expand(true);
391 }
392 return panel;
393
394 }
395 // }}}
396 // {{{
397 /**
398 * attach panel to this accordion
399 * @param {Ext.ux.InfoPanel} panel panel to attach
400 * @return {Ext.ux.Accordion} this
401 */
402 , attach: function(panel) {
403
404 // fire beforeattach event
405 if(false === this.fireEvent('beforeattach', this, panel)) {
406 return this;
407 }
408
409 // add panel to items
410 this.items.add(panel.id, panel);
411
412 // install event handlers
413 this.installRelays(panel);
414 panel.bodyClickDelegate = this.onClickPanelBody.createDelegate(this, [panel]);
415 panel.body.on('click', panel.bodyClickDelegate);
416
417 // set panel dock
418 panel.dock = this;
419
420 // add docked class to panel body
421 panel.body.replaceClass('x-dock-panel-body-undocked', 'x-dock-panel-body-docked');
422
423 // repair panel height
424 panel.autoSize();
425 if(this.fitHeight) {
426 this.setPanelHeight(panel);
427 }
428
429 // fire attach event
430 this.fireEvent('attach', this, panel);
431
432 return this;
433 }
434 // }}}
435 // {{{
436 /**
437 * detach panel from this accordion
438 * @param {Ext.ux.InfoPanel} panel to detach
439 * @return {Ext.ux.Accordion} this
440 */
441 , detach: function(panel) {
442
443 // fire beforedetach event
444 if(false === this.fireEvent('beforedetach', this, panel)) {
445 return this;
446 }
447
448 // unhook events from panel
449 this.removeRelays(panel);
450 panel.body.un('click', panel.bodyClickDelegate);
451
452 // remove panel from items
453 this.items.remove(panel);
454 panel.dock = null;
455
456 // remove docked class from panel body
457 panel.body.replaceClass('x-dock-panel-body-docked', 'x-dock-panel-body-undocked');
458
459 // repair expanded property
460 if(this.expanded === panel) {
461 this.expanded = null;
462 }
463
464 // repair panel height
465 panel.autoSize();
466 if(this.fitHeight) {
467 this.setPanelHeight();
468 }
469
470 // fire detach event
471 this.fireEvent('detach', this, panel);
472
473 return this;
474 }
475 // }}}
476 // {{{
477 /**
478 * Called internally to raise panel above others
479 * @param {Ext.ux.InfoPanel} panel Panel to raise
480 * @return {Ext.ux.InfoPanel} panel Panel that has been raised
481 */
482 , raise: function(panel) {
483 return Ext.ux.AccordionManager.raise(panel);
484 }
485 // }}}
486 // {{{
487 /**
488 * Resets the order of panels within the dock
489 *
490 * @return {Ext.ux.Accordion} this
491 */
492 , resetOrder: function() {
493 this.items.each(function(panel) {
494 if(!panel.docked) {
495 return;
496 }
497 this.body.appendChild(panel.el);
498 }, this);
499 this.updateOrder();
500 return this;
501 }
502 // }}}
503 // {{{
504 /**
505 * Called internally to update the order variable after dragging
506 */
507 , updateOrder: function() {
508 var order = [];
509 var titles = this.body.select('div.x-layout-panel-hd');
510 titles.each(function(titleEl) {
511 order.push(titleEl.dom.parentNode.id);
512 });
513 this.order = order;
514 this.fireEvent('orderchange', this, order);
515 }
516 // }}}
517 // {{{
518 /**
519 * Returns array of panel ids in the current order
520 * @return {Array} order of panels
521 */
522 , getOrder: function() {
523 return this.order;
524 }
525 // }}}
526 // {{{
527 /**
528 * Set the order of panels
529 * @param {Array} order Array of ids of panels in required order.
530 * @return {Ext.ux.Accordion} this
531 */
532 , setOrder: function(order) {
533 if('object' !== typeof order || undefined === order.length) {
534 throw "setOrder: Argument is not array.";
535 }
536 var panelEl, dock, panelId, panel;
537 for(var i = 0; i < order.length; i++) {
538 panelId = order[i];
539 dock = Ext.ux.AccordionManager.get(panelId);
540 if(dock && dock !== this) {
541 panel = dock.items.get(panelId);
542 dock.detach(panel);
543 this.attach(panel);
544 }
545 panelEl = Ext.get(panelId);
546 if(panelEl) {
547 this.body.appendChild(panelEl);
548 }
549 }
550 this.updateOrder();
551 return this;
552 }
553 // }}}
554 // {{{
555 /**
556 * Collapse all docked panels
557 * @param {Boolean} alsoPinned true to first unpin then collapse
558 * @param {Ext.ux.InfoPanel} except This panel will not be collapsed.
559 * @return {Ext.ux.Accordion} this
560 */
561 , collapseAll: function(alsoPinned, except) {
562 this.items.each(function(panel) {
563 if(panel.docked) {
564 panel.pinned = alsoPinned ? false : panel.pinned;
565 if(!except || panel !== except) {
566 panel.collapse();
567 }
568 }
569 }, this);
570 return this;
571 }
572 // }}}
573 // {{{
574 /**
575 * Expand all docked panels in independent mode
576 * @return {Ext.ux.Accordion} this
577 */
578 , expandAll: function() {
579 if(this.independent) {
580 this.items.each(function(panel) {
581 if(panel.docked && panel.collapsed) {
582 panel.expand();
583 }
584 }, this);
585 }
586 }
587 // }}}
588 // {{{
589 /**
590 * Called internally while dragging and by state manager
591 * @param {Ext.ux.InfoPanel/String} panel Panel object or id of the panel
592 * @box {Object} box coordinates with target position and size
593 * @return {Ext.ux.Accordion} this
594 */
595 , undock: function(panel, box) {
596
597 // get panel if necessary
598 panel = 'string' === typeof panel ? this.items.get(panel) : panel;
599
600 // proceed only if we have docked panel and in undockable mode
601 if(panel && panel.docked && this.undockable) {
602
603 // sanity check
604 if(box.x < 0 || box.y < 0) {
605 return this;
606 }
607
608 // todo: check this
609 // if(panel.collapsed) {
610 // box.height = panel.lastHeight || panel.maxHeight || box.height;
611 // }
612
613 // move the panel in the dom (append to desktop)
614 this.desktop.appendChild(panel.el.dom);
615
616 // adjust panel visuals
617 panel.el.applyStyles({
618 position:'absolute'
619 , 'z-index': panel.zindex
620 });
621 panel.body.replaceClass('x-dock-panel-body-docked', 'x-dock-panel-body-undocked');
622
623 // position the panel
624 panel.setBox(box);
625
626 // reset docked flag
627 panel.docked = false;
628
629 // hide panel shadow (will be shown by raise)
630 if(panel.shadow) {
631 panel.shadow.hide();
632 }
633
634 // raise panel above others
635 this.raise(panel);
636
637 panel.autoSize();
638
639 if(panel === this.expanded) {
640 this.expanded = null;
641 }
642
643 // set the height of a docked expanded panel
644 this.setPanelHeight(this.expanded);
645
646 // enable resizing and scrolling
647 panel.setResizable(!panel.collapsed);
648
649 // remember size of the undocked panel
650 panel.lastWidth = box.width;
651 // panel.lastHeight = box.height;
652
653 // fire panelundock event
654 this.fireEvent('panelundock', panel, {x:box.x, y:box.y, width:box.width, height:box.height});
655
656 // this.updateOrder();
657 }
658
659 return this;
660 }
661 // }}}
662 // {{{
663 /**
664 * Called internally while dragging
665 * @param {Ext.ux.InfoPanel/String} panel Panel object or id of the panel
666 * @param {String} targetId id of panel after which this panel will be docked
667 * @return {Ext.ux.Accordion} this
668 */
669 , dock: function(panel, targetId) {
670
671 // get panel if necessary
672 panel = 'string' === typeof panel ? this.items.get(panel) : panel;
673
674 // proceed only if we have a docked panel
675 var dockWidth, newTargetId, panelHeight, idx, i, targetPanel;
676 if(panel && !panel.docked) {
677
678 // find correct target if order is forced
679 if(this.forceOrder) {
680 idx = this.items.indexOf(panel);
681 for(i = idx + 1; i < this.items.getCount(); i++) {
682 targetPanel = this.items.itemAt(i);
683 if(targetPanel.docked) {
684 newTargetId = targetPanel.id;
685 break;
686 }
687 }
688 targetId = newTargetId || this.id;
689 }
690
691 // remember width and height
692 if(!panel.collapsed) {
693 // panel.lastWidth = panel.el.getWidth();
694 // panel.lastHeight = panel.el.getHeight();
695 if(!this.independent && this.expanded) {
696 this.expanded.collapse();
697 }
698 this.expanded = panel;
699 }
700
701 dockWidth = this.body.getWidth(true);
702
703 // move the panel element in the dom
704 if(targetId && (this.body.id !== targetId)) {
705 panel.el.insertBefore(Ext.fly(targetId));
706 }
707 else {
708 panel.el.appendTo(this.body);
709 }
710
711 // set docked flag
712 panel.docked = true;
713
714 // adjust panel visuals
715 panel.body.replaceClass('x-dock-panel-body-undocked', 'x-dock-panel-body-docked');
716 panel.el.applyStyles({
717 top:''
718 , left:''
719 , width:''
720 // , height:''
721 , 'z-index':''
722 , position:'relative'
723 , visibility:''
724 });
725 panel.body.applyStyles({width: Ext.isIE ? dockWidth + 'px' : '', height:''});
726
727 panel.autoSize();
728 // if(!this.fitHeight) {
729 // panelHeight = panel.fixedHeight || panel.maxHeight;
730 // if(panelHeight) {
731 // panel.setHeight(panelHeight);
732 // }
733 // }
734
735 // disable resizing and shadow
736 panel.setResizable(false);
737 if(panel.shadow) {
738 panel.shadow.hide();
739 }
740
741 // set panel height (only if this.fitHeight = true)
742 this.setPanelHeight(panel.collapsed ? this.expanded : panel);
743
744 // fire paneldock event
745 this.fireEvent('paneldock', panel);
746
747 // this.updateOrder();
748 }
749
750 return this;
751 }
752 // }}}
753 // {{{
754 /**
755 * Moves panel from this dock (accordion) to another
756 * @param {Ext.ux.InfoPanel} panel Panel to move
757 * @param {Ext.ux.Accordion} targetDock Dock to move to
758 */
759 , moveToDock: function(panel, targetDock) {
760 this.detach(panel);
761 targetDock.attach(panel);
762 panel.docked = false;
763 targetDock.dock(panel);
764 this.setPanelHeight();
765 this.updateOrder();
766 targetDock.updateOrder();
767 }
768 // }}}
769 // {{{
770 /**
771 * Sets the independent mode
772 * @param {Boolean} independent set to false for normal mode
773 * @return {Ext.ux.Accordion} this
774 */
775 , setIndependent: function(independent) {
776 this.independent = independent ? true : false;
777 this.fireEvent('independent', this, independent);
778 return this;
779 }
780 // }}}
781 // {{{
782 /**
783 * Sets the undockable mode
784 * If undockable === true all undocked panels are docked and collapsed (except pinned)
785 * @param {Boolean} undockable set to true to not allow undocking
786 * @return {Ext.ux.Accordion} this
787 */
788 , setUndockable: function(undockable) {
789 this.items.each(function(panel) {
790
791 // dock and collapse (except pinned) all undocked panels if not undockable
792 if(!undockable && !panel.docked) {
793 this.dock(panel);
794 if(!this.independent && !panel.collapsed && !panel.pinned) {
795 panel.collapse();
796 }
797 }
798
799 // refresh dragging constraints
800 if(panel.docked && panel.draggable) {
801 panel.dd.constrainTo(this.body, 0, false);
802 panel.dd.clearConstraints();
803 if(undockable) {
804 panel.constrainToDesktop();
805 }
806 else {
807 panel.dd.setXConstraint(0,0);
808 }
809 }
810 }, this);
811
812 // set the flag and fire event
813 this.undockable = undockable;
814 this.fireEvent('undockable', this, undockable);
815 return this;
816 }
817 // }}}
818 // {{{
819 /**
820 * Sets the shadows for all panels
821 * @param {Boolean} shadow set to false to disable shadows
822 * @return {Ext.ux.Accordion} this
823 */
824 , setShadow: function(shadow) {
825 this.items.each(function(panel) {
826 panel.useShadow = shadow;
827 panel.setShadow(false);
828 if(!panel.docked) {
829 panel.setShadow(shadow);
830 }
831 });
832 this.useShadow = shadow;
833 this.fireEvent('useshadow', this, shadow);
834 return this;
835 }
836 // }}}
837 // {{{
838 /**
839 * Called when user clicks the panel body
840 * @param {Ext.ux.InfoPanel} panel
841 */
842 , onClickPanelBody: function(panel) {
843 if(!panel.docked) {
844 this.raise(panel);
845 }
846 }
847 // }}}
848 // {{{
849 /**
850 * Called internally for fixed height docks to get current height of panel(s)
851 */
852 , getPanelBodyHeight: function() {
853 var titleHeight = 0;
854 this.items.each(function(panel) {
855 titleHeight += panel.docked ? panel.titleEl.getHeight() : 0;
856 });
857 this.panelBodyHeight = this.body.getHeight() - titleHeight - this.body.getFrameWidth('tb') + 1;
858 // this.panelBodyHeight = this.body.getHeight() - titleHeight - this.body.getFrameWidth('tb');
859 return this.panelBodyHeight;
860 }
861 // }}}
862 // {{{
863 /**
864 * Sets the height of panel body
865 * Used with fixed height (fitHeight:true) docs
866 * @param {Ext.ux.InfoPanel} panel (defaults to this.expanded)
867 * @return {Ext.ux.Accordion} this
868 */
869 , setPanelHeight: function(panel) {
870 panel = panel || this.expanded;
871 if(this.fitHeight && panel && panel.docked) {
872 panel.body.setHeight(this.getPanelBodyHeight());
873 panel.setHeight(panel.getHeight());
874 }
875 return this;
876 }
877 // }}}
878 // {{{
879 /**
880 * Constrains the dragging of panels do the desktop
881 * @return {Ext.ux.Accordion} this
882 */
883 , constrainToDesktop: function() {
884 this.items.each(function(panel) {
885 panel.constrainToDesktop();
886 }, this);
887 return this;
888 }
889 // }}}
890 // {{{
891 /**
892 * Clears dragging constraints of panels
893 * @return {Ext.ux.Accordion} this
894 */
895 , clearConstraints: function() {
896 this.items.each(function(panel) {
897 panel.dd.clearConstraints();
898 });
899 }
900 // }}}
901 // {{{
902 /**
903 * Shows all panels
904 * @param {Boolean} show (optional) if false hides the panels instead of showing
905 * @param {Boolean} alsoUndocked show also undocked panels (defaults to false)
906 * @return {Ext.ux.Accordion} this
907 */
908 , showAll: function(show, alsoUndocked) {
909 show = (false === show ? false : true);
910 this.items.each(function(panel) {
911 panel.show(show, alsoUndocked);
912 });
913 return this;
914 }
915 // }}}
916
917 , showOther: function(panel, show, alsoPinned) {
918 show = (false === show ? false : true);
919 this.items.each(function(p) {
920 if(p === panel || (p.pinned && !alsoPinned)) {
921 return;
922 }
923 if(show) {
924 p.show();
925 }
926 else {
927 p.hide();
928 }
929 });
930 }
931
932 , hideOther: function(panel, alsoPinned) {
933 this.showOther(panel, false, alsoPinned);
934 }
935
936 // {{{
937 /**
938 * Hides all panels
939 * @param {Boolean} alsoUndocked hide also undocked panels (defaults to false)
940 * @return {Ext.ux.Accordion} this
941 */
942 , hideAll: function(alsoUndocked) {
943 return this.showAll(false, alsoUndocked);
944 }
945 // }}}
946 // {{{
947 /**
948 * Called internally to disable/enable scrolling of the dock while animating
949 * @param {Boolean} enable true to enable, false to disable
950 * @return {void}
951 * @todo not used at present - revise
952 */
953 , setDockScroll: function(enable) {
954 if(enable && !this.fitHeight) {
955 this.body.setStyle('overflow','auto');
956 }
957 else {
958 this.body.setStyle('overflow','hidden');
959 }
960 }
961 // }}}
962 // {{{
963 /**
964 * Set Accordion size
965 * Overrides ContentPanel.setSize
966 *
967 * @param {Integer} w width
968 * @param {Integer} h height
969 * @return {Ext.ux.Accordion} this
970 */
971 , setSize: function(w, h) {
972 // call parent's setSize
973 Ext.ux.Accordion.superclass.setSize.call(this, w, h);
974 // this.body.setHeight(h);
975 this.setPanelHeight();
976
977 return this;
978 }
979 // }}}
980 // {{{
981 /**
98