Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / docs / source / AnchorLayout.html
1 <html>
2 <head>
3   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    
4   <title>The source code</title>
5     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
6     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
7 </head>
8 <body  onload="prettyPrint();">
9     <pre class="prettyprint lang-js">/*!
10  * Ext JS Library 3.2.0
11  * Copyright(c) 2006-2010 Ext JS, Inc.
12  * licensing@extjs.com
13  * http://www.extjs.com/license
14  */
15 <div id="cls-Ext.layout.AnchorLayout"></div>/**
16  * @class Ext.layout.AnchorLayout
17  * @extends Ext.layout.ContainerLayout
18  * <p>This is a layout that enables anchoring of contained elements relative to the container's dimensions.
19  * If the container is resized, all anchored items are automatically rerendered according to their
20  * <b><tt>{@link #anchor}</tt></b> rules.</p>
21  * <p>This class is intended to be extended or created via the layout:'anchor' {@link Ext.Container#layout}
22  * config, and should generally not need to be created directly via the new keyword.</p>
23  * <p>AnchorLayout does not have any direct config options (other than inherited ones). By default,
24  * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the
25  * container using the AnchorLayout can supply an anchoring-specific config property of <b>anchorSize</b>.
26  * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating
27  * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring
28  * logic if necessary.  For example:</p>
29  * <pre><code>
30 var viewport = new Ext.Viewport({
31     layout:'anchor',
32     anchorSize: {width:800, height:600},
33     items:[{
34         title:'Item 1',
35         html:'Content 1',
36         width:800,
37         anchor:'right 20%'
38     },{
39         title:'Item 2',
40         html:'Content 2',
41         width:300,
42         anchor:'50% 30%'
43     },{
44         title:'Item 3',
45         html:'Content 3',
46         width:600,
47         anchor:'-100 50%'
48     }]
49 });
50  * </code></pre>
51  */
52 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
53     <div id="cfg-Ext.layout.AnchorLayout-anchor"></div>/**
54      * @cfg {String} anchor
55      * <p>This configuation option is to be applied to <b>child <tt>items</tt></b> of a container managed by
56      * this layout (ie. configured with <tt>layout:'anchor'</tt>).</p><br/>
57      *
58      * <p>This value is what tells the layout how an item should be anchored to the container. <tt>items</tt>
59      * added to an AnchorLayout accept an anchoring-specific config property of <b>anchor</b> which is a string
60      * containing two values: the horizontal anchor value and the vertical anchor value (for example, '100% 50%').
61      * The following types of anchor values are supported:<div class="mdetail-params"><ul>
62      *
63      * <li><b>Percentage</b> : Any value between 1 and 100, expressed as a percentage.<div class="sub-desc">
64      * The first anchor is the percentage width that the item should take up within the container, and the
65      * second is the percentage height.  For example:<pre><code>
66 // two values specified
67 anchor: '100% 50%' // render item complete width of the container and
68                    // 1/2 height of the container
69 // one value specified
70 anchor: '100%'     // the width value; the height will default to auto
71      * </code></pre></div></li>
72      *
73      * <li><b>Offsets</b> : Any positive or negative integer value.<div class="sub-desc">
74      * This is a raw adjustment where the first anchor is the offset from the right edge of the container,
75      * and the second is the offset from the bottom edge. For example:<pre><code>
76 // two values specified
77 anchor: '-50 -100' // render item the complete width of the container
78                    // minus 50 pixels and
79                    // the complete height minus 100 pixels.
80 // one value specified
81 anchor: '-50'      // anchor value is assumed to be the right offset value
82                    // bottom offset will default to 0
83      * </code></pre></div></li>
84      *
85      * <li><b>Sides</b> : Valid values are <tt>'right'</tt> (or <tt>'r'</tt>) and <tt>'bottom'</tt>
86      * (or <tt>'b'</tt>).<div class="sub-desc">
87      * Either the container must have a fixed size or an anchorSize config value defined at render time in
88      * order for these to have any effect.</div></li>
89      *
90      * <li><b>Mixed</b> : <div class="sub-desc">
91      * Anchor values can also be mixed as needed.  For example, to render the width offset from the container
92      * right edge by 50 pixels and 75% of the container's height use:
93      * <pre><code>
94 anchor: '-50 75%'
95      * </code></pre></div></li>
96      *
97      *
98      * </ul></div>
99      */
100
101     // private
102     monitorResize : true,
103
104     type : 'anchor',
105
106     <div id="cfg-Ext.layout.AnchorLayout-defaultAnchor"></div>/**
107      * @cfg {String} defaultAnchor
108      *
109      * default anchor for all child container items applied if no anchor or specific width is set on the child item.  Defaults to '100%'.
110      *
111      */
112     defaultAnchor : '100%',
113
114     parseAnchorRE : /^(r|right|b|bottom)$/i,
115
116     getLayoutTargetSize : function() {
117         var target = this.container.getLayoutTarget();
118         if (!target) {
119             return {};
120         }
121         // Style Sized (scrollbars not included)
122         return target.getStyleSize();
123     },
124
125     // private
126     onLayout : function(ct, target){
127         Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
128         var size = this.getLayoutTargetSize();
129
130         var w = size.width, h = size.height;
131
132         if(w < 20 && h < 20){
133             return;
134         }
135
136         // find the container anchoring size
137         var aw, ah;
138         if(ct.anchorSize){
139             if(typeof ct.anchorSize == 'number'){
140                 aw = ct.anchorSize;
141             }else{
142                 aw = ct.anchorSize.width;
143                 ah = ct.anchorSize.height;
144             }
145         }else{
146             aw = ct.initialConfig.width;
147             ah = ct.initialConfig.height;
148         }
149
150         var cs = this.getRenderedItems(ct), len = cs.length, i, c, a, cw, ch, el, vs, boxes = [];
151         for(i = 0; i < len; i++){
152             c = cs[i];
153             el = c.getPositionEl();
154
155             // If a child container item has no anchor and no specific width, set the child to the default anchor size
156             if (!c.anchor && c.items && !Ext.isNumber(c.width) && !(Ext.isIE6 && Ext.isStrict)){
157                 c.anchor = this.defaultAnchor;
158             }
159
160             if(c.anchor){
161                 a = c.anchorSpec;
162                 if(!a){ // cache all anchor values
163                     vs = c.anchor.split(' ');
164                     c.anchorSpec = a = {
165                         right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
166                         bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
167                     };
168                 }
169                 cw = a.right ? this.adjustWidthAnchor(a.right(w) - el.getMargins('lr'), c) : undefined;
170                 ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h) - el.getMargins('tb'), c) : undefined;
171
172                 if(cw || ch){
173                     boxes.push({
174                         comp: c,
175                         width: cw || undefined,
176                         height: ch || undefined
177                     });
178                 }
179             }
180         }
181         for (i = 0, len = boxes.length; i < len; i++) {
182             c = boxes[i];
183             c.comp.setSize(c.width, c.height);
184         }
185     },
186
187     // private
188     parseAnchor : function(a, start, cstart){
189         if(a && a != 'none'){
190             var last;
191             // standard anchor
192             if(this.parseAnchorRE.test(a)){
193                 var diff = cstart - start;
194                 return function(v){
195                     if(v !== last){
196                         last = v;
197                         return v - diff;
198                     }
199                 }
200             // percentage
201             }else if(a.indexOf('%') != -1){
202                 var ratio = parseFloat(a.replace('%', ''))*.01;
203                 return function(v){
204                     if(v !== last){
205                         last = v;
206                         return Math.floor(v*ratio);
207                     }
208                 }
209             // simple offset adjustment
210             }else{
211                 a = parseInt(a, 10);
212                 if(!isNaN(a)){
213                     return function(v){
214                         if(v !== last){
215                             last = v;
216                             return v + a;
217                         }
218                     }
219                 }
220             }
221         }
222         return false;
223     },
224
225     // private
226     adjustWidthAnchor : function(value, comp){
227         return value;
228     },
229
230     // private
231     adjustHeightAnchor : function(value, comp){
232         return value;
233     }
234
235     <div id="prop-Ext.layout.AnchorLayout-activeItem"></div>/**
236      * @property activeItem
237      * @hide
238      */
239 });
240 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
241 </pre>    
242 </body>
243 </html>