X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/Layer.js
diff --git a/src/Layer.js b/src/Layer.js
new file mode 100644
index 00000000..89a06e3f
--- /dev/null
+++ b/src/Layer.js
@@ -0,0 +1,466 @@
+/**
+ * @class Ext.Layer
+ * @extends Ext.core.Element
+ * An extended {@link Ext.core.Element} object that supports a shadow and shim, constrain to viewport and
+ * automatic maintaining of shadow/shim positions.
+ * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)
+ * @cfg {String/Boolean} shadow True to automatically create an {@link Ext.Shadow}, or a string indicating the
+ * shadow's display {@link Ext.Shadow#mode}. False to disable the shadow. (defaults to false)
+ * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: 'div', cls: 'x-layer'}).
+ * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)
+ * @cfg {String} cls CSS class to add to the element
+ * @cfg {Number} zindex Starting z-index (defaults to 11000)
+ * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 4)
+ * @cfg {Boolean} useDisplay
+ * Defaults to use css offsets to hide the Layer. Specify true
+ * to use css style 'display:none;' to hide the Layer.
+ * @cfg {String} visibilityCls The CSS class name to add in order to hide this Layer if this layer
+ * is configured with {@link #hideMode}: 'asclass'
+ * @cfg {String} hideMode
+ * A String which specifies how this Layer will be hidden.
+ * Values may be
'display'
: The Component will be hidden using the display: none
style.'visibility'
: The Component will be hidden using the visibility: hidden
style.'offsets'
: The Component will be hidden by absolutely positioning it out of the visible area of the document. This
+ * is useful when a hidden Component must maintain measurable dimensions. Hiding using display
results
+ * in a Component having zero dimensions.Synchronize this Layer's associated elements, the shadow, and possibly the shim.
+ *This code can execute repeatedly in milliseconds, + * eg: dragging a Component configured liveDrag: true, or which has no ghost method + * so code size was sacrificed for efficiency (e.g. no getBox/setBox, no XY calls)
+ * @param {Boolean} doShow Pass true to ensure that the shadow is shown. + */ + sync: function(doShow) { + var me = this, + shadow = me.shadow, + shadowPos, shimStyle, shadowSize; + + if (!this.updating && this.isVisible() && (shadow || this.useShim)) { + var shim = this.getShim(), + l = this.getLeft(true), + t = this.getTop(true), + w = this.getWidth(), + h = this.getHeight(), + shimIndex; + + if (shadow && !this.shadowDisabled) { + if (doShow && !shadow.isVisible()) { + shadow.show(this); + } else { + shadow.realign(l, t, w, h); + } + if (shim) { + // TODO: Determine how the shims zIndex is above the layer zIndex at this point + shimIndex = shim.getStyle('z-index'); + if (shimIndex > me.zindex) { + me.shim.setStyle('z-index', me.zindex - 2); + } + shim.show(); + // fit the shim behind the shadow, so it is shimmed too + if (shadow.isVisible()) { + shadowPos = shadow.el.getXY(); + shimStyle = shim.dom.style; + shadowSize = shadow.el.getSize(); + shimStyle.left = (shadowPos[0]) + 'px'; + shimStyle.top = (shadowPos[1]) + 'px'; + shimStyle.width = (shadowSize.width) + 'px'; + shimStyle.height = (shadowSize.height) + 'px'; + } else { + shim.setSize(w, h); + shim.setLeftTop(l, t); + } + } + } else if (shim) { + // TODO: Determine how the shims zIndex is above the layer zIndex at this point + shimIndex = shim.getStyle('z-index'); + if (shimIndex > me.zindex) { + me.shim.setStyle('z-index', me.zindex - 2); + } + shim.show(); + shim.setSize(w, h); + shim.setLeftTop(l, t); + } + } + return this; + }, + + remove: function() { + this.hideUnders(); + this.callParent(); + }, + + // private + beginUpdate: function() { + this.updating = true; + }, + + // private + endUpdate: function() { + this.updating = false; + this.sync(true); + }, + + // private + hideUnders: function() { + if (this.shadow) { + this.shadow.hide(); + } + this.hideShim(); + }, + + // private + constrainXY: function() { + if (this.constrain) { + var vw = Ext.core.Element.getViewWidth(), + vh = Ext.core.Element.getViewHeight(), + s = Ext.getDoc().getScroll(), + xy = this.getXY(), + x = xy[0], + y = xy[1], + so = this.shadowOffset, + w = this.dom.offsetWidth + so, + h = this.dom.offsetHeight + so, + moved = false; // only move it if it needs it + // first validate right/bottom + if ((x + w) > vw + s.left) { + x = vw - w - so; + moved = true; + } + if ((y + h) > vh + s.top) { + y = vh - h - so; + moved = true; + } + // then make sure top/left isn't negative + if (x < s.left) { + x = s.left; + moved = true; + } + if (y < s.top) { + y = s.top; + moved = true; + } + if (moved) { + Ext.Layer.superclass.setXY.call(this, [x, y]); + this.sync(); + } + } + return this; + }, + + getConstrainOffset: function() { + return this.shadowOffset; + }, + + // overridden Element method + setVisible: function(visible, animate, duration, callback, easing) { + var me = this, + cb; + + // post operation processing + cb = function() { + if (visible) { + me.sync(true); + } + if (callback) { + callback(); + } + }; + + // Hide shadow and shim if hiding + if (!visible) { + this.hideUnders(true); + } + this.callParent([visible, animate, duration, callback, easing]); + if (!animate) { + cb(); + } + return this; + }, + + // private + beforeFx: function() { + this.beforeAction(); + return this.callParent(arguments); + }, + + // private + afterFx: function() { + this.callParent(arguments); + this.sync(this.isVisible()); + }, + + // private + beforeAction: function() { + if (!this.updating && this.shadow) { + this.shadow.hide(); + } + }, + + // overridden Element method + setLeft: function(left) { + this.callParent(arguments); + return this.sync(); + }, + + setTop: function(top) { + this.callParent(arguments); + return this.sync(); + }, + + setLeftTop: function(left, top) { + this.callParent(arguments); + return this.sync(); + }, + + setXY: function(xy, animate, duration, callback, easing) { + + // Callback will restore shadow state and call the passed callback + callback = this.createCB(callback); + + this.fixDisplay(); + this.beforeAction(); + this.callParent([xy, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, + + // private + createCB: function(callback) { + var me = this, + showShadow = me.shadow && me.shadow.isVisible(); + + return function() { + me.constrainXY(); + me.sync(showShadow); + if (callback) { + callback(); + } + }; + }, + + // overridden Element method + setX: function(x, animate, duration, callback, easing) { + this.setXY([x, this.getY()], animate, duration, callback, easing); + return this; + }, + + // overridden Element method + setY: function(y, animate, duration, callback, easing) { + this.setXY([this.getX(), y], animate, duration, callback, easing); + return this; + }, + + // overridden Element method + setSize: function(w, h, animate, duration, callback, easing) { + // Callback will restore shadow state and call the passed callback + callback = this.createCB(callback); + + this.beforeAction(); + this.callParent([w, h, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, + + // overridden Element method + setWidth: function(w, animate, duration, callback, easing) { + // Callback will restore shadow state and call the passed callback + callback = this.createCB(callback); + + this.beforeAction(); + this.callParent([w, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, + + // overridden Element method + setHeight: function(h, animate, duration, callback, easing) { + // Callback will restore shadow state and call the passed callback + callback = this.createCB(callback); + + this.beforeAction(); + this.callParent([h, animate, duration, callback, easing]); + if (!animate) { + callback(); + } + return this; + }, + + // overridden Element method + setBounds: function(x, y, width, height, animate, duration, callback, easing) { + // Callback will restore shadow state and call the passed callback + callback = this.createCB(callback); + + this.beforeAction(); + if (!animate) { + Ext.Layer.superclass.setXY.call(this, [x, y]); + Ext.Layer.superclass.setSize.call(this, width, height); + callback(); + } else { + this.callParent([x, y, width, height, animate, duration, callback, easing]); + } + return this; + }, + + /** + *Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically + * incremented depending upon the presence of a shim or a shadow in so that it always shows above those two associated elements.
+ *Any shim, will be assigned the passed z-index. A shadow will be assigned the next highet z-index, and the Layer's + * element will receive the highest z-index. + * @param {Number} zindex The new z-index to set + * @return {this} The Layer + */ + setZIndex: function(zindex) { + this.zindex = zindex; + if (this.getShim()) { + this.shim.setStyle('z-index', zindex++); + } + if (this.shadow) { + this.shadow.setZIndex(zindex++); + } + this.setStyle('z-index', zindex); + return this; + } +});