@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.
- package/dist/CellInputField.css +23 -0
- package/dist/CellInputField.css.map +1 -0
- package/dist/CellInputField.js +174 -0
- package/dist/CellInputField.js.map +1 -0
- package/dist/CellRenderer.js +64 -0
- package/dist/CellRenderer.js.map +1 -0
- package/dist/ColumnHeaderGroup.js +2 -0
- package/dist/ColumnHeaderGroup.js.map +1 -0
- package/dist/DataBarCellRenderer.js +404 -0
- package/dist/DataBarCellRenderer.js.map +1 -0
- package/dist/DataBarGridModel.js +27 -0
- package/dist/DataBarGridModel.js.map +1 -0
- package/dist/EditableGridModel.js +14 -0
- package/dist/EditableGridModel.js.map +1 -0
- package/dist/EventHandlerResult.js +2 -0
- package/dist/EventHandlerResult.js.map +1 -0
- package/dist/ExpandableGridModel.js +8 -0
- package/dist/ExpandableGridModel.js.map +1 -0
- package/dist/Grid.css +45 -0
- package/dist/Grid.css.map +1 -0
- package/dist/Grid.js +1947 -0
- package/dist/Grid.js.map +1 -0
- package/dist/GridAxisRange.js +17 -0
- package/dist/GridAxisRange.js.map +1 -0
- package/dist/GridColorUtils.js +146 -0
- package/dist/GridColorUtils.js.map +1 -0
- package/dist/GridMetricCalculator.js +1500 -0
- package/dist/GridMetricCalculator.js.map +1 -0
- package/dist/GridMetrics.js +2 -0
- package/dist/GridMetrics.js.map +1 -0
- package/dist/GridModel.js +193 -0
- package/dist/GridModel.js.map +1 -0
- package/dist/GridMouseHandler.js +57 -0
- package/dist/GridMouseHandler.js.map +1 -0
- package/dist/GridRange.js +684 -0
- package/dist/GridRange.js.map +1 -0
- package/dist/GridRenderer.js +2038 -0
- package/dist/GridRenderer.js.map +1 -0
- package/dist/GridRendererTypes.js +3 -0
- package/dist/GridRendererTypes.js.map +1 -0
- package/dist/GridTestUtils.js +16 -0
- package/dist/GridTestUtils.js.map +1 -0
- package/dist/GridTheme.js +100 -0
- package/dist/GridTheme.js.map +1 -0
- package/dist/GridUtils.js +1198 -0
- package/dist/GridUtils.js.map +1 -0
- package/dist/KeyHandler.js +36 -0
- package/dist/KeyHandler.js.map +1 -0
- package/dist/MockDataBarGridModel.js +119 -0
- package/dist/MockDataBarGridModel.js.map +1 -0
- package/dist/MockGridData.js +5 -0
- package/dist/MockGridData.js.map +1 -0
- package/dist/MockGridModel.js +122 -0
- package/dist/MockGridModel.js.map +1 -0
- package/dist/MockTreeGridModel.js +193 -0
- package/dist/MockTreeGridModel.js.map +1 -0
- package/dist/StaticDataGridModel.js +40 -0
- package/dist/StaticDataGridModel.js.map +1 -0
- package/dist/TextCellRenderer.js +210 -0
- package/dist/TextCellRenderer.js.map +1 -0
- package/dist/ThemeContext.js +4 -0
- package/dist/ThemeContext.js.map +1 -0
- package/dist/TokenBoxCellRenderer.js +4 -0
- package/dist/TokenBoxCellRenderer.js.map +1 -0
- package/dist/ViewportDataGridModel.js +43 -0
- package/dist/ViewportDataGridModel.js.map +1 -0
- package/dist/errors/AssertionError.js +11 -0
- package/dist/errors/AssertionError.js.map +1 -0
- package/dist/errors/PasteError.js +11 -0
- package/dist/errors/PasteError.js.map +1 -0
- package/dist/errors/assertIsDefined.js +8 -0
- package/dist/errors/assertIsDefined.js.map +1 -0
- package/dist/errors/index.js +4 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/key-handlers/EditKeyHandler.js +46 -0
- package/dist/key-handlers/EditKeyHandler.js.map +1 -0
- package/dist/key-handlers/PasteKeyHandler.js +124 -0
- package/dist/key-handlers/PasteKeyHandler.js.map +1 -0
- package/dist/key-handlers/SelectionKeyHandler.js +272 -0
- package/dist/key-handlers/SelectionKeyHandler.js.map +1 -0
- package/dist/key-handlers/TreeKeyHandler.js +45 -0
- package/dist/key-handlers/TreeKeyHandler.js.map +1 -0
- package/dist/key-handlers/index.js +5 -0
- package/dist/key-handlers/index.js.map +1 -0
- package/dist/memoizeClear.js +33 -0
- package/dist/memoizeClear.js.map +1 -0
- package/dist/mouse-handlers/EditMouseHandler.js +25 -0
- package/dist/mouse-handlers/EditMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +504 -0
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +67 -0
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +164 -0
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js +139 -0
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +54 -0
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js +58 -0
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +39 -0
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridSelectionMouseHandler.js +223 -0
- package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js +213 -0
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridTokenMouseHandler.js +161 -0
- package/dist/mouse-handlers/GridTokenMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +165 -0
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -0
- package/dist/mouse-handlers/index.js +13 -0
- package/dist/mouse-handlers/index.js.map +1 -0
- 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
|