X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/selection/CellModel.js?ds=sidebyside diff --git a/src/selection/CellModel.js b/src/selection/CellModel.js new file mode 100644 index 00000000..be4d00f3 --- /dev/null +++ b/src/selection/CellModel.js @@ -0,0 +1,221 @@ +/** + * @class Ext.selection.CellModel + * @extends Ext.selection.Model + * @private + */ +Ext.define('Ext.selection.CellModel', { + extend: 'Ext.selection.Model', + alias: 'selection.cellmodel', + requires: ['Ext.util.KeyNav'], + + /** + * @cfg {Boolean} enableKeyNav + * Turns on/off keyboard navigation within the grid. Defaults to true. + */ + enableKeyNav: true, + + /** + * @cfg {Boolean} preventWrap + * Set this configuration to true to prevent wrapping around of selection as + * a user navigates to the first or last column. Defaults to false. + */ + preventWrap: false, + + constructor: function(){ + this.addEvents( + /** + * @event deselect + * Fired after a cell is deselected + * @param {Ext.selection.CellModel} this + * @param {Ext.data.Model} record The record of the deselected cell + * @param {Number} row The row index deselected + * @param {Number} column The column index deselected + */ + 'deselect', + + /** + * @event select + * Fired after a cell is selected + * @param {Ext.selection.CellModel} this + * @param {Ext.data.Model} record The record of the selected cell + * @param {Number} row The row index selected + * @param {Number} column The column index selected + */ + 'select' + ); + this.callParent(arguments); + }, + + bindComponent: function(view) { + var me = this; + me.primaryView = view; + me.views = me.views || []; + me.views.push(view); + me.bind(view.getStore(), true); + + view.on({ + cellmousedown: me.onMouseDown, + refresh: me.onViewRefresh, + scope: me + }); + + if (me.enableKeyNav) { + me.initKeyNav(view); + } + }, + + initKeyNav: function(view) { + var me = this; + + if (!view.rendered) { + view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true}); + return; + } + + view.el.set({ + tabIndex: -1 + }); + + // view.el has tabIndex -1 to allow for + // keyboard events to be passed to it. + me.keyNav = Ext.create('Ext.util.KeyNav', view.el, { + up: me.onKeyUp, + down: me.onKeyDown, + right: me.onKeyRight, + left: me.onKeyLeft, + tab: me.onKeyTab, + scope: me + }); + }, + + getHeaderCt: function() { + return this.primaryView.headerCt; + }, + + onKeyUp: function(e, t) { + this.move('up', e); + }, + + onKeyDown: function(e, t) { + this.move('down', e); + }, + + onKeyLeft: function(e, t) { + this.move('left', e); + }, + + onKeyRight: function(e, t) { + this.move('right', e); + }, + + move: function(dir, e) { + var me = this, + pos = me.primaryView.walkCells(me.getCurrentPosition(), dir, e, me.preventWrap); + if (pos) { + me.setCurrentPosition(pos); + } + return pos; + }, + + /** + * Returns the current position in the format {row: row, column: column} + */ + getCurrentPosition: function() { + return this.position; + }, + + /** + * Sets the current position + * @param {Object} position The position to set. + */ + setCurrentPosition: function(pos) { + var me = this; + + if (me.position) { + me.onCellDeselect(me.position); + } + if (pos) { + me.onCellSelect(pos); + } + me.position = pos; + }, + + /** + * Set the current position based on where the user clicks. + * @private + */ + onMouseDown: function(view, cell, cellIndex, record, row, rowIndex, e) { + this.setCurrentPosition({ + row: rowIndex, + column: cellIndex + }); + }, + + // notify the view that the cell has been selected to update the ui + // appropriately and bring the cell into focus + onCellSelect: function(position) { + var me = this, + store = me.view.getStore(), + record = store.getAt(position.row); + + me.doSelect(record); + me.primaryView.onCellSelect(position); + // TODO: Remove temporary cellFocus call here. + me.primaryView.onCellFocus(position); + me.fireEvent('select', me, record, position.row, position.column); + }, + + // notify view that the cell has been deselected to update the ui + // appropriately + onCellDeselect: function(position) { + var me = this, + store = me.view.getStore(), + record = store.getAt(position.row); + + me.doDeselect(record); + me.primaryView.onCellDeselect(position); + me.fireEvent('deselect', me, record, position.row, position.column); + }, + + onKeyTab: function(e, t) { + var me = this, + direction = e.shiftKey ? 'left' : 'right', + editingPlugin = me.view.editingPlugin, + position = me.move(direction, e); + + if (editingPlugin && position && me.wasEditing) { + editingPlugin.startEditByPosition(position); + } + delete me.wasEditing; + }, + + onEditorTab: function(editingPlugin, e) { + var me = this, + direction = e.shiftKey ? 'left' : 'right', + position = me.move(direction, e); + + if (position) { + editingPlugin.startEditByPosition(position); + me.wasEditing = true; + } + }, + + refresh: function() { + var pos = this.getCurrentPosition(); + if (pos) { + this.onCellSelect(pos); + } + }, + + onViewRefresh: function() { + var pos = this.getCurrentPosition(); + if (pos) { + this.onCellDeselect(pos); + this.setCurrentPosition(null); + } + }, + + selectByPosition: function(position) { + this.setCurrentPosition(position); + } +}); \ No newline at end of file