]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * A lightweight component to display data in a simple tree structure.\r | |
3 | * @since 6.0.0\r | |
4 | */\r | |
5 | Ext.define('Ext.list.Tree', {\r | |
6 | extend: 'Ext.Widget',\r | |
7 | xtype: 'treelist',\r | |
8 | \r | |
9 | requires: [\r | |
10 | 'Ext.list.RootTreeItem'\r | |
11 | ],\r | |
12 | \r | |
13 | expanderFirstCls: Ext.baseCSSPrefix + 'treelist-expander-first',\r | |
14 | expanderOnlyCls: Ext.baseCSSPrefix + 'treelist-expander-only',\r | |
15 | highlightPathCls: Ext.baseCSSPrefix + 'treelist-highlight-path',\r | |
16 | microCls: Ext.baseCSSPrefix + 'treelist-micro',\r | |
17 | \r | |
18 | uiPrefix: Ext.baseCSSPrefix + 'treelist-',\r | |
19 | \r | |
20 | element: {\r | |
21 | reference: 'element',\r | |
22 | cls: Ext.baseCSSPrefix + 'treelist ' + Ext.baseCSSPrefix + 'unselectable',\r | |
23 | listeners: {\r | |
24 | click: 'onClick',\r | |
25 | mouseenter: 'onMouseEnter',\r | |
26 | mouseleave: 'onMouseLeave',\r | |
27 | mouseover: 'onMouseOver'\r | |
28 | },\r | |
29 | children: [{\r | |
30 | reference: 'toolsElement',\r | |
31 | cls: Ext.baseCSSPrefix + 'treelist-toolstrip',\r | |
32 | listeners: {\r | |
33 | click: 'onToolStripClick',\r | |
34 | mouseover: 'onToolStripMouseOver'\r | |
35 | }\r | |
36 | }]\r | |
37 | },\r | |
38 | \r | |
39 | cachedConfig: {\r | |
40 | animation: {\r | |
41 | duration: 500,\r | |
42 | easing: 'ease'\r | |
43 | },\r | |
44 | \r | |
45 | expanderFirst: true,\r | |
46 | \r | |
47 | /**\r | |
48 | * @cfg {Boolean} expanderOnly\r | |
49 | * `true` to expand only on the click of the expander element. Setting this to\r | |
50 | * `false` will allow expansion on click of any part of the element.\r | |
51 | */\r | |
52 | expanderOnly: true\r | |
53 | },\r | |
54 | \r | |
55 | config: {\r | |
56 | /**\r | |
57 | * @cfg {Object} [defaults]\r | |
58 | * The default configuration for the widgets created for tree items.\r | |
59 | *\r | |
60 | * @cfg {String} [defaults.xtype="treelistitem"]\r | |
61 | * The type of item to create. By default, items are `{@link Ext.list.TreeItem treelistitem}`\r | |
62 | * instances. This can be customized but this `xtype` must reference a class that\r | |
63 | * ultimately derives from the `{@link Ext.list.AbstractTreeItem}` base class.\r | |
64 | */\r | |
65 | defaults: {\r | |
66 | xtype: 'treelistitem'\r | |
67 | },\r | |
68 | \r | |
69 | highlightPath: null,\r | |
70 | \r | |
71 | iconSize: null,\r | |
72 | \r | |
73 | indent: null,\r | |
74 | \r | |
75 | micro: null,\r | |
76 | \r | |
77 | overItem: null,\r | |
78 | \r | |
79 | /**\r | |
80 | * @cfg {Ext.data.TreeModel} selection\r | |
81 | * \r | |
82 | * The current selected node.\r | |
83 | */\r | |
84 | selection: null, \r | |
85 | \r | |
86 | /**\r | |
87 | * @cfg {Boolean} selectOnExpander\r | |
88 | * `true` to select the node when clicking the expander.\r | |
89 | */\r | |
90 | selectOnExpander: false,\r | |
91 | \r | |
92 | /**\r | |
93 | * @cfg {Boolean} [singleExpand=false]\r | |
94 | * `true` if only 1 node per branch may be expanded.\r | |
95 | */\r | |
96 | singleExpand: null,\r | |
97 | \r | |
98 | /**\r | |
99 | * @cfg {String/Object/Ext.data.TreeStore}\r | |
100 | * The data source to which this component is bound.\r | |
101 | */\r | |
102 | store: null,\r | |
103 | \r | |
104 | ui: null\r | |
105 | },\r | |
106 | \r | |
107 | twoWayBindable: {\r | |
108 | selection: 1\r | |
109 | },\r | |
110 | \r | |
111 | publishes: {\r | |
112 | selection: 1\r | |
113 | },\r | |
114 | \r | |
115 | defaultBindProperty: 'store',\r | |
116 | \r | |
117 | constructor: function(config) {\r | |
118 | this.callParent([config]);\r | |
119 | // Important to publish the value here, so the vm can\r | |
120 | // will know our intial state.\r | |
121 | this.publishState('selection', this.getSelection());\r | |
122 | },\r | |
123 | \r | |
124 | beforeLayout: function () {\r | |
125 | // Only called in classic, ignored in modern\r | |
126 | this.syncIconSize();\r | |
127 | },\r | |
128 | \r | |
129 | destroy: function () {\r | |
130 | var me = this;\r | |
131 | \r | |
132 | me.destroying = true; // normally set in callParent\r | |
133 | \r | |
134 | me.unfloatAll(); \r | |
135 | me.activeFloater = null;\r | |
136 | me.setSelection(null);\r | |
137 | me.setStore(null);\r | |
138 | me.callParent();\r | |
139 | },\r | |
140 | \r | |
141 | updateOverItem: function (over, wasOver) {\r | |
142 | var map = {},\r | |
143 | state = 2,\r | |
144 | c, node;\r | |
145 | \r | |
146 | // Walk up the node hierarchy starting at the "over" item and set their "over"\r | |
147 | // config appropriately (2 when over that row, 1 when over a descendant).\r | |
148 | //\r | |
149 | for (c = over; c; c = this.getItem(node.parentNode)) {\r | |
150 | node = c.getNode();\r | |
151 | map[node.internalId] = true;\r | |
152 | \r | |
153 | c.setOver(state);\r | |
154 | \r | |
155 | state = 1;\r | |
156 | }\r | |
157 | \r | |
158 | if (wasOver) {\r | |
159 | // If we wasOver something else previously, walk up that node hierarchy and\r | |
160 | // set their "over" to 0... until we encounter some node that we are still\r | |
161 | // "over" (as determined in previous loop).\r | |
162 | //\r | |
163 | for (c = wasOver; c; c = this.getItem(node.parentNode)) {\r | |
164 | node = c.getNode();\r | |
165 | if (map[node.internalId]) {\r | |
166 | break;\r | |
167 | }\r | |
168 | \r | |
169 | c.setOver(0);\r | |
170 | }\r | |
171 | }\r | |
172 | },\r | |
173 | \r | |
174 | applySelection: function(selection, oldSelection) {\r | |
175 | var store = this.getStore();\r | |
176 | if (!store) {\r | |
177 | selection = null;\r | |
178 | }\r | |
179 | if (selection && selection.get('selectable') === false) {\r | |
180 | selection = oldSelection;\r | |
181 | }\r | |
182 | return selection;\r | |
183 | },\r | |
184 | \r | |
185 | updateSelection: function(selection, oldSelection) {\r | |
186 | var me = this,\r | |
187 | item;\r | |
188 | \r | |
189 | if (!me.destroying) {\r | |
190 | // getItem has guards around null, so we don't\r | |
191 | // need to check for oldSelection/selection here\r | |
192 | item = me.getItem(oldSelection);\r | |
193 | if (item) {\r | |
194 | item.setSelected(false);\r | |
195 | }\r | |
196 | \r | |
197 | item = me.getItem(selection);\r | |
198 | if (item) {\r | |
199 | item.setSelected(true);\r | |
200 | }\r | |
201 | me.fireEvent('selectionchange', me, selection);\r | |
202 | }\r | |
203 | },\r | |
204 | \r | |
205 | applyStore: function (store) {\r | |
206 | return store && Ext.StoreManager.lookup(store, 'tree');\r | |
207 | },\r | |
208 | \r | |
209 | updateStore: function (store, oldStore) {\r | |
210 | var me = this,\r | |
211 | root;\r | |
212 | \r | |
213 | if (oldStore) {\r | |
214 | if (oldStore.getAutoDestroy()) {\r | |
215 | oldStore.destroy();\r | |
216 | } else {\r | |
217 | me.storeListeners.destroy();\r | |
218 | }\r | |
219 | me.removeRoot();\r | |
220 | me.storeListeners = null;\r | |
221 | }\r | |
222 | \r | |
223 | if (store) {\r | |
224 | me.storeListeners = store.on({\r | |
225 | destroyable: true,\r | |
226 | scope: me,\r | |
227 | nodeappend: me.onNodeAppend,\r | |
228 | nodecollapse: me.onNodeCollapse,\r | |
229 | nodeexpand: me.onNodeExpand,\r | |
230 | nodeinsert: me.onNodeInsert,\r | |
231 | noderemove: me.onNodeRemove,\r | |
232 | rootchange: me.onRootChange,\r | |
233 | update: me.onNodeUpdate\r | |
234 | });\r | |
235 | \r | |
236 | root = store.getRoot();\r | |
237 | if (root) {\r | |
238 | me.createRootItem(root);\r | |
239 | }\r | |
240 | }\r | |
241 | \r | |
242 | if (!me.destroying) {\r | |
243 | me.updateLayout();\r | |
244 | }\r | |
245 | },\r | |
246 | \r | |
247 | updateExpanderFirst: function (expanderFirst) {\r | |
248 | this.element.toggleCls(this.expanderFirstCls, expanderFirst);\r | |
249 | },\r | |
250 | \r | |
251 | updateExpanderOnly: function (value) {\r | |
252 | this.element.toggleCls(this.expanderOnlyCls, !value);\r | |
253 | },\r | |
254 | \r | |
255 | updateHighlightPath: function (updatePath) {\r | |
256 | this.element.toggleCls(this.highlightPathCls, updatePath);\r | |
257 | },\r | |
258 | \r | |
259 | updateMicro: function (micro) {\r | |
260 | var me = this;\r | |
261 | \r | |
262 | if (!micro) {\r | |
263 | me.unfloatAll();\r | |
264 | me.activeFloater = null;\r | |
265 | }\r | |
266 | \r | |
267 | me.element.toggleCls(me.microCls, micro);\r | |
268 | },\r | |
269 | \r | |
270 | updateUi: function (ui, oldValue) {\r | |
271 | var el = this.element,\r | |
272 | uiPrefix = this.uiPrefix;\r | |
273 | \r | |
274 | if (oldValue) {\r | |
275 | el.removeCls(uiPrefix + oldValue);\r | |
276 | }\r | |
277 | if (ui) {\r | |
278 | el.addCls(uiPrefix + ui);\r | |
279 | }\r | |
280 | \r | |
281 | // Ensure that the cached iconSize is read from the style.\r | |
282 | delete this.iconSize;\r | |
283 | this.syncIconSize();\r | |
284 | },\r | |
285 | \r | |
286 | /**\r | |
287 | * Get a child {@link Ext.list.AbstractTreeItem item} by node.\r | |
288 | * @param {Ext.data.TreeModel} node The node.\r | |
289 | * @return {Ext.list.AbstractTreeItem} The item. `null` if not found.\r | |
290 | */\r | |
291 | getItem: function (node) {\r | |
292 | var map = this.itemMap,\r | |
293 | ret;\r | |
294 | \r | |
295 | if (node && map) {\r | |
296 | ret = map[node.internalId];\r | |
297 | }\r | |
298 | \r | |
299 | return ret || null;\r | |
300 | },\r | |
301 | \r | |
302 | /**\r | |
303 | * This method is called to populate and return a config object for new nodes. This\r | |
304 | * can be overridden by derived classes to manipulate properties or `xtype` of the\r | |
305 | * returned object. Upon return, the object is passed to `{@link Ext#create}` and the\r | |
306 | * reference is stored as part of this tree.\r | |
307 | *\r | |
308 | * The base class implementation will apply any configured `{@link #defaults}` to the\r | |
309 | * object it returns.\r | |
310 | *\r | |
311 | * @param {Ext.data.TreeModel} node The node backing the item.\r | |
312 | * @param {Ext.list.AbstractTreeItem} parent The parent item. This is never `null` but\r | |
313 | * may be an instance of `{@link Ext.list.RootTreeItem}`.\r | |
314 | * @return {Object} The config object to pass to `{@link Ext#create}` for the item.\r | |
315 | * @template\r | |
316 | */\r | |
317 | getItemConfig: function (node, parent) {\r | |
318 | return Ext.apply({\r | |
319 | parentItem: parent.isRootListItem ? null : parent,\r | |
320 | owner: this,\r | |
321 | node: node,\r | |
322 | indent: this.getIndent()\r | |
323 | }, this.getDefaults());\r | |
324 | },\r | |
325 | \r | |
326 | privates: {\r | |
327 | checkForOutsideClick: function(e) {\r | |
328 | var floater = this.activeFloater;\r | |
329 | if (!floater.element.contains(e.target)) {\r | |
330 | this.unfloatAll();\r | |
331 | }\r | |
332 | },\r | |
333 | \r | |
334 | collapsingForExpand: false,\r | |
335 | \r | |
336 | /**\r | |
337 | * Create a new list item.\r | |
338 | * @param {Ext.data.TreeModel} node The node backing the item.\r | |
339 | * @param {Ext.list.AbstractTreeItem} parent The parent item.\r | |
340 | * @return {Ext.list.AbstractTreeItem} The list item.\r | |
341 | *\r | |
342 | * @private\r | |
343 | */\r | |
344 | createItem: function (node, parent) {\r | |
345 | var item = Ext.create(this.getItemConfig(node, parent)),\r | |
346 | toolEl;\r | |
347 | \r | |
348 | if (parent.isRootListItem) {\r | |
349 | toolEl = item.getToolElement();\r | |
350 | if (toolEl) {\r | |
351 | this.toolsElement.appendChild(toolEl);\r | |
352 | toolEl.dom.setAttribute('data-recordId', node.internalId);\r | |
353 | toolEl.isTool = true;\r | |
354 | }\r | |
355 | }\r | |
356 | \r | |
357 | return (this.itemMap[node.internalId] = item); // <== assignment\r | |
358 | },\r | |
359 | \r | |
360 | /**\r | |
361 | * Create a root item for this list.\r | |
362 | * @param {Ext.data.TreeModel} root The root node.\r | |
363 | *\r | |
364 | * @private\r | |
365 | */\r | |
366 | createRootItem: function (root) {\r | |
367 | var me = this,\r | |
368 | item;\r | |
369 | \r | |
370 | me.itemMap = {};\r | |
371 | me.rootItem = item = new Ext.list.RootTreeItem({\r | |
372 | indent: me.getIndent(),\r | |
373 | node: root,\r | |
374 | owner: me\r | |
375 | });\r | |
376 | \r | |
377 | me.element.appendChild(item.element);\r | |
378 | \r | |
379 | me.itemMap[root.internalId] = item;\r | |
380 | },\r | |
381 | \r | |
382 | floatItem: function(item, byHover) {\r | |
383 | var me = this,\r | |
384 | floater;\r | |
385 | \r | |
386 | if (item.getFloated()) {\r | |
387 | return;\r | |
388 | }\r | |
389 | \r | |
390 | me.unfloatAll();\r | |
391 | \r | |
392 | me.activeFloater = floater = item;\r | |
393 | me.floatedByHover = byHover;\r | |
394 | \r | |
395 | item.setFloated(true);\r | |
396 | \r | |
397 | if (byHover) {\r | |
398 | item.getToolElement().on('mouseleave', me.checkForMouseLeave, me);\r | |
399 | floater.element.on('mouseleave', me.checkForMouseLeave, me);\r | |
400 | } else {\r | |
401 | Ext.on('mousedown', me.checkForOutsideClick, me);\r | |
402 | }\r | |
403 | },\r | |
404 | \r | |
405 | /**\r | |
406 | * Handles when this element is clicked.\r | |
407 | * @param {Ext.event.Event} e The event.\r | |
408 | *\r | |
409 | * @private\r | |
410 | */\r | |
411 | onClick: function (e) {\r | |
412 | var item = e.getTarget('[data-recordId]'),\r | |
413 | id;\r | |
414 | \r | |
415 | if (item) {\r | |
416 | id = item.getAttribute('data-recordId');\r | |
417 | item = this.itemMap[id];\r | |
418 | if (item) {\r | |
419 | item.onClick(e);\r | |
420 | }\r | |
421 | }\r | |
422 | },\r | |
423 | \r | |
424 | onMouseEnter: function (e) {\r | |
425 | this.onMouseOver(e);\r | |
426 | },\r | |
427 | \r | |
428 | onMouseLeave: function () {\r | |
429 | this.setOverItem(null);\r | |
430 | },\r | |
431 | \r | |
432 | onMouseOver: function (e) {\r | |
433 | var comp = Ext.Component.fromElement(e.getTarget());\r | |
434 | \r | |
435 | this.setOverItem(comp && comp.isTreeListItem && comp);\r | |
436 | },\r | |
437 | \r | |
438 | checkForMouseLeave: function (e) {\r | |
439 | var floater = this.activeFloater,\r | |
440 | relatedTarget = e.getRelatedTarget();\r | |
441 | \r | |
442 | if (floater) {\r | |
443 | if (relatedTarget !== floater.getToolElement().dom && !floater.element.contains(relatedTarget)) {\r | |
444 | this.unfloatAll();\r | |
445 | }\r | |
446 | }\r | |
447 | },\r | |
448 | \r | |
449 | /**\r | |
450 | * Handles a node being appended to a parent.\r | |
451 | * @param {Ext.data.TreeModel} parentNode The parent node.\r | |
452 | * @param {Ext.data.TreeModel} node The appended node.\r | |
453 | *\r | |
454 | * @private\r | |
455 | */\r | |
456 | onNodeAppend: function (parentNode, node) {\r | |
457 | // If it's a root we'll handle it on rootchange\r | |
458 | if (parentNode) {\r | |
459 | var item = this.itemMap[parentNode.internalId];\r | |
460 | \r | |
461 | if (item) {\r | |
462 | item.nodeInsert(node, null);\r | |
463 | }\r | |
464 | }\r | |
465 | },\r | |
466 | \r | |
467 | /**\r | |
468 | * Handles when a node collapses.\r | |
469 | * @param {Ext.data.TreeModel} node The node.\r | |
470 | *\r | |
471 | * @private\r | |
472 | */\r | |
473 | onNodeCollapse: function (node) {\r | |
474 | var item = this.itemMap[node.internalId];\r | |
475 | \r | |
476 | if (item) {\r | |
477 | item.nodeCollapse(node, this.collapsingForExpand);\r | |
478 | }\r | |
479 | },\r | |
480 | \r | |
481 | /**\r | |
482 | * Handles when a node expands.\r | |
483 | * @param {Ext.data.TreeModel} node The node.\r | |
484 | *\r | |
485 | * @private\r | |
486 | */\r | |
487 | onNodeExpand: function (node) {\r | |
488 | var me = this,\r | |
489 | item = me.itemMap[node.internalId],\r | |
490 | childNodes, len, i, parentNode, child;\r | |
491 | \r | |
492 | if (item) {\r | |
493 | if (!item.isRootItem && me.getSingleExpand()) {\r | |
494 | me.collapsingForExpand = true;\r | |
495 | parentNode = (item.getParentItem() || me.rootItem).getNode();\r | |
496 | childNodes = parentNode.childNodes;\r | |
497 | for (i = 0, len = childNodes.length; i < len; ++i) {\r | |
498 | child = childNodes[i];\r | |
499 | if (child !== node) {\r | |
500 | child.collapse();\r | |
501 | }\r | |
502 | }\r | |
503 | me.collapsing = false;\r | |
504 | }\r | |
505 | \r | |
506 | item.nodeExpand(node);\r | |
507 | }\r | |
508 | },\r | |
509 | \r | |
510 | /**\r | |
511 | * Handles a node being inserted into a parent.\r | |
512 | * @param {Ext.data.TreeModel} parentNode The parent node.\r | |
513 | * @param {Ext.data.TreeModel} node The inserted node.\r | |
514 | * @param {Ext.data.TreeModel} refNode The node this was inserted before.\r | |
515 | *\r | |
516 | * @private\r | |
517 | */\r | |
518 | onNodeInsert: function (parentNode, node, refNode) {\r | |
519 | var item = this.itemMap[parentNode.internalId];\r | |
520 | \r | |
521 | if (item) {\r | |
522 | item.nodeInsert(node, refNode);\r | |
523 | }\r | |
524 | },\r | |
525 | \r | |
526 | /**\r | |
527 | * Handles a node being removed from a parent.\r | |
528 | * @param {Ext.data.TreeModel} parentNode The parent node.\r | |
529 | * @param {Ext.data.TreeModel} node The removed node.\r | |
530 | * @param {Boolean} isMove `true` if this node is moving inside the tree.\r | |
531 | *\r | |
532 | * @private\r | |
533 | */\r | |
534 | onNodeRemove: function (parentNode, node, isMove) {\r | |
535 | // If it's a move we don't need to do anything, we won't process it\r | |
536 | // as a removal, the addition will handle it all.\r | |
537 | // Also if the node being removed is the root we'll handle it in rootchange\r | |
538 | if (parentNode && !isMove) {\r | |
539 | var item = this.itemMap[parentNode.internalId];\r | |
540 | \r | |
541 | if (item) {\r | |
542 | item.nodeRemove(node);\r | |
543 | }\r | |
544 | }\r | |
545 | }, \r | |
546 | \r | |
547 | /**\r | |
548 | * Handles when a node updates.\r | |
549 | * @param {Ext.data.TreeStore} store The store.\r | |
550 | * @param {Ext.data.TreeModel} node The node.\r | |
551 | * @param {String} type The update type.\r | |
552 | * @param {String[]} modifiedFieldNames The modified field names, if known.\r | |
553 | *\r | |
554 | * @private\r | |
555 | */\r | |
556 | onNodeUpdate: function (store, node, type, modifiedFieldNames) {\r | |
557 | var item = this.itemMap[node.internalId];\r | |
558 | \r | |
559 | if (item) {\r | |
560 | item.nodeUpdate(node, modifiedFieldNames);\r | |
561 | }\r | |
562 | },\r | |
563 | \r | |
564 | /**\r | |
565 | * Handles when the root node in the tree changes.\r | |
566 | * @param {Ext.data.TreeModel} root The root.\r | |
567 | *\r | |
568 | * @private\r | |
569 | */\r | |
570 | onRootChange: function (root) {\r | |
571 | this.removeRoot();\r | |
572 | \r | |
573 | if (root) {\r | |
574 | this.createRootItem(root);\r | |
575 | }\r | |
576 | \r | |
577 | this.updateLayout();\r | |
578 | },\r | |
579 | \r | |
580 | /**\r | |
581 | * Removes a list item.\r | |
582 | * @param {Ext.data.TreeModel} node The node backing the item.\r | |
583 | *\r | |
584 | * @private\r | |
585 | */\r | |
586 | removeItem: function (node) {\r | |
587 | var map = this.itemMap;\r | |
588 | \r | |
589 | if (map) {\r | |
590 | delete map[node.internalId];\r | |
591 | }\r | |
592 | },\r | |
593 | \r | |
594 | removeRoot: function () {\r | |
595 | var me = this,\r | |
596 | rootItem = me.rootItem;\r | |
597 | \r | |
598 | if (rootItem) {\r | |
599 | me.element.removeChild(rootItem.element);\r | |
600 | me.rootItem = me.itemMap = Ext.destroy(rootItem);\r | |
601 | }\r | |
602 | },\r | |
603 | \r | |
604 | /**\r | |
605 | * Handles when the toolstrip has a click.\r | |
606 | * @param {Ext.event.Event} e The event.\r | |
607 | *\r | |
608 | * @private\r | |
609 | */\r | |
610 | onToolStripClick: function(e) {\r | |
611 | var item = e.getTarget('[data-recordId]'),\r | |
612 | id;\r | |
613 | \r | |
614 | if (item) {\r | |
615 | id = item.getAttribute('data-recordId');\r | |
616 | item = this.itemMap[id];\r | |
617 | if (item) {\r | |
618 | if (item === this.activeFloater) {\r | |
619 | this.unfloatAll();\r | |
620 | } else {\r | |
621 | this.floatItem(item, false);\r | |
622 | }\r | |
623 | }\r | |
624 | }\r | |
625 | },\r | |
626 | \r | |
627 | /**\r | |
628 | * Handles when the toolstrip has a mouseover.\r | |
629 | * @param {Ext.event.Event} e The event.\r | |
630 | *\r | |
631 | * @private\r | |
632 | */\r | |
633 | onToolStripMouseOver: function(e) {\r | |
634 | var item = e.getTarget('[data-recordId]'),\r | |
635 | id;\r | |
636 | \r | |
637 | if (item) {\r | |
638 | id = item.getAttribute('data-recordId');\r | |
639 | item = this.itemMap[id];\r | |
640 | if (item) {\r | |
641 | this.floatItem(item, true);\r | |
642 | }\r | |
643 | }\r | |
644 | },\r | |
645 | \r | |
646 | syncIconSize: function() {\r | |
647 | var me = this,\r | |
648 | size = me.iconSize ||\r | |
649 | (me.iconSize = parseInt(me.element.getStyle('background-position'), 10));\r | |
650 | \r | |
651 | me.setIconSize(size);\r | |
652 | },\r | |
653 | \r | |
654 | unfloatAll: function () {\r | |
655 | var me = this,\r | |
656 | floater = me.activeFloater;\r | |
657 | \r | |
658 | if (floater) {\r | |
659 | floater.setFloated(false);\r | |
660 | me.activeFloater = null;\r | |
661 | \r | |
662 | if (me.floatedByHover) {\r | |
663 | floater.element.un('mouseleave', me.checkForMouseLeave, me);\r | |
664 | } else {\r | |
665 | Ext.un('mousedown', me.checkForOutsideClick, me);\r | |
666 | }\r | |
667 | }\r | |
668 | },\r | |
669 | \r | |
670 | defaultIconSize: 22,\r | |
671 | \r | |
672 | updateIconSize: function (value) {\r | |
673 | this.setIndent(value || this.defaultIconSize);\r | |
674 | },\r | |
675 | \r | |
676 | updateIndent: function (value) {\r | |
677 | var rootItem = this.rootItem;\r | |
678 | \r | |
679 | if (rootItem) {\r | |
680 | rootItem.setIndent(value);\r | |
681 | }\r | |
682 | }\r | |
683 | }\r | |
684 | });\r |