@deephaven/grid 0.43.0 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/dist/CellInputField.css +23 -0
  2. package/dist/CellInputField.css.map +1 -0
  3. package/dist/CellInputField.js +174 -0
  4. package/dist/CellInputField.js.map +1 -0
  5. package/dist/CellRenderer.js +64 -0
  6. package/dist/CellRenderer.js.map +1 -0
  7. package/dist/ColumnHeaderGroup.js +2 -0
  8. package/dist/ColumnHeaderGroup.js.map +1 -0
  9. package/dist/DataBarCellRenderer.js +404 -0
  10. package/dist/DataBarCellRenderer.js.map +1 -0
  11. package/dist/DataBarGridModel.js +27 -0
  12. package/dist/DataBarGridModel.js.map +1 -0
  13. package/dist/EditableGridModel.js +14 -0
  14. package/dist/EditableGridModel.js.map +1 -0
  15. package/dist/EventHandlerResult.js +2 -0
  16. package/dist/EventHandlerResult.js.map +1 -0
  17. package/dist/ExpandableGridModel.js +8 -0
  18. package/dist/ExpandableGridModel.js.map +1 -0
  19. package/dist/Grid.css +45 -0
  20. package/dist/Grid.css.map +1 -0
  21. package/dist/Grid.js +1947 -0
  22. package/dist/Grid.js.map +1 -0
  23. package/dist/GridAxisRange.js +17 -0
  24. package/dist/GridAxisRange.js.map +1 -0
  25. package/dist/GridColorUtils.js +146 -0
  26. package/dist/GridColorUtils.js.map +1 -0
  27. package/dist/GridMetricCalculator.js +1500 -0
  28. package/dist/GridMetricCalculator.js.map +1 -0
  29. package/dist/GridMetrics.js +2 -0
  30. package/dist/GridMetrics.js.map +1 -0
  31. package/dist/GridModel.js +193 -0
  32. package/dist/GridModel.js.map +1 -0
  33. package/dist/GridMouseHandler.js +57 -0
  34. package/dist/GridMouseHandler.js.map +1 -0
  35. package/dist/GridRange.js +684 -0
  36. package/dist/GridRange.js.map +1 -0
  37. package/dist/GridRenderer.js +2038 -0
  38. package/dist/GridRenderer.js.map +1 -0
  39. package/dist/GridRendererTypes.js +3 -0
  40. package/dist/GridRendererTypes.js.map +1 -0
  41. package/dist/GridTestUtils.js +16 -0
  42. package/dist/GridTestUtils.js.map +1 -0
  43. package/dist/GridTheme.js +100 -0
  44. package/dist/GridTheme.js.map +1 -0
  45. package/dist/GridUtils.js +1198 -0
  46. package/dist/GridUtils.js.map +1 -0
  47. package/dist/KeyHandler.js +36 -0
  48. package/dist/KeyHandler.js.map +1 -0
  49. package/dist/MockDataBarGridModel.js +119 -0
  50. package/dist/MockDataBarGridModel.js.map +1 -0
  51. package/dist/MockGridData.js +5 -0
  52. package/dist/MockGridData.js.map +1 -0
  53. package/dist/MockGridModel.js +122 -0
  54. package/dist/MockGridModel.js.map +1 -0
  55. package/dist/MockTreeGridModel.js +193 -0
  56. package/dist/MockTreeGridModel.js.map +1 -0
  57. package/dist/StaticDataGridModel.js +40 -0
  58. package/dist/StaticDataGridModel.js.map +1 -0
  59. package/dist/TextCellRenderer.js +210 -0
  60. package/dist/TextCellRenderer.js.map +1 -0
  61. package/dist/ThemeContext.js +4 -0
  62. package/dist/ThemeContext.js.map +1 -0
  63. package/dist/TokenBoxCellRenderer.js +4 -0
  64. package/dist/TokenBoxCellRenderer.js.map +1 -0
  65. package/dist/ViewportDataGridModel.js +43 -0
  66. package/dist/ViewportDataGridModel.js.map +1 -0
  67. package/dist/errors/AssertionError.js +11 -0
  68. package/dist/errors/AssertionError.js.map +1 -0
  69. package/dist/errors/PasteError.js +11 -0
  70. package/dist/errors/PasteError.js.map +1 -0
  71. package/dist/errors/assertIsDefined.js +8 -0
  72. package/dist/errors/assertIsDefined.js.map +1 -0
  73. package/dist/errors/index.js +4 -0
  74. package/dist/errors/index.js.map +1 -0
  75. package/dist/index.js +32 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/key-handlers/EditKeyHandler.js +46 -0
  78. package/dist/key-handlers/EditKeyHandler.js.map +1 -0
  79. package/dist/key-handlers/PasteKeyHandler.js +124 -0
  80. package/dist/key-handlers/PasteKeyHandler.js.map +1 -0
  81. package/dist/key-handlers/SelectionKeyHandler.js +272 -0
  82. package/dist/key-handlers/SelectionKeyHandler.js.map +1 -0
  83. package/dist/key-handlers/TreeKeyHandler.js +45 -0
  84. package/dist/key-handlers/TreeKeyHandler.js.map +1 -0
  85. package/dist/key-handlers/index.js +5 -0
  86. package/dist/key-handlers/index.js.map +1 -0
  87. package/dist/memoizeClear.js +33 -0
  88. package/dist/memoizeClear.js.map +1 -0
  89. package/dist/mouse-handlers/EditMouseHandler.js +25 -0
  90. package/dist/mouse-handlers/EditMouseHandler.js.map +1 -0
  91. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +504 -0
  92. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -0
  93. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +67 -0
  94. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -0
  95. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +164 -0
  96. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -0
  97. package/dist/mouse-handlers/GridRowMoveMouseHandler.js +139 -0
  98. package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -0
  99. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +54 -0
  100. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -0
  101. package/dist/mouse-handlers/GridRowTreeMouseHandler.js +58 -0
  102. package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -0
  103. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +39 -0
  104. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -0
  105. package/dist/mouse-handlers/GridSelectionMouseHandler.js +223 -0
  106. package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -0
  107. package/dist/mouse-handlers/GridSeparatorMouseHandler.js +213 -0
  108. package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -0
  109. package/dist/mouse-handlers/GridTokenMouseHandler.js +161 -0
  110. package/dist/mouse-handlers/GridTokenMouseHandler.js.map +1 -0
  111. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +165 -0
  112. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -0
  113. package/dist/mouse-handlers/index.js +13 -0
  114. package/dist/mouse-handlers/index.js.map +1 -0
  115. package/package.json +3 -3
