From 01c2a064f287638382f0f7fe474098393b73b9ca Mon Sep 17 00:00:00 2001 From: Mike Bender Date: Thu, 18 Apr 2024 12:39:53 -0400 Subject: [PATCH] fix: Fix issues when auto-size columns/rows is false, and when row headers are not 0 (#1927) - Shouldn't throw in those cases, we should handle when calculatedSizes is empty - Found when using out [deephaven-doom](https://github.com/mofojed/deephaven-doom), couldn't resize/move columns like expected - Also tested in the styleguide - dragging columns when there were row headers visible did not work correctly --- packages/grid/src/GridRenderer.ts | 9 +++++++-- .../GridColumnMoveMouseHandler.ts | 18 ++++++++++-------- .../GridSeparatorMouseHandler.ts | 15 +++++++-------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/packages/grid/src/GridRenderer.ts b/packages/grid/src/GridRenderer.ts index 920e31b707..2013c2a682 100644 --- a/packages/grid/src/GridRenderer.ts +++ b/packages/grid/src/GridRenderer.ts @@ -2323,7 +2323,9 @@ export class GridRenderer { ); context.clip(); - context.translate(draggingLeft - originalLeft, 0); + // The header drawing functions expect the context to be at the edge of the canvas + // We offset it by how much the user has dragged + context.translate(draggingLeft - originalLeft - gridX, 0); context.font = headerFont; const visibleColumns: VisibleIndex[] = []; @@ -2352,11 +2354,14 @@ export class GridRenderer { } ); - context.translate(0, gridY); + // Now move to the edge of the "grid" (top-left of top-left cell). We then draw the + // grid background, but only the clipped region will be drawn where the dragging column is. + context.translate(gridX, gridY); context.font = font; this.drawGridBackground(context, state); + // Then draw the contents of the column that is being dragged for (let i = startIndex; i <= endIndex; i += 1) { this.drawColumnCellContents(context, state, i); } diff --git a/packages/grid/src/mouse-handlers/GridColumnMoveMouseHandler.ts b/packages/grid/src/mouse-handlers/GridColumnMoveMouseHandler.ts index e9d6300e4a..b65f8362bb 100644 --- a/packages/grid/src/mouse-handlers/GridColumnMoveMouseHandler.ts +++ b/packages/grid/src/mouse-handlers/GridColumnMoveMouseHandler.ts @@ -1,4 +1,5 @@ import clamp from 'lodash.clamp'; +import { assertNotNull } from '@deephaven/utils'; import Grid from '../Grid'; import GridUtils, { GridPoint } from '../GridUtils'; import GridMouseHandler, { GridMouseEvent } from '../GridMouseHandler'; @@ -381,6 +382,9 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { ) { return; } + const { metrics } = grid; + assertNotNull(metrics, 'Metrics not set'); + const { gridX } = metrics; // Cursor has moved past the column drag bounds, don't move the column until we hit the initial offset point again if (this.initialOffset !== this.draggingOffset) { @@ -400,7 +404,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { this.draggingColumn = { ...this.draggingColumn, - left: mouseX - this.draggingOffset, + left: mouseX - this.draggingOffset - gridX, }; grid.setState({ draggingColumn: this.draggingColumn }); return; @@ -410,8 +414,6 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { const { model } = grid.props; const { movedColumns } = grid.state; - const { metrics } = grid; - if (!metrics) throw new Error('Metrics not set'); const { floatingLeftWidth, width, columnHeaderMaxDepth, allColumnXs } = metrics; @@ -431,7 +433,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { // The returned left/right are the original position, not dragged position // This is where the dragging column's floating position accounting for dragged distance - const floatingDraggingLeft = mouseX - this.draggingOffset; + const floatingDraggingLeft = mouseX - this.draggingOffset - gridX; const floatingDraggingRight = floatingDraggingLeft + draggingColumn.width; this.draggingColumn = { @@ -448,7 +450,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { isDraggingLeft ? floatingDraggingLeft : floatingDraggingRight, floatingLeftWidth, width - ), + ) + gridX, metrics, true ), @@ -481,7 +483,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { mouseX - (allColumnXs.get(parentVisibleRange[0]) ?? 0); this.draggingColumn = { ...this.draggingColumn, - left: mouseX - this.draggingOffset, + left: mouseX - this.draggingOffset - gridX, }; this.clearScrollInterval(); grid.setState({ @@ -506,7 +508,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { this.draggingOffset = mouseX - (parentRight - draggingColumn.width); this.draggingColumn = { ...this.draggingColumn, - left: mouseX - this.draggingOffset, + left: mouseX - this.draggingOffset - gridX, }; this.clearScrollInterval(); grid.setState({ @@ -570,7 +572,7 @@ class GridColumnMoveMouseHandler extends GridMouseHandler { this.draggingColumn = { ...this.draggingColumn, - left: mouseX - this.draggingOffset, + left: mouseX - this.draggingOffset - gridX, }; grid.setState({ diff --git a/packages/grid/src/mouse-handlers/GridSeparatorMouseHandler.ts b/packages/grid/src/mouse-handlers/GridSeparatorMouseHandler.ts index 7074520131..e9321b7051 100644 --- a/packages/grid/src/mouse-handlers/GridSeparatorMouseHandler.ts +++ b/packages/grid/src/mouse-handlers/GridSeparatorMouseHandler.ts @@ -174,12 +174,13 @@ abstract class GridSeparatorMouseHandler extends GridMouseHandler { const targetSize = this.targetSizes.get(modelIndex); const isResizingMultiple = this.resizingItems.length > 1; const hiddenIndex = this.hiddenItems.indexOf(resizeIndex); - let calculatedSize = getOrThrow(calculatedSizes, modelIndex); - if (resizeIndex === firstIndex) { + let calculatedSize = calculatedSizes.get(modelIndex); + if (calculatedSize != null && resizeIndex === firstIndex) { calculatedSize += treePadding; } let newSize = itemSize; if ( + calculatedSize != null && Math.abs(itemSize - calculatedSize) <= theme.headerResizeSnapThreshold ) { // Snapping behaviour to "natural" width @@ -275,14 +276,12 @@ abstract class GridSeparatorMouseHandler extends GridMouseHandler { const modelIndexes = metrics[this.modelIndexesProperty]; const modelIndex = getOrThrow(modelIndexes, separator.index); - const calculatedSize = getOrThrow( - metrics[this.calculatedSizesProperty], - modelIndex - ); + const calculatedSize = + metrics[this.calculatedSizesProperty].get(modelIndex); const defaultSize = metricCalculator[this.initialSizesProperty].get(modelIndex); - if (calculatedSize === defaultSize) { + if (calculatedSize === defaultSize || calculatedSize == null) { this.resetSize(metricCalculator, modelIndex); } else { this.setSize(metricCalculator, modelIndex, calculatedSize); @@ -314,7 +313,7 @@ abstract class GridSeparatorMouseHandler extends GridMouseHandler { const modelIndex = getOrThrow(modelIndexes, itemIndex); let targetSize = userSizes.get(modelIndex); if (targetSize == null || targetSize === 0) { - targetSize = getOrThrow(calculatedSizes, modelIndex) + treePadding; + targetSize = (calculatedSizes.get(modelIndex) ?? 0) + treePadding; } this.targetSizes.set(modelIndex, targetSize); }