(function() {
/**
* @class Ext.ux.grid.VarHeaders
*
* Plugin for GridPanel that enables configuration of three different headers which are shown depending on the available column width:
* longText, text, shortText.
*
* Plugin alias is 'varheaders' (use "plugins: 'varheaders'" in GridPanel config).
*
* @author Stephen Friedrich
* @author Fabian Urban
*
* @copyright (c) 2011 Fortis IT Services GmbH
* @license Ext.ux.grid.VarHeaders is released under the
* Apache License, Version 2.0.
*
*/
Ext.define('Ext.ux.grid.VarHeaders', {
alias: 'plugin.varheaders',
/**
* Called by plug-in system to initialize the plugin for a specific grid panel
*/
init: function(grid) {
grid.on('afterrender',
function(){
Ext.Array.forEach(grid.query('headercontainer'), this.initColumn, this);
},
this);
},
initColumn: function(column) {
this.addListeners(column);
this.updateColumnTextIfNeeded(column);
},
/**
* Attach listeners to a column for resize (update text), sort change (required width changes due to sort icon, so text
* might need to be updated, too) and add (new sub columns that also need to be listened to).
*/
addListeners: function(headerCt) {
if (!headerCt.varHeadersListeners) {
headerCt.on('add', this.handleColumnAdded, this);
headerCt.on('columnresize', this.handleColumnHeaderResize, this);
headerCt.on('sortchange', this.handleColumnSortChange, this);
// Backup standard text value (headerCt.text changes when another text is set after resizing the column)
headerCt.normalText = headerCt.text;
// Set a flag, so that listeners aren't added twice (when columns are removed/added)
headerCt.varHeadersListeners = true;
}
return true;
},
handleColumnAdded: function(headerContainer, component, index) {
this.initColumn(component);
},
handleColumnHeaderResize: function(headerContainer, column, width) {
this.updateColumnTextIfNeeded(column);
},
handleColumnSortChange: function(headerContainer, column, direction) {
this.updateColumnTextIfNeeded(column);
},
/**
* Update the column's text to one of shortText, normalText (contains saved original text) and longText depending
* on current column width.
*/
updateColumnTextIfNeeded: function(column) {
var textElement = column.textEl; // textEL is set via renderSelector in Ext.grid.column.Column)
if (!textElement) {
return;
}
var availableWidth = column.getWidth();
var columnEl = column.el;
var el = textElement;
while(true) {
availableWidth -= (el.getPadding('lr') + el.getMargin('lr') + el.getBorderWidth('lr'));
if(el == columnEl) {
break;
}
el = el.parent();
}
var newText = this.findMatchingText(availableWidth, textElement,
[column.longText, column.normalText, column.shortText]);
if (newText != column.text) {
column.setText(newText);
}
},
/**
* Returns the first text from "texts" array that is at most "availableWidth" wide when rendered with same CSS as
* "element". If no text matches the last non-null entry of "texts" is returned.
* null entries in the "texts" array are skipped.
*/
findMatchingText: function(availableWidth, element, texts) {
var newText = null;
for(var i = 0, length = texts.length; i < length; ++i) {
var text = texts[i];
if(!text) {
continue;
}
newText = text;
var width = Ext.util.TextMetrics.measure(element, text).width;
if(width <= availableWidth) {
break;
}
}
return newText;
}
});
})();