Bienvenue sur PostGIS.fr

Bienvenue sur PostGIS.fr , le site de la communauté des utilisateurs francophones de PostGIS.

PostGIS ajoute le support d'objets géographique à la base de données PostgreSQL. En effet, PostGIS "spatialise" le serverur PostgreSQL, ce qui permet de l'utiliser comme une base de données SIG.

Maintenu à jour, en fonction de nos disponibilités et des diverses sorties des outils que nous testons, nous vous proposons l'ensemble de nos travaux publiés en langue française.

source: trunk/workshop-routing-foss4g/web/ext/src/widgets/layout/BorderLayout.js @ 76

Revision 76, 41.8 KB checked in by djay, 12 years ago (diff)

Ajout du répertoire web

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