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 * A mixin to add floating capability to a Component.
18 Ext.define('Ext.util.Floating', {
20 uses: ['Ext.Layer', 'Ext.window.Window'],
23 * @cfg {Boolean} focusOnToFront
24 * Specifies whether the floated component should be automatically {@link Ext.Component#focus focused} when
25 * it is {@link #toFront brought to the front}.
30 * @cfg {String/Boolean} shadow
31 * Specifies whether the floating component should be given a shadow. Set to true to automatically create an {@link
32 * Ext.Shadow}, or a string indicating the shadow's display {@link Ext.Shadow#mode}. Set to false to disable the
37 constructor: function(config) {
41 me.el = Ext.create('Ext.Layer', Ext.apply({}, config, {
42 hideMode: me.hideMode,
44 shadow: Ext.isDefined(me.shadow) ? me.shadow : 'sides',
45 shadowOffset: me.shadowOffset,
47 shim: me.shim === false ? false : undefined
51 onFloatRender: function() {
53 me.zIndexParent = me.getZIndexParent();
54 me.setFloatParent(me.ownerCt);
57 if (me.zIndexParent) {
58 me.zIndexParent.registerFloatingItem(me);
60 Ext.WindowManager.register(me);
64 setFloatParent: function(floatParent) {
67 // Remove listeners from previous floatParent
69 me.mun(me.floatParent, {
70 hide: me.onFloatParentHide,
71 show: me.onFloatParentShow,
76 me.floatParent = floatParent;
78 // Floating Components as children of Containers must hide when their parent hides.
80 me.mon(me.floatParent, {
81 hide: me.onFloatParentHide,
82 show: me.onFloatParentShow,
87 // If a floating Component is configured to be constrained, but has no configured
88 // constrainTo setting, set its constrainTo to be it's ownerCt before rendering.
89 if ((me.constrain || me.constrainHeader) && !me.constrainTo) {
90 me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container;
94 onFloatParentHide: function() {
97 if (me.hideOnParentHide !== false) {
98 me.showOnParentShow = me.isVisible();
103 onFloatParentShow: function() {
104 if (this.showOnParentShow) {
105 delete this.showOnParentShow;
112 * Finds the ancestor Container responsible for allocating zIndexes for the passed Component.
114 * That will be the outermost floating Container (a Container which has no ownerCt and has floating:true).
116 * If we have no ancestors, or we walk all the way up to the document body, there's no zIndexParent,
117 * and the global Ext.WindowManager will be used.
119 getZIndexParent: function() {
120 var p = this.ownerCt,
135 // z-index is managed by the zIndexManager and may be overwritten at any time.
136 // Returns the next z-index to be used.
137 // If this is a Container, then it will have rebased any managed floating Components,
138 // and so the next available z-index will be approximately 10000 above that.
139 setZIndex: function(index) {
141 me.el.setZIndex(index);
143 // Next item goes 10 above;
146 // When a Container with floating items has its z-index set, it rebases any floating items it is managing.
147 // The returned value is a round number approximately 10000 above the last z-index used.
148 if (me.floatingItems) {
149 index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000;
155 * Moves this floating Component into a constrain region.
157 * By default, this Component is constrained to be within the container it was added to, or the element it was
160 * An alternative constraint may be passed.
161 * @param {String/HTMLElement/Ext.Element/Ext.util.Region} constrainTo (Optional) The Element or {@link Ext.util.Region Region} into which this Component is
162 * to be constrained. Defaults to the element into which this floating Component was rendered.
164 doConstrain: function(constrainTo) {
166 vector = me.getConstrainVector(constrainTo || me.el.getScopeParent()),
170 xy = me.getPosition();
179 * Gets the x/y offsets to constrain this float
181 * @param {String/HTMLElement/Ext.Element/Ext.util.Region} constrainTo (Optional) The Element or {@link Ext.util.Region Region} into which this Component is to be constrained.
182 * @return {Number[]} The x/y constraints
184 getConstrainVector: function(constrainTo){
188 if (me.constrain || me.constrainHeader) {
189 el = me.constrainHeader ? me.header.el : me.el;
190 constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container;
191 return el.getConstrainVector(constrainTo);
196 * Aligns this floating Component to the specified element
198 * @param {Ext.Component/Ext.Element/HTMLElement/String} element
199 * The element or {@link Ext.Component} to align to. If passing a component, it must be a
200 * omponent instance. If a string id is passed, it will be used as an element id.
201 * @param {String} [position="tl-bl?"] The position to align to (see {@link
202 * Ext.Element#alignTo} for more details).
203 * @param {Number[]} [offsets] Offset the positioning by [x, y]
204 * @return {Ext.Component} this
206 alignTo: function(element, position, offsets) {
207 if (element.isComponent) {
208 element = element.getEl();
210 var xy = this.el.getAlignToXY(element, position, offsets);
211 this.setPagePosition(xy);
216 * Brings this floating Component to the front of any other visible, floating Components managed by the same {@link
217 * Ext.ZIndexManager ZIndexManager}
219 * If this Component is modal, inserts the modal mask just below this Component in the z-index stack.
221 * @param {Boolean} [preventFocus=false] Specify `true` to prevent the Component from being focused.
222 * @return {Ext.Component} this
224 toFront: function(preventFocus) {
227 // Find the floating Component which provides the base for this Component's zIndexing.
228 // That must move to front to then be able to rebase its zIndex stack and move this to the front
229 if (me.zIndexParent) {
230 me.zIndexParent.toFront(true);
232 if (me.zIndexManager.bringToFront(me)) {
233 if (!Ext.isDefined(preventFocus)) {
234 preventFocus = !me.focusOnToFront;
237 // Kick off a delayed focus request.
238 // If another floating Component is toFronted before the delay expires
239 // this will not receive focus.
240 me.focus(false, true);
247 * This method is called internally by {@link Ext.ZIndexManager} to signal that a floating Component has either been
248 * moved to the top of its zIndex stack, or pushed from the top of its zIndex stack.
250 * If a _Window_ is superceded by another Window, deactivating it hides its shadow.
252 * This method also fires the {@link Ext.Component#activate activate} or
253 * {@link Ext.Component#deactivate deactivate} event depending on which action occurred.
255 * @param {Boolean} [active=false] True to activate the Component, false to deactivate it.
256 * @param {Ext.Component} [newActive] The newly active Component which is taking over topmost zIndex position.
258 setActive: function(active, newActive) {
262 if (me.el.shadow && !me.maximized) {
263 me.el.enableShadow(true);
265 me.fireEvent('activate', me);
267 // Only the *Windows* in a zIndex stack share a shadow. All other types of floaters
268 // can keep their shadows all the time
269 if ((me instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) {
270 me.el.disableShadow();
272 me.fireEvent('deactivate', me);
277 * Sends this Component to the back of (lower z-index than) any other visible windows
278 * @return {Ext.Component} this
281 this.zIndexManager.sendToBack(this);
286 * Center this Component in its container.
287 * @return {Ext.Component} this
291 xy = me.el.getAlignToXY(me.container, 'c-c');
292 me.setPagePosition(xy);
297 syncShadow : function(){
304 fitContainer: function() {
305 var parent = this.floatParent,
306 container = parent ? parent.getTargetEl() : this.container,
307 size = container.getViewSize(false);