initial import
[roojs1] / Roo / Shadow.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11
12
13 /**
14  * @class Roo.Shadow
15  * Simple class that can provide a shadow effect for any element.  Note that the element MUST be absolutely positioned,
16  * and the shadow does not provide any shimming.  This should be used only in simple cases -- for more advanced
17  * functionality that can also provide the same shadow effect, see the {@link Roo.Layer} class.
18  * @constructor
19  * Create a new Shadow
20  * @param {Object} config The config object
21  */
22 Roo.Shadow = function(config){
23     Roo.apply(this, config);
24     if(typeof this.mode != "string"){
25         this.mode = this.defaultMode;
26     }
27     var o = this.offset, a = {h: 0};
28     var rad = Math.floor(this.offset/2);
29     switch(this.mode.toLowerCase()){ // all this hideous nonsense calculates the various offsets for shadows
30         case "drop":
31             a.w = 0;
32             a.l = a.t = o;
33             a.t -= 1;
34             if(Roo.isIE){
35                 a.l -= this.offset + rad;
36                 a.t -= this.offset + rad;
37                 a.w -= rad;
38                 a.h -= rad;
39                 a.t += 1;
40             }
41         break;
42         case "sides":
43             a.w = (o*2);
44             a.l = -o;
45             a.t = o-1;
46             if(Roo.isIE){
47                 a.l -= (this.offset - rad);
48                 a.t -= this.offset + rad;
49                 a.l += 1;
50                 a.w -= (this.offset - rad)*2;
51                 a.w -= rad + 1;
52                 a.h -= 1;
53             }
54         break;
55         case "frame":
56             a.w = a.h = (o*2);
57             a.l = a.t = -o;
58             a.t += 1;
59             a.h -= 2;
60             if(Roo.isIE){
61                 a.l -= (this.offset - rad);
62                 a.t -= (this.offset - rad);
63                 a.l += 1;
64                 a.w -= (this.offset + rad + 1);
65                 a.h -= (this.offset + rad);
66                 a.h += 1;
67             }
68         break;
69     };
70
71     this.adjusts = a;
72 };
73
74 Roo.Shadow.prototype = {
75     /**
76      * @cfg {String} mode
77      * The shadow display mode.  Supports the following options:<br />
78      * sides: Shadow displays on both sides and bottom only<br />
79      * frame: Shadow displays equally on all four sides<br />
80      * drop: Traditional bottom-right drop shadow (default)
81      */
82     /**
83      * @cfg {String} offset
84      * The number of pixels to offset the shadow from the element (defaults to 4)
85      */
86     offset: 4,
87
88     // private
89     defaultMode: "drop",
90
91     /**
92      * Displays the shadow under the target element
93      * @param {String/HTMLElement/Element} targetEl The id or element under which the shadow should display
94      */
95     show : function(target){
96         target = Roo.get(target);
97         if(!this.el){
98             this.el = Roo.Shadow.Pool.pull();
99             if(this.el.dom.nextSibling != target.dom){
100                 this.el.insertBefore(target);
101             }
102         }
103         this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
104         if(Roo.isIE){
105             this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
106         }
107         this.realign(
108             target.getLeft(true),
109             target.getTop(true),
110             target.getWidth(),
111             target.getHeight()
112         );
113         this.el.dom.style.display = "block";
114     },
115
116     /**
117      * Returns true if the shadow is visible, else false
118      */
119     isVisible : function(){
120         return this.el ? true : false;  
121     },
122
123     /**
124      * Direct alignment when values are already available. Show must be called at least once before
125      * calling this method to ensure it is initialized.
126      * @param {Number} left The target element left position
127      * @param {Number} top The target element top position
128      * @param {Number} width The target element width
129      * @param {Number} height The target element height
130      */
131     realign : function(l, t, w, h){
132         if(!this.el){
133             return;
134         }
135         var a = this.adjusts, d = this.el.dom, s = d.style;
136         var iea = 0;
137         s.left = (l+a.l)+"px";
138         s.top = (t+a.t)+"px";
139         var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
140         if(s.width != sws || s.height != shs){
141             s.width = sws;
142             s.height = shs;
143             if(!Roo.isIE){
144                 var cn = d.childNodes;
145                 var sww = Math.max(0, (sw-12))+"px";
146                 cn[0].childNodes[1].style.width = sww;
147                 cn[1].childNodes[1].style.width = sww;
148                 cn[2].childNodes[1].style.width = sww;
149                 cn[1].style.height = Math.max(0, (sh-12))+"px";
150             }
151         }
152     },
153
154     /**
155      * Hides this shadow
156      */
157     hide : function(){
158         if(this.el){
159             this.el.dom.style.display = "none";
160             Roo.Shadow.Pool.push(this.el);
161             delete this.el;
162         }
163     },
164
165     /**
166      * Adjust the z-index of this shadow
167      * @param {Number} zindex The new z-index
168      */
169     setZIndex : function(z){
170         this.zIndex = z;
171         if(this.el){
172             this.el.setStyle("z-index", z);
173         }
174     }
175 };
176
177 // Private utility class that manages the internal Shadow cache
178 Roo.Shadow.Pool = function(){
179     var p = [];
180     var markup = Roo.isIE ?
181                  '<div class="x-ie-shadow"></div>' :
182                  '<div class="x-shadow"><div class="xst"><div class="xstl"></div><div class="xstc"></div><div class="xstr"></div></div><div class="xsc"><div class="xsml"></div><div class="xsmc"></div><div class="xsmr"></div></div><div class="xsb"><div class="xsbl"></div><div class="xsbc"></div><div class="xsbr"></div></div></div>';
183     return {
184         pull : function(){
185             var sh = p.shift();
186             if(!sh){
187                 sh = Roo.get(Roo.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
188                 sh.autoBoxAdjust = false;
189             }
190             return sh;
191         },
192
193         push : function(sh){
194             p.push(sh);
195         }
196     };
197 }();