Skip to content
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
5 changes: 5 additions & 0 deletions examples/example-datagrid/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,13 +436,18 @@ function main(): void {
horizontalAlignment: 'right'
});

let elideFloatRenderer = new TextRenderer({
elideDirection: ({ column }) => (column % 2 === 0) ? 'right' : 'left',
});

let grid1 = new DataGrid({ style: blueStripeStyle });
grid1.dataModel = model1;
grid1.keyHandler = new BasicKeyHandler();
grid1.mouseHandler = new BasicMouseHandler();
grid1.selectionModel = new BasicSelectionModel({ dataModel: model1 });

let grid2 = new DataGrid({ style: brownStripeStyle });
grid2.cellRenderers.update({ 'body': elideFloatRenderer });
grid2.dataModel = model2;
grid2.keyHandler = new BasicKeyHandler();
grid2.mouseHandler = new BasicMouseHandler();
Expand Down
60 changes: 58 additions & 2 deletions packages/datagrid/src/textrenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class TextRenderer extends CellRenderer {
this.verticalAlignment = options.verticalAlignment || 'center';
this.horizontalAlignment = options.horizontalAlignment || 'left';
this.format = options.format || TextRenderer.formatGeneric();
this.elideDirection = options.elideDirection || 'right';
}

/**
Expand Down Expand Up @@ -66,6 +67,11 @@ class TextRenderer extends CellRenderer {
*/
readonly format: TextRenderer.FormatFunc;

/**
* Which side to draw the ellipsis.
*/
readonly elideDirection: CellRenderer.ConfigOption<TextRenderer.ElideDirection>;

/**
* Paint the content for a cell.
*
Expand Down Expand Up @@ -136,6 +142,9 @@ class TextRenderer extends CellRenderer {
let vAlign = CellRenderer.resolveOption(this.verticalAlignment, config);
let hAlign = CellRenderer.resolveOption(this.horizontalAlignment, config);

// Resolve the elision direction
let elideDirection = CellRenderer.resolveOption(this.elideDirection, config);

// Compute the padded text box height for the specified alignment.
let boxHeight = config.height - (vAlign === 'center' ? 1 : 2);

Expand All @@ -150,6 +159,7 @@ class TextRenderer extends CellRenderer {
// Set up the text position variables.
let textX: number;
let textY: number;
let boxWidth: number;

// Compute the Y position for the text.
switch (vAlign) {
Expand All @@ -169,13 +179,16 @@ class TextRenderer extends CellRenderer {
// Compute the X position for the text.
switch (hAlign) {
case 'left':
textX = config.x + 2;
textX = config.x + 8;
boxWidth = config.width - 14;
break;
case 'center':
textX = config.x + config.width / 2;
boxWidth = config.width;
break;
case 'right':
textX = config.x + config.width - 3;
textX = config.x + config.width - 8;
boxWidth = config.width - 14;
break;
default:
throw 'unreachable';
Expand All @@ -194,6 +207,35 @@ class TextRenderer extends CellRenderer {
gc.textAlign = hAlign;
gc.textBaseline = 'bottom';

// Elide text that is too long
let elide = '\u2026';
let textWidth = gc.measureText(text).width;

// Compute elided text
if (elideDirection === 'right') {
while ((textWidth > boxWidth) && (text.length > 1)) {
if (text.length > 4 && textWidth >= 2 * boxWidth) {
// If text width is substantially bigger, take half the string
text = text.substring(0, (text.length / 2) + 1) + elide;
} else {
// Otherwise incrementally remove the last character
text = text.substring(0, text.length - 2) + elide;
}
textWidth = gc.measureText(text).width;
}
} else {
while ((textWidth > boxWidth) && (text.length > 1)) {
if (text.length > 4 && textWidth >= 2 * boxWidth) {
// If text width is substantially bigger, take half the string
text = elide + text.substring((text.length / 2));
} else {
// Otherwise incrementally remove the last character
text = elide + text.substring(2);
}
textWidth = gc.measureText(text).width;
}
}

// Draw the text for the cell.
gc.fillText(text, textX, textY);
}
Expand All @@ -217,6 +259,12 @@ namespace TextRenderer {
export
type HorizontalAlignment = 'left' | 'center' | 'right';

/**
* A type alias for the supported ellipsis sides.
*/
export
type ElideDirection = 'left' | 'right';

/**
* An options object for initializing a text renderer.
*/
Expand Down Expand Up @@ -263,6 +311,14 @@ namespace TextRenderer {
* The default is `TextRenderer.formatGeneric()`.
*/
format?: FormatFunc;

/**
* The ellipsis direction for the cell text.
*
* The default is `'right'`.
*/
elideDirection?: CellRenderer.ConfigOption<ElideDirection>;

}

/**
Expand Down