@@ -34,6 +34,7 @@ class TextRenderer extends CellRenderer {
34
34
this . verticalAlignment = options . verticalAlignment || 'center' ;
35
35
this . horizontalAlignment = options . horizontalAlignment || 'left' ;
36
36
this . format = options . format || TextRenderer . formatGeneric ( ) ;
37
+ this . elideDirection = options . elideDirection || 'right' ;
37
38
}
38
39
39
40
/**
@@ -66,6 +67,11 @@ class TextRenderer extends CellRenderer {
66
67
*/
67
68
readonly format : TextRenderer . FormatFunc ;
68
69
70
+ /**
71
+ * Which side to draw the ellipsis.
72
+ */
73
+ readonly elideDirection : CellRenderer . ConfigOption < TextRenderer . ElideDirection > ;
74
+
69
75
/**
70
76
* Paint the content for a cell.
71
77
*
@@ -136,6 +142,9 @@ class TextRenderer extends CellRenderer {
136
142
let vAlign = CellRenderer . resolveOption ( this . verticalAlignment , config ) ;
137
143
let hAlign = CellRenderer . resolveOption ( this . horizontalAlignment , config ) ;
138
144
145
+ // Resolve the elision direction
146
+ let elideDirection = CellRenderer . resolveOption ( this . elideDirection , config ) ;
147
+
139
148
// Compute the padded text box height for the specified alignment.
140
149
let boxHeight = config . height - ( vAlign === 'center' ? 1 : 2 ) ;
141
150
@@ -150,6 +159,7 @@ class TextRenderer extends CellRenderer {
150
159
// Set up the text position variables.
151
160
let textX : number ;
152
161
let textY : number ;
162
+ let boxWidth : number ;
153
163
154
164
// Compute the Y position for the text.
155
165
switch ( vAlign ) {
@@ -169,13 +179,16 @@ class TextRenderer extends CellRenderer {
169
179
// Compute the X position for the text.
170
180
switch ( hAlign ) {
171
181
case 'left' :
172
- textX = config . x + 2 ;
182
+ textX = config . x + 8 ;
183
+ boxWidth = config . width - 14 ;
173
184
break ;
174
185
case 'center' :
175
186
textX = config . x + config . width / 2 ;
187
+ boxWidth = config . width ;
176
188
break ;
177
189
case 'right' :
178
- textX = config . x + config . width - 3 ;
190
+ textX = config . x + config . width - 8 ;
191
+ boxWidth = config . width - 14 ;
179
192
break ;
180
193
default :
181
194
throw 'unreachable' ;
@@ -194,6 +207,35 @@ class TextRenderer extends CellRenderer {
194
207
gc . textAlign = hAlign ;
195
208
gc . textBaseline = 'bottom' ;
196
209
210
+ // Elide text that is too long
211
+ let elide = '\u2026' ;
212
+ let textWidth = gc . measureText ( text ) . width ;
213
+
214
+ // Compute elided text
215
+ if ( elideDirection === 'right' ) {
216
+ while ( ( textWidth > boxWidth ) && ( text . length > 1 ) ) {
217
+ if ( text . length > 4 && textWidth >= 2 * boxWidth ) {
218
+ // If text width is substantially bigger, take half the string
219
+ text = text . substring ( 0 , ( text . length / 2 ) + 1 ) + elide ;
220
+ } else {
221
+ // Otherwise incrementally remove the last character
222
+ text = text . substring ( 0 , text . length - 2 ) + elide ;
223
+ }
224
+ textWidth = gc . measureText ( text ) . width ;
225
+ }
226
+ } else {
227
+ while ( ( textWidth > boxWidth ) && ( text . length > 1 ) ) {
228
+ if ( text . length > 4 && textWidth >= 2 * boxWidth ) {
229
+ // If text width is substantially bigger, take half the string
230
+ text = elide + text . substring ( ( text . length / 2 ) ) ;
231
+ } else {
232
+ // Otherwise incrementally remove the last character
233
+ text = elide + text . substring ( 2 ) ;
234
+ }
235
+ textWidth = gc . measureText ( text ) . width ;
236
+ }
237
+ }
238
+
197
239
// Draw the text for the cell.
198
240
gc . fillText ( text , textX , textY ) ;
199
241
}
@@ -217,6 +259,12 @@ namespace TextRenderer {
217
259
export
218
260
type HorizontalAlignment = 'left' | 'center' | 'right' ;
219
261
262
+ /**
263
+ * A type alias for the supported ellipsis sides.
264
+ */
265
+ export
266
+ type ElideDirection = 'left' | 'right' ;
267
+
220
268
/**
221
269
* An options object for initializing a text renderer.
222
270
*/
@@ -263,6 +311,14 @@ namespace TextRenderer {
263
311
* The default is `TextRenderer.formatGeneric()`.
264
312
*/
265
313
format ?: FormatFunc ;
314
+
315
+ /**
316
+ * The ellipsis direction for the cell text.
317
+ *
318
+ * The default is `'right'`.
319
+ */
320
+ elideDirection ?: CellRenderer . ConfigOption < ElideDirection > ;
321
+
266
322
}
267
323
268
324
/**
0 commit comments