source: trunk/web/addons/job_monarch/lib/extjs-30/src/core/Element.alignment.js @ 625

Last change on this file since 625 was 625, checked in by ramonb, 15 years ago

lib/extjs-30:

  • new ExtJS 3.0
File size: 13.7 KB
Line 
1/*!
2 * Ext JS Library 3.0.0
3 * Copyright(c) 2006-2009 Ext JS, LLC
4 * licensing@extjs.com
5 * http://www.extjs.com/license
6 */
7/**
8 * @class Ext.Element
9 */
10Ext.Element.addMethods({
11    /**
12     * Gets the x,y coordinates specified by the anchor position on the element.
13     * @param {String} anchor (optional) The specified anchor position (defaults to "c").  See {@link #alignTo}
14     * for details on supported anchor positions.
15     * @param {Boolean} local (optional) True to get the local (element top/left-relative) anchor position instead
16     * of page coordinates
17     * @param {Object} size (optional) An object containing the size to use for calculating anchor position
18     * {width: (target width), height: (target height)} (defaults to the element's current size)
19     * @return {Array} [x, y] An array containing the element's x and y coordinates
20     */
21    getAnchorXY : function(anchor, local, s){
22        //Passing a different size is useful for pre-calculating anchors,
23        //especially for anchored animations that change the el size.
24                anchor = (anchor || "tl").toLowerCase();
25        s = s || {};
26       
27        var me = this,       
28                vp = me.dom == document.body || me.dom == document,
29                w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
30                h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),                             
31                xy,             
32                r = Math.round,
33                o = me.getXY(),
34                scroll = me.getScroll(),
35                extraX = vp ? scroll.left : !local ? o[0] : 0,
36                extraY = vp ? scroll.top : !local ? o[1] : 0,
37                hash = {
38                        c  : [r(w * 0.5), r(h * 0.5)],
39                        t  : [r(w * 0.5), 0],
40                        l  : [0, r(h * 0.5)],
41                        r  : [w, r(h * 0.5)],
42                        b  : [r(w * 0.5), h],
43                        tl : [0, 0],   
44                        bl : [0, h],
45                        br : [w, h],
46                        tr : [w, 0]
47                };
48       
49        xy = hash[anchor];     
50        return [xy[0] + extraX, xy[1] + extraY]; 
51    },
52
53    /**
54     * Anchors an element to another element and realigns it when the window is resized.
55     * @param {Mixed} element The element to align to.
56     * @param {String} position The position to align to.
57     * @param {Array} offsets (optional) Offset the positioning by [x, y]
58     * @param {Boolean/Object} animate (optional) True for the default animation or a standard Element animation config object
59     * @param {Boolean/Number} monitorScroll (optional) True to monitor body scroll and reposition. If this parameter
60     * is a number, it is used as the buffer delay (defaults to 50ms).
61     * @param {Function} callback The function to call after the animation finishes
62     * @return {Ext.Element} this
63     */
64    anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){       
65            var me = this,
66            dom = me.dom;
67           
68            function action(){
69            Ext.fly(dom).alignTo(el, alignment, offsets, animate);
70            Ext.callback(callback, Ext.fly(dom));
71        }
72       
73        Ext.EventManager.onWindowResize(action, me);
74       
75        if(!Ext.isEmpty(monitorScroll)){
76            Ext.EventManager.on(window, 'scroll', action, me,
77                {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
78        }
79        action.call(me); // align immediately
80        return me;
81    },
82
83    /**
84     * Gets the x,y coordinates to align this element with another element. See {@link #alignTo} for more info on the
85     * supported position values.
86     * @param {Mixed} element The element to align to.
87     * @param {String} position The position to align to.
88     * @param {Array} offsets (optional) Offset the positioning by [x, y]
89     * @return {Array} [x, y]
90     */
91    getAlignToXY : function(el, p, o){     
92        el = Ext.get(el);
93       
94        if(!el || !el.dom){
95            throw "Element.alignToXY with an element that doesn't exist";
96        }
97       
98        o = o || [0,0];
99        p = (p == "?" ? "tl-bl?" : (!/-/.test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();       
100               
101        var me = this,
102                d = me.dom,
103                a1,
104                a2,
105                x,
106                y,
107                //constrain the aligned el to viewport if necessary
108                w,
109                h,
110                r,
111                dw = Ext.lib.Dom.getViewWidth() -10, // 10px of margin for ie
112                dh = Ext.lib.Dom.getViewHeight()-10, // 10px of margin for ie
113                p1y,
114                p1x,           
115                p2y,
116                p2x,
117                swapY,
118                swapX,
119                doc = document,
120                docElement = doc.documentElement,
121                docBody = doc.body,
122                scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
123                scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
124                c = false, //constrain to viewport
125                p1 = "", 
126                p2 = "",
127                m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
128       
129        if(!m){
130           throw "Element.alignTo with an invalid alignment " + p;
131        }
132       
133        p1 = m[1]; 
134        p2 = m[2]; 
135        c = !!m[3];
136
137        //Subtract the aligned el's internal xy from the target's offset xy
138        //plus custom offset to get the aligned el's new offset xy
139        a1 = me.getAnchorXY(p1, true);
140        a2 = el.getAnchorXY(p2, false);
141
142        x = a2[0] - a1[0] + o[0];
143        y = a2[1] - a1[1] + o[1];
144
145        if(c){   
146               w = me.getWidth();
147           h = me.getHeight();
148           r = el.getRegion();       
149           //If we are at a viewport boundary and the aligned el is anchored on a target border that is
150           //perpendicular to the vp border, allow the aligned el to slide on that border,
151           //otherwise swap the aligned el to the opposite border of the target.
152           p1y = p1.charAt(0);
153           p1x = p1.charAt(p1.length-1);
154           p2y = p2.charAt(0);
155           p2x = p2.charAt(p2.length-1);
156           swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
157           swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));         
158           
159
160           if (x + w > dw + scrollX) {
161                x = swapX ? r.left-w : dw+scrollX-w;
162           }
163           if (x < scrollX) {
164               x = swapX ? r.right : scrollX;
165           }
166           if (y + h > dh + scrollY) {
167                y = swapY ? r.top-h : dh+scrollY-h;
168            }
169           if (y < scrollY){
170               y = swapY ? r.bottom : scrollY;
171           }
172        }
173        return [x,y];
174    },
175
176    /**
177     * Aligns this element with another element relative to the specified anchor points. If the other element is the
178     * document it aligns it to the viewport.
179     * The position parameter is optional, and can be specified in any one of the following formats:
180     * <ul>
181     *   <li><b>Blank</b>: Defaults to aligning the element's top-left corner to the target's bottom-left corner ("tl-bl").</li>
182     *   <li><b>One anchor (deprecated)</b>: The passed anchor position is used as the target element's anchor point.
183     *       The element being aligned will position its top-left corner (tl) to that point.  <i>This method has been
184     *       deprecated in favor of the newer two anchor syntax below</i>.</li>
185     *   <li><b>Two anchors</b>: If two values from the table below are passed separated by a dash, the first value is used as the
186     *       element's anchor point, and the second value is used as the target's anchor point.</li>
187     * </ul>
188     * In addition to the anchor points, the position parameter also supports the "?" character.  If "?" is passed at the end of
189     * the position string, the element will attempt to align as specified, but the position will be adjusted to constrain to
190     * the viewport if necessary.  Note that the element being aligned might be swapped to align to a different position than
191     * that specified in order to enforce the viewport constraints.
192     * Following are all of the supported anchor positions:
193<pre>
194Value  Description
195-----  -----------------------------
196tl     The top left corner (default)
197t      The center of the top edge
198tr     The top right corner
199l      The center of the left edge
200c      In the center of the element
201r      The center of the right edge
202bl     The bottom left corner
203b      The center of the bottom edge
204br     The bottom right corner
205</pre>
206Example Usage:
207<pre><code>
208// align el to other-el using the default positioning ("tl-bl", non-constrained)
209el.alignTo("other-el");
210
211// align the top left corner of el with the top right corner of other-el (constrained to viewport)
212el.alignTo("other-el", "tr?");
213
214// align the bottom right corner of el with the center left edge of other-el
215el.alignTo("other-el", "br-l?");
216
217// align the center of el with the bottom left corner of other-el and
218// adjust the x position by -6 pixels (and the y position by 0)
219el.alignTo("other-el", "c-bl", [-6, 0]);
220</code></pre>
221     * @param {Mixed} element The element to align to.
222     * @param {String} position The position to align to.
223     * @param {Array} offsets (optional) Offset the positioning by [x, y]
224     * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
225     * @return {Ext.Element} this
226     */
227    alignTo : function(element, position, offsets, animate){
228            var me = this;
229        return me.setXY(me.getAlignToXY(element, position, offsets),
230                                me.preanim && !!animate ? me.preanim(arguments, 3) : false);
231    },
232   
233    // private ==>  used outside of core
234    adjustForConstraints : function(xy, parent, offsets){
235        return this.getConstrainToXY(parent || document, false, offsets, xy) ||  xy;
236    },
237
238    // private ==>  used outside of core
239    getConstrainToXY : function(el, local, offsets, proposedXY){   
240            var os = {top:0, left:0, bottom:0, right: 0};
241
242        return function(el, local, offsets, proposedXY){
243            el = Ext.get(el);
244            offsets = offsets ? Ext.applyIf(offsets, os) : os;
245
246            var vw, vh, vx = 0, vy = 0;
247            if(el.dom == document.body || el.dom == document){
248                vw =Ext.lib.Dom.getViewWidth();
249                vh = Ext.lib.Dom.getViewHeight();
250            }else{
251                vw = el.dom.clientWidth;
252                vh = el.dom.clientHeight;
253                if(!local){
254                    var vxy = el.getXY();
255                    vx = vxy[0];
256                    vy = vxy[1];
257                }
258            }
259
260            var s = el.getScroll();
261
262            vx += offsets.left + s.left;
263            vy += offsets.top + s.top;
264
265            vw -= offsets.right;
266            vh -= offsets.bottom;
267
268            var vr = vx+vw;
269            var vb = vy+vh;
270
271            var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
272            var x = xy[0], y = xy[1];
273            var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
274
275            // only move it if it needs it
276            var moved = false;
277
278            // first validate right/bottom
279            if((x + w) > vr){
280                x = vr - w;
281                moved = true;
282            }
283            if((y + h) > vb){
284                y = vb - h;
285                moved = true;
286            }
287            // then make sure top/left isn't negative
288            if(x < vx){
289                x = vx;
290                moved = true;
291            }
292            if(y < vy){
293                y = vy;
294                moved = true;
295            }
296            return moved ? [x, y] : false;
297        };
298    }(),
299           
300           
301               
302//         el = Ext.get(el);
303//         offsets = Ext.applyIf(offsets || {}, {top : 0, left : 0, bottom : 0, right : 0});
304
305//         var  me = this,
306//              doc = document,
307//              s = el.getScroll(),
308//              vxy = el.getXY(),
309//              vx = offsets.left + s.left,
310//              vy = offsets.top + s.top,               
311//              vw = -offsets.right,
312//              vh = -offsets.bottom,
313//              vr,
314//              vb,
315//              xy = proposedXY || (!local ? me.getXY() : [me.getLeft(true), me.getTop(true)]),
316//              x = xy[0],
317//              y = xy[1],
318//              w = me.dom.offsetWidth, h = me.dom.offsetHeight,
319//              moved = false; // only move it if it needs it
320//       
321//             
322//         if(el.dom == doc.body || el.dom == doc){
323//             vw += Ext.lib.Dom.getViewWidth();
324//             vh += Ext.lib.Dom.getViewHeight();
325//         }else{
326//             vw += el.dom.clientWidth;
327//             vh += el.dom.clientHeight;
328//             if(!local){                   
329//                 vx += vxy[0];
330//                 vy += vxy[1];
331//             }
332//         }
333
334//         // first validate right/bottom
335//         if(x + w > vx + vw){
336//             x = vx + vw - w;
337//             moved = true;
338//         }
339//         if(y + h > vy + vh){
340//             y = vy + vh - h;
341//             moved = true;
342//         }
343//         // then make sure top/left isn't negative
344//         if(x < vx){
345//             x = vx;
346//             moved = true;
347//         }
348//         if(y < vy){
349//             y = vy;
350//             moved = true;
351//         }
352//         return moved ? [x, y] : false;
353//    },
354   
355    /**
356    * Calculates the x, y to center this element on the screen
357    * @return {Array} The x, y values [x, y]
358    */
359    getCenterXY : function(){
360        return this.getAlignToXY(document, 'c-c');
361    },
362
363    /**
364    * Centers the Element in either the viewport, or another Element.
365    * @param {Mixed} centerIn (optional) The element in which to center the element.
366    */
367    center : function(centerIn){
368        return this.alignTo(centerIn || document, 'c-c');       
369    }   
370});
Note: See TracBrowser for help on using the repository browser.