Skip to content
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

Customize minimum row and column section sizes for datagrid #65

Merged
merged 3 commits into from
Apr 24, 2020
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
9 changes: 8 additions & 1 deletion examples/example-datagrid/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
114 changes: 85 additions & 29 deletions packages/datagrid/src/datagrid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +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;

// 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: 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();
Expand Down Expand Up @@ -468,17 +469,36 @@ 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);
let cw = Private.clampSectionSize(value.columnWidth);
let rhw = Private.clampSectionSize(value.rowHeaderWidth);
let chh = Private.clampSectionSize(value.columnHeaderHeight);
// Update the section default sizes.
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();
}

/**
* 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.defaultSize = rh;
this._columnSections.defaultSize = cw;
this._rowHeaderSections.defaultSize = rhw;
this._columnHeaderSections.defaultSize = chh;
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();
Expand Down Expand Up @@ -3027,7 +3047,7 @@ class DataGrid extends Widget {
let oldSize = list.sizeOf(index);

// Normalize the new size of the section.
let newSize = Private.clampSectionSize(size);
let newSize = list.clampSize(size);

// Bail early if the size does not change.
if (oldSize === newSize) {
Expand Down Expand Up @@ -3139,7 +3159,7 @@ class DataGrid extends Widget {
let oldSize = list.sizeOf(index);

// Normalize the new size of the section.
let newSize = Private.clampSectionSize(size);
let newSize = list.clampSize(size);

// Bail early if the size does not change.
if (oldSize === newSize) {
Expand Down Expand Up @@ -3251,7 +3271,7 @@ class DataGrid extends Widget {
let oldSize = list.sizeOf(index);

// Normalize the new size of the section.
let newSize = Private.clampSectionSize(size);
let newSize = list.clampSize(size);

// Bail early if the size does not change.
if (oldSize === newSize) {
Expand Down Expand Up @@ -3339,7 +3359,7 @@ class DataGrid extends Widget {
let oldSize = list.sizeOf(index);

// Normalize the new size of the section.
let newSize = Private.clampSectionSize(size);
let newSize = list.clampSize(size);

// Bail early if the size does not change.
if (oldSize === newSize) {
Expand Down Expand Up @@ -5335,6 +5355,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.
*/
Expand Down Expand Up @@ -5423,6 +5469,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.
*
Expand Down Expand Up @@ -5675,6 +5728,17 @@ namespace DataGrid {
columnHeaderHeight: 20
};

/**
* The default minimum sizes for a data grid.
*/
export
const minimumSizes: MinimumSizes = {
rowHeight: 20,
columnWidth: 10,
rowHeaderWidth: 10,
columnHeaderHeight: 20
};

/**
* The default copy config for a data grid.
*/
Expand Down Expand Up @@ -5721,14 +5785,6 @@ namespace Private {
return canvas;
}

/**
* Clamp a section size to the limits.
*/
export
function clampSectionSize(size: number): number {
return Math.max(10, Math.floor(size));
}

/**
* An object which represents a region to be painted.
*/
Expand Down
60 changes: 56 additions & 4 deletions packages/datagrid/src/sectionlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

/**
Expand All @@ -51,6 +52,40 @@ 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;
}

// 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.
*
Expand All @@ -69,7 +104,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) {
Expand Down Expand Up @@ -106,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.
*
Expand Down Expand Up @@ -293,8 +339,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);
Expand Down Expand Up @@ -566,6 +612,7 @@ class SectionList {

private _count = 0;
private _length = 0;
private _minimumSize: number;
private _defaultSize: number;
private _sections: Private.Section[] = [];
}
Expand All @@ -585,6 +632,11 @@ namespace SectionList {
* The size of new sections added to the list.
*/
defaultSize: number;

/**
* The minimum size of the section list.
*/
minimumSize?: number;
}
}

Expand Down