/** * @private */Ext.define('Ext.util.PositionMap', { config: { minimumHeight: null }, constructor: function(config) { var me = this; me.map = []; me.adjustments = {}; me.offset = 0; me.initConfig(config); }, populate: function(count, offset) { var me = this, map = me.map = me.map || [], minimumHeight = me.getMinimumHeight(), i, previousIndex, ln; me.adjustments = { indices: [], heights: {} }; if (minimumHeight === null) { return; } offset = offset || 0; // We add 1 item to the count so that we can get the height of the bottom item count++; map.length = count; map[0] = 0; for (i = offset + 1, ln = count - 1; i <= ln; i++) { previousIndex = i - 1; map[i] = map[previousIndex] + minimumHeight; } me.offset = 0; for (i = 1, ln = count - 1; i <= ln; i++) { previousIndex = i - 1; me.offset += map[i] - map[previousIndex] - minimumHeight; } }, setItemHeight: function(index, height) { height = Math.max(height, this.getMinimumHeight()); if (height !== this.getItemHeight(index)) { var adjustments = this.adjustments; adjustments.indices.push(parseInt(index, 10)); adjustments.heights[index] = height; } }, update: function() { var me = this, adjustments = me.adjustments, indices = adjustments.indices, heights = adjustments.heights, map = me.map, ln = indices && indices.length, minimumHeight = me.getMinimumHeight(), difference = 0, i, j, height, index, nextIndex, currentHeight; if (!ln) { return false; } Ext.Array.sort(indices, function(a, b) { return a - b; }); for (i = 0; i < ln; i++) { index = indices[i]; nextIndex = indices[i + 1] || map.length - 1; currentHeight = (map[index + 1] !== undefined) ? (map[index + 1] - map[index] + difference) : minimumHeight; height = heights[index]; difference += height - currentHeight; for (j = index + 1; j <= nextIndex; j++) { map[j] += difference; } } me.offset += difference; me.adjustments = { indices: [], heights: {} }; return true; }, getItemHeight: function(index) { return this.map[index + 1] - this.map[index]; }, getTotalHeight: function() { return ((this.map.length - 1) * this.getMinimumHeight()) + this.offset; }, findIndex: function(pos) { return this.map.length ? this.binarySearch(this.map, pos) : 0; }, binarySearch: function(sorted, value) { var start = 0, end = sorted.length; if (value < sorted[0]) { return 0; } if (value > sorted[end - 1]) { return end - 1; } while (start + 1 < end) { var mid = (start + end) >> 1, val = sorted[mid]; if (val == value) { return mid; } else if (val < value) { start = mid; } else { end = mid; } } return start; }});