431 lines
No EOL
16 KiB
HTML
431 lines
No EOL
16 KiB
HTML
<html><head><title>SplitBar.js</title><link rel="stylesheet" type="text/css" href="../resources/style.css" media="screen"/></head><body><h1>SplitBar.js</h1><pre class="highlighted"><code><i>/**
|
|
* @class Ext.SplitBar
|
|
* @extends Ext.util.Observable
|
|
* Creates draggable splitter bar functionality from two elements.
|
|
* <br><br>
|
|
* Usage:
|
|
* <pre><code>
|
|
<b>var</b> split = <b>new</b> Ext.SplitBar("elementToDrag", "elementToSize",
|
|
Ext.SplitBar.HORIZONTAL, Ext.SplitBar.LEFT);
|
|
split.setAdapter(<b>new</b> Ext.SplitBar.AbsoluteLayoutAdapter("container"));
|
|
split.minSize = 100;
|
|
split.maxSize = 600;
|
|
split.animate = true;
|
|
split.on('moved', splitterMoved);
|
|
</code></pre>
|
|
* @constructor
|
|
* Create a <b>new</b> SplitBar
|
|
* @param {String/HTMLElement/Element} dragElement The element to be dragged and act as the SplitBar.
|
|
* @param {String/HTMLElement/Element} resizingElement The element to be resized based on where the SplitBar element is dragged
|
|
* @param {Number} orientation (optional) Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
|
|
* @param {Number} placement (optional) Either Ext.SplitBar.LEFT or Ext.SplitBar.RIGHT <b>for</b> horizontal or
|
|
Ext.SplitBar.TOP or Ext.SplitBar.BOTTOM <b>for</b> vertical. (By <b>default</b>, <b>this</b> is determined automatically by the intial position
|
|
position of the SplitBar).
|
|
*/</i>
|
|
Ext.SplitBar = <b>function</b>(dragElement, resizingElement, orientation, placement, existingProxy){
|
|
|
|
<i>/** @private */</i>
|
|
<b>this</b>.el = Ext.get(dragElement, true);
|
|
<b>this</b>.el.dom.unselectable = "on";
|
|
<i>/** @private */</i>
|
|
<b>this</b>.resizingEl = Ext.get(resizingElement, true);
|
|
|
|
<i>/**
|
|
* @private
|
|
* The orientation of the split. Either Ext.SplitBar.HORIZONTAL or Ext.SplitBar.VERTICAL. (Defaults to HORIZONTAL)
|
|
* Note: If <b>this</b> is changed after creating the SplitBar, the placement property must be manually updated
|
|
* @type Number
|
|
*/</i>
|
|
<b>this</b>.orientation = orientation || Ext.SplitBar.HORIZONTAL;
|
|
|
|
<i>/**
|
|
* The minimum size of the resizing element. (Defaults to 0)
|
|
* @type Number
|
|
*/</i>
|
|
<b>this</b>.minSize = 0;
|
|
|
|
<i>/**
|
|
* The maximum size of the resizing element. (Defaults to 2000)
|
|
* @type Number
|
|
*/</i>
|
|
<b>this</b>.maxSize = 2000;
|
|
|
|
<i>/**
|
|
* Whether to animate the transition to the <b>new</b> size
|
|
* @type Boolean
|
|
*/</i>
|
|
<b>this</b>.animate = false;
|
|
|
|
<i>/**
|
|
* Whether to create a transparent shim that overlays the page when dragging, enables dragging across iframes.
|
|
* @type Boolean
|
|
*/</i>
|
|
<b>this</b>.useShim = false;
|
|
|
|
<i>/** @private */</i>
|
|
<b>this</b>.shim = null;
|
|
|
|
<b>if</b>(!existingProxy){
|
|
<i>/** @private */</i>
|
|
<b>this</b>.proxy = Ext.SplitBar.createProxy(<b>this</b>.orientation);
|
|
}<b>else</b>{
|
|
<b>this</b>.proxy = Ext.get(existingProxy).dom;
|
|
}
|
|
<i>/** @private */</i>
|
|
<b>this</b>.dd = <b>new</b> Ext.dd.DDProxy(<b>this</b>.el.dom.id, "XSplitBars", {dragElId : <b>this</b>.proxy.id});
|
|
|
|
<i>/** @private */</i>
|
|
<b>this</b>.dd.b4StartDrag = <b>this</b>.onStartProxyDrag.createDelegate(<b>this</b>);
|
|
|
|
<i>/** @private */</i>
|
|
<b>this</b>.dd.endDrag = <b>this</b>.onEndProxyDrag.createDelegate(<b>this</b>);
|
|
|
|
<i>/** @private */</i>
|
|
<b>this</b>.dragSpecs = {};
|
|
|
|
<i>/**
|
|
* @private The adapter to use to positon and resize elements
|
|
*/</i>
|
|
<b>this</b>.adapter = <b>new</b> Ext.SplitBar.BasicLayoutAdapter();
|
|
<b>this</b>.adapter.init(<b>this</b>);
|
|
|
|
<b>if</b>(this.orientation == Ext.SplitBar.HORIZONTAL){
|
|
<i>/** @private */</i>
|
|
<b>this</b>.placement = placement || (<b>this</b>.el.getX() > <b>this</b>.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
|
|
<b>this</b>.el.addClass("x-splitbar-h");
|
|
}<b>else</b>{
|
|
<i>/** @private */</i>
|
|
<b>this</b>.placement = placement || (<b>this</b>.el.getY() > <b>this</b>.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
|
|
<b>this</b>.el.addClass("x-splitbar-v");
|
|
}
|
|
|
|
<b>this</b>.addEvents({
|
|
<i>/**
|
|
* @event resize
|
|
* Fires when the splitter is moved (alias <b>for</b> moved)
|
|
* @param {Ext.SplitBar} <b>this</b>
|
|
* @param {Number} newSize the <b>new</b> width or height
|
|
*/</i>
|
|
"resize" : true,
|
|
<i>/**
|
|
* @event moved
|
|
* Fires when the splitter is moved
|
|
* @param {Ext.SplitBar} <b>this</b>
|
|
* @param {Number} newSize the <b>new</b> width or height
|
|
*/</i>
|
|
"moved" : true,
|
|
<i>/**
|
|
* @event beforeresize
|
|
* Fires before the splitter is dragged
|
|
* @param {Ext.SplitBar} <b>this</b>
|
|
*/</i>
|
|
"beforeresize" : true,
|
|
|
|
"beforeapply" : true
|
|
});
|
|
|
|
Ext.SplitBar.superclass.constructor.call(<b>this</b>);
|
|
};
|
|
|
|
Ext.extend(Ext.SplitBar, Ext.util.Observable, {
|
|
onStartProxyDrag : <b>function</b>(x, y){
|
|
<b>this</b>.fireEvent("beforeresize", <b>this</b>);
|
|
<b>if</b>(!<b>this</b>.overlay){
|
|
<b>var</b> o = Ext.DomHelper.insertFirst(document.body, {cls: "x-drag-overlay", html: "&#160;"}, true);
|
|
o.unselectable();
|
|
o.enableDisplayMode("block");
|
|
<i>// all splitbars share the same overlay</i>
|
|
Ext.SplitBar.prototype.overlay = o;
|
|
}
|
|
<b>this</b>.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
|
|
<b>this</b>.overlay.show();
|
|
Ext.get(<b>this</b>.proxy).setDisplayed("block");
|
|
<b>var</b> size = <b>this</b>.adapter.getElementSize(<b>this</b>);
|
|
<b>this</b>.activeMinSize = <b>this</b>.getMinimumSize();;
|
|
<b>this</b>.activeMaxSize = <b>this</b>.getMaximumSize();;
|
|
<b>var</b> c1 = size - <b>this</b>.activeMinSize;
|
|
<b>var</b> c2 = Math.max(<b>this</b>.activeMaxSize - size, 0);
|
|
<b>if</b>(this.orientation == Ext.SplitBar.HORIZONTAL){
|
|
<b>this</b>.dd.resetConstraints();
|
|
<b>this</b>.dd.setXConstraint(
|
|
<b>this</b>.placement == Ext.SplitBar.LEFT ? c1 : c2,
|
|
<b>this</b>.placement == Ext.SplitBar.LEFT ? c2 : c1
|
|
);
|
|
<b>this</b>.dd.setYConstraint(0, 0);
|
|
}<b>else</b>{
|
|
<b>this</b>.dd.resetConstraints();
|
|
<b>this</b>.dd.setXConstraint(0, 0);
|
|
<b>this</b>.dd.setYConstraint(
|
|
<b>this</b>.placement == Ext.SplitBar.TOP ? c1 : c2,
|
|
<b>this</b>.placement == Ext.SplitBar.TOP ? c2 : c1
|
|
);
|
|
}
|
|
<b>this</b>.dragSpecs.startSize = size;
|
|
<b>this</b>.dragSpecs.startPoint = [x, y];
|
|
Ext.dd.DDProxy.prototype.b4StartDrag.call(<b>this</b>.dd, x, y);
|
|
},
|
|
|
|
<i>/**
|
|
* @private Called after the drag operation by the DDProxy
|
|
*/</i>
|
|
onEndProxyDrag : <b>function</b>(e){
|
|
Ext.get(<b>this</b>.proxy).setDisplayed(false);
|
|
<b>var</b> endPoint = Ext.lib.Event.getXY(e);
|
|
<b>if</b>(this.overlay){
|
|
<b>this</b>.overlay.hide();
|
|
}
|
|
<b>var</b> newSize;
|
|
<b>if</b>(this.orientation == Ext.SplitBar.HORIZONTAL){
|
|
newSize = <b>this</b>.dragSpecs.startSize +
|
|
(<b>this</b>.placement == Ext.SplitBar.LEFT ?
|
|
endPoint[0] - <b>this</b>.dragSpecs.startPoint[0] :
|
|
<b>this</b>.dragSpecs.startPoint[0] - endPoint[0]
|
|
);
|
|
}<b>else</b>{
|
|
newSize = <b>this</b>.dragSpecs.startSize +
|
|
(<b>this</b>.placement == Ext.SplitBar.TOP ?
|
|
endPoint[1] - <b>this</b>.dragSpecs.startPoint[1] :
|
|
<b>this</b>.dragSpecs.startPoint[1] - endPoint[1]
|
|
);
|
|
}
|
|
newSize = Math.min(Math.max(newSize, <b>this</b>.activeMinSize), <b>this</b>.activeMaxSize);
|
|
<b>if</b>(newSize != <b>this</b>.dragSpecs.startSize){
|
|
<b>if</b>(this.fireEvent('beforeapply', <b>this</b>, newSize) !== false){
|
|
<b>this</b>.adapter.setElementSize(<b>this</b>, newSize);
|
|
<b>this</b>.fireEvent("moved", <b>this</b>, newSize);
|
|
<b>this</b>.fireEvent("resize", <b>this</b>, newSize);
|
|
}
|
|
}
|
|
},
|
|
|
|
<i>/**
|
|
* Get the adapter <b>this</b> SplitBar uses
|
|
* @<b>return</b> The adapter object
|
|
*/</i>
|
|
getAdapter : <b>function</b>(){
|
|
<b>return</b> this.adapter;
|
|
},
|
|
|
|
<i>/**
|
|
* Set the adapter <b>this</b> SplitBar uses
|
|
* @param {Object} adapter A SplitBar adapter object
|
|
*/</i>
|
|
setAdapter : <b>function</b>(adapter){
|
|
<b>this</b>.adapter = adapter;
|
|
<b>this</b>.adapter.init(<b>this</b>);
|
|
},
|
|
|
|
<i>/**
|
|
* Gets the minimum size <b>for</b> the resizing element
|
|
* @<b>return</b> {Number} The minimum size
|
|
*/</i>
|
|
getMinimumSize : <b>function</b>(){
|
|
<b>return</b> this.minSize;
|
|
},
|
|
|
|
<i>/**
|
|
* Sets the minimum size <b>for</b> the resizing element
|
|
* @param {Number} minSize The minimum size
|
|
*/</i>
|
|
setMinimumSize : <b>function</b>(minSize){
|
|
<b>this</b>.minSize = minSize;
|
|
},
|
|
|
|
<i>/**
|
|
* Gets the maximum size <b>for</b> the resizing element
|
|
* @<b>return</b> {Number} The maximum size
|
|
*/</i>
|
|
getMaximumSize : <b>function</b>(){
|
|
<b>return</b> this.maxSize;
|
|
},
|
|
|
|
<i>/**
|
|
* Sets the maximum size <b>for</b> the resizing element
|
|
* @param {Number} maxSize The maximum size
|
|
*/</i>
|
|
setMaximumSize : <b>function</b>(maxSize){
|
|
<b>this</b>.maxSize = maxSize;
|
|
},
|
|
|
|
<i>/**
|
|
* Sets the initialize size <b>for</b> the resizing element
|
|
* @param {Number} size The initial size
|
|
*/</i>
|
|
setCurrentSize : <b>function</b>(size){
|
|
<b>var</b> oldAnimate = <b>this</b>.animate;
|
|
<b>this</b>.animate = false;
|
|
<b>this</b>.adapter.setElementSize(<b>this</b>, size);
|
|
<b>this</b>.animate = oldAnimate;
|
|
},
|
|
|
|
<i>/**
|
|
* Destroy <b>this</b> splitbar.
|
|
* @param {Boolean} removeEl True to remove the element
|
|
*/</i>
|
|
destroy : <b>function</b>(removeEl){
|
|
<b>if</b>(this.shim){
|
|
<b>this</b>.shim.remove();
|
|
}
|
|
<b>this</b>.dd.unreg();
|
|
<b>this</b>.proxy.parentNode.removeChild(<b>this</b>.proxy);
|
|
<b>if</b>(removeEl){
|
|
<b>this</b>.el.remove();
|
|
}
|
|
}
|
|
});
|
|
|
|
<i>/**
|
|
* @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.
|
|
*/</i>
|
|
Ext.SplitBar.createProxy = <b>function</b>(dir){
|
|
<b>var</b> proxy = <b>new</b> Ext.Element(document.createElement("div"));
|
|
proxy.unselectable();
|
|
<b>var</b> cls = 'x-splitbar-proxy';
|
|
proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
|
|
document.body.appendChild(proxy.dom);
|
|
<b>return</b> proxy.dom;
|
|
};
|
|
|
|
<i>/**
|
|
* @class Ext.SplitBar.BasicLayoutAdapter
|
|
* Default Adapter. It assumes the splitter and resizing element are not positioned
|
|
* elements and only gets/sets the width of the element. Generally used <b>for</b> table based layouts.
|
|
*/</i>
|
|
Ext.SplitBar.BasicLayoutAdapter = <b>function</b>(){
|
|
};
|
|
|
|
Ext.SplitBar.BasicLayoutAdapter.prototype = {
|
|
<i>// <b>do</b> nothing <b>for</b> now</i>
|
|
init : <b>function</b>(s){
|
|
|
|
},
|
|
<i>/**
|
|
* Called before drag operations to get the current size of the resizing element.
|
|
* @param {Ext.SplitBar} s The SplitBar using <b>this</b> adapter
|
|
*/</i>
|
|
getElementSize : <b>function</b>(s){
|
|
<b>if</b>(s.orientation == Ext.SplitBar.HORIZONTAL){
|
|
<b>return</b> s.resizingEl.getWidth();
|
|
}<b>else</b>{
|
|
<b>return</b> s.resizingEl.getHeight();
|
|
}
|
|
},
|
|
|
|
<i>/**
|
|
* Called after drag operations to set the size of the resizing element.
|
|
* @param {Ext.SplitBar} s The SplitBar using <b>this</b> adapter
|
|
* @param {Number} newSize The <b>new</b> size to set
|
|
* @param {Function} onComplete A <b>function</b> to be invoke when resizing is complete
|
|
*/</i>
|
|
setElementSize : <b>function</b>(s, newSize, onComplete){
|
|
<b>if</b>(s.orientation == Ext.SplitBar.HORIZONTAL){
|
|
<b>if</b>(!s.animate){
|
|
s.resizingEl.setWidth(newSize);
|
|
<b>if</b>(onComplete){
|
|
onComplete(s, newSize);
|
|
}
|
|
}<b>else</b>{
|
|
s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
|
|
}
|
|
}<b>else</b>{
|
|
|
|
<b>if</b>(!s.animate){
|
|
s.resizingEl.setHeight(newSize);
|
|
<b>if</b>(onComplete){
|
|
onComplete(s, newSize);
|
|
}
|
|
}<b>else</b>{
|
|
s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
<i>/**
|
|
*@class Ext.SplitBar.AbsoluteLayoutAdapter
|
|
* @extends Ext.SplitBar.BasicLayoutAdapter
|
|
* Adapter that moves the splitter element to align <b>with</b> the resized sizing element.
|
|
* Used <b>with</b> an absolute positioned SplitBar.
|
|
* @param {String/HTMLElement/Element} container The container that wraps around the absolute positioned content. If it's
|
|
* document.body, make sure you assign an id to the body element.
|
|
*/</i>
|
|
Ext.SplitBar.AbsoluteLayoutAdapter = <b>function</b>(container){
|
|
<b>this</b>.basic = <b>new</b> Ext.SplitBar.BasicLayoutAdapter();
|
|
<b>this</b>.container = Ext.get(container);
|
|
};
|
|
|
|
Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
|
|
init : <b>function</b>(s){
|
|
<b>this</b>.basic.init(s);
|
|
},
|
|
|
|
getElementSize : <b>function</b>(s){
|
|
<b>return</b> this.basic.getElementSize(s);
|
|
},
|
|
|
|
setElementSize : <b>function</b>(s, newSize, onComplete){
|
|
<b>this</b>.basic.setElementSize(s, newSize, <b>this</b>.moveSplitter.createDelegate(<b>this</b>, [s]));
|
|
},
|
|
|
|
moveSplitter : <b>function</b>(s){
|
|
<b>var</b> yes = Ext.SplitBar;
|
|
<b>switch</b>(s.placement){
|
|
<b>case</b> yes.LEFT:
|
|
s.el.setX(s.resizingEl.getRight());
|
|
<b>break</b>;
|
|
<b>case</b> yes.RIGHT:
|
|
s.el.setStyle("right", (<b>this</b>.container.getWidth() - s.resizingEl.getLeft()) + "px");
|
|
<b>break</b>;
|
|
<b>case</b> yes.TOP:
|
|
s.el.setY(s.resizingEl.getBottom());
|
|
<b>break</b>;
|
|
<b>case</b> yes.BOTTOM:
|
|
s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
|
|
<b>break</b>;
|
|
}
|
|
}
|
|
};
|
|
|
|
<i>/**
|
|
* Orientation constant - Create a vertical SplitBar
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.VERTICAL = 1;
|
|
|
|
<i>/**
|
|
* Orientation constant - Create a horizontal SplitBar
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.HORIZONTAL = 2;
|
|
|
|
<i>/**
|
|
* Placement constant - The resizing element is to the left of the splitter element
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.LEFT = 1;
|
|
|
|
<i>/**
|
|
* Placement constant - The resizing element is to the right of the splitter element
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.RIGHT = 2;
|
|
|
|
<i>/**
|
|
* Placement constant - The resizing element is positioned above the splitter element
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.TOP = 3;
|
|
|
|
<i>/**
|
|
* Placement constant - The resizing element is positioned under splitter element
|
|
* @static
|
|
* @type Number
|
|
*/</i>
|
|
Ext.SplitBar.BOTTOM = 4;
|
|
</code></pre><hr><div style="font-size:10px;text-align:center;color:gray;">Ext - Copyright © 2006-2007 Ext JS, LLC<br />All rights reserved.</div>
|
|
</body></html> |