4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-layout-container-Anchor'>/**
19 </span> * @class Ext.layout.container.Anchor
20 * @extends Ext.layout.container.Container
22 * This is a layout that enables anchoring of contained elements relative to the container's dimensions.
23 * If the container is resized, all anchored items are automatically rerendered according to their
24 * `{@link #anchor}` rules.
26 * This class is intended to be extended or created via the {@link Ext.container.AbstractContainer#layout layout}: 'anchor'
27 * config, and should generally not need to be created directly via the new keyword.
29 * AnchorLayout does not have any direct config options (other than inherited ones). By default,
30 * AnchorLayout will calculate anchor measurements based on the size of the container itself. However, the
31 * container using the AnchorLayout can supply an anchoring-specific config property of `anchorSize`.
33 * If anchorSize is specifed, the layout will use it as a virtual container for the purposes of calculating
34 * anchor measurements based on it instead, allowing the container to be sized independently of the anchoring
38 * Ext.create('Ext.Panel', {
41 * title: "AnchorLayout Panel",
43 * renderTo: Ext.getBody(),
47 * title: '75% Width and 20% Height',
52 * title: 'Offset -300 Width & -200 Height',
57 * title: 'Mixed Offset and Percent',
63 Ext.define('Ext.layout.container.Anchor', {
65 /* Begin Definitions */
67 alias: 'layout.anchor',
68 extend: 'Ext.layout.container.Container',
69 alternateClassName: 'Ext.layout.AnchorLayout',
73 <span id='Ext-layout-container-Anchor-cfg-anchor'> /**
74 </span> * @cfg {String} anchor
76 * This configuation option is to be applied to **child `items`** of a container managed by
77 * this layout (ie. configured with `layout:'anchor'`).
79 * This value is what tells the layout how an item should be anchored to the container. `items`
80 * added to an AnchorLayout accept an anchoring-specific config property of **anchor** which is a string
81 * containing two values: the horizontal anchor value and the vertical anchor value (for example, '100% 50%').
82 * The following types of anchor values are supported:
84 * - **Percentage** : Any value between 1 and 100, expressed as a percentage.
86 * The first anchor is the percentage width that the item should take up within the container, and the
87 * second is the percentage height. For example:
89 * // two values specified
90 * anchor: '100% 50%' // render item complete width of the container and
91 * // 1/2 height of the container
92 * // one value specified
93 * anchor: '100%' // the width value; the height will default to auto
95 * - **Offsets** : Any positive or negative integer value.
97 * This is a raw adjustment where the first anchor is the offset from the right edge of the container,
98 * and the second is the offset from the bottom edge. For example:
100 * // two values specified
101 * anchor: '-50 -100' // render item the complete width of the container
102 * // minus 50 pixels and
103 * // the complete height minus 100 pixels.
104 * // one value specified
105 * anchor: '-50' // anchor value is assumed to be the right offset value
106 * // bottom offset will default to 0
108 * - **Sides** : Valid values are `right` (or `r`) and `bottom` (or `b`).
110 * Either the container must have a fixed size or an anchorSize config value defined at render time in
111 * order for these to have any effect.
115 * Anchor values can also be mixed as needed. For example, to render the width offset from the container
116 * right edge by 50 pixels and 75% of the container's height use:
122 <span id='Ext-layout-container-Anchor-cfg-defaultAnchor'> /**
123 </span> * @cfg {String} defaultAnchor
124 * Default anchor for all child <b>container</b> items applied if no anchor or specific width is set on the child item. Defaults to '100%'.
126 defaultAnchor: '100%',
128 parseAnchorRE: /^(r|right|b|bottom)$/i,
131 onLayout: function() {
132 this.callParent(arguments);
135 size = me.getLayoutTargetSize(),
137 target = me.getTarget(),
138 ownerWidth = size.width,
139 ownerHeight = size.height,
140 overflow = target.getStyle('overflow'),
141 components = me.getVisibleItems(owner),
142 len = components.length,
144 box, newTargetSize, component, anchorSpec, calcWidth, calcHeight,
147 if (ownerWidth < 20 && ownerHeight < 20) {
151 // Anchor layout uses natural HTML flow to arrange the child items.
152 // To ensure that all browsers (I'm looking at you IE!) add the bottom margin of the last child to the
153 // containing element height, we create a zero-sized element with style clear:both to force a "new line"
155 me.clearEl = target.createChild({
156 cls: Ext.baseCSSPrefix + 'clear',
161 // Work around WebKit RightMargin bug. We're going to inline-block all the children only ONCE and remove it when we're done
162 if (!Ext.supports.RightMargin) {
163 cleaner = Ext.Element.getRightMarginFixCleaner(target);
164 target.addCls(Ext.baseCSSPrefix + 'inline-children');
167 for (i = 0; i < len; i++) {
168 component = components[i];
171 anchorSpec = component.anchorSpec;
173 if (anchorSpec.right) {
174 calcWidth = me.adjustWidthAnchor(anchorSpec.right(ownerWidth) - el.getMargin('lr'), component);
176 calcWidth = undefined;
178 if (anchorSpec.bottom) {
179 calcHeight = me.adjustHeightAnchor(anchorSpec.bottom(ownerHeight) - el.getMargin('tb'), component);
181 calcHeight = undefined;
185 component: component,
187 width: calcWidth || undefined,
188 height: calcHeight || undefined
192 component: component,
198 // Work around WebKit RightMargin bug. We're going to inline-block all the children only ONCE and remove it when we're done
199 if (!Ext.supports.RightMargin) {
200 target.removeCls(Ext.baseCSSPrefix + 'inline-children');
204 for (i = 0; i < len; i++) {
206 me.setItemSize(box.component, box.width, box.height);
209 if (overflow && overflow != 'hidden' && !me.adjustmentPass) {
210 newTargetSize = me.getLayoutTargetSize();
211 if (newTargetSize.width != size.width || newTargetSize.height != size.height) {
212 me.adjustmentPass = true;
217 delete me.adjustmentPass;
221 parseAnchor: function(a, start, cstart) {
222 if (a && a != 'none') {
225 if (this.parseAnchorRE.test(a)) {
226 var diff = cstart - start;
232 else if (a.indexOf('%') != -1) {
233 ratio = parseFloat(a.replace('%', '')) * 0.01;
235 return Math.floor(v * ratio);
238 // simple offset adjustment
252 adjustWidthAnchor: function(value, comp) {
257 adjustHeightAnchor: function(value, comp) {
261 configureItem: function(item) {
270 if (!item.anchor && item.items && !Ext.isNumber(item.width) && !(Ext.isIE6 && Ext.isStrict)) {
271 item.anchor = anchor = me.defaultAnchor;
274 // find the container anchoring size
275 if (owner.anchorSize) {
276 if (typeof owner.anchorSize == 'number') {
277 anchorWidth = owner.anchorSize;
280 anchorWidth = owner.anchorSize.width;
281 anchorHeight = owner.anchorSize.height;
285 anchorWidth = owner.initialConfig.width;
286 anchorHeight = owner.initialConfig.height;
290 // cache all anchor values
291 anchorsArray = anchor.split(' ');
292 item.anchorSpec = anchorSpec = {
293 right: me.parseAnchor(anchorsArray[0], item.initialConfig.width, anchorWidth),
294 bottom: me.parseAnchor(anchorsArray[1], item.initialConfig.height, anchorHeight)
297 if (anchorSpec.right) {
298 item.layoutManagedWidth = 1;
300 item.layoutManagedWidth = 2;
303 if (anchorSpec.bottom) {
304 item.layoutManagedHeight = 1;
306 item.layoutManagedHeight = 2;
309 item.layoutManagedWidth = 2;
310 item.layoutManagedHeight = 2;
312 this.callParent(arguments);