1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  
     5  import org.aswing.border.Border;
     6  import org.aswing.Component;
     7  import org.aswing.ElementCreater;
     8  import org.aswing.Event;
     9  import org.aswing.Icon;
    10  import org.aswing.utils.Delegate;
    11  import org.aswing.utils.HashMap;
    12  import org.aswing.utils.MCUtils;
    13   
    14  /**
    15   * ComponentDecorator, manage a decorator for a component. Creats MCs TextFields for a component.
    16   * One component's can only manage one decorator MC or TextFiled in one Components by a ComponentDecorator.
    17   * @author iiley
    18   */
    19  class org.aswing.ComponentDecorator {
    20  	
    21  	public static function get creater():ElementCreater{
    22  		return ElementCreater.getInstance();
    23  	}
    24  	//////////////////////////////////////Utils For Decorators//////////////////////////////////////
    25  	/**	 
    26  	 * This method add a listener to the component, make to do icon uninstallation 
    27  	 * at next component painting time, this avoid the icon flicker before paint.
    28  	 * <p>
    29  	 * This function usually be used when you changed a icon for a component and then 
    30  	 * call <code>repaint</code> to redraw. But if you call <code>repaintImmediately</code> 
    31  	 * to redraw the component, you should not call this method, just call <code>Icon.uninstallIcon</code> 
    32  	 * generally.
    33  	 * @see org.aswing.Icon#uninstallIcon()
    34  	 */
    35  	public static function removeIconWhenNextPaint(com:Component, icon:Icon):Void{
    36  		var listener:Object = new Object();
    37  		listener[Component.ON_PAINT] = Delegate.create(ComponentDecorator, _removeIcon, icon, listener);
    38  		com.addEventListener(listener);
    39  	}
    40  	private static function _removeIcon(event:Event, icon:Icon, listener:Object):Void{
    41  		var com:Component = Component(event.getSource());
    42  		icon.uninstallIcon(com);
    43  		com.removeEventListener(listener);
    44  	}
    45  	
    46  	/**	 
    47  	 * This method add a listener to the component, make to do border uninstallation 
    48  	 * at next component painting time, this avoid the border flicker before paint.
    49  	 * <p>
    50  	 * This function usually be used when you changed a border for a component and then 
    51  	 * call <code>repaint</code> to redraw. But if you call <code>repaintImmediately</code> 
    52  	 * to redraw the component, you should not call this method, just call <code>Border.uninstallBorder</code> 
    53  	 * generally.
    54  	 * @see org.aswing.border.Border#uninstallBorder()
    55  	 */
    56  	public static function removeBorderWhenNextPaint(com:Component, border:Border):Void{
    57  		var listener:Object = new Object();
    58  		listener[Component.ON_PAINT] = Delegate.create(ComponentDecorator, _removeBorder, border, listener);
    59  		com.addEventListener(listener);
    60  	}
    61  	private static function _removeBorder(event:Event, border:Border, listener:Object):Void{
    62  		var com:Component = Component(event.getSource());
    63  		border.uninstallBorder(com);
    64  		com.removeEventListener(listener);
    65  	}	
    66  	
    67  	/////////////////////////////////////////////////////////////////////////////////////////////
    68  	
    69  	private var mcMap:HashMap;
    70  	private var tfMap:HashMap;
    71  	
    72  	public function ComponentDecorator(){
    73  		mcMap = new HashMap();
    74  		tfMap = new HashMap();
    75  	}
    76  	
    77  	public function createDecorateMC(c:Component):MovieClip{
    78  		var mc:MovieClip = c.createMovieClip("decorator");
    79  		if(MCUtils.isMovieClipExist(mc)){
    80  			mcMap.put(c.getID(), mc);
    81  			return mc;
    82  		}else{
    83  			return null;
    84  		}
    85  	}
    86  	
    87  	public function createDecorateTextField(c:Component):TextField{
    88  		var tf:TextField = c.createTextField("decor_txt");
    89  			if(MCUtils.isTextFieldExist(tf)){
    90  			tfMap.put(c.getID(), tf);
    91  			return tf;
    92  		}else{
    93  			return null;
    94  		}
    95  	}
    96  	
    97  	public function attachDecrateMC(c:Component, linkage:String):MovieClip{
    98  		var mc:MovieClip = c.attachMovieClip(linkage, "deco_att");
    99  		if(MCUtils.isMovieClipExist(mc)){
   100  			mcMap.put(c.getID(), mc);
   101  			return mc;
   102  		}else{
   103  			return null;
   104  		}
   105  	}
   106  	
   107  	public function getCreateDecorateMC(c:Component):MovieClip{
   108  		var mc:MovieClip = getDecorateMC(c);
   109  		if(!MCUtils.isMovieClipExist(mc)){
   110  			return createDecorateMC(c);
   111  		}else{
   112  			return mc;
   113  		}
   114  	}
   115  	
   116  	public function getCreateDecorateTextField(c:Component):TextField{
   117  		var tf:TextField = getDecorateTextField(c);
   118  		if(tf == null || tf.toString()==null){
   119  			return createDecorateTextField(c);
   120  		}else{
   121  			return tf;
   122  		}
   123  	}
   124  	
   125  	public function getAttachDecorateMC(c:Component, linkage:String):MovieClip{
   126  		var mc:MovieClip = getDecorateMC(c);
   127  		if(!MCUtils.isMovieClipExist(mc)){
   128  			return attachDecrateMC(c, linkage);
   129  		}else{
   130  			return mc;
   131  		}
   132  	}	
   133  	
   134  	public function getDecorateMC(c:Component):MovieClip{
   135  		return MovieClip(mcMap.get(c.getID()));
   136  	}
   137  	
   138  	public function getDecorateTextField(c:Component):TextField{
   139  		return TextField(tfMap.get(c.getID()));
   140  	}
   141  	
   142  	public function removeDecorateMC(c:Component):Void{
   143  		var mc:MovieClip = MovieClip(mcMap.remove(c.getID()));
   144  		mc.unloadMovie();
   145  		mc.removeMovieClip();
   146  	}
   147  	
   148  	public function removeDecorateTextField(c:Component):Void{
   149  		var tf:TextField = TextField(tfMap.remove(c.getID()));
   150  		tf.unloadMovie();
   151  		tf.removeMovieClip();
   152  	}
   153  		
   154  	/**
   155  	 * This casue to call <code>uninstallDecorateExtra</code> and 
   156  	 * remove decorate mcs created for the component.
   157  	 */
   158  	public function uninstallDecorate(com:Component):Void{
   159  		uninstallDecorateExtra(com);
   160  		removeDecorateMC(com);
   161  		removeDecorateTextField(com);
   162  	}
   163  	
   164  	/**
   165  	 * Override this method to do your uninstall in sub-class
   166  	 */
   167  	private function uninstallDecorateExtra(com:Component):Void{
   168  	}
   169  }
   170