source: trunk/web/addons/job_monarch/lib/extjs/source/widgets/layout/BorderLayout.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 34.7 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.layout.BorderLayout
11 * @extends Ext.layout.ContainerLayout
12 * <p>This is a multi-pane, application-oriented UI layout style that supports multiple nested panels, automatic
13 * split bars between regions and built-in expanding and collapsing of regions.
14 * This class is intended to be extended or created via the layout:'border' {@link Ext.Container#layout} config,
15 * and should generally not need to be created directly via the new keyword.</p>
16 * <p>BorderLayout does not have any direct config options (other than inherited ones).  All configs available
17 * for customizing the BorderLayout are at the {@link Ext.layout.BorderLayout.Region} and
18 * {@link Ext.layout.BorderLayout.SplitRegion} levels.</p>
19 * <p><b>The regions of a BorderLayout are fixed at render time and thereafter, no regions may be removed or
20 * added. The BorderLayout must have a center region, which will always fill the remaining space not used by
21 * the other regions in the layout.</b></p>
22 * <p>Example usage:</p>
23 * <pre><code>
24var border = new Ext.Panel({
25    title: 'Border Layout',
26    layout:'border',
27    items: [{
28        title: 'South Panel',
29        region: 'south',
30        height: 100,
31        minSize: 75,
32        maxSize: 250,
33        margins: '0 5 5 5'
34    },{
35        title: 'West Panel',
36        region:'west',
37        margins: '5 0 0 5',
38        cmargins: '5 5 0 5',
39        width: 200,
40        minSize: 100,
41        maxSize: 300
42    },{
43        title: 'Main Content',
44        region:'center',
45        margins: '5 5 0 0'
46    }]
47});
48</code></pre>
49 */
50Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
51    // private
52    monitorResize:true,
53    // private
54    rendered : false,
55
56    // private
57    onLayout : function(ct, target){
58        var collapsed;
59        if(!this.rendered){
60            target.position();
61            target.addClass('x-border-layout-ct');
62            var items = ct.items.items;
63            collapsed = [];
64            for(var i = 0, len = items.length; i < len; i++) {
65                var c = items[i];
66                var pos = c.region;
67                if(c.collapsed){
68                    collapsed.push(c);
69                }
70                c.collapsed = false;
71                if(!c.rendered){
72                    c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
73                    c.render(target, i);
74                }
75                this[pos] = pos != 'center' && c.split ?
76                    new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
77                    new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
78                this[pos].render(target, c);
79            }
80            this.rendered = true;
81        }
82
83        var size = target.getViewSize();
84        if(size.width < 20 || size.height < 20){ // display none?
85            if(collapsed){
86                this.restoreCollapsed = collapsed;
87            }
88            return;
89        }else if(this.restoreCollapsed){
90            collapsed = this.restoreCollapsed;
91            delete this.restoreCollapsed;
92        }
93
94        var w = size.width, h = size.height;
95        var centerW = w, centerH = h, centerY = 0, centerX = 0;
96
97        var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
98        if(!c && Ext.layout.BorderLayout.WARN !== false){
99            throw 'No center region defined in BorderLayout ' + ct.id;
100        }
101
102        if(n && n.isVisible()){
103            var b = n.getSize();
104            var m = n.getMargins();
105            b.width = w - (m.left+m.right);
106            b.x = m.left;
107            b.y = m.top;
108            centerY = b.height + b.y + m.bottom;
109            centerH -= centerY;
110            n.applyLayout(b);
111        }
112        if(s && s.isVisible()){
113            var b = s.getSize();
114            var m = s.getMargins();
115            b.width = w - (m.left+m.right);
116            b.x = m.left;
117            var totalHeight = (b.height + m.top + m.bottom);
118            b.y = h - totalHeight + m.top;
119            centerH -= totalHeight;
120            s.applyLayout(b);
121        }
122        if(west && west.isVisible()){
123            var b = west.getSize();
124            var m = west.getMargins();
125            b.height = centerH - (m.top+m.bottom);
126            b.x = m.left;
127            b.y = centerY + m.top;
128            var totalWidth = (b.width + m.left + m.right);
129            centerX += totalWidth;
130            centerW -= totalWidth;
131            west.applyLayout(b);
132        }
133        if(e && e.isVisible()){
134            var b = e.getSize();
135            var m = e.getMargins();
136            b.height = centerH - (m.top+m.bottom);
137            var totalWidth = (b.width + m.left + m.right);
138            b.x = w - totalWidth + m.left;
139            b.y = centerY + m.top;
140            centerW -= totalWidth;
141            e.applyLayout(b);
142        }
143
144        if(c){
145            var m = c.getMargins();
146            var centerBox = {
147                x: centerX + m.left,
148                y: centerY + m.top,
149                width: centerW - (m.left+m.right),
150                height: centerH - (m.top+m.bottom)
151            };
152            c.applyLayout(centerBox);
153        }
154        if(collapsed){
155            for(var i = 0, len = collapsed.length; i < len; i++){
156                collapsed[i].collapse(false);
157            }
158        }
159
160        if(Ext.isIE && Ext.isStrict){ // workaround IE strict repainting issue
161            target.repaint();
162        }
163    },
164
165    // inherit docs
166    destroy: function() {
167        var r = ['north', 'south', 'east', 'west'];
168        for (var i = 0; i < r.length; i++) {
169            var region = this[r[i]];
170            if(region){
171                if(region.destroy){
172                        region.destroy();
173                    }else if (region.split){
174                        region.split.destroy(true);
175                    }
176            }
177        }
178        Ext.layout.BorderLayout.superclass.destroy.call(this);
179    }
180   
181    /**
182     * @property activeItem
183     * @hide
184     */
185});
186
187/**
188 * @class Ext.layout.BorderLayout.Region
189 * This is a region of a BorderLayout that acts as a subcontainer within the layout.  Each region has its own
190 * layout that is independent of other regions and the containing BorderLayout, and can be any of the valid
191 * Ext layout types.  Region size is managed automatically and cannot be changed by the user -- for resizable
192 * regions, see {@link Ext.layout.BorderLayout.SplitRegion}.
193 * @constructor
194 * Create a new Region.
195 * @param {Layout} layout Any valid Ext layout class
196 * @param {Object} config The configuration options
197 * @param {String} position The region position.  Valid values are: north, south, east, west and center.  Every
198 * BorderLayout must have a center region for the primary content -- all other regions are optional.
199 */
200Ext.layout.BorderLayout.Region = function(layout, config, pos){
201    Ext.apply(this, config);
202    this.layout = layout;
203    this.position = pos;
204    this.state = {};
205    if(typeof this.margins == 'string'){
206        this.margins = this.layout.parseMargins(this.margins);
207    }
208    this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
209    if(this.collapsible){
210        if(typeof this.cmargins == 'string'){
211            this.cmargins = this.layout.parseMargins(this.cmargins);
212        }
213        if(this.collapseMode == 'mini' && !this.cmargins){
214            this.cmargins = {left:0,top:0,right:0,bottom:0};
215        }else{
216            this.cmargins = Ext.applyIf(this.cmargins || {},
217                pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
218        }
219    }
220};
221
222Ext.layout.BorderLayout.Region.prototype = {
223    /**
224     * @cfg {Boolean} animFloat
225     * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated panel that will
226     * close again once the user mouses out of that panel (or clicks out if autoHide = false).  Setting animFloat
227     * to false will prevent the open and close of these floated panels from being animated (defaults to true).
228     */
229    /**
230     * @cfg {Boolean} autoHide
231     * When a collapsed region's bar is clicked, the region's panel will be displayed as a floated panel.  If
232     * autoHide is true, the panel will automatically hide after the user mouses out of the panel.  If autoHide
233     * is false, the panel will continue to display until the user clicks outside of the panel (defaults to true).
234     */
235        /**
236         * @cfg {Boolean} collapsed
237         * By default, collapsible regions will be visible when rendered. Set the collapsed config to true to render
238         * the region as collapsed.
239         */
240    /**
241     * @cfg {String} collapseMode
242     * By default, collapsible regions are collapsed by clicking the expand/collapse tool button that renders into
243     * the region's title bar.  Optionally, when collapseMode is set to 'mini' the region's split bar will also
244     * display a small collapse button in the center of the bar.  In 'mini' mode the region will collapse to a
245     * thinner bar than in normal mode.  By default collapseMode is undefined, and the only two supported values
246     * are undefined and 'mini'.  Note that if a collapsible region does not have a title bar, then collapseMode
247     * must be set to 'mini' in order for the region to be collapsible by the user as the tool button will not
248     * be rendered.
249     */
250    /**
251     * @cfg {Object} margins
252     * An object containing margins to apply to the region when in the expanded state in the format:<pre><code>
253{
254    top: (top margin),
255    right: (right margin),
256    bottom: (bottom margin)
257    left: (left margin),
258}</code></pre>
259     * <p>May also be a string containing space-separated, numeric margin values. The order of the sides associated
260     * with each value matches the way CSS processes margin values:</p>
261     * <p><ul>
262     * <li>If there is only one value, it applies to all sides.</li>
263     * <li>If there are two values, the top and bottom borders are set to the first value and the right
264     * and left are set to the second.</li>
265     * <li>If there are three values, the top is set to the first value, the left and right are set to the second, and the bottom
266     * is set to the third.</li>
267     * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li>
268     * </ul></p>
269     */
270    /**
271     * @cfg {Object} cmargins
272     * An object containing margins to apply to the region when in the collapsed state in the format:<pre><code>
273{
274    top: (top margin),
275    right: (right margin),
276    bottom: (bottom margin)
277    left: (left margin),
278}</code></pre>
279     * <p>May also be a string containing space-separated, numeric margin values. The order of the sides associated
280     * with each value matches the way CSS processes margin values.</p>
281     * <p><ul>
282     * <li>If there is only one value, it applies to all sides.</li>
283     * <li>If there are two values, the top and bottom borders are set to the first value and the right
284     * and left are set to the second.</li>
285     * <li>If there are three values, the top is set to the first value, the left and right are set to the second, and the bottom
286     * is set to the third.</li>
287     * <li>If there are four values, they apply to the top, right, bottom, and left, respectively.</li>
288     * </ul></p>
289     */
290    /**
291     * @cfg {Boolean} collapsible
292     * True to allow the user to collapse this region (defaults to false).  If true, an expand/collapse tool button
293     * will automatically be rendered into the title bar of the region, otherwise the button will not be shown.
294     * Note that a title bar is required to display the toggle button -- if no region title is specified, the
295     * region will only be collapsible if {@link #collapseMode} is set to 'mini'.
296     */
297    collapsible : false,
298    /**
299     * @cfg {Boolean} split
300     * True to display a {@link Ext.SplitBar} between this region and its neighbor, allowing the user to resize
301     * the regions dynamically (defaults to false).  When split == true, it is common to specify a minSize
302     * and maxSize for the BoxComponent representing the region. These are not native configs of BoxComponent, and
303     * are used only by this class.
304     */
305    split:false,
306    /**
307     * @cfg {Boolean} floatable
308     * True to allow clicking a collapsed region's bar to display the region's panel floated above the layout,
309     * false to force the user to fully expand a collapsed region by clicking the expand button to see it again
310     * (defaults to true).
311     */
312    floatable: true,
313    /**
314     * @cfg {Number} minWidth
315     * The minimum allowable width in pixels for this region (defaults to 50)
316     */
317    minWidth:50,
318    /**
319     * @cfg {Number} minHeight
320     * The minimum allowable height in pixels for this region (defaults to 50)
321     */
322    minHeight:50,
323
324    // private
325    defaultMargins : {left:0,top:0,right:0,bottom:0},
326    // private
327    defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
328    // private
329    defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
330
331    /**
332     * True if this region is collapsed. Read-only.
333     * @type Boolean
334     * @property
335     */
336    isCollapsed : false,
337
338    /**
339     * This region's panel.  Read-only.
340     * @type Ext.Panel
341     * @property panel
342     */
343    /**
344     * This region's layout.  Read-only.
345     * @type Layout
346     * @property layout
347     */
348    /**
349     * This region's layout position (north, south, east, west or center).  Read-only.
350     * @type String
351     * @property position
352     */
353
354    // private
355    render : function(ct, p){
356        this.panel = p;
357        p.el.enableDisplayMode();
358        this.targetEl = ct;
359        this.el = p.el;
360
361        var gs = p.getState, ps = this.position;
362        p.getState = function(){
363            return Ext.apply(gs.call(p) || {}, this.state);
364        }.createDelegate(this);
365
366        if(ps != 'center'){
367            p.allowQueuedExpand = false;
368            p.on({
369                beforecollapse: this.beforeCollapse,
370                collapse: this.onCollapse,
371                beforeexpand: this.beforeExpand,
372                expand: this.onExpand,
373                hide: this.onHide,
374                show: this.onShow,
375                scope: this
376            });
377            if(this.collapsible){
378                p.collapseEl = 'el';
379                p.slideAnchor = this.getSlideAnchor();
380            }
381            if(p.tools && p.tools.toggle){
382                p.tools.toggle.addClass('x-tool-collapse-'+ps);
383                p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
384            }
385        }
386    },
387
388    // private
389    getCollapsedEl : function(){
390        if(!this.collapsedEl){
391            if(!this.toolTemplate){
392                var tt = new Ext.Template(
393                     '<div class="x-tool x-tool-{id}">&#160;</div>'
394                );
395                tt.disableFormats = true;
396                tt.compile();
397                Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
398            }
399            this.collapsedEl = this.targetEl.createChild({
400                cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
401                id: this.panel.id + '-xcollapsed'
402            });
403            this.collapsedEl.enableDisplayMode('block');
404
405            if(this.collapseMode == 'mini'){
406                this.collapsedEl.addClass('x-layout-cmini-'+this.position);
407                this.miniCollapsedEl = this.collapsedEl.createChild({
408                    cls: "x-layout-mini x-layout-mini-"+this.position, html: "&#160;"
409                });
410                this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
411                this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
412                this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
413            }else {
414                var t = this.toolTemplate.append(
415                        this.collapsedEl.dom,
416                        {id:'expand-'+this.position}, true);
417                t.addClassOnOver('x-tool-expand-'+this.position+'-over');
418                t.on('click', this.onExpandClick, this, {stopEvent:true});
419               
420                if(this.floatable !== false){
421                   this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
422                   this.collapsedEl.on("click", this.collapseClick, this);
423                }
424            }
425        }
426        return this.collapsedEl;
427    },
428
429    // private
430    onExpandClick : function(e){
431        if(this.isSlid){
432            this.afterSlideIn();
433            this.panel.expand(false);
434        }else{
435            this.panel.expand();
436        }
437    },
438
439    // private
440    onCollapseClick : function(e){
441        this.panel.collapse();
442    },
443
444    // private
445    beforeCollapse : function(p, animate){
446        this.lastAnim = animate;
447        if(this.splitEl){
448            this.splitEl.hide();
449        }
450        this.getCollapsedEl().show();
451        this.panel.el.setStyle('z-index', 100);
452        this.isCollapsed = true;
453        this.layout.layout();
454    },
455
456    // private
457    onCollapse : function(animate){
458        this.panel.el.setStyle('z-index', 1);
459        if(this.lastAnim === false || this.panel.animCollapse === false){
460            this.getCollapsedEl().dom.style.visibility = 'visible';
461        }else{
462            this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
463        }
464        this.state.collapsed = true;
465        this.panel.saveState();
466    },
467
468    // private
469    beforeExpand : function(animate){
470        var c = this.getCollapsedEl();
471        this.el.show();
472        if(this.position == 'east' || this.position == 'west'){
473            this.panel.setSize(undefined, c.getHeight());
474        }else{
475            this.panel.setSize(c.getWidth(), undefined);
476        }
477        c.hide();
478        c.dom.style.visibility = 'hidden';
479        this.panel.el.setStyle('z-index', 100);
480    },
481
482    // private
483    onExpand : function(){
484        this.isCollapsed = false;
485        if(this.splitEl){
486            this.splitEl.show();
487        }
488        this.layout.layout();
489        this.panel.el.setStyle('z-index', 1);
490        this.state.collapsed = false;
491        this.panel.saveState();
492    },
493
494    // private
495    collapseClick : function(e){
496        if(this.isSlid){
497           e.stopPropagation();
498           this.slideIn();
499        }else{
500           e.stopPropagation();
501           this.slideOut();
502        }
503    },
504
505    // private
506    onHide : function(){
507        if(this.isCollapsed){
508            this.getCollapsedEl().hide();
509        }else if(this.splitEl){
510            this.splitEl.hide();
511        }
512    },
513
514    // private
515    onShow : function(){
516        if(this.isCollapsed){
517            this.getCollapsedEl().show();
518        }else if(this.splitEl){
519            this.splitEl.show();
520        }
521    },
522
523    /**
524     * True if this region is currently visible, else false.
525     * @return {Boolean}
526     */
527    isVisible : function(){
528        return !this.panel.hidden;
529    },
530
531    /**
532     * Returns the current margins for this region.  If the region is collapsed, the cmargins (collapsed
533     * margins) value will be returned, otherwise the margins value will be returned.
534     * @return {Object} An object containing the element's margins: {left: (left margin), top: (top margin),
535     * right: (right margin), bottom: (bottom margin)}
536     */
537    getMargins : function(){
538        return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
539    },
540
541    /**
542     * Returns the current size of this region.  If the region is collapsed, the size of the collapsedEl will
543     * be returned, otherwise the size of the region's panel will be returned.
544     * @return {Object} An object containing the element's size: {width: (element width), height: (element height)} 
545     */
546    getSize : function(){
547        return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
548    },
549
550    /**
551     * Sets the specified panel as the container element for this region.
552     * @param {Ext.Panel} panel The new panel
553     */
554    setPanel : function(panel){
555        this.panel = panel;
556    },
557
558    /**
559     * Returns the minimum allowable width for this region.
560     * @return {Number} The minimum width
561     */
562    getMinWidth: function(){
563        return this.minWidth;
564    },
565
566    /**
567     * Returns the minimum allowable height for this region.
568     * @return {Number} The minimum height
569     */
570    getMinHeight: function(){
571        return this.minHeight;
572    },
573
574    // private
575    applyLayoutCollapsed : function(box){
576        var ce = this.getCollapsedEl();
577        ce.setLeftTop(box.x, box.y);
578        ce.setSize(box.width, box.height);
579    },
580
581    // private
582    applyLayout : function(box){
583        if(this.isCollapsed){
584            this.applyLayoutCollapsed(box);
585        }else{
586            this.panel.setPosition(box.x, box.y);
587            this.panel.setSize(box.width, box.height);
588        }
589    },
590
591    // private
592    beforeSlide: function(){
593        this.panel.beforeEffect();
594    },
595
596    // private
597    afterSlide : function(){
598        this.panel.afterEffect();
599    },
600
601    // private
602    initAutoHide : function(){
603        if(this.autoHide !== false){
604            if(!this.autoHideHd){
605                var st = new Ext.util.DelayedTask(this.slideIn, this);
606                this.autoHideHd = {
607                    "mouseout": function(e){
608                        if(!e.within(this.el, true)){
609                            st.delay(500);
610                        }
611                    },
612                    "mouseover" : function(e){
613                        st.cancel();
614                    },
615                    scope : this
616                };
617            }
618            this.el.on(this.autoHideHd);
619        }
620    },
621
622    // private
623    clearAutoHide : function(){
624        if(this.autoHide !== false){
625            this.el.un("mouseout", this.autoHideHd.mouseout);
626            this.el.un("mouseover", this.autoHideHd.mouseover);
627        }
628    },
629
630    // private
631    clearMonitor : function(){
632        Ext.getDoc().un("click", this.slideInIf, this);
633    },
634
635    // these names are backwards but not changed for compat
636    // private
637    slideOut : function(){
638        if(this.isSlid || this.el.hasActiveFx()){
639            return;
640        }
641        this.isSlid = true;
642        var ts = this.panel.tools;
643        if(ts && ts.toggle){
644            ts.toggle.hide();
645        }
646        this.el.show();
647        if(this.position == 'east' || this.position == 'west'){
648            this.panel.setSize(undefined, this.collapsedEl.getHeight());
649        }else{
650            this.panel.setSize(this.collapsedEl.getWidth(), undefined);
651        }
652        this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
653        this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
654        this.el.setStyle("z-index", 102);
655        this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
656        if(this.animFloat !== false){
657            this.beforeSlide();
658            this.el.slideIn(this.getSlideAnchor(), {
659                callback: function(){
660                    this.afterSlide();
661                    this.initAutoHide();
662                    Ext.getDoc().on("click", this.slideInIf, this);
663                },
664                scope: this,
665                block: true
666            });
667        }else{
668            this.initAutoHide();
669             Ext.getDoc().on("click", this.slideInIf, this);
670        }
671    },
672
673    // private
674    afterSlideIn : function(){
675        this.clearAutoHide();
676        this.isSlid = false;
677        this.clearMonitor();
678        this.el.setStyle("z-index", "");
679        this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
680        this.el.dom.style.left = this.restoreLT[0];
681        this.el.dom.style.top = this.restoreLT[1];
682
683        var ts = this.panel.tools;
684        if(ts && ts.toggle){
685            ts.toggle.show();
686        }
687    },
688
689    // private
690    slideIn : function(cb){
691        if(!this.isSlid || this.el.hasActiveFx()){
692            Ext.callback(cb);
693            return;
694        }
695        this.isSlid = false;
696        if(this.animFloat !== false){
697            this.beforeSlide();
698            this.el.slideOut(this.getSlideAnchor(), {
699                callback: function(){
700                    this.el.hide();
701                    this.afterSlide();
702                    this.afterSlideIn();
703                    Ext.callback(cb);
704                },
705                scope: this,
706                block: true
707            });
708        }else{
709            this.el.hide();
710            this.afterSlideIn();
711        }
712    },
713
714    // private
715    slideInIf : function(e){
716        if(!e.within(this.el)){
717            this.slideIn();
718        }
719    },
720
721    // private
722    anchors : {
723        "west" : "left",
724        "east" : "right",
725        "north" : "top",
726        "south" : "bottom"
727    },
728
729    // private
730    sanchors : {
731        "west" : "l",
732        "east" : "r",
733        "north" : "t",
734        "south" : "b"
735    },
736
737    // private
738    canchors : {
739        "west" : "tl-tr",
740        "east" : "tr-tl",
741        "north" : "tl-bl",
742        "south" : "bl-tl"
743    },
744
745    // private
746    getAnchor : function(){
747        return this.anchors[this.position];
748    },
749
750    // private
751    getCollapseAnchor : function(){
752        return this.canchors[this.position];
753    },
754
755    // private
756    getSlideAnchor : function(){
757        return this.sanchors[this.position];
758    },
759
760    // private
761    getAlignAdj : function(){
762        var cm = this.cmargins;
763        switch(this.position){
764            case "west":
765                return [0, 0];
766            break;
767            case "east":
768                return [0, 0];
769            break;
770            case "north":
771                return [0, 0];
772            break;
773            case "south":
774                return [0, 0];
775            break;
776        }
777    },
778
779    // private
780    getExpandAdj : function(){
781        var c = this.collapsedEl, cm = this.cmargins;
782        switch(this.position){
783            case "west":
784                return [-(cm.right+c.getWidth()+cm.left), 0];
785            break;
786            case "east":
787                return [cm.right+c.getWidth()+cm.left, 0];
788            break;
789            case "north":
790                return [0, -(cm.top+cm.bottom+c.getHeight())];
791            break;
792            case "south":
793                return [0, cm.top+cm.bottom+c.getHeight()];
794            break;
795        }
796    }
797};
798
799/**
800 * @class Ext.layout.BorderLayout.SplitRegion
801 * @extends Ext.layout.BorderLayout.Region
802 * This is a specialized type of BorderLayout region that has a built-in {@link Ext.SplitBar} for user resizing of regions.
803 * @constructor
804 * Create a new SplitRegion.
805 * @param {Layout} layout Any valid Ext layout class
806 * @param {Object} config The configuration options
807 * @param {String} position The region position.  Valid values are: north, south, east, west and center.  Every
808 * BorderLayout must have a center region for the primary content -- all other regions are optional.
809 */
810Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
811    Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
812    // prevent switch
813    this.applyLayout = this.applyFns[pos];
814};
815
816Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
817    /**
818     * @cfg {String} splitTip
819     * The tooltip to display when the user hovers over a non-collapsible region's split bar (defaults to "Drag
820     * to resize.").  Only applies if {@link #useSplitTips} = true.
821     */
822    splitTip : "Drag to resize.",
823    /**
824     * @cfg {String} collapsibleSplitTip
825     * The tooltip to display when the user hovers over a collapsible region's split bar (defaults to "Drag
826     * to resize. Double click to hide.").  Only applies if {@link #useSplitTips} = true.
827     */
828    collapsibleSplitTip : "Drag to resize. Double click to hide.",
829    /**
830     * @cfg {Boolean} useSplitTips
831     * True to display a tooltip when the user hovers over a region's split bar (defaults to false).  The tooltip
832     * text will be the value of either {@link #splitTip} or {@link #collapsibleSplitTip} as appropriate.
833     */
834    useSplitTips : false,
835
836    // private
837    splitSettings : {
838        north : {
839            orientation: Ext.SplitBar.VERTICAL,
840            placement: Ext.SplitBar.TOP,
841            maxFn : 'getVMaxSize',
842            minProp: 'minHeight',
843            maxProp: 'maxHeight'
844        },
845        south : {
846            orientation: Ext.SplitBar.VERTICAL,
847            placement: Ext.SplitBar.BOTTOM,
848            maxFn : 'getVMaxSize',
849            minProp: 'minHeight',
850            maxProp: 'maxHeight'
851        },
852        east : {
853            orientation: Ext.SplitBar.HORIZONTAL,
854            placement: Ext.SplitBar.RIGHT,
855            maxFn : 'getHMaxSize',
856            minProp: 'minWidth',
857            maxProp: 'maxWidth'
858        },
859        west : {
860            orientation: Ext.SplitBar.HORIZONTAL,
861            placement: Ext.SplitBar.LEFT,
862            maxFn : 'getHMaxSize',
863            minProp: 'minWidth',
864            maxProp: 'maxWidth'
865        }
866    },
867
868    // private
869    applyFns : {
870        west : function(box){
871            if(this.isCollapsed){
872                return this.applyLayoutCollapsed(box);
873            }
874            var sd = this.splitEl.dom, s = sd.style;
875            this.panel.setPosition(box.x, box.y);
876            var sw = sd.offsetWidth;
877            s.left = (box.x+box.width-sw)+'px';
878            s.top = (box.y)+'px';
879            s.height = Math.max(0, box.height)+'px';
880            this.panel.setSize(box.width-sw, box.height);
881        },
882        east : function(box){
883            if(this.isCollapsed){
884                return this.applyLayoutCollapsed(box);
885            }
886            var sd = this.splitEl.dom, s = sd.style;
887            var sw = sd.offsetWidth;
888            this.panel.setPosition(box.x+sw, box.y);
889            s.left = (box.x)+'px';
890            s.top = (box.y)+'px';
891            s.height = Math.max(0, box.height)+'px';
892            this.panel.setSize(box.width-sw, box.height);
893        },
894        north : function(box){
895            if(this.isCollapsed){
896                return this.applyLayoutCollapsed(box);
897            }
898            var sd = this.splitEl.dom, s = sd.style;
899            var sh = sd.offsetHeight;
900            this.panel.setPosition(box.x, box.y);
901            s.left = (box.x)+'px';
902            s.top = (box.y+box.height-sh)+'px';
903            s.width = Math.max(0, box.width)+'px';
904            this.panel.setSize(box.width, box.height-sh);
905        },
906        south : function(box){
907            if(this.isCollapsed){
908                return this.applyLayoutCollapsed(box);
909            }
910            var sd = this.splitEl.dom, s = sd.style;
911            var sh = sd.offsetHeight;
912            this.panel.setPosition(box.x, box.y+sh);
913            s.left = (box.x)+'px';
914            s.top = (box.y)+'px';
915            s.width = Math.max(0, box.width)+'px';
916            this.panel.setSize(box.width, box.height-sh);
917        }
918    },
919
920    // private
921    render : function(ct, p){
922        Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
923
924        var ps = this.position;
925
926        this.splitEl = ct.createChild({
927            cls: "x-layout-split x-layout-split-"+ps, html: "&#160;",
928            id: this.panel.id + '-xsplit'
929        });
930
931        if(this.collapseMode == 'mini'){
932            this.miniSplitEl = this.splitEl.createChild({
933                cls: "x-layout-mini x-layout-mini-"+ps, html: "&#160;"
934            });
935            this.miniSplitEl.addClassOnOver('x-layout-mini-over');
936            this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
937        }
938
939        var s = this.splitSettings[ps];
940
941        this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
942        this.split.placement = s.placement;
943        this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
944        this.split.minSize = this.minSize || this[s.minProp];
945        this.split.on("beforeapply", this.onSplitMove, this);
946        this.split.useShim = this.useShim === true;
947        this.maxSize = this.maxSize || this[s.maxProp];
948
949        if(p.hidden){
950            this.splitEl.hide();
951        }
952
953        if(this.useSplitTips){
954            this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
955        }
956        if(this.collapsible){
957            this.splitEl.on("dblclick", this.onCollapseClick,  this);
958        }
959    },
960
961    //docs inherit from superclass
962    getSize : function(){
963        if(this.isCollapsed){
964            return this.collapsedEl.getSize();
965        }
966        var s = this.panel.getSize();
967        if(this.position == 'north' || this.position == 'south'){
968            s.height += this.splitEl.dom.offsetHeight;
969        }else{
970            s.width += this.splitEl.dom.offsetWidth;
971        }
972        return s;
973    },
974
975    // private
976    getHMaxSize : function(){
977         var cmax = this.maxSize || 10000;
978         var center = this.layout.center;
979         return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
980    },
981
982    // private
983    getVMaxSize : function(){
984        var cmax = this.maxSize || 10000;
985        var center = this.layout.center;
986        return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
987    },
988
989    // private
990    onSplitMove : function(split, newSize){
991        var s = this.panel.getSize();
992        this.lastSplitSize = newSize;
993        if(this.position == 'north' || this.position == 'south'){
994            this.panel.setSize(s.width, newSize);
995            this.state.height = newSize;
996        }else{
997            this.panel.setSize(newSize, s.height);
998            this.state.width = newSize;
999        }
1000        this.layout.layout();
1001        this.panel.saveState();
1002        return false;
1003    },
1004
1005    /**
1006     * Returns a reference to the split bar in use by this region.
1007     * @return {Ext.SplitBar} The split bar
1008     */
1009    getSplitBar : function(){
1010        return this.split;
1011    },
1012   
1013    // inherit docs
1014    destroy : function() {
1015        Ext.destroy(
1016            this.miniSplitEl, 
1017            this.split, 
1018            this.splitEl
1019        );
1020    }
1021});
1022
1023Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
Note: See TracBrowser for help on using the repository browser.