1 /** 2 * @ignore 3 */ 4 var Ozone = Ozone ? Ozone : {}; 5 6 /** 7 * @ignore 8 * @namespace 9 */ 10 Ozone.dragAndDrop = Ozone.dragAndDrop ? Ozone.dragAndDrop : {}; 11 12 Ozone.dragAndDrop.WidgetDragAndDropContainer = function(cfg) { 13 14 this.callback = cfg.callback; 15 16 //set initial drag text 17 this.dragIndicatorText = cfg.dragIndicatorText ? cfg.dragIndicatorText : 'Dragging Data'; 18 19 //create drag indicator 20 this.dragIndicator = this.createDragIndicator(); 21 this.dragIndicatorTextNode = owfdojo.query('span.ddText',this.dragIndicator)[0]; 22 23 //subscribe to channels 24 this.eventingContainer = cfg.eventingContainer; 25 this.eventingContainer.subscribe(this.dragStartName, owfdojo.hitch(this, this.onStartDrag)); 26 this.eventingContainer.subscribe(this.dragStopInWidgetName, owfdojo.hitch(this, this.onDragStopInWidget)); 27 this.eventingContainer.subscribe(this.dragSendDataName, owfdojo.hitch(this, this.onDragSendData)); 28 29 //hook mouse move and mouse up 30 this.listeners = {}; 31 32 this.callbacks = {}; 33 34 var lastEl; 35 36 function fireMouseEvent(el, type, msg) { 37 var evt; 38 if(document.createEvent) { 39 evt = document.createEvent('MouseEvents'); 40 evt.initMouseEvent(type, true, true, window, 1, 41 msg.screenX, msg.screenY, msg.pageX, msg.pageY, 42 false, false, false, false, null, null 43 ); 44 el.dispatchEvent(evt); 45 } 46 else if(document.createEventObject) { 47 evt = document.createEventObject(); 48 el.fireEvent('on' + type, evt); 49 } 50 } 51 52 gadgets.rpc.register('_fake_mouse_move', owfdojo.hitch(this, function(msg) { 53 var senderObj = gadgets.json.parse(msg.sender); 54 var iframeId = gadgets.json.stringify({id:senderObj.id}); 55 var position = Ext.get(iframeId).getOffsetsTo(Ext.getBody()); 56 var el = document.elementFromPoint(position[0]+msg.pageX, position[1]+msg.pageY); 57 58 // convert widget pageX and pageY to container pageX and pageY 59 msg.pageX += position[0]; 60 msg.pageY += position[1]; 61 62 if(lastEl && lastEl !== el) { 63 if(lastEl.nodeName === 'IFRAME') { 64 this.eventingContainer.publish(this.dragOutName, null, lastEl.id); 65 } 66 else { 67 fireMouseEvent(lastEl, 'mouseout', msg); 68 fireMouseEvent(el, 'mouseover', msg); 69 } 70 } 71 if(el && el.nodeName === 'IFRAME') { 72 var elPos = Ext.get(el.id).getOffsetsTo(Ext.getBody()); 73 74 // convert container pageX and pageY to sending widget's pageX and pageY to 75 msg.pageX -= elPos[0]; 76 msg.pageY -= elPos[1]; 77 78 gadgets.rpc.call(el.id, '_fire_mouse_move', null, msg); 79 this.hideDragIndicator(); 80 } 81 else if(el){ 82 fireMouseEvent(el, 'mousemove', msg); 83 } 84 // update lastEl 85 lastEl = el; 86 })); 87 88 gadgets.rpc.register('_fake_mouse_out', owfdojo.hitch(this, this.hideDragIndicator)); 89 90 gadgets.rpc.register('_fake_mouse_up', owfdojo.hitch(this, function(msg) { 91 var senderObj = gadgets.json.parse(msg.sender); 92 var iframeId = gadgets.json.stringify({id:senderObj.id}); 93 var position = Ext.get(iframeId).getOffsetsTo(Ext.getBody()); 94 var el = document.elementFromPoint(position[0]+msg.pageX, position[1]+msg.pageY); 95 96 msg.pageX += position[0]; 97 msg.pageY += position[1]; 98 99 if(el.nodeName === 'IFRAME') { 100 var elPos = Ext.get(el.id).getOffsetsTo(Ext.getBody()) 101 msg.pageX -= elPos[0]; 102 msg.pageY -= elPos[1]; 103 gadgets.rpc.call(el.id, '_fire_mouse_up', null, msg); 104 } 105 else { 106 fireMouseEvent(el, 'mouseup', msg); 107 } 108 lastEl = null; 109 })); 110 }; 111 112 Ozone.dragAndDrop.WidgetDragAndDropContainer.prototype = { 113 114 //public events 115 dragStart: 'dragStart', 116 dragStop: 'dragStop', 117 dropReceive: 'dropReceive', 118 119 //private events 120 dragStartName: '_dragStart', 121 dragOverWidgetName: '_dragOverWidget', 122 dragOutName: '_dragOutName', 123 dragStopInContainerName: '_dragStopInContainer', 124 dragStopInWidgetName: '_dragStopInWidget', 125 dragSendDataName: "_dragSendData", 126 dropReceiveDataName: "_dropReceiveData", 127 version: Ozone.version.owfversion + Ozone.version.dragAndDrop, 128 dragDropData: null, 129 130 131 createDragIndicator: function () { 132 return owfdojo.create('span', { 133 className: 'ddBox ddBoxCannotDrop', 134 style: 'display: none', 135 innerHTML: '<span class="ddText">' + this.dragIndicatorText + '</span>' 136 }, 137 owfdojo.body() 138 ); 139 }, 140 141 onStartDrag : function(sender, msg) { 142 this.dragging = true; 143 144 if (owfdojo.isFunction(this.callbacks[this.dragStart])) { 145 //execute callback if false is returned don't continue 146 if (this.callbacks[this.dragStart](sender,msg) === false) { 147 return; 148 } 149 } 150 151 this.dragIndicatorText = msg.dragDropLabel; 152 153 if (this.listeners.onmousemove == null) { 154 this.listeners.onmousemove = owfdojo.connect(document, 'onmousemove', this, this.mouseMove); 155 } 156 if (this.listeners.onmouseup == null) { 157 this.listeners.onmouseup = owfdojo.connect(document, 'onmouseup', this, this.mouseUp); 158 } 159 if (this.listeners.onmouseout == null) { 160 this.listeners.onmouseout = owfdojo.connect(document, 'onmouseout', this, this.mouseOut); 161 } 162 }, 163 164 getMouseCoordinates: function (e) { 165 var returnValue = null; 166 if (e.pageX || e.pageY) { 167 returnValue = { 168 x : e.pageX, 169 y : e.pageY 170 }; 171 } 172 else { 173 returnValue = { 174 x : e.clientX + document.body.scrollLeft - document.body.clientLeft, 175 y : e.clientY + document.body.scrollTop - document.body.clientTop 176 }; 177 } 178 return returnValue; 179 }, 180 181 mouseMove : function(e) { 182 var clientWidth = null; 183 var clientHeight = null; 184 var mousePosition = this.getMouseCoordinates(e); 185 var leftWidth = mousePosition.x; 186 var topHeight = mousePosition.y; 187 188 // Hide the drag indicator box while we move it 189 this.hideDragIndicator(); 190 191 if (e === undefined) { 192 e = window.event; 193 } 194 195 // flipping mechanism when the cursor reaches the right or bottom edge of the widget 196 this.dragIndicator.style.top = topHeight + 19 + "px"; 197 if (owfdojo.isIE) { 198 clientWidth = document.body.clientWidth; 199 clientHeight = document.body.clientHeight; 200 } 201 else { 202 clientWidth = window.innerWidth; 203 clientHeight = window.innerHeight; 204 } 205 206 var rightLimit = clientWidth - 100; 207 if ((leftWidth < clientWidth) && (leftWidth > rightLimit)) { 208 this.dragIndicator.style.left = leftWidth - 88 + "px"; 209 } 210 else { 211 this.dragIndicator.style.left = leftWidth + 12 + "px"; 212 } 213 var bottomLimit = clientHeight - 40; 214 if ((topHeight > bottomLimit) && (topHeight < clientHeight)) { 215 this.dragIndicator.style.top = topHeight - 30 + "px"; 216 } 217 218 // set text on indicator 219 this.dragIndicatorTextNode.innerHTML = this.dragIndicatorText; 220 owfdojo.style(this.dragIndicator, { 221 display: 'block' 222 }); 223 }, 224 225 onDragStopInWidget : function(sender, msg) { 226 this.hideDragIndicator(); 227 228 //disconnect listeners 229 for (l in this.listeners) { 230 owfdojo.disconnect(this.listeners[l]); 231 this.listeners[l] = null; 232 } 233 234 //actually send data 235 this.eventingContainer.publish(this.dropReceiveDataName, this.dragDropData,sender); 236 // Publish event to let widgets know that the mouse button was released 237 this.eventingContainer.publish(this.dragStopInContainerName, null); 238 239 this.dragging = false; 240 241 if (owfdojo.isFunction(this.callbacks[this.dragStop])) { 242 //execute callback if false is returned don't continue 243 this.callbacks[this.dragStop](msg); 244 } 245 }, 246 247 mouseUp: function() { 248 this.hideDragIndicator(); 249 250 //disconnect listeners 251 for (l in this.listeners) { 252 owfdojo.disconnect(this.listeners[l]); 253 this.listeners[l] = null; 254 } 255 256 // Publish event to let widgets know that the mouse button was released 257 this.eventingContainer.publish(this.dragStopInContainerName, null); 258 259 this.dragging = false; 260 261 if (owfdojo.isFunction(this.callbacks[this.dragStop])) { 262 //execute callback if false is returned don't continue 263 this.callbacks[this.dragStop](); 264 } 265 }, 266 267 mouseOut : function(e) { 268 if (e === undefined) { 269 e = window.event; 270 } 271 var mouseOutTarget = null; 272 if (e.toElement === undefined) { 273 mouseOutTarget = e.relatedTarget; 274 } 275 else { 276 mouseOutTarget = e.toElement; 277 } 278 if (mouseOutTarget) { 279 280 this.hideDragIndicator(); 281 282 // Mouse cursor is moving into the desktop or another widget, 283 // so we send an event informing widgets of this 284 this.eventingContainer.publish(this.dragOutName, null); 285 } 286 }, 287 288 onDragSendData: function(sender,data) { 289 this.dragDropData = data; 290 }, 291 292 addCallback : function(eventName, cb) { 293 this.callbacks[eventName] = cb; 294 }, 295 296 /** 297 * @description returns whether a drag is in progress 298 */ 299 isDragging : function() { 300 return this.dragging; 301 }, 302 303 hideDragIndicator: function() { 304 owfdojo.style(this.dragIndicator, { 305 display: 'none' 306 }); 307 } 308 }; 309