Skip to content

Refactor(styleComputations): fixes rendercontainer rendering problems #3145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions misc/api/design-rendering-cycle.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ appears to be to accomodate filters.

The style builders include:

- `GridRenderContainer`, which appears to currently apply no styles
- `uiGrid.updateColumnWidths`, which calculates column widths based on the defined settings, including resolving * and ** etc. No rendering
- `GridRenderContainer.updateColumnWidths`, which calculates column widths based on the defined settings, including resolving * and ** etc. No rendering
is involved - all based on the availableWidth. This may be the source of some of the iteration - because availableWidth must in some way be
based on columnWidth - the canvas doesn't really have an available width. I also have question on why we calculate widths on the grid
and not on the renderContainer, that may be another source of iteration. Having said that, things like % and * probably apply to the
Expand All @@ -54,6 +53,7 @@ The style builders include:
width of each column in the render container, and the width of the overall render container.
- `Grid.prototype.getFooterStyles()`, sets the columnFooterHeight and the gridFooterHeight based on fixed values declared in the options
- when there are multiple renderContainers (e.g. a left container), the non-body render containers appear to execute first
- `ui-pinned-container.updateContainerDimensions()`: sets the width of a pinned container. How does this interact with render container width?

### Vision
The vision is to make the style calculations more deterministic, and remove any iteration or other dependencies. A single pass through
Expand Down
14 changes: 12 additions & 2 deletions misc/tutorial/204_column_resizing.ngdoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,17 @@

The Resize Columns feature allows each column to be resized.

To enable, you must include the 'ui.grid.resizeColumns' module and you must include the ui-grid-resize-columns directive on your grid element.
To enable, you must include the 'ui.grid.resizeColumns' module and you must include the ui-grid-resize-columns directive
on your grid element.

You can set individual columns to not be resizeable, if you do this it is recommended that those columns have a fixed
pixel width - otherwise they may get automatically resized to fill the remaining space if other columns are reduced in size,
and there will be no way to reduce their width again.

When you resize a column any other columns with fixed widths, or that have already been resized, retain their width. All other
columns resize to take up the remaining space. As long as there is at least one variable column left your columns won't reduce
below the full grid width - but once you've resized all the columns then you can end up with the total column width less than the
grid width.

<pre>
angular.module('yourApp', ['ui.grid', 'ui.grid.resizeColumns']);
Expand Down Expand Up @@ -45,7 +55,7 @@ $scope.gridOptions = {
$scope.gridOptions = {
enableSorting: true,
columnDefs: [
{ field: 'name', minWidth: 200, width: '50%', enableColumnResizing: false },
{ field: 'name', minWidth: 200, width: 250, enableColumnResizing: false },
{ field: 'gender', width: '30%', maxWidth: 200, minWidth: 70 },
{ field: 'company', width: '20%' }
]
Expand Down
28 changes: 3 additions & 25 deletions src/features/pinning/js/pinning.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@
col.grid.refresh()
.then(function () {
col.renderContainer = 'left';
// Need to calculate the width. If col.drawnWidth is used instead then the width
// will be 100% if it's the first column, 50% if it's the second etc.
col.width = col.grid.canvasWidth / col.grid.columns.length;
col.grid.createLeftContainer();
});
}
Expand All @@ -106,9 +103,6 @@
col.grid.refresh()
.then(function () {
col.renderContainer = 'right';
// Need to calculate the width. If col.drawnWidth is used instead then the width
// will be 100% if it's the first column, 50% if it's the second etc.
col.width = col.grid.canvasWidth / col.grid.columns.length;
col.grid.createRightContainer();
});
}
Expand All @@ -134,12 +128,7 @@
this.context.col.width = this.context.col.drawnWidth;
this.context.col.grid.createLeftContainer();

// Need to call refresh twice; once to move our column over to the new render container and then
// a second time to update the grid viewport dimensions with our adjustments
col.grid.refresh()
.then(function () {
col.grid.refresh();
});
col.grid.refresh();
}
};

Expand All @@ -155,13 +144,7 @@
this.context.col.width = this.context.col.drawnWidth;
this.context.col.grid.createRightContainer();


// Need to call refresh twice; once to move our column over to the new render container and then
// a second time to update the grid viewport dimensions with our adjustments
col.grid.refresh()
.then(function () {
col.grid.refresh();
});
col.grid.refresh();
}
};

