Upgrade to ExtJS 3.3.1 - Released 11/30/2010
[extjs.git] / docs / source / SplitBar.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.3.1
11  * Copyright(c) 2006-2010 Sencha Inc.
12  * licensing@sencha.com
13  * http://www.sencha.com/license
14  */
15 <div id="cls-Ext.SplitBar"></div>/**
16  * @class Ext.SplitBar
17  * @extends Ext.util.Observable
18  * Creates draggable splitter bar functionality from two elements (element to be dragged and element to be resized).
19  * <br><br>
20  * Usage:
21  * <pre><code>
22 var split = new Ext.SplitBar("elementToDrag", "elementToSize",
23                    Ext.SplitBar.HORIZONTAL, Ext.SplitBar.LEFT);
24 split.setAdapter(new Ext.SplitBar.AbsoluteLayoutAdapter("container"));
25 split.minSize = 100;
26 split.maxSize = 600;
27 split.animate = true;
28 split.on('moved', splitterMoved);
29 </code></pre>
30  * @constructor
31  * Create a new SplitBar
32  * @param {Mixed} dragElement The element to be dragged and act as the SplitBar.
33  * @param {Mixed} resizingElement The element to be resized based on where the SplitBar element is dragged
34  * @param {Number} orientation (optional) Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
35  * @param {Number} placement (optional) Either Ext.SplitBar.LEFT or Ext.SplitBar.RIGHT for horizontal or
36                         Ext.SplitBar.TOP or Ext.SplitBar.BOTTOM for vertical. (By default, this is determined automatically by the initial
37                         position of the SplitBar).
38  */
39 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
40
41     /** @private */
42     this.el = Ext.get(dragElement, true);
43     this.el.dom.unselectable = "on";
44     /** @private */
45     this.resizingEl = Ext.get(resizingElement, true);
46
47     /**
48      * @private
49      * The orientation of the split. Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
50      * Note: If this is changed after creating the SplitBar, the placement property must be manually updated
51      * @type Number
52      */
53     this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
54
55     <div id="prop-Ext.SplitBar-tickSize"></div>/**
56      * The increment, in pixels by which to move this SplitBar. When <i>undefined</i>, the SplitBar moves smoothly.
57      * @type Number
58      * @property tickSize
59      */
60     <div id="prop-Ext.SplitBar-minSize"></div>/**
61      * The minimum size of the resizing element. (Defaults to 0)
62      * @type Number
63      */
64     this.minSize = 0;
65
66     <div id="prop-Ext.SplitBar-maxSize"></div>/**
67      * The maximum size of the resizing element. (Defaults to 2000)
68      * @type Number
69      */
70     this.maxSize = 2000;
71
72     <div id="prop-Ext.SplitBar-animate"></div>/**
73      * Whether to animate the transition to the new size
74      * @type Boolean
75      */
76     this.animate = false;
77
78     <div id="prop-Ext.SplitBar-useShim"></div>/**
79      * Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes.
80      * @type Boolean
81      */
82     this.useShim = false;
83
84     /** @private */
85     this.shim = null;
86
87     if(!existingProxy){
88         /** @private */
89         this.proxy = Ext.SplitBar.createProxy(this.orientation);
90     }else{
91         this.proxy = Ext.get(existingProxy).dom;
92     }
93     /** @private */
94     this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
95
96     /** @private */
97     this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
98
99     /** @private */
100     this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
101
102     /** @private */
103     this.dragSpecs = {};
104
105     /**
106      * @private The adapter to use to positon and resize elements
107      */
108     this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
109     this.adapter.init(this);
110
111     if(this.orientation == Ext.SplitBar.HORIZONTAL){
112         /** @private */
113         this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
114         this.el.addClass("x-splitbar-h");
115     }else{
116         /** @private */
117         this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
118         this.el.addClass("x-splitbar-v");
119     }
120
121     this.addEvents(
122         <div id="event-Ext.SplitBar-resize"></div>/**
123          * @event resize
124          * Fires when the splitter is moved (alias for {@link #moved})
125          * @param {Ext.SplitBar} this
126          * @param {Number} newSize the new width or height
127          */
128         "resize",
129         <div id="event-Ext.SplitBar-moved"></div>/**
130          * @event moved
131          * Fires when the splitter is moved
132          * @param {Ext.SplitBar} this
133          * @param {Number} newSize the new width or height
134          */
135         "moved",
136         <div id="event-Ext.SplitBar-beforeresize"></div>/**
137          * @event beforeresize
138          * Fires before the splitter is dragged
139          * @param {Ext.SplitBar} this
140          */
141         "beforeresize",
142
143         "beforeapply"
144     );
145
146     Ext.SplitBar.superclass.constructor.call(this);
147 };
148
149 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
150     onStartProxyDrag : function(x, y){
151         this.fireEvent("beforeresize", this);
152         this.overlay =  Ext.DomHelper.append(document.body,  {cls: "x-drag-overlay", html: "&#160;"}, true);
153         this.overlay.unselectable();
154         this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
155         this.overlay.show();
156         Ext.get(this.proxy).setDisplayed("block");
157         var size = this.adapter.getElementSize(this);
158         this.activeMinSize = this.getMinimumSize();
159         this.activeMaxSize = this.getMaximumSize();
160         var c1 = size - this.activeMinSize;
161         var c2 = Math.max(this.activeMaxSize - size, 0);
162         if(this.orientation == Ext.SplitBar.HORIZONTAL){
163             this.dd.resetConstraints();
164             this.dd.setXConstraint(
165                 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
166                 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
167                 this.tickSize
168             );
169             this.dd.setYConstraint(0, 0);
170         }else{
171             this.dd.resetConstraints();
172             this.dd.setXConstraint(0, 0);
173             this.dd.setYConstraint(
174                 this.placement == Ext.SplitBar.TOP ? c1 : c2,
175                 this.placement == Ext.SplitBar.TOP ? c2 : c1,
176                 this.tickSize
177             );
178          }
179         this.dragSpecs.startSize = size;
180         this.dragSpecs.startPoint = [x, y];
181         Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
182     },
183
184     /**
185      * @private Called after the drag operation by the DDProxy
186      */
187     onEndProxyDrag : function(e){
188         Ext.get(this.proxy).setDisplayed(false);
189         var endPoint = Ext.lib.Event.getXY(e);
190         if(this.overlay){
191             Ext.destroy(this.overlay);
192             delete this.overlay;
193         }
194         var newSize;
195         if(this.orientation == Ext.SplitBar.HORIZONTAL){
196             newSize = this.dragSpecs.startSize +
197                 (this.placement == Ext.SplitBar.LEFT ?
198                     endPoint[0] - this.dragSpecs.startPoint[0] :
199                     this.dragSpecs.startPoint[0] - endPoint[0]
200                 );
201         }else{
202             newSize = this.dragSpecs.startSize +
203                 (this.placement == Ext.SplitBar.TOP ?
204                     endPoint[1] - this.dragSpecs.startPoint[1] :
205                     this.dragSpecs.startPoint[1] - endPoint[1]
206                 );
207         }
208         newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
209         if(newSize != this.dragSpecs.startSize){
210             if(this.fireEvent('beforeapply', this, newSize) !== false){
211                 this.adapter.setElementSize(this, newSize);
212                 this.fireEvent("moved", this, newSize);
213                 this.fireEvent("resize", this, newSize);
214             }
215         }
216     },
217
218     <div id="method-Ext.SplitBar-getAdapter"></div>/**
219      * Get the adapter this SplitBar uses
220      * @return The adapter object
221      */
222     getAdapter : function(){
223         return this.adapter;
224     },
225
226     <div id="method-Ext.SplitBar-setAdapter"></div>/**
227      * Set the adapter this SplitBar uses
228      * @param {Object} adapter A SplitBar adapter object
229      */
230     setAdapter : function(adapter){
231         this.adapter = adapter;
232         this.adapter.init(this);
233     },
234
235     <div id="method-Ext.SplitBar-getMinimumSize"></div>/**
236      * Gets the minimum size for the resizing element
237      * @return {Number} The minimum size
238      */
239     getMinimumSize : function(){
240         return this.minSize;
241     },
242
243     <div id="method-Ext.SplitBar-setMinimumSize"></div>/**
244      * Sets the minimum size for the resizing element
245      * @param {Number} minSize The minimum size
246      */
247     setMinimumSize : function(minSize){
248         this.minSize = minSize;
249     },
250
251     <div id="method-Ext.SplitBar-getMaximumSize"></div>/**
252      * Gets the maximum size for the resizing element
253      * @return {Number} The maximum size
254      */
255     getMaximumSize : function(){
256         return this.maxSize;
257     },
258
259     <div id="method-Ext.SplitBar-setMaximumSize"></div>/**
260      * Sets the maximum size for the resizing element
261      * @param {Number} maxSize The maximum size
262      */
263     setMaximumSize : function(maxSize){
264         this.maxSize = maxSize;
265     },
266
267     <div id="method-Ext.SplitBar-setCurrentSize"></div>/**
268      * Sets the initialize size for the resizing element
269      * @param {Number} size The initial size
270      */
271     setCurrentSize : function(size){
272         var oldAnimate = this.animate;
273         this.animate = false;
274         this.adapter.setElementSize(this, size);
275         this.animate = oldAnimate;
276     },
277
278     <div id="method-Ext.SplitBar-destroy"></div>/**
279      * Destroy this splitbar.
280      * @param {Boolean} removeEl True to remove the element
281      */
282     destroy : function(removeEl){
283         Ext.destroy(this.shim, Ext.get(this.proxy));
284         this.dd.unreg();
285         if(removeEl){
286             this.el.remove();
287         }
288         this.purgeListeners();
289     }
290 });
291
292 /**
293  * @private static Create our own proxy element element. So it will be the same same size on all browsers, we won't use borders. Instead we use a background color.
294  */
295 Ext.SplitBar.createProxy = function(dir){
296     var proxy = new Ext.Element(document.createElement("div"));
297     document.body.appendChild(proxy.dom);
298     proxy.unselectable();
299     var cls = 'x-splitbar-proxy';
300     proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
301     return proxy.dom;
302 };
303
304 <div id="cls-Ext.SplitBar.BasicLayoutAdapter"></div>/**
305  * @class Ext.SplitBar.BasicLayoutAdapter
306  * Default Adapter. It assumes the splitter and resizing element are not positioned
307  * elements and only gets/sets the width of the element. Generally used for table based layouts.
308  */
309 Ext.SplitBar.BasicLayoutAdapter = function(){
310 };
311
312 Ext.SplitBar.BasicLayoutAdapter.prototype = {
313     // do nothing for now
314     init : function(s){
315
316     },
317     <div id="method-Ext.SplitBar.BasicLayoutAdapter-getElementSize"></div>/**
318      * Called before drag operations to get the current size of the resizing element.
319      * @param {Ext.SplitBar} s The SplitBar using this adapter
320      */
321      getElementSize : function(s){
322         if(s.orientation == Ext.SplitBar.HORIZONTAL){
323             return s.resizingEl.getWidth();
324         }else{
325             return s.resizingEl.getHeight();
326         }
327     },
328
329     <div id="method-Ext.SplitBar.BasicLayoutAdapter-setElementSize"></div>/**
330      * Called after drag operations to set the size of the resizing element.
331      * @param {Ext.SplitBar} s The SplitBar using this adapter
332      * @param {Number} newSize The new size to set
333      * @param {Function} onComplete A function to be invoked when resizing is complete
334      */
335     setElementSize : function(s, newSize, onComplete){
336         if(s.orientation == Ext.SplitBar.HORIZONTAL){
337             if(!s.animate){
338                 s.resizingEl.setWidth(newSize);
339                 if(onComplete){
340                     onComplete(s, newSize);
341                 }
342             }else{
343                 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
344             }
345         }else{
346
347             if(!s.animate){
348                 s.resizingEl.setHeight(newSize);
349                 if(onComplete){
350                     onComplete(s, newSize);
351                 }
352             }else{
353                 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
354             }
355         }
356     }
357 };
358
359 <div id="cls-Ext.SplitBar.AbsoluteLayoutAdapter"></div>/**
360  *@class Ext.SplitBar.AbsoluteLayoutAdapter
361  * @extends Ext.SplitBar.BasicLayoutAdapter
362  * Adapter that  moves the splitter element to align with the resized sizing element.
363  * Used with an absolute positioned SplitBar.
364  * @param {Mixed} container The container that wraps around the absolute positioned content. If it's
365  * document.body, make sure you assign an id to the body element.
366  */
367 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
368     this.basic = new Ext.SplitBar.BasicLayoutAdapter();
369     this.container = Ext.get(container);
370 };
371
372 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
373     init : function(s){
374         this.basic.init(s);
375     },
376
377     getElementSize : function(s){
378         return this.basic.getElementSize(s);
379     },
380
381     setElementSize : function(s, newSize, onComplete){
382         this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
383     },
384
385     moveSplitter : function(s){
386         var yes = Ext.SplitBar;
387         switch(s.placement){
388             case yes.LEFT:
389                 s.el.setX(s.resizingEl.getRight());
390                 break;
391             case yes.RIGHT:
392                 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
393                 break;
394             case yes.TOP:
395                 s.el.setY(s.resizingEl.getBottom());
396                 break;
397             case yes.BOTTOM:
398                 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
399                 break;
400         }
401     }
402 };
403
404 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-VERTICAL"></div>/**
405  * Orientation constant - Create a vertical SplitBar
406  * @static
407  * @type Number
408  */
409 Ext.SplitBar.VERTICAL = 1;
410
411 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-HORIZONTAL"></div>/**
412  * Orientation constant - Create a horizontal SplitBar
413  * @static
414  * @type Number
415  */
416 Ext.SplitBar.HORIZONTAL = 2;
417
418 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-LEFT"></div>/**
419  * Placement constant - The resizing element is to the left of the splitter element
420  * @static
421  * @type Number
422  */
423 Ext.SplitBar.LEFT = 1;
424
425 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-RIGHT"></div>/**
426  * Placement constant - The resizing element is to the right of the splitter element
427  * @static
428  * @type Number
429  */
430 Ext.SplitBar.RIGHT = 2;
431
432 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-TOP"></div>/**
433  * Placement constant - The resizing element is positioned above the splitter element
434  * @static
435  * @type Number
436  */
437 Ext.SplitBar.TOP = 3;
438
439 <div id="prop-Ext.SplitBar.AbsoluteLayoutAdapter-BOTTOM"></div>/**
440  * Placement constant - The resizing element is positioned under splitter element
441  * @static
442  * @type Number
443  */
444 Ext.SplitBar.BOTTOM = 4;
445 </pre>    
446 </body>
447 </html>