1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  
     5  import org.aswing.ASColor;
     6  import org.aswing.Component;
     7  import org.aswing.ElementCreater;
     8  import org.aswing.geom.Point;
     9  import org.aswing.geom.Rectangle;
    10  import org.aswing.graphices.Graphics;
    11  import org.aswing.graphices.Pen;
    12  import org.aswing.graphices.SolidBrush;
    13  import org.aswing.plaf.basic.frame.ResizeBarHandler;
    14  import org.aswing.plaf.basic.frame.ResizeStrategy;
    15  import org.aswing.plaf.basic.frame.ResizeStrategyImp;
    16  import org.aswing.plaf.UIResource;
    17  import org.aswing.UIManager;
    18  
    19  /**
    20   * Resizer is a resizer for Components to make it resizable when user mouse on component's edge.
    21   *
    22   * @author iiley
    23   */
    24  class org.aswing.plaf.basic.frame.Resizer implements org.aswing.Resizer, UIResource{
    25  	private static var RESIZE_MC_WIDTH:Number = 4;
    26  	
    27  	
    28  	private var com:Component;
    29  
    30  	//-----------resize equiments--------------
    31  	private var resizeMC:MovieClip;
    32  	
    33  	private var resizeArrowMC:MovieClip;
    34  	private var boundsMC:MovieClip;
    35  	
    36  	private var topResizeMC:MovieClip;
    37  	private var leftResizeMC:MovieClip;
    38  	private var bottomResizeMC:MovieClip;
    39  	private var rightResizeMC:MovieClip;
    40  	
    41  	private var topLeftResizeMC:MovieClip;
    42  	private var topRightResizeMC:MovieClip;
    43  	private var bottomLeftResizeMC:MovieClip;
    44  	private var bottomRightResizeMC:MovieClip;
    45  	
    46  	private var startX:Number;
    47  	private var startY:Number;
    48  	
    49  	private var enabled:Boolean;
    50  	private var resizeDirectly:Boolean;
    51  	
    52  	private var resizeArrowColor:ASColor;
    53  	private var resizeArrowLightColor:ASColor;
    54  	private var resizeArrowDarkColor:ASColor;
    55  	
    56  	private var listener:Object;
    57  	
    58  	/**
    59  	 * Create a Resizer for specified component.
    60  	 */
    61  	public function Resizer(){
    62  		enabled = true;
    63  		resizeDirectly = false;
    64  		startX = 0;
    65  		startY = 0;
    66  		
    67  	    resizeArrowColor = UIManager.getColor("Frame.resizeArrow");
    68  	    resizeArrowLightColor = UIManager.getColor("Frame.resizeArrowLight");
    69  	    resizeArrowDarkColor = UIManager.getColor("Frame.resizeArrowDark");	
    70  	}
    71  	
    72  	public function setOwner(c:Component):Void{
    73  		com.removeEventListener(listener);
    74  		com = c;
    75  		listener = com.addEventListener(Component.ON_PAINT, locate, this);
    76  	}
    77  	
    78  	/**
    79  	 * Attach the resizer's mc onto specified mc.
    80  	 */
    81  	public function createTo(mc:MovieClip):Void{
    82  		createResizeMCs(mc);
    83  	}
    84  
    85  	/**
    86  	 * <p>Indicate whether need resize component directly when drag the resizer arrow.
    87  	 * <p>if set to false, there will be a rectange to represent then size what will be resized to.
    88  	 * <p>if set to true, the component will be resize directly when drag, but this is need more cpu counting.
    89  	 * <p>Default is false.
    90  	 * @see org.aswing.JFrame
    91  	 */	
    92  	public function setResizeDirectly(r:Boolean):Void{
    93  		resizeDirectly = r;
    94  	}
    95  	
    96  	/**
    97  	 * Returns whether need resize component directly when drag the resizer arrow.
    98  	 * @see #setResizeDirectly
    99  	 */
   100  	public function isResizeDirectly():Boolean{
   101  		return resizeDirectly;
   102  	}
   103  	
   104  	//-----------------------For Handlers-------------------------
   105  	
   106  	public function setArrowRotation(r:Number):Void{
   107  		resizeArrowMC._rotation = r;
   108  	}
   109  	
   110  	public function hideArrow():Void{
   111  		resizeArrowMC._visible = false;
   112  	}
   113  	
   114  	public function showArrowToMousePos():Void{
   115  		resizeArrowMC._visible = true;
   116  		resizeArrowMC._x = resizeArrowMC._parent._xmouse;
   117  		resizeArrowMC._y = resizeArrowMC._parent._ymouse;		
   118  	}
   119  	
   120  	public function startDragArrow():Void{
   121  		resizeArrowMC.startDrag(true);
   122  	}
   123  	
   124  	public function stopDragArrow():Void{
   125  		resizeArrowMC.stopDrag();
   126  	}
   127  	
   128  	public function startResize(strategy:ResizeStrategy):Void{
   129  		if(!resizeDirectly){
   130  			boundsMC._visible = true;
   131  			representRect(com.getBounds());
   132  		}
   133  		startX = resizeMC._xmouse;
   134  		startY = resizeMC._ymouse;
   135  	}
   136  	
   137  	public function resizing(strategy:ResizeStrategy):Void{
   138  		var bounds:Rectangle = strategy.getBounds(com, resizeMC._xmouse - startX, resizeMC._ymouse - startY);
   139  		if(resizeDirectly){
   140  			com.setBounds(bounds);
   141  			com.validate();
   142  			updateAfterEvent();
   143  			startX = resizeMC._xmouse;//restart every time
   144  			startY = resizeMC._ymouse;//restart every time
   145  		}else{
   146  			representRect(bounds);
   147  		}
   148  	}
   149  	
   150  	public function finishResize(strategy:ResizeStrategy):Void{
   151  		if(!resizeDirectly){
   152  			com.setBounds(lastRepresentedBounds);
   153  			boundsMC._visible = false;
   154  			com.revalidate();
   155  		}
   156  	}
   157  	
   158  	private var lastRepresentedBounds:Rectangle;
   159  	
   160  	private function representRect(bounds:Rectangle):Void{
   161  		if(!resizeDirectly){
   162  			var currentPos:Point = com.getLocation();
   163  			var x:Number = bounds.x - currentPos.x;
   164  			var y:Number = bounds.y - currentPos.y;
   165  			var w:Number = bounds.width;
   166  			var h:Number = bounds.height;
   167  			var g:Graphics = new Graphics(boundsMC);
   168  			boundsMC.clear();
   169  			g.drawRectangle(new Pen(resizeArrowLightColor), x-1,y-1,w+2,h+2);
   170  			g.drawRectangle(new Pen(resizeArrowColor), x,y,w,h);
   171  			g.drawRectangle(new Pen(resizeArrowDarkColor), x+1,y+1,w-2,h-2);
   172  			lastRepresentedBounds = bounds;
   173  		}
   174  	}
   175  	
   176  	private function createResizeMCs(mc:MovieClip):Void{
   177  		var r:Number = RESIZE_MC_WIDTH;
   178  		var creater:ElementCreater = ElementCreater.getInstance();
   179  		
   180  		
   181  		
   182  		resizeMC.removeMovieClip();
   183  		resizeMC = creater.createMC(mc, "resizeMC");
   184  		resizeArrowMC = creater.createMC(resizeMC, "resizeArrowMC");
   185  		var w:Number = 1; //arrowAxisHalfWidth
   186  		var arrowPoints:Array = [{x:-r*2, y:0}, {x:-r, y:-r}, {x:-r, y:-w},
   187  								 {x:r, y:-w}, {x:r, y:-r}, {x:r*2, y:0},
   188  								 {x:r, y:r}, {x:r, y:w}, {x:-r, y:w},
   189  								 {x:-r, y:r}];
   190  								 
   191  		var gdi:Graphics;
   192  		gdi = new Graphics(resizeArrowMC);
   193  		gdi.drawPolygon(new Pen(resizeArrowColor.getRGB(), 4, 40), arrowPoints);
   194  		gdi.fillPolygon(new SolidBrush(resizeArrowLightColor), arrowPoints);
   195  		gdi.drawPolygon(new Pen(resizeArrowDarkColor, 1), arrowPoints);
   196  		resizeArrowMC._visible = false;
   197  		
   198  		boundsMC = creater.createMC(resizeMC, "boundsMC");
   199  		boundsMC._visible = false;
   200  		
   201  		topResizeMC = creater.createMC(resizeMC, "topResizeMC");
   202  		leftResizeMC = creater.createMC(resizeMC, "leftResizeMC");
   203  		rightResizeMC = creater.createMC(resizeMC, "rightResizeMC");
   204  		bottomResizeMC = creater.createMC(resizeMC, "bottomResizeMC");
   205  		
   206  		topLeftResizeMC = creater.createMC(resizeMC, "topLeftResizeMC");
   207  		topRightResizeMC = creater.createMC(resizeMC, "topRightResizeMC");
   208  		bottomLeftResizeMC = creater.createMC(resizeMC, "bottomLeftResizeMC");
   209  		bottomRightResizeMC = creater.createMC(resizeMC, "bottomRightResizeMC");	
   210  		
   211  		ResizeBarHandler.createHandler(this, topResizeMC, 90, new ResizeStrategyImp(0, -1));
   212  		ResizeBarHandler.createHandler(this, leftResizeMC, 0, new ResizeStrategyImp(-1, 0));
   213  		ResizeBarHandler.createHandler(this, rightResizeMC, 0, new ResizeStrategyImp(1, 0));
   214  		ResizeBarHandler.createHandler(this, bottomResizeMC, 90, new ResizeStrategyImp(0, 1));
   215  		
   216  		ResizeBarHandler.createHandler(this, topLeftResizeMC, 45, new ResizeStrategyImp(-1, -1));
   217  		ResizeBarHandler.createHandler(this, topRightResizeMC, -45, new ResizeStrategyImp(1, -1));
   218  		ResizeBarHandler.createHandler(this, bottomLeftResizeMC, -45, new ResizeStrategyImp(-1, 1));
   219  		ResizeBarHandler.createHandler(this, bottomRightResizeMC, 45, new ResizeStrategyImp(1, 1));
   220  		
   221  		var brush:SolidBrush = new SolidBrush(new ASColor(0, 0));
   222  		gdi = new Graphics(topResizeMC);
   223  		gdi.fillRectangle(brush, 0, 0, r, r);
   224  		gdi = new Graphics(leftResizeMC);
   225  		gdi.fillRectangle(brush, 0, 0, r, r);
   226  		gdi = new Graphics(rightResizeMC);
   227  		gdi.fillRectangle(brush, -r, 0, r, r);	
   228  		gdi = new Graphics(bottomResizeMC);
   229  		gdi.fillRectangle(brush, 0, -r, r, r);	
   230  		
   231  		gdi = new Graphics(topLeftResizeMC);
   232  		gdi.fillRectangle(brush, 0, 0, r*2, r);
   233  		gdi.fillRectangle(brush, 0, 0, r, r*2);
   234  		gdi = new Graphics(topRightResizeMC);
   235  		gdi.fillRectangle(brush, -r*2, 0, r*2, r);
   236  		gdi.fillRectangle(brush, -r, 0, r, r*2);
   237  		gdi = new Graphics(bottomLeftResizeMC);
   238  		gdi.fillRectangle(brush, 0, -r, r*2, r);
   239  		gdi.fillRectangle(brush, 0, -r*2, r, r*2);
   240  		gdi = new Graphics(bottomRightResizeMC);
   241  		gdi.fillRectangle(brush, -r*2, -r, r*2, r);
   242  		gdi.fillRectangle(brush, -r, -r*2, r, r*2);
   243  		
   244  		resizeMC._visible = enabled;
   245  	}
   246  	
   247  	public function setEnabled(e:Boolean):Void{
   248  		enabled = e;
   249  		resizeMC._visible = enabled;
   250  	}
   251  	
   252  	public function isEnabled():Boolean{
   253  		return enabled;
   254  	}
   255  	
   256  	/**
   257  	 * Locate the resizer mcs to fit the component.
   258  	 */
   259  	private function locate():Void{
   260  		//var x:Number = 0;
   261  		//var y:Number = 0;
   262  		var w:Number = com.getWidth();
   263  		var h:Number = com.getHeight();
   264  		var r:Number = RESIZE_MC_WIDTH;
   265  		
   266  		topResizeMC._width = Math.max(0, w-r*2);
   267  		topResizeMC._x = r;
   268  		topResizeMC._y = 0;
   269  		leftResizeMC._height = Math.max(0, h-r*2);
   270  		leftResizeMC._x = 0;
   271  		leftResizeMC._y = r;
   272  		rightResizeMC._height = Math.max(0, h-r*2);
   273  		rightResizeMC._x = w;
   274  		rightResizeMC._y = r;
   275  		bottomResizeMC._width = Math.max(0, w-r*2);
   276  		bottomResizeMC._x = r;
   277  		bottomResizeMC._y = h;
   278  		
   279  		topLeftResizeMC._x = 0;
   280  		topLeftResizeMC._y = 0;
   281  		topRightResizeMC._x = w;
   282  		topRightResizeMC._y = 0;
   283  		bottomLeftResizeMC._x = 0;
   284  		bottomLeftResizeMC._y = h;
   285  		bottomRightResizeMC._x = w;
   286  		bottomRightResizeMC._y = h;
   287  	}
   288  }
   289