+ getFloatingButtons: function() {
+ var me = this,
+ cssPrefix = Ext.baseCSSPrefix,
+ btnsCss = cssPrefix + 'grid-row-editor-buttons',
+ plugin = me.editingPlugin,
+ btns;
+
+ if (!me.floatingButtons) {
+ btns = me.floatingButtons = Ext.create('Ext.Container', {
+ renderTpl: [
+ '<div class="{baseCls}-ml"></div>',
+ '<div class="{baseCls}-mr"></div>',
+ '<div class="{baseCls}-bl"></div>',
+ '<div class="{baseCls}-br"></div>',
+ '<div class="{baseCls}-bc"></div>'
+ ],
+
+ renderTo: me.el,
+ baseCls: btnsCss,
+ layout: {
+ type: 'hbox',
+ align: 'middle'
+ },
+ defaults: {
+ margins: '0 1 0 1'
+ },
+ items: [{
+ itemId: 'update',
+ flex: 1,
+ xtype: 'button',
+ handler: plugin.completeEdit,
+ scope: plugin,
+ text: me.saveBtnText,
+ disabled: !me.isValid
+ }, {
+ flex: 1,
+ xtype: 'button',
+ handler: plugin.cancelEdit,
+ scope: plugin,
+ text: me.cancelBtnText
+ }]
+ });
+
+ // Prevent from bubbling click events to the grid view
+ me.mon(btns.el, {
+ // BrowserBug: Opera 11.01
+ // causes the view to scroll when a button is focused from mousedown
+ mousedown: Ext.emptyFn,
+ click: Ext.emptyFn,
+ stopEvent: true
+ });
+ }
+ return me.floatingButtons;
+ },
+
+ reposition: function(animateConfig) {
+ var me = this,
+ context = me.context,
+ row = context && Ext.get(context.row),
+ btns = me.getFloatingButtons(),
+ btnEl = btns.el,
+ grid = me.editingPlugin.grid,
+ viewEl = grid.view.el,
+ scroller = grid.verticalScroller,
+
+ // always get data from ColumnModel as its what drives
+ // the GridView's sizing
+ mainBodyWidth = grid.headerCt.getFullWidth(),
+ scrollerWidth = grid.getWidth(),
+
+ // use the minimum as the columns may not fill up the entire grid
+ // width
+ width = Math.min(mainBodyWidth, scrollerWidth),
+ scrollLeft = grid.view.el.dom.scrollLeft,
+ btnWidth = btns.getWidth(),
+ left = (width - btnWidth) / 2 + scrollLeft,
+ y, rowH, newHeight,
+
+ invalidateScroller = function() {
+ if (scroller) {
+ scroller.invalidate();
+ btnEl.scrollIntoView(viewEl, false);
+ }
+ if (animateConfig && animateConfig.callback) {
+ animateConfig.callback.call(animateConfig.scope || me);
+ }
+ };
+
+ // need to set both top/left
+ if (row && Ext.isElement(row.dom)) {
+ // Bring our row into view if necessary, so a row editor that's already
+ // visible and animated to the row will appear smooth
+ row.scrollIntoView(viewEl, false);
+
+ // Get the y position of the row relative to its top-most static parent.
+ // offsetTop will be relative to the table, and is incorrect
+ // when mixed with certain grid features (e.g., grouping).
+ y = row.getXY()[1] - 5;
+ rowH = row.getHeight();
+ newHeight = rowH + 10;
+
+ // IE doesn't set the height quite right.
+ // This isn't a border-box issue, it even happens
+ // in IE8 and IE7 quirks.
+ // TODO: Test in IE9!
+ if (Ext.isIE) {
+ newHeight += 2;
+ }
+
+ // Set editor height to match the row height
+ if (me.getHeight() != newHeight) {
+ me.setHeight(newHeight);
+ me.el.setLeft(0);
+ }
+
+ if (animateConfig) {
+ var animObj = {
+ to: {
+ y: y
+ },
+ duration: animateConfig.duration || 125,
+ listeners: {
+ afteranimate: function() {
+ invalidateScroller();
+ y = row.getXY()[1] - 5;
+ me.el.setY(y);
+ }
+ }
+ };
+ me.animate(animObj);
+ } else {
+ me.el.setY(y);
+ invalidateScroller();
+ }
+ }
+ if (me.getWidth() != mainBodyWidth) {
+ me.setWidth(mainBodyWidth);