Expand All @@ -175,12 +158,7 @@
action: function () {
this.context.col.renderContainer = null;

// Need to call refresh twice; once to move our column over to the new render container and then
// a second time to update the grid viewport dimensions with our adjustments
col.grid.refresh()
.then(function () {
col.grid.refresh();
});
col.grid.refresh();
}
};

Expand Down
22 changes: 0 additions & 22 deletions src/features/resize-columns/js/ui-grid-column-resizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,22 +328,6 @@
$elm.addClass('right');
}

// Resize all the other columns around col
function resizeAroundColumn(col) {
// Get this column's render container
var renderContainer = col.getRenderContainer();

renderContainer.visibleColumnCache.forEach(function (column) {
// Skip the column we just resized
if (column === col) { return; }

var colDef = column.colDef;
if (!colDef.width || (angular.isString(colDef.width) && (colDef.width.indexOf('*') !== -1 || colDef.width.indexOf('%') !== -1))) {
column.width = column.drawnWidth;
}
});
}

// Build the columns then refresh the grid canvas
// takes an argument representing the diff along the X-axis that the resize had
function buildColumnsAndRefresh(xDiff) {
Expand Down Expand Up @@ -440,9 +424,6 @@
// check we're not outside the allowable bounds for this column
col.width = constrainWidth(col, newWidth);

// All other columns because fixed to their drawn width, if they aren't already
resizeAroundColumn(col);

buildColumnsAndRefresh(xDiff);

uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
Expand Down Expand Up @@ -527,9 +508,6 @@
// check we're not outside the allowable bounds for this column
col.width = constrainWidth(col, maxWidth);

// All other columns because fixed to their drawn width, if they aren't already
resizeAroundColumn(col);

buildColumnsAndRefresh(xDiff);

uiGridResizeColumnsService.fireColumnSizeChanged(uiGridCtrl.grid, col.colDef, xDiff);
Expand Down
114 changes: 9 additions & 105 deletions src/js/core/directives/ui-grid-header.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,118 +81,22 @@
gridUtil.disableAnimations($elm);

function updateColumnWidths() {
// Get the width of the viewport
var availableWidth = containerCtrl.colContainer.getViewportWidth() - grid.scrollbarWidth;

//if (typeof(uiGridCtrl.grid.verticalScrollbarWidth) !== 'undefined' && uiGridCtrl.grid.verticalScrollbarWidth !== undefined && uiGridCtrl.grid.verticalScrollbarWidth > 0) {
// availableWidth = availableWidth + uiGridCtrl.grid.verticalScrollbarWidth;
//}

// The total number of columns
// var equalWidthColumnCount = columnCount = uiGridCtrl.grid.options.columnDefs.length;
// var equalWidth = availableWidth / equalWidthColumnCount;

var columnCache = containerCtrl.colContainer.visibleColumnCache,
canvasWidth = 0,
asteriskNum = 0,
oneAsterisk = 0,
leftoverWidth = availableWidth,
hasVariableWidth = false;

var getColWidth = function(column){
if (column.widthType === "manual"){
return +column.width;
}
else if (column.widthType === "percent"){
return parseInt(column.width.replace(/%/g, ''), 10) * availableWidth / 100;
}
else if (column.widthType === "auto"){
// leftOverWidth is subtracted from after each call to this
// function so we need to calculate oneAsterisk size only once
if (oneAsterisk === 0) {
oneAsterisk = parseInt(leftoverWidth / asteriskNum, 10);
}
return column.width.length * oneAsterisk;
}
};

// Populate / determine column width types:
columnCache.forEach(function(column){
column.widthType = null;
if (isFinite(+column.width)){
column.widthType = "manual";
}
else if (gridUtil.endsWith(column.width, "%")){
column.widthType = "percent";
hasVariableWidth = true;
}
else if (angular.isString(column.width) && column.width.indexOf('*') !== -1){
column.widthType = "auto";
asteriskNum += column.width.length;
hasVariableWidth = true;
}
});

// For sorting, calculate width from first to last:
var colWidthPriority = ["manual", "percent", "auto"];
columnCache.filter(function(column){
// Only draw visible items with a widthType
return (column.visible && column.widthType);
}).sort(function(a,b){
// Calculate widths in order, so that manual comes first, etc.
return colWidthPriority.indexOf(a.widthType) - colWidthPriority.indexOf(b.widthType);
}).forEach(function(column){
// Calculate widths:
var colWidth = getColWidth(column);
if (column.minWidth){
colWidth = Math.max(colWidth, column.minWidth);
}
if (column.maxWidth){
colWidth = Math.min(colWidth, column.maxWidth);
}
column.drawnWidth = Math.floor(colWidth);
canvasWidth += column.drawnWidth;
leftoverWidth -= column.drawnWidth;
});

// If the grid width didn't divide evenly into the column widths and we have pixels left over, dole them out to the columns one by one to make everything fit
if (hasVariableWidth && leftoverWidth > 0 && canvasWidth > 0 && canvasWidth < availableWidth) {
var remFn = function (column) {
if (leftoverWidth > 0 && (column.widthType === "auto" || column.widthType === "percent")) {
column.drawnWidth = column.drawnWidth + 1;
canvasWidth = canvasWidth + 1;
leftoverWidth--;
}
};
var prevLeftover = 0;
do {
prevLeftover = leftoverWidth;
columnCache.forEach(remFn);
} while (leftoverWidth > 0 && leftoverWidth !== prevLeftover );
}
canvasWidth = Math.max(canvasWidth, availableWidth);
// this styleBuilder always runs after the renderContainer, so we can rely on the column widths
// already being populated correctly

var columnCache = containerCtrl.colContainer.visibleColumnCache;

// Build the CSS
// uiGridCtrl.grid.columns.forEach(function (column) {
var ret = '';
var canvasWidth = 0;
columnCache.forEach(function (column) {
ret = ret + column.getColClassDefinition();
canvasWidth += column.drawnWidth;
});

// Add the vertical scrollbar width back in to the canvas width, it's taken out in getViewportWidth
//if (grid.verticalScrollbarWidth) {
// canvasWidth = canvasWidth + grid.verticalScrollbarWidth;
//}
// canvasWidth = canvasWidth + 1;

// if we have a grid menu, then we prune the width of the last column header
// to allow room for the button whilst still getting to the column menu
if (columnCache.length > 0) { // && grid.options.enableGridMenu) {
columnCache[columnCache.length - 1].headerWidth = columnCache[columnCache.length - 1].drawnWidth - 30;
}

containerCtrl.colContainer.canvasWidth = parseInt(canvasWidth, 10);

containerCtrl.colContainer.canvasWidth = canvasWidth;

// Return the styles back to buildStyles which pops them into the `customStyles` scope variable
return ret;
}
Expand All @@ -207,7 +111,7 @@
//todo: remove this if by injecting gridCtrl into unit tests
if (uiGridCtrl) {
uiGridCtrl.grid.registerStyleComputation({
priority: 5,
priority: 15,
func: updateColumnWidths
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/js/core/directives/ui-grid-render-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
function update() {
var ret = '';

var canvasWidth = colContainer.getCanvasWidth();
var canvasWidth = colContainer.canvasWidth;
var viewportWidth = colContainer.getViewportWidth();

var canvasHeight = rowContainer.getCanvasHeight();
Expand Down
13 changes: 5 additions & 8 deletions src/js/core/directives/ui-pinned-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,33 @@
width += col.drawnWidth || col.width || 0;
}

myWidth = width;
return width;
}
}

function updateContainerDimensions() {
// gridUtil.logDebug('update ' + $scope.side + ' dimensions');

var ret = '';

// Column containers
if ($scope.side === 'left' || $scope.side === 'right') {
updateContainerWidth();
myWidth = updateContainerWidth();

// gridUtil.logDebug('myWidth', myWidth);

// TODO(c0bra): Subtract sum of col widths from grid viewport width and update it
$elm.attr('style', null);

var myHeight = grid.renderContainers.body.getViewportHeight(); // + grid.horizontalScrollbarHeight;

ret += '.grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ', .grid' + grid.id + ' .ui-grid-pinned-container-' + $scope.side + ' .ui-grid-render-container-' + $scope.side + ' .ui-grid-viewport { width: ' + myWidth + 'px; height: ' + myHeight + 'px; } ';
}

return ret;
}

grid.renderContainers.body.registerViewportAdjuster(function (adjustment) {
if ( myWidth === 0 || !myWidth ){
updateContainerWidth();
}
myWidth = updateContainerWidth();

// Subtract our own width
adjustment.width -= myWidth;

Expand Down
Loading