Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / docs / source / Portal.html
1 <html>
2 <head>
3   <title>The source code</title>
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
6 </head>
7 <body  onload="prettyPrint();">
8     <pre class="prettyprint lang-js">Ext.ux.Portal = Ext.extend(Ext.Panel, {\r
9     layout : 'column',\r
10     autoScroll : true,\r
11     cls : 'x-portal',\r
12     defaultType : 'portalcolumn',\r
13     \r
14     initComponent : function(){\r
15         Ext.ux.Portal.superclass.initComponent.call(this);\r
16         this.addEvents({\r
17             validatedrop:true,\r
18             beforedragover:true,\r
19             dragover:true,\r
20             beforedrop:true,\r
21             drop:true\r
22         });\r
23     },\r
24 \r
25     initEvents : function(){\r
26         Ext.ux.Portal.superclass.initEvents.call(this);\r
27         this.dd = new Ext.ux.Portal.DropZone(this, this.dropConfig);\r
28     },\r
29     \r
30     beforeDestroy : function() {\r
31         if(this.dd){\r
32             this.dd.unreg();\r
33         }\r
34         Ext.ux.Portal.superclass.beforeDestroy.call(this);\r
35     }\r
36 });\r
37 \r
38 Ext.reg('portal', Ext.ux.Portal);\r
39 \r
40 \r
41 Ext.ux.Portal.DropZone = function(portal, cfg){\r
42     this.portal = portal;\r
43     Ext.dd.ScrollManager.register(portal.body);\r
44     Ext.ux.Portal.DropZone.superclass.constructor.call(this, portal.bwrap.dom, cfg);\r
45     portal.body.ddScrollConfig = this.ddScrollConfig;\r
46 };\r
47 \r
48 Ext.extend(Ext.ux.Portal.DropZone, Ext.dd.DropTarget, {\r
49     ddScrollConfig : {\r
50         vthresh: 50,\r
51         hthresh: -1,\r
52         animate: true,\r
53         increment: 200\r
54     },\r
55 \r
56     createEvent : function(dd, e, data, col, c, pos){\r
57         return {\r
58             portal: this.portal,\r
59             panel: data.panel,\r
60             columnIndex: col,\r
61             column: c,\r
62             position: pos,\r
63             data: data,\r
64             source: dd,\r
65             rawEvent: e,\r
66             status: this.dropAllowed\r
67         };\r
68     },\r
69 \r
70     notifyOver : function(dd, e, data){\r
71         var xy = e.getXY(), portal = this.portal, px = dd.proxy;\r
72 \r
73         // case column widths\r
74         if(!this.grid){\r
75             this.grid = this.getGrid();\r
76         }\r
77 \r
78         // handle case scroll where scrollbars appear during drag\r
79         var cw = portal.body.dom.clientWidth;\r
80         if(!this.lastCW){\r
81             this.lastCW = cw;\r
82         }else if(this.lastCW != cw){\r
83             this.lastCW = cw;\r
84             portal.doLayout();\r
85             this.grid = this.getGrid();\r
86         }\r
87 \r
88         // determine column\r
89         var col = 0, xs = this.grid.columnX, cmatch = false;\r
90         for(var len = xs.length; col < len; col++){\r
91             if(xy[0] < (xs[col].x + xs[col].w)){\r
92                 cmatch = true;\r
93                 break;\r
94             }\r
95         }\r
96         // no match, fix last index\r
97         if(!cmatch){\r
98             col--;\r
99         }\r
100 \r
101         // find insert position\r
102         var p, match = false, pos = 0,\r
103             c = portal.items.itemAt(col),\r
104             items = c.items.items, overSelf = false;\r
105 \r
106         for(var len = items.length; pos < len; pos++){\r
107             p = items[pos];\r
108             var h = p.el.getHeight();\r
109             if(h === 0){\r
110                 overSelf = true;\r
111             }\r
112             else if((p.el.getY()+(h/2)) > xy[1]){\r
113                 match = true;\r
114                 break;\r
115             }\r
116         }\r
117 \r
118         pos = (match && p ? pos : c.items.getCount()) + (overSelf ? -1 : 0);\r
119         var overEvent = this.createEvent(dd, e, data, col, c, pos);\r
120 \r
121         if(portal.fireEvent('validatedrop', overEvent) !== false &&\r
122            portal.fireEvent('beforedragover', overEvent) !== false){\r
123 \r
124             // make sure proxy width is fluid\r
125             px.getProxy().setWidth('auto');\r
126 \r
127             if(p){\r
128                 px.moveProxy(p.el.dom.parentNode, match ? p.el.dom : null);\r
129             }else{\r
130                 px.moveProxy(c.el.dom, null);\r
131             }\r
132 \r
133             this.lastPos = {c: c, col: col, p: overSelf || (match && p) ? pos : false};\r
134             this.scrollPos = portal.body.getScroll();\r
135 \r
136             portal.fireEvent('dragover', overEvent);\r
137 \r
138             return overEvent.status;\r
139         }else{\r
140             return overEvent.status;\r
141         }\r
142 \r
143     },\r
144 \r
145     notifyOut : function(){\r
146         delete this.grid;\r
147     },\r
148 \r
149     notifyDrop : function(dd, e, data){\r
150         delete this.grid;\r
151         if(!this.lastPos){\r
152             return;\r
153         }\r
154         var c = this.lastPos.c, col = this.lastPos.col, pos = this.lastPos.p;\r
155 \r
156         var dropEvent = this.createEvent(dd, e, data, col, c,\r
157             pos !== false ? pos : c.items.getCount());\r
158 \r
159         if(this.portal.fireEvent('validatedrop', dropEvent) !== false &&\r
160            this.portal.fireEvent('beforedrop', dropEvent) !== false){\r
161 \r
162             dd.proxy.getProxy().remove();\r
163             dd.panel.el.dom.parentNode.removeChild(dd.panel.el.dom);\r
164             \r
165             if(pos !== false){\r
166                 if(c == dd.panel.ownerCt && (c.items.items.indexOf(dd.panel) <= pos)){\r
167                     pos++;\r
168                 }\r
169                 c.insert(pos, dd.panel);\r
170             }else{\r
171                 c.add(dd.panel);\r
172             }\r
173             \r
174             c.doLayout();\r
175 \r
176             this.portal.fireEvent('drop', dropEvent);\r
177 \r
178             // scroll position is lost on drop, fix it\r
179             var st = this.scrollPos.top;\r
180             if(st){\r
181                 var d = this.portal.body.dom;\r
182                 setTimeout(function(){\r
183                     d.scrollTop = st;\r
184                 }, 10);\r
185             }\r
186 \r
187         }\r
188         delete this.lastPos;\r
189     },\r
190 \r
191     // internal cache of body and column coords\r
192     getGrid : function(){\r
193         var box = this.portal.bwrap.getBox();\r
194         box.columnX = [];\r
195         this.portal.items.each(function(c){\r
196              box.columnX.push({x: c.el.getX(), w: c.el.getWidth()});\r
197         });\r
198         return box;\r
199     },\r
200 \r
201     // unregister the dropzone from ScrollManager\r
202     unreg: function() {\r
203         //Ext.dd.ScrollManager.unregister(this.portal.body);\r
204         Ext.ux.Portal.DropZone.superclass.unreg.call(this);\r
205     }\r
206 });\r
207 </pre>
208 </body>
209 </html>