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