From 6b477b2fe7549b6a1d332549646e03efe4fefc72 Mon Sep 17 00:00:00 2001 From: Naveen Michaud-Agrawal Date: Thu, 23 Apr 2020 21:31:31 -0400 Subject: [PATCH 1/3] Add support for configuring minimum sizes --- packages/datagrid/src/datagrid.ts | 107 ++++++++++++++++++++++----- packages/datagrid/src/sectionlist.ts | 52 ++++++++++++- 2 files changed, 136 insertions(+), 23 deletions(-) diff --git a/packages/datagrid/src/datagrid.ts b/packages/datagrid/src/datagrid.ts index b7f881f93..0e50a50a9 100644 --- a/packages/datagrid/src/datagrid.ts +++ b/packages/datagrid/src/datagrid.ts @@ -94,17 +94,17 @@ class DataGrid extends Widget { // Parse the default sizes. let defaultSizes = options.defaultSizes || DataGrid.defaultSizes; - let rh = Private.clampSectionSize(defaultSizes.rowHeight); - let cw = Private.clampSectionSize(defaultSizes.columnWidth); - let rhw = Private.clampSectionSize(defaultSizes.rowHeaderWidth); - let chh = Private.clampSectionSize(defaultSizes.columnHeaderHeight); + let minimumSizes = options.minimumSizes || DataGrid.minimumSizes; + let rh = Private.clampSectionSize(defaultSizes.rowHeight, minimumSizes.rowHeight); + let cw = Private.clampSectionSize(defaultSizes.columnWidth, minimumSizes.columnWidth); + let rhw = Private.clampSectionSize(defaultSizes.rowHeaderWidth, minimumSizes.rowHeaderWidth); + let chh = Private.clampSectionSize(defaultSizes.columnHeaderHeight, minimumSizes.columnHeaderHeight); // Set up the sections lists. - this._rowSections = new SectionList({ defaultSize: rh }); - this._columnSections = new SectionList({ defaultSize: cw }); - this._rowHeaderSections = new SectionList({ defaultSize: rhw }); - this._columnHeaderSections = new SectionList({ defaultSize: chh }); - + this._rowSections = new SectionList({ defaultSize: rh, minimumSize: minimumSizes.rowHeight }); + this._columnSections = new SectionList({ defaultSize: cw, minimumSize: minimumSizes.columnWidth}); + this._rowHeaderSections = new SectionList({ defaultSize: rhw, minimumSize: minimumSizes.rowHeaderWidth}); + this._columnHeaderSections = new SectionList({ defaultSize: chh, minimumSize: minimumSizes.columnHeaderHeight}); // Create the canvas, buffer, and overlay objects. this._canvas = Private.createCanvas(); this._buffer = Private.createCanvas(); @@ -469,10 +469,10 @@ class DataGrid extends Widget { */ set defaultSizes(value: DataGrid.DefaultSizes) { // Clamp the sizes. - let rh = Private.clampSectionSize(value.rowHeight); - let cw = Private.clampSectionSize(value.columnWidth); - let rhw = Private.clampSectionSize(value.rowHeaderWidth); - let chh = Private.clampSectionSize(value.columnHeaderHeight); + let rh = Private.clampSectionSize(value.rowHeight, this._rowSections.minimumSize); + let cw = Private.clampSectionSize(value.columnWidth, this._columnSections.minimumSize); + let rhw = Private.clampSectionSize(value.rowHeaderWidth, this._rowHeaderSections.minimumSize); + let chh = Private.clampSectionSize(value.columnHeaderHeight, this._columnHeaderSections.minimumSize); // Update the section default sizes. this._rowSections.defaultSize = rh; @@ -484,6 +484,31 @@ class DataGrid extends Widget { this._syncViewport(); } + /** + * Get the minimum sizes for the various sections of the data grid. + */ + get minimumSizes(): DataGrid.DefaultSizes { + let rowHeight = this._rowSections.minimumSize; + let columnWidth = this._columnSections.minimumSize; + let rowHeaderWidth = this._rowHeaderSections.minimumSize; + let columnHeaderHeight = this._columnHeaderSections.minimumSize; + return { rowHeight, columnWidth, rowHeaderWidth, columnHeaderHeight }; + } + + /** + * Set the minimum sizes for the various sections of the data grid. + */ + set minimumSizes(value: DataGrid.DefaultSizes) { + // Update the section default sizes. + this._rowSections.minimumSize = value.rowHeight; + this._columnSections.minimumSize = value.columnWidth; + this._rowHeaderSections.minimumSize = value.rowHeaderWidth; + this._columnHeaderSections.minimumSize = value.columnHeaderHeight; + + // Sync the viewport. + this._syncViewport(); + } + /** * Get the copy configuration for the data grid. */ @@ -3027,7 +3052,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size); + let newSize = Private.clampSectionSize(size, list.minimumSize); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3139,7 +3164,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size); + let newSize = Private.clampSectionSize(size, list.minimumSize); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3251,7 +3276,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size); + let newSize = Private.clampSectionSize(size, list.minimumSize); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3339,7 +3364,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size); + let newSize = Private.clampSectionSize(size, list.minimumSize); // Bail early if the size does not change. if (oldSize === newSize) { @@ -5335,6 +5360,32 @@ namespace DataGrid { readonly columnHeaderHeight: number; }; + /** + * An object which defines the minimum sizes for a data grid. + */ + export + type MinimumSizes = { + /** + * The minimum height of a row. + */ + readonly rowHeight: number; + + /** + * The minimum width of a column. + */ + readonly columnWidth: number; + + /** + * The minimum width of a row header. + */ + readonly rowHeaderWidth: number; + + /** + * The minimum height of a column header. + */ + readonly columnHeaderHeight: number; + }; + /** * A type alias for the supported header visibility modes. */ @@ -5423,6 +5474,13 @@ namespace DataGrid { */ defaultSizes?: DefaultSizes; + /** + * The minimum sizes for the data grid. + * + * The default is `DataGrid.minimumSizes`. + */ + minimumSizes?: MinimumSizes; + /** * The header visibility for the data grid. * @@ -5675,6 +5733,17 @@ namespace DataGrid { columnHeaderHeight: 20 }; + /** + * The default minimum sizes for a data grid. + */ + export + const minimumSizes: MinimumSizes = { + rowHeight: 10, + columnWidth: 10, + rowHeaderWidth: 10, + columnHeaderHeight: 10 + }; + /** * The default copy config for a data grid. */ @@ -5725,8 +5794,8 @@ namespace Private { * Clamp a section size to the limits. */ export - function clampSectionSize(size: number): number { - return Math.max(10, Math.floor(size)); + function clampSectionSize(size: number, clamp: number): number { + return Math.max(clamp, Math.floor(size)); } /** diff --git a/packages/datagrid/src/sectionlist.ts b/packages/datagrid/src/sectionlist.ts index d7289dbce..ab74aa9b7 100644 --- a/packages/datagrid/src/sectionlist.ts +++ b/packages/datagrid/src/sectionlist.ts @@ -28,7 +28,8 @@ class SectionList { * @param options - The options for initializing the list. */ constructor(options: SectionList.IOptions) { - this._defaultSize = Math.max(0, Math.floor(options.defaultSize)); + this._minimumSize = options.minimumSize || 2; + this._defaultSize = Math.max(this._minimumSize, Math.floor(options.defaultSize)); } /** @@ -51,6 +52,43 @@ class SectionList { return this._count; } + /** + * Get the minimum size of sections in the list. + * + * #### Complexity + * Constant. + */ + get minimumSize(): number { + return this._minimumSize; + } + + /** + * Set the minimum size of sections in the list. + * + * #### Complexity + * Linear on the number of resized sections. + */ + set minimumSize(value: number) { + // Normalize the value. + value = Math.max(2, Math.floor(value)); + + // Bail early if the value does not change. + if (this._minimumSize === value) { + return; + } + + // Compute the delta default size. + //let delta = value - this._minimumSize; + + // Update the internal minimum size. + this._minimumSize = value; + + // Update default size if larger than minimum size + if (value > this._defaultSize) { + this.defaultSize = value; + } + } + /** * Get the default size of sections in the list. * @@ -69,7 +107,7 @@ class SectionList { */ set defaultSize(value: number) { // Normalize the value. - value = Math.max(0, Math.floor(value)); + value = Math.max(this._minimumSize, Math.floor(value)); // Bail early if the value does not change. if (this._defaultSize === value) { @@ -293,8 +331,8 @@ class SectionList { return; } - // Clamp the size to an integer >= 0. - size = Math.max(0, Math.floor(size)); + // Clamp the size to an integer >= minimum size. + size = Math.max(this._minimumSize, Math.floor(size)); // Find the modified section for the given index. let i = ArrayExt.lowerBound(this._sections, index, Private.indexCmp); @@ -566,6 +604,7 @@ class SectionList { private _count = 0; private _length = 0; + private _minimumSize: number; private _defaultSize: number; private _sections: Private.Section[] = []; } @@ -585,6 +624,11 @@ namespace SectionList { * The size of new sections added to the list. */ defaultSize: number; + + /** + * The minimum size of the section list. + */ + minimumSize?: number; } } From 1ed86994fc4ce6261301ef9e0ff5feb2d530ca8f Mon Sep 17 00:00:00 2001 From: Naveen Michaud-Agrawal Date: Thu, 23 Apr 2020 21:31:54 -0400 Subject: [PATCH 2/3] Move clamping to sectionlist --- packages/datagrid/src/datagrid.ts | 51 +++++++++++----------------- packages/datagrid/src/sectionlist.ts | 14 ++++++-- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/packages/datagrid/src/datagrid.ts b/packages/datagrid/src/datagrid.ts index 0e50a50a9..fbda6ae48 100644 --- a/packages/datagrid/src/datagrid.ts +++ b/packages/datagrid/src/datagrid.ts @@ -95,16 +95,17 @@ class DataGrid extends Widget { // Parse the default sizes. let defaultSizes = options.defaultSizes || DataGrid.defaultSizes; let minimumSizes = options.minimumSizes || DataGrid.minimumSizes; - let rh = Private.clampSectionSize(defaultSizes.rowHeight, minimumSizes.rowHeight); - let cw = Private.clampSectionSize(defaultSizes.columnWidth, minimumSizes.columnWidth); - let rhw = Private.clampSectionSize(defaultSizes.rowHeaderWidth, minimumSizes.rowHeaderWidth); - let chh = Private.clampSectionSize(defaultSizes.columnHeaderHeight, minimumSizes.columnHeaderHeight); // Set up the sections lists. - this._rowSections = new SectionList({ defaultSize: rh, minimumSize: minimumSizes.rowHeight }); - this._columnSections = new SectionList({ defaultSize: cw, minimumSize: minimumSizes.columnWidth}); - this._rowHeaderSections = new SectionList({ defaultSize: rhw, minimumSize: minimumSizes.rowHeaderWidth}); - this._columnHeaderSections = new SectionList({ defaultSize: chh, minimumSize: minimumSizes.columnHeaderHeight}); + this._rowSections = new SectionList({ defaultSize: defaultSizes.rowHeight, + minimumSize: minimumSizes.rowHeight }); + this._columnSections = new SectionList({ defaultSize: defaultSizes.columnWidth, + minimumSize: minimumSizes.columnWidth}); + this._rowHeaderSections = new SectionList({ defaultSize: defaultSizes.rowHeaderWidth, + minimumSize: minimumSizes.rowHeaderWidth}); + this._columnHeaderSections = new SectionList({ defaultSize: defaultSizes.columnHeaderHeight, + minimumSize: minimumSizes.columnHeaderHeight}); + // Create the canvas, buffer, and overlay objects. this._canvas = Private.createCanvas(); this._buffer = Private.createCanvas(); @@ -468,17 +469,11 @@ class DataGrid extends Widget { * Set the default sizes for the various sections of the data grid. */ set defaultSizes(value: DataGrid.DefaultSizes) { - // Clamp the sizes. - let rh = Private.clampSectionSize(value.rowHeight, this._rowSections.minimumSize); - let cw = Private.clampSectionSize(value.columnWidth, this._columnSections.minimumSize); - let rhw = Private.clampSectionSize(value.rowHeaderWidth, this._rowHeaderSections.minimumSize); - let chh = Private.clampSectionSize(value.columnHeaderHeight, this._columnHeaderSections.minimumSize); - // Update the section default sizes. - this._rowSections.defaultSize = rh; - this._columnSections.defaultSize = cw; - this._rowHeaderSections.defaultSize = rhw; - this._columnHeaderSections.defaultSize = chh; + this._rowSections.defaultSize = value.rowHeight; + this._columnSections.defaultSize = value.columnWidth; + this._rowHeaderSections.defaultSize = value.rowHeaderWidth; + this._columnHeaderSections.defaultSize = value.columnHeaderHeight; // Sync the viewport. this._syncViewport(); @@ -3052,7 +3047,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size, list.minimumSize); + let newSize = list.clampSize(size); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3164,7 +3159,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size, list.minimumSize); + let newSize = list.clampSize(size); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3276,7 +3271,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size, list.minimumSize); + let newSize = list.clampSize(size); // Bail early if the size does not change. if (oldSize === newSize) { @@ -3364,7 +3359,7 @@ class DataGrid extends Widget { let oldSize = list.sizeOf(index); // Normalize the new size of the section. - let newSize = Private.clampSectionSize(size, list.minimumSize); + let newSize = list.clampSize(size); // Bail early if the size does not change. if (oldSize === newSize) { @@ -5738,10 +5733,10 @@ namespace DataGrid { */ export const minimumSizes: MinimumSizes = { - rowHeight: 10, + rowHeight: 20, columnWidth: 10, rowHeaderWidth: 10, - columnHeaderHeight: 10 + columnHeaderHeight: 20 }; /** @@ -5790,14 +5785,6 @@ namespace Private { return canvas; } - /** - * Clamp a section size to the limits. - */ - export - function clampSectionSize(size: number, clamp: number): number { - return Math.max(clamp, Math.floor(size)); - } - /** * An object which represents a region to be painted. */ diff --git a/packages/datagrid/src/sectionlist.ts b/packages/datagrid/src/sectionlist.ts index ab74aa9b7..7f616b049 100644 --- a/packages/datagrid/src/sectionlist.ts +++ b/packages/datagrid/src/sectionlist.ts @@ -77,9 +77,6 @@ class SectionList { return; } - // Compute the delta default size. - //let delta = value - this._minimumSize; - // Update the internal minimum size. this._minimumSize = value; @@ -144,6 +141,17 @@ class SectionList { } } + /** + * Clamp a size to the minimum section size + * + * @param size - The size to clamp. + * + * @returns The size or the section minimum size, whichever is larger + */ + clampSize(size: number): number { + return Math.max(this._minimumSize, Math.floor(size)); + } + /** * Find the index of the section which covers the given offset. * From c454c494ad38a000294919f841b9a62c37f38168 Mon Sep 17 00:00:00 2001 From: Naveen Michaud-Agrawal Date: Thu, 23 Apr 2020 21:32:11 -0400 Subject: [PATCH 3/3] Update example --- examples/example-datagrid/src/index.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/example-datagrid/src/index.ts b/examples/example-datagrid/src/index.ts index 58a58677b..32336bd6c 100644 --- a/examples/example-datagrid/src/index.ts +++ b/examples/example-datagrid/src/index.ts @@ -451,7 +451,14 @@ function main(): void { selectionMode: 'column' }); - let grid3 = new DataGrid({ stretchLastColumn: true }); + let grid3 = new DataGrid({ stretchLastColumn: true, + minimumSizes: { + rowHeight: 25, + columnWidth: 70, + rowHeaderWidth: 70, + columnHeaderHeight: 25 + } + }); grid3.cellRenderers.update({ 'body': fgColorFloatRenderer }); grid3.dataModel = model3; grid3.keyHandler = new BasicKeyHandler();