1  /*
     2   Copyright aswing.org, see the LICENCE.txt.
     3  */
     4  
     5  import org.aswing.Component;
     6  import org.aswing.Container;
     7  import org.aswing.EmptyLayout;
     8  import org.aswing.geom.Dimension;
     9  import org.aswing.geom.Rectangle;
    10  import org.aswing.Insets;
    11  
    12  /**
    13   * A layout manager that allows multiple components to be laid out either vertically or 
    14   * horizontally. The components will not wrap so, for example, a vertical arrangement 
    15   * of components will stay vertically arranged when the frame is resized.
    16   * @author iiley
    17   */
    18  class org.aswing.BoxLayout extends EmptyLayout{
    19  	
    20      /**
    21       * Specifies that components should be laid out left to right.
    22       */
    23      public static var X_AXIS:Number = 0;
    24      
    25      /**
    26       * Specifies that components should be laid out top to bottom.
    27       */
    28      public static var Y_AXIS:Number = 1;
    29      
    30      
    31      private var axis:Number;
    32      private var gap:Number;
    33      
    34      /**
    35       * <br>
    36       * BoxLayout(axis:Number, gap:Number)<br>
    37       * BoxLayout(axis:Number)<br>
    38       * @param axis (optional)the layout axis, default is X_AXIS
    39       * @param gap (optional)the gap between children, default is 0
    40       * @see #X_AXIS
    41       * @see #X_AXIS
    42       */
    43      public function BoxLayout(axis:Number, gap:Number){
    44      	this.axis = (axis == undefined ? X_AXIS : axis);
    45      	this.gap  = (gap == undefined ? 0 : gap);
    46      }
    47      	
    48  	/**
    49  	 * return target.getSize();
    50  	 */
    51      public function preferredLayoutSize(target:Container):Dimension{
    52      	var count:Number = target.getComponentCount();
    53      	var insets:Insets = target.getInsets();
    54      	var width:Number = 0;
    55      	var height:Number = 0;
    56      	var amount:Number = 0;
    57      	for(var i:Number=0; i<count; i++){
    58      		var c:Component = target.getComponent(i);
    59      		if(c.isVisible()){
    60  	    		var size:Dimension = c.getPreferredSize();
    61  	    		width = Math.max(width, size.width);
    62  	    		height = Math.max(height, size.height);
    63      			amount++;
    64      		}
    65      	}
    66      	if(axis == Y_AXIS){
    67      		height = height*amount;
    68      		if(amount > 0){
    69      			height += (amount-1)*gap;
    70      		}
    71      	}else{
    72      		width = width*amount;
    73      		if(amount > 0){
    74      			width += (amount-1)*gap;
    75      		}
    76      	}
    77      	
    78      	var dim:Dimension = new Dimension(width, height);
    79      	return insets.roundsSize(dim);
    80      }
    81  
    82  	/**
    83  	 * target.getSize();
    84  	 */
    85      public function minimumLayoutSize(target:Container):Dimension{
    86      	var count:Number = target.getComponentCount();
    87      	var insets:Insets = target.getInsets();
    88      	var width:Number = 0;
    89      	var height:Number = 0;
    90      	var amount:Number = 0;
    91      	for(var i:Number=0; i<count; i++){
    92      		var c:Component = target.getComponent(i);
    93      		if(c.isVisible()){
    94  	    		var size:Dimension = c.getMinimumSize();
    95  	    		width = Math.max(width, size.width);
    96  	    		height = Math.max(height, size.height);
    97  	    		amount++;
    98      		}
    99      	}
   100      	if(axis == Y_AXIS){
   101      		height = height*amount;
   102      		if(amount > 0){
   103      			height += (amount-1)*gap;
   104      		}
   105      	}else{
   106      		width = width*amount;
   107      		if(amount > 0){
   108      			width += (amount-1)*gap;
   109      		}
   110      	}
   111      	var dim:Dimension = new Dimension(width, height);
   112      	return insets.roundsSize(dim);
   113      }
   114      
   115  	/**
   116  	 * return new Dimension(Number.MAX_VALUE, Number.MAX_VALUE);
   117  	 */
   118      public function maximumLayoutSize(target:Container):Dimension{
   119      	var count:Number = target.getComponentCount();
   120      	var insets:Insets = target.getInsets();
   121      	var width:Number = 0;
   122      	var height:Number = 0;
   123      	var amount:Number = 0;
   124      	for(var i:Number=0; i<count; i++){
   125      		var c:Component = target.getComponent(i);
   126      		if(c.isVisible()){
   127  	    		var size:Dimension = c.getMaximumSize();
   128  	    		width = Math.max(width, size.width);
   129  	    		height = Math.max(height, size.height);
   130  	    		amount++;
   131      		}
   132      	}
   133      	if(axis == Y_AXIS){
   134      		height = height*amount;
   135      		if(amount > 0){
   136      			height += (amount-1)*gap;
   137      		}
   138      	}else{
   139      		width = width*amount;
   140      		if(amount > 0){
   141      			width += (amount-1)*gap;
   142      		}
   143      	}
   144      	var dim:Dimension = new Dimension(width, height);
   145      	return insets.roundsSize(dim);
   146      }    
   147      
   148      public function layoutContainer(target:Container):Void{
   149      	var count:Number = target.getComponentCount();
   150      	var amount:Number = 0;
   151      	for(var i:Number=0; i<count; i++){
   152      		var c:Component = target.getComponent(i);
   153      		if(c.isVisible()){
   154  	    		amount ++;
   155      		}
   156      	}
   157      	var size:Dimension = target.getSize();
   158      	var insets:Insets = target.getInsets();
   159      	var rd:Rectangle = insets.getInsideBounds(size.getBounds());
   160      	var ch:Number;
   161      	var cw:Number;
   162      	if(axis == Y_AXIS){
   163      		ch = (rd.height - (amount-1)*gap)/amount;
   164      		cw = rd.width;
   165      	}else{
   166      		ch = rd.height;
   167      		cw = (rd.width - (amount-1)*gap)/amount;
   168      	}
   169      	var x:Number = rd.x;
   170      	var y:Number = rd.y;
   171      	var xAdd:Number = (axis == Y_AXIS ? 0 : cw+gap);
   172      	var yAdd:Number = (axis == Y_AXIS ? ch+gap : 0);
   173      	for(var i:Number=0; i<count; i++){
   174      		var c:Component = target.getComponent(i);
   175      		if(c.isVisible()){
   176  	    		c.setBounds(x, y, cw, ch);
   177  	    		x += xAdd;
   178  	    		y += yAdd;
   179      		}
   180      	}
   181      }
   182      
   183  	/**
   184  	 * return 0.5
   185  	 */
   186      public function getLayoutAlignmentX(target:Container):Number{
   187      	return 0.5;
   188      }
   189  
   190  	/**
   191  	 * return 0.5
   192  	 */
   193      public function getLayoutAlignmentY(target:Container):Number{
   194      	return 0.5;
   195      }
   196  }
   197