SplitBar.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:14k
源码类别:

JavaScript

开发平台:

JavaScript

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