/** * This class is used for {@link Ext.grid.Grid grid} cells that contain a child * {@link Ext.Component} or {@link Ext.Widget}. This cell type is typically used by * specifying {@link Ext.grid.column.Widget} column type. * * {@link Ext.grid.Row Rows} create cells based on the {@link Ext.grid.column.Column#cell} * config. Application code would rarely create cells directly. */Ext.define('Ext.grid.cell.Widget', { extend: 'Ext.grid.cell.Base', xtype: 'widgetcell', isWidgetCell: true, config: { /** * @cfg {Boolean} forceWidth * `true` to measure the available width of the cell and set that * width on the underlying widget. If `false`, the widget width will auto * size. */ forceWidth: false, /** * @cfg {Object} widget (required) * The config object for a {@link Ext.Component} or {@link Ext.Widget}. * * @cfg {String} widget.xtype (required) The type of component or widget to create. */ widget: null }, /** * @cfg align * @inheritdoc */ align: 'center', /** * @property classCls * @inheritdoc */ classCls: Ext.baseCSSPrefix + 'widgetcell', /** * @cfg selectable * @inheritdoc */ selectable: false, getRefItems: function(deep) { var result = [], widget = this.getWidget(); if (widget) { result.push(widget); if (deep && widget.getRefItems) { result.push.apply(result, widget.getRefItems(deep)); } } return result; }, setValue: function(value) { // If it's an object, its internals may have changed, but the simple // equality test of the config's setter will reject it, so // go directly to the updater. if (value && typeof value === 'object') { // we still need to update _value otherwise the Base cell refresh() will ignore us. this._value = value; this.updateValue(value); } else { if (value === undefined) { // The config system doesn't do well w/setFoo(undefined) value = null; } this.callParent([value]); } return this; }, updateValue: function(value) { var me = this, widget = me.getWidget(), // this may create the widget & set defaultBindCfg defaultBindCfg = me.defaultBindCfg; if (defaultBindCfg && widget) { widget[defaultBindCfg.names.set](value); } }, applyWidget: function(widget) { var me = this; if (widget) { widget = Ext.apply({ ownerCmp: me }, widget); widget = Ext.create(widget); } return widget; }, updateWidget: function(widget, oldWidget) { var me = this, defaultBindCfg; if (oldWidget) { me.widgetChangeListener = Ext.destroy(me.widgetChangeListener); oldWidget.measurer = null; oldWidget.destroy(); } if (widget) { // in FF/Edge the cell body should only contain the widget canvas and nothing else // otherwise the widget is not visible me.bodyElement.setHtml(''); me.bodyElement.appendChild(widget.element); if (me.getForceWidth()) { me.setWidgetWidth(me.getWidth()); } defaultBindCfg = widget.defaultBindProperty; defaultBindCfg = widget.self.getConfigurator().configs[defaultBindCfg]; me.defaultBindCfg = defaultBindCfg || null; //<debug> if (!defaultBindCfg || !widget[defaultBindCfg.names.get] || !widget[defaultBindCfg.names.set]) { Ext.raise('Invalid config "' + widget.defaultBindProperty + '" for ' + widget.$className); } //</debug> if (me.dataIndex) { me.widgetChangeListener = widget.on({ change: 'onWidgetChange', scope: me }); } } }, onWidgetChange: function(widget) { var me = this, record, defaultBindCfg, dataIndex, value; if (!me.refreshContext) { record = me.getRecord(); defaultBindCfg = me.defaultBindCfg; dataIndex = me.dataIndex; if (defaultBindCfg) { value = widget[defaultBindCfg.names.get](); me.setValue(value); if (record && !record.isSummaryRecord && dataIndex) { record.set(dataIndex, value); } } } }, updateWidth: function(width, oldWidth) { this.callParent([width, oldWidth]); if (this.getForceWidth()) { this.setWidgetWidth(width); } }, onRender: function() { var me = this; if (me.getForceWidth()) { me.setWidgetWidth(me.getWidth()); } }, doDestroy: function() { this.setWidget(null); this.callParent(); }, privates: { setWidgetWidth: function(width) { var me = this, el = me.bodyElement, widget, column, leftPad, rightPad; if (!me.rendered) { return; } widget = me.getWidget(); if (widget) { column = me.getColumn(); leftPad = parseInt(column.getCachedStyle(el, 'padding-left'), 10) || 0; rightPad = parseInt(column.getCachedStyle(el, 'padding-right'), 10) || 0; // Give the widget a reference to ourself to allow it to do any extra measuring widget.measurer = column; widget.setWidth(width - leftPad - rightPad); } } }});