/** * This class is used internally to provide a single interface when using * a locking grid. Internally, the locking grid creates two separate grids, * so this class is used to map calls appropriately. * @private */ Ext.define('Ext.grid.locking.View', { alternateClassName: 'Ext.grid.LockingView', mixins: { observable: 'Ext.util.Observable' }, /** * @property {Boolean} isLockingView * `true` in this class to identify an object as an instantiated LockingView, or subclass thereof. */ isLockingView: true, eventRelayRe: /^(beforeitem|beforecontainer|item|container|cell|refresh)/, constructor: function(config){ var me = this, eventNames = [], eventRe = me.eventRelayRe, locked = config.locked.getView(), normal = config.normal.getView(), events, event; Ext.apply(me, { lockedView: locked, normalView: normal, lockedGrid: config.locked, normalGrid: config.normal, panel: config.panel }); me.mixins.observable.constructor.call(me, config); // relay events events = locked.events; for (event in events) { if (events.hasOwnProperty(event) && eventRe.test(event)) { eventNames.push(event); } } me.relayEvents(locked, eventNames); me.relayEvents(normal, eventNames); normal.on({ scope: me, itemmouseleave: me.onItemMouseLeave, itemmouseenter: me.onItemMouseEnter }); locked.on({ scope: me, itemmouseleave: me.onItemMouseLeave, itemmouseenter: me.onItemMouseEnter }); me.panel.on({ render: me.onPanelRender, scope: me }); }, onPanelRender: function() { var me = this, mask = me.loadMask, cfg = { target: me.panel, msg: me.loadingText, msgCls: me.loadingCls, useMsg: me.loadingUseMsg, store: me.panel.store }; // Because this is used as a View, it should have an el. Use the owning Lockable's body. // It also has to fire a render event so that Editing plugins can attach listeners me.el = me.panel.body; me.fireEvent('render', me); if (mask) { // either a config object if (Ext.isObject(mask)) { cfg = Ext.apply(cfg, mask); } // Attach the LoadMask to a *Component* so that it can be sensitive to resizing during long loads. // If this DataView is floating, then mask this DataView. // Otherwise, mask its owning Container (or this, if there *is* no owning Container). // LoadMask captures the element upon render. me.loadMask = new Ext.LoadMask(cfg); } }, getGridColumns: function() { var cols = this.lockedGrid.headerCt.getVisibleGridColumns(); return cols.concat(this.normalGrid.headerCt.getVisibleGridColumns()); }, getEl: function(column){ return this.getViewForColumn(column).getEl(); }, getViewForColumn: function(column) { var view = this.lockedView, inLocked; view.headerCt.cascade(function(col){ if (col === column) { inLocked = true; return false; } }); return inLocked ? view : this.normalView; }, onItemMouseEnter: function(view, record){ var me = this, locked = me.lockedView, other = me.normalView, item; if (view.trackOver) { if (view !== locked) { other = locked; } item = other.getNode(record, false); other.highlightItem(item); } }, onItemMouseLeave: function(view, record){ var me = this, locked = me.lockedView, other = me.normalView; if (view.trackOver) { if (view !== locked) { other = locked; } other.clearHighlight(); } }, relayFn: function(name, args){ args = args || []; var view = this.lockedView; view[name].apply(view, args); view = this.normalView; view[name].apply(view, args); }, getSelectionModel: function(){ return this.panel.getSelectionModel(); }, getStore: function(){ return this.panel.store; }, getNode: function(nodeInfo, dataRow) { // default to the normal view return this.normalView.getNode(nodeInfo, dataRow); }, getCell: function(record, column) { var view = this.getViewForColumn(column), row = view.getNode(record, true); return Ext.fly(row).down(column.getCellSelector()); }, indexOf: function(record) { var result = this.lockedView.indexOf(record); if (!result) { result = this.normalView.indexOf(record); } return result; }, focus: function() { var p = this.getSelectionModel().getCurrentPosition(), v = p ? p.view : this.normalView; v.focus(); }, focusRow: function(row) { this.normalView.focusRow(row); }, focusCell: function(position) { position.view.focusCell(position); }, isVisible: function(deep) { return this.panel.isVisible(deep); }, getRecord: function(node) { var result = this.lockedView.getRecord(node); if (!result) { result = this.normalView.getRecord(node); } return result; }, scrollBy: function(){ var normal = this.normalView; normal.scrollBy.apply(normal, arguments); }, addElListener: function(eventName, fn, scope){ this.relayFn('addElListener', arguments); }, refreshNode: function(){ this.relayFn('refreshNode', arguments); }, refresh: function(){ this.relayFn('refresh', arguments); }, bindStore: function(){ this.relayFn('bindStore', arguments); }, addRowCls: function(){ this.relayFn('addRowCls', arguments); }, removeRowCls: function(){ this.relayFn('removeRowCls', arguments); }, destroy: function(){ var me = this, mask = me.loadMask; // Typically the mask unbinding is handled by the view, but // we aren't a normal view, so clear it out here me.clearListeners(); if (mask && mask.bindStore) { mask.bindStore(null); } } });