1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  import org.aswing.ASColor;
     5  import org.aswing.ASFont;
     6  import org.aswing.ASWingUtils;
     7  import org.aswing.border.Border;
     8  import org.aswing.Component;
     9  import org.aswing.geom.Dimension;
    10  import org.aswing.geom.Rectangle;
    11  import org.aswing.graphices.Graphics;
    12  import org.aswing.Icon;
    13  import org.aswing.JLabel;
    14  import org.aswing.LookAndFeel;
    15  import org.aswing.plaf.ComponentUI;
    16  import org.aswing.plaf.LabelUI;
    17  import org.aswing.utils.HashMap;
    18  
    19  /**
    20   *
    21   * @author iiley
    22   */
    23  class org.aswing.plaf.basic.BasicLabelUI extends LabelUI {
    24      // Shared UI object
    25      private static var labelUI:BasicLabelUI;
    26          
    27     	//map to recored the buttons -> last painted icon
    28     	private var lastPaintedIconMap:HashMap;
    29     	//map to recored the buttons -> topTextField
    30     	private var topTextFieldMap:HashMap;
    31     	//map to recored the buttons -> bottomTextField
    32     	private var bottomTextFieldMap:HashMap;
    33  
    34      private static var propertyPrefix:String = "Label" + ".";
    35  
    36      // ********************************
    37      //          Create PLAF
    38      // ********************************
    39      public static function createInstance(c:Component):ComponentUI {
    40      	if(labelUI == null){
    41      		labelUI = new BasicLabelUI();
    42      	}
    43          return labelUI;
    44      }
    45  
    46      private function getPropertyPrefix():String {
    47          return propertyPrefix;
    48      }
    49      	
    50      public function BasicLabelUI() {
    51      	super();
    52      	lastPaintedIconMap = new HashMap();
    53      	topTextFieldMap = new HashMap();
    54      	bottomTextFieldMap = new HashMap();
    55      	checkRectsForCountLayout();
    56      }
    57  
    58      public function installUI(c:Component):Void{
    59      	var b:JLabel = JLabel(c);
    60          installDefaults(b);
    61          installListeners(b);
    62      }
    63      
    64      private var defaultForeground:ASColor;
    65      private var defaultBackground:ASColor;
    66      private var defaultTextFormat:TextFormat;
    67      private var defaultBorder:Border;    
    68  
    69  	private function installDefaults(b:JLabel):Void{
    70          // load shared instance defaults
    71          var pp:String = getPropertyPrefix();
    72  
    73          LookAndFeel.installColorsAndFont(b, pp + "background", pp + "foreground", pp + "font");
    74          LookAndFeel.installBorder(b, pp + "border");
    75  	}
    76  	
    77  	private function installListeners(b:JLabel):Void{
    78  	}
    79  		
    80  	
    81      public function uninstallUI(c:Component):Void{
    82      	var b:JLabel = JLabel(c);
    83          uninstallDefaults(b);
    84          uninstallListeners(b);
    85          removeMCs(b);
    86      	lastPaintedIconMap.remove(c.getID());
    87      	topTextFieldMap.remove(c.getID());
    88      	bottomTextFieldMap.remove(c.getID());
    89      }
    90      
    91      private function uninstallDefaults(b:JLabel):Void{
    92      	LookAndFeel.uninstallBorder(b);
    93      }
    94      
    95      private function uninstallListeners(b:JLabel):Void{
    96      }
    97          
    98      private function removeMCs(c:Component):Void{
    99      	getTopTextField(c).removeTextField();
   100      	getBottomTextField(c).removeTextField();
   101      }
   102      
   103      public function create(c:Component):Void{
   104      	var topText:TextField = c.createTextField("t_text");
   105      	var bottomText:TextField = c.createTextField("b_text");
   106      	topTextFieldMap.put(c.getID(), topText);
   107      	bottomTextFieldMap.put(c.getID(), bottomText);
   108      }
   109      
   110      private function getTopTextField(c:Component):TextField{
   111      	return TextField(topTextFieldMap.get(c.getID()));
   112      }
   113      
   114      private function getBottomTextField(c:Component):TextField{
   115      	return TextField(bottomTextFieldMap.get(c.getID()));
   116      }
   117      
   118      /* These rectangles/insets are allocated once for all 
   119       * ButtonUI.paint() calls.  Re-using rectangles rather than 
   120       * allocating them in each paint call substantially reduced the time
   121       * it took paint to run.  Obviously, this method can't be re-entered.
   122       */
   123  	private static var viewRect:Rectangle;
   124      private static var textRect:Rectangle;
   125      private static var iconRect:Rectangle;
   126         
   127      private static function checkRectsForCountLayout():Void{
   128      	if(viewRect == null){
   129  			viewRect = new Rectangle();
   130      		textRect = new Rectangle();
   131      		iconRect = new Rectangle();
   132      	}
   133      }
   134          
   135      public function paint(c:Component, g:Graphics, r:Rectangle):Void{
   136      	super.paint(c, g, r);
   137      	var b:JLabel = JLabel(c);
   138      	    	
   139      	viewRect.setRect(r);
   140      	
   141      	textRect.x = textRect.y = textRect.width = textRect.height = 0;
   142          iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
   143  
   144          // layout the text and icon
   145          var text:String = ASWingUtils.layoutCompoundLabel(
   146              c.getFont(), b.getText(), b.getIcon(), 
   147              b.getVerticalAlignment(), b.getHorizontalAlignment(),
   148              b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
   149              viewRect, iconRect, textRect, 
   150  	    	b.getText() == null ? 0 : b.getIconTextGap());
   151  	   	
   152    
   153      	paintIcon(b, g, iconRect);
   154      	
   155          if (text != null && text != ""){
   156  			paintText(b, textRect, text);
   157          }else{
   158          	getTopTextField(b).text = "";
   159          	getBottomTextField(b).text = "";
   160          }
   161      }
   162      
   163      /**
   164       * paint the text to specified button with specified bounds
   165       */
   166      private function paintText(b:JLabel, textRect:Rectangle, text:String):Void{
   167      	
   168      	var font:ASFont = b.getFont();
   169      	if(b.isEnabled()){
   170      		paintTextField(textRect, getTopTextField(b), text, font, b.getForeground());
   171      		getBottomTextField(b)._visible = false;
   172      	}else{
   173      		getBottomTextField(b)._visible = true;
   174      		paintTextField(textRect, getTopTextField(b), text, font, b.getBackground().darker());
   175      		var rbRectangle:Rectangle = new Rectangle(textRect);
   176      		rbRectangle.x++;
   177      		rbRectangle.y++;
   178      		paintTextField(rbRectangle, getBottomTextField(b), text, font, b.getBackground().brighter());
   179      	}
   180      }
   181      
   182      private function paintTextField(tRect:Rectangle, textField:TextField, text:String, font:ASFont, color:ASColor):Void{
   183  		textField.text = text;
   184      	ASWingUtils.applyTextFontAndColor(textField, font, color);
   185  		textField._x = tRect.x;
   186  		textField._y = tRect.y;
   187      }
   188      
   189      /**
   190       * paint the icon to specified button's mc with specified bounds
   191       */
   192      private function paintIcon(b:JLabel, g:Graphics, iconRect:Rectangle):Void{
   193  		var icon:Icon = b.getIcon();
   194  	    if(icon == null) {
   195  			unistallLastPaintIcon(b, icon);
   196  			return;
   197  	    }
   198  
   199          if(!b.isEnabled()) {
   200          	if(b.getDisabledIcon() != null){
   201             		icon = b.getDisabledIcon();
   202          	}
   203          }
   204                 
   205          unistallLastPaintIcon(b, icon);
   206          icon.paintIcon(b, g, iconRect.x, iconRect.y);
   207          setJustPaintedIcon(b, icon);
   208      }
   209      
   210      private function unistallLastPaintIcon(b:JLabel, currentIcon:Icon):Void{
   211      	var lastPaintedIcon:Icon = Icon(lastPaintedIconMap.get(b.getID()));
   212          if(lastPaintedIcon != currentIcon){
   213          	lastPaintedIcon.uninstallIcon(b);
   214          }
   215      }
   216      
   217      private function setJustPaintedIcon(b:JLabel, ic:Icon):Void{
   218      	lastPaintedIconMap.put(b.getID(), ic);
   219      }
   220      
   221      /**
   222       * Returns the a label's preferred size with specified icon and text.
   223       */
   224      private function getLabelPreferredSize(b:JLabel, icon:Icon, text:String):Dimension{
   225      	viewRect.setRect(0, 0, 100000, 100000);
   226      	textRect.x = textRect.y = textRect.width = textRect.height = 0;
   227          iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
   228          
   229          ASWingUtils.layoutCompoundLabel(
   230              b.getFont(), text, icon, 
   231              b.getVerticalAlignment(), b.getHorizontalAlignment(),
   232              b.getVerticalTextPosition(), b.getHorizontalTextPosition(),
   233              viewRect, iconRect, textRect, 
   234  	    	b.getText() == null ? 0 : b.getIconTextGap()
   235          );
   236          /* The preferred size of the button is the size of 
   237           * the text and icon rectangles plus the buttons insets.
   238           */
   239          var r:Rectangle = iconRect.union(textRect);
   240          var size:Dimension = r.getSize();
   241          size = b.getInsets().roundsSize(size);
   242          return size;
   243      }
   244      /**
   245       * Returns the a button's minimum size with specified icon and text.
   246       */    
   247      private function getLabelMinimumSize(b:JLabel, icon:Icon, text:String):Dimension{
   248          var size:Dimension = b.getInsets().roundsSize();
   249  		return size;
   250      }    
   251      
   252      public function getPreferredSize(c:Component):Dimension{
   253      	var b:JLabel = JLabel(c);
   254      	var icon:Icon = b.getIcon();
   255      	var text:String = b.getText();
   256      	return getLabelPreferredSize(b, icon, text);
   257      }
   258  
   259      public function getMinimumSize(c:Component):Dimension{
   260      	var b:JLabel = JLabel(c);
   261      	var icon:Icon = b.getIcon();
   262      	var text:String = b.getText();
   263      	return getLabelMinimumSize(b, icon, text);
   264      }
   265  
   266      public function getMaximumSize(c:Component):Dimension{
   267  		return new Dimension(Number.MAX_VALUE, Number.MAX_VALUE);
   268      }    
   269  }
   270