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