@@ -0,0 +1,2038 @@
1
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
+ import clamp from 'lodash.clamp';
5
+ import { ColorUtils, getOrThrow } from '@deephaven/utils';
6
+ import memoizeClear from "./memoizeClear.js";
7
+ import GridUtils from "./GridUtils.js";
8
+ import GridColorUtils from "./GridColorUtils.js";
9
+ import { isExpandableGridModel } from "./ExpandableGridModel.js";
10
+ import { isEditableGridModel } from "./EditableGridModel.js";
11
+ import GridColumnSeparatorMouseHandler from "./mouse-handlers/GridColumnSeparatorMouseHandler.js";
12
+ import { DEFAULT_FONT_WIDTH } from "./GridRendererTypes.js";
13
+ import DataBarCellRenderer from "./DataBarCellRenderer.js";
14
+ import TextCellRenderer from "./TextCellRenderer.js";
15
+ /* eslint react/destructuring-assignment: "off" */
16
+ /* eslint class-methods-use-this: "off" */
17
+ /* eslint no-param-reassign: "off" */
18
+ /**
19
+ * A GridRenderer handles rendering the different parts of the grid
20
+ * This default rendering just renders a basic grid. Extend this class and implement
21
+ * your own methods to customize drawing of the grid (eg. Draw icons or special features)
22
+ */
23
+ export class GridRenderer {
24
+ constructor() {
25
+ _defineProperty(this, "textCellRenderer", new TextCellRenderer());
26
+ _defineProperty(this, "dataBarCellRenderer", new DataBarCellRenderer());
27
+ _defineProperty(this, "getCachedBackgroundColors", memoizeClear((backgroundColors, maxDepth) => backgroundColors.split(' ').map(color => {
28
+ var colors = [];
29
+ for (var i = 0; i < maxDepth; i += 1) {
30
+ colors.push(GridColorUtils.darkenForDepth(color, i, maxDepth));
31
+ }
32
+ return colors;
33
+ }), {
34
+ max: 1000
35
+ }));
36
+ _defineProperty(this, "getCachedColorWithAlpha", memoizeClear((color, alpha) => GridColorUtils.colorWithAlpha(color, alpha), {
37
+ max: 1000
38
+ }));
39
+ _defineProperty(this, "getCachedColorIsDark", memoizeClear(color => ColorUtils.isDark(color), {
40
+ max: 1000
41
+ }));
42
+ }
43
+ /**
44
+ * Truncate a string to the specified length and add ellipses if necessary
45
+ * @param str The string to truncate
46
+ * @param len The length to truncate the string to. If longer than the actual string, just returns the string
47
+ * @returns The truncated string
48
+ */
49
+ static truncate(str, len) {
50
+ if (len < str.length) {
51
+ // eslint-disable-next-line prefer-template
52
+ return str.substr(0, len) + '…';
53
+ }
54
+ return str;
55
+ }
56
+
57
+ /**
58
+ * Uses binary search to truncate a string to fit in the provided width
59
+ * @param context The drawing context to measure the text in
60
+ * @param str The string to get the maximum length it can draw
61
+ * @param width The width to truncate it to
62
+ * @param start The low boundary to start the search
63
+ * @param end The high boundary to start the search
64
+ * @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis
65
+ * @returns The truncated string
66
+ */
67
+ static binaryTruncateToWidth(context, str, width) {
68
+ var start = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
69
+ var end = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : str.length;
70
+ var truncationChar = arguments.length > 5 ? arguments[5] : undefined;
71
+ if (end >= str.length && context.measureText(str).width <= width) {
72
+ // IDS-6069 If the whole string can fit, don't bother checking for truncation
73
+ // The ellipses are actually slightly wider than other chars, and it's possible
74
+ // that the "truncation" ends up being slightly longer, which messes up the search
75
+ // algorithm below.
76
+ // Besides, if we already fit, it's just faster to not bother checking other truncations.
77
+ return str;
78
+ }
79
+ if (truncationChar !== undefined) {
80
+ var charWidth = context.measureText(truncationChar).width;
81
+ return truncationChar.repeat(Math.max(1, Math.floor(width / charWidth)));
82
+ }
83
+ var lo = start;
84
+ var hi = Math.min(str.length - 1, end);
85
+ var result = str;
86
+ while (hi >= lo) {
87
+ var mid = Math.ceil((hi + lo) / 2);
88
+ var truncatedStr = GridRenderer.truncate(str, mid);
89
+ if (context.measureText(truncatedStr).width <= width) {
90
+ result = truncatedStr;
91
+ if (lo === mid) {
92
+ break;
93
+ }
94
+ lo = mid;
95
+ } else if (mid === 0) {
96
+ // We already truncated to zero chars and it still doesn't fit, no need to keep looking
97
+ result = truncatedStr;
98
+ break;
99
+ } else {
100
+ hi = mid - 1;
101
+ }
102
+ }
103
+ return result;
104
+ }
105
+
106
+ /**
107
+ * Truncate a string (if necessary) to fit in the specified width.
108
+ * First uses the estimated font width to calculate a lower/upper bound
109
+ * Then uses binary search within those bounds to find the exact max length
110
+ * @param context The drawing context
111
+ * @param str The string to calculate max length for
112
+ * @param width The width to truncate within
113
+ * @param fontWidth The estimated width of each character
114
+ * @param truncationChar This char will be repeated as the display string if the string is truncated instead of just adding an ellipsis
115
+ * @returns The truncated string that fits within the width provided
116
+ */
117
+ static truncateToWidth(context, str, width) {
118
+ var fontWidth = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : DEFAULT_FONT_WIDTH;
119
+ var truncationChar = arguments.length > 4 ? arguments[4] : undefined;
120
+ if (width <= 0 || str.length <= 0) {
121
+ return '';
122
+ }
123
+
124
+ // Estimate the possible low and high boundaries for truncating the text
125
+ // Use the width of the space divided by the estimated width of each character,
126
+ // and take half that as the low (minus 5 just to be extra safe), and double that as the high.
127
+ var lo = Math.min(Math.max(0, Math.floor(width / fontWidth / 2) - 5), str.length);
128
+ var hi = Math.min(Math.ceil(width / fontWidth * 2), str.length);
129
+ return GridRenderer.binaryTruncateToWidth(context, str, width, lo, hi, truncationChar);
130
+ }
131
+
132
+ /**
133
+ * Draw the grid canvas with the state provided
134
+ * @param state The state of the grid
135
+ */
136
+ drawCanvas(state) {
137
+ var {
138
+ context
139
+ } = state;
140
+ context.save();
141
+ this.configureContext(context, state);
142
+ this.drawBackground(context, state);
143
+ this.drawGrid(context, state);
144
+ this.drawHeaders(context, state);
145
+ this.drawFooters(context, state);
146
+ this.drawDraggingColumn(context, state);
147
+ this.drawDraggingRow(context, state);
148
+ this.drawScrollBars(context, state);
149
+ context.restore();
150
+ }
151
+ configureContext(context, state) {
152
+ var {
153
+ theme
154
+ } = state;
155
+ context.font = theme.font;
156
+ context.textBaseline = 'middle';
157
+ context.lineCap = 'butt';
158
+ }
159
+ drawBackground(context, state) {
160
+ var {
161
+ theme,
162
+ metrics
163
+ } = state;
164
+ var {
165
+ width,
166
+ height
167
+ } = metrics;
168
+ context.fillStyle = theme.backgroundColor;
169
+ context.fillRect(0, 0, width, height);
170
+ }
171
+ drawGrid(context, state) {
172
+ var {
173
+ metrics,
174
+ draggingRow,
175
+ draggingColumn
176
+ } = state;
177
+ var {
178
+ gridX,
179
+ gridY
180
+ } = metrics;
181
+ context.translate(gridX, gridY);
182
+ this.drawGridBackground(context, state, draggingRow == null && draggingColumn == null);
183
+ this.drawCellContents(context, state);
184
+ this.drawFloatingRows(context, state);
185
+ this.drawFloatingColumns(context, state);
186
+ context.translate(-gridX, -gridY);
187
+ }
188
+ drawFloatingRows(context, state) {
189
+ var {
190
+ draggingRow,
191
+ draggingColumn,
192
+ metrics,
193
+ theme
194
+ } = state;
195
+ var {
196
+ floatingTopRowCount,
197
+ floatingBottomRowCount,
198
+ floatingRows,
199
+ rowCount,
200
+ visibleColumns,
201
+ allRowYs,
202
+ allRowHeights
203
+ } = metrics;
204
+ if (floatingRows.length === 0) {
205
+ return;
206
+ }
207
+ if (theme.floatingRowBackgroundColors) {
208
+ this.drawRowStripesForRows(context, state, floatingRows, theme.floatingRowBackgroundColors);
209
+ }
210
+ if (draggingRow == null && draggingColumn == null) {
211
+ this.drawFloatingMouseRowHover(context, state);
212
+ }
213
+ this.drawGridLinesForItems(context, state, visibleColumns, floatingRows, theme.floatingGridColumnColor, theme.floatingGridRowColor);
214
+ this.drawCellBackgroundsForItems(context, state, visibleColumns, floatingRows);
215
+ this.drawFloatingBorders(context, state);
216
+
217
+ // Draw the floating row selection...
218
+ if (floatingTopRowCount > 0) {
219
+ this.drawSelectedRanges(context, state, {
220
+ top: 0,
221
+ bottom: floatingTopRowCount - 1,
222
+ maxY: getOrThrow(allRowYs, floatingTopRowCount - 1) + getOrThrow(allRowHeights, floatingTopRowCount - 1) - 0.5
223
+ });
224
+ }
225
+ if (floatingBottomRowCount > 0) {
226
+ this.drawSelectedRanges(context, state, {
227
+ top: rowCount - floatingBottomRowCount - 1,
228
+ bottom: rowCount - 1,
229
+ minY: getOrThrow(allRowYs, rowCount - floatingBottomRowCount) + 0.5,
230
+ maxY: getOrThrow(allRowYs, rowCount - 1) + getOrThrow(allRowHeights, rowCount - 1) - 0.5
231
+ });
232
+ }
233
+
234
+ // Draw the cell content...
235
+ for (var c = 0; c < visibleColumns.length; c += 1) {
236
+ var column = visibleColumns[c];
237
+ for (var r = 0; r < floatingRows.length; r += 1) {
238
+ var row = floatingRows[r];
239
+ this.drawCellContent(context, state, column, row);
240
+ }
241
+ }
242
+ }
243
+ drawFloatingColumns(context, state) {
244
+ var {
245
+ draggingRow,
246
+ draggingColumn,
247
+ metrics,
248
+ theme
249
+ } = state;
250
+ var {
251
+ floatingLeftColumnCount,
252
+ floatingRightColumnCount,
253
+ floatingLeftWidth,
254
+ floatingRightWidth,
255
+ floatingColumns,
256
+ gridX,
257
+ maxX,
258
+ columnCount,
259
+ visibleRows,
260
+ allColumnXs,
261
+ allColumnWidths,
262
+ width,
263
+ height
264
+ } = metrics;
265
+ if (floatingColumns.length === 0) {
266
+ return;
267
+ }
268
+ if (theme.floatingRowBackgroundColors) {
269
+ this.drawRowStripesForRows(context, state, visibleRows, theme.floatingRowBackgroundColors, 0, floatingLeftWidth);
270
+ this.drawRowStripesForRows(context, state, visibleRows, theme.floatingRowBackgroundColors, width - gridX - floatingRightWidth, maxX);
271
+ }
272
+ if (draggingRow == null && draggingColumn == null) {
273
+ this.drawFloatingMouseRowHover(context, state);
274
+ }
275
+
276
+ // Clip floated column grid lines.
277
+ context.save();
278
+ context.beginPath();
279
+ context.rect(0, 0, floatingLeftWidth, height);
280
+ context.clip();
281
+ this.drawGridLinesForItems(context, state, floatingColumns, visibleRows, theme.floatingGridColumnColor, theme.floatingGridRowColor);
282
+ context.restore();
283
+ this.drawCellBackgroundsForItems(context, state, floatingColumns, visibleRows);
284
+ this.drawFloatingBorders(context, state);
285
+
286
+ // Draw the floating column selection...
287
+ if (floatingLeftColumnCount > 0) {
288
+ this.drawSelectedRanges(context, state, {
289
+ left: 0,
290
+ maxX: getOrThrow(allColumnXs, floatingLeftColumnCount - 1) + getOrThrow(allColumnWidths, floatingLeftColumnCount - 1)
291
+ });
292
+ }
293
+ if (floatingRightColumnCount > 0) {
294
+ this.drawSelectedRanges(context, state, {
295
+ left: columnCount - floatingRightColumnCount,
296
+ right: columnCount - 1,
297
+ minX: getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) + 0.5,
298
+ maxX: getOrThrow(allColumnXs, columnCount - 1) + getOrThrow(allColumnWidths, columnCount - 1)
299
+ });
300
+ }
301
+
302
+ // Draw the cell content...
303
+ for (var c = 0; c < floatingColumns.length; c += 1) {
304
+ var column = floatingColumns[c];
305
+ for (var r = 0; r < visibleRows.length; r += 1) {
306
+ var row = visibleRows[r];
307
+ this.drawCellContent(context, state, column, row);
308
+ }
309
+ }
310
+ }
311
+ drawFloatingBorders(context, state) {
312
+ var {
313
+ metrics,
314
+ theme
315
+ } = state;
316
+ var {
317
+ floatingTopRowCount,
318
+ floatingBottomRowCount,
319
+ floatingLeftColumnCount,
320
+ floatingRightColumnCount,
321
+ rowCount,
322
+ columnCount,
323
+ allRowYs,
324
+ allColumnXs,
325
+ allRowHeights,
326
+ allColumnWidths,
327
+ maxX,
328
+ maxY
329
+ } = metrics;
330
+ var {
331
+ floatingDividerOuterColor,
332
+ floatingDividerInnerColor
333
+ } = theme;
334
+ context.lineWidth = 3;
335
+ context.beginPath();
336
+ context.strokeStyle = floatingDividerOuterColor;
337
+ if (floatingTopRowCount > 0) {
338
+ var y = getOrThrow(allRowYs, floatingTopRowCount - 1) + getOrThrow(allRowHeights, floatingTopRowCount - 1) + 0.5;
339
+ context.moveTo(0, y);
340
+ context.lineTo(maxX, y);
341
+ }
342
+ if (floatingBottomRowCount > 0) {
343
+ var _y = getOrThrow(allRowYs, rowCount - floatingBottomRowCount) - 0.5;
344
+ context.moveTo(0, _y);
345
+ context.lineTo(maxX, _y);
346
+ }
347
+ if (floatingLeftColumnCount > 0) {
348
+ var x = getOrThrow(allColumnXs, floatingLeftColumnCount - 1) + getOrThrow(allColumnWidths, floatingLeftColumnCount - 1) + 0.5;
349
+ context.moveTo(x, 0);
350
+ context.lineTo(x, maxY);
351
+ }
352
+ if (floatingRightColumnCount > 0) {
353
+ var _x = getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) - 0.5;
354
+ context.moveTo(_x, 0);
355
+ context.lineTo(_x, maxY);
356
+ }
357
+ context.stroke();
358
+ context.beginPath();
359
+ context.lineWidth = 1;
360
+ context.strokeStyle = floatingDividerInnerColor;
361
+ if (floatingTopRowCount > 0) {
362
+ var _y2 = getOrThrow(allRowYs, floatingTopRowCount - 1) + getOrThrow(allRowHeights, floatingTopRowCount - 1) + 0.5;
363
+ context.moveTo(0, _y2);
364
+ context.lineTo(maxX, _y2);
365
+ }
366
+ if (floatingBottomRowCount > 0) {
367
+ var _y3 = getOrThrow(allRowYs, rowCount - floatingBottomRowCount) - 0.5;
368
+ context.moveTo(0, _y3);
369
+ context.lineTo(maxX, _y3);
370
+ }
371
+ if (floatingLeftColumnCount > 0) {
372
+ var _x2 = getOrThrow(allColumnXs, floatingLeftColumnCount - 1) + getOrThrow(allColumnWidths, floatingLeftColumnCount - 1) + 0.5;
373
+ context.moveTo(_x2, 0);
374
+ context.lineTo(_x2, maxY);
375
+ }
376
+ if (floatingRightColumnCount > 0) {
377
+ var _x3 = getOrThrow(allColumnXs, columnCount - floatingRightColumnCount) - 0.5;
378
+ context.moveTo(_x3, 0);
379
+ context.lineTo(_x3, maxY);
380
+ }
381
+ context.stroke();
382
+ }
383
+ drawGridBackground(context, state) {
384
+ var drawHover = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
385
+ this.drawRowStripes(context, state);
386
+ if (drawHover) {
387
+ this.drawMouseColumnHover(context, state);
388
+ this.drawMouseRowHover(context, state);
389
+ }
390
+ this.drawGridLines(context, state);
391
+ this.drawCellBackgrounds(context, state);
392
+ var {
393
+ metrics
394
+ } = state;
395
+ var {
396
+ bottom,
397
+ right,
398
+ floatingBottomRowCount,
399
+ floatingLeftColumnCount,
400
+ floatingRightColumnCount,
401
+ floatingTopRowCount,
402
+ columnCount,
403
+ rowCount,
404
+ allRowHeights,
405
+ allRowYs,
406
+ allColumnXs,
407
+ allColumnWidths,
408
+ width,
409
+ height
410
+ } = metrics;
411
+ this.drawSelectedRanges(context, state, {
412
+ bottom: Math.min(bottom, rowCount - floatingBottomRowCount - 1),
413
+ right: Math.min(right, columnCount - floatingRightColumnCount - 1),
414
+ minX: floatingLeftColumnCount > 0 && allColumnXs.has(floatingLeftColumnCount + 1) ? getOrThrow(allColumnXs, floatingLeftColumnCount + 1) : -10,
415
+ minY: floatingTopRowCount > 0 && allRowYs.has(floatingTopRowCount + 1) ? getOrThrow(allRowYs, floatingTopRowCount + 1) : -10,
416
+ maxX: floatingRightColumnCount > 0 && allColumnXs.has(columnCount - floatingRightColumnCount - 1) ? getOrThrow(allColumnXs, columnCount - floatingRightColumnCount - 1) + getOrThrow(allColumnWidths, columnCount - floatingRightColumnCount - 1) - 0.5 : width + 10,
417
+ maxY: floatingBottomRowCount > 0 && allRowYs.has(rowCount - floatingBottomRowCount - 1) ? getOrThrow(allRowYs, rowCount - floatingBottomRowCount - 1) + getOrThrow(allRowHeights, rowCount - floatingBottomRowCount - 1) - 0.5 : height + 10
418
+ });
419
+ }
420
+ drawRowStripes(context, state) {
421
+ var {
422
+ metrics,
423
+ theme
424
+ } = state;
425
+ var {
426
+ visibleRows
427
+ } = metrics;
428
+ var {
429
+ rowBackgroundColors
430
+ } = theme;
431
+ if (!rowBackgroundColors) {
432
+ return;
433
+ }
434
+ this.drawRowStripesForRows(context, state, visibleRows, rowBackgroundColors);
435
+ }
436
+ drawRowStripesForRows(context, state, rows, rowBackgroundColors) {
437
+ var minX = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
438
+ var maxX = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : state.metrics.maxX;
439
+ var {
440
+ theme,
441
+ metrics,
442
+ model
443
+ } = state;
444
+ var {
445
+ maxDepth,
446
+ shadowBlur,
447
+ shadowColor
448
+ } = theme;
449
+ var colorSets = this.getCachedBackgroundColors(rowBackgroundColors, maxDepth);
450
+ var {
451
+ allRowYs,
452
+ allRowHeights
453
+ } = metrics;
454
+
455
+ // Optimize by grouping together all rows that end up with the same color
456
+ var colorRowMap = new Map();
457
+ var topShadowRows = []; // Rows that are deeper than the row above them
458
+ var bottomShadowRows = [];
459
+ var addRowToColorMap = (row, rowAbove) => {
460
+ var depth = isExpandableGridModel(model) ? model.depthForRow(row) : 0;
461
+ var colorSet = colorSets[row % colorSets.length];
462
+ var color = colorSet[Math.min(depth, colorSet.length - 1)];
463
+ if (!colorRowMap.has(color)) {
464
+ colorRowMap.set(color, []);
465
+ }
466
+ colorRowMap.get(color).push(row);
467
+ if (rowAbove != null) {
468
+ var depthAbove = isExpandableGridModel(model) ? model.depthForRow(rowAbove) : 0;
469
+ if (depthAbove < depth) {
470
+ topShadowRows.push(row);
471
+ } else if (depthAbove > depth) {
472
+ bottomShadowRows.push(rowAbove);
473
+ }
474
+ }
475
+ };
476
+
477
+ // Add all the regular row stripes
478
+ for (var i = 0; i < rows.length; i += 1) {
479
+ var row = rows[i];
480
+ var rowAbove = i > 0 ? rows[i - 1] : undefined;
481
+ addRowToColorMap(row, rowAbove);
482
+ }
483
+ colorRowMap.forEach((colorRows, color) => {
484
+ context.fillStyle = color;
485
+ context.beginPath();
486
+ for (var _i = 0; _i < colorRows.length; _i += 1) {
487
+ var _row = colorRows[_i];
488
+ var y = getOrThrow(allRowYs, _row);
489
+ var rowHeight = getOrThrow(allRowHeights, _row);
490
+ context.rect(minX, y, maxX, rowHeight);
491
+ }
492
+ context.fill();
493
+ });
494
+ if (topShadowRows.length > 0) {
495
+ context.save();
496
+ var startColor = this.getCachedColorWithAlpha(shadowColor, 0.15);
497
+ var endColor = this.getCachedColorWithAlpha(shadowColor, 0);
498
+ var gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
499
+ gradient.addColorStop(0, startColor);
500
+ gradient.addColorStop(1, endColor);
501
+ context.fillStyle = gradient;
502
+ for (var _i2 = 0; _i2 < topShadowRows.length; _i2 += 1) {
503
+ var _row2 = topShadowRows[_i2];
504
+ var y = getOrThrow(allRowYs, _row2);
505
+ // Use a translate so we can reuse the gradient
506
+ context.translate(0, y);
507
+ context.fillRect(minX, 0, maxX, shadowBlur);
508
+ context.translate(0, -y);
509
+ }
510
+ context.restore();
511
+ }
512
+ if (bottomShadowRows.length > 0) {
513
+ context.save();
514
+ var _startColor = this.getCachedColorWithAlpha(shadowColor, 0);
515
+ var _endColor = this.getCachedColorWithAlpha(shadowColor, 0.15);
516
+ var _gradient = context.createLinearGradient(0, 0, 0, shadowBlur);
517
+ _gradient.addColorStop(0, _startColor);
518
+ _gradient.addColorStop(1, _endColor);
519
+ context.fillStyle = _gradient;
520
+ for (var _i3 = 0; _i3 < bottomShadowRows.length; _i3 += 1) {
521
+ var _row3 = bottomShadowRows[_i3];
522
+ var _y4 = getOrThrow(allRowYs, _row3);
523
+ var rowHeight = getOrThrow(allRowHeights, _row3);
524
+ var gradientY = _y4 + rowHeight - shadowBlur;
525
+ // Use a translate so we can reuse the gradient
526
+ context.translate(0, gradientY);
527
+ context.fillRect(minX, 0, maxX, shadowBlur);
528
+ context.translate(0, -gradientY);
529
+ }
530
+ context.restore();
531
+ }
532
+ }
533
+ drawMouseColumnHover(context, state) {
534
+ var {
535
+ mouseX,
536
+ mouseY,
537
+ theme,
538
+ metrics
539
+ } = state;
540
+ if (mouseX == null || mouseY == null) return;
541
+ var mouseColumn = GridUtils.getColumnAtX(mouseX, metrics);
542
+ if (mouseColumn == null || theme.columnHoverBackgroundColor == null) {
543
+ return;
544
+ }
545
+ var {
546
+ allColumnWidths,
547
+ allColumnXs,
548
+ maxY
549
+ } = metrics;
550
+ if (mouseY > maxY) {
551
+ return;
552
+ }
553
+ var x = getOrThrow(allColumnXs, mouseColumn);
554
+ var columnWidth = getOrThrow(allColumnWidths, mouseColumn);
555
+ context.fillStyle = theme.columnHoverBackgroundColor;
556
+ context.fillRect(x, 0, columnWidth, maxY);
557
+ }
558
+ drawMouseRowHover(context, state) {
559
+ var {
560
+ mouseX,
561
+ mouseY,
562
+ theme,
563
+ metrics
564
+ } = state;
565
+ if (mouseX == null || mouseY == null) return;
566
+ var {
567
+ maxX
568
+ } = metrics;
569
+ if (mouseX > maxX || theme.rowHoverBackgroundColor == null) {
570
+ return;
571
+ }
572
+ var mouseRow = GridUtils.getRowAtY(mouseY, metrics);
573
+ if (mouseRow == null) {
574
+ return;
575
+ }
576
+ this.drawMouseRowHoverForRow(context, state, mouseRow);
577
+ }
578
+ drawFloatingMouseRowHover(context, state) {
579
+ var {
580
+ mouseX,
581
+ mouseY,
582
+ theme,
583
+ metrics
584
+ } = state;
585
+ var {
586
+ maxX,
587
+ floatingTopRowCount,
588
+ floatingBottomRowCount,
589
+ rowCount,
590
+ rowFooterWidth
591
+ } = metrics;
592
+ if (mouseX == null || mouseY == null || mouseX > maxX + rowFooterWidth || theme.rowHoverBackgroundColor == null) {
593
+ return;
594
+ }
595
+ var mouseRow = GridUtils.getRowAtY(mouseY, metrics);
596
+ if (mouseRow != null && (mouseRow < floatingTopRowCount || rowCount - floatingBottomRowCount <= mouseRow)) {
597
+ this.drawMouseRowHoverForRow(context, state, mouseRow);
598
+ }
599
+ }
600
+ drawMouseRowHoverForRow(context, state, row) {
601
+ var {
602
+ metrics,
603
+ selectedRanges,
604
+ theme
605
+ } = state;
606
+ var {
607
+ allRowHeights,
608
+ allRowYs,
609
+ maxX
610
+ } = metrics;
611
+ var y = getOrThrow(allRowYs, row);
612
+ var rowHeight = getOrThrow(allRowHeights, row);
613
+ if (theme.rowHoverBackgroundColor != null) {
614
+ context.fillStyle = theme.rowHoverBackgroundColor;
615
+ }
616
+ for (var i = 0; i < selectedRanges.length; i += 1) {
617
+ var {
618
+ startRow,
619
+ endRow
620
+ } = selectedRanges[i];
621
+ if (startRow != null && endRow != null && startRow <= row && endRow >= row) {
622
+ if (theme.selectedRowHoverBackgroundColor != null) {
623
+ context.fillStyle = theme.selectedRowHoverBackgroundColor;
624
+ }
625
+ break;
626
+ }
627
+ }
628
+ context.fillRect(0, y, maxX, rowHeight);
629
+ }
630
+ drawGridLines(context, state) {
631
+ var {
632
+ metrics,
633
+ theme
634
+ } = state;
635
+ var {
636
+ visibleColumns,
637
+ visibleRows
638
+ } = metrics;
639
+ this.drawGridLinesForItems(context, state, visibleColumns, visibleRows, theme.gridColumnColor, theme.gridRowColor);
640
+ }
641
+ drawGridLinesForItems(context, state, columns, rows, columnColor, rowColor) {
642
+ if (columnColor == null && rowColor == null) {
643
+ return;
644
+ }
645
+ context.lineWidth = 1;
646
+ context.beginPath();
647
+ if (columnColor != null) {
648
+ context.strokeStyle = columnColor;
649
+ this.drawGridLinesForColumns(context, state, columns);
650
+ }
651
+ if (rowColor != null) {
652
+ context.strokeStyle = rowColor;
653
+ this.drawGridLinesForRows(context, state, rows);
654
+ }
655
+ context.stroke();
656
+ }
657
+ drawGridLinesForColumns(context, state, columns) {
658
+ var {
659
+ metrics
660
+ } = state;
661
+ var {
662
+ allColumnXs,
663
+ maxY
664
+ } = metrics;
665
+ for (var i = 0; i < columns.length; i += 1) {
666
+ var column = columns[i];
667
+ var x = getOrThrow(allColumnXs, column) + 0.5;
668
+ context.moveTo(x, 0);
669
+ context.lineTo(x, maxY);
670
+ }
671
+ }
672
+ drawGridLinesForRows(context, state, rows) {
673
+ var {
674
+ metrics
675
+ } = state;
676
+ var {
677
+ allRowYs,
678
+ maxX: metricsMaxX
679
+ } = metrics;
680
+ var maxX = metricsMaxX;
681
+
682
+ // Draw row lines
683
+ for (var i = 0; i < rows.length; i += 1) {
684
+ var row = rows[i];
685
+ var y = getOrThrow(allRowYs, row) + 0.5;
686
+ context.moveTo(0.5, y);
687
+ context.lineTo(maxX - 0.5, y);
688
+ }
689
+ }
690
+ drawCellBackgrounds(context, state) {
691
+ var {
692
+ metrics
693
+ } = state;
694
+ var {
695
+ visibleColumns,
696
+ visibleRows
697
+ } = metrics;
698
+ this.drawCellBackgroundsForItems(context, state, visibleColumns, visibleRows);
699
+ }
700
+ drawCellBackgroundsForItems(context, state, columns, rows) {
701
+ context.save();
702
+ for (var i = 0; i < columns.length; i += 1) {
703
+ var column = columns[i];
704
+ for (var j = 0; j < rows.length; j += 1) {
705
+ var row = rows[j];
706
+ var rowAfter = j + 1 < rows.length ? rows[j + 1] : undefined;
707
+ this.drawCellBackground(context, state, column, row, rowAfter);
708
+ }
709
+ }
710
+ context.restore();
711
+ }
712
+ drawCellBackground(context, state, column, row, rowAfter) {
713
+ var {
714
+ metrics,
715
+ model,
716
+ theme
717
+ } = state;
718
+ var {
719
+ firstColumn,
720
+ modelColumns,
721
+ modelRows,
722
+ allColumnXs,
723
+ allColumnWidths,
724
+ allRowYs,
725
+ allRowHeights
726
+ } = metrics;
727
+ var modelRow = getOrThrow(modelRows, row);
728
+ var modelColumn = getOrThrow(modelColumns, column);
729
+ var backgroundColor = model.backgroundColorForCell(modelColumn, modelRow, theme);
730
+ var isFirstColumn = column === firstColumn;
731
+ var hasExpandableRows = isExpandableGridModel(model) && model.hasExpandableRows;
732
+ if (backgroundColor != null) {
733
+ var x = getOrThrow(allColumnXs, column) + 1;
734
+ var y = getOrThrow(allRowYs, row) + 1;
735
+ var columnWidth = getOrThrow(allColumnWidths, column) - 1;
736
+ var rowHeight = getOrThrow(allRowHeights, row) - 1;
737
+ context.fillStyle = backgroundColor;
738
+ context.fillRect(x, y, columnWidth, rowHeight);
739
+ }
740
+ if (isFirstColumn && hasExpandableRows) {
741
+ this.drawCellRowTreeDepthLines(context, state, row, rowAfter);
742
+ }
743
+ }
744
+ drawCellContents(context, state) {
745
+ var {
746
+ metrics
747
+ } = state;
748
+ var {
749
+ visibleColumns
750
+ } = metrics;
751
+ for (var i = 0; i < visibleColumns.length; i += 1) {
752
+ var column = visibleColumns[i];
753
+ this.drawColumnCellContents(context, state, column);
754
+ }
755
+ }
756
+ drawColumnCellContents(context, state, column) {
757
+ var {
758
+ metrics
759
+ } = state;
760
+ var {
761
+ allColumnXs,
762
+ allColumnWidths,
763
+ visibleRows,
764
+ height
765
+ } = metrics;
766
+ var x = getOrThrow(allColumnXs, column);
767
+ var columnWidth = getOrThrow(allColumnWidths, column);
768
+ context.save();
769
+ context.beginPath();
770
+ context.rect(x, 0, columnWidth, height);
771
+ context.clip();
772
+ for (var i = 0; i < visibleRows.length; i += 1) {
773
+ var row = visibleRows[i];
774
+ this.drawCellContent(context, state, column, row);
775
+ }
776
+ context.restore();
777
+ }
778
+ drawCellContent(context, state, column, row) {
779
+ var {
780
+ metrics,
781
+ model
782
+ } = state;
783
+ var {
784
+ modelColumns,
785
+ modelRows
786
+ } = metrics;
787
+ var modelRow = getOrThrow(modelRows, row);
788
+ var modelColumn = getOrThrow(modelColumns, column);
789
+ var renderType = model.renderTypeForCell(modelColumn, modelRow);
790
+ var cellRenderer = this.getCellRenderer(renderType);
791
+ cellRenderer.drawCellContent(context, state, column, row);
792
+ }
793
+ getCellRenderer(renderType) {
794
+ switch (renderType) {
795
+ case 'dataBar':
796
+ return this.dataBarCellRenderer;
797
+ default:
798
+ return this.textCellRenderer;
799
+ }
800
+ }
801
+ drawCellRowTreeDepthLines(context, state, row, rowAfter) {
802
+ var {
803
+ metrics,
804
+ model,
805
+ theme
806
+ } = state;
807
+ if (!isExpandableGridModel(model)) return;
808
+ var depth = model.depthForRow(row);
809
+ if (depth === 0) return;
810
+ var {
811
+ firstColumn,
812
+ allColumnXs,
813
+ allRowYs,
814
+ allRowHeights
815
+ } = metrics;
816
+ var {
817
+ treeDepthIndent,
818
+ treeHorizontalPadding,
819
+ treeLineColor
820
+ } = theme;
821
+ var columnX = getOrThrow(allColumnXs, firstColumn);
822
+ var rowY = getOrThrow(allRowYs, row);
823
+ var rowHeight = getOrThrow(allRowHeights, row);
824
+ var depthRowAfter = rowAfter !== undefined ? model.depthForRow(rowAfter) : 0;
825
+ var depthDiff = depth > depthRowAfter ? depth - depthRowAfter : 0;
826
+ context.strokeStyle = treeLineColor;
827
+ context.lineWidth = 1;
828
+
829
+ // draw normal depth lines
830
+ if (depth - depthDiff > 0) {
831
+ context.beginPath();
832
+ for (var i = 0; i < depth - depthDiff; i += 1) {
833
+ var lineX = columnX + i * treeDepthIndent + treeDepthIndent * 0.5 + treeHorizontalPadding + 0.5;
834
+ context.moveTo(lineX, rowY);
835
+ context.lineTo(lineX, rowY + rowHeight);
836
+ }
837
+ context.stroke();
838
+ }
839
+
840
+ // draw as hockey stick if last row at depth
841
+ if (depthDiff > 0) {
842
+ context.beginPath();
843
+ for (var _i4 = depth - depthDiff; _i4 < depth; _i4 += 1) {
844
+ var _lineX = columnX + _i4 * treeDepthIndent + treeDepthIndent * 0.5 + treeHorizontalPadding + 0.5;
845
+ context.moveTo(_lineX, rowY);
846
+ context.lineTo(_lineX, rowY + Math.ceil(rowHeight / 2));
847
+ // extra moveTo prevents halfpixel in corner
848
+ context.moveTo(_lineX - 0.5, rowY + Math.ceil(rowHeight / 2) + 0.5);
849
+ context.lineTo(_lineX + treeDepthIndent - 0.5, rowY + Math.ceil(rowHeight / 2) + 0.5);
850
+ }
851
+ context.stroke();
852
+ }
853
+ }
854
+ drawHeaders(context, state) {
855
+ var {
856
+ theme
857
+ } = state;
858
+ context.font = theme.headerFont;
859
+ this.drawColumnHeaders(context, state);
860
+ this.drawRowHeaders(context, state);
861
+ }
862
+ drawFooters(context, state) {
863
+ var {
864
+ theme
865
+ } = state;
866
+ context.font = theme.headerFont;
867
+ this.drawRowFooters(context, state);
868
+ }
869
+ drawColumnHeaders(context, state) {
870
+ var {
871
+ mouseX,
872
+ mouseY,
873
+ theme,
874
+ metrics,
875
+ draggingColumnSeparator,
876
+ isDragging,
877
+ model
878
+ } = state;
879
+ var {
880
+ columnHeaderHeight,
881
+ floatingColumns,
882
+ gridX,
883
+ width,
884
+ visibleColumns,
885
+ allColumnWidths,
886
+ allColumnXs,
887
+ floatingLeftColumnCount,
888
+ floatingLeftWidth,
889
+ floatingRightWidth,
890
+ modelColumns,
891
+ columnHeaderMaxDepth
892
+ } = metrics;
893
+ if (columnHeaderHeight <= 0) {
894
+ return;
895
+ }
896
+ var {
897
+ headerHiddenSeparatorSize,
898
+ headerHiddenSeparatorHoverColor,
899
+ headerSeparatorColor,
900
+ headerSeparatorHoverColor
901
+ } = theme;
902
+ var hiddenSeparatorHeight = columnHeaderHeight * 0.5;
903
+ var hiddenY = columnHeaderHeight * (columnHeaderMaxDepth - 1) + columnHeaderHeight * 0.5 - hiddenSeparatorHeight * 0.5;
904
+ var containsFrozenColumns = floatingLeftColumnCount > 0;
905
+ context.save();
906
+ this.drawColumnHeadersForRange(context, state, [visibleColumns[0], visibleColumns[visibleColumns.length - 1]], {
907
+ minX: gridX + floatingLeftWidth,
908
+ maxX: width - floatingRightWidth
909
+ });
910
+ if (containsFrozenColumns) {
911
+ this.drawColumnHeadersForRange(context, state, [floatingColumns[0], floatingColumns[floatingColumns.length - 1]], {
912
+ minX: gridX,
913
+ maxX: gridX + floatingLeftWidth
914
+ });
915
+ }
916
+ if (headerSeparatorColor) {
917
+ context.strokeStyle = headerSeparatorColor;
918
+ var hiddenColumns = [...allColumnWidths.entries()].filter(_ref => {
919
+ var [_, w] = _ref;
920
+ return w === 0;
921
+ }).map(_ref2 => {
922
+ var [index] = _ref2;
923
+ return index;
924
+ });
925
+
926
+ // Now draw the hidden column separator boxes
927
+ context.beginPath();
928
+ context.fillStyle = headerSeparatorColor;
929
+ for (var i = 0; i < hiddenColumns.length; i += 1) {
930
+ var column = hiddenColumns[i];
931
+ var columnX = getOrThrow(allColumnXs, column);
932
+ var columnWidth = getOrThrow(allColumnWidths, column);
933
+ var minX = gridX + columnX + columnWidth + 0.5 - headerHiddenSeparatorSize * 0.5;
934
+ context.rect(minX, hiddenY, headerHiddenSeparatorSize, hiddenSeparatorHeight);
935
+ }
936
+ context.fill();
937
+ }
938
+ if (headerSeparatorHoverColor) {
939
+ var {
940
+ index: highlightedSeparator,
941
+ depth
942
+ } = draggingColumnSeparator !== null && draggingColumnSeparator !== void 0 ? draggingColumnSeparator : {};
943
+ if (highlightedSeparator == null && mouseX != null && mouseY != null) {
944
+ var separator = GridColumnSeparatorMouseHandler.getColumnSeparator(GridUtils.getGridPointFromXY(mouseX, mouseY, metrics), metrics, model, theme);
945
+ highlightedSeparator = separator === null || separator === void 0 ? void 0 : separator.index;
946
+ depth = separator === null || separator === void 0 ? void 0 : separator.depth;
947
+ }
948
+ var shouldDrawSeparator;
949
+ if (highlightedSeparator == null) {
950
+ shouldDrawSeparator = false;
951
+ } else {
952
+ var columnIndex = modelColumns.get(highlightedSeparator);
953
+ var nextColumnIndex = modelColumns.get(highlightedSeparator + 1);
954
+ if (columnIndex == null || nextColumnIndex == null) {
955
+ shouldDrawSeparator = false;
956
+ } else {
957
+ shouldDrawSeparator = model.textForColumnHeader(columnIndex, depth) !== model.textForColumnHeader(nextColumnIndex, depth);
958
+ }
959
+ }
960
+ if (shouldDrawSeparator && highlightedSeparator != null && depth != null && (!isDragging || draggingColumnSeparator != null)) {
961
+ context.strokeStyle = headerSeparatorHoverColor;
962
+ var _columnX = getOrThrow(allColumnXs, highlightedSeparator);
963
+ var _columnWidth = getOrThrow(allColumnWidths, highlightedSeparator);
964
+ var x = gridX + _columnX + _columnWidth + 0.5;
965
+ var visibleColumnIndex = visibleColumns.indexOf(highlightedSeparator);
966
+ var nextColumn = visibleColumnIndex < visibleColumns.length - 1 ? visibleColumns[visibleColumnIndex + 1] : null;
967
+ var nextColumnWidth = nextColumn != null ? allColumnWidths.get(nextColumn) : null;
968
+ var isColumnHidden = _columnWidth === 0;
969
+ var isNextColumnHidden = nextColumnWidth != null && nextColumnWidth === 0;
970
+ if (isColumnHidden) {
971
+ context.strokeStyle = headerHiddenSeparatorHoverColor;
972
+ context.fillStyle = headerHiddenSeparatorHoverColor;
973
+ context.fillRect(x, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
974
+ } else if (isNextColumnHidden) {
975
+ context.fillStyle = headerSeparatorHoverColor;
976
+ context.fillRect(x - headerHiddenSeparatorSize * 0.5, hiddenY, headerHiddenSeparatorSize * 0.5, hiddenSeparatorHeight);
977
+ }
978
+
979
+ // column seperator hover line
980
+ context.beginPath();
981
+ context.moveTo(x, (columnHeaderMaxDepth - depth - 1) * columnHeaderHeight);
982
+ context.lineTo(x, (columnHeaderMaxDepth - depth) * columnHeaderHeight - 1);
983
+ context.stroke();
984
+ }
985
+ }
986
+ context.restore();
987
+ }
988
+ drawColumnHeadersForRange(context, state, range, bounds) {
989
+ var {
990
+ model
991
+ } = state;
992
+ var {
993
+ columnHeaderMaxDepth
994
+ } = model;
995
+ if (columnHeaderMaxDepth === 0) {
996
+ return;
997
+ }
998
+ for (var d = 0; d <= columnHeaderMaxDepth; d += 1) {
999
+ this.drawColumnHeadersAtDepth(context, state, range, bounds, d);
1000
+ }
1001
+ }
1002
+ drawColumnHeadersAtDepth(context, state, range, bounds, depth) {
1003
+ var {
1004
+ metrics,
1005
+ model,
1006
+ theme
1007
+ } = state;
1008
+ var {
1009
+ modelColumns,
1010
+ allColumnXs,
1011
+ gridX,
1012
+ userColumnWidths,
1013
+ allColumnWidths,
1014
+ movedColumns
1015
+ } = metrics;
1016
+ var {
1017
+ columnHeaderHeight,
1018
+ columnWidth
1019
+ } = theme;
1020
+ var {
1021
+ columnHeaderMaxDepth
1022
+ } = model;
1023
+ var {
1024
+ minX,
1025
+ maxX
1026
+ } = bounds;
1027
+ var visibleWidth = maxX - minX;
1028
+ if (columnHeaderMaxDepth === 0) {
1029
+ return;
1030
+ }
1031
+ var startIndex = range[0];
1032
+ var endIndex = range[1];
1033
+ context.save();
1034
+ context.translate(0, (columnHeaderMaxDepth - depth - 1) * columnHeaderHeight);
1035
+ if (depth === 0) {
1036
+ // Make sure base column header background always goes to the right edge
1037
+ this.drawColumnHeader(context, state, '', minX, maxX);
1038
+
1039
+ // Draw base column headers
1040
+ for (var i = startIndex; i <= endIndex; i += 1) {
1041
+ this.drawColumnHeaderAtIndex(context, state, i, bounds);
1042
+ }
1043
+ }
1044
+
1045
+ // Draw column header group
1046
+ if (depth > 0) {
1047
+ var columnIndex = startIndex;
1048
+ while (columnIndex <= endIndex) {
1049
+ var {
1050
+ columnCount
1051
+ } = metrics;
1052
+ var modelColumn = getOrThrow(modelColumns, columnIndex);
1053
+ var columnGroupName = model.textForColumnHeader(modelColumn, depth);
1054
+ var columnGroupColor = model.colorForColumnHeader(modelColumn, depth);
1055
+ var columnGroupLeft = getOrThrow(allColumnXs, columnIndex) + gridX;
1056
+ var columnGroupRight = columnGroupLeft + getOrThrow(allColumnWidths, columnIndex);
1057
+ if (columnGroupName != null) {
1058
+ // Need to determine if the column group is at least the width of the bounds
1059
+ // And if the left/right of the group extend past the bounds
1060
+ // The group will be drawn as if it were a column with a max width of the bounds width
1061
+ var prevColumnIndex = columnIndex - 1;
1062
+ while (prevColumnIndex >= 0 && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupLeft > minX)) {
1063
+ var _modelColumns$get, _ref3, _userColumnWidths$get;
1064
+ var prevModelIndex = (_modelColumns$get = modelColumns.get(prevColumnIndex)) !== null && _modelColumns$get !== void 0 ? _modelColumns$get : GridUtils.getModelIndex(prevColumnIndex, movedColumns);
1065
+ if (prevModelIndex == null || model.textForColumnHeader(prevModelIndex, depth) !== columnGroupName) {
1066
+ // Previous column not in the same group
1067
+ break;
1068
+ }
1069
+ var prevColumnWidth = (_ref3 = (_userColumnWidths$get = userColumnWidths.get(prevModelIndex)) !== null && _userColumnWidths$get !== void 0 ? _userColumnWidths$get : allColumnWidths.get(prevColumnIndex)) !== null && _ref3 !== void 0 ? _ref3 : columnWidth;
1070
+ columnGroupLeft -= prevColumnWidth;
1071
+ prevColumnIndex -= 1;
1072
+ }
1073
+ var nextColumnIndex = columnIndex + 1;
1074
+ while (nextColumnIndex < columnCount && (columnGroupRight - columnGroupLeft < visibleWidth || columnGroupRight < maxX)) {
1075
+ var _modelColumns$get2, _ref4, _userColumnWidths$get2;
1076
+ var nextModelIndex = (_modelColumns$get2 = modelColumns.get(nextColumnIndex)) !== null && _modelColumns$get2 !== void 0 ? _modelColumns$get2 : GridUtils.getModelIndex(nextColumnIndex, movedColumns);
1077
+ if (model.textForColumnHeader(nextModelIndex, depth) !== columnGroupName) {
1078
+ // Next column not in the same group
1079
+ break;
1080
+ }
1081
+ var nextColumnWidth = (_ref4 = (_userColumnWidths$get2 = userColumnWidths.get(nextModelIndex)) !== null && _userColumnWidths$get2 !== void 0 ? _userColumnWidths$get2 : allColumnWidths.get(nextColumnIndex)) !== null && _ref4 !== void 0 ? _ref4 : columnWidth;
1082
+ columnGroupRight += nextColumnWidth;
1083
+ nextColumnIndex += 1;
1084
+ }
1085
+
1086
+ // Set column index to end of the current group
1087
+ columnIndex = nextColumnIndex - 1;
1088
+ var isFullWidth = columnGroupRight - columnGroupLeft >= visibleWidth;
1089
+ var x = columnGroupLeft;
1090
+ if (isFullWidth) {
1091
+ if (columnGroupRight < maxX) {
1092
+ x = columnGroupRight - visibleWidth;
1093
+ } else if (columnGroupLeft < minX) {
1094
+ x = minX;
1095
+ }
1096
+ }
1097
+ this.drawColumnHeader(context, state, columnGroupName, x, Math.min(columnGroupRight - columnGroupLeft, visibleWidth), {
1098
+ backgroundColor: columnGroupColor !== null && columnGroupColor !== void 0 ? columnGroupColor : undefined
1099
+ }, bounds);
1100
+ }
1101
+ columnIndex += 1;
1102
+ }
1103
+ }
1104
+ context.restore();
1105
+ }
1106
+
1107
+ /**
1108
+ * Draws the column header for the given visible index
1109
+ * @param context Canvas context
1110
+ * @param state Grid render state
1111
+ * @param index Visible index of the column header to draw
1112
+ * @param bounds The horizontal bounds the header can be drawn in
1113
+ */
1114
+ drawColumnHeaderAtIndex(context, state, index, bounds) {
1115
+ var _model$colorForColumn;
1116
+ var {
1117
+ metrics,
1118
+ model
1119
+ } = state;
1120
+ var {
1121
+ modelColumns,
1122
+ allColumnWidths,
1123
+ allColumnXs,
1124
+ gridX
1125
+ } = metrics;
1126
+ var width = getOrThrow(allColumnWidths, index);
1127
+ var x = getOrThrow(allColumnXs, index) + gridX;
1128
+ var modelColumn = getOrThrow(modelColumns, index);
1129
+ var text = model.textForColumnHeader(modelColumn);
1130
+ if (text == null) {
1131
+ return;
1132
+ }
1133
+ this.drawColumnHeader(context, state, text, x, width, {
1134
+ backgroundColor: (_model$colorForColumn = model.colorForColumnHeader(modelColumn)) !== null && _model$colorForColumn !== void 0 ? _model$colorForColumn : undefined
1135
+ }, bounds);
1136
+ }
1137
+ drawColumnHeader(context, state, columnText, columnX, columnWidth, style, bounds) {
1138
+ var _fontWidths$get;
1139
+ if (columnWidth <= 0) {
1140
+ return;
1141
+ }
1142
+ var {
1143
+ metrics,
1144
+ theme
1145
+ } = state;
1146
+ var {
1147
+ headerHorizontalPadding,
1148
+ columnHeaderHeight,
1149
+ headerBackgroundColor,
1150
+ headerColor,
1151
+ headerSeparatorColor,
1152
+ black,
1153
+ white
1154
+ } = theme;
1155
+ var {
1156
+ fontWidths,
1157
+ width
1158
+ } = metrics;
1159
+ var fontWidth = (_fontWidths$get = fontWidths.get(context.font)) !== null && _fontWidths$get !== void 0 ? _fontWidths$get : DEFAULT_FONT_WIDTH;
1160
+ var maxWidth = columnWidth - headerHorizontalPadding * 2;
1161
+ var maxLength = maxWidth / fontWidth;
1162
+ var {
1163
+ backgroundColor = headerBackgroundColor,
1164
+ separatorColor = headerSeparatorColor
1165
+ } = style !== null && style !== void 0 ? style : {};
1166
+ var {
1167
+ textColor = headerColor
1168
+ } = style !== null && style !== void 0 ? style : {};
1169
+ try {
1170
+ var isDarkBackground = this.getCachedColorIsDark(backgroundColor);
1171
+ var isDarkText = this.getCachedColorIsDark(textColor);
1172
+ if (isDarkBackground && isDarkText) {
1173
+ textColor = white;
1174
+ } else if (!isDarkBackground && !isDarkText) {
1175
+ textColor = black;
1176
+ }
1177
+ } catch (_unused) {
1178
+ // Invalid color provided
1179
+ // no-op since we don't use logging in base grid
1180
+ }
1181
+ var {
1182
+ minX = 0,
1183
+ maxX = width
1184
+ } = bounds !== null && bounds !== void 0 ? bounds : {};
1185
+ context.save();
1186
+ context.rect(minX, 0, maxX - minX, columnHeaderHeight);
1187
+ context.clip();
1188
+
1189
+ // Fill background color if specified
1190
+ if (backgroundColor != null) {
1191
+ context.fillStyle = backgroundColor;
1192
+ context.fillRect(columnX, 0, columnWidth, columnHeaderHeight);
1193
+ }
1194
+ if (separatorColor != null) {
1195
+ context.strokeStyle = separatorColor;
1196
+ context.beginPath();
1197
+
1198
+ // Don't draw left separator if column touches the left edge
1199
+ if (columnX > 0) {
1200
+ context.moveTo(columnX + 0.5, 0);
1201
+ context.lineTo(columnX + 0.5, columnHeaderHeight);
1202
+ }
1203
+ context.moveTo(columnX + columnWidth + 0.5, 0);
1204
+ context.lineTo(columnX + columnWidth + 0.5, columnHeaderHeight);
1205
+
1206
+ // Bottom Border, should be interior to the header height
1207
+ context.moveTo(columnX, columnHeaderHeight - 0.5);
1208
+ context.lineTo(columnX + columnWidth, columnHeaderHeight - 0.5);
1209
+ context.stroke();
1210
+ }
1211
+ context.beginPath();
1212
+ context.rect(columnX, 0, columnWidth, columnHeaderHeight);
1213
+ context.clip();
1214
+ context.fillStyle = textColor;
1215
+ var renderText = columnText;
1216
+ if (maxLength <= 0) {
1217
+ renderText = '';
1218
+ } else if (renderText.length > maxLength) {
1219
+ renderText = "".concat(renderText.substring(0, maxLength - 1), "\u2026");
1220
+ }
1221
+ var textWidth = renderText.length * fontWidth;
1222
+ var x = columnX + columnWidth * 0.5;
1223
+ var y = columnHeaderHeight * 0.5;
1224
+ minX += headerHorizontalPadding;
1225
+ maxX -= headerHorizontalPadding;
1226
+ var columnLeft = columnX + headerHorizontalPadding;
1227
+ var visibleLeft = clamp(columnLeft, minX, maxX);
1228
+ var columnRight = columnX + columnWidth - headerHorizontalPadding;
1229
+ var visibleRight = clamp(columnRight, minX, maxX);
1230
+ var visibleWidth = visibleRight - visibleLeft;
1231
+ var isBeyondLeft = x - textWidth * 0.5 < minX;
1232
+ var isBeyondRight = x + textWidth * 0.5 > maxX;
1233
+ if (isBeyondLeft) {
1234
+ // Column name would be off the left side of the canvas
1235
+ if (textWidth < visibleWidth) {
1236
+ // Can render the entire text in the visible space. Stick to left
1237
+ x = minX + textWidth * 0.5;
1238
+ } else {
1239
+ x = columnRight - textWidth * 0.5;
1240
+ }
1241
+ } else if (isBeyondRight) {
1242
+ if (textWidth < visibleWidth) {
1243
+ // Can render the entire text in the visible space. Stick to right
1244
+ x = maxX - textWidth * 0.5;
1245
+ } else {
1246
+ x = columnLeft + textWidth * 0.5;
1247
+ }
1248
+ }
1249
+ context.textAlign = 'center';
1250
+ context.fillText(renderText, x, y);
1251
+ context.restore();
1252
+ }
1253
+ drawRowHeaders(context, state) {
1254
+ var {
1255
+ mouseX,
1256
+ mouseY,
1257
+ metrics,
1258
+ theme,
1259
+ draggingRowSeparator
1260
+ } = state;
1261
+ var {
1262
+ gridY,
1263
+ rowHeaderWidth,
1264
+ height,
1265
+ visibleRows,
1266
+ allRowHeights,
1267
+ allRowYs
1268
+ } = metrics;
1269
+ if (rowHeaderWidth <= 0) {
1270
+ return;
1271
+ }
1272
+ var {
1273
+ headerBackgroundColor,
1274
+ headerColor,
1275
+ headerHiddenSeparatorSize,
1276
+ headerHiddenSeparatorHoverColor,
1277
+ headerSeparatorColor,
1278
+ headerSeparatorHoverColor
1279
+ } = theme;
1280
+ var hiddenSeparatorWidth = rowHeaderWidth * 0.5;
1281
+ var hiddenX = rowHeaderWidth * 0.5 - hiddenSeparatorWidth * 0.5;
1282
+ context.save();
1283
+ context.beginPath();
1284
+
1285
+ // Fill in the background
1286
+ context.fillStyle = headerBackgroundColor;
1287
+ context.fillRect(0, 0, rowHeaderWidth, height);
1288
+
1289
+ // Draw the separators
1290
+ if (headerSeparatorColor) {
1291
+ context.strokeStyle = headerSeparatorColor;
1292
+ context.beginPath();
1293
+ context.moveTo(0, gridY + 0.5);
1294
+ context.lineTo(rowHeaderWidth, gridY + 0.5);
1295
+ var hiddenRows = [];
1296
+ var isPreviousRowHidden = false;
1297
+ for (var i = 0; i < visibleRows.length; i += 1) {
1298
+ var row = visibleRows[i];
1299
+ var rowY = getOrThrow(allRowYs, row);
1300
+ var rowHeight = getOrThrow(allRowHeights, row);
1301
+ if (rowHeight > 0) {
1302
+ var y = gridY + rowY + rowHeight + 0.5;
1303
+ context.moveTo(0, y);
1304
+ context.lineTo(rowHeaderWidth, y);
1305
+ isPreviousRowHidden = false;
1306
+ } else if (!isPreviousRowHidden) {
1307
+ isPreviousRowHidden = true;
1308
+ hiddenRows.push(row);
1309
+ }
1310
+ }
1311
+
1312
+ // border right, interior to the headerWidth
1313
+ context.moveTo(rowHeaderWidth - 0.5, 0);
1314
+ context.lineTo(rowHeaderWidth - 0.5, height);
1315
+ context.stroke();
1316
+
1317
+ // Draw the hidden column separators
1318
+ context.beginPath();
1319
+ context.fillStyle = headerSeparatorColor;
1320
+ for (var _i5 = 0; _i5 < hiddenRows.length; _i5 += 1) {
1321
+ var _row4 = hiddenRows[_i5];
1322
+ var _rowY = getOrThrow(allRowYs, _row4);
1323
+ var _rowHeight = getOrThrow(allRowHeights, _row4);
1324
+ var minY = gridY + _rowY + _rowHeight + 0.5 - headerHiddenSeparatorSize * 0.5;
1325
+ context.rect(hiddenX, minY, hiddenSeparatorWidth, headerHiddenSeparatorSize);
1326
+ }
1327
+ context.fill();
1328
+ }
1329
+ if (headerSeparatorHoverColor) {
1330
+ var {
1331
+ index: highlightedSeparator = null
1332
+ } = draggingRowSeparator !== null && draggingRowSeparator !== void 0 ? draggingRowSeparator : {};
1333
+ if (highlightedSeparator == null && mouseX != null && mouseY != null) {
1334
+ highlightedSeparator = GridUtils.getRowSeparatorIndex(mouseX, mouseY, metrics, theme);
1335
+ }
1336
+ if (highlightedSeparator != null) {
1337
+ context.strokeStyle = headerSeparatorHoverColor;
1338
+ var _rowY2 = getOrThrow(allRowYs, highlightedSeparator);
1339
+ var _rowHeight2 = getOrThrow(allRowHeights, highlightedSeparator);
1340
+ var _y5 = gridY + _rowY2 + _rowHeight2 + 0.5;
1341
+ var visibleRowIndex = visibleRows.indexOf(highlightedSeparator);
1342
+ var nextRow = visibleRowIndex < visibleRows.length - 1 ? visibleRows[visibleRowIndex + 1] : null;
1343
+ var nextRowHeight = nextRow != null ? allRowHeights.get(nextRow) : null;
1344
+ var isRowHidden = _rowHeight2 === 0;
1345
+ var isNextRowHidden = nextRowHeight != null && nextRowHeight === 0;
1346
+ if (isRowHidden) {
1347
+ context.strokeStyle = headerHiddenSeparatorHoverColor;
1348
+ context.fillStyle = headerHiddenSeparatorHoverColor;
1349
+ context.fillRect(hiddenX, _y5, hiddenSeparatorWidth, headerHiddenSeparatorSize * 0.5);
1350
+ } else if (isNextRowHidden) {
1351
+ context.fillStyle = headerSeparatorHoverColor;
1352
+ context.fillRect(hiddenX, _y5 - headerHiddenSeparatorSize * 0.5, hiddenSeparatorWidth, headerHiddenSeparatorSize * 0.5);
1353
+ }
1354
+ context.beginPath();
1355
+ context.moveTo(0.5, _y5);
1356
+ context.lineTo(rowHeaderWidth + 0.5, _y5);
1357
+ context.stroke();
1358
+ }
1359
+ }
1360
+
1361
+ // Fill in the text
1362
+ context.beginPath();
1363
+ context.rect(0, gridY, rowHeaderWidth, height);
1364
+ context.clip();
1365
+ context.fillStyle = headerColor;
1366
+ context.textAlign = 'right';
1367
+ for (var _i6 = 0; _i6 < visibleRows.length; _i6 += 1) {
1368
+ var _row5 = visibleRows[_i6];
1369
+ var _rowHeight3 = getOrThrow(allRowHeights, _row5);
1370
+ var _y6 = getOrThrow(allRowYs, _row5) + gridY;
1371
+ this.drawRowHeader(context, state, _row5, _y6, _rowHeight3);
1372
+ }
1373
+ context.restore();
1374
+ }
1375
+ drawRowHeader(context, state, row, rowY, rowHeight) {
1376
+ if (rowHeight <= 0) {
1377
+ return;
1378
+ }
1379
+ var {
1380
+ metrics,
1381
+ model,
1382
+ theme
1383
+ } = state;
1384
+ var {
1385
+ modelRows,
1386
+ rowHeaderWidth
1387
+ } = metrics;
1388
+ var modelRow = getOrThrow(modelRows, row);
1389
+ var x = rowHeaderWidth - theme.cellHorizontalPadding;
1390
+ var y = rowY + rowHeight * 0.5;
1391
+ context.fillText(model.textForRowHeader(modelRow), x, y);
1392
+ }
1393
+ drawRowFooters(context, state) {
1394
+ var {
1395
+ mouseX,
1396
+ mouseY,
1397
+ metrics,
1398
+ model,
1399
+ theme,
1400
+ draggingRowSeparator
1401
+ } = state;
1402
+ var {
1403
+ gridY,
1404
+ gridX,
1405
+ maxX,
1406
+ modelRows,
1407
+ rowFooterWidth,
1408
+ height,
1409
+ verticalBarWidth,
1410
+ visibleRows,
1411
+ allRowHeights,
1412
+ allRowYs,
1413
+ width
1414
+ } = metrics;
1415
+ if (rowFooterWidth <= 0) {
1416
+ return;
1417
+ }
1418
+ var {
1419
+ cellHorizontalPadding,
1420
+ headerBackgroundColor,
1421
+ headerColor,
1422
+ headerHiddenSeparatorSize,
1423
+ headerHiddenSeparatorHoverColor,
1424
+ headerSeparatorColor,
1425
+ headerSeparatorHoverColor
1426
+ } = theme;
1427
+ var hiddenSeparatorWidth = rowFooterWidth * 0.5;
1428
+ var hiddenX = rowFooterWidth * 0.5 - hiddenSeparatorWidth * 0.5;
1429
+ var x = Math.min(gridX + maxX, width - rowFooterWidth - verticalBarWidth);
1430
+ context.save();
1431
+ context.beginPath();
1432
+
1433
+ // Fill in the background
1434
+ context.fillStyle = headerBackgroundColor;
1435
+ context.fillRect(x, gridY, rowFooterWidth, height);
1436
+
1437
+ // Draw the separators
1438
+ if (headerSeparatorColor) {
1439
+ context.strokeStyle = headerSeparatorColor;
1440
+ context.beginPath();
1441
+ context.moveTo(x, gridY + 0.5);
1442
+ context.lineTo(rowFooterWidth, gridY + 0.5);
1443
+ var hiddenRows = [];
1444
+ var isPreviousRowHidden = false;
1445
+ for (var i = 0; i < visibleRows.length; i += 1) {
1446
+ var row = visibleRows[i];
1447
+ var rowY = getOrThrow(allRowYs, row);
1448
+ var rowHeight = getOrThrow(allRowHeights, row);
1449
+ if (rowHeight > 0) {
1450
+ var y = gridY + rowY + rowHeight + 0.5;
1451
+ context.moveTo(x + 0.5, y);
1452
+ context.lineTo(x + rowFooterWidth - 0.5, y);
1453
+ isPreviousRowHidden = false;
1454
+ } else if (!isPreviousRowHidden) {
1455
+ isPreviousRowHidden = true;
1456
+ hiddenRows.push(row);
1457
+ }
1458
+ }
1459
+
1460
+ // border left, interior to the headerWidth
1461
+ context.moveTo(x + 0.5, gridY);
1462
+ context.lineTo(x + 0.5, height);
1463
+ context.stroke();
1464
+
1465
+ // Draw the hidden column separators
1466
+ context.beginPath();
1467
+ context.fillStyle = headerSeparatorColor;
1468
+ for (var _i7 = 0; _i7 < hiddenRows.length; _i7 += 1) {
1469
+ var _row6 = hiddenRows[_i7];
1470
+ var _rowY3 = getOrThrow(allRowYs, _row6);
1471
+ var _rowHeight4 = getOrThrow(allRowHeights, _row6);
1472
+ var minY = gridY + _rowY3 + _rowHeight4 + 0.5 - headerHiddenSeparatorSize * 0.5;
1473
+ context.rect(x + hiddenX, minY, hiddenSeparatorWidth, headerHiddenSeparatorSize);
1474
+ }
1475
+ context.fill();
1476
+ }
1477
+ if (headerSeparatorHoverColor) {
1478
+ var {
1479
+ index: highlightedSeparator = null
1480
+ } = draggingRowSeparator !== null && draggingRowSeparator !== void 0 ? draggingRowSeparator : {};
1481
+ if (highlightedSeparator == null && mouseX != null && mouseY != null) {
1482
+ highlightedSeparator = GridUtils.getRowSeparatorIndex(mouseX, mouseY, metrics, theme);
1483
+ }
1484
+ if (highlightedSeparator != null) {
1485
+ context.strokeStyle = headerSeparatorHoverColor;
1486
+ var _rowY4 = getOrThrow(allRowYs, highlightedSeparator);
1487
+ var _rowHeight5 = getOrThrow(allRowHeights, highlightedSeparator);
1488
+ var _y7 = gridY + _rowY4 + _rowHeight5 + 0.5;
1489
+ var visibleRowIndex = visibleRows.indexOf(highlightedSeparator);
1490
+ var nextRow = visibleRowIndex < visibleRows.length - 1 ? visibleRows[visibleRowIndex + 1] : null;
1491
+ var nextRowHeight = nextRow != null ? allRowHeights.get(nextRow) : null;
1492
+ var isRowHidden = _rowHeight5 === 0;
1493
+ var isNextRowHidden = nextRowHeight != null && nextRowHeight === 0;
1494
+ if (isRowHidden) {
1495
+ context.strokeStyle = headerHiddenSeparatorHoverColor;
1496
+ context.fillStyle = headerHiddenSeparatorHoverColor;
1497
+ context.fillRect(hiddenX, _y7, hiddenSeparatorWidth, headerHiddenSeparatorSize * 0.5);
1498
+ } else if (isNextRowHidden) {
1499
+ context.fillStyle = headerSeparatorHoverColor;
1500
+ context.fillRect(hiddenX, _y7 - headerHiddenSeparatorSize * 0.5, hiddenSeparatorWidth, headerHiddenSeparatorSize * 0.5);
1501
+ }
1502
+ context.beginPath();
1503
+ context.moveTo(x + 0.5, _y7);
1504
+ context.lineTo(x + rowFooterWidth + 0.5, _y7);
1505
+ context.stroke();
1506
+ }
1507
+ }
1508
+
1509
+ // Fill in the text
1510
+ context.beginPath();
1511
+ context.rect(x, gridY, rowFooterWidth, height);
1512
+ context.clip();
1513
+ context.fillStyle = headerColor;
1514
+ context.textAlign = 'left';
1515
+ var textX = x + cellHorizontalPadding;
1516
+ for (var _i8 = 0; _i8 < visibleRows.length; _i8 += 1) {
1517
+ var _row7 = visibleRows[_i8];
1518
+ var _rowHeight6 = getOrThrow(allRowHeights, _row7);
1519
+ if (_rowHeight6 > 0) {
1520
+ var _rowY5 = getOrThrow(allRowYs, _row7) + gridY;
1521
+ var modelRow = getOrThrow(modelRows, _row7);
1522
+ var textY = _rowY5 + _rowHeight6 * 0.5;
1523
+ context.fillText(model.textForRowFooter(modelRow), textX, textY);
1524
+ }
1525
+ }
1526
+ context.restore();
1527
+ }
1528
+ drawSelectedRanges(context, state) {
1529
+ var viewport = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
1530
+ var {
1531
+ cursorColumn: column,
1532
+ cursorRow: row,
1533
+ draggingRow,
1534
+ draggingColumn,
1535
+ editingCell,
1536
+ metrics,
1537
+ model,
1538
+ selectedRanges,
1539
+ theme
1540
+ } = state;
1541
+ var {
1542
+ allColumnWidths,
1543
+ allColumnXs,
1544
+ allRowHeights,
1545
+ allRowYs,
1546
+ width,
1547
+ height
1548
+ } = metrics;
1549
+ var {
1550
+ left = metrics.left,
1551
+ top = metrics.top,
1552
+ right = metrics.right,
1553
+ bottom = metrics.bottom,
1554
+ minY = -10,
1555
+ maxY = height + 10,
1556
+ minX = -10,
1557
+ maxX = width + 10
1558
+ } = viewport;
1559
+ if (selectedRanges.length === 0) {
1560
+ return;
1561
+ }
1562
+ var isCursorVisible = isEditableGridModel(model) && model.isEditable && editingCell == null && draggingRow == null && draggingColumn == null && column != null && row != null && allColumnXs.has(column) && allRowYs.has(row);
1563
+ if (isCursorVisible) {
1564
+ // Punch a hole out where the active cell is, it gets styled differently.
1565
+ var x = getOrThrow(allColumnXs, column);
1566
+ var y = getOrThrow(allRowYs, row);
1567
+ var w = getOrThrow(allColumnWidths, column);
1568
+ var h = getOrThrow(allRowHeights, row);
1569
+ context.save();
1570
+ context.beginPath();
1571
+ context.rect(0, 0, width, height);
1572
+ context.rect(x, y, w, h);
1573
+ context.clip('evenodd');
1574
+ }
1575
+
1576
+ // Draw selection ranges
1577
+ context.beginPath();
1578
+ for (var i = 0; i < selectedRanges.length; i += 1) {
1579
+ var selectedRange = selectedRanges[i];
1580
+ var startColumn = selectedRange.startColumn !== null ? selectedRange.startColumn : left;
1581
+ var startRow = selectedRange.startRow !== null ? selectedRange.startRow : top;
1582
+ var endColumn = selectedRange.endColumn !== null ? selectedRange.endColumn : right;
1583
+ var endRow = selectedRange.endRow !== null ? selectedRange.endRow : bottom;
1584
+ if (endRow >= top && bottom >= startRow && endColumn >= left && right >= startColumn) {
1585
+ // Need to offset the x/y coordinates so that the line draws nice and crisp
1586
+ var _x4 = startColumn >= left && allColumnXs.has(startColumn) ? Math.round(getOrThrow(allColumnXs, startColumn)) + 0.5 : minX;
1587
+ var _y8 = startRow >= top && allRowYs.has(startRow) ? Math.max(Math.round(getOrThrow(allRowYs, startRow)) + 0.5, 0.5) : minY;
1588
+ var endX = endColumn <= right && allColumnXs.has(endColumn) ? Math.round(getOrThrow(allColumnXs, endColumn) + getOrThrow(allColumnWidths, endColumn)) - 0.5 : maxX;
1589
+ var endY = endRow <= bottom && allRowYs.has(endRow) ? Math.round(getOrThrow(allRowYs, endRow) + getOrThrow(allRowHeights, endRow)) - 0.5 : maxY;
1590
+ context.rect(_x4, _y8, endX - _x4, endY - _y8);
1591
+ }
1592
+
1593
+ // draw the inner transparent fill
1594
+ context.fillStyle = theme.selectionColor;
1595
+ context.fill();
1596
+
1597
+ /**
1598
+ * draw an "inner stroke" that's clipped to just inside of the rects
1599
+ * to act as a casing to the outer stroke. 3px width because 1px is outside
1600
+ * the rect (but clipped), 1px is "on" the rect (technically this pixel is
1601
+ * a half pixel clip as well due to rects offset, but we are immediately painting
1602
+ * over it), and then the 1px inside (which is the desired pixel).
1603
+ */
1604
+ context.save();
1605
+ context.clip();
1606
+ context.strokeStyle = theme.selectionOutlineCasingColor;
1607
+ context.lineWidth = 3;
1608
+ context.stroke();
1609
+ context.restore();
1610
+
1611
+ // draw the outerstroke border on top of the inner stroke
1612
+ context.strokeStyle = theme.selectionOutlineColor;
1613
+ context.lineWidth = 1;
1614
+ context.stroke();
1615
+ }
1616
+ if (isCursorVisible && column != null && row != null) {
1617
+ context.restore();
1618
+ this.drawActiveCell(context, state, column, row);
1619
+ }
1620
+ }
1621
+ drawActiveCell(context, state, column, row) {
1622
+ var borderWidth = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : GridRenderer.ACTIVE_CELL_BORDER_WIDTH;
1623
+ var {
1624
+ metrics,
1625
+ theme
1626
+ } = state;
1627
+ var {
1628
+ allColumnWidths,
1629
+ allColumnXs,
1630
+ allRowHeights,
1631
+ allRowYs
1632
+ } = metrics;
1633
+ var cellX = getOrThrow(allColumnXs, column);
1634
+ var cellY = getOrThrow(allRowYs, row);
1635
+ var cellW = getOrThrow(allColumnWidths, column);
1636
+ var cellH = getOrThrow(allRowHeights, row);
1637
+
1638
+ // Now get the outline for the active cell
1639
+ var x = cellX - borderWidth * 0.5;
1640
+ var y = cellY - borderWidth * 0.5;
1641
+ var w = cellW + borderWidth;
1642
+ var h = cellH + borderWidth;
1643
+
1644
+ // Make sure the outline is interior on the edge
1645
+ if (x <= 0) {
1646
+ w += x - 1;
1647
+ x = 1;
1648
+ }
1649
+ if (y <= 0) {
1650
+ h += y - 1;
1651
+ y = 1;
1652
+ }
1653
+ var {
1654
+ lineWidth
1655
+ } = context;
1656
+ context.beginPath();
1657
+ context.lineWidth = borderWidth;
1658
+ context.strokeStyle = theme.selectionOutlineColor;
1659
+ this.drawRoundedRect(context, x, y, w, h);
1660
+ context.stroke();
1661
+ context.lineWidth = lineWidth;
1662
+ }
1663
+
1664
+ /**
1665
+ * Draws a rounded rectangle using the current state of the canvas.
1666
+ *
1667
+ * @param context The canvas context
1668
+ * @param x coordinate of the left side
1669
+ * @param y coordinate of the top side
1670
+ * @param w width of the rectangle
1671
+ * @param h height of the rectangle
1672
+ * @param r corner radius of the rectangle
1673
+ */
1674
+ drawRoundedRect(context, x, y, w, h) {
1675
+ var r = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : GridRenderer.DEFAULT_EDGE_RADIUS;
1676
+ context.beginPath();
1677
+ context.moveTo(x + r, y);
1678
+ context.lineTo(x + w - r, y);
1679
+ context.quadraticCurveTo(x + w, y, x + w, y + r);
1680
+ context.lineTo(x + w, y + h - r);
1681
+ context.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
1682
+ context.lineTo(x + r, y + h);
1683
+ context.quadraticCurveTo(x, y + h, x, y + h - r);
1684
+ context.lineTo(x, y + r);
1685
+ context.quadraticCurveTo(x, y, x + r, y);
1686
+ context.closePath();
1687
+ }
1688
+ drawDraggingColumn(context, state) {
1689
+ var _modelColumns$get3;
1690
+ var {
1691
+ draggingColumn,
1692
+ metrics,
1693
+ mouseX,
1694
+ theme,
1695
+ model
1696
+ } = state;
1697
+ if (draggingColumn == null || mouseX == null) {
1698
+ return;
1699
+ }
1700
+ var {
1701
+ range: draggingColumnVisibleRange,
1702
+ depth: draggingColumnDepth
1703
+ } = draggingColumn;
1704
+ var {
1705
+ gridX,
1706
+ gridY,
1707
+ allColumnXs,
1708
+ allColumnWidths,
1709
+ height,
1710
+ width,
1711
+ columnHeaderMaxDepth,
1712
+ columnHeaderHeight,
1713
+ movedColumns,
1714
+ modelColumns,
1715
+ floatingLeftWidth
1716
+ } = metrics;
1717
+ var draggingModelIndex = (_modelColumns$get3 = modelColumns.get(draggingColumnVisibleRange[0])) !== null && _modelColumns$get3 !== void 0 ? _modelColumns$get3 : GridUtils.getModelIndex(draggingColumnVisibleRange[0], movedColumns);
1718
+ var draggingGroup = model.getColumnHeaderGroup(draggingModelIndex, draggingColumnDepth);
1719
+ if (draggingColumnDepth > 0 && !draggingGroup) {
1720
+ return;
1721
+ }
1722
+ var [startIndex, endIndex] = draggingColumnVisibleRange;
1723
+ var originalLeft = getOrThrow(allColumnXs, startIndex);
1724
+ var originalRight = getOrThrow(allColumnXs, endIndex) + getOrThrow(allColumnWidths, endIndex);
1725
+ var originalWidth = originalRight - originalLeft;
1726
+ var draggingLeft = draggingColumn.left;
1727
+ var {
1728
+ backgroundColor,
1729
+ font,
1730
+ headerFont,
1731
+ reorderOffset,
1732
+ shadowBlur,
1733
+ shadowColor
1734
+ } = theme;
1735
+ var columnHeaderOffset = (columnHeaderMaxDepth - draggingColumnDepth - 1) * columnHeaderHeight;
1736
+ context.save();
1737
+ context.translate(gridX, 0);
1738
+ context.save();
1739
+ context.beginPath();
1740
+
1741
+ // Don't draw over frozen columns
1742
+ context.rect(floatingLeftWidth, 0, width, height);
1743
+ context.clip();
1744
+
1745
+ // First, we need to draw over where the column is coming from
1746
+ context.fillStyle = backgroundColor;
1747
+ context.fillRect(originalLeft, columnHeaderOffset, originalWidth, height);
1748
+ context.restore();
1749
+
1750
+ // Then draw the shadow of the moving column
1751
+ context.translate(0, reorderOffset);
1752
+ context.save();
1753
+ context.shadowColor = shadowColor;
1754
+ context.shadowBlur = shadowBlur;
1755
+ context.fillStyle = backgroundColor;
1756
+ context.fillRect(draggingColumn.left, columnHeaderOffset + reorderOffset, draggingColumn.width, height);
1757
+ context.restore(); // Reset style
1758
+
1759
+ // Now set the clipping region and pretty much just redraw this column and all it's contents
1760
+ context.beginPath();
1761
+ context.rect(draggingColumn.left, columnHeaderOffset, draggingColumn.width + 1, height);
1762
+ context.clip();
1763
+ context.translate(draggingLeft - originalLeft, 0);
1764
+ context.font = headerFont;
1765
+ var visibleColumns = [];
1766
+ for (var i = draggingColumn.range[0]; i <= draggingColumn.range[1]; i += 1) {
1767
+ visibleColumns.push(i);
1768
+ }
1769
+
1770
+ /**
1771
+ * This will not draw the header text properly, but extensions of Grid
1772
+ * may draw extra things in the header like sorts and filters
1773
+ */
1774
+ this.drawColumnHeaders(context, state);
1775
+
1776
+ // Ensure the column header gets drawn
1777
+ this.drawColumnHeadersForRange(context, state, [visibleColumns[0], visibleColumns[visibleColumns.length - 1]], {
1778
+ minX: originalLeft,
1779
+ maxX: width
1780
+ });
1781
+ context.translate(0, gridY);
1782
+ context.font = font;
1783
+ this.drawGridBackground(context, state);
1784
+ for (var _i9 = startIndex; _i9 <= endIndex; _i9 += 1) {
1785
+ this.drawColumnCellContents(context, state, _i9);
1786
+ }
1787
+ context.restore();
1788
+ }
1789
+ drawDraggingRow(context, state) {
1790
+ var {
1791
+ draggingRow,
1792
+ draggingRowOffset,
1793
+ metrics,
1794
+ mouseY,
1795
+ theme
1796
+ } = state;
1797
+ if (draggingRow == null || mouseY == null) {
1798
+ return;
1799
+ }
1800
+ var {
1801
+ gridX,
1802
+ gridY,
1803
+ allRowYs,
1804
+ allRowHeights,
1805
+ width
1806
+ } = metrics;
1807
+ var y = getOrThrow(allRowYs, draggingRow);
1808
+ var rowHeight = getOrThrow(allRowHeights, draggingRow) + 1;
1809
+ var {
1810
+ backgroundColor,
1811
+ font,
1812
+ headerFont,
1813
+ reorderOffset,
1814
+ shadowBlur,
1815
+ shadowColor
1816
+ } = theme;
1817
+ context.save();
1818
+ context.translate(0, gridY);
1819
+
1820
+ // First, we need to draw over the row stripes where the row is coming from
1821
+ context.fillStyle = backgroundColor;
1822
+ context.fillRect(0, y, width, rowHeight);
1823
+ context.translate(gridX + reorderOffset, mouseY - y - gridY - (draggingRowOffset !== null && draggingRowOffset !== void 0 ? draggingRowOffset : 0));
1824
+
1825
+ // Then draw the shadow of the moving row
1826
+ context.save();
1827
+ context.shadowColor = shadowColor;
1828
+ context.shadowBlur = shadowBlur;
1829
+ context.fillStyle = backgroundColor;
1830
+ context.fillRect(-gridX, y, width, rowHeight);
1831
+ context.restore();
1832
+
1833
+ // Now set the clipping region and pretty much just redraw this row and all it's contents
1834
+ context.beginPath();
1835
+ context.rect(-gridX, y, width, rowHeight);
1836
+ context.clip();
1837
+ context.font = font;
1838
+ this.drawGridBackground(context, state);
1839
+ this.drawCellContents(context, state);
1840
+
1841
+ // Now translate it back up and draw the header
1842
+ context.translate(-gridX, -gridY);
1843
+ context.font = headerFont;
1844
+ this.drawRowHeaders(context, state);
1845
+ context.restore();
1846
+ }
1847
+ drawScrollBars(context, state) {
1848
+ var {
1849
+ isDraggingHorizontalScrollBar,
1850
+ isDraggingVerticalScrollBar,
1851
+ isDragging,
1852
+ metrics,
1853
+ mouseX,
1854
+ mouseY,
1855
+ theme
1856
+ } = state;
1857
+ if (theme.scrollBarSize <= 0) {
1858
+ return;
1859
+ }
1860
+ var {
1861
+ width,
1862
+ height,
1863
+ handleHeight,
1864
+ handleWidth,
1865
+ scrollX,
1866
+ scrollY,
1867
+ hasHorizontalBar,
1868
+ hasVerticalBar,
1869
+ barWidth,
1870
+ barHeight,
1871
+ barLeft,
1872
+ barTop
1873
+ } = metrics;
1874
+ var {
1875
+ scrollBarBackgroundColor,
1876
+ scrollBarHoverBackgroundColor,
1877
+ scrollBarCasingColor,
1878
+ scrollBarCornerColor,
1879
+ scrollBarColor,
1880
+ scrollBarHoverColor,
1881
+ scrollBarActiveColor,
1882
+ scrollBarSize,
1883
+ scrollBarHoverSize,
1884
+ scrollBarCasingWidth,
1885
+ scrollBarSelectionTick,
1886
+ scrollBarSelectionTickColor,
1887
+ scrollBarActiveSelectionTickColor,
1888
+ autoSelectRow,
1889
+ autoSelectColumn
1890
+ } = theme;
1891
+ var isInbounds = mouseX != null && mouseY != null && mouseX <= width && mouseY <= height;
1892
+ var isVerticalBarHover = isDraggingVerticalScrollBar || hasVerticalBar && !isDraggingHorizontalScrollBar && !isDragging && mouseX != null && mouseY != null && mouseX >= width - scrollBarHoverSize && mouseY >= barTop && isInbounds;
1893
+ var isHorizontalBarHover = isDraggingHorizontalScrollBar || hasHorizontalBar && !isDraggingVerticalScrollBar && !isDragging && !isVerticalBarHover &&
1894
+ // vert bar gets priorty in overlapped corner hover area
1895
+ mouseX != null && mouseY != null && mouseY >= height - scrollBarHoverSize && mouseX >= barLeft && isInbounds;
1896
+ var hScrollBarSize = isHorizontalBarHover ? scrollBarHoverSize : scrollBarSize;
1897
+ var vScrollBarSize = isVerticalBarHover ? scrollBarHoverSize : scrollBarSize;
1898
+ context.translate(barLeft, barTop);
1899
+ if (hasHorizontalBar && hasVerticalBar) {
1900
+ // That little corner in the bottom right
1901
+ context.fillStyle = scrollBarCasingColor;
1902
+ context.fillRect(width - barLeft - scrollBarSize, height - barTop - scrollBarSize, scrollBarSize, scrollBarSize);
1903
+ context.fillStyle = scrollBarCornerColor;
1904
+ context.fillRect(width - barLeft - scrollBarSize + scrollBarCasingWidth, height - barTop - scrollBarSize + scrollBarCasingWidth, scrollBarSize - scrollBarCasingWidth, scrollBarSize - scrollBarCasingWidth);
1905
+ }
1906
+ if (hasHorizontalBar) {
1907
+ var x = scrollX;
1908
+ var y = height - barTop - hScrollBarSize;
1909
+
1910
+ // scrollbar casing
1911
+ context.fillStyle = scrollBarCasingColor;
1912
+ context.fillRect(0, y, barWidth, hScrollBarSize - scrollBarCasingWidth);
1913
+
1914
+ // scrollbar track
1915
+ context.fillStyle = isHorizontalBarHover ? scrollBarHoverBackgroundColor : scrollBarBackgroundColor;
1916
+ context.fillRect(0, y + scrollBarCasingWidth, barWidth, hScrollBarSize - scrollBarCasingWidth);
1917
+
1918
+ // scrollbar thumb
1919
+ if (isDraggingHorizontalScrollBar) {
1920
+ context.fillStyle = scrollBarActiveColor;
1921
+ } else if (isHorizontalBarHover) {
1922
+ context.fillStyle = scrollBarHoverColor;
1923
+ } else {
1924
+ context.fillStyle = scrollBarColor;
1925
+ }
1926
+ context.fillRect(x, y + scrollBarCasingWidth, handleWidth, hScrollBarSize - scrollBarCasingWidth);
1927
+ if (!autoSelectRow && scrollBarSelectionTick && scrollBarSelectionTickColor != null && scrollBarActiveSelectionTickColor != null) {
1928
+ context.fillStyle = scrollBarSelectionTickColor;
1929
+ // Scrollbar Selection Tick
1930
+ var {
1931
+ selectedRanges,
1932
+ cursorColumn
1933
+ } = state;
1934
+ var {
1935
+ lastLeft,
1936
+ columnCount
1937
+ } = metrics;
1938
+ var filteredRanges = [...selectedRanges].filter(value => value.startColumn != null && value.endColumn != null);
1939
+ var sortedRanges = filteredRanges.map(value => [value.startColumn, value.endColumn]).sort(GridUtils.compareRanges);
1940
+ var mergedRanges = GridUtils.mergeSortedRanges(sortedRanges);
1941
+ var getTickX = index => {
1942
+ if (index <= lastLeft) {
1943
+ return index / lastLeft * (barWidth - handleWidth);
1944
+ }
1945
+ return barWidth - handleWidth + (index - lastLeft) / (columnCount - lastLeft) * handleWidth;
1946
+ };
1947
+ for (var i = 0; i < mergedRanges.length; i += 1) {
1948
+ var range = mergedRanges[i];
1949
+ var startColumn = range[0];
1950
+ var endColumn = range[1];
1951
+ if (startColumn != null && endColumn != null && (startColumn !== cursorColumn || endColumn !== cursorColumn)) {
1952
+ var tickX = getTickX(startColumn);
1953
+ var tickWidth = Math.max(1, Math.round(getTickX(endColumn + 1) - tickX));
1954
+ var trackHeight = hScrollBarSize - scrollBarCasingWidth;
1955
+ context.fillRect(tickX, y + scrollBarCasingWidth + Math.round(trackHeight / 3), tickWidth, Math.round(trackHeight / 3));
1956
+ }
1957
+ }
1958
+
1959
+ // Current Active Tick
1960
+ if (cursorColumn != null) {
1961
+ var _tickX = getTickX(cursorColumn);
1962
+ var _tickWidth = 2;
1963
+ var _trackHeight = hScrollBarSize - scrollBarCasingWidth;
1964
+ context.fillStyle = scrollBarActiveSelectionTickColor;
1965
+ context.fillRect(_tickX, y + scrollBarCasingWidth, _tickWidth, _trackHeight);
1966
+ }
1967
+ }
1968
+ }
1969
+ if (hasVerticalBar) {
1970
+ var _x5 = width - barLeft - vScrollBarSize;
1971
+ var _y9 = scrollY;
1972
+
1973
+ // scrollbar casing
1974
+ context.fillStyle = scrollBarCasingColor;
1975
+ context.fillRect(_x5, 0, vScrollBarSize - scrollBarCasingWidth, barHeight);
1976
+
1977
+ // scrollbar track
1978
+ context.fillStyle = isVerticalBarHover ? scrollBarHoverBackgroundColor : scrollBarBackgroundColor;
1979
+ context.fillRect(_x5 + scrollBarCasingWidth, 0, vScrollBarSize - scrollBarCasingWidth, barHeight);
1980
+
1981
+ // scrollbar thumb
1982
+ if (isDraggingVerticalScrollBar) {
1983
+ context.fillStyle = scrollBarActiveColor;
1984
+ } else if (isVerticalBarHover) {
1985
+ context.fillStyle = scrollBarHoverColor;
1986
+ } else {
1987
+ context.fillStyle = scrollBarColor;
1988
+ }
1989
+ context.fillRect(_x5 + scrollBarCasingWidth, _y9, vScrollBarSize - scrollBarCasingWidth, handleHeight);
1990
+ if (!autoSelectColumn && scrollBarSelectionTick && scrollBarSelectionTickColor != null && scrollBarActiveSelectionTickColor != null) {
1991
+ // Scrollbar Selection Tick
1992
+ var {
1993
+ selectedRanges: _selectedRanges,
1994
+ cursorRow
1995
+ } = state;
1996
+ var {
1997
+ lastTop,
1998
+ rowCount
1999
+ } = metrics;
2000
+ var getTickY = index => {
2001
+ if (index <= lastTop) {
2002
+ return index / lastTop * (barHeight - handleHeight);
2003
+ }
2004
+ return barHeight - handleHeight + (index - lastTop) / (rowCount - lastTop) * handleHeight;
2005
+ };
2006
+ context.fillStyle = scrollBarSelectionTickColor;
2007
+ var _filteredRanges = [..._selectedRanges].filter(value => value.startRow != null && value.endRow != null);
2008
+ var _sortedRanges = _filteredRanges.map(value => [value.startRow, value.endRow]).sort(GridUtils.compareRanges);
2009
+ var _mergedRanges = GridUtils.mergeSortedRanges(_sortedRanges);
2010
+ for (var _i10 = 0; _i10 < _mergedRanges.length; _i10 += 1) {
2011
+ var _range = _mergedRanges[_i10];
2012
+ var startRow = _range[0];
2013
+ var endRow = _range[1];
2014
+ if (startRow != null && endRow != null && (startRow !== cursorRow || endRow !== cursorRow)) {
2015
+ var tickY = getTickY(startRow);
2016
+ var trackWidth = vScrollBarSize - scrollBarCasingWidth;
2017
+ var tickHeight = Math.max(1, Math.round(getTickY(endRow + 1) - tickY));
2018
+ context.fillRect(_x5 + scrollBarCasingWidth + Math.round(trackWidth / 3), tickY, Math.round(trackWidth / 3), tickHeight);
2019
+ }
2020
+ }
2021
+
2022
+ // Current Active Tick
2023
+ if (cursorRow != null) {
2024
+ var _tickY = Math.round(getTickY(cursorRow));
2025
+ var _trackWidth = vScrollBarSize - scrollBarCasingWidth;
2026
+ var _tickHeight = 2;
2027
+ context.fillStyle = scrollBarActiveSelectionTickColor;
2028
+ context.fillRect(_x5 + scrollBarCasingWidth, _tickY, _trackWidth, _tickHeight);
2029
+ }
2030
+ }
2031
+ }
2032
+ context.translate(-barLeft, -barTop);
2033
+ }
2034
+ }
2035
+ _defineProperty(GridRenderer, "DEFAULT_EDGE_RADIUS", 2);
2036
+ _defineProperty(GridRenderer, "ACTIVE_CELL_BORDER_WIDTH", 2);
2037
+ export default GridRenderer;
2038
+ //# sourceMappingURL=GridRenderer.js.map