/** * Provides indentation and folder structure markup for a Tree taking into account * depth and position within the tree hierarchy. */Ext.define('Ext.tree.Column', { extend: 'Ext.grid.column.Column', alias: 'widget.treecolumn', tdCls: Ext.baseCSSPrefix + 'grid-cell-treecolumn', autoLock: true, lockable: false, draggable: false, hideable: false, iconCls: Ext.baseCSSPrefix + 'tree-icon', checkboxCls: Ext.baseCSSPrefix + 'tree-checkbox', elbowCls: Ext.baseCSSPrefix + 'tree-elbow', expanderCls: Ext.baseCSSPrefix + 'tree-expander', textCls: Ext.baseCSSPrefix + 'tree-node-text', innerCls: Ext.baseCSSPrefix + 'grid-cell-inner-treecolumn', isTreeColumn: true, cellTpl: [ '<tpl for="lines">', '<img src="{parent.blankUrl}" class="{parent.childCls} {parent.elbowCls}-img ', '{parent.elbowCls}-<tpl if=".">line<tpl else>empty</tpl>" role="presentation"/>', '</tpl>', '<img src="{blankUrl}" class="{childCls} {elbowCls}-img {elbowCls}', '<tpl if="isLast">-end</tpl><tpl if="expandable">-plus {expanderCls}</tpl>" role="presentation"/>', '<tpl if="checked !== null">', '<input type="button" {ariaCellCheckboxAttr}', ' class="{childCls} {checkboxCls}<tpl if="checked"> {checkboxCls}-checked</tpl>"/>', '</tpl>', '<img src="{blankUrl}" role="presentation" class="{childCls} {baseIconCls} ', '{baseIconCls}-<tpl if="leaf">leaf<tpl else>parent</tpl> {iconCls}"', '<tpl if="icon">style="background-image:url({icon})"</tpl>/>', '<tpl if="href">', '<a href="{href}" role="link" target="{hrefTarget}" class="{textCls} {childCls}">{value}</a>', '<tpl else>', '<span class="{textCls} {childCls}">{value}</span>', '</tpl>' ], // fields that will trigger a change in the ui that aren't likely to be bound to a column uiFields: { checked: 1, icon: 1, iconCls: 1 }, // fields that requires a full row render rowFields: { expanded: 1, loaded: 1, expandable: 1, leaf: 1, loading: 1, qtip: 1, qtitle: 1, cls: 1 }, initComponent: function() { var me = this; me.rendererScope = me.scope; me.setupRenderer(); // This always uses its own renderer. // Any custom renderer is used as an inner renderer to produce the text node of a tree cell. me.innerRenderer = me.renderer; me.renderer = me.treeRenderer; me.callParent(); me.scope = me; me.hasCustomRenderer = me.innerRenderer && me.innerRenderer.length > 1; }, treeRenderer: function(value, metaData, record, rowIdx, colIdx, store, view){ var me = this, cls = record.get('cls'), rendererData; // The initial render will inject the cls into the TD's attributes. // If cls is ever *changed*, then the full rendering path is followed. if (metaData && cls) { metaData.tdCls += ' ' + cls; } rendererData = me.initTemplateRendererData(value, metaData, record, rowIdx, colIdx, store, view); return me.getTpl('cellTpl').apply(rendererData); }, initTemplateRendererData: function(value, metaData, record, rowIdx, colIdx, store, view) { var me = this, innerRenderer = me.innerRenderer, data = record.data, parent = record.parentNode, rootVisible = view.rootVisible, lines = [], parentData; while (parent && (rootVisible || parent.data.depth > 0)) { parentData = parent.data; lines[rootVisible ? parentData.depth : parentData.depth - 1] = parent.isLastVisible() ? 0 : 1; parent = parent.parentNode; } return { record: record, baseIconCls: me.iconCls, iconCls: data.iconCls, icon: data.icon, checkboxCls: me.checkboxCls, checked: data.checked, elbowCls: me.elbowCls, expanderCls: me.expanderCls, textCls: me.textCls, leaf: data.leaf, expandable: record.isExpandable(), isLast: record.isLastVisible(), blankUrl: Ext.BLANK_IMAGE_URL, href: data.href, hrefTarget: data.hrefTarget, lines: lines, metaData: metaData, // subclasses or overrides can implement a getChildCls() method, which can // return an extra class to add to all of the cell's child elements (icon, // expander, elbow, checkbox). This is used by the rtl override to add the // "x-rtl" class to these elements. childCls: me.getChildCls ? me.getChildCls() + ' ' : '', value: innerRenderer ? innerRenderer.apply(me.rendererScope, arguments) : value }; }, shouldUpdateCell: function(record, changedFieldNames) { // For the TreeColumn, if any of the known tree column UI affecting fields are updated // the cell should be updated in whatever way. // 1 if a custom renderer (not our default tree cell renderer), else 2. var me = this, i = 0, len, field; if (changedFieldNames) { len = changedFieldNames.length; for (; i < len; ++i) { field = changedFieldNames[i]; // Check for fields which always require a full row update. if (me.rowFields[field]) { return 1; } // Check for fields which require this column to be updated. // The TreeColumn's treeRenderer is not a custom renderer. if (me.uiFields[field]) { return 2; } } } return me.callParent([record, changedFieldNames]); }});