[483] | 1 | define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) { |
---|
| 2 | |
---|
| 3 | return dojo.declare('dojox.dnd.Selector', dojo.dnd.Selector, { |
---|
| 4 | |
---|
| 5 | conservative: true, |
---|
| 6 | |
---|
| 7 | isSelected: function(node) { |
---|
| 8 | // summary: |
---|
| 9 | // checks if node is selected |
---|
| 10 | // node: String|DomNode |
---|
| 11 | // Node to check (id or DOM Node) |
---|
| 12 | var id = dojo.isString(node) ? node : node.id, |
---|
| 13 | item = this.getItem(id); |
---|
| 14 | return item && this.selected[id]; // Boolean |
---|
| 15 | }, |
---|
| 16 | |
---|
| 17 | selectNode: function(node, add) { |
---|
| 18 | // summary: |
---|
| 19 | // selects a node |
---|
| 20 | // node: String|DomNode |
---|
| 21 | // Node to select (id or DOM Node) |
---|
| 22 | // add: Boolean? |
---|
| 23 | // If true, node is added to selection, otherwise current |
---|
| 24 | // selection is removed, and node will be the only selection. |
---|
| 25 | if (!add) { |
---|
| 26 | this.selectNone(); |
---|
| 27 | } |
---|
| 28 | var id = dojo.isString(node) ? node : node.id, |
---|
| 29 | item = this.getItem(id); |
---|
| 30 | if (item) { |
---|
| 31 | this._removeAnchor(); |
---|
| 32 | this.anchor = dojo.byId(node); |
---|
| 33 | this._addItemClass(this.anchor, 'Anchor'); |
---|
| 34 | this.selection[id] = 1; |
---|
| 35 | this._addItemClass(this.anchor, 'Selected'); |
---|
| 36 | } |
---|
| 37 | return this; // self |
---|
| 38 | }, |
---|
| 39 | |
---|
| 40 | deselectNode: function(node) { |
---|
| 41 | // summary: |
---|
| 42 | // deselects a node |
---|
| 43 | // node: String|DomNode |
---|
| 44 | // Node to deselect (id or DOM Node) |
---|
| 45 | var id = dojo.isString(node) ? node : node.id, |
---|
| 46 | item = this.getItem(id); |
---|
| 47 | if (item && this.selection[id]) { |
---|
| 48 | if (this.anchor === dojo.byId(node)) { |
---|
| 49 | this._removeAnchor(); |
---|
| 50 | } |
---|
| 51 | delete this.selection[id]; |
---|
| 52 | this._removeItemClass(this.anchor, 'Selected'); |
---|
| 53 | } |
---|
| 54 | return this; // self |
---|
| 55 | }, |
---|
| 56 | |
---|
| 57 | selectByBBox: function(left, top, right, bottom, add) { |
---|
| 58 | // summary: |
---|
| 59 | // selects nodes by bounding box |
---|
| 60 | // left: Number |
---|
| 61 | // Left coordinate of the bounding box |
---|
| 62 | // top: Number |
---|
| 63 | // Top coordinate of the bounding box |
---|
| 64 | // right: Number |
---|
| 65 | // Right coordinate of the bounding box |
---|
| 66 | // bottom: Number |
---|
| 67 | // Bottom coordinate of the bounding box |
---|
| 68 | // add: Boolean? |
---|
| 69 | // If true, node is added to selection, otherwise current |
---|
| 70 | // selection is removed, and node will be the only selection. |
---|
| 71 | |
---|
| 72 | // user has drawn a bounding box ... time to see whether any dom nodes |
---|
| 73 | // in this container satisfy the bounding box range. |
---|
| 74 | if (!add) { |
---|
| 75 | this.selectNone(); |
---|
| 76 | } |
---|
| 77 | this.forInItems(function(data, id) { |
---|
| 78 | var node = dojo.byId(id); |
---|
| 79 | if (node && this._isBoundedByBox(node, left, top, right, bottom)) { |
---|
| 80 | this.selectNode(id, true); |
---|
| 81 | } |
---|
| 82 | }, this); |
---|
| 83 | return this; // self |
---|
| 84 | }, |
---|
| 85 | |
---|
| 86 | _isBoundedByBox: function(node, left, top, right, bottom) { |
---|
| 87 | // summary: |
---|
| 88 | // figures out whether certain coodinates bound a particular |
---|
| 89 | // dom node. |
---|
| 90 | // node: String|DomNode |
---|
| 91 | // Node to check (id or DOM Node) |
---|
| 92 | // left: Number |
---|
| 93 | // Left coordinate of the bounding box |
---|
| 94 | // top: Number |
---|
| 95 | // Top coordinate of the bounding box |
---|
| 96 | // right: Number |
---|
| 97 | // Right coordinate of the bounding box |
---|
| 98 | // bottom: Number |
---|
| 99 | // Bottom coordinate of the bounding box |
---|
| 100 | return this.conservative ? this._conservativeBBLogic(node, left, top, right, bottom) : this._liberalBBLogic(node, left, top, right, bottom); |
---|
| 101 | }, |
---|
| 102 | |
---|
| 103 | shift: function(toNext, add) { |
---|
| 104 | // summary: |
---|
| 105 | // shifts the currently selected dnd item forwards and backwards. |
---|
| 106 | // One possible use would be to allow a user select different |
---|
| 107 | // dnd items using the right and left keys. |
---|
| 108 | // toNext: Boolean |
---|
| 109 | // If true, we select the next node, otherwise the previous one. |
---|
| 110 | // add: Boolean? |
---|
| 111 | // If true, add to selection, otherwise current selection is |
---|
| 112 | // removed before adding any nodes. |
---|
| 113 | var selectedNodes = this.getSelectedNodes(); |
---|
| 114 | if (selectedNodes && selectedNodes.length) { |
---|
| 115 | // only delegate to selectNode if at least one node is selected. |
---|
| 116 | // If multiple nodes are selected assume that we go with |
---|
| 117 | // the last selected node. |
---|
| 118 | this.selectNode(this._getNodeId(selectedNodes[selectedNodes.length - 1].id, toNext), add); |
---|
| 119 | } |
---|
| 120 | }, |
---|
| 121 | |
---|
| 122 | _getNodeId: function(nodeId, toNext) { |
---|
| 123 | // summary: |
---|
| 124 | // finds a next/previous node in relation to nodeId |
---|
| 125 | // nodeId: String |
---|
| 126 | // the id of the node to use as the base node |
---|
| 127 | // toNext: Boolean |
---|
| 128 | // If true, we select the next node, otherwise the previous one. |
---|
| 129 | var allNodes = this.getAllNodes(), newId = nodeId; |
---|
| 130 | for (var i = 0, l = allNodes.length; i < l; ++i) { |
---|
| 131 | if (allNodes[i].id == nodeId) { |
---|
| 132 | // have a match ... make sure we don't go outside |
---|
| 133 | var j = Math.min(l - 1, Math.max(0, i + (toNext ? 1 : -1))); |
---|
| 134 | if (i != j) { |
---|
| 135 | // we should be fine to go with the id the user has requested. |
---|
| 136 | newId = allNodes[j].id; |
---|
| 137 | } |
---|
| 138 | break; |
---|
| 139 | } |
---|
| 140 | } |
---|
| 141 | // if we don't get a match, the newId defaults to the currently selected node |
---|
| 142 | return newId; |
---|
| 143 | }, |
---|
| 144 | |
---|
| 145 | _conservativeBBLogic: function(node, left, top, right, bottom) { |
---|
| 146 | // summary: |
---|
| 147 | // logic which determines whether a node is bounded by the |
---|
| 148 | // left,top,right,bottom parameters. This function returns true |
---|
| 149 | // only if the coordinates of the node parameter are fully |
---|
| 150 | // encompassed by the box determined by the left, top, right, bottom parameters. |
---|
| 151 | var c = dojo.coords(node), t; |
---|
| 152 | // normalize input |
---|
| 153 | if (left > right) { |
---|
| 154 | t = left; |
---|
| 155 | left = right; |
---|
| 156 | right = t; |
---|
| 157 | } |
---|
| 158 | if (top > bottom) { |
---|
| 159 | t = top; |
---|
| 160 | top = bottom; |
---|
| 161 | bottom = t; |
---|
| 162 | } |
---|
| 163 | return c.x >= left && c.x + c.w <= right && c.y >= top && c.y + c.h <= bottom; // Boolean |
---|
| 164 | }, |
---|
| 165 | |
---|
| 166 | _liberalBBLogic: function(node, left, top, right, bottom) { |
---|
| 167 | // summary: |
---|
| 168 | // logic which determines whether a node is bounded by the |
---|
| 169 | // left,top,right,bottom parameters. Allows for the case where |
---|
| 170 | // any section of the box determined by the left,top,right,bottom parameters |
---|
| 171 | // overlapping the coordinates of the node parameter constitutes a true |
---|
| 172 | // return value |
---|
| 173 | var c = dojo.position(node), xBounded, yBounded, tlx, tly, brx, bry, leftGreater = false, bottomGreater = false, |
---|
| 174 | nodeTlx = c.x, nodeTly = c.y, nodeBrx = c.x + c.w, nodeBry = c.y + c.h; |
---|
| 175 | // tlx, tly represents the x,y coordinates for the top left of the bounding box |
---|
| 176 | // brx, bry represents the x,y coordinates for the bottom right of the bounding box |
---|
| 177 | // nodeTlx, nodeTly represents the x,y coordinates for the top left of the dom node |
---|
| 178 | // nodeBrx, nodeBry represents the x,y coordinates for the bottom right of the dom node |
---|
| 179 | if (left < right) { |
---|
| 180 | tlx = left; |
---|
| 181 | tly = top; |
---|
| 182 | } else { |
---|
| 183 | leftGreater = true; |
---|
| 184 | tlx = right; |
---|
| 185 | tly = bottom; |
---|
| 186 | } |
---|
| 187 | if (top < bottom) { |
---|
| 188 | bottomGreater = true; |
---|
| 189 | brx = right; |
---|
| 190 | bry = bottom; |
---|
| 191 | } else { |
---|
| 192 | brx = left; |
---|
| 193 | bry = top; |
---|
| 194 | tlx = right; |
---|
| 195 | tly = bottom; |
---|
| 196 | } |
---|
| 197 | if (leftGreater && bottomGreater) { |
---|
| 198 | // accommodate for the case where the user is drawing from top down and from right to left. |
---|
| 199 | brx = left; |
---|
| 200 | bry = bottom; |
---|
| 201 | tlx = right; |
---|
| 202 | tly = top; |
---|
| 203 | } |
---|
| 204 | xBounded = (nodeTlx >= tlx || nodeBrx <= brx) && (tlx <= nodeBrx && brx >= nodeTlx) || (nodeTlx <= tlx && nodeBrx >= brx); |
---|
| 205 | yBounded = (tly <= nodeBry && bry >= nodeTly) || (nodeBry >= bry && nodeTly <= bry); |
---|
| 206 | return xBounded && yBounded; // Boolean |
---|
| 207 | } |
---|
| 208 | } |
---|
| 209 | ); |
---|
| 210 | }); |
---|