1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  import org.aswing.ASColor;
     5  import org.aswing.ASFont;
     6  import org.aswing.ASTextExtent;
     7  import org.aswing.ASWingConstants;
     8  import org.aswing.ASWingUtils;
     9  import org.aswing.border.Border;
    10  import org.aswing.border.DecorateBorder;
    11  import org.aswing.Component;
    12  import org.aswing.geom.Dimension;
    13  import org.aswing.geom.Rectangle;
    14  import org.aswing.graphices.Graphics;
    15  import org.aswing.Insets;
    16  import org.aswing.utils.HashMap;
    17  
    18  /**
    19   * A poor Title Border.
    20   * @author iiley
    21   */
    22  class org.aswing.border.SimpleTitledBorder extends DecorateBorder{
    23  	
    24  	public static var TOP:Number = ASWingConstants.TOP;
    25  	public static var BOTTOM:Number = ASWingConstants.BOTTOM;
    26  	
    27  	public static var CENTER:Number = ASWingConstants.CENTER;
    28  	public static var LEFT:Number = ASWingConstants.LEFT;
    29  	public static var RIGHT:Number = ASWingConstants.RIGHT;
    30  	
    31  
    32      // Space between the border and the component's edge
    33      public static var EDGE_SPACING:Number = 0;	
    34  	
    35  	private var title:String;
    36  	private var position:Number;
    37  	private var align:Number;
    38  	private var offset:Number;
    39  	private var font:ASFont;
    40  	private var color:ASColor;
    41  	
    42  	private var textFields:HashMap;
    43  	private var textFieldExtent:ASTextExtent;
    44  	private var colorFontValid:Boolean;
    45  	
    46  	/**
    47  	 * SimpleTitledBorder(interior:Border, title:String, position:Number, align:Number, offset:Number, font:ASFont, color:ASColor)<br>
    48  	 * SimpleTitledBorder(interior:Border, title:String, position:Number, align:Number, offset:Number, font:ASFont)<br>
    49  	 * SimpleTitledBorder(interior:Border, title:String, position:Number, align:Number, offset:Number)<br>
    50  	 * SimpleTitledBorder(interior:Border, title:String, position:Number, align:Number,)<br>
    51  	 * SimpleTitledBorder(interior:Border, title:String, position:Number)<br>
    52  	 * SimpleTitledBorder(interior:Border, title:String)<br>
    53  	 * @param title the title text string.
    54  	 * @param position the position of the title(TOP or BOTTOM), default is TOP
    55  	 * @see #TOP
    56  	 * @see #BOTTOM
    57  	 * @param align the align of the title(CENTER or LEFT or RIGHT), default is CENTER
    58  	 * @see #CENTER
    59  	 * @see #LEFT
    60  	 * @see #RIGHT
    61  	 * @param offset the addition of title text's x position, default is 0
    62  	 * @param font the title text's ASFont
    63  	 * @param color the color of the title text
    64  	 * @see org.aswing.border.TitledBorder
    65  	 */
    66  	public function SimpleTitledBorder(interior:Border, title:String, position:Number, align:Number, offset:Number, font:ASFont, color:ASColor){
    67  		super(interior);
    68  		this.title = title;
    69  		this.position = (position==undefined ? TOP : position);
    70  		this.align = (align==undefined ? LEFT : align);
    71  		this.offset = (offset==undefined ? 0 : offset);
    72  		this.font = (font==undefined ? ASFont.getASFont(null , null) : font);
    73  		this.color = (color==undefined ? ASColor.BLACK : color);
    74  		textFields = new HashMap();
    75  		colorFontValid = false;
    76  	}
    77  	
    78  	
    79  	//------------get set-------------
    80  	
    81  		
    82  	public function getPosition():Number {
    83  		return position;
    84  	}
    85  
    86  	public function setPosition(position:Number):Void {
    87  		this.position = position;
    88  	}
    89  
    90  	public function getColor():ASColor {
    91  		return color;
    92  	}
    93  
    94  	public function setColor(color:ASColor):Void {
    95  		this.color = color;
    96  		this.invalidateColorFont();
    97  	}
    98  
    99  	public function getFont():ASFont {
   100  		return font;
   101  	}
   102  
   103  	public function setFont(font:ASFont):Void {
   104  		this.font = font;
   105  		this.invalidateColorFont();
   106  	}
   107  
   108  	public function getAlign():Number {
   109  		return align;
   110  	}
   111  
   112  	public function setAlign(align:Number):Void {
   113  		this.align = align;
   114  	}
   115  
   116  	public function getTitle():String {
   117  		return title;
   118  	}
   119  
   120  	public function setTitle(title:String):Void {
   121  		this.title = title;
   122  		this.invalidateExtent();
   123  		this.invalidateColorFont();
   124  	}
   125  
   126  	public function getOffset():Number {
   127  		return offset;
   128  	}
   129  
   130  	public function setOffset(offset:Number):Void {
   131  		this.offset = offset;
   132  	}
   133  	
   134  	private function invalidateExtent():Void{
   135  		textFieldExtent = null;
   136  	}
   137  	private function invalidateColorFont():Void{
   138  		colorFontValid = false;
   139  	}
   140  	
   141  	public function paintBorderImp(c:Component, g:Graphics, bounds:Rectangle):Void{
   142      	var text_field:TextField = TextField(textFields.get(c.getID()));
   143      	if(text_field == null){
   144  	    	text_field = c.createTextField("stitleBorder");
   145  	    	if(text_field != null){
   146      			text_field.text = title;
   147      			textFields.put(c.getID(), text_field);
   148  	    	}
   149      	}
   150      	if(text_field == null){
   151      		return;
   152      	}
   153      	if(!colorFontValid){
   154      		ASWingUtils.applyTextFontAndColor(text_field, font, color);
   155      		colorFontValid = true;
   156      	}
   157      	
   158      	var width:Number = text_field._width;
   159      	var height:Number = text_field._height;
   160      	var x:Number = offset;
   161      	if(align == LEFT){
   162      		x += bounds.x;
   163      	}else if(position == RIGHT){
   164      		x += (bounds.x + bounds.width - width);
   165      	}else{
   166      		x += (bounds.x + bounds.width/2 - width/2);
   167      	}
   168      	var y:Number = bounds.y + EDGE_SPACING;
   169      	if(position == BOTTOM){
   170      		y = bounds.y + bounds.height - height + EDGE_SPACING;
   171      	}
   172      	text_field._x = x;
   173      	text_field._y = y;
   174      }
   175      	   
   176      public function getBorderInsetsImp(c:Component, bounds:Rectangle):Insets{
   177      	var insets:Insets = new Insets();
   178      	var cs:Dimension = bounds.getSize();
   179      	if(textFieldExtent == null){
   180  			textFieldExtent = font.getASTextFormat().getTextExtent(title);
   181      	}
   182  		if(cs.width < textFieldExtent.getTextFieldWidth()){
   183  			var delta:Number = textFieldExtent.getTextFieldWidth() - cs.width;
   184  			if(align == RIGHT){
   185  				insets.left = delta;
   186  			}else if(align == CENTER){
   187  				insets.left = delta/2;
   188  				insets.right = delta/2;
   189  			}else{
   190  				insets.right = delta;
   191  			}
   192  		}
   193      	if(position == BOTTOM){
   194      		insets.bottom = EDGE_SPACING*2 + textFieldExtent.getTextFieldHeight();
   195      	}else{
   196      		insets.top = EDGE_SPACING*2 + textFieldExtent.getTextFieldHeight();
   197      	}
   198      	return insets;
   199      }
   200      	
   201  	public function uninstallBorderImp(com:Component):Void{
   202  		var text_field:TextField = TextField(textFields.remove(com.getID()));
   203  		text_field.removeTextField();
   204  	}
   205  }
   206