@deephaven/grid 0.5.2-beta.0 → 0.6.1-demo.8
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.js +40 -88
- package/dist/CellInputField.js.map +1 -1
- package/dist/Grid.js +1449 -1484
- package/dist/Grid.js.map +1 -1
- package/dist/GridColorUtils.js +18 -51
- package/dist/GridColorUtils.js.map +1 -1
- package/dist/GridMetricCalculator.d.ts +8 -1
- package/dist/GridMetricCalculator.d.ts.map +1 -1
- package/dist/GridMetricCalculator.js +1031 -994
- package/dist/GridMetricCalculator.js.map +1 -1
- package/dist/GridModel.d.ts +4 -1
- package/dist/GridModel.d.ts.map +1 -1
- package/dist/GridModel.js +175 -286
- package/dist/GridModel.js.map +1 -1
- package/dist/GridMouseHandler.js +39 -59
- package/dist/GridMouseHandler.js.map +1 -1
- package/dist/GridRange.js +572 -630
- package/dist/GridRange.js.map +1 -1
- package/dist/GridRenderer.js +1650 -1564
- package/dist/GridRenderer.js.map +1 -1
- package/dist/GridTestUtils.js +15 -29
- package/dist/GridTestUtils.js.map +1 -1
- package/dist/GridUtils.js +679 -717
- package/dist/GridUtils.js.map +1 -1
- package/dist/KeyHandler.js +6 -18
- package/dist/KeyHandler.js.map +1 -1
- package/dist/MockGridModel.js +105 -210
- package/dist/MockGridModel.js.map +1 -1
- package/dist/MockTreeGridModel.js +113 -183
- package/dist/MockTreeGridModel.js.map +1 -1
- package/dist/errors/PasteError.js +5 -44
- package/dist/errors/PasteError.js.map +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/errors/index.js.map +1 -1
- package/dist/index.js +15 -15
- package/dist/index.js.map +1 -1
- package/dist/key-handlers/EditKeyHandler.js +42 -75
- package/dist/key-handlers/EditKeyHandler.js.map +1 -1
- package/dist/key-handlers/PasteKeyHandler.js +42 -78
- package/dist/key-handlers/PasteKeyHandler.js.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.d.ts.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.js +239 -229
- package/dist/key-handlers/SelectionKeyHandler.js.map +1 -1
- package/dist/key-handlers/TreeKeyHandler.js +42 -72
- package/dist/key-handlers/TreeKeyHandler.js.map +1 -1
- package/dist/key-handlers/index.js +4 -4
- package/dist/key-handlers/index.js.map +1 -1
- package/dist/memoizeClear.js +1 -1
- package/dist/memoizeClear.js.map +1 -1
- package/dist/mouse-handlers/EditMouseHandler.js +18 -50
- package/dist/mouse-handlers/EditMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +141 -163
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +47 -86
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +145 -171
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js +125 -147
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +47 -86
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js +46 -76
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +31 -62
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSelectionMouseHandler.js +200 -222
- package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js +206 -253
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +146 -172
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/index.js +10 -10
- package/dist/mouse-handlers/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -10
package/dist/Grid.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
2
|
-
|
|
3
1
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
4
2
|
|
|
5
3
|
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
@@ -8,38 +6,6 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
8
6
|
|
|
9
7
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
10
8
|
|
|
11
|
-
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
|
12
|
-
|
|
13
|
-
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
14
|
-
|
|
15
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
16
|
-
|
|
17
|
-
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
|
18
|
-
|
|
19
|
-
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
20
|
-
|
|
21
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
22
|
-
|
|
23
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
24
|
-
|
|
25
|
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
26
|
-
|
|
27
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
|
28
|
-
|
|
29
|
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
30
|
-
|
|
31
|
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
32
|
-
|
|
33
|
-
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
34
|
-
|
|
35
|
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
|
|
36
|
-
|
|
37
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
38
|
-
|
|
39
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
40
|
-
|
|
41
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
42
|
-
|
|
43
9
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
44
10
|
|
|
45
11
|
/* eslint react/no-did-update-set-state: "off" */
|
|
@@ -48,19 +14,19 @@ import classNames from 'classnames';
|
|
|
48
14
|
import memoize from 'memoize-one';
|
|
49
15
|
import PropTypes from 'prop-types';
|
|
50
16
|
import clamp from 'lodash.clamp';
|
|
51
|
-
import GridMetricCalculator from
|
|
52
|
-
import GridModel from
|
|
53
|
-
import GridMouseHandler from
|
|
54
|
-
import GridTheme from
|
|
55
|
-
import GridRange from
|
|
56
|
-
import GridRenderer from
|
|
57
|
-
import GridUtils from
|
|
58
|
-
import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from
|
|
17
|
+
import GridMetricCalculator from "./GridMetricCalculator.js";
|
|
18
|
+
import GridModel from "./GridModel.js";
|
|
19
|
+
import GridMouseHandler from "./GridMouseHandler.js";
|
|
20
|
+
import GridTheme from "./GridTheme.js";
|
|
21
|
+
import GridRange from "./GridRange.js";
|
|
22
|
+
import GridRenderer from "./GridRenderer.js";
|
|
23
|
+
import GridUtils from "./GridUtils.js";
|
|
24
|
+
import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from "./mouse-handlers/index.js";
|
|
59
25
|
import "./Grid.css";
|
|
60
|
-
import KeyHandler from
|
|
61
|
-
import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from
|
|
62
|
-
import CellInputField from
|
|
63
|
-
import PasteError from
|
|
26
|
+
import KeyHandler from "./KeyHandler.js";
|
|
27
|
+
import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from "./key-handlers/index.js";
|
|
28
|
+
import CellInputField from "./CellInputField.js";
|
|
29
|
+
import PasteError from "./errors/PasteError.js";
|
|
64
30
|
/**
|
|
65
31
|
* High performance, extendible, themeable grid component.
|
|
66
32
|
* Architectured to be fast and handle billions of rows/columns by default.
|
|
@@ -76,67 +42,65 @@ import PasteError from './errors/PasteError';
|
|
|
76
42
|
* Can also add onClick and onContextMenu handlers to add custom functionality and menus.
|
|
77
43
|
*/
|
|
78
44
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
_classCallCheck(this, Grid);
|
|
88
|
-
|
|
89
|
-
_this = _super.call(this, props);
|
|
90
|
-
|
|
91
|
-
_defineProperty(_assertThisInitialized(_this), "getCachedKeyHandlers", memoize(function (keyHandlers) {
|
|
92
|
-
return [].concat(_toConsumableArray(keyHandlers), _toConsumableArray(_this.keyHandlers)).sort(function (a, b) {
|
|
93
|
-
return a.order - b.order;
|
|
94
|
-
});
|
|
95
|
-
}));
|
|
45
|
+
class Grid extends PureComponent {
|
|
46
|
+
// use same constant as chrome source for windows
|
|
47
|
+
// https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285
|
|
48
|
+
static getScale(context) {
|
|
49
|
+
var devicePixelRatio = window.devicePixelRatio || 1;
|
|
50
|
+
var backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
|
|
51
|
+
return devicePixelRatio / backingStorePixelRatio;
|
|
52
|
+
}
|
|
96
53
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
101
|
-
}));
|
|
54
|
+
static getCursorClassName(cursor) {
|
|
55
|
+
return cursor ? "grid-cursor-".concat(cursor) : null;
|
|
56
|
+
}
|
|
102
57
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
58
|
+
constructor(props) {
|
|
59
|
+
super(props);
|
|
60
|
+
|
|
61
|
+
_defineProperty(this, "getCachedKeyHandlers", memoize(keyHandlers => [...keyHandlers, ...this.keyHandlers].sort((a, b) => a.order - b.order)));
|
|
62
|
+
|
|
63
|
+
_defineProperty(this, "getCachedMouseHandlers", memoize(mouseHandlers => [...mouseHandlers, ...this.mouseHandlers].sort((a, b) => a.order - b.order)));
|
|
64
|
+
|
|
65
|
+
this.handleClick = this.handleClick.bind(this);
|
|
66
|
+
this.handleContextMenu = this.handleContextMenu.bind(this);
|
|
67
|
+
this.handleEditCellCancel = this.handleEditCellCancel.bind(this);
|
|
68
|
+
this.handleEditCellChange = this.handleEditCellChange.bind(this);
|
|
69
|
+
this.handleEditCellCommit = this.handleEditCellCommit.bind(this);
|
|
70
|
+
this.handleDoubleClick = this.handleDoubleClick.bind(this);
|
|
71
|
+
this.handleKeyDown = this.handleKeyDown.bind(this);
|
|
72
|
+
this.handleMouseDown = this.handleMouseDown.bind(this);
|
|
73
|
+
this.handleMouseDrag = this.handleMouseDrag.bind(this);
|
|
74
|
+
this.handleMouseMove = this.handleMouseMove.bind(this);
|
|
75
|
+
this.handleMouseLeave = this.handleMouseLeave.bind(this);
|
|
76
|
+
this.handleMouseUp = this.handleMouseUp.bind(this);
|
|
77
|
+
this.handleResize = this.handleResize.bind(this);
|
|
78
|
+
this.handleWheel = this.handleWheel.bind(this);
|
|
79
|
+
var {
|
|
80
|
+
metricCalculator,
|
|
81
|
+
movedColumns,
|
|
82
|
+
movedRows,
|
|
83
|
+
renderer
|
|
84
|
+
} = props;
|
|
85
|
+
this.renderer = renderer || new GridRenderer();
|
|
86
|
+
this.metricCalculator = metricCalculator || new GridMetricCalculator();
|
|
87
|
+
this.canvas = null;
|
|
88
|
+
this.canvasContext = null;
|
|
89
|
+
this.animationFrame = null;
|
|
90
|
+
this.prevMetrics = null;
|
|
91
|
+
this.metrics = null;
|
|
92
|
+
this.isStuckToBottom = false;
|
|
93
|
+
this.isStuckToRight = false; // Track the cursor that is currently added to the document
|
|
130
94
|
// Add to document so that when dragging the cursor stays, even if mouse leaves the canvas
|
|
131
95
|
// Note: on document, not body so that cursor styling can be combined with
|
|
132
96
|
// blocked pointer events that would otherwise prevent cursor styling from showing
|
|
133
97
|
|
|
134
|
-
|
|
135
|
-
|
|
98
|
+
this.documentCursor = null;
|
|
99
|
+
this.dragTimer = null; // specify handler ordering, such that any extensions can insert handlers in between
|
|
136
100
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
101
|
+
this.keyHandlers = [new EditKeyHandler(400), new PasteKeyHandler(450), new SelectionKeyHandler(500), new TreeKeyHandler(900)];
|
|
102
|
+
this.mouseHandlers = [new GridRowSeparatorMouseHandler(100), new GridColumnSeparatorMouseHandler(200), new GridRowMoveMouseHandler(300), new GridColumnMoveMouseHandler(400), new EditMouseHandler(450), new GridVerticalScrollBarMouseHandler(500), new GridHorizontalScrollBarMouseHandler(600), new GridScrollBarCornerMouseHandler(700), new GridRowTreeMouseHandler(800), new GridSelectionMouseHandler(900)];
|
|
103
|
+
this.state = {
|
|
140
104
|
// Top/left visible cell in the grid. Note that it's visible row/column index, not the model index (ie. if columns are re-ordered)
|
|
141
105
|
top: 0,
|
|
142
106
|
left: 0,
|
|
@@ -161,8 +125,8 @@ var Grid = /*#__PURE__*/function (_PureComponent) {
|
|
|
161
125
|
mouseX: null,
|
|
162
126
|
mouseY: null,
|
|
163
127
|
// Move operations the user has performed on this grids columns/rows
|
|
164
|
-
movedColumns
|
|
165
|
-
movedRows
|
|
128
|
+
movedColumns,
|
|
129
|
+
movedRows,
|
|
166
130
|
// Cursor (highlighted cell) location and active selected range
|
|
167
131
|
cursorRow: null,
|
|
168
132
|
cursorColumn: null,
|
|
@@ -181,1552 +145,1553 @@ var Grid = /*#__PURE__*/function (_PureComponent) {
|
|
|
181
145
|
// The cell that is currently being edited
|
|
182
146
|
editingCell: null
|
|
183
147
|
};
|
|
184
|
-
return _this;
|
|
185
148
|
}
|
|
186
149
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
150
|
+
componentDidMount() {
|
|
151
|
+
this.initContext(); // Need to explicitly add wheel event to canvas so we can preventDefault/avoid passive listener issue
|
|
152
|
+
// Otherwise React attaches listener at doc level and you can't prevent default
|
|
153
|
+
// https://github.com/facebook/react/issues/14856
|
|
154
|
+
|
|
155
|
+
this.canvas.addEventListener('wheel', this.handleWheel, {
|
|
156
|
+
passive: false
|
|
157
|
+
});
|
|
158
|
+
window.addEventListener('resize', this.handleResize);
|
|
159
|
+
this.updateCanvasScale();
|
|
160
|
+
this.updateCanvas();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
componentDidUpdate(prevProps, prevState) {
|
|
164
|
+
var {
|
|
165
|
+
isStickyBottom,
|
|
166
|
+
isStickyRight,
|
|
167
|
+
movedColumns,
|
|
168
|
+
movedRows,
|
|
169
|
+
onMovedColumnsChanged,
|
|
170
|
+
onMoveColumnComplete
|
|
171
|
+
} = this.props;
|
|
172
|
+
var {
|
|
173
|
+
isStickyBottom: prevIsStickyBottom,
|
|
174
|
+
isStickyRight: prevIsStickyRight,
|
|
175
|
+
movedColumns: prevPropMovedColumns,
|
|
176
|
+
movedRows: prevMovedRows
|
|
177
|
+
} = prevProps;
|
|
178
|
+
var {
|
|
179
|
+
movedColumns: prevStateMovedColumns
|
|
180
|
+
} = prevState;
|
|
181
|
+
var {
|
|
182
|
+
draggingColumn,
|
|
183
|
+
movedColumns: currentStateMovedColumns
|
|
184
|
+
} = this.state;
|
|
185
|
+
|
|
186
|
+
if (prevPropMovedColumns !== movedColumns) {
|
|
187
|
+
this.setState({
|
|
188
|
+
movedColumns
|
|
189
|
+
});
|
|
190
|
+
}
|
|
193
191
|
|
|
194
|
-
|
|
195
|
-
|
|
192
|
+
if (prevMovedRows !== movedRows) {
|
|
193
|
+
this.setState({
|
|
194
|
+
movedRows
|
|
196
195
|
});
|
|
197
|
-
window.addEventListener('resize', this.handleResize);
|
|
198
|
-
this.updateCanvasScale();
|
|
199
|
-
this.updateCanvas();
|
|
200
196
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
197
|
+
|
|
198
|
+
if (prevStateMovedColumns !== currentStateMovedColumns) {
|
|
199
|
+
onMovedColumnsChanged(currentStateMovedColumns);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (prevState.draggingColumn != null && draggingColumn == null) {
|
|
203
|
+
onMoveColumnComplete(currentStateMovedColumns);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (isStickyBottom !== prevIsStickyBottom) {
|
|
207
|
+
this.isStuckToBottom = false;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (isStickyRight !== prevIsStickyRight) {
|
|
211
|
+
this.isStuckToRight = false;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.updateMetrics();
|
|
215
|
+
this.requestUpdateCanvas();
|
|
216
|
+
|
|
217
|
+
if (!this.metrics || !this.prevMetrics) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
var {
|
|
222
|
+
bottomVisible,
|
|
223
|
+
rightVisible,
|
|
224
|
+
rowCount,
|
|
225
|
+
columnCount,
|
|
226
|
+
top,
|
|
227
|
+
left,
|
|
228
|
+
height,
|
|
229
|
+
width
|
|
230
|
+
} = this.metrics;
|
|
231
|
+
var {
|
|
232
|
+
rowCount: prevRowCount,
|
|
233
|
+
columnCount: prevColumnCount,
|
|
234
|
+
height: prevHeight,
|
|
235
|
+
width: prevWidth
|
|
236
|
+
} = this.prevMetrics;
|
|
237
|
+
var metricState = this.getMetricState();
|
|
238
|
+
|
|
239
|
+
if (prevRowCount !== rowCount || height !== prevHeight) {
|
|
240
|
+
var lastTop = this.metricCalculator.getLastTop(metricState);
|
|
241
|
+
|
|
242
|
+
if (this.isStuckToBottom && bottomVisible < rowCount - 1 && bottomVisible > 0 && top > 0 || top > lastTop) {
|
|
221
243
|
this.setState({
|
|
222
|
-
|
|
244
|
+
top: lastTop
|
|
223
245
|
});
|
|
224
246
|
}
|
|
247
|
+
}
|
|
225
248
|
|
|
226
|
-
|
|
249
|
+
if (prevColumnCount !== columnCount || width !== prevWidth) {
|
|
250
|
+
var lastLeft = this.metricCalculator.getLastLeft(metricState);
|
|
251
|
+
|
|
252
|
+
if (this.isStuckToRight && rightVisible < columnCount - 1 && rightVisible > 0 && left > 0 || left > lastLeft) {
|
|
227
253
|
this.setState({
|
|
228
|
-
|
|
254
|
+
left: lastLeft
|
|
229
255
|
});
|
|
230
256
|
}
|
|
257
|
+
}
|
|
231
258
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
259
|
+
if (this.validateSelection()) {
|
|
260
|
+
this.checkSelectionChange(prevState);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
235
263
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
264
|
+
componentWillUnmount() {
|
|
265
|
+
if (this.animationFrame != null) {
|
|
266
|
+
cancelAnimationFrame(this.animationFrame);
|
|
267
|
+
}
|
|
239
268
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
269
|
+
this.canvas.removeEventListener('wheel', this.handleWheel, {
|
|
270
|
+
passive: false
|
|
271
|
+
});
|
|
272
|
+
window.removeEventListener('mousemove', this.handleMouseDrag, true);
|
|
273
|
+
window.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
274
|
+
window.removeEventListener('resize', this.handleResize);
|
|
275
|
+
this.stopDragTimer();
|
|
276
|
+
}
|
|
243
277
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
278
|
+
getTheme() {
|
|
279
|
+
var {
|
|
280
|
+
theme
|
|
281
|
+
} = this.props;
|
|
282
|
+
return Grid.getTheme(theme);
|
|
283
|
+
}
|
|
247
284
|
|
|
248
|
-
|
|
249
|
-
|
|
285
|
+
getGridPointFromEvent(event) {
|
|
286
|
+
var rect = this.canvas.getBoundingClientRect();
|
|
287
|
+
var x = event.clientX - rect.left;
|
|
288
|
+
var y = event.clientY - rect.top;
|
|
289
|
+
return this.getGridPointFromXY(x, y);
|
|
290
|
+
}
|
|
250
291
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
292
|
+
getGridPointFromXY(x, y) {
|
|
293
|
+
return GridUtils.getGridPointFromXY(x, y, this.metrics);
|
|
294
|
+
}
|
|
254
295
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
296
|
+
getMetricState() {
|
|
297
|
+
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
|
|
298
|
+
var theme = this.getTheme();
|
|
299
|
+
var {
|
|
300
|
+
model,
|
|
301
|
+
stateOverride
|
|
302
|
+
} = this.props;
|
|
303
|
+
var context = this.canvasContext;
|
|
304
|
+
var width = this.canvas.clientWidth;
|
|
305
|
+
var height = this.canvas.clientHeight;
|
|
306
|
+
var {
|
|
307
|
+
left,
|
|
308
|
+
top,
|
|
309
|
+
leftOffset,
|
|
310
|
+
topOffset,
|
|
311
|
+
movedColumns,
|
|
312
|
+
movedRows,
|
|
313
|
+
isDraggingHorizontalScrollBar,
|
|
314
|
+
isDraggingVerticalScrollBar
|
|
315
|
+
} = state;
|
|
316
|
+
return _objectSpread({
|
|
317
|
+
left,
|
|
318
|
+
top,
|
|
319
|
+
leftOffset,
|
|
320
|
+
topOffset,
|
|
321
|
+
width,
|
|
322
|
+
height,
|
|
323
|
+
context,
|
|
324
|
+
theme,
|
|
325
|
+
model,
|
|
326
|
+
movedColumns,
|
|
327
|
+
movedRows,
|
|
328
|
+
isDraggingHorizontalScrollBar,
|
|
329
|
+
isDraggingVerticalScrollBar
|
|
330
|
+
}, stateOverride);
|
|
331
|
+
}
|
|
280
332
|
|
|
281
|
-
|
|
282
|
-
|
|
333
|
+
getKeyHandlers() {
|
|
334
|
+
var {
|
|
335
|
+
keyHandlers
|
|
336
|
+
} = this.props;
|
|
337
|
+
return this.getCachedKeyHandlers(keyHandlers);
|
|
338
|
+
}
|
|
283
339
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
340
|
+
getMouseHandlers() {
|
|
341
|
+
var {
|
|
342
|
+
mouseHandlers
|
|
343
|
+
} = this.props;
|
|
344
|
+
return this.getCachedMouseHandlers(mouseHandlers);
|
|
345
|
+
}
|
|
290
346
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
347
|
+
getModelColumn(columnIndex) {
|
|
348
|
+
var _this$metrics, _this$metrics$modelCo;
|
|
349
|
+
|
|
350
|
+
return (_this$metrics = this.metrics) === null || _this$metrics === void 0 ? void 0 : (_this$metrics$modelCo = _this$metrics.modelColumns) === null || _this$metrics$modelCo === void 0 ? void 0 : _this$metrics$modelCo.get(columnIndex);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
getModelRow(rowIndex) {
|
|
354
|
+
var _this$metrics2, _this$metrics2$modelR;
|
|
355
|
+
|
|
356
|
+
return (_this$metrics2 = this.metrics) === null || _this$metrics2 === void 0 ? void 0 : (_this$metrics2$modelR = _this$metrics2.modelRows) === null || _this$metrics2$modelR === void 0 ? void 0 : _this$metrics2$modelR.get(rowIndex);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
toggleRowExpanded(row) {
|
|
360
|
+
var {
|
|
361
|
+
metrics
|
|
362
|
+
} = this;
|
|
363
|
+
var {
|
|
364
|
+
modelRows
|
|
365
|
+
} = metrics;
|
|
366
|
+
var modelRow = modelRows.get(row);
|
|
367
|
+
var {
|
|
368
|
+
model
|
|
369
|
+
} = this.props; // We only want to set expansion if the row is expandable
|
|
370
|
+
// If it's not, still move the cursor to that position, as it may be outside of the current viewport and we don't know if it's expandable yet
|
|
371
|
+
|
|
372
|
+
if (model.isRowExpandable(modelRow)) {
|
|
373
|
+
model.setRowExpanded(modelRow, !model.isRowExpanded(modelRow));
|
|
294
374
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
375
|
+
|
|
376
|
+
this.clearSelectedRanges();
|
|
377
|
+
this.commitSelection(); // Need to commit before moving in case we're selecting same row again
|
|
378
|
+
|
|
379
|
+
this.moveCursorToPosition(0, row);
|
|
380
|
+
this.commitSelection();
|
|
381
|
+
this.isStuckToBottom = false;
|
|
382
|
+
}
|
|
383
|
+
/** Allows the selected range to be set programatically */
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
setSelectedRanges(gridRanges) {
|
|
387
|
+
var {
|
|
388
|
+
model
|
|
389
|
+
} = this.props;
|
|
390
|
+
var {
|
|
391
|
+
columnCount,
|
|
392
|
+
rowCount
|
|
393
|
+
} = model;
|
|
394
|
+
var {
|
|
395
|
+
cursorRow,
|
|
396
|
+
cursorColumn,
|
|
397
|
+
selectedRanges
|
|
398
|
+
} = this.state;
|
|
399
|
+
this.setState({
|
|
400
|
+
selectedRanges: gridRanges,
|
|
401
|
+
lastSelectedRanges: selectedRanges
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
if (gridRanges.length > 0) {
|
|
405
|
+
var range = GridRange.boundedRange(gridRanges[0], columnCount, rowCount);
|
|
406
|
+
var newCursorRow = cursorRow;
|
|
407
|
+
var newCursorColumn = cursorColumn;
|
|
408
|
+
|
|
409
|
+
if (!range.containsCell(cursorColumn, cursorRow)) {
|
|
410
|
+
({
|
|
411
|
+
row: newCursorRow,
|
|
412
|
+
column: newCursorColumn
|
|
413
|
+
} = range.startCell());
|
|
300
414
|
}
|
|
301
415
|
|
|
302
|
-
this.
|
|
303
|
-
|
|
416
|
+
this.setState({
|
|
417
|
+
selectionStartColumn: range.startColumn,
|
|
418
|
+
selectionStartRow: range.startRow,
|
|
419
|
+
selectionEndColumn: range.endColumn,
|
|
420
|
+
selectionEndRow: range.endRow,
|
|
421
|
+
cursorColumn: newCursorColumn,
|
|
422
|
+
cursorRow: newCursorRow
|
|
304
423
|
});
|
|
305
|
-
window.removeEventListener('mousemove', this.handleMouseDrag, true);
|
|
306
|
-
window.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
307
|
-
window.removeEventListener('resize', this.handleResize);
|
|
308
|
-
this.stopDragTimer();
|
|
309
|
-
}
|
|
310
|
-
}, {
|
|
311
|
-
key: "getTheme",
|
|
312
|
-
value: function getTheme() {
|
|
313
|
-
var theme = this.props.theme;
|
|
314
|
-
return Grid.getTheme(theme);
|
|
315
|
-
}
|
|
316
|
-
}, {
|
|
317
|
-
key: "getGridPointFromEvent",
|
|
318
|
-
value: function getGridPointFromEvent(event) {
|
|
319
|
-
var rect = this.canvas.getBoundingClientRect();
|
|
320
|
-
var x = event.clientX - rect.left;
|
|
321
|
-
var y = event.clientY - rect.top;
|
|
322
|
-
return this.getGridPointFromXY(x, y);
|
|
323
424
|
}
|
|
324
|
-
}
|
|
325
|
-
key: "getGridPointFromXY",
|
|
326
|
-
value: function getGridPointFromXY(x, y) {
|
|
327
|
-
return GridUtils.getGridPointFromXY(x, y, this.metrics);
|
|
328
|
-
}
|
|
329
|
-
}, {
|
|
330
|
-
key: "getMetricState",
|
|
331
|
-
value: function getMetricState() {
|
|
332
|
-
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
|
|
333
|
-
var theme = this.getTheme();
|
|
334
|
-
var _this$props2 = this.props,
|
|
335
|
-
model = _this$props2.model,
|
|
336
|
-
stateOverride = _this$props2.stateOverride;
|
|
337
|
-
var context = this.canvasContext;
|
|
338
|
-
var width = this.canvas.clientWidth;
|
|
339
|
-
var height = this.canvas.clientHeight;
|
|
340
|
-
var left = state.left,
|
|
341
|
-
top = state.top,
|
|
342
|
-
leftOffset = state.leftOffset,
|
|
343
|
-
topOffset = state.topOffset,
|
|
344
|
-
movedColumns = state.movedColumns,
|
|
345
|
-
movedRows = state.movedRows,
|
|
346
|
-
isDraggingHorizontalScrollBar = state.isDraggingHorizontalScrollBar,
|
|
347
|
-
isDraggingVerticalScrollBar = state.isDraggingVerticalScrollBar;
|
|
348
|
-
return _objectSpread({
|
|
349
|
-
left: left,
|
|
350
|
-
top: top,
|
|
351
|
-
leftOffset: leftOffset,
|
|
352
|
-
topOffset: topOffset,
|
|
353
|
-
width: width,
|
|
354
|
-
height: height,
|
|
355
|
-
context: context,
|
|
356
|
-
theme: theme,
|
|
357
|
-
model: model,
|
|
358
|
-
movedColumns: movedColumns,
|
|
359
|
-
movedRows: movedRows,
|
|
360
|
-
isDraggingHorizontalScrollBar: isDraggingHorizontalScrollBar,
|
|
361
|
-
isDraggingVerticalScrollBar: isDraggingVerticalScrollBar
|
|
362
|
-
}, stateOverride);
|
|
363
|
-
}
|
|
364
|
-
}, {
|
|
365
|
-
key: "getKeyHandlers",
|
|
366
|
-
value: function getKeyHandlers() {
|
|
367
|
-
var keyHandlers = this.props.keyHandlers;
|
|
368
|
-
return this.getCachedKeyHandlers(keyHandlers);
|
|
369
|
-
}
|
|
370
|
-
}, {
|
|
371
|
-
key: "getMouseHandlers",
|
|
372
|
-
value: function getMouseHandlers() {
|
|
373
|
-
var mouseHandlers = this.props.mouseHandlers;
|
|
374
|
-
return this.getCachedMouseHandlers(mouseHandlers);
|
|
375
|
-
}
|
|
376
|
-
}, {
|
|
377
|
-
key: "getModelColumn",
|
|
378
|
-
value: function getModelColumn(columnIndex) {
|
|
379
|
-
var _this$metrics2, _this$metrics2$modelC;
|
|
425
|
+
}
|
|
380
426
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
427
|
+
initContext() {
|
|
428
|
+
var {
|
|
429
|
+
canvas
|
|
430
|
+
} = this;
|
|
431
|
+
var {
|
|
432
|
+
canvasOptions
|
|
433
|
+
} = this.props;
|
|
434
|
+
this.canvasContext = canvas.getContext('2d', canvasOptions);
|
|
435
|
+
}
|
|
387
436
|
|
|
388
|
-
|
|
437
|
+
requestUpdateCanvas() {
|
|
438
|
+
if (this.animationFrame != null) {
|
|
439
|
+
return;
|
|
389
440
|
}
|
|
390
|
-
}, {
|
|
391
|
-
key: "toggleRowExpanded",
|
|
392
|
-
value: function toggleRowExpanded(row) {
|
|
393
|
-
var metrics = this.metrics;
|
|
394
|
-
var modelRows = metrics.modelRows;
|
|
395
|
-
var modelRow = modelRows.get(row);
|
|
396
|
-
var model = this.props.model; // We only want to set expansion if the row is expandable
|
|
397
|
-
// If it's not, still move the cursor to that position, as it may be outside of the current viewport and we don't know if it's expandable yet
|
|
398
|
-
|
|
399
|
-
if (model.isRowExpandable(modelRow)) {
|
|
400
|
-
model.setRowExpanded(modelRow, !model.isRowExpanded(modelRow));
|
|
401
|
-
}
|
|
402
441
|
|
|
403
|
-
|
|
404
|
-
this.
|
|
442
|
+
this.animationFrame = requestAnimationFrame(() => {
|
|
443
|
+
this.animationFrame = null;
|
|
444
|
+
this.updateCanvas(this.metrics);
|
|
445
|
+
});
|
|
446
|
+
}
|
|
405
447
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
var model = this.props.model;
|
|
416
|
-
var columnCount = model.columnCount,
|
|
417
|
-
rowCount = model.rowCount;
|
|
418
|
-
var _this$state2 = this.state,
|
|
419
|
-
cursorRow = _this$state2.cursorRow,
|
|
420
|
-
cursorColumn = _this$state2.cursorColumn,
|
|
421
|
-
selectedRanges = _this$state2.selectedRanges;
|
|
422
|
-
this.setState({
|
|
423
|
-
selectedRanges: gridRanges,
|
|
424
|
-
lastSelectedRanges: selectedRanges
|
|
425
|
-
});
|
|
448
|
+
updateCanvas() {
|
|
449
|
+
var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
|
|
450
|
+
this.updateCanvasScale();
|
|
451
|
+
var {
|
|
452
|
+
onViewChanged
|
|
453
|
+
} = this.props;
|
|
454
|
+
onViewChanged(metrics);
|
|
455
|
+
this.drawCanvas(metrics);
|
|
456
|
+
}
|
|
426
457
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
458
|
+
updateCanvasScale() {
|
|
459
|
+
var {
|
|
460
|
+
canvas,
|
|
461
|
+
canvasContext
|
|
462
|
+
} = this;
|
|
463
|
+
var scale = Grid.getScale(canvasContext); // the parent wrapper has 100% width/height, and is used for determining size
|
|
464
|
+
// we don't want to stretch the canvas to 100%, to avoid fractional pixels.
|
|
465
|
+
// A wrapper element must be used for sizing, and canvas size must be
|
|
466
|
+
// set manually to a floored value in css and a scaled value in width/height
|
|
467
|
+
|
|
468
|
+
var {
|
|
469
|
+
width,
|
|
470
|
+
height
|
|
471
|
+
} = canvas.parentElement.getBoundingClientRect();
|
|
472
|
+
canvas.style.width = "".concat(Math.floor(width), "px");
|
|
473
|
+
canvas.style.height = "".concat(Math.floor(height), "px");
|
|
474
|
+
canvas.width = Math.floor(width) * scale;
|
|
475
|
+
canvas.height = Math.floor(height) * scale;
|
|
476
|
+
canvasContext.scale(scale, scale);
|
|
477
|
+
}
|
|
431
478
|
|
|
432
|
-
|
|
433
|
-
|
|
479
|
+
updateMetrics() {
|
|
480
|
+
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
|
|
481
|
+
this.prevMetrics = this.metrics;
|
|
482
|
+
var {
|
|
483
|
+
metricCalculator
|
|
484
|
+
} = this;
|
|
485
|
+
var metricState = this.getMetricState(state);
|
|
486
|
+
this.metrics = metricCalculator.getMetrics(metricState);
|
|
487
|
+
return this.metrics;
|
|
488
|
+
}
|
|
434
489
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
490
|
+
checkSelectionChange(prevState) {
|
|
491
|
+
var {
|
|
492
|
+
selectedRanges: oldSelectedRanges
|
|
493
|
+
} = prevState;
|
|
494
|
+
var {
|
|
495
|
+
selectedRanges
|
|
496
|
+
} = this.state;
|
|
497
|
+
|
|
498
|
+
if (selectedRanges !== oldSelectedRanges) {
|
|
499
|
+
var {
|
|
500
|
+
onSelectionChanged
|
|
501
|
+
} = this.props;
|
|
502
|
+
onSelectionChanged(selectedRanges);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
438
505
|
|
|
506
|
+
validateSelection() {
|
|
507
|
+
var {
|
|
508
|
+
model
|
|
509
|
+
} = this.props;
|
|
510
|
+
var {
|
|
511
|
+
selectedRanges
|
|
512
|
+
} = this.state;
|
|
513
|
+
var {
|
|
514
|
+
columnCount,
|
|
515
|
+
rowCount
|
|
516
|
+
} = model;
|
|
517
|
+
|
|
518
|
+
for (var i = 0; i < selectedRanges.length; i += 1) {
|
|
519
|
+
var range = selectedRanges[i];
|
|
520
|
+
|
|
521
|
+
if (range.endColumn != null && range.endColumn >= columnCount || range.endRow != null && range.endRow >= rowCount) {
|
|
522
|
+
// Just clear the selection rather than trying to trim it.
|
|
439
523
|
this.setState({
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
selectionEndColumn: range.endColumn,
|
|
443
|
-
selectionEndRow: range.endRow,
|
|
444
|
-
cursorColumn: newCursorColumn,
|
|
445
|
-
cursorRow: newCursorRow
|
|
524
|
+
selectedRanges: [],
|
|
525
|
+
lastSelectedRanges: []
|
|
446
526
|
});
|
|
527
|
+
return false;
|
|
447
528
|
}
|
|
448
529
|
}
|
|
449
|
-
}, {
|
|
450
|
-
key: "initContext",
|
|
451
|
-
value: function initContext() {
|
|
452
|
-
var canvas = this.canvas;
|
|
453
|
-
var canvasOptions = this.props.canvasOptions;
|
|
454
|
-
this.canvasContext = canvas.getContext('2d', canvasOptions);
|
|
455
|
-
}
|
|
456
|
-
}, {
|
|
457
|
-
key: "requestUpdateCanvas",
|
|
458
|
-
value: function requestUpdateCanvas() {
|
|
459
|
-
var _this2 = this;
|
|
460
530
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
this.animationFrame = requestAnimationFrame(function () {
|
|
466
|
-
_this2.animationFrame = null;
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
467
533
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
this.drawCanvas(metrics);
|
|
479
|
-
}
|
|
480
|
-
}, {
|
|
481
|
-
key: "updateCanvasScale",
|
|
482
|
-
value: function updateCanvasScale() {
|
|
483
|
-
var canvas = this.canvas,
|
|
484
|
-
canvasContext = this.canvasContext;
|
|
485
|
-
var scale = Grid.getScale(canvasContext); // the parent wrapper has 100% width/height, and is used for determining size
|
|
486
|
-
// we don't want to stretch the canvas to 100%, to avoid fractional pixels.
|
|
487
|
-
// A wrapper element must be used for sizing, and canvas size must be
|
|
488
|
-
// set manually to a floored value in css and a scaled value in width/height
|
|
489
|
-
|
|
490
|
-
var _canvas$parentElement = canvas.parentElement.getBoundingClientRect(),
|
|
491
|
-
width = _canvas$parentElement.width,
|
|
492
|
-
height = _canvas$parentElement.height;
|
|
493
|
-
|
|
494
|
-
canvas.style.width = "".concat(Math.floor(width), "px");
|
|
495
|
-
canvas.style.height = "".concat(Math.floor(height), "px");
|
|
496
|
-
canvas.width = Math.floor(width) * scale;
|
|
497
|
-
canvas.height = Math.floor(height) * scale;
|
|
498
|
-
canvasContext.scale(scale, scale);
|
|
499
|
-
}
|
|
500
|
-
}, {
|
|
501
|
-
key: "updateMetrics",
|
|
502
|
-
value: function updateMetrics() {
|
|
503
|
-
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
|
|
504
|
-
this.prevMetrics = this.metrics;
|
|
505
|
-
var metricCalculator = this.metricCalculator;
|
|
506
|
-
var metricState = this.getMetricState(state);
|
|
507
|
-
this.metrics = metricCalculator.getMetrics(metricState);
|
|
508
|
-
return this.metrics;
|
|
509
|
-
}
|
|
510
|
-
}, {
|
|
511
|
-
key: "checkSelectionChange",
|
|
512
|
-
value: function checkSelectionChange(prevState) {
|
|
513
|
-
var oldSelectedRanges = prevState.selectedRanges;
|
|
514
|
-
var selectedRanges = this.state.selectedRanges;
|
|
515
|
-
|
|
516
|
-
if (selectedRanges !== oldSelectedRanges) {
|
|
517
|
-
var onSelectionChanged = this.props.onSelectionChanged;
|
|
518
|
-
onSelectionChanged(selectedRanges);
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
}, {
|
|
522
|
-
key: "validateSelection",
|
|
523
|
-
value: function validateSelection() {
|
|
524
|
-
var model = this.props.model;
|
|
525
|
-
var selectedRanges = this.state.selectedRanges;
|
|
526
|
-
var columnCount = model.columnCount,
|
|
527
|
-
rowCount = model.rowCount;
|
|
528
|
-
|
|
529
|
-
for (var i = 0; i < selectedRanges.length; i += 1) {
|
|
530
|
-
var range = selectedRanges[i];
|
|
531
|
-
|
|
532
|
-
if (range.endColumn != null && range.endColumn >= columnCount || range.endRow != null && range.endRow >= rowCount) {
|
|
533
|
-
// Just clear the selection rather than trying to trim it.
|
|
534
|
-
this.setState({
|
|
535
|
-
selectedRanges: [],
|
|
536
|
-
lastSelectedRanges: []
|
|
537
|
-
});
|
|
538
|
-
return false;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
534
|
+
clearSelectedRanges() {
|
|
535
|
+
var {
|
|
536
|
+
selectedRanges
|
|
537
|
+
} = this.state;
|
|
538
|
+
this.setState({
|
|
539
|
+
selectedRanges: [],
|
|
540
|
+
lastSelectedRanges: selectedRanges
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
/** Clears all but the last selected range */
|
|
541
544
|
|
|
542
|
-
return true;
|
|
543
|
-
}
|
|
544
|
-
}, {
|
|
545
|
-
key: "clearSelectedRanges",
|
|
546
|
-
value: function clearSelectedRanges() {
|
|
547
|
-
var selectedRanges = this.state.selectedRanges;
|
|
548
|
-
this.setState({
|
|
549
|
-
selectedRanges: [],
|
|
550
|
-
lastSelectedRanges: selectedRanges
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
/** Clears all but the last selected range */
|
|
554
545
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
546
|
+
trimSelectedRanges() {
|
|
547
|
+
var {
|
|
548
|
+
selectedRanges
|
|
549
|
+
} = this.state;
|
|
559
550
|
|
|
560
|
-
|
|
561
|
-
this.setState({
|
|
562
|
-
selectedRanges: selectedRanges.slice(selectedRanges.length - 1)
|
|
563
|
-
});
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
}, {
|
|
567
|
-
key: "beginSelection",
|
|
568
|
-
value: function beginSelection(column, row) {
|
|
551
|
+
if (selectedRanges.length > 0) {
|
|
569
552
|
this.setState({
|
|
570
|
-
|
|
571
|
-
selectionStartRow: row,
|
|
572
|
-
selectionEndColumn: column,
|
|
573
|
-
selectionEndRow: row,
|
|
574
|
-
cursorColumn: column,
|
|
575
|
-
cursorRow: row
|
|
553
|
+
selectedRanges: selectedRanges.slice(selectedRanges.length - 1)
|
|
576
554
|
});
|
|
577
555
|
}
|
|
578
|
-
|
|
579
|
-
* Moves the selection to the cell specified
|
|
580
|
-
* @param {number} column The column index to move the cursor to
|
|
581
|
-
* @param {number} row The row index to move the cursor to
|
|
582
|
-
* @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
|
|
583
|
-
* @param {boolean} maximizePreviousRange When true, maximize/add to the previous range only, ignoring where the selection was started.
|
|
584
|
-
*/
|
|
556
|
+
}
|
|
585
557
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
558
|
+
beginSelection(column, row) {
|
|
559
|
+
this.setState({
|
|
560
|
+
selectionStartColumn: column,
|
|
561
|
+
selectionStartRow: row,
|
|
562
|
+
selectionEndColumn: column,
|
|
563
|
+
selectionEndRow: row,
|
|
564
|
+
cursorColumn: column,
|
|
565
|
+
cursorRow: row
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Moves the selection to the cell specified
|
|
570
|
+
* @param {number} column The column index to move the cursor to
|
|
571
|
+
* @param {number} row The row index to move the cursor to
|
|
572
|
+
* @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
|
|
573
|
+
* @param {boolean} maximizePreviousRange When true, maximize/add to the previous range only, ignoring where the selection was started.
|
|
574
|
+
*/
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
moveSelection(column, row) {
|
|
578
|
+
var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
579
|
+
var maximizePreviousRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
580
|
+
this.setState(state => {
|
|
581
|
+
var {
|
|
582
|
+
selectedRanges,
|
|
583
|
+
selectionStartRow,
|
|
584
|
+
selectionStartColumn
|
|
585
|
+
} = state;
|
|
586
|
+
var {
|
|
587
|
+
theme
|
|
588
|
+
} = this.props;
|
|
589
|
+
var {
|
|
590
|
+
autoSelectRow,
|
|
591
|
+
autoSelectColumn
|
|
592
|
+
} = theme;
|
|
593
|
+
|
|
594
|
+
if (extendSelection && selectedRanges.length > 0) {
|
|
595
|
+
var lastSelectedRange = selectedRanges[selectedRanges.length - 1];
|
|
596
|
+
var left = null;
|
|
597
|
+
var top = null;
|
|
598
|
+
var right = null;
|
|
599
|
+
var bottom = null;
|
|
600
|
+
|
|
601
|
+
if (maximizePreviousRange) {
|
|
602
|
+
left = autoSelectRow ? null : Math.min(column, lastSelectedRange.startColumn);
|
|
603
|
+
top = autoSelectColumn ? null : Math.min(row, lastSelectedRange.startRow);
|
|
604
|
+
right = autoSelectRow ? null : Math.max(column, lastSelectedRange.endColumn);
|
|
605
|
+
bottom = autoSelectColumn ? null : Math.max(row, lastSelectedRange.endRow);
|
|
606
|
+
} else {
|
|
607
|
+
left = lastSelectedRange.startColumn;
|
|
608
|
+
top = lastSelectedRange.startRow;
|
|
609
|
+
|
|
610
|
+
if (selectionStartColumn != null || selectionStartRow != null) {
|
|
611
|
+
if (!autoSelectRow) {
|
|
612
|
+
left = selectionStartColumn;
|
|
625
613
|
}
|
|
626
614
|
|
|
627
|
-
|
|
628
|
-
|
|
615
|
+
if (!autoSelectColumn) {
|
|
616
|
+
top = selectionStartRow;
|
|
617
|
+
}
|
|
629
618
|
}
|
|
630
619
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
return null;
|
|
635
|
-
}
|
|
620
|
+
right = autoSelectRow ? null : column;
|
|
621
|
+
bottom = autoSelectColumn ? null : row;
|
|
622
|
+
}
|
|
636
623
|
|
|
637
|
-
|
|
624
|
+
var selectedRange = GridRange.makeNormalized(left, top, right, bottom);
|
|
638
625
|
|
|
639
|
-
|
|
640
|
-
return
|
|
641
|
-
selectedRanges: _newRanges,
|
|
642
|
-
selectionEndColumn: column,
|
|
643
|
-
selectionEndRow: row
|
|
644
|
-
};
|
|
626
|
+
if (lastSelectedRange.equals(selectedRange)) {
|
|
627
|
+
return null;
|
|
645
628
|
}
|
|
646
629
|
|
|
647
|
-
var
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
newRanges.push(GridRange.makeNormalized(selectedColumn, selectedRow, selectedColumn, selectedRow));
|
|
630
|
+
var _newRanges = [].concat(selectedRanges);
|
|
631
|
+
|
|
632
|
+
_newRanges[_newRanges.length - 1] = selectedRange;
|
|
651
633
|
return {
|
|
652
|
-
selectedRanges:
|
|
634
|
+
selectedRanges: _newRanges,
|
|
653
635
|
selectionEndColumn: column,
|
|
654
636
|
selectionEndRow: row
|
|
655
637
|
};
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
/**
|
|
659
|
-
* Commits the last selected range to the selected ranges.
|
|
660
|
-
* First checks if the last range is completely contained within another range, and if it
|
|
661
|
-
* is then it blows those ranges apart.
|
|
662
|
-
* Then it consolidates all the selected ranges, reducing them.
|
|
663
|
-
*/
|
|
638
|
+
}
|
|
664
639
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
640
|
+
var newRanges = [].concat(selectedRanges);
|
|
641
|
+
var selectedColumn = autoSelectRow ? null : column;
|
|
642
|
+
var selectedRow = autoSelectColumn ? null : row;
|
|
643
|
+
newRanges.push(GridRange.makeNormalized(selectedColumn, selectedRow, selectedColumn, selectedRow));
|
|
644
|
+
return {
|
|
645
|
+
selectedRanges: newRanges,
|
|
646
|
+
selectionEndColumn: column,
|
|
647
|
+
selectionEndRow: row
|
|
648
|
+
};
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Commits the last selected range to the selected ranges.
|
|
653
|
+
* First checks if the last range is completely contained within another range, and if it
|
|
654
|
+
* is then it blows those ranges apart.
|
|
655
|
+
* Then it consolidates all the selected ranges, reducing them.
|
|
656
|
+
*/
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
commitSelection() {
|
|
660
|
+
this.setState(state => {
|
|
661
|
+
var {
|
|
662
|
+
theme
|
|
663
|
+
} = this.props;
|
|
664
|
+
var {
|
|
665
|
+
autoSelectRow
|
|
666
|
+
} = theme;
|
|
667
|
+
var {
|
|
668
|
+
selectedRanges,
|
|
669
|
+
lastSelectedRanges,
|
|
670
|
+
cursorRow,
|
|
671
|
+
cursorColumn
|
|
672
|
+
} = state;
|
|
673
|
+
|
|
674
|
+
if (selectedRanges.length === 1 && (autoSelectRow ? GridRange.rowCount(selectedRanges) === 1 : GridRange.cellCount(selectedRanges) === 1) && GridRange.rangeArraysEqual(selectedRanges, lastSelectedRanges)) {
|
|
675
|
+
// If it's the exact same single selection, then deselect.
|
|
676
|
+
// For if we click on one cell multiple times.
|
|
677
|
+
return {
|
|
678
|
+
selectedRanges: [],
|
|
679
|
+
lastSelectedRanges: []
|
|
680
|
+
};
|
|
681
|
+
}
|
|
686
682
|
|
|
687
|
-
|
|
683
|
+
var newSelectedRanges = selectedRanges.slice();
|
|
688
684
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
685
|
+
if (newSelectedRanges.length > 1) {
|
|
686
|
+
// Check if the latest selection is entirely within a previously selected range
|
|
687
|
+
// If that's the case, then deselect that section instead
|
|
688
|
+
var lastRange = newSelectedRanges[newSelectedRanges.length - 1];
|
|
693
689
|
|
|
694
|
-
|
|
695
|
-
|
|
690
|
+
for (var i = 0; i < newSelectedRanges.length - 1; i += 1) {
|
|
691
|
+
var selectedRange = newSelectedRanges[i];
|
|
696
692
|
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
}
|
|
693
|
+
if (selectedRange.contains(lastRange)) {
|
|
694
|
+
// We found a match, now remove the two matching ranges, and add back
|
|
695
|
+
// the remainder of the two
|
|
696
|
+
var remainder = selectedRange.subtract(lastRange);
|
|
697
|
+
newSelectedRanges.pop();
|
|
698
|
+
newSelectedRanges.splice(i, 1);
|
|
699
|
+
newSelectedRanges = newSelectedRanges.concat(remainder);
|
|
700
|
+
break;
|
|
706
701
|
}
|
|
707
|
-
|
|
708
|
-
newSelectedRanges = GridRange.consolidate(newSelectedRanges);
|
|
709
702
|
}
|
|
710
703
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
704
|
+
newSelectedRanges = GridRange.consolidate(newSelectedRanges);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
var newCursorColumn = cursorColumn;
|
|
708
|
+
var newCursorRow = cursorRow;
|
|
709
|
+
|
|
710
|
+
if (!GridRange.containsCell(newSelectedRanges, cursorColumn, cursorRow)) {
|
|
711
|
+
var {
|
|
712
|
+
model
|
|
713
|
+
} = this.props;
|
|
714
|
+
var {
|
|
715
|
+
columnCount,
|
|
716
|
+
rowCount
|
|
717
|
+
} = model;
|
|
718
|
+
var nextCursor = GridRange.nextCell(GridRange.boundedRanges(selectedRanges, columnCount, rowCount));
|
|
719
|
+
|
|
720
|
+
if (nextCursor != null) {
|
|
721
|
+
({
|
|
722
|
+
column: newCursorColumn,
|
|
723
|
+
row: newCursorRow
|
|
724
|
+
} = nextCursor);
|
|
725
|
+
} else {
|
|
726
|
+
newCursorColumn = null;
|
|
727
|
+
newCursorRow = null;
|
|
727
728
|
}
|
|
729
|
+
}
|
|
728
730
|
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
731
|
+
return {
|
|
732
|
+
cursorRow: newCursorRow,
|
|
733
|
+
cursorColumn: newCursorColumn,
|
|
734
|
+
selectedRanges: newSelectedRanges,
|
|
735
|
+
lastSelectedRanges: selectedRanges
|
|
736
|
+
};
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
selectAll() {
|
|
741
|
+
var {
|
|
742
|
+
model,
|
|
743
|
+
theme
|
|
744
|
+
} = this.props;
|
|
745
|
+
var {
|
|
746
|
+
autoSelectRow,
|
|
747
|
+
autoSelectColumn
|
|
748
|
+
} = theme;
|
|
749
|
+
var top = autoSelectColumn ? null : 0;
|
|
750
|
+
var bottom = autoSelectColumn ? null : model.rowCount - 1;
|
|
751
|
+
var left = autoSelectRow ? null : 0;
|
|
752
|
+
var right = autoSelectRow ? null : model.columnCount - 1;
|
|
753
|
+
this.setSelectedRanges([new GridRange(left, top, right, bottom)]);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
moveCursor(deltaColumn, deltaRow, extendSelection) {
|
|
757
|
+
var {
|
|
758
|
+
cursorRow,
|
|
759
|
+
cursorColumn,
|
|
760
|
+
selectionEndColumn,
|
|
761
|
+
selectionEndRow
|
|
762
|
+
} = this.state;
|
|
763
|
+
var column = extendSelection ? selectionEndColumn : cursorColumn;
|
|
764
|
+
var row = extendSelection ? selectionEndRow : cursorRow;
|
|
765
|
+
|
|
766
|
+
if (row === null || column === null) {
|
|
767
|
+
var {
|
|
768
|
+
left,
|
|
769
|
+
top
|
|
770
|
+
} = this.state;
|
|
771
|
+
this.moveCursorToPosition(left, top, extendSelection);
|
|
772
|
+
} else {
|
|
773
|
+
var {
|
|
774
|
+
model
|
|
775
|
+
} = this.props;
|
|
776
|
+
var {
|
|
777
|
+
columnCount,
|
|
778
|
+
rowCount
|
|
779
|
+
} = model;
|
|
780
|
+
|
|
781
|
+
var _left = clamp(column + deltaColumn, 0, columnCount - 1);
|
|
782
|
+
|
|
783
|
+
var _top = clamp(row + deltaRow, 0, rowCount - 1);
|
|
784
|
+
|
|
785
|
+
this.moveCursorToPosition(_left, _top, extendSelection);
|
|
750
786
|
}
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Move the cursor in the provided selection direction
|
|
790
|
+
* @param {string} direction The direction to move the cursor in
|
|
791
|
+
*/
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
moveCursorInDirection() {
|
|
795
|
+
var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
796
|
+
var {
|
|
797
|
+
model
|
|
798
|
+
} = this.props;
|
|
799
|
+
var {
|
|
800
|
+
columnCount,
|
|
801
|
+
rowCount
|
|
802
|
+
} = model;
|
|
803
|
+
var {
|
|
804
|
+
cursorRow,
|
|
805
|
+
cursorColumn,
|
|
806
|
+
selectedRanges
|
|
807
|
+
} = this.state;
|
|
808
|
+
var ranges = selectedRanges.length > 0 ? selectedRanges : [GridRange.makeCell(cursorColumn, cursorRow)];
|
|
809
|
+
var nextCursor = null;
|
|
810
|
+
|
|
811
|
+
if (ranges.length === 1 && GridRange.cellCount(ranges) === 1) {
|
|
812
|
+
var _gridRange$nextCell;
|
|
813
|
+
|
|
814
|
+
// If we only have one cell selected, we want to update the cursor and we want to update the selected cells
|
|
815
|
+
var gridRange = new GridRange(0, 0, columnCount - 1, rowCount - 1);
|
|
816
|
+
nextCursor = (_gridRange$nextCell = gridRange.nextCell(cursorColumn, cursorRow, direction)) !== null && _gridRange$nextCell !== void 0 ? _gridRange$nextCell : gridRange.startCell(direction);
|
|
817
|
+
} else {
|
|
818
|
+
nextCursor = GridRange.nextCell(GridRange.boundedRanges(ranges, columnCount, rowCount), cursorColumn, cursorRow, direction);
|
|
778
819
|
}
|
|
779
|
-
/**
|
|
780
|
-
* Move the cursor in the provided selection direction
|
|
781
|
-
* @param {string} direction The direction to move the cursor in
|
|
782
|
-
*/
|
|
783
820
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
cursorColumn = _this$state5.cursorColumn,
|
|
794
|
-
selectedRanges = _this$state5.selectedRanges;
|
|
795
|
-
var ranges = selectedRanges.length > 0 ? selectedRanges : [GridRange.makeCell(cursorColumn, cursorRow)];
|
|
796
|
-
var nextCursor = null;
|
|
797
|
-
|
|
798
|
-
if (ranges.length === 1 && GridRange.cellCount(ranges) === 1) {
|
|
799
|
-
var _gridRange$nextCell;
|
|
800
|
-
|
|
801
|
-
// If we only have one cell selected, we want to update the cursor and we want to update the selected cells
|
|
802
|
-
var gridRange = new GridRange(0, 0, columnCount - 1, rowCount - 1);
|
|
803
|
-
nextCursor = (_gridRange$nextCell = gridRange.nextCell(cursorColumn, cursorRow, direction)) !== null && _gridRange$nextCell !== void 0 ? _gridRange$nextCell : gridRange.startCell(direction);
|
|
804
|
-
} else {
|
|
805
|
-
nextCursor = GridRange.nextCell(GridRange.boundedRanges(ranges, columnCount, rowCount), cursorColumn, cursorRow, direction);
|
|
806
|
-
}
|
|
821
|
+
if (nextCursor != null) {
|
|
822
|
+
var {
|
|
823
|
+
column,
|
|
824
|
+
row
|
|
825
|
+
} = nextCursor;
|
|
826
|
+
this.setState({
|
|
827
|
+
cursorColumn: column,
|
|
828
|
+
cursorRow: row
|
|
829
|
+
});
|
|
807
830
|
|
|
808
|
-
if (
|
|
809
|
-
var _nextCursor = nextCursor,
|
|
810
|
-
column = _nextCursor.column,
|
|
811
|
-
row = _nextCursor.row;
|
|
831
|
+
if (!GridRange.containsCell(selectedRanges, column, row)) {
|
|
812
832
|
this.setState({
|
|
813
|
-
|
|
814
|
-
|
|
833
|
+
selectedRanges: [GridRange.makeCell(column, row)],
|
|
834
|
+
selectionStartColumn: column,
|
|
835
|
+
selectionStartRow: row,
|
|
836
|
+
selectionEndColumn: column,
|
|
837
|
+
selectionEndRow: row
|
|
815
838
|
});
|
|
839
|
+
}
|
|
816
840
|
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
841
|
+
this.moveViewToCell(nextCursor.column, nextCursor.row);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Move a cursor to the specified position in the grid.
|
|
846
|
+
* @param {number|null} column The column index to move the cursor to
|
|
847
|
+
* @param {number|null} row The row index to move the cursor to
|
|
848
|
+
* @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
|
|
849
|
+
* @param {boolean} keepCursorInView Whether to move the viewport so that the cursor is in view
|
|
850
|
+
* @param {boolean} maximizePreviousRange With this and `extendSelection` true, it will maximize/add to the previous range only, ignoring where the selection was started
|
|
851
|
+
*/
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
moveCursorToPosition(column, row) {
|
|
855
|
+
var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
856
|
+
var keepCursorInView = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
|
857
|
+
var maximizePreviousRange = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
858
|
+
|
|
859
|
+
if (!extendSelection) {
|
|
860
|
+
this.beginSelection(column, row);
|
|
861
|
+
}
|
|
826
862
|
|
|
827
|
-
|
|
863
|
+
this.moveSelection(column, row, extendSelection, maximizePreviousRange);
|
|
864
|
+
|
|
865
|
+
if (keepCursorInView) {
|
|
866
|
+
this.moveViewToCell(column, row);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Moves the view to make the specified cell visible
|
|
871
|
+
*
|
|
872
|
+
* @param {number|null} column The column index to bring into view
|
|
873
|
+
* @param {number|null} row The row index to bring into view
|
|
874
|
+
*/
|
|
875
|
+
|
|
876
|
+
|
|
877
|
+
moveViewToCell(column, row) {
|
|
878
|
+
var {
|
|
879
|
+
metricCalculator
|
|
880
|
+
} = this;
|
|
881
|
+
var {
|
|
882
|
+
bottomVisible,
|
|
883
|
+
rightVisible,
|
|
884
|
+
topVisible,
|
|
885
|
+
leftVisible
|
|
886
|
+
} = this.metrics;
|
|
887
|
+
var metricState = this.getMetricState(this.state);
|
|
888
|
+
var {
|
|
889
|
+
top,
|
|
890
|
+
left,
|
|
891
|
+
topOffset,
|
|
892
|
+
leftOffset
|
|
893
|
+
} = this.state;
|
|
894
|
+
|
|
895
|
+
if (row != null && !GridUtils.isFloatingRow(row, this.metrics)) {
|
|
896
|
+
if (row < topVisible) {
|
|
897
|
+
top = metricCalculator.getTopForTopVisible(metricState, row);
|
|
898
|
+
topOffset = 0;
|
|
899
|
+
} else if (row > bottomVisible) {
|
|
900
|
+
top = metricCalculator.getTopForBottomVisible(metricState, row);
|
|
901
|
+
topOffset = 0;
|
|
828
902
|
}
|
|
829
903
|
}
|
|
830
|
-
/**
|
|
831
|
-
* Move a cursor to the specified position in the grid.
|
|
832
|
-
* @param {number|null} column The column index to move the cursor to
|
|
833
|
-
* @param {number|null} row The row index to move the cursor to
|
|
834
|
-
* @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
|
|
835
|
-
* @param {boolean} keepCursorInView Whether to move the viewport so that the cursor is in view
|
|
836
|
-
* @param {boolean} maximizePreviousRange With this and `extendSelection` true, it will maximize/add to the previous range only, ignoring where the selection was started
|
|
837
|
-
*/
|
|
838
|
-
|
|
839
|
-
}, {
|
|
840
|
-
key: "moveCursorToPosition",
|
|
841
|
-
value: function moveCursorToPosition(column, row) {
|
|
842
|
-
var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
843
|
-
var keepCursorInView = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
|
844
|
-
var maximizePreviousRange = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
845
904
|
|
|
846
|
-
|
|
847
|
-
|
|
905
|
+
if (column != null && !GridUtils.isFloatingColumn(column, this.metrics)) {
|
|
906
|
+
if (column < leftVisible) {
|
|
907
|
+
left = metricCalculator.getLeftForLeftVisible(metricState, column);
|
|
908
|
+
leftOffset = 0;
|
|
909
|
+
} else if (column > rightVisible) {
|
|
910
|
+
left = metricCalculator.getLeftForRightVisible(metricState, column);
|
|
911
|
+
leftOffset = 0;
|
|
848
912
|
}
|
|
913
|
+
}
|
|
849
914
|
|
|
850
|
-
|
|
915
|
+
this.setViewState({
|
|
916
|
+
top,
|
|
917
|
+
left,
|
|
918
|
+
topOffset,
|
|
919
|
+
leftOffset
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* Checks the `top` and `left` properties that are set and updates the isStuckToBottom/Right properties
|
|
924
|
+
* Should be called when user interaction occurs
|
|
925
|
+
* @param {object} viewState New state properties to set.
|
|
926
|
+
* @param {boolean} forceUpdate Whether to force an update.
|
|
927
|
+
*/
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
setViewState(viewState) {
|
|
931
|
+
var forceUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
932
|
+
var {
|
|
933
|
+
isStickyBottom,
|
|
934
|
+
isStickyRight
|
|
935
|
+
} = this.props;
|
|
936
|
+
var {
|
|
937
|
+
top,
|
|
938
|
+
left
|
|
939
|
+
} = viewState;
|
|
940
|
+
var {
|
|
941
|
+
lastTop,
|
|
942
|
+
lastLeft
|
|
943
|
+
} = this.metrics;
|
|
944
|
+
|
|
945
|
+
if (top != null) {
|
|
946
|
+
this.isStuckToBottom = isStickyBottom && top >= lastTop;
|
|
947
|
+
}
|
|
851
948
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
}
|
|
949
|
+
if (left != null) {
|
|
950
|
+
this.isStuckToRight = isStickyRight && left >= lastLeft;
|
|
855
951
|
}
|
|
856
|
-
/**
|
|
857
|
-
* Moves the view to make the specified cell visible
|
|
858
|
-
*
|
|
859
|
-
* @param {number|null} column The column index to bring into view
|
|
860
|
-
* @param {number|null} row The row index to bring into view
|
|
861
|
-
*/
|
|
862
952
|
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
953
|
+
this.setState(viewState);
|
|
954
|
+
|
|
955
|
+
if (forceUpdate) {
|
|
956
|
+
this.forceUpdate();
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
/**
|
|
960
|
+
* Start editing the data at the given index
|
|
961
|
+
*
|
|
962
|
+
* @param {number} column The visible column index to start editing
|
|
963
|
+
* @param {number} row The visible row index to start editing
|
|
964
|
+
* @param {boolean} isQuickEdit If this is a quick edit (the arrow keys can commit)
|
|
965
|
+
* @param {number[]|null} selectionRange The tuple [start,end] text selection range of the value to select when editing
|
|
966
|
+
* @param {string?} value The value to start with in the edit field. Leave undefined to use the current value.
|
|
967
|
+
*/
|
|
968
|
+
|
|
969
|
+
|
|
970
|
+
startEditing(column, row) {
|
|
971
|
+
var isQuickEdit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
972
|
+
var selectionRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
973
|
+
var value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
|
|
974
|
+
var {
|
|
975
|
+
model
|
|
976
|
+
} = this.props;
|
|
977
|
+
var modelColumn = this.getModelColumn(column);
|
|
978
|
+
var modelRow = this.getModelRow(row);
|
|
979
|
+
var cell = {
|
|
980
|
+
column,
|
|
981
|
+
row,
|
|
982
|
+
selectionRange,
|
|
983
|
+
value: value !== undefined ? value : model.editValueForCell(modelColumn, modelRow),
|
|
984
|
+
isQuickEdit
|
|
985
|
+
};
|
|
986
|
+
this.setState({
|
|
987
|
+
editingCell: cell,
|
|
988
|
+
cursorColumn: column,
|
|
989
|
+
cursorRow: row
|
|
990
|
+
});
|
|
991
|
+
this.moveViewToCell(column, row);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
isValidForCell(column, row, value) {
|
|
995
|
+
var {
|
|
996
|
+
model
|
|
997
|
+
} = this.props;
|
|
998
|
+
var modelColumn = this.getModelColumn(column);
|
|
999
|
+
var modelRow = this.getModelRow(row);
|
|
1000
|
+
return model.isValidForCell(modelColumn, modelRow, value);
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* Paste a value with the current selection
|
|
1004
|
+
* It first needs to validate that the pasted table is valid for the given selection.
|
|
1005
|
+
* Also may update selection if single cells are selected and a table is pasted.
|
|
1006
|
+
* @param {string[][] | string} value Table or a string that is being pasted
|
|
1007
|
+
*/
|
|
1008
|
+
|
|
1009
|
+
|
|
1010
|
+
pasteValue(value) {
|
|
1011
|
+
var _this = this;
|
|
1012
|
+
|
|
1013
|
+
return _asyncToGenerator(function* () {
|
|
1014
|
+
var {
|
|
1015
|
+
model
|
|
1016
|
+
} = _this.props;
|
|
1017
|
+
var {
|
|
1018
|
+
movedColumns,
|
|
1019
|
+
movedRows,
|
|
1020
|
+
selectedRanges
|
|
1021
|
+
} = _this.state;
|
|
1022
|
+
|
|
1023
|
+
try {
|
|
1024
|
+
if (!model.isEditable || !selectedRanges.every(range => model.isEditableRange(range))) {
|
|
1025
|
+
throw new PasteError("Can't paste in to read-only area.");
|
|
886
1026
|
}
|
|
887
|
-
}
|
|
888
1027
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
left = metricCalculator.getLeftForLeftVisible(metricState, column);
|
|
892
|
-
leftOffset = 0;
|
|
893
|
-
} else if (column > rightVisible) {
|
|
894
|
-
left = metricCalculator.getLeftForRightVisible(metricState, column);
|
|
895
|
-
leftOffset = 0;
|
|
1028
|
+
if (selectedRanges.length <= 0) {
|
|
1029
|
+
throw new PasteError('Select an area to paste to.');
|
|
896
1030
|
}
|
|
897
|
-
}
|
|
898
1031
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
1032
|
+
if (typeof value === 'string') {
|
|
1033
|
+
// Just paste the value into all the selected cells
|
|
1034
|
+
var _edits = [];
|
|
1035
|
+
var modelRanges = GridUtils.getModelRanges(selectedRanges, movedColumns, movedRows);
|
|
1036
|
+
GridRange.forEachCell(modelRanges, (x, y) => {
|
|
1037
|
+
_edits.push({
|
|
1038
|
+
x,
|
|
1039
|
+
y,
|
|
1040
|
+
text: value
|
|
1041
|
+
});
|
|
1042
|
+
});
|
|
1043
|
+
yield model.setValues(_edits);
|
|
1044
|
+
return;
|
|
1045
|
+
} // Otherwise it's a table of data
|
|
912
1046
|
|
|
913
|
-
}, {
|
|
914
|
-
key: "setViewState",
|
|
915
|
-
value: function setViewState(viewState) {
|
|
916
|
-
var forceUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
917
|
-
var _this$props4 = this.props,
|
|
918
|
-
isStickyBottom = _this$props4.isStickyBottom,
|
|
919
|
-
isStickyRight = _this$props4.isStickyRight;
|
|
920
|
-
var top = viewState.top,
|
|
921
|
-
left = viewState.left;
|
|
922
|
-
var _this$metrics5 = this.metrics,
|
|
923
|
-
lastTop = _this$metrics5.lastTop,
|
|
924
|
-
lastLeft = _this$metrics5.lastLeft;
|
|
925
|
-
|
|
926
|
-
if (top != null) {
|
|
927
|
-
this.isStuckToBottom = isStickyBottom && top >= lastTop;
|
|
928
|
-
}
|
|
929
1047
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1048
|
+
var tableHeight = value.length;
|
|
1049
|
+
var tableWidth = value[0].length;
|
|
1050
|
+
var {
|
|
1051
|
+
columnCount,
|
|
1052
|
+
rowCount
|
|
1053
|
+
} = model;
|
|
1054
|
+
var ranges = selectedRanges; // If each cell is a single selection, we need to update the selection to map to the newly pasted data
|
|
933
1055
|
|
|
934
|
-
|
|
1056
|
+
if (ranges.every(range => GridRange.cellCount([range]) === 1 && range.startColumn + tableWidth <= columnCount && range.startRow + tableHeight <= rowCount)) {
|
|
1057
|
+
// Remap the selected ranges
|
|
1058
|
+
ranges = ranges.map(range => new GridRange(range.startColumn, range.startRow, range.startColumn + tableWidth - 1, range.startRow + tableHeight - 1));
|
|
935
1059
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
/**
|
|
941
|
-
* Start editing the data at the given index
|
|
942
|
-
*
|
|
943
|
-
* @param {number} column The visible column index to start editing
|
|
944
|
-
* @param {number} row The visible row index to start editing
|
|
945
|
-
* @param {boolean} isQuickEdit If this is a quick edit (the arrow keys can commit)
|
|
946
|
-
* @param {number[]|null} selectionRange The tuple [start,end] text selection range of the value to select when editing
|
|
947
|
-
* @param {string?} value The value to start with in the edit field. Leave undefined to use the current value.
|
|
948
|
-
*/
|
|
1060
|
+
_this.setSelectedRanges(ranges);
|
|
1061
|
+
}
|
|
949
1062
|
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
var isQuickEdit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
954
|
-
var selectionRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
|
|
955
|
-
var value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
|
|
956
|
-
var model = this.props.model;
|
|
957
|
-
var modelColumn = this.getModelColumn(column);
|
|
958
|
-
var modelRow = this.getModelRow(row);
|
|
959
|
-
var cell = {
|
|
960
|
-
column: column,
|
|
961
|
-
row: row,
|
|
962
|
-
selectionRange: selectionRange,
|
|
963
|
-
value: value !== undefined ? value : model.editValueForCell(modelColumn, modelRow),
|
|
964
|
-
isQuickEdit: isQuickEdit
|
|
965
|
-
};
|
|
966
|
-
this.setState({
|
|
967
|
-
editingCell: cell,
|
|
968
|
-
cursorColumn: column,
|
|
969
|
-
cursorRow: row
|
|
970
|
-
});
|
|
971
|
-
this.moveViewToCell(column, row);
|
|
972
|
-
}
|
|
973
|
-
}, {
|
|
974
|
-
key: "isValidForCell",
|
|
975
|
-
value: function isValidForCell(column, row, value) {
|
|
976
|
-
var model = this.props.model;
|
|
977
|
-
var modelColumn = this.getModelColumn(column);
|
|
978
|
-
var modelRow = this.getModelRow(row);
|
|
979
|
-
return model.isValidForCell(modelColumn, modelRow, value);
|
|
980
|
-
}
|
|
981
|
-
/**
|
|
982
|
-
* Paste a value with the current selection
|
|
983
|
-
* It first needs to validate that the pasted table is valid for the given selection.
|
|
984
|
-
* Also may update selection if single cells are selected and a table is pasted.
|
|
985
|
-
* @param {string[][] | string} value Table or a string that is being pasted
|
|
986
|
-
*/
|
|
1063
|
+
if (!ranges.every(range => GridRange.rowCount([range]) === tableHeight && GridRange.columnCount([range]) === tableWidth)) {
|
|
1064
|
+
throw new PasteError('Copy and paste area are not same size.');
|
|
1065
|
+
}
|
|
987
1066
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
case 0:
|
|
998
|
-
model = this.props.model;
|
|
999
|
-
_this$state7 = this.state, movedColumns = _this$state7.movedColumns, movedRows = _this$state7.movedRows, selectedRanges = _this$state7.selectedRanges;
|
|
1000
|
-
_context.prev = 2;
|
|
1001
|
-
|
|
1002
|
-
if (!(!model.isEditable || !selectedRanges.every(function (range) {
|
|
1003
|
-
return model.isEditableRange(range);
|
|
1004
|
-
}))) {
|
|
1005
|
-
_context.next = 5;
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
throw new PasteError("Can't paste in to read-only area.");
|
|
1010
|
-
|
|
1011
|
-
case 5:
|
|
1012
|
-
if (!(selectedRanges.length <= 0)) {
|
|
1013
|
-
_context.next = 7;
|
|
1014
|
-
break;
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
throw new PasteError('Select an area to paste to.');
|
|
1018
|
-
|
|
1019
|
-
case 7:
|
|
1020
|
-
if (!(typeof value === 'string')) {
|
|
1021
|
-
_context.next = 14;
|
|
1022
|
-
break;
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
// Just paste the value into all the selected cells
|
|
1026
|
-
_edits = [];
|
|
1027
|
-
modelRanges = GridUtils.getModelRanges(selectedRanges, movedColumns, movedRows);
|
|
1028
|
-
GridRange.forEachCell(modelRanges, function (x, y) {
|
|
1029
|
-
_edits.push({
|
|
1030
|
-
x: x,
|
|
1031
|
-
y: y,
|
|
1032
|
-
text: value
|
|
1033
|
-
});
|
|
1034
|
-
});
|
|
1035
|
-
_context.next = 13;
|
|
1036
|
-
return model.setValues(_edits);
|
|
1037
|
-
|
|
1038
|
-
case 13:
|
|
1039
|
-
return _context.abrupt("return");
|
|
1040
|
-
|
|
1041
|
-
case 14:
|
|
1042
|
-
// Otherwise it's a table of data
|
|
1043
|
-
tableHeight = value.length;
|
|
1044
|
-
tableWidth = value[0].length;
|
|
1045
|
-
columnCount = model.columnCount, rowCount = model.rowCount;
|
|
1046
|
-
ranges = selectedRanges; // If each cell is a single selection, we need to update the selection to map to the newly pasted data
|
|
1047
|
-
|
|
1048
|
-
if (ranges.every(function (range) {
|
|
1049
|
-
return GridRange.cellCount([range]) === 1 && range.startColumn + tableWidth <= columnCount && range.startRow + tableHeight <= rowCount;
|
|
1050
|
-
})) {
|
|
1051
|
-
// Remap the selected ranges
|
|
1052
|
-
ranges = ranges.map(function (range) {
|
|
1053
|
-
return new GridRange(range.startColumn, range.startRow, range.startColumn + tableWidth - 1, range.startRow + tableHeight - 1);
|
|
1054
|
-
});
|
|
1055
|
-
this.setSelectedRanges(ranges);
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
if (ranges.every(function (range) {
|
|
1059
|
-
return GridRange.rowCount([range]) === tableHeight && GridRange.columnCount([range]) === tableWidth;
|
|
1060
|
-
})) {
|
|
1061
|
-
_context.next = 21;
|
|
1062
|
-
break;
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
throw new PasteError('Copy and paste area are not same size.');
|
|
1066
|
-
|
|
1067
|
-
case 21:
|
|
1068
|
-
edits = [];
|
|
1069
|
-
ranges.forEach(function (range) {
|
|
1070
|
-
for (var x = 0; x < tableWidth; x += 1) {
|
|
1071
|
-
for (var y = 0; y < tableHeight; y += 1) {
|
|
1072
|
-
edits.push({
|
|
1073
|
-
x: range.startColumn + x,
|
|
1074
|
-
y: range.startRow + y,
|
|
1075
|
-
text: value[y][x]
|
|
1076
|
-
});
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
});
|
|
1080
|
-
_context.next = 25;
|
|
1081
|
-
return model.setValues(edits);
|
|
1082
|
-
|
|
1083
|
-
case 25:
|
|
1084
|
-
_context.next = 31;
|
|
1085
|
-
break;
|
|
1086
|
-
|
|
1087
|
-
case 27:
|
|
1088
|
-
_context.prev = 27;
|
|
1089
|
-
_context.t0 = _context["catch"](2);
|
|
1090
|
-
onError = this.props.onError;
|
|
1091
|
-
onError(_context.t0);
|
|
1092
|
-
|
|
1093
|
-
case 31:
|
|
1094
|
-
case "end":
|
|
1095
|
-
return _context.stop();
|
|
1067
|
+
var edits = [];
|
|
1068
|
+
ranges.forEach(range => {
|
|
1069
|
+
for (var x = 0; x < tableWidth; x += 1) {
|
|
1070
|
+
for (var y = 0; y < tableHeight; y += 1) {
|
|
1071
|
+
edits.push({
|
|
1072
|
+
x: range.startColumn + x,
|
|
1073
|
+
y: range.startRow + y,
|
|
1074
|
+
text: value[y][x]
|
|
1075
|
+
});
|
|
1096
1076
|
}
|
|
1097
1077
|
}
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1078
|
+
});
|
|
1079
|
+
yield model.setValues(edits);
|
|
1080
|
+
} catch (e) {
|
|
1081
|
+
var {
|
|
1082
|
+
onError
|
|
1083
|
+
} = _this.props;
|
|
1084
|
+
onError(e);
|
|
1103
1085
|
}
|
|
1086
|
+
})();
|
|
1087
|
+
}
|
|
1104
1088
|
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
var modelColumn = this.getModelColumn(column);
|
|
1112
|
-
var modelRow = this.getModelRow(row);
|
|
1113
|
-
|
|
1114
|
-
if (model.isValidForCell(modelColumn, modelRow, value)) {
|
|
1115
|
-
model.setValueForCell(modelColumn, modelRow, value);
|
|
1116
|
-
}
|
|
1117
|
-
}
|
|
1118
|
-
}, {
|
|
1119
|
-
key: "setValueForRanges",
|
|
1120
|
-
value: function setValueForRanges(ranges, value) {
|
|
1121
|
-
var model = this.props.model;
|
|
1122
|
-
var _this$state8 = this.state,
|
|
1123
|
-
movedColumns = _this$state8.movedColumns,
|
|
1124
|
-
movedRows = _this$state8.movedRows;
|
|
1125
|
-
var modelRanges = GridUtils.getModelRanges(ranges, movedColumns, movedRows);
|
|
1126
|
-
model.setValueForRanges(modelRanges, value);
|
|
1127
|
-
}
|
|
1128
|
-
}, {
|
|
1129
|
-
key: "isSelected",
|
|
1130
|
-
value: function isSelected(row, column) {
|
|
1131
|
-
var selectedRanges = this.state.selectedRanges;
|
|
1132
|
-
|
|
1133
|
-
for (var i = 0; i < selectedRanges.length; i += 1) {
|
|
1134
|
-
var selectedRange = selectedRanges[i];
|
|
1135
|
-
var rowSelected = selectedRange.startRow === null || selectedRange.startRow <= row && row <= selectedRange.endRow;
|
|
1136
|
-
var columnSelected = selectedRange.startColumn === null || selectedRange.startColumn <= column && column <= selectedRange.endColumn;
|
|
1137
|
-
|
|
1138
|
-
if (rowSelected && columnSelected) {
|
|
1139
|
-
return true;
|
|
1140
|
-
}
|
|
1141
|
-
}
|
|
1089
|
+
setValueForCell(column, row, value) {
|
|
1090
|
+
var {
|
|
1091
|
+
model
|
|
1092
|
+
} = this.props;
|
|
1093
|
+
var modelColumn = this.getModelColumn(column);
|
|
1094
|
+
var modelRow = this.getModelRow(row);
|
|
1142
1095
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
}, {
|
|
1146
|
-
key: "addDocumentCursor",
|
|
1147
|
-
value: function addDocumentCursor() {
|
|
1148
|
-
var cursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
1149
|
-
if (this.documentCursor === Grid.getCursorClassName(cursor)) return;
|
|
1150
|
-
document.documentElement.classList.remove(this.documentCursor);
|
|
1151
|
-
this.documentCursor = Grid.getCursorClassName(cursor);
|
|
1152
|
-
document.documentElement.classList.add(this.documentCursor);
|
|
1153
|
-
document.documentElement.classList.add('grid-block-events');
|
|
1154
|
-
}
|
|
1155
|
-
}, {
|
|
1156
|
-
key: "removeDocumentCursor",
|
|
1157
|
-
value: function removeDocumentCursor() {
|
|
1158
|
-
if (this.documentCursor) {
|
|
1159
|
-
document.documentElement.classList.remove(this.documentCursor);
|
|
1160
|
-
document.documentElement.classList.remove('grid-block-events');
|
|
1161
|
-
this.documentCursor = null;
|
|
1162
|
-
}
|
|
1096
|
+
if (model.isValidForCell(modelColumn, modelRow, value)) {
|
|
1097
|
+
model.setValueForCell(modelColumn, modelRow, value);
|
|
1163
1098
|
}
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
setValueForRanges(ranges, value) {
|
|
1102
|
+
var {
|
|
1103
|
+
model
|
|
1104
|
+
} = this.props;
|
|
1105
|
+
var {
|
|
1106
|
+
movedColumns,
|
|
1107
|
+
movedRows
|
|
1108
|
+
} = this.state;
|
|
1109
|
+
var modelRanges = GridUtils.getModelRanges(ranges, movedColumns, movedRows);
|
|
1110
|
+
model.setValueForRanges(modelRanges, value);
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
isSelected(row, column) {
|
|
1114
|
+
var {
|
|
1115
|
+
selectedRanges
|
|
1116
|
+
} = this.state;
|
|
1117
|
+
|
|
1118
|
+
for (var i = 0; i < selectedRanges.length; i += 1) {
|
|
1119
|
+
var selectedRange = selectedRanges[i];
|
|
1120
|
+
var rowSelected = selectedRange.startRow === null || selectedRange.startRow <= row && row <= selectedRange.endRow;
|
|
1121
|
+
var columnSelected = selectedRange.startColumn === null || selectedRange.startColumn <= column && column <= selectedRange.endColumn;
|
|
1122
|
+
|
|
1123
|
+
if (rowSelected && columnSelected) {
|
|
1124
|
+
return true;
|
|
1181
1125
|
}
|
|
1182
1126
|
}
|
|
1183
|
-
/**
|
|
1184
|
-
* When scrolling you've have to re-draw the whole canvas. As a consequence, all these drawing methods
|
|
1185
|
-
* must be very quick.
|
|
1186
|
-
*/
|
|
1187
1127
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
value: function drawCanvas() {
|
|
1191
|
-
var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
|
|
1192
|
-
var _this$state9 = this.state,
|
|
1193
|
-
left = _this$state9.left,
|
|
1194
|
-
top = _this$state9.top,
|
|
1195
|
-
cursorColumn = _this$state9.cursorColumn,
|
|
1196
|
-
cursorRow = _this$state9.cursorRow,
|
|
1197
|
-
draggingColumn = _this$state9.draggingColumn,
|
|
1198
|
-
draggingColumnOffset = _this$state9.draggingColumnOffset,
|
|
1199
|
-
draggingColumnSeparator = _this$state9.draggingColumnSeparator,
|
|
1200
|
-
draggingRow = _this$state9.draggingRow,
|
|
1201
|
-
draggingRowOffset = _this$state9.draggingRowOffset,
|
|
1202
|
-
draggingRowSeparator = _this$state9.draggingRowSeparator,
|
|
1203
|
-
editingCell = _this$state9.editingCell,
|
|
1204
|
-
isDraggingHorizontalScrollBar = _this$state9.isDraggingHorizontalScrollBar,
|
|
1205
|
-
isDraggingVerticalScrollBar = _this$state9.isDraggingVerticalScrollBar,
|
|
1206
|
-
isDragging = _this$state9.isDragging,
|
|
1207
|
-
mouseX = _this$state9.mouseX,
|
|
1208
|
-
mouseY = _this$state9.mouseY,
|
|
1209
|
-
selectedRanges = _this$state9.selectedRanges;
|
|
1210
|
-
var _this$props5 = this.props,
|
|
1211
|
-
model = _this$props5.model,
|
|
1212
|
-
stateOverride = _this$props5.stateOverride;
|
|
1213
|
-
var renderer = this.renderer;
|
|
1214
|
-
var context = this.canvasContext;
|
|
1215
|
-
var theme = this.getTheme();
|
|
1216
|
-
var width = this.canvas.clientWidth;
|
|
1217
|
-
var height = this.canvas.clientHeight;
|
|
1218
|
-
|
|
1219
|
-
var renderState = _objectSpread({
|
|
1220
|
-
left: left,
|
|
1221
|
-
top: top,
|
|
1222
|
-
width: width,
|
|
1223
|
-
height: height,
|
|
1224
|
-
context: context,
|
|
1225
|
-
theme: theme,
|
|
1226
|
-
model: model,
|
|
1227
|
-
metrics: metrics,
|
|
1228
|
-
mouseX: mouseX,
|
|
1229
|
-
mouseY: mouseY,
|
|
1230
|
-
selectedRanges: selectedRanges,
|
|
1231
|
-
draggingColumn: draggingColumn,
|
|
1232
|
-
draggingColumnOffset: draggingColumnOffset,
|
|
1233
|
-
draggingColumnSeparator: draggingColumnSeparator,
|
|
1234
|
-
draggingRow: draggingRow,
|
|
1235
|
-
draggingRowOffset: draggingRowOffset,
|
|
1236
|
-
draggingRowSeparator: draggingRowSeparator,
|
|
1237
|
-
editingCell: editingCell,
|
|
1238
|
-
isDraggingHorizontalScrollBar: isDraggingHorizontalScrollBar,
|
|
1239
|
-
isDraggingVerticalScrollBar: isDraggingVerticalScrollBar,
|
|
1240
|
-
isDragging: isDragging,
|
|
1241
|
-
cursorColumn: cursorColumn,
|
|
1242
|
-
cursorRow: cursorRow
|
|
1243
|
-
}, stateOverride);
|
|
1244
|
-
|
|
1245
|
-
context.save();
|
|
1246
|
-
renderer.drawCanvas(renderState);
|
|
1247
|
-
context.restore();
|
|
1248
|
-
}
|
|
1249
|
-
}, {
|
|
1250
|
-
key: "focus",
|
|
1251
|
-
value: function focus() {
|
|
1252
|
-
this.canvas.focus();
|
|
1253
|
-
}
|
|
1254
|
-
}, {
|
|
1255
|
-
key: "isFocused",
|
|
1256
|
-
value: function isFocused() {
|
|
1257
|
-
return document.activeElement === this.canvas;
|
|
1258
|
-
}
|
|
1259
|
-
}, {
|
|
1260
|
-
key: "handleClick",
|
|
1261
|
-
value: function handleClick(event) {
|
|
1262
|
-
var gridPoint = this.getGridPointFromEvent(event);
|
|
1263
|
-
var mouseHandlers = this.getMouseHandlers();
|
|
1264
|
-
|
|
1265
|
-
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1266
|
-
var mouseHandler = mouseHandlers[i];
|
|
1267
|
-
|
|
1268
|
-
if (mouseHandler.onClick(gridPoint, this, event)) {
|
|
1269
|
-
event.stopPropagation();
|
|
1270
|
-
event.preventDefault();
|
|
1271
|
-
break;
|
|
1272
|
-
}
|
|
1273
|
-
}
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1274
1130
|
|
|
1275
|
-
|
|
1131
|
+
addDocumentCursor() {
|
|
1132
|
+
var cursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
1133
|
+
if (this.documentCursor === Grid.getCursorClassName(cursor)) return;
|
|
1134
|
+
document.documentElement.classList.remove(this.documentCursor);
|
|
1135
|
+
this.documentCursor = Grid.getCursorClassName(cursor);
|
|
1136
|
+
document.documentElement.classList.add(this.documentCursor);
|
|
1137
|
+
document.documentElement.classList.add('grid-block-events');
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
removeDocumentCursor() {
|
|
1141
|
+
if (this.documentCursor) {
|
|
1142
|
+
document.documentElement.classList.remove(this.documentCursor);
|
|
1143
|
+
document.documentElement.classList.remove('grid-block-events');
|
|
1144
|
+
this.documentCursor = null;
|
|
1276
1145
|
}
|
|
1277
|
-
}
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
startDragTimer(event) {
|
|
1149
|
+
this.stopDragTimer();
|
|
1150
|
+
var mouseEvent = new MouseEvent('custom', event);
|
|
1151
|
+
this.dragTimer = setTimeout(() => {
|
|
1152
|
+
this.handleMouseDrag(mouseEvent);
|
|
1153
|
+
}, Grid.dragTimeout);
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
stopDragTimer() {
|
|
1157
|
+
if (this.dragTimer) {
|
|
1158
|
+
clearTimeout(this.dragTimer);
|
|
1159
|
+
this.dragTimer = null;
|
|
1292
1160
|
}
|
|
1293
|
-
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* When scrolling you've have to re-draw the whole canvas. As a consequence, all these drawing methods
|
|
1164
|
+
* must be very quick.
|
|
1165
|
+
*/
|
|
1166
|
+
|
|
1167
|
+
|
|
1168
|
+
drawCanvas() {
|
|
1169
|
+
var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
|
|
1170
|
+
var {
|
|
1171
|
+
left,
|
|
1172
|
+
top,
|
|
1173
|
+
cursorColumn,
|
|
1174
|
+
cursorRow,
|
|
1175
|
+
draggingColumn,
|
|
1176
|
+
draggingColumnOffset,
|
|
1177
|
+
draggingColumnSeparator,
|
|
1178
|
+
draggingRow,
|
|
1179
|
+
draggingRowOffset,
|
|
1180
|
+
draggingRowSeparator,
|
|
1181
|
+
editingCell,
|
|
1182
|
+
isDraggingHorizontalScrollBar,
|
|
1183
|
+
isDraggingVerticalScrollBar,
|
|
1184
|
+
isDragging,
|
|
1185
|
+
mouseX,
|
|
1186
|
+
mouseY,
|
|
1187
|
+
selectedRanges
|
|
1188
|
+
} = this.state;
|
|
1189
|
+
var {
|
|
1190
|
+
model,
|
|
1191
|
+
stateOverride
|
|
1192
|
+
} = this.props;
|
|
1193
|
+
var {
|
|
1194
|
+
renderer
|
|
1195
|
+
} = this;
|
|
1196
|
+
var context = this.canvasContext;
|
|
1197
|
+
var theme = this.getTheme();
|
|
1198
|
+
var width = this.canvas.clientWidth;
|
|
1199
|
+
var height = this.canvas.clientHeight;
|
|
1200
|
+
|
|
1201
|
+
var renderState = _objectSpread({
|
|
1202
|
+
left,
|
|
1203
|
+
top,
|
|
1204
|
+
width,
|
|
1205
|
+
height,
|
|
1206
|
+
context,
|
|
1207
|
+
theme,
|
|
1208
|
+
model,
|
|
1209
|
+
metrics,
|
|
1210
|
+
mouseX,
|
|
1211
|
+
mouseY,
|
|
1212
|
+
selectedRanges,
|
|
1213
|
+
draggingColumn,
|
|
1214
|
+
draggingColumnOffset,
|
|
1215
|
+
draggingColumnSeparator,
|
|
1216
|
+
draggingRow,
|
|
1217
|
+
draggingRowOffset,
|
|
1218
|
+
draggingRowSeparator,
|
|
1219
|
+
editingCell,
|
|
1220
|
+
isDraggingHorizontalScrollBar,
|
|
1221
|
+
isDraggingVerticalScrollBar,
|
|
1222
|
+
isDragging,
|
|
1223
|
+
cursorColumn,
|
|
1224
|
+
cursorRow
|
|
1225
|
+
}, stateOverride);
|
|
1226
|
+
|
|
1227
|
+
context.save();
|
|
1228
|
+
renderer.drawCanvas(renderState);
|
|
1229
|
+
context.restore();
|
|
1230
|
+
}
|
|
1297
1231
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1232
|
+
focus() {
|
|
1233
|
+
this.canvas.focus();
|
|
1234
|
+
}
|
|
1301
1235
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1236
|
+
isFocused() {
|
|
1237
|
+
return document.activeElement === this.canvas;
|
|
1238
|
+
}
|
|
1304
1239
|
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1240
|
+
handleClick(event) {
|
|
1241
|
+
var gridPoint = this.getGridPointFromEvent(event);
|
|
1242
|
+
var mouseHandlers = this.getMouseHandlers();
|
|
1243
|
+
|
|
1244
|
+
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1245
|
+
var mouseHandler = mouseHandlers[i];
|
|
1246
|
+
|
|
1247
|
+
if (mouseHandler.onClick(gridPoint, this, event)) {
|
|
1248
|
+
event.stopPropagation();
|
|
1249
|
+
event.preventDefault();
|
|
1250
|
+
break;
|
|
1309
1251
|
}
|
|
1310
1252
|
}
|
|
1311
|
-
/**
|
|
1312
|
-
* Notify all of the mouse handlers for this grid of a mouse event.
|
|
1313
|
-
* @param {String} functionName The name of the function in the mouse handler to call
|
|
1314
|
-
* @param {MouseEvent} event The mouse event to notify
|
|
1315
|
-
* @param {Boolean} updateCoordinates Whether to update the mouse coordinates
|
|
1316
|
-
* @param {Boolean} addCursorToDocument Whether to add a cursor overlay or not (for dragging)
|
|
1317
|
-
*/
|
|
1318
1253
|
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
value: function notifyMouseHandlers(functionName, event) {
|
|
1322
|
-
var updateCoordinates = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
1323
|
-
var addCursorToDocument = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1324
|
-
var gridPoint = this.getGridPointFromEvent(event);
|
|
1325
|
-
var mouseHandlers = this.getMouseHandlers();
|
|
1326
|
-
var cursor = null;
|
|
1254
|
+
this.canvas.focus();
|
|
1255
|
+
}
|
|
1327
1256
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1257
|
+
handleContextMenu(event) {
|
|
1258
|
+
var gridPoint = this.getGridPointFromEvent(event);
|
|
1259
|
+
var mouseHandlers = this.getMouseHandlers();
|
|
1331
1260
|
|
|
1332
|
-
|
|
1333
|
-
|
|
1261
|
+
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1262
|
+
var mouseHandler = mouseHandlers[i];
|
|
1334
1263
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1264
|
+
if (mouseHandler.onContextMenu(gridPoint, this, event)) {
|
|
1265
|
+
event.stopPropagation();
|
|
1266
|
+
event.preventDefault();
|
|
1267
|
+
break;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1337
1271
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
}
|
|
1341
|
-
} // result is bool or object, events are stopped by default
|
|
1272
|
+
handleKeyDown(e) {
|
|
1273
|
+
var keyHandlers = this.getKeyHandlers();
|
|
1342
1274
|
|
|
1275
|
+
for (var i = 0; i < keyHandlers.length; i += 1) {
|
|
1276
|
+
var keyHandler = keyHandlers[i];
|
|
1277
|
+
var result = keyHandler.onDown(e, this);
|
|
1343
1278
|
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1279
|
+
if (result) {
|
|
1280
|
+
var _result$stopPropagati, _result$preventDefaul;
|
|
1281
|
+
|
|
1282
|
+
if ((_result$stopPropagati = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati !== void 0 ? _result$stopPropagati : true) e.stopPropagation();
|
|
1283
|
+
if ((_result$preventDefaul = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul !== void 0 ? _result$preventDefaul : true) e.preventDefault();
|
|
1284
|
+
break;
|
|
1348
1285
|
}
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
/**
|
|
1289
|
+
* Notify all of the mouse handlers for this grid of a mouse event.
|
|
1290
|
+
* @param {String} functionName The name of the function in the mouse handler to call
|
|
1291
|
+
* @param {MouseEvent} event The mouse event to notify
|
|
1292
|
+
* @param {Boolean} updateCoordinates Whether to update the mouse coordinates
|
|
1293
|
+
* @param {Boolean} addCursorToDocument Whether to add a cursor overlay or not (for dragging)
|
|
1294
|
+
*/
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
notifyMouseHandlers(functionName, event) {
|
|
1298
|
+
var updateCoordinates = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
1299
|
+
var addCursorToDocument = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
1300
|
+
var gridPoint = this.getGridPointFromEvent(event);
|
|
1301
|
+
var mouseHandlers = this.getMouseHandlers();
|
|
1302
|
+
var cursor = null;
|
|
1303
|
+
|
|
1304
|
+
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1305
|
+
var mouseHandler = mouseHandlers[i];
|
|
1306
|
+
var result = mouseHandler[functionName] && mouseHandler[functionName](gridPoint, this, event);
|
|
1307
|
+
|
|
1308
|
+
if (result) {
|
|
1309
|
+
var _result$stopPropagati2, _result$preventDefaul2;
|
|
1310
|
+
|
|
1311
|
+
if (mouseHandler.cursor != null) {
|
|
1312
|
+
({
|
|
1313
|
+
cursor
|
|
1314
|
+
} = mouseHandler);
|
|
1315
|
+
|
|
1316
|
+
if (addCursorToDocument) {
|
|
1317
|
+
this.addDocumentCursor(cursor);
|
|
1318
|
+
}
|
|
1319
|
+
} // result is bool or object, events are stopped by default
|
|
1349
1320
|
|
|
1350
|
-
this.setState({
|
|
1351
|
-
cursor: cursor
|
|
1352
|
-
});
|
|
1353
1321
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
this.setState({
|
|
1358
|
-
mouseX: x,
|
|
1359
|
-
mouseY: y
|
|
1360
|
-
});
|
|
1322
|
+
if ((_result$stopPropagati2 = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati2 !== void 0 ? _result$stopPropagati2 : true) event.stopPropagation();
|
|
1323
|
+
if ((_result$preventDefaul2 = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul2 !== void 0 ? _result$preventDefaul2 : true) event.preventDefault();
|
|
1324
|
+
break;
|
|
1361
1325
|
}
|
|
1362
1326
|
}
|
|
1363
|
-
}, {
|
|
1364
|
-
key: "handleMouseDown",
|
|
1365
|
-
value: function handleMouseDown(event) {
|
|
1366
|
-
window.addEventListener('mousemove', this.handleMouseDrag, true);
|
|
1367
|
-
window.addEventListener('mouseup', this.handleMouseUp, true);
|
|
1368
|
-
|
|
1369
|
-
if (event.button != null && event.button !== 0) {
|
|
1370
|
-
return;
|
|
1371
|
-
}
|
|
1372
1327
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
key: "handleMouseMove",
|
|
1383
|
-
value: function handleMouseMove(event) {
|
|
1384
|
-
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.MOVE, event);
|
|
1385
|
-
}
|
|
1386
|
-
}, {
|
|
1387
|
-
key: "handleMouseLeave",
|
|
1388
|
-
value: function handleMouseLeave(event) {
|
|
1389
|
-
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.LEAVE, event, false);
|
|
1328
|
+
this.setState({
|
|
1329
|
+
cursor
|
|
1330
|
+
});
|
|
1331
|
+
|
|
1332
|
+
if (updateCoordinates) {
|
|
1333
|
+
var {
|
|
1334
|
+
x,
|
|
1335
|
+
y
|
|
1336
|
+
} = gridPoint;
|
|
1390
1337
|
this.setState({
|
|
1391
|
-
mouseX:
|
|
1392
|
-
mouseY:
|
|
1338
|
+
mouseX: x,
|
|
1339
|
+
mouseY: y
|
|
1393
1340
|
});
|
|
1394
1341
|
}
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
handleMouseDown(event) {
|
|
1345
|
+
window.addEventListener('mousemove', this.handleMouseDrag, true);
|
|
1346
|
+
window.addEventListener('mouseup', this.handleMouseUp, true);
|
|
1347
|
+
|
|
1348
|
+
if (event.button != null && event.button !== 0) {
|
|
1349
|
+
return;
|
|
1403
1350
|
}
|
|
1404
|
-
}, {
|
|
1405
|
-
key: "handleMouseUp",
|
|
1406
|
-
value: function handleMouseUp(event) {
|
|
1407
|
-
window.removeEventListener('mousemove', this.handleMouseDrag, true);
|
|
1408
|
-
window.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
1409
|
-
|
|
1410
|
-
if (event.button != null && event.button !== 0) {
|
|
1411
|
-
return;
|
|
1412
|
-
}
|
|
1413
1351
|
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1352
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOWN, event);
|
|
1353
|
+
this.startDragTimer(event);
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
handleDoubleClick(event) {
|
|
1357
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOUBLE_CLICK, event);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
handleMouseMove(event) {
|
|
1361
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.MOVE, event);
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1364
|
+
handleMouseLeave(event) {
|
|
1365
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.LEAVE, event, false);
|
|
1366
|
+
this.setState({
|
|
1367
|
+
mouseX: null,
|
|
1368
|
+
mouseY: null
|
|
1369
|
+
});
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
handleMouseDrag(event) {
|
|
1373
|
+
this.setState({
|
|
1374
|
+
isDragging: true
|
|
1375
|
+
});
|
|
1376
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DRAG, event, true, true);
|
|
1377
|
+
this.stopDragTimer();
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
handleMouseUp(event) {
|
|
1381
|
+
window.removeEventListener('mousemove', this.handleMouseDrag, true);
|
|
1382
|
+
window.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
1383
|
+
|
|
1384
|
+
if (event.button != null && event.button !== 0) {
|
|
1385
|
+
return;
|
|
1417
1386
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1387
|
+
|
|
1388
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.UP, event, false);
|
|
1389
|
+
this.stopDragTimer();
|
|
1390
|
+
this.removeDocumentCursor();
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
handleResize() {
|
|
1394
|
+
/**
|
|
1395
|
+
* We need to always redraw the canvas in the same frame as the updateCanvasScale
|
|
1396
|
+
* because it clears the canvas by nature of direct dom manipulation. However,
|
|
1397
|
+
* We also need to verify the state/metrics, which we currently have no way
|
|
1398
|
+
* of doing outside of a full componentDidUpdate() call, so we force the update.
|
|
1399
|
+
* Ideally, we could verify state/metrics without the forced update.
|
|
1400
|
+
*/
|
|
1401
|
+
this.updateCanvasScale();
|
|
1402
|
+
this.updateCanvas();
|
|
1403
|
+
this.forceUpdate();
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
handleWheel(e) {
|
|
1407
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.WHEEL, e);
|
|
1408
|
+
|
|
1409
|
+
if (e.defaultPrevented) {
|
|
1410
|
+
return;
|
|
1431
1411
|
}
|
|
1432
|
-
}, {
|
|
1433
|
-
key: "handleWheel",
|
|
1434
|
-
value: function handleWheel(e) {
|
|
1435
|
-
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.WHEEL, e);
|
|
1436
1412
|
|
|
1437
|
-
|
|
1438
|
-
|
|
1413
|
+
var {
|
|
1414
|
+
metricCalculator,
|
|
1415
|
+
metrics
|
|
1416
|
+
} = this;
|
|
1417
|
+
var metricState = this.getMetricState();
|
|
1418
|
+
var {
|
|
1419
|
+
lastTop,
|
|
1420
|
+
lastLeft
|
|
1421
|
+
} = metrics;
|
|
1422
|
+
var {
|
|
1423
|
+
top,
|
|
1424
|
+
left,
|
|
1425
|
+
topOffset,
|
|
1426
|
+
leftOffset
|
|
1427
|
+
} = metrics;
|
|
1428
|
+
var theme = this.getTheme();
|
|
1429
|
+
var {
|
|
1430
|
+
deltaX,
|
|
1431
|
+
deltaY
|
|
1432
|
+
} = GridUtils.getScrollDelta(e, metrics.barWidth, metrics.barHeight, metrics.rowHeight, metrics.rowHeight); // iterate through each column to determine column width and figure out how far to scroll
|
|
1433
|
+
// get column width of next column to scroll to, and subract it from the remaining distance to travel
|
|
1434
|
+
|
|
1435
|
+
while (deltaX !== 0) {
|
|
1436
|
+
leftOffset += deltaX;
|
|
1437
|
+
deltaX = 0; // no scrolling needed, at directional edge
|
|
1438
|
+
|
|
1439
|
+
if (leftOffset > 0 && left >= lastLeft || leftOffset < 0 && left <= 0) {
|
|
1440
|
+
leftOffset = 0;
|
|
1441
|
+
break;
|
|
1439
1442
|
}
|
|
1440
1443
|
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
var metricState = this.getMetricState();
|
|
1444
|
-
var lastTop = metrics.lastTop,
|
|
1445
|
-
lastLeft = metrics.lastLeft;
|
|
1446
|
-
var top = metrics.top,
|
|
1447
|
-
left = metrics.left,
|
|
1448
|
-
topOffset = metrics.topOffset,
|
|
1449
|
-
leftOffset = metrics.leftOffset;
|
|
1450
|
-
var theme = this.getTheme();
|
|
1444
|
+
if (leftOffset > 0) {
|
|
1445
|
+
var _metrics$visibleColum;
|
|
1451
1446
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
// get column width of next column to scroll to, and subract it from the remaining distance to travel
|
|
1447
|
+
// scroll right
|
|
1448
|
+
// get width of next column
|
|
1449
|
+
var columnWidth = (_metrics$visibleColum = metrics.visibleColumnWidths.get(left)) !== null && _metrics$visibleColum !== void 0 ? _metrics$visibleColum : metricCalculator.getVisibleColumnWidth(left, metricState);
|
|
1456
1450
|
|
|
1451
|
+
if (leftOffset >= columnWidth) {
|
|
1452
|
+
// remove width from balance and advance by 1 column
|
|
1453
|
+
deltaX = leftOffset - columnWidth;
|
|
1454
|
+
leftOffset = 0;
|
|
1455
|
+
left += 1;
|
|
1456
|
+
} else if (theme.scrollSnapToColumn) {
|
|
1457
|
+
// if there's still a balance to travel but its less then a column and snapping is on
|
|
1458
|
+
leftOffset = 0;
|
|
1459
|
+
left += 1;
|
|
1460
|
+
}
|
|
1461
|
+
} else if (leftOffset < 0) {
|
|
1462
|
+
var _metrics$visibleColum2;
|
|
1457
1463
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1464
|
+
// scroll left
|
|
1465
|
+
// get width of next column
|
|
1466
|
+
var _columnWidth = (_metrics$visibleColum2 = metrics.visibleColumnWidths.get(left - 1)) !== null && _metrics$visibleColum2 !== void 0 ? _metrics$visibleColum2 : metricCalculator.getVisibleColumnWidth(left - 1, metricState);
|
|
1461
1467
|
|
|
1462
|
-
if (leftOffset
|
|
1468
|
+
if (Math.abs(leftOffset) <= _columnWidth && theme.scrollSnapToColumn) {
|
|
1469
|
+
// if there's still a balance to travel but its less then a column and snapping is on
|
|
1470
|
+
leftOffset = 0;
|
|
1471
|
+
left -= 1;
|
|
1472
|
+
} else {
|
|
1473
|
+
// remove width from balance and advance by 1 column
|
|
1474
|
+
deltaX = leftOffset + _columnWidth;
|
|
1463
1475
|
leftOffset = 0;
|
|
1464
|
-
|
|
1476
|
+
left -= 1;
|
|
1465
1477
|
}
|
|
1478
|
+
}
|
|
1479
|
+
} // iterate through each row to determine row height and figure out how far to scroll
|
|
1480
|
+
// get row height of next row to scroll to, and subract it from the remaining distance to travel
|
|
1466
1481
|
|
|
1467
|
-
if (leftOffset > 0) {
|
|
1468
|
-
var _metrics$visibleColum;
|
|
1469
|
-
|
|
1470
|
-
// scroll right
|
|
1471
|
-
// get width of next column
|
|
1472
|
-
var columnWidth = (_metrics$visibleColum = metrics.visibleColumnWidths.get(left)) !== null && _metrics$visibleColum !== void 0 ? _metrics$visibleColum : metricCalculator.getVisibleColumnWidth(left, metricState);
|
|
1473
|
-
|
|
1474
|
-
if (leftOffset >= columnWidth) {
|
|
1475
|
-
// remove width from balance and advance by 1 column
|
|
1476
|
-
deltaX = leftOffset - columnWidth;
|
|
1477
|
-
leftOffset = 0;
|
|
1478
|
-
left += 1;
|
|
1479
|
-
} else if (theme.scrollSnapToColumn) {
|
|
1480
|
-
// if there's still a balance to travel but its less then a column and snapping is on
|
|
1481
|
-
leftOffset = 0;
|
|
1482
|
-
left += 1;
|
|
1483
|
-
}
|
|
1484
|
-
} else if (leftOffset < 0) {
|
|
1485
|
-
var _metrics$visibleColum2;
|
|
1486
|
-
|
|
1487
|
-
// scroll left
|
|
1488
|
-
// get width of next column
|
|
1489
|
-
var _columnWidth = (_metrics$visibleColum2 = metrics.visibleColumnWidths.get(left - 1)) !== null && _metrics$visibleColum2 !== void 0 ? _metrics$visibleColum2 : metricCalculator.getVisibleColumnWidth(left - 1, metricState);
|
|
1490
|
-
|
|
1491
|
-
if (Math.abs(leftOffset) <= _columnWidth && theme.scrollSnapToColumn) {
|
|
1492
|
-
// if there's still a balance to travel but its less then a column and snapping is on
|
|
1493
|
-
leftOffset = 0;
|
|
1494
|
-
left -= 1;
|
|
1495
|
-
} else {
|
|
1496
|
-
// remove width from balance and advance by 1 column
|
|
1497
|
-
deltaX = leftOffset + _columnWidth;
|
|
1498
|
-
leftOffset = 0;
|
|
1499
|
-
left -= 1;
|
|
1500
|
-
}
|
|
1501
|
-
}
|
|
1502
|
-
} // iterate through each row to determine row height and figure out how far to scroll
|
|
1503
|
-
// get row height of next row to scroll to, and subract it from the remaining distance to travel
|
|
1504
1482
|
|
|
1483
|
+
while (deltaY !== 0) {
|
|
1484
|
+
topOffset += deltaY;
|
|
1485
|
+
deltaY = 0; // no scrolling needed, at directional edge
|
|
1486
|
+
|
|
1487
|
+
if (topOffset > 0 && top >= lastTop || topOffset < 0 && top <= 0) {
|
|
1488
|
+
topOffset = 0;
|
|
1489
|
+
break;
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
if (topOffset > 0) {
|
|
1493
|
+
var _metrics$visibleRowHe;
|
|
1505
1494
|
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1495
|
+
// scroll direction down
|
|
1496
|
+
// get height of next row
|
|
1497
|
+
var rowHeight = (_metrics$visibleRowHe = metrics.visibleRowHeights.get(top)) !== null && _metrics$visibleRowHe !== void 0 ? _metrics$visibleRowHe : metricCalculator.getVisibleRowHeight(top, metricState);
|
|
1509
1498
|
|
|
1510
|
-
if (topOffset
|
|
1499
|
+
if (topOffset >= rowHeight) {
|
|
1500
|
+
// remove height from balance and advance by 1 row
|
|
1501
|
+
deltaY = topOffset - rowHeight;
|
|
1502
|
+
topOffset = 0;
|
|
1503
|
+
top += 1;
|
|
1504
|
+
} else if (theme.scrollSnapToRow) {
|
|
1505
|
+
// if there's still a balance to travel but its less then a row and snapping is on
|
|
1511
1506
|
topOffset = 0;
|
|
1512
|
-
|
|
1507
|
+
top += 1;
|
|
1513
1508
|
}
|
|
1509
|
+
} else if (topOffset < 0) {
|
|
1510
|
+
var _metrics$visibleRowHe2;
|
|
1514
1511
|
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
// if there's still a balance to travel but its less then a row and snapping is on
|
|
1529
|
-
topOffset = 0;
|
|
1530
|
-
top += 1;
|
|
1531
|
-
}
|
|
1532
|
-
} else if (topOffset < 0) {
|
|
1533
|
-
var _metrics$visibleRowHe2;
|
|
1534
|
-
|
|
1535
|
-
// scroll direction up
|
|
1536
|
-
// get height of next row
|
|
1537
|
-
var _rowHeight = (_metrics$visibleRowHe2 = metrics.visibleRowHeights.get(top - 1)) !== null && _metrics$visibleRowHe2 !== void 0 ? _metrics$visibleRowHe2 : metricCalculator.getVisibleRowHeight(top - 1, metricState);
|
|
1538
|
-
|
|
1539
|
-
if (Math.abs(topOffset) <= _rowHeight && theme.scrollSnapToRow) {
|
|
1540
|
-
// if there's still a balance to travel but its less then a row and snapping is on
|
|
1541
|
-
topOffset = 0;
|
|
1542
|
-
top -= 1;
|
|
1543
|
-
} else {
|
|
1544
|
-
// remove height from balance and advance by 1 row
|
|
1545
|
-
deltaY = topOffset + _rowHeight;
|
|
1546
|
-
topOffset = 0;
|
|
1547
|
-
top -= 1;
|
|
1548
|
-
}
|
|
1512
|
+
// scroll direction up
|
|
1513
|
+
// get height of next row
|
|
1514
|
+
var _rowHeight = (_metrics$visibleRowHe2 = metrics.visibleRowHeights.get(top - 1)) !== null && _metrics$visibleRowHe2 !== void 0 ? _metrics$visibleRowHe2 : metricCalculator.getVisibleRowHeight(top - 1, metricState);
|
|
1515
|
+
|
|
1516
|
+
if (Math.abs(topOffset) <= _rowHeight && theme.scrollSnapToRow) {
|
|
1517
|
+
// if there's still a balance to travel but its less then a row and snapping is on
|
|
1518
|
+
topOffset = 0;
|
|
1519
|
+
top -= 1;
|
|
1520
|
+
} else {
|
|
1521
|
+
// remove height from balance and advance by 1 row
|
|
1522
|
+
deltaY = topOffset + _rowHeight;
|
|
1523
|
+
topOffset = 0;
|
|
1524
|
+
top -= 1;
|
|
1549
1525
|
}
|
|
1550
1526
|
}
|
|
1551
|
-
|
|
1552
|
-
this.setViewState({
|
|
1553
|
-
top: top,
|
|
1554
|
-
left: left,
|
|
1555
|
-
leftOffset: leftOffset,
|
|
1556
|
-
topOffset: topOffset
|
|
1557
|
-
});
|
|
1558
|
-
e.stopPropagation();
|
|
1559
|
-
e.preventDefault();
|
|
1560
1527
|
}
|
|
1561
|
-
}, {
|
|
1562
|
-
key: "handleEditCellCancel",
|
|
1563
|
-
value: function handleEditCellCancel() {
|
|
1564
|
-
this.setState({
|
|
1565
|
-
editingCell: null
|
|
1566
|
-
});
|
|
1567
|
-
this.focus();
|
|
1568
|
-
}
|
|
1569
|
-
}, {
|
|
1570
|
-
key: "handleEditCellChange",
|
|
1571
|
-
value: function handleEditCellChange(value) {
|
|
1572
|
-
this.setState(function (_ref) {
|
|
1573
|
-
var editingCell = _ref.editingCell;
|
|
1574
|
-
return {
|
|
1575
|
-
editingCell: _objectSpread(_objectSpread({}, editingCell), {}, {
|
|
1576
|
-
value: value
|
|
1577
|
-
})
|
|
1578
|
-
};
|
|
1579
|
-
});
|
|
1580
|
-
}
|
|
1581
|
-
}, {
|
|
1582
|
-
key: "handleEditCellCommit",
|
|
1583
|
-
value: function handleEditCellCommit(value) {
|
|
1584
|
-
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
1585
|
-
_ref2$direction = _ref2.direction,
|
|
1586
|
-
direction = _ref2$direction === void 0 ? GridRange.SELECTION_DIRECTION.DOWN : _ref2$direction,
|
|
1587
|
-
_ref2$fillRange = _ref2.fillRange,
|
|
1588
|
-
fillRange = _ref2$fillRange === void 0 ? false : _ref2$fillRange;
|
|
1589
|
-
|
|
1590
|
-
var _this$state10 = this.state,
|
|
1591
|
-
column = _this$state10.cursorColumn,
|
|
1592
|
-
row = _this$state10.cursorRow,
|
|
1593
|
-
selectedRanges = _this$state10.selectedRanges;
|
|
1594
|
-
|
|
1595
|
-
if (!this.isValidForCell(column, row, value)) {
|
|
1596
|
-
// Don't allow an invalid value to be commited, the editing cell should show an error
|
|
1597
|
-
if (direction == null) {
|
|
1598
|
-
// If they clicked off of the editing cell, just remove focus
|
|
1599
|
-
this.setState({
|
|
1600
|
-
editingCell: null
|
|
1601
|
-
});
|
|
1602
|
-
}
|
|
1603
1528
|
|
|
1604
|
-
|
|
1605
|
-
|
|
1529
|
+
this.setViewState({
|
|
1530
|
+
top,
|
|
1531
|
+
left,
|
|
1532
|
+
leftOffset,
|
|
1533
|
+
topOffset
|
|
1534
|
+
});
|
|
1535
|
+
e.stopPropagation();
|
|
1536
|
+
e.preventDefault();
|
|
1537
|
+
}
|
|
1606
1538
|
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1539
|
+
handleEditCellCancel() {
|
|
1540
|
+
this.setState({
|
|
1541
|
+
editingCell: null
|
|
1542
|
+
});
|
|
1543
|
+
this.focus();
|
|
1544
|
+
}
|
|
1612
1545
|
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1546
|
+
handleEditCellChange(value) {
|
|
1547
|
+
this.setState((_ref) => {
|
|
1548
|
+
var {
|
|
1549
|
+
editingCell
|
|
1550
|
+
} = _ref;
|
|
1551
|
+
return {
|
|
1552
|
+
editingCell: _objectSpread(_objectSpread({}, editingCell), {}, {
|
|
1553
|
+
value
|
|
1554
|
+
})
|
|
1555
|
+
};
|
|
1556
|
+
});
|
|
1557
|
+
}
|
|
1616
1558
|
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1559
|
+
handleEditCellCommit(value) {
|
|
1560
|
+
var {
|
|
1561
|
+
direction = GridRange.SELECTION_DIRECTION.DOWN,
|
|
1562
|
+
fillRange = false
|
|
1563
|
+
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
1564
|
+
var {
|
|
1565
|
+
cursorColumn: column,
|
|
1566
|
+
cursorRow: row,
|
|
1567
|
+
selectedRanges
|
|
1568
|
+
} = this.state;
|
|
1569
|
+
|
|
1570
|
+
if (!this.isValidForCell(column, row, value)) {
|
|
1571
|
+
// Don't allow an invalid value to be commited, the editing cell should show an error
|
|
1572
|
+
if (direction == null) {
|
|
1573
|
+
// If they clicked off of the editing cell, just remove focus
|
|
1574
|
+
this.setState({
|
|
1575
|
+
editingCell: null
|
|
1576
|
+
});
|
|
1631
1577
|
}
|
|
1632
1578
|
|
|
1633
|
-
|
|
1634
|
-
selectionRange = _editingCell$selectio === void 0 ? null : _editingCell$selectio,
|
|
1635
|
-
value = editingCell.value,
|
|
1636
|
-
isQuickEdit = editingCell.isQuickEdit;
|
|
1637
|
-
var _this$state11 = this.state,
|
|
1638
|
-
row = _this$state11.cursorRow,
|
|
1639
|
-
column = _this$state11.cursorColumn;
|
|
1640
|
-
var gridX = metrics.gridX,
|
|
1641
|
-
gridY = metrics.gridY,
|
|
1642
|
-
visibleColumnXs = metrics.visibleColumnXs,
|
|
1643
|
-
visibleRowYs = metrics.visibleRowYs,
|
|
1644
|
-
visibleColumnWidths = metrics.visibleColumnWidths,
|
|
1645
|
-
visibleRowHeights = metrics.visibleRowHeights;
|
|
1646
|
-
var x = visibleColumnXs.get(column);
|
|
1647
|
-
var y = visibleRowYs.get(row);
|
|
1648
|
-
var w = visibleColumnWidths.get(column);
|
|
1649
|
-
var h = visibleRowHeights.get(row);
|
|
1650
|
-
var isVisible = x != null && y != null && w != null && h != null; // If the cell isn't visible, we still need to display an invisible cell for focus purposes
|
|
1651
|
-
|
|
1652
|
-
var wrapperStyle = isVisible ? {
|
|
1653
|
-
position: 'absolute',
|
|
1654
|
-
left: gridX + x,
|
|
1655
|
-
top: gridY + y,
|
|
1656
|
-
width: w,
|
|
1657
|
-
height: h
|
|
1658
|
-
} : {
|
|
1659
|
-
opacity: 0
|
|
1660
|
-
};
|
|
1661
|
-
var modelColumn = this.getModelColumn(column);
|
|
1662
|
-
var modelRow = this.getModelRow(row);
|
|
1663
|
-
var inputStyle = modelColumn != null && modelRow != null ? {
|
|
1664
|
-
textAlign: model.textAlignForCell(modelColumn, modelRow)
|
|
1665
|
-
} : null;
|
|
1666
|
-
var isValid = model.isValidForCell(modelColumn, modelRow, value);
|
|
1667
|
-
return /*#__PURE__*/React.createElement("div", {
|
|
1668
|
-
style: wrapperStyle
|
|
1669
|
-
}, /*#__PURE__*/React.createElement(CellInputField, {
|
|
1670
|
-
key: "".concat(column, ",").concat(row),
|
|
1671
|
-
selectionRange: selectionRange,
|
|
1672
|
-
className: classNames({
|
|
1673
|
-
error: !isValid
|
|
1674
|
-
}),
|
|
1675
|
-
onCancel: this.handleEditCellCancel,
|
|
1676
|
-
onChange: this.handleEditCellChange,
|
|
1677
|
-
onDone: this.handleEditCellCommit,
|
|
1678
|
-
isQuickEdit: isQuickEdit,
|
|
1679
|
-
style: inputStyle,
|
|
1680
|
-
value: value
|
|
1681
|
-
}));
|
|
1579
|
+
return;
|
|
1682
1580
|
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
var cursor = this.state.cursor;
|
|
1689
|
-
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("canvas", {
|
|
1690
|
-
className: classNames('grid-canvas', Grid.getCursorClassName(cursor)),
|
|
1691
|
-
ref: function ref(canvas) {
|
|
1692
|
-
_this6.canvas = canvas;
|
|
1693
|
-
},
|
|
1694
|
-
onClick: this.handleClick,
|
|
1695
|
-
onContextMenu: this.handleContextMenu,
|
|
1696
|
-
onDoubleClick: this.handleDoubleClick,
|
|
1697
|
-
onKeyDown: this.handleKeyDown,
|
|
1698
|
-
onMouseDown: this.handleMouseDown,
|
|
1699
|
-
onMouseMove: this.handleMouseMove,
|
|
1700
|
-
onMouseLeave: this.handleMouseLeave,
|
|
1701
|
-
tabIndex: 0
|
|
1702
|
-
}, "Your browser does not support HTML canvas. Update your browser?"), this.renderInputField());
|
|
1581
|
+
|
|
1582
|
+
if (fillRange) {
|
|
1583
|
+
this.setValueForRanges(selectedRanges, value);
|
|
1584
|
+
} else {
|
|
1585
|
+
this.setValueForCell(column, row, value);
|
|
1703
1586
|
}
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
// https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285
|
|
1708
|
-
function getScale(context) {
|
|
1709
|
-
var devicePixelRatio = window.devicePixelRatio || 1;
|
|
1710
|
-
var backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
|
|
1711
|
-
return devicePixelRatio / backingStorePixelRatio;
|
|
1587
|
+
|
|
1588
|
+
if (direction != null) {
|
|
1589
|
+
this.moveCursorInDirection(direction);
|
|
1712
1590
|
}
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1591
|
+
|
|
1592
|
+
this.setState({
|
|
1593
|
+
editingCell: null
|
|
1594
|
+
});
|
|
1595
|
+
this.focus();
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
renderInputField() {
|
|
1599
|
+
var {
|
|
1600
|
+
model
|
|
1601
|
+
} = this.props;
|
|
1602
|
+
var {
|
|
1603
|
+
editingCell
|
|
1604
|
+
} = this.state;
|
|
1605
|
+
var {
|
|
1606
|
+
metrics
|
|
1607
|
+
} = this;
|
|
1608
|
+
|
|
1609
|
+
if (editingCell == null || metrics == null) {
|
|
1610
|
+
return null;
|
|
1717
1611
|
}
|
|
1718
|
-
}]);
|
|
1719
1612
|
|
|
1720
|
-
|
|
1721
|
-
|
|
1613
|
+
var {
|
|
1614
|
+
selectionRange = null,
|
|
1615
|
+
value,
|
|
1616
|
+
isQuickEdit
|
|
1617
|
+
} = editingCell;
|
|
1618
|
+
var {
|
|
1619
|
+
cursorRow: row,
|
|
1620
|
+
cursorColumn: column
|
|
1621
|
+
} = this.state;
|
|
1622
|
+
var {
|
|
1623
|
+
gridX,
|
|
1624
|
+
gridY,
|
|
1625
|
+
visibleColumnXs,
|
|
1626
|
+
visibleRowYs,
|
|
1627
|
+
visibleColumnWidths,
|
|
1628
|
+
visibleRowHeights
|
|
1629
|
+
} = metrics;
|
|
1630
|
+
var x = visibleColumnXs.get(column);
|
|
1631
|
+
var y = visibleRowYs.get(row);
|
|
1632
|
+
var w = visibleColumnWidths.get(column);
|
|
1633
|
+
var h = visibleRowHeights.get(row);
|
|
1634
|
+
var isVisible = x != null && y != null && w != null && h != null; // If the cell isn't visible, we still need to display an invisible cell for focus purposes
|
|
1635
|
+
|
|
1636
|
+
var wrapperStyle = isVisible ? {
|
|
1637
|
+
position: 'absolute',
|
|
1638
|
+
left: gridX + x,
|
|
1639
|
+
top: gridY + y,
|
|
1640
|
+
width: w,
|
|
1641
|
+
height: h
|
|
1642
|
+
} : {
|
|
1643
|
+
opacity: 0
|
|
1644
|
+
};
|
|
1645
|
+
var modelColumn = this.getModelColumn(column);
|
|
1646
|
+
var modelRow = this.getModelRow(row);
|
|
1647
|
+
var inputStyle = modelColumn != null && modelRow != null ? {
|
|
1648
|
+
textAlign: model.textAlignForCell(modelColumn, modelRow)
|
|
1649
|
+
} : null;
|
|
1650
|
+
var isValid = model.isValidForCell(modelColumn, modelRow, value);
|
|
1651
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
1652
|
+
style: wrapperStyle
|
|
1653
|
+
}, /*#__PURE__*/React.createElement(CellInputField, {
|
|
1654
|
+
key: "".concat(column, ",").concat(row),
|
|
1655
|
+
selectionRange: selectionRange,
|
|
1656
|
+
className: classNames({
|
|
1657
|
+
error: !isValid
|
|
1658
|
+
}),
|
|
1659
|
+
onCancel: this.handleEditCellCancel,
|
|
1660
|
+
onChange: this.handleEditCellChange,
|
|
1661
|
+
onDone: this.handleEditCellCommit,
|
|
1662
|
+
isQuickEdit: isQuickEdit,
|
|
1663
|
+
style: inputStyle,
|
|
1664
|
+
value: value
|
|
1665
|
+
}));
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
render() {
|
|
1669
|
+
var {
|
|
1670
|
+
cursor
|
|
1671
|
+
} = this.state;
|
|
1672
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("canvas", {
|
|
1673
|
+
className: classNames('grid-canvas', Grid.getCursorClassName(cursor)),
|
|
1674
|
+
ref: canvas => {
|
|
1675
|
+
this.canvas = canvas;
|
|
1676
|
+
},
|
|
1677
|
+
onClick: this.handleClick,
|
|
1678
|
+
onContextMenu: this.handleContextMenu,
|
|
1679
|
+
onDoubleClick: this.handleDoubleClick,
|
|
1680
|
+
onKeyDown: this.handleKeyDown,
|
|
1681
|
+
onMouseDown: this.handleMouseDown,
|
|
1682
|
+
onMouseMove: this.handleMouseMove,
|
|
1683
|
+
onMouseLeave: this.handleMouseLeave,
|
|
1684
|
+
tabIndex: 0
|
|
1685
|
+
}, "Your browser does not support HTML canvas. Update your browser?"), this.renderInputField());
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
}
|
|
1722
1689
|
|
|
1723
1690
|
_defineProperty(Grid, "pixelsPerLine", 100 / 3);
|
|
1724
1691
|
|
|
1725
1692
|
_defineProperty(Grid, "dragTimeout", 1000);
|
|
1726
1693
|
|
|
1727
|
-
_defineProperty(Grid, "getTheme", memoize(
|
|
1728
|
-
return _objectSpread(_objectSpread({}, GridTheme), userTheme);
|
|
1729
|
-
}));
|
|
1694
|
+
_defineProperty(Grid, "getTheme", memoize(userTheme => _objectSpread(_objectSpread({}, GridTheme), userTheme)));
|
|
1730
1695
|
|
|
1731
1696
|
Grid.propTypes = {
|
|
1732
1697
|
canvasOptions: PropTypes.shape({}),
|
|
@@ -1767,11 +1732,11 @@ Grid.defaultProps = {
|
|
|
1767
1732
|
mouseHandlers: [],
|
|
1768
1733
|
movedColumns: [],
|
|
1769
1734
|
movedRows: [],
|
|
1770
|
-
onError:
|
|
1771
|
-
onSelectionChanged:
|
|
1772
|
-
onMovedColumnsChanged:
|
|
1773
|
-
onMoveColumnComplete:
|
|
1774
|
-
onViewChanged:
|
|
1735
|
+
onError: () => {},
|
|
1736
|
+
onSelectionChanged: () => {},
|
|
1737
|
+
onMovedColumnsChanged: () => {},
|
|
1738
|
+
onMoveColumnComplete: () => {},
|
|
1739
|
+
onViewChanged: () => {},
|
|
1775
1740
|
renderer: null,
|
|
1776
1741
|
stateOverride: {},
|
|
1777
1742
|
theme: {
|