[483] | 1 | define(["dojo", "../util/oo", "../defaults"], |
---|
| 2 | function(dojo, oo, defaults){ |
---|
| 3 | |
---|
| 4 | var surface, surfaceNode; |
---|
| 5 | //dojox.drawing.manager.Stencil = |
---|
| 6 | return oo.declare( |
---|
| 7 | function(options){ |
---|
| 8 | |
---|
| 9 | // TODO: mixin props |
---|
| 10 | |
---|
| 11 | surface = options.surface; |
---|
| 12 | this.canvas = options.canvas; |
---|
| 13 | |
---|
| 14 | //this.defaults = defaults.copy(); |
---|
| 15 | this.undo = options.undo; |
---|
| 16 | this.mouse = options.mouse; |
---|
| 17 | this.keys = options.keys; |
---|
| 18 | this.anchors = options.anchors; |
---|
| 19 | this.stencils = {}; |
---|
| 20 | this.selectedStencils = {}; |
---|
| 21 | this._mouseHandle = this.mouse.register(this); |
---|
| 22 | |
---|
| 23 | dojo.connect(this.keys, "onArrow", this, "onArrow"); |
---|
| 24 | dojo.connect(this.keys, "onEsc", this, "deselect"); |
---|
| 25 | dojo.connect(this.keys, "onDelete", this, "onDelete"); |
---|
| 26 | |
---|
| 27 | }, |
---|
| 28 | { |
---|
| 29 | // summary: |
---|
| 30 | // The main class for tracking Stencils that are cretaed, added, |
---|
| 31 | // selected, or deleted. Also handles selections, multiple |
---|
| 32 | // selections, adding and removing from selections, and dragging |
---|
| 33 | // selections. It's this class that triggers the anchors to |
---|
| 34 | // appear on a Stencil and whther there are anchor on a multiple |
---|
| 35 | // select or not (currently not) |
---|
| 36 | |
---|
| 37 | _dragBegun: false, |
---|
| 38 | _wasDragged:false, |
---|
| 39 | _secondClick:false, |
---|
| 40 | _isBusy:false, |
---|
| 41 | |
---|
| 42 | setRecentStencil: function(stencil){ |
---|
| 43 | // summary: |
---|
| 44 | // Keeps track of the most recent stencil interacted |
---|
| 45 | // with, whether created or selected. |
---|
| 46 | this.recent = stencil; |
---|
| 47 | }, |
---|
| 48 | |
---|
| 49 | getRecentStencil: function(){ |
---|
| 50 | // summary: |
---|
| 51 | // Returns the stencil most recently interacted |
---|
| 52 | // with whether it's last created or last selected |
---|
| 53 | return this.recent; |
---|
| 54 | }, |
---|
| 55 | |
---|
| 56 | register: function(/*Object*/stencil){ |
---|
| 57 | // summary: |
---|
| 58 | // Key method for adding Stencils. Stencils |
---|
| 59 | // can be added to the canvas without adding |
---|
| 60 | // them to this, but they won't have selection |
---|
| 61 | // or drag ability. |
---|
| 62 | |
---|
| 63 | console.log("Selection.register ::::::", stencil.id); |
---|
| 64 | if(stencil.isText && !stencil.editMode && stencil.deleteEmptyCreate && !stencil.getText()){ |
---|
| 65 | // created empty text field |
---|
| 66 | // defaults say to delete |
---|
| 67 | console.warn("EMPTY CREATE DELETE", stencil); |
---|
| 68 | stencil.destroy(); |
---|
| 69 | return false; |
---|
| 70 | } |
---|
| 71 | |
---|
| 72 | this.stencils[stencil.id] = stencil; |
---|
| 73 | this.setRecentStencil(stencil); |
---|
| 74 | |
---|
| 75 | if(stencil.execText){ |
---|
| 76 | if(stencil._text && !stencil.editMode){ |
---|
| 77 | console.log("select text"); |
---|
| 78 | this.selectItem(stencil); |
---|
| 79 | } |
---|
| 80 | stencil.connect("execText", this, function(){ |
---|
| 81 | if(stencil.isText && stencil.deleteEmptyModify && !stencil.getText()){ |
---|
| 82 | console.warn("EMPTY MOD DELETE", stencil); |
---|
| 83 | // text deleted |
---|
| 84 | // defaults say to delete |
---|
| 85 | this.deleteItem(stencil); |
---|
| 86 | }else if(stencil.selectOnExec){ |
---|
| 87 | this.selectItem(stencil); |
---|
| 88 | } |
---|
| 89 | }); |
---|
| 90 | } |
---|
| 91 | |
---|
| 92 | stencil.connect("deselect", this, function(){ |
---|
| 93 | if(!this._isBusy && this.isSelected(stencil)){ |
---|
| 94 | // called from within stencil. do action. |
---|
| 95 | this.deselectItem(stencil); |
---|
| 96 | } |
---|
| 97 | }); |
---|
| 98 | |
---|
| 99 | stencil.connect("select", this, function(){ |
---|
| 100 | if(!this._isBusy && !this.isSelected(stencil)){ |
---|
| 101 | // called from within stencil. do action. |
---|
| 102 | this.selectItem(stencil); |
---|
| 103 | } |
---|
| 104 | }); |
---|
| 105 | |
---|
| 106 | return stencil; |
---|
| 107 | }, |
---|
| 108 | unregister: function(/*Object*/stencil){ |
---|
| 109 | // summary: |
---|
| 110 | // Method for removing Stencils from the manager. |
---|
| 111 | // This doesn't delete them, only removes them from |
---|
| 112 | // the list. |
---|
| 113 | |
---|
| 114 | console.log("Selection.unregister ::::::", stencil.id, "sel:", stencil.selected); |
---|
| 115 | if(stencil){ |
---|
| 116 | stencil.selected && this.onDeselect(stencil); |
---|
| 117 | delete this.stencils[stencil.id]; |
---|
| 118 | } |
---|
| 119 | }, |
---|
| 120 | |
---|
| 121 | onArrow: function(/*Key Event*/evt){ |
---|
| 122 | // summary: |
---|
| 123 | // Moves selection based on keyboard arrow keys |
---|
| 124 | |
---|
| 125 | // FIXME: Check constraints |
---|
| 126 | if(this.hasSelected()){ |
---|
| 127 | this.saveThrottledState(); |
---|
| 128 | this.group.applyTransform({dx:evt.x, dy: evt.y}); |
---|
| 129 | } |
---|
| 130 | }, |
---|
| 131 | |
---|
| 132 | _throttleVrl:null, |
---|
| 133 | _throttle: false, |
---|
| 134 | throttleTime:400, |
---|
| 135 | _lastmxx:-1, |
---|
| 136 | _lastmxy:-1, |
---|
| 137 | saveMoveState: function(){ |
---|
| 138 | // summary: |
---|
| 139 | // Internal. Used for the prototype undo stack. |
---|
| 140 | // Saves selection position. |
---|
| 141 | |
---|
| 142 | var mx = this.group.getTransform(); |
---|
| 143 | if(mx.dx == this._lastmxx && mx.dy == this._lastmxy){ return; } |
---|
| 144 | this._lastmxx = mx.dx; |
---|
| 145 | this._lastmxy = mx.dy; |
---|
| 146 | //console.warn("SAVE MOVE!", mx.dx, mx.dy); |
---|
| 147 | this.undo.add({ |
---|
| 148 | before:dojo.hitch(this.group, "setTransform", mx) |
---|
| 149 | }); |
---|
| 150 | }, |
---|
| 151 | |
---|
| 152 | saveThrottledState: function(){ |
---|
| 153 | // summary: |
---|
| 154 | // Internal. Used for the prototype undo stack. |
---|
| 155 | // Prevents an undo point on every mouse move. |
---|
| 156 | // Only does a point when the mouse hesitates. |
---|
| 157 | |
---|
| 158 | clearTimeout(this._throttleVrl); |
---|
| 159 | clearInterval(this._throttleVrl); |
---|
| 160 | this._throttleVrl = setTimeout(dojo.hitch(this, function(){ |
---|
| 161 | this._throttle = false; |
---|
| 162 | this.saveMoveState(); |
---|
| 163 | }), this.throttleTime); |
---|
| 164 | if(this._throttle){ return; } |
---|
| 165 | this._throttle = true; |
---|
| 166 | |
---|
| 167 | this.saveMoveState(); |
---|
| 168 | |
---|
| 169 | }, |
---|
| 170 | unDelete: function(/*Array*/stencils){ |
---|
| 171 | // summary: |
---|
| 172 | // Undeletes a stencil. Used in undo stack. |
---|
| 173 | |
---|
| 174 | console.log("unDelete:", stencils); |
---|
| 175 | for(var s in stencils){ |
---|
| 176 | stencils[s].render(); |
---|
| 177 | this.onSelect(stencils[s]); |
---|
| 178 | } |
---|
| 179 | }, |
---|
| 180 | onDelete: function(/*Boolean*/noundo){ |
---|
| 181 | // summary: |
---|
| 182 | // Event fired on deletion of a stencil |
---|
| 183 | |
---|
| 184 | console.log("Stencil onDelete", noundo); |
---|
| 185 | if(noundo!==true){ |
---|
| 186 | this.undo.add({ |
---|
| 187 | before:dojo.hitch(this, "unDelete", this.selectedStencils), |
---|
| 188 | after:dojo.hitch(this, "onDelete", true) |
---|
| 189 | }); |
---|
| 190 | } |
---|
| 191 | this.withSelected(function(m){ |
---|
| 192 | this.anchors.remove(m); |
---|
| 193 | var id = m.id; |
---|
| 194 | console.log("delete:", m); |
---|
| 195 | m.destroy(); |
---|
| 196 | delete this.stencils[id]; |
---|
| 197 | }); |
---|
| 198 | this.selectedStencils = {}; |
---|
| 199 | }, |
---|
| 200 | |
---|
| 201 | deleteItem: function(/*Object*/stencil){ |
---|
| 202 | // summary: |
---|
| 203 | // Deletes a stencil. |
---|
| 204 | // NOTE: supports limited undo. |
---|
| 205 | |
---|
| 206 | // manipulating the selection to fire onDelete properly |
---|
| 207 | if(this.hasSelected()){ |
---|
| 208 | // there is a selection |
---|
| 209 | var sids = []; |
---|
| 210 | for(var m in this.selectedStencils){ |
---|
| 211 | if(this.selectedStencils.id == stencil.id){ |
---|
| 212 | if(this.hasSelected()==1){ |
---|
| 213 | // the deleting stencil is the only one selected |
---|
| 214 | this.onDelete(); |
---|
| 215 | return; |
---|
| 216 | } |
---|
| 217 | }else{ |
---|
| 218 | sids.push(this.selectedStencils.id); |
---|
| 219 | } |
---|
| 220 | } |
---|
| 221 | // remove selection, delete, restore selection |
---|
| 222 | this.deselect(); |
---|
| 223 | this.selectItem(stencil); |
---|
| 224 | this.onDelete(); |
---|
| 225 | dojo.forEach(sids, function(id){ |
---|
| 226 | this.selectItem(id); |
---|
| 227 | }, this); |
---|
| 228 | }else{ |
---|
| 229 | // there is not a selection. select it, delete it |
---|
| 230 | this.selectItem(stencil); |
---|
| 231 | // now delete selection |
---|
| 232 | this.onDelete(); |
---|
| 233 | } |
---|
| 234 | }, |
---|
| 235 | |
---|
| 236 | removeAll: function(){ |
---|
| 237 | // summary: |
---|
| 238 | // Deletes all Stencils on the canvas. |
---|
| 239 | |
---|
| 240 | this.selectAll(); |
---|
| 241 | this._isBusy = true; |
---|
| 242 | this.onDelete(); |
---|
| 243 | this.stencils = {}; |
---|
| 244 | this._isBusy = false; |
---|
| 245 | }, |
---|
| 246 | |
---|
| 247 | setSelectionGroup: function(){ |
---|
| 248 | // summary: |
---|
| 249 | // Internal. Creates a new selection group |
---|
| 250 | // used to hold selected stencils. |
---|
| 251 | |
---|
| 252 | this.withSelected(function(m){ |
---|
| 253 | this.onDeselect(m, true); |
---|
| 254 | }); |
---|
| 255 | |
---|
| 256 | if(this.group){ |
---|
| 257 | surface.remove(this.group); |
---|
| 258 | this.group.removeShape(); |
---|
| 259 | } |
---|
| 260 | this.group = surface.createGroup(); |
---|
| 261 | this.group.setTransform({dx:0, dy: 0}); |
---|
| 262 | |
---|
| 263 | this.withSelected(function(m){ |
---|
| 264 | this.group.add(m.container); |
---|
| 265 | m.select(); |
---|
| 266 | }); |
---|
| 267 | }, |
---|
| 268 | |
---|
| 269 | setConstraint: function(){ |
---|
| 270 | // summary: |
---|
| 271 | // Internal. Gets all selected stencils' coordinates |
---|
| 272 | // and determines how far left and up the selection |
---|
| 273 | // can go without going below zero |
---|
| 274 | |
---|
| 275 | var t = Infinity, l = Infinity; |
---|
| 276 | this.withSelected(function(m){ |
---|
| 277 | var o = m.getBounds(); |
---|
| 278 | t = Math.min(o.y1, t); |
---|
| 279 | l = Math.min(o.x1, l); |
---|
| 280 | }); |
---|
| 281 | this.constrain = {l:-l, t:-t}; |
---|
| 282 | }, |
---|
| 283 | |
---|
| 284 | |
---|
| 285 | |
---|
| 286 | onDeselect: function(stencil, keepObject){ |
---|
| 287 | // summary: |
---|
| 288 | // Event fired on deselection of a stencil |
---|
| 289 | |
---|
| 290 | if(!keepObject){ |
---|
| 291 | delete this.selectedStencils[stencil.id]; |
---|
| 292 | } |
---|
| 293 | //console.log('onDeselect, keep:', keepObject, "stencil:", stencil.type) |
---|
| 294 | |
---|
| 295 | this.anchors.remove(stencil); |
---|
| 296 | |
---|
| 297 | surface.add(stencil.container); |
---|
| 298 | stencil.selected && stencil.deselect(); |
---|
| 299 | stencil.applyTransform(this.group.getTransform()); |
---|
| 300 | }, |
---|
| 301 | |
---|
| 302 | deselectItem: function(/*Object*/stencil){ |
---|
| 303 | // summary: |
---|
| 304 | // Deselect passed stencil |
---|
| 305 | |
---|
| 306 | // note: just keeping with standardized methods |
---|
| 307 | this.onDeselect(stencil); |
---|
| 308 | }, |
---|
| 309 | |
---|
| 310 | deselect: function(){ // all stencils |
---|
| 311 | // summary: |
---|
| 312 | // Deselect all stencils |
---|
| 313 | |
---|
| 314 | this.withSelected(function(m){ |
---|
| 315 | this.onDeselect(m); |
---|
| 316 | }); |
---|
| 317 | this._dragBegun = false; |
---|
| 318 | this._wasDragged = false; |
---|
| 319 | }, |
---|
| 320 | |
---|
| 321 | onSelect: function(/*Object*/stencil){ |
---|
| 322 | // summary: |
---|
| 323 | // Event fired on selection of a stencil |
---|
| 324 | |
---|
| 325 | //console.log("stencil.onSelect", stencil); |
---|
| 326 | if(!stencil){ |
---|
| 327 | console.error("null stencil is not selected:", this.stencils) |
---|
| 328 | } |
---|
| 329 | if(this.selectedStencils[stencil.id]){ return; } |
---|
| 330 | this.selectedStencils[stencil.id] = stencil; |
---|
| 331 | this.group.add(stencil.container); |
---|
| 332 | stencil.select(); |
---|
| 333 | if(this.hasSelected()==1){ |
---|
| 334 | this.anchors.add(stencil, this.group); |
---|
| 335 | } |
---|
| 336 | }, |
---|
| 337 | |
---|
| 338 | selectAll: function(){ |
---|
| 339 | // summary: |
---|
| 340 | // Selects all items |
---|
| 341 | this._isBusy = true; |
---|
| 342 | for(var m in this.stencils){ |
---|
| 343 | //if(!this.stencils[m].selected){ |
---|
| 344 | this.selectItem(m); |
---|
| 345 | //} |
---|
| 346 | } |
---|
| 347 | this._isBusy = false; |
---|
| 348 | }, |
---|
| 349 | |
---|
| 350 | selectItem: function(/*String|Object*/ idOrItem){ |
---|
| 351 | // summary: |
---|
| 352 | // Method used to select a stencil. |
---|
| 353 | |
---|
| 354 | var id = typeof(idOrItem)=="string" ? idOrItem : idOrItem.id; |
---|
| 355 | var stencil = this.stencils[id]; |
---|
| 356 | this.setSelectionGroup(); |
---|
| 357 | this.onSelect(stencil); |
---|
| 358 | this.group.moveToFront(); |
---|
| 359 | this.setConstraint(); |
---|
| 360 | }, |
---|
| 361 | |
---|
| 362 | onLabelDoubleClick: function(/*EventObject*/obj){ |
---|
| 363 | // summary: |
---|
| 364 | // Event to connect a textbox to |
---|
| 365 | // for label edits |
---|
| 366 | console.info("mgr.onLabelDoubleClick:", obj); |
---|
| 367 | if(this.selectedStencils[obj.id]){ |
---|
| 368 | this.deselect(); |
---|
| 369 | } |
---|
| 370 | }, |
---|
| 371 | |
---|
| 372 | onStencilDoubleClick: function(/*EventObject*/obj){ |
---|
| 373 | // summary: |
---|
| 374 | // Event fired on the double-click of a stencil |
---|
| 375 | |
---|
| 376 | console.info("mgr.onStencilDoubleClick:", obj); |
---|
| 377 | if(this.selectedStencils[obj.id]){ |
---|
| 378 | if(this.selectedStencils[obj.id].edit){ |
---|
| 379 | console.info("Mgr Stencil Edit -> ", this.selectedStencils[obj.id]); |
---|
| 380 | var m = this.selectedStencils[obj.id]; |
---|
| 381 | // deselect must happen first to set the transform |
---|
| 382 | // then edit knows where to set the text box |
---|
| 383 | m.editMode = true; |
---|
| 384 | this.deselect(); |
---|
| 385 | m.edit(); |
---|
| 386 | } |
---|
| 387 | } |
---|
| 388 | |
---|
| 389 | }, |
---|
| 390 | |
---|
| 391 | onAnchorUp: function(){ |
---|
| 392 | // summary: |
---|
| 393 | // Event fire on mouseup off of an anchor point |
---|
| 394 | this.setConstraint(); |
---|
| 395 | }, |
---|
| 396 | |
---|
| 397 | onStencilDown: function(/*EventObject*/obj, evt){ |
---|
| 398 | // summary: |
---|
| 399 | // Event fired on mousedown on a stencil |
---|
| 400 | |
---|
| 401 | console.info(" >>> onStencilDown:", obj.id, this.keys.meta); |
---|
| 402 | if(!this.stencils[obj.id]){ return; } |
---|
| 403 | this.setRecentStencil(this.stencils[obj.id]); |
---|
| 404 | this._isBusy = true; |
---|
| 405 | |
---|
| 406 | |
---|
| 407 | if(this.selectedStencils[obj.id] && this.keys.meta){ |
---|
| 408 | if(dojo.isMac && this.keys.cmmd){ |
---|
| 409 | // block context menu |
---|
| 410 | |
---|
| 411 | } |
---|
| 412 | console.log(" shift remove"); |
---|
| 413 | this.onDeselect(this.selectedStencils[obj.id]); |
---|
| 414 | if(this.hasSelected()==1){ |
---|
| 415 | this.withSelected(function(m){ |
---|
| 416 | this.anchors.add(m, this.group); |
---|
| 417 | }); |
---|
| 418 | } |
---|
| 419 | this.group.moveToFront(); |
---|
| 420 | this.setConstraint(); |
---|
| 421 | return; |
---|
| 422 | |
---|
| 423 | }else if(this.selectedStencils[obj.id]){ |
---|
| 424 | console.log(" clicked on selected"); |
---|
| 425 | // clicking on same selected item(s) |
---|
| 426 | // RESET OFFSETS |
---|
| 427 | var mx = this.group.getTransform(); |
---|
| 428 | this._offx = obj.x - mx.dx; |
---|
| 429 | this._offy = obj.y - mx.dy; |
---|
| 430 | return; |
---|
| 431 | |
---|
| 432 | }else if(!this.keys.meta){ |
---|
| 433 | |
---|
| 434 | console.log(" deselect all"); |
---|
| 435 | this.deselect(); |
---|
| 436 | |
---|
| 437 | }else{ |
---|
| 438 | // meta-key add |
---|
| 439 | //console.log("reset sel and add stencil") |
---|
| 440 | } |
---|
| 441 | console.log(" add stencil to selection"); |
---|
| 442 | // add a stencil |
---|
| 443 | this.selectItem(obj.id); |
---|
| 444 | |
---|
| 445 | mx = this.group.getTransform(); |
---|
| 446 | this._offx = obj.x - mx.dx; |
---|
| 447 | this._offy = obj.y - mx.dx; |
---|
| 448 | |
---|
| 449 | this.orgx = obj.x; |
---|
| 450 | this.orgy = obj.y; |
---|
| 451 | |
---|
| 452 | this._isBusy = false; |
---|
| 453 | |
---|
| 454 | // TODO: |
---|
| 455 | // dojo.style(surfaceNode, "cursor", "pointer"); |
---|
| 456 | |
---|
| 457 | // TODO: |
---|
| 458 | this.undo.add({ |
---|
| 459 | before:function(){ |
---|
| 460 | |
---|
| 461 | }, |
---|
| 462 | after: function(){ |
---|
| 463 | |
---|
| 464 | } |
---|
| 465 | }); |
---|
| 466 | }, |
---|
| 467 | |
---|
| 468 | onLabelDown: function(/*EventObject*/obj, evt){ |
---|
| 469 | // summary: |
---|
| 470 | // Event fired on mousedown of a stencil's label |
---|
| 471 | // Because it's an annotation the id will be the |
---|
| 472 | // master stencil. |
---|
| 473 | |
---|
| 474 | //console.info("===============>>>Label click: ",obj, " evt: ",evt); |
---|
| 475 | this.onStencilDown(obj,evt); |
---|
| 476 | }, |
---|
| 477 | |
---|
| 478 | onStencilUp: function(/*EventObject*/obj){ |
---|
| 479 | // summary: |
---|
| 480 | // Event fired on mouseup off of a stencil |
---|
| 481 | |
---|
| 482 | }, |
---|
| 483 | |
---|
| 484 | onLabelUp: function(/*EventObject*/obj){ |
---|
| 485 | this.onStencilUp(obj); |
---|
| 486 | }, |
---|
| 487 | |
---|
| 488 | onStencilDrag: function(/*EventObject*/obj){ |
---|
| 489 | // summary: |
---|
| 490 | // Event fired on every mousemove of a stencil drag |
---|
| 491 | |
---|
| 492 | if(!this._dragBegun){ |
---|
| 493 | // bug, in FF anyway - first mouse move shows x=0 |
---|
| 494 | // the 'else' fixes it |
---|
| 495 | this.onBeginDrag(obj); |
---|
| 496 | this._dragBegun = true; |
---|
| 497 | }else{ |
---|
| 498 | this.saveThrottledState(); |
---|
| 499 | |
---|
| 500 | var x = obj.x - obj.last.x, |
---|
| 501 | y = obj.y - obj.last.y, |
---|
| 502 | c = this.constrain, |
---|
| 503 | mz = defaults.anchors.marginZero; |
---|
| 504 | |
---|
| 505 | |
---|
| 506 | x = obj.x - this._offx; |
---|
| 507 | y = obj.y - this._offy; |
---|
| 508 | |
---|
| 509 | if(x < c.l + mz){ |
---|
| 510 | x = c.l + mz; |
---|
| 511 | } |
---|
| 512 | if(y < c.t + mz){ |
---|
| 513 | y = c.t + mz; |
---|
| 514 | } |
---|
| 515 | |
---|
| 516 | this.group.setTransform({ |
---|
| 517 | dx: x, |
---|
| 518 | dy: y |
---|
| 519 | }); |
---|
| 520 | |
---|
| 521 | |
---|
| 522 | } |
---|
| 523 | }, |
---|
| 524 | |
---|
| 525 | onLabelDrag: function(/*EventObject*/obj){ |
---|
| 526 | this.onStencilDrag(obj); |
---|
| 527 | }, |
---|
| 528 | |
---|
| 529 | onDragEnd: function(/*EventObject*/obj){ |
---|
| 530 | // summary: |
---|
| 531 | // Event fired at the end of a stencil drag |
---|
| 532 | |
---|
| 533 | this._dragBegun = false; |
---|
| 534 | }, |
---|
| 535 | onBeginDrag: function(/*EventObject*/obj){ |
---|
| 536 | // summary: |
---|
| 537 | // Event fired at the beginning of a stencil drag |
---|
| 538 | |
---|
| 539 | this._wasDragged = true; |
---|
| 540 | }, |
---|
| 541 | |
---|
| 542 | onDown: function(/*EventObject*/obj){ |
---|
| 543 | // summary: |
---|
| 544 | // Event fired on mousedown on the canvas |
---|
| 545 | |
---|
| 546 | this.deselect(); |
---|
| 547 | }, |
---|
| 548 | |
---|
| 549 | |
---|
| 550 | onStencilOver: function(obj){ |
---|
| 551 | // summary: |
---|
| 552 | // This changes the cursor when hovering over |
---|
| 553 | // a selectable stencil. |
---|
| 554 | |
---|
| 555 | //console.log("OVER") |
---|
| 556 | dojo.style(obj.id, "cursor", "move"); |
---|
| 557 | }, |
---|
| 558 | |
---|
| 559 | onStencilOut: function(obj){ |
---|
| 560 | // summary: |
---|
| 561 | // This restores the cursor. |
---|
| 562 | |
---|
| 563 | //console.log("OUT") |
---|
| 564 | dojo.style(obj.id, "cursor", "crosshair"); |
---|
| 565 | }, |
---|
| 566 | |
---|
| 567 | exporter: function(){ |
---|
| 568 | // summary: |
---|
| 569 | // Collects all Stencil data and returns an |
---|
| 570 | // Array of objects. |
---|
| 571 | var items = []; |
---|
| 572 | for(var m in this.stencils){ |
---|
| 573 | this.stencils[m].enabled && items.push(this.stencils[m].exporter()); |
---|
| 574 | } |
---|
| 575 | return items; // Array |
---|
| 576 | }, |
---|
| 577 | |
---|
| 578 | listStencils: function(){ |
---|
| 579 | return this.stencils; |
---|
| 580 | }, |
---|
| 581 | |
---|
| 582 | toSelected: function(/*String*/func){ |
---|
| 583 | // summary: |
---|
| 584 | // Convenience function calls function *within* |
---|
| 585 | // all selected stencils |
---|
| 586 | var args = Array.prototype.slice.call(arguments).splice(1); |
---|
| 587 | for(var m in this.selectedStencils){ |
---|
| 588 | var item = this.selectedStencils[m]; |
---|
| 589 | item[func].apply(item, args); |
---|
| 590 | } |
---|
| 591 | }, |
---|
| 592 | |
---|
| 593 | withSelected: function(/*Function*/func){ |
---|
| 594 | // summary: |
---|
| 595 | // Convenience function calls function on |
---|
| 596 | // all selected stencils |
---|
| 597 | var f = dojo.hitch(this, func); |
---|
| 598 | for(var m in this.selectedStencils){ |
---|
| 599 | f(this.selectedStencils[m]); |
---|
| 600 | } |
---|
| 601 | }, |
---|
| 602 | |
---|
| 603 | withUnselected: function(/*Function*/func){ |
---|
| 604 | // summary: |
---|
| 605 | // Convenience function calls function on |
---|
| 606 | // all stencils that are not selected |
---|
| 607 | var f = dojo.hitch(this, func); |
---|
| 608 | for(var m in this.stencils){ |
---|
| 609 | !this.stencils[m].selected && f(this.stencils[m]); |
---|
| 610 | } |
---|
| 611 | }, |
---|
| 612 | |
---|
| 613 | withStencils: function(/*Function*/func){ |
---|
| 614 | // summary: |
---|
| 615 | // Convenience function calls function on |
---|
| 616 | // all stencils |
---|
| 617 | var f = dojo.hitch(this, func); |
---|
| 618 | for(var m in this.stencils){ |
---|
| 619 | f(this.stencils[m]); |
---|
| 620 | } |
---|
| 621 | }, |
---|
| 622 | |
---|
| 623 | hasSelected: function(){ |
---|
| 624 | // summary: |
---|
| 625 | // Returns number of selected (generally used |
---|
| 626 | // as truthy or falsey) |
---|
| 627 | |
---|
| 628 | // FIXME: should be areSelected? |
---|
| 629 | var ln = 0; |
---|
| 630 | for(var m in this.selectedStencils){ ln++; } |
---|
| 631 | return ln; // Number |
---|
| 632 | }, |
---|
| 633 | |
---|
| 634 | isSelected: function(/*Object*/stencil){ |
---|
| 635 | // summary: |
---|
| 636 | // Returns if passed stencil is selected or not |
---|
| 637 | // based on internal collection, not on stencil |
---|
| 638 | // boolean |
---|
| 639 | return !!this.selectedStencils[stencil.id]; // Boolean |
---|
| 640 | } |
---|
| 641 | } |
---|
| 642 | |
---|
| 643 | ); |
---|
| 644 | }); |
---|