4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
15 * @extends Roo.util.Observable
16 * Creates draggable splitter bar functionality from two elements (element to be dragged and element to be resized).
20 var split = new Roo.SplitBar("elementToDrag", "elementToSize",
21 Roo.SplitBar.HORIZONTAL, Roo.SplitBar.LEFT);
22 split.setAdapter(new Roo.SplitBar.AbsoluteLayoutAdapter("container"));
26 split.on('moved', splitterMoved);
29 * Create a new SplitBar
30 * @param {String/HTMLElement/Roo.Element} dragElement The element to be dragged and act as the SplitBar.
31 * @param {String/HTMLElement/Roo.Element} resizingElement The element to be resized based on where the SplitBar element is dragged
32 * @param {Number} orientation (optional) Either Roo.SplitBar.HORIZONTAL or Roo.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
33 * @param {Number} placement (optional) Either Roo.SplitBar.LEFT or Roo.SplitBar.RIGHT for horizontal or
34 Roo.SplitBar.TOP or Roo.SplitBar.BOTTOM for vertical. (By default, this is determined automatically by the initial
35 position of the SplitBar).
37 Roo.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
40 this.el = Roo.get(dragElement, true);
41 this.el.dom.unselectable = "on";
43 this.resizingEl = Roo.get(resizingElement, true);
47 * The orientation of the split. Either Roo.SplitBar.HORIZONTAL or Roo.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
48 * Note: If this is changed after creating the SplitBar, the placement property must be manually updated
51 this.orientation = orientation || Roo.SplitBar.HORIZONTAL;
54 * The minimum size of the resizing element. (Defaults to 0)
60 * The maximum size of the resizing element. (Defaults to 2000)
66 * Whether to animate the transition to the new size
72 * Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes.
82 this.proxy = Roo.SplitBar.createProxy(this.orientation);
84 this.proxy = Roo.get(existingProxy).dom;
87 this.dd = new Roo.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
90 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
93 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
99 * @private The adapter to use to positon and resize elements
101 this.adapter = new Roo.SplitBar.BasicLayoutAdapter();
102 this.adapter.init(this);
104 if(this.orientation == Roo.SplitBar.HORIZONTAL){
106 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Roo.SplitBar.LEFT : Roo.SplitBar.RIGHT);
107 this.el.addClass("x-splitbar-h");
110 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Roo.SplitBar.TOP : Roo.SplitBar.BOTTOM);
111 this.el.addClass("x-splitbar-v");
117 * Fires when the splitter is moved (alias for {@link #event-moved})
118 * @param {Roo.SplitBar} this
119 * @param {Number} newSize the new width or height
124 * Fires when the splitter is moved
125 * @param {Roo.SplitBar} this
126 * @param {Number} newSize the new width or height
130 * @event beforeresize
131 * Fires before the splitter is dragged
132 * @param {Roo.SplitBar} this
134 "beforeresize" : true,
139 Roo.util.Observable.call(this);
142 Roo.extend(Roo.SplitBar, Roo.util.Observable, {
143 onStartProxyDrag : function(x, y){
144 this.fireEvent("beforeresize", this);
146 var o = Roo.DomHelper.insertFirst(document.body, {cls: "x-drag-overlay", html: " "}, true);
148 o.enableDisplayMode("block");
149 // all splitbars share the same overlay
150 Roo.SplitBar.prototype.overlay = o;
152 this.overlay.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
154 Roo.get(this.proxy).setDisplayed("block");
155 var size = this.adapter.getElementSize(this);
156 this.activeMinSize = this.getMinimumSize();;
157 this.activeMaxSize = this.getMaximumSize();;
158 var c1 = size - this.activeMinSize;
159 var c2 = Math.max(this.activeMaxSize - size, 0);
160 if(this.orientation == Roo.SplitBar.HORIZONTAL){
161 this.dd.resetConstraints();
162 this.dd.setXConstraint(
163 this.placement == Roo.SplitBar.LEFT ? c1 : c2,
164 this.placement == Roo.SplitBar.LEFT ? c2 : c1
166 this.dd.setYConstraint(0, 0);
168 this.dd.resetConstraints();
169 this.dd.setXConstraint(0, 0);
170 this.dd.setYConstraint(
171 this.placement == Roo.SplitBar.TOP ? c1 : c2,
172 this.placement == Roo.SplitBar.TOP ? c2 : c1
175 this.dragSpecs.startSize = size;
176 this.dragSpecs.startPoint = [x, y];
177 Roo.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
181 * @private Called after the drag operation by the DDProxy
183 onEndProxyDrag : function(e){
184 Roo.get(this.proxy).setDisplayed(false);
185 var endPoint = Roo.lib.Event.getXY(e);
190 if(this.orientation == Roo.SplitBar.HORIZONTAL){
191 newSize = this.dragSpecs.startSize +
192 (this.placement == Roo.SplitBar.LEFT ?
193 endPoint[0] - this.dragSpecs.startPoint[0] :
194 this.dragSpecs.startPoint[0] - endPoint[0]
197 newSize = this.dragSpecs.startSize +
198 (this.placement == Roo.SplitBar.TOP ?
199 endPoint[1] - this.dragSpecs.startPoint[1] :
200 this.dragSpecs.startPoint[1] - endPoint[1]
203 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
204 if(newSize != this.dragSpecs.startSize){
205 if(this.fireEvent('beforeapply', this, newSize) !== false){
206 this.adapter.setElementSize(this, newSize);
207 this.fireEvent("moved", this, newSize);
208 this.fireEvent("resize", this, newSize);
214 * Get the adapter this SplitBar uses
215 * @return The adapter object
217 getAdapter : function(){
222 * Set the adapter this SplitBar uses
223 * @param {Object} adapter A SplitBar adapter object
225 setAdapter : function(adapter){
226 this.adapter = adapter;
227 this.adapter.init(this);
231 * Gets the minimum size for the resizing element
232 * @return {Number} The minimum size
234 getMinimumSize : function(){
239 * Sets the minimum size for the resizing element
240 * @param {Number} minSize The minimum size
242 setMinimumSize : function(minSize){
243 this.minSize = minSize;
247 * Gets the maximum size for the resizing element
248 * @return {Number} The maximum size
250 getMaximumSize : function(){
255 * Sets the maximum size for the resizing element
256 * @param {Number} maxSize The maximum size
258 setMaximumSize : function(maxSize){
259 this.maxSize = maxSize;
263 * Sets the initialize size for the resizing element
264 * @param {Number} size The initial size
266 setCurrentSize : function(size){
267 var oldAnimate = this.animate;
268 this.animate = false;
269 this.adapter.setElementSize(this, size);
270 this.animate = oldAnimate;
274 * Destroy this splitbar.
275 * @param {Boolean} removeEl True to remove the element
277 destroy : function(removeEl){
282 this.proxy.parentNode.removeChild(this.proxy);
290 * @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.
292 Roo.SplitBar.createProxy = function(dir){
293 var proxy = new Roo.Element(document.createElement("div"));
294 proxy.unselectable();
295 var cls = 'x-splitbar-proxy';
296 proxy.addClass(cls + ' ' + (dir == Roo.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
297 document.body.appendChild(proxy.dom);
302 * @class Roo.SplitBar.BasicLayoutAdapter
303 * Default Adapter. It assumes the splitter and resizing element are not positioned
304 * elements and only gets/sets the width of the element. Generally used for table based layouts.
306 Roo.SplitBar.BasicLayoutAdapter = function(){
309 Roo.SplitBar.BasicLayoutAdapter.prototype = {
310 // do nothing for now
315 * Called before drag operations to get the current size of the resizing element.
316 * @param {Roo.SplitBar} s The SplitBar using this adapter
318 getElementSize : function(s){
319 if(s.orientation == Roo.SplitBar.HORIZONTAL){
320 return s.resizingEl.getWidth();
322 return s.resizingEl.getHeight();
327 * Called after drag operations to set the size of the resizing element.
328 * @param {Roo.SplitBar} s The SplitBar using this adapter
329 * @param {Number} newSize The new size to set
330 * @param {Function} onComplete A function to be invoked when resizing is complete
332 setElementSize : function(s, newSize, onComplete){
333 if(s.orientation == Roo.SplitBar.HORIZONTAL){
335 s.resizingEl.setWidth(newSize);
337 onComplete(s, newSize);
340 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
345 s.resizingEl.setHeight(newSize);
347 onComplete(s, newSize);
350 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
357 *@class Roo.SplitBar.AbsoluteLayoutAdapter
358 * @extends Roo.SplitBar.BasicLayoutAdapter
359 * Adapter that moves the splitter element to align with the resized sizing element.
360 * Used with an absolute positioned SplitBar.
361 * @param {String/HTMLElement/Roo.Element} container The container that wraps around the absolute positioned content. If it's
362 * document.body, make sure you assign an id to the body element.
364 Roo.SplitBar.AbsoluteLayoutAdapter = function(container){
365 this.basic = new Roo.SplitBar.BasicLayoutAdapter();
366 this.container = Roo.get(container);
369 Roo.SplitBar.AbsoluteLayoutAdapter.prototype = {
374 getElementSize : function(s){
375 return this.basic.getElementSize(s);
378 setElementSize : function(s, newSize, onComplete){
379 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
382 moveSplitter : function(s){
383 var yes = Roo.SplitBar;
386 s.el.setX(s.resizingEl.getRight());
389 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
392 s.el.setY(s.resizingEl.getBottom());
395 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
402 * Orientation constant - Create a vertical SplitBar
406 Roo.SplitBar.VERTICAL = 1;
409 * Orientation constant - Create a horizontal SplitBar
413 Roo.SplitBar.HORIZONTAL = 2;
416 * Placement constant - The resizing element is to the left of the splitter element
420 Roo.SplitBar.LEFT = 1;
423 * Placement constant - The resizing element is to the right of the splitter element
427 Roo.SplitBar.RIGHT = 2;
430 * Placement constant - The resizing element is positioned above the splitter element
434 Roo.SplitBar.TOP = 3;
437 * Placement constant - The resizing element is positioned under splitter element
441 Roo.SplitBar.BOTTOM = 4;