3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.util.Floating
17 * A mixin to add floating capability to a Component
19 Ext.define('Ext.util.Floating', {
21 uses: ['Ext.Layer', 'Ext.window.Window'],
24 * @cfg {Boolean} focusOnToFront
25 * Specifies whether the floated component should be automatically {@link #focus focused} when it is
26 * {@link #toFront brought to the front}. Defaults to true.
31 * @cfg {String/Boolean} shadow Specifies whether the floating component should be given a shadow. Set to
32 * <tt>true</tt> to automatically create an {@link Ext.Shadow}, or a string indicating the
33 * shadow's display {@link Ext.Shadow#mode}. Set to <tt>false</tt> to disable the shadow.
34 * (Defaults to <tt>'sides'</tt>.)
38 constructor: function(config) {
40 this.el = Ext.create('Ext.Layer', Ext.apply({}, config, {
41 hideMode: this.hideMode,
43 shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
44 shadowOffset: this.shadowOffset,
46 shim: this.shim === false ? false : undefined
50 onFloatRender: function() {
52 me.zIndexParent = me.getZIndexParent();
53 me.setFloatParent(me.ownerCt);
56 if (me.zIndexParent) {
57 me.zIndexParent.registerFloatingItem(me);
59 Ext.WindowManager.register(me);
63 setFloatParent: function(floatParent) {
66 // Remove listeners from previous floatParent
68 me.mun(me.floatParent, {
69 hide: me.onFloatParentHide,
70 show: me.onFloatParentShow,
75 me.floatParent = floatParent;
77 // Floating Components as children of Containers must hide when their parent hides.
79 me.mon(me.floatParent, {
80 hide: me.onFloatParentHide,
81 show: me.onFloatParentShow,
86 // If a floating Component is configured to be constrained, but has no configured
87 // constrainTo setting, set its constrainTo to be it's ownerCt before rendering.
88 if ((me.constrain || me.constrainHeader) && !me.constrainTo) {
89 me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container;
93 onFloatParentHide: function() {
94 if (this.hideOnParentHide !== false) {
95 this.showOnParentShow = this.isVisible();
100 onFloatParentShow: function() {
101 if (this.showOnParentShow) {
102 delete this.showOnParentShow;
109 * <p>Finds the ancestor Container responsible for allocating zIndexes for the passed Component.</p>
110 * <p>That will be the outermost floating Container (a Container which has no ownerCt and has floating:true).</p>
111 * <p>If we have no ancestors, or we walk all the way up to the document body, there's no zIndexParent,
112 * and the global Ext.WindowManager will be used.</p>
114 getZIndexParent: function() {
115 var p = this.ownerCt,
130 // z-index is managed by the zIndexManager and may be overwritten at any time.
131 // Returns the next z-index to be used.
132 // If this is a Container, then it will have rebased any managed floating Components,
133 // and so the next available z-index will be approximately 10000 above that.
134 setZIndex: function(index) {
136 this.el.setZIndex(index);
138 // Next item goes 10 above;
141 // When a Container with floating items has its z-index set, it rebases any floating items it is managing.
142 // The returned value is a round number approximately 10000 above the last z-index used.
143 if (me.floatingItems) {
144 index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000;
150 * <p>Moves this floating Component into a constrain region.</p>
151 * <p>By default, this Component is constrained to be within the container it was added to, or the element
152 * it was rendered to.</p>
153 * <p>An alternative constraint may be passed.</p>
154 * @param {Mixed} constrainTo Optional. The Element or {@link Ext.util.Region Region} into which this Component is to be constrained.
156 doConstrain: function(constrainTo) {
158 vector = me.getConstrainVector(constrainTo),
162 xy = me.getPosition();
171 * Gets the x/y offsets to constrain this float
173 * @param {Mixed} constrainTo Optional. The Element or {@link Ext.util.Region Region} into which this Component is to be constrained.
174 * @return {Array} The x/y constraints
176 getConstrainVector: function(constrainTo){
180 if (me.constrain || me.constrainHeader) {
181 el = me.constrainHeader ? me.header.el : me.el;
182 constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container;
183 return el.getConstrainVector(constrainTo);
188 * Aligns this floating Component to the specified element
189 * @param {Mixed} element The element or {@link Ext.Component} to align to. If passing a component, it must
190 * be a omponent instance. If a string id is passed, it will be used as an element id.
191 * @param {String} position (optional, defaults to "tl-bl?") The position to align to (see {@link Ext.core.Element#alignTo} for more details).
192 * @param {Array} offsets (optional) Offset the positioning by [x, y]
193 * @return {Component} this
195 alignTo: function(element, position, offsets) {
196 if (element.isComponent) {
197 element = element.getEl();
199 var xy = this.el.getAlignToXY(element, position, offsets);
200 this.setPagePosition(xy);
205 * <p>Brings this floating Component to the front of any other visible, floating Components managed by the same {@link Ext.ZIndexManager ZIndexManager}</p>
206 * <p>If this Component is modal, inserts the modal mask just below this Component in the z-index stack.</p>
207 * @param {Boolean} preventFocus (optional) Specify <code>true</code> to prevent the Component from being focused.
208 * @return {Component} this
210 toFront: function(preventFocus) {
213 // Find the floating Component which provides the base for this Component's zIndexing.
214 // That must move to front to then be able to rebase its zIndex stack and move this to the front
215 if (me.zIndexParent) {
216 me.zIndexParent.toFront(true);
218 if (me.zIndexManager.bringToFront(me)) {
219 if (!Ext.isDefined(preventFocus)) {
220 preventFocus = !me.focusOnToFront;
223 // Kick off a delayed focus request.
224 // If another floating Component is toFronted before the delay expires
225 // this will not receive focus.
226 me.focus(false, true);
233 * <p>This method is called internally by {@link Ext.ZIndexManager} to signal that a floating
234 * Component has either been moved to the top of its zIndex stack, or pushed from the top of its zIndex stack.</p>
235 * <p>If a <i>Window</i> is superceded by another Window, deactivating it hides its shadow.</p>
236 * <p>This method also fires the {@link #activate} or {@link #deactivate} event depending on which action occurred.</p>
237 * @param {Boolean} active True to activate the Component, false to deactivate it (defaults to false)
238 * @param {Component} newActive The newly active Component which is taking over topmost zIndex position.
240 setActive: function(active, newActive) {
242 if ((this instanceof Ext.window.Window) && !this.maximized) {
243 this.el.enableShadow(true);
245 this.fireEvent('activate', this);
247 // Only the *Windows* in a zIndex stack share a shadow. All other types of floaters
248 // can keep their shadows all the time
249 if ((this instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) {
250 this.el.disableShadow();
252 this.fireEvent('deactivate', this);
257 * Sends this Component to the back of (lower z-index than) any other visible windows
258 * @return {Component} this
261 this.zIndexManager.sendToBack(this);
266 * Center this Component in its container.
267 * @return {Component} this
270 var xy = this.el.getAlignToXY(this.container, 'c-c');
271 this.setPagePosition(xy);
276 syncShadow : function(){
283 fitContainer: function() {
284 var parent = this.floatParent,
285 container = parent ? parent.getTargetEl() : this.container,
286 size = container.getViewSize(false);