@deephaven/grid 0.4.1-modules.0 → 0.5.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/CellInputField.js +88 -40
- package/dist/CellInputField.js.map +1 -1
- package/dist/Grid.js +1484 -1449
- package/dist/Grid.js.map +1 -1
- package/dist/GridColorUtils.js +51 -18
- package/dist/GridColorUtils.js.map +1 -1
- package/dist/GridMetricCalculator.js +994 -1017
- package/dist/GridMetricCalculator.js.map +1 -1
- package/dist/GridModel.js +286 -171
- package/dist/GridModel.js.map +1 -1
- package/dist/GridMouseHandler.js +59 -39
- package/dist/GridMouseHandler.js.map +1 -1
- package/dist/GridRange.js +630 -572
- package/dist/GridRange.js.map +1 -1
- package/dist/GridRenderer.d.ts.map +1 -1
- package/dist/GridRenderer.js +1564 -1650
- package/dist/GridRenderer.js.map +1 -1
- package/dist/GridTestUtils.js +29 -15
- package/dist/GridTestUtils.js.map +1 -1
- package/dist/GridUtils.js +717 -679
- package/dist/GridUtils.js.map +1 -1
- package/dist/KeyHandler.js +18 -6
- package/dist/KeyHandler.js.map +1 -1
- package/dist/MockGridModel.js +210 -105
- package/dist/MockGridModel.js.map +1 -1
- package/dist/MockTreeGridModel.js +183 -113
- package/dist/MockTreeGridModel.js.map +1 -1
- package/dist/errors/PasteError.js +44 -5
- 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 +75 -42
- package/dist/key-handlers/EditKeyHandler.js.map +1 -1
- package/dist/key-handlers/PasteKeyHandler.js +78 -42
- package/dist/key-handlers/PasteKeyHandler.js.map +1 -1
- package/dist/key-handlers/SelectionKeyHandler.js +234 -220
- package/dist/key-handlers/SelectionKeyHandler.js.map +1 -1
- package/dist/key-handlers/TreeKeyHandler.js +72 -42
- 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 +50 -18
- package/dist/mouse-handlers/EditMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +163 -141
- package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +86 -47
- package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +171 -143
- package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js +147 -125
- package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +86 -47
- package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js +76 -46
- package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +62 -31
- package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSelectionMouseHandler.js +222 -200
- package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js +253 -206
- package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.d.ts.map +1 -1
- package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +172 -144
- 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 +4 -5
package/dist/Grid.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
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
|
+
|
|
1
3
|
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); } }
|
|
2
4
|
|
|
3
5
|
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); }); }; }
|
|
@@ -6,6 +8,38 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
6
8
|
|
|
7
9
|
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; }
|
|
8
10
|
|
|
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
|
+
|
|
9
43
|
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; }
|
|
10
44
|
|
|
11
45
|
/* eslint react/no-did-update-set-state: "off" */
|
|
@@ -14,19 +48,19 @@ import classNames from 'classnames';
|
|
|
14
48
|
import memoize from 'memoize-one';
|
|
15
49
|
import PropTypes from 'prop-types';
|
|
16
50
|
import clamp from 'lodash.clamp';
|
|
17
|
-
import GridMetricCalculator from
|
|
18
|
-
import GridModel from
|
|
19
|
-
import GridMouseHandler from
|
|
20
|
-
import GridTheme from
|
|
21
|
-
import GridRange from
|
|
22
|
-
import GridRenderer from
|
|
23
|
-
import GridUtils from
|
|
24
|
-
import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from
|
|
51
|
+
import GridMetricCalculator from './GridMetricCalculator';
|
|
52
|
+
import GridModel from './GridModel';
|
|
53
|
+
import GridMouseHandler from './GridMouseHandler';
|
|
54
|
+
import GridTheme from './GridTheme';
|
|
55
|
+
import GridRange from './GridRange';
|
|
56
|
+
import GridRenderer from './GridRenderer';
|
|
57
|
+
import GridUtils from './GridUtils';
|
|
58
|
+
import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from './mouse-handlers';
|
|
25
59
|
import "./Grid.css";
|
|
26
|
-
import KeyHandler from
|
|
27
|
-
import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from
|
|
28
|
-
import CellInputField from
|
|
29
|
-
import PasteError from
|
|
60
|
+
import KeyHandler from './KeyHandler';
|
|
61
|
+
import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from './key-handlers';
|
|
62
|
+
import CellInputField from './CellInputField';
|
|
63
|
+
import PasteError from './errors/PasteError';
|
|
30
64
|
/**
|
|
31
65
|
* High performance, extendible, themeable grid component.
|
|
32
66
|
* Architectured to be fast and handle billions of rows/columns by default.
|
|
@@ -42,65 +76,67 @@ import PasteError from "./errors/PasteError.js";
|
|
|
42
76
|
* Can also add onClick and onContextMenu handlers to add custom functionality and menus.
|
|
43
77
|
*/
|
|
44
78
|
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
}
|
|
79
|
+
var Grid = /*#__PURE__*/function (_PureComponent) {
|
|
80
|
+
_inherits(Grid, _PureComponent);
|
|
53
81
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
82
|
+
var _super = _createSuper(Grid);
|
|
83
|
+
|
|
84
|
+
function Grid(props) {
|
|
85
|
+
var _this;
|
|
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
|
+
}));
|
|
96
|
+
|
|
97
|
+
_defineProperty(_assertThisInitialized(_this), "getCachedMouseHandlers", memoize(function (mouseHandlers) {
|
|
98
|
+
return [].concat(_toConsumableArray(mouseHandlers), _toConsumableArray(_this.mouseHandlers)).sort(function (a, b) {
|
|
99
|
+
return a.order - b.order;
|
|
100
|
+
});
|
|
101
|
+
}));
|
|
57
102
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
|
103
|
+
_this.handleClick = _this.handleClick.bind(_assertThisInitialized(_this));
|
|
104
|
+
_this.handleContextMenu = _this.handleContextMenu.bind(_assertThisInitialized(_this));
|
|
105
|
+
_this.handleEditCellCancel = _this.handleEditCellCancel.bind(_assertThisInitialized(_this));
|
|
106
|
+
_this.handleEditCellChange = _this.handleEditCellChange.bind(_assertThisInitialized(_this));
|
|
107
|
+
_this.handleEditCellCommit = _this.handleEditCellCommit.bind(_assertThisInitialized(_this));
|
|
108
|
+
_this.handleDoubleClick = _this.handleDoubleClick.bind(_assertThisInitialized(_this));
|
|
109
|
+
_this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this));
|
|
110
|
+
_this.handleMouseDown = _this.handleMouseDown.bind(_assertThisInitialized(_this));
|
|
111
|
+
_this.handleMouseDrag = _this.handleMouseDrag.bind(_assertThisInitialized(_this));
|
|
112
|
+
_this.handleMouseMove = _this.handleMouseMove.bind(_assertThisInitialized(_this));
|
|
113
|
+
_this.handleMouseLeave = _this.handleMouseLeave.bind(_assertThisInitialized(_this));
|
|
114
|
+
_this.handleMouseUp = _this.handleMouseUp.bind(_assertThisInitialized(_this));
|
|
115
|
+
_this.handleResize = _this.handleResize.bind(_assertThisInitialized(_this));
|
|
116
|
+
_this.handleWheel = _this.handleWheel.bind(_assertThisInitialized(_this));
|
|
117
|
+
var metricCalculator = props.metricCalculator,
|
|
118
|
+
movedColumns = props.movedColumns,
|
|
119
|
+
movedRows = props.movedRows,
|
|
120
|
+
renderer = props.renderer;
|
|
121
|
+
_this.renderer = renderer || new GridRenderer();
|
|
122
|
+
_this.metricCalculator = metricCalculator || new GridMetricCalculator();
|
|
123
|
+
_this.canvas = null;
|
|
124
|
+
_this.canvasContext = null;
|
|
125
|
+
_this.animationFrame = null;
|
|
126
|
+
_this.prevMetrics = null;
|
|
127
|
+
_this.metrics = null;
|
|
128
|
+
_this.isStuckToBottom = false;
|
|
129
|
+
_this.isStuckToRight = false; // Track the cursor that is currently added to the document
|
|
94
130
|
// Add to document so that when dragging the cursor stays, even if mouse leaves the canvas
|
|
95
131
|
// Note: on document, not body so that cursor styling can be combined with
|
|
96
132
|
// blocked pointer events that would otherwise prevent cursor styling from showing
|
|
97
133
|
|
|
98
|
-
|
|
99
|
-
|
|
134
|
+
_this.documentCursor = null;
|
|
135
|
+
_this.dragTimer = null; // specify handler ordering, such that any extensions can insert handlers in between
|
|
100
136
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
137
|
+
_this.keyHandlers = [new EditKeyHandler(400), new PasteKeyHandler(450), new SelectionKeyHandler(500), new TreeKeyHandler(900)];
|
|
138
|
+
_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)];
|
|
139
|
+
_this.state = {
|
|
104
140
|
// 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)
|
|
105
141
|
top: 0,
|
|
106
142
|
left: 0,
|
|
@@ -125,8 +161,8 @@ class Grid extends PureComponent {
|
|
|
125
161
|
mouseX: null,
|
|
126
162
|
mouseY: null,
|
|
127
163
|
// Move operations the user has performed on this grids columns/rows
|
|
128
|
-
movedColumns,
|
|
129
|
-
movedRows,
|
|
164
|
+
movedColumns: movedColumns,
|
|
165
|
+
movedRows: movedRows,
|
|
130
166
|
// Cursor (highlighted cell) location and active selected range
|
|
131
167
|
cursorRow: null,
|
|
132
168
|
cursorColumn: null,
|
|
@@ -145,1553 +181,1552 @@ class Grid extends PureComponent {
|
|
|
145
181
|
// The cell that is currently being edited
|
|
146
182
|
editingCell: null
|
|
147
183
|
};
|
|
184
|
+
return _this;
|
|
148
185
|
}
|
|
149
186
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
}
|
|
187
|
+
_createClass(Grid, [{
|
|
188
|
+
key: "componentDidMount",
|
|
189
|
+
value: function componentDidMount() {
|
|
190
|
+
this.initContext(); // Need to explicitly add wheel event to canvas so we can preventDefault/avoid passive listener issue
|
|
191
|
+
// Otherwise React attaches listener at doc level and you can't prevent default
|
|
192
|
+
// https://github.com/facebook/react/issues/14856
|
|
191
193
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
movedRows
|
|
194
|
+
this.canvas.addEventListener('wheel', this.handleWheel, {
|
|
195
|
+
passive: false
|
|
195
196
|
});
|
|
197
|
+
window.addEventListener('resize', this.handleResize);
|
|
198
|
+
this.updateCanvasScale();
|
|
199
|
+
this.updateCanvas();
|
|
196
200
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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) {
|
|
201
|
+
}, {
|
|
202
|
+
key: "componentDidUpdate",
|
|
203
|
+
value: function componentDidUpdate(prevProps, prevState) {
|
|
204
|
+
var _this$props = this.props,
|
|
205
|
+
isStickyBottom = _this$props.isStickyBottom,
|
|
206
|
+
isStickyRight = _this$props.isStickyRight,
|
|
207
|
+
movedColumns = _this$props.movedColumns,
|
|
208
|
+
movedRows = _this$props.movedRows,
|
|
209
|
+
onMovedColumnsChanged = _this$props.onMovedColumnsChanged,
|
|
210
|
+
onMoveColumnComplete = _this$props.onMoveColumnComplete;
|
|
211
|
+
var prevIsStickyBottom = prevProps.isStickyBottom,
|
|
212
|
+
prevIsStickyRight = prevProps.isStickyRight,
|
|
213
|
+
prevPropMovedColumns = prevProps.movedColumns,
|
|
214
|
+
prevMovedRows = prevProps.movedRows;
|
|
215
|
+
var prevStateMovedColumns = prevState.movedColumns;
|
|
216
|
+
var _this$state = this.state,
|
|
217
|
+
draggingColumn = _this$state.draggingColumn,
|
|
218
|
+
currentStateMovedColumns = _this$state.movedColumns;
|
|
219
|
+
|
|
220
|
+
if (prevPropMovedColumns !== movedColumns) {
|
|
243
221
|
this.setState({
|
|
244
|
-
|
|
222
|
+
movedColumns: movedColumns
|
|
245
223
|
});
|
|
246
224
|
}
|
|
247
|
-
}
|
|
248
225
|
|
|
249
|
-
|
|
250
|
-
var lastLeft = this.metricCalculator.getLastLeft(metricState);
|
|
251
|
-
|
|
252
|
-
if (this.isStuckToRight && rightVisible < columnCount - 1 && rightVisible > 0 && left > 0 || left > lastLeft) {
|
|
226
|
+
if (prevMovedRows !== movedRows) {
|
|
253
227
|
this.setState({
|
|
254
|
-
|
|
228
|
+
movedRows: movedRows
|
|
255
229
|
});
|
|
256
230
|
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (this.validateSelection()) {
|
|
260
|
-
this.checkSelectionChange(prevState);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
componentWillUnmount() {
|
|
265
|
-
if (this.animationFrame != null) {
|
|
266
|
-
cancelAnimationFrame(this.animationFrame);
|
|
267
|
-
}
|
|
268
|
-
|
|
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
|
-
}
|
|
277
231
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
} = this.props;
|
|
282
|
-
return Grid.getTheme(theme);
|
|
283
|
-
}
|
|
284
|
-
|
|
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
|
-
}
|
|
232
|
+
if (prevStateMovedColumns !== currentStateMovedColumns) {
|
|
233
|
+
onMovedColumnsChanged(currentStateMovedColumns);
|
|
234
|
+
}
|
|
291
235
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
236
|
+
if (prevState.draggingColumn != null && draggingColumn == null) {
|
|
237
|
+
onMoveColumnComplete(currentStateMovedColumns);
|
|
238
|
+
}
|
|
295
239
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
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
|
-
}
|
|
240
|
+
if (isStickyBottom !== prevIsStickyBottom) {
|
|
241
|
+
this.isStuckToBottom = false;
|
|
242
|
+
}
|
|
332
243
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
} = this.props;
|
|
337
|
-
return this.getCachedKeyHandlers(keyHandlers);
|
|
338
|
-
}
|
|
244
|
+
if (isStickyRight !== prevIsStickyRight) {
|
|
245
|
+
this.isStuckToRight = false;
|
|
246
|
+
}
|
|
339
247
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
mouseHandlers
|
|
343
|
-
} = this.props;
|
|
344
|
-
return this.getCachedMouseHandlers(mouseHandlers);
|
|
345
|
-
}
|
|
248
|
+
this.updateMetrics();
|
|
249
|
+
this.requestUpdateCanvas();
|
|
346
250
|
|
|
347
|
-
|
|
348
|
-
|
|
251
|
+
if (!this.metrics || !this.prevMetrics) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
349
254
|
|
|
350
|
-
|
|
351
|
-
|
|
255
|
+
var _this$metrics = this.metrics,
|
|
256
|
+
bottomVisible = _this$metrics.bottomVisible,
|
|
257
|
+
rightVisible = _this$metrics.rightVisible,
|
|
258
|
+
rowCount = _this$metrics.rowCount,
|
|
259
|
+
columnCount = _this$metrics.columnCount,
|
|
260
|
+
top = _this$metrics.top,
|
|
261
|
+
left = _this$metrics.left,
|
|
262
|
+
height = _this$metrics.height,
|
|
263
|
+
width = _this$metrics.width;
|
|
264
|
+
var _this$prevMetrics = this.prevMetrics,
|
|
265
|
+
prevRowCount = _this$prevMetrics.rowCount,
|
|
266
|
+
prevColumnCount = _this$prevMetrics.columnCount,
|
|
267
|
+
prevHeight = _this$prevMetrics.height,
|
|
268
|
+
prevWidth = _this$prevMetrics.width;
|
|
269
|
+
var metricState = this.getMetricState();
|
|
270
|
+
|
|
271
|
+
if (prevRowCount !== rowCount || height !== prevHeight) {
|
|
272
|
+
var lastTop = this.metricCalculator.getLastTop(metricState);
|
|
273
|
+
|
|
274
|
+
if (this.isStuckToBottom && bottomVisible < rowCount - 1 && bottomVisible > 0 && top > 0 || top > lastTop) {
|
|
275
|
+
this.setState({
|
|
276
|
+
top: lastTop
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
352
280
|
|
|
353
|
-
|
|
354
|
-
|
|
281
|
+
if (prevColumnCount !== columnCount || width !== prevWidth) {
|
|
282
|
+
var lastLeft = this.metricCalculator.getLastLeft(metricState);
|
|
355
283
|
|
|
356
|
-
|
|
357
|
-
|
|
284
|
+
if (this.isStuckToRight && rightVisible < columnCount - 1 && rightVisible > 0 && left > 0 || left > lastLeft) {
|
|
285
|
+
this.setState({
|
|
286
|
+
left: lastLeft
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
358
290
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
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));
|
|
291
|
+
if (this.validateSelection()) {
|
|
292
|
+
this.checkSelectionChange(prevState);
|
|
293
|
+
}
|
|
374
294
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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());
|
|
295
|
+
}, {
|
|
296
|
+
key: "componentWillUnmount",
|
|
297
|
+
value: function componentWillUnmount() {
|
|
298
|
+
if (this.animationFrame != null) {
|
|
299
|
+
cancelAnimationFrame(this.animationFrame);
|
|
414
300
|
}
|
|
415
301
|
|
|
416
|
-
this.
|
|
417
|
-
|
|
418
|
-
selectionStartRow: range.startRow,
|
|
419
|
-
selectionEndColumn: range.endColumn,
|
|
420
|
-
selectionEndRow: range.endRow,
|
|
421
|
-
cursorColumn: newCursorColumn,
|
|
422
|
-
cursorRow: newCursorRow
|
|
302
|
+
this.canvas.removeEventListener('wheel', this.handleWheel, {
|
|
303
|
+
passive: false
|
|
423
304
|
});
|
|
305
|
+
window.removeEventListener('mousemove', this.handleMouseDrag, true);
|
|
306
|
+
window.removeEventListener('mouseup', this.handleMouseUp, true);
|
|
307
|
+
window.removeEventListener('resize', this.handleResize);
|
|
308
|
+
this.stopDragTimer();
|
|
424
309
|
}
|
|
425
|
-
}
|
|
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
|
+
}
|
|
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;
|
|
426
380
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
} = this.props;
|
|
434
|
-
this.canvasContext = canvas.getContext('2d', canvasOptions);
|
|
435
|
-
}
|
|
381
|
+
return (_this$metrics2 = this.metrics) === null || _this$metrics2 === void 0 ? void 0 : (_this$metrics2$modelC = _this$metrics2.modelColumns) === null || _this$metrics2$modelC === void 0 ? void 0 : _this$metrics2$modelC.get(columnIndex);
|
|
382
|
+
}
|
|
383
|
+
}, {
|
|
384
|
+
key: "getModelRow",
|
|
385
|
+
value: function getModelRow(rowIndex) {
|
|
386
|
+
var _this$metrics3, _this$metrics3$modelR;
|
|
436
387
|
|
|
437
|
-
|
|
438
|
-
if (this.animationFrame != null) {
|
|
439
|
-
return;
|
|
388
|
+
return (_this$metrics3 = this.metrics) === null || _this$metrics3 === void 0 ? void 0 : (_this$metrics3$modelR = _this$metrics3.modelRows) === null || _this$metrics3$modelR === void 0 ? void 0 : _this$metrics3$modelR.get(rowIndex);
|
|
440
389
|
}
|
|
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
|
+
}
|
|
441
402
|
|
|
442
|
-
|
|
443
|
-
this.
|
|
444
|
-
this.updateCanvas(this.metrics);
|
|
445
|
-
});
|
|
446
|
-
}
|
|
403
|
+
this.clearSelectedRanges();
|
|
404
|
+
this.commitSelection(); // Need to commit before moving in case we're selecting same row again
|
|
447
405
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
406
|
+
this.moveCursorToPosition(0, row);
|
|
407
|
+
this.commitSelection();
|
|
408
|
+
this.isStuckToBottom = false;
|
|
409
|
+
}
|
|
410
|
+
/** Allows the selected range to be set programatically */
|
|
411
|
+
|
|
412
|
+
}, {
|
|
413
|
+
key: "setSelectedRanges",
|
|
414
|
+
value: function setSelectedRanges(gridRanges) {
|
|
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
|
+
});
|
|
457
426
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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
|
-
}
|
|
427
|
+
if (gridRanges.length > 0) {
|
|
428
|
+
var range = GridRange.boundedRange(gridRanges[0], columnCount, rowCount);
|
|
429
|
+
var newCursorRow = cursorRow;
|
|
430
|
+
var newCursorColumn = cursorColumn;
|
|
478
431
|
|
|
479
|
-
|
|
480
|
-
|
|
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
|
-
}
|
|
432
|
+
if (!range.containsCell(cursorColumn, cursorRow)) {
|
|
433
|
+
var _range$startCell = range.startCell();
|
|
489
434
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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
|
-
}
|
|
435
|
+
newCursorRow = _range$startCell.row;
|
|
436
|
+
newCursorColumn = _range$startCell.column;
|
|
437
|
+
}
|
|
505
438
|
|
|
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.
|
|
523
439
|
this.setState({
|
|
524
|
-
|
|
525
|
-
|
|
440
|
+
selectionStartColumn: range.startColumn,
|
|
441
|
+
selectionStartRow: range.startRow,
|
|
442
|
+
selectionEndColumn: range.endColumn,
|
|
443
|
+
selectionEndRow: range.endRow,
|
|
444
|
+
cursorColumn: newCursorColumn,
|
|
445
|
+
cursorRow: newCursorRow
|
|
526
446
|
});
|
|
527
|
-
return false;
|
|
528
447
|
}
|
|
529
448
|
}
|
|
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;
|
|
530
460
|
|
|
531
|
-
|
|
532
|
-
|
|
461
|
+
if (this.animationFrame != null) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
533
464
|
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
465
|
+
this.animationFrame = requestAnimationFrame(function () {
|
|
466
|
+
_this2.animationFrame = null;
|
|
467
|
+
|
|
468
|
+
_this2.updateCanvas(_this2.metrics);
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
}, {
|
|
472
|
+
key: "updateCanvas",
|
|
473
|
+
value: function updateCanvas() {
|
|
474
|
+
var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
|
|
475
|
+
this.updateCanvasScale();
|
|
476
|
+
var onViewChanged = this.props.onViewChanged;
|
|
477
|
+
onViewChanged(metrics);
|
|
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
|
+
}
|
|
544
541
|
|
|
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 */
|
|
545
554
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
555
|
+
}, {
|
|
556
|
+
key: "trimSelectedRanges",
|
|
557
|
+
value: function trimSelectedRanges() {
|
|
558
|
+
var selectedRanges = this.state.selectedRanges;
|
|
550
559
|
|
|
551
|
-
|
|
560
|
+
if (selectedRanges.length > 0) {
|
|
561
|
+
this.setState({
|
|
562
|
+
selectedRanges: selectedRanges.slice(selectedRanges.length - 1)
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}, {
|
|
567
|
+
key: "beginSelection",
|
|
568
|
+
value: function beginSelection(column, row) {
|
|
552
569
|
this.setState({
|
|
553
|
-
|
|
570
|
+
selectionStartColumn: column,
|
|
571
|
+
selectionStartRow: row,
|
|
572
|
+
selectionEndColumn: column,
|
|
573
|
+
selectionEndRow: row,
|
|
574
|
+
cursorColumn: column,
|
|
575
|
+
cursorRow: row
|
|
554
576
|
});
|
|
555
577
|
}
|
|
556
|
-
|
|
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
|
+
*/
|
|
557
585
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
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;
|
|
586
|
+
}, {
|
|
587
|
+
key: "moveSelection",
|
|
588
|
+
value: function moveSelection(column, row) {
|
|
589
|
+
var _this3 = this;
|
|
590
|
+
|
|
591
|
+
var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
592
|
+
var maximizePreviousRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
593
|
+
this.setState(function (state) {
|
|
594
|
+
var selectedRanges = state.selectedRanges,
|
|
595
|
+
selectionStartRow = state.selectionStartRow,
|
|
596
|
+
selectionStartColumn = state.selectionStartColumn;
|
|
597
|
+
var theme = _this3.props.theme;
|
|
598
|
+
var autoSelectRow = theme.autoSelectRow,
|
|
599
|
+
autoSelectColumn = theme.autoSelectColumn;
|
|
600
|
+
|
|
601
|
+
if (extendSelection && selectedRanges.length > 0) {
|
|
602
|
+
var lastSelectedRange = selectedRanges[selectedRanges.length - 1];
|
|
603
|
+
var left = null;
|
|
604
|
+
var top = null;
|
|
605
|
+
var right = null;
|
|
606
|
+
var bottom = null;
|
|
607
|
+
|
|
608
|
+
if (maximizePreviousRange) {
|
|
609
|
+
left = autoSelectRow ? null : Math.min(column, lastSelectedRange.startColumn);
|
|
610
|
+
top = autoSelectColumn ? null : Math.min(row, lastSelectedRange.startRow);
|
|
611
|
+
right = autoSelectRow ? null : Math.max(column, lastSelectedRange.endColumn);
|
|
612
|
+
bottom = autoSelectColumn ? null : Math.max(row, lastSelectedRange.endRow);
|
|
613
|
+
} else {
|
|
614
|
+
left = lastSelectedRange.startColumn;
|
|
615
|
+
top = lastSelectedRange.startRow;
|
|
616
|
+
|
|
617
|
+
if (selectionStartColumn != null || selectionStartRow != null) {
|
|
618
|
+
if (!autoSelectRow) {
|
|
619
|
+
left = selectionStartColumn;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
if (!autoSelectColumn) {
|
|
623
|
+
top = selectionStartRow;
|
|
624
|
+
}
|
|
613
625
|
}
|
|
614
626
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}
|
|
627
|
+
right = autoSelectRow ? null : column;
|
|
628
|
+
bottom = autoSelectColumn ? null : row;
|
|
618
629
|
}
|
|
619
630
|
|
|
620
|
-
|
|
621
|
-
bottom = autoSelectColumn ? null : row;
|
|
622
|
-
}
|
|
631
|
+
var selectedRange = GridRange.makeNormalized(left, top, right, bottom);
|
|
623
632
|
|
|
624
|
-
|
|
633
|
+
if (lastSelectedRange.equals(selectedRange)) {
|
|
634
|
+
return null;
|
|
635
|
+
}
|
|
625
636
|
|
|
626
|
-
|
|
627
|
-
return null;
|
|
628
|
-
}
|
|
637
|
+
var _newRanges = [].concat(selectedRanges);
|
|
629
638
|
|
|
630
|
-
|
|
639
|
+
_newRanges[_newRanges.length - 1] = selectedRange;
|
|
640
|
+
return {
|
|
641
|
+
selectedRanges: _newRanges,
|
|
642
|
+
selectionEndColumn: column,
|
|
643
|
+
selectionEndRow: row
|
|
644
|
+
};
|
|
645
|
+
}
|
|
631
646
|
|
|
632
|
-
|
|
647
|
+
var newRanges = [].concat(selectedRanges);
|
|
648
|
+
var selectedColumn = autoSelectRow ? null : column;
|
|
649
|
+
var selectedRow = autoSelectColumn ? null : row;
|
|
650
|
+
newRanges.push(GridRange.makeNormalized(selectedColumn, selectedRow, selectedColumn, selectedRow));
|
|
633
651
|
return {
|
|
634
|
-
selectedRanges:
|
|
652
|
+
selectedRanges: newRanges,
|
|
635
653
|
selectionEndColumn: column,
|
|
636
654
|
selectionEndRow: row
|
|
637
655
|
};
|
|
638
|
-
}
|
|
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
|
+
*/
|
|
639
664
|
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
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
|
-
}
|
|
665
|
+
}, {
|
|
666
|
+
key: "commitSelection",
|
|
667
|
+
value: function commitSelection() {
|
|
668
|
+
var _this4 = this;
|
|
669
|
+
|
|
670
|
+
this.setState(function (state) {
|
|
671
|
+
var theme = _this4.props.theme;
|
|
672
|
+
var autoSelectRow = theme.autoSelectRow;
|
|
673
|
+
var selectedRanges = state.selectedRanges,
|
|
674
|
+
lastSelectedRanges = state.lastSelectedRanges,
|
|
675
|
+
cursorRow = state.cursorRow,
|
|
676
|
+
cursorColumn = state.cursorColumn;
|
|
677
|
+
|
|
678
|
+
if (selectedRanges.length === 1 && (autoSelectRow ? GridRange.rowCount(selectedRanges) === 1 : GridRange.cellCount(selectedRanges) === 1) && GridRange.rangeArraysEqual(selectedRanges, lastSelectedRanges)) {
|
|
679
|
+
// If it's the exact same single selection, then deselect.
|
|
680
|
+
// For if we click on one cell multiple times.
|
|
681
|
+
return {
|
|
682
|
+
selectedRanges: [],
|
|
683
|
+
lastSelectedRanges: []
|
|
684
|
+
};
|
|
685
|
+
}
|
|
682
686
|
|
|
683
|
-
|
|
687
|
+
var newSelectedRanges = selectedRanges.slice();
|
|
684
688
|
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
+
if (newSelectedRanges.length > 1) {
|
|
690
|
+
// Check if the latest selection is entirely within a previously selected range
|
|
691
|
+
// If that's the case, then deselect that section instead
|
|
692
|
+
var lastRange = newSelectedRanges[newSelectedRanges.length - 1];
|
|
689
693
|
|
|
690
|
-
|
|
691
|
-
|
|
694
|
+
for (var i = 0; i < newSelectedRanges.length - 1; i += 1) {
|
|
695
|
+
var selectedRange = newSelectedRanges[i];
|
|
692
696
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
697
|
+
if (selectedRange.contains(lastRange)) {
|
|
698
|
+
// We found a match, now remove the two matching ranges, and add back
|
|
699
|
+
// the remainder of the two
|
|
700
|
+
var remainder = selectedRange.subtract(lastRange);
|
|
701
|
+
newSelectedRanges.pop();
|
|
702
|
+
newSelectedRanges.splice(i, 1);
|
|
703
|
+
newSelectedRanges = newSelectedRanges.concat(remainder);
|
|
704
|
+
break;
|
|
705
|
+
}
|
|
701
706
|
}
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
newSelectedRanges = GridRange.consolidate(newSelectedRanges);
|
|
705
|
-
}
|
|
706
707
|
|
|
707
|
-
|
|
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;
|
|
708
|
+
newSelectedRanges = GridRange.consolidate(newSelectedRanges);
|
|
728
709
|
}
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
return {
|
|
732
|
-
cursorRow: newCursorRow,
|
|
733
|
-
cursorColumn: newCursorColumn,
|
|
734
|
-
selectedRanges: newSelectedRanges,
|
|
735
|
-
lastSelectedRanges: selectedRanges
|
|
736
|
-
};
|
|
737
|
-
});
|
|
738
|
-
}
|
|
739
710
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
711
|
+
var newCursorColumn = cursorColumn;
|
|
712
|
+
var newCursorRow = cursorRow;
|
|
713
|
+
|
|
714
|
+
if (!GridRange.containsCell(newSelectedRanges, cursorColumn, cursorRow)) {
|
|
715
|
+
var model = _this4.props.model;
|
|
716
|
+
var columnCount = model.columnCount,
|
|
717
|
+
rowCount = model.rowCount;
|
|
718
|
+
var nextCursor = GridRange.nextCell(GridRange.boundedRanges(selectedRanges, columnCount, rowCount));
|
|
719
|
+
|
|
720
|
+
if (nextCursor != null) {
|
|
721
|
+
newCursorColumn = nextCursor.column;
|
|
722
|
+
newCursorRow = nextCursor.row;
|
|
723
|
+
} else {
|
|
724
|
+
newCursorColumn = null;
|
|
725
|
+
newCursorRow = null;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
755
728
|
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
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);
|
|
729
|
+
return {
|
|
730
|
+
cursorRow: newCursorRow,
|
|
731
|
+
cursorColumn: newCursorColumn,
|
|
732
|
+
selectedRanges: newSelectedRanges,
|
|
733
|
+
lastSelectedRanges: selectedRanges
|
|
734
|
+
};
|
|
735
|
+
});
|
|
786
736
|
}
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
737
|
+
}, {
|
|
738
|
+
key: "selectAll",
|
|
739
|
+
value: function selectAll() {
|
|
740
|
+
var _this$props3 = this.props,
|
|
741
|
+
model = _this$props3.model,
|
|
742
|
+
theme = _this$props3.theme;
|
|
743
|
+
var autoSelectRow = theme.autoSelectRow,
|
|
744
|
+
autoSelectColumn = theme.autoSelectColumn;
|
|
745
|
+
var top = autoSelectColumn ? null : 0;
|
|
746
|
+
var bottom = autoSelectColumn ? null : model.rowCount - 1;
|
|
747
|
+
var left = autoSelectRow ? null : 0;
|
|
748
|
+
var right = autoSelectRow ? null : model.columnCount - 1;
|
|
749
|
+
this.setSelectedRanges([new GridRange(left, top, right, bottom)]);
|
|
750
|
+
}
|
|
751
|
+
}, {
|
|
752
|
+
key: "moveCursor",
|
|
753
|
+
value: function moveCursor(deltaColumn, deltaRow, extendSelection) {
|
|
754
|
+
var _this$state3 = this.state,
|
|
755
|
+
cursorRow = _this$state3.cursorRow,
|
|
756
|
+
cursorColumn = _this$state3.cursorColumn,
|
|
757
|
+
selectionEndColumn = _this$state3.selectionEndColumn,
|
|
758
|
+
selectionEndRow = _this$state3.selectionEndRow;
|
|
759
|
+
var column = extendSelection ? selectionEndColumn : cursorColumn;
|
|
760
|
+
var row = extendSelection ? selectionEndRow : cursorRow;
|
|
761
|
+
|
|
762
|
+
if (row === null || column === null) {
|
|
763
|
+
var _this$state4 = this.state,
|
|
764
|
+
left = _this$state4.left,
|
|
765
|
+
top = _this$state4.top;
|
|
766
|
+
this.moveCursorToPosition(left, top, extendSelection);
|
|
767
|
+
} else {
|
|
768
|
+
var model = this.props.model;
|
|
769
|
+
var columnCount = model.columnCount,
|
|
770
|
+
rowCount = model.rowCount;
|
|
771
|
+
|
|
772
|
+
var _left = clamp(column + deltaColumn, 0, columnCount - 1);
|
|
773
|
+
|
|
774
|
+
var _top = clamp(row + deltaRow, 0, rowCount - 1);
|
|
775
|
+
|
|
776
|
+
this.moveCursorToPosition(_left, _top, extendSelection);
|
|
777
|
+
}
|
|
819
778
|
}
|
|
779
|
+
/**
|
|
780
|
+
* Move the cursor in the provided selection direction
|
|
781
|
+
* @param {string} direction The direction to move the cursor in
|
|
782
|
+
*/
|
|
820
783
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
784
|
+
}, {
|
|
785
|
+
key: "moveCursorInDirection",
|
|
786
|
+
value: function moveCursorInDirection() {
|
|
787
|
+
var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
|
|
788
|
+
var model = this.props.model;
|
|
789
|
+
var columnCount = model.columnCount,
|
|
790
|
+
rowCount = model.rowCount;
|
|
791
|
+
var _this$state5 = this.state,
|
|
792
|
+
cursorRow = _this$state5.cursorRow,
|
|
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
|
+
}
|
|
830
807
|
|
|
831
|
-
if (
|
|
808
|
+
if (nextCursor != null) {
|
|
809
|
+
var _nextCursor = nextCursor,
|
|
810
|
+
column = _nextCursor.column,
|
|
811
|
+
row = _nextCursor.row;
|
|
832
812
|
this.setState({
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
selectionStartRow: row,
|
|
836
|
-
selectionEndColumn: column,
|
|
837
|
-
selectionEndRow: row
|
|
813
|
+
cursorColumn: column,
|
|
814
|
+
cursorRow: row
|
|
838
815
|
});
|
|
839
|
-
}
|
|
840
|
-
|
|
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
|
-
}
|
|
862
|
-
|
|
863
|
-
this.moveSelection(column, row, extendSelection, maximizePreviousRange);
|
|
864
816
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
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;
|
|
902
|
-
}
|
|
903
|
-
}
|
|
817
|
+
if (!GridRange.containsCell(selectedRanges, column, row)) {
|
|
818
|
+
this.setState({
|
|
819
|
+
selectedRanges: [GridRange.makeCell(column, row)],
|
|
820
|
+
selectionStartColumn: column,
|
|
821
|
+
selectionStartRow: row,
|
|
822
|
+
selectionEndColumn: column,
|
|
823
|
+
selectionEndRow: row
|
|
824
|
+
});
|
|
825
|
+
}
|
|
904
826
|
|
|
905
|
-
|
|
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;
|
|
827
|
+
this.moveViewToCell(nextCursor.column, nextCursor.row);
|
|
912
828
|
}
|
|
913
829
|
}
|
|
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
|
+
*/
|
|
914
838
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
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
|
-
}
|
|
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;
|
|
948
845
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
846
|
+
if (!extendSelection) {
|
|
847
|
+
this.beginSelection(column, row);
|
|
848
|
+
}
|
|
952
849
|
|
|
953
|
-
|
|
850
|
+
this.moveSelection(column, row, extendSelection, maximizePreviousRange);
|
|
954
851
|
|
|
955
|
-
|
|
956
|
-
|
|
852
|
+
if (keepCursorInView) {
|
|
853
|
+
this.moveViewToCell(column, row);
|
|
854
|
+
}
|
|
957
855
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
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
|
-
}
|
|
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
|
+
*/
|
|
993
862
|
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
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.");
|
|
863
|
+
}, {
|
|
864
|
+
key: "moveViewToCell",
|
|
865
|
+
value: function moveViewToCell(column, row) {
|
|
866
|
+
var metricCalculator = this.metricCalculator;
|
|
867
|
+
var _this$metrics4 = this.metrics,
|
|
868
|
+
bottomVisible = _this$metrics4.bottomVisible,
|
|
869
|
+
rightVisible = _this$metrics4.rightVisible,
|
|
870
|
+
topVisible = _this$metrics4.topVisible,
|
|
871
|
+
leftVisible = _this$metrics4.leftVisible;
|
|
872
|
+
var metricState = this.getMetricState(this.state);
|
|
873
|
+
var _this$state6 = this.state,
|
|
874
|
+
top = _this$state6.top,
|
|
875
|
+
left = _this$state6.left,
|
|
876
|
+
topOffset = _this$state6.topOffset,
|
|
877
|
+
leftOffset = _this$state6.leftOffset;
|
|
878
|
+
|
|
879
|
+
if (row != null && !GridUtils.isFloatingRow(row, this.metrics)) {
|
|
880
|
+
if (row < topVisible) {
|
|
881
|
+
top = metricCalculator.getTopForTopVisible(metricState, row);
|
|
882
|
+
topOffset = 0;
|
|
883
|
+
} else if (row > bottomVisible) {
|
|
884
|
+
top = metricCalculator.getTopForBottomVisible(metricState, row);
|
|
885
|
+
topOffset = 0;
|
|
1026
886
|
}
|
|
887
|
+
}
|
|
1027
888
|
|
|
1028
|
-
|
|
1029
|
-
|
|
889
|
+
if (column != null && !GridUtils.isFloatingColumn(column, this.metrics)) {
|
|
890
|
+
if (column < leftVisible) {
|
|
891
|
+
left = metricCalculator.getLeftForLeftVisible(metricState, column);
|
|
892
|
+
leftOffset = 0;
|
|
893
|
+
} else if (column > rightVisible) {
|
|
894
|
+
left = metricCalculator.getLeftForRightVisible(metricState, column);
|
|
895
|
+
leftOffset = 0;
|
|
1030
896
|
}
|
|
897
|
+
}
|
|
1031
898
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
} // Otherwise it's a table of data
|
|
1046
|
-
|
|
1047
|
-
|
|
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
|
|
1055
|
-
|
|
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));
|
|
1059
|
-
|
|
1060
|
-
_this.setSelectedRanges(ranges);
|
|
1061
|
-
}
|
|
899
|
+
this.setViewState({
|
|
900
|
+
top: top,
|
|
901
|
+
left: left,
|
|
902
|
+
topOffset: topOffset,
|
|
903
|
+
leftOffset: leftOffset
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Checks the `top` and `left` properties that are set and updates the isStuckToBottom/Right properties
|
|
908
|
+
* Should be called when user interaction occurs
|
|
909
|
+
* @param {object} viewState New state properties to set.
|
|
910
|
+
* @param {boolean} forceUpdate Whether to force an update.
|
|
911
|
+
*/
|
|
1062
912
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
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
|
+
}
|
|
1066
929
|
|
|
1067
|
-
|
|
1068
|
-
|
|
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
|
-
});
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
});
|
|
1079
|
-
yield model.setValues(edits);
|
|
1080
|
-
} catch (e) {
|
|
1081
|
-
var {
|
|
1082
|
-
onError
|
|
1083
|
-
} = _this.props;
|
|
1084
|
-
onError(e);
|
|
930
|
+
if (left != null) {
|
|
931
|
+
this.isStuckToRight = isStickyRight && left >= lastLeft;
|
|
1085
932
|
}
|
|
1086
|
-
})();
|
|
1087
|
-
}
|
|
1088
933
|
|
|
1089
|
-
|
|
1090
|
-
var {
|
|
1091
|
-
model
|
|
1092
|
-
} = this.props;
|
|
1093
|
-
var modelColumn = this.getModelColumn(column);
|
|
1094
|
-
var modelRow = this.getModelRow(row);
|
|
934
|
+
this.setState(viewState);
|
|
1095
935
|
|
|
1096
|
-
|
|
1097
|
-
|
|
936
|
+
if (forceUpdate) {
|
|
937
|
+
this.forceUpdate();
|
|
938
|
+
}
|
|
1098
939
|
}
|
|
1099
|
-
|
|
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
|
+
*/
|
|
1100
949
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
950
|
+
}, {
|
|
951
|
+
key: "startEditing",
|
|
952
|
+
value: function startEditing(column, row) {
|
|
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
|
+
*/
|
|
1112
987
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
988
|
+
}, {
|
|
989
|
+
key: "pasteValue",
|
|
990
|
+
value: function () {
|
|
991
|
+
var _pasteValue = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(value) {
|
|
992
|
+
var model, _this$state7, movedColumns, movedRows, selectedRanges, _edits, modelRanges, tableHeight, tableWidth, columnCount, rowCount, ranges, edits, onError;
|
|
993
|
+
|
|
994
|
+
return regeneratorRuntime.wrap(function _callee$(_context) {
|
|
995
|
+
while (1) {
|
|
996
|
+
switch (_context.prev = _context.next) {
|
|
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();
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}, _callee, this, [[2, 27]]);
|
|
1099
|
+
}));
|
|
1117
1100
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
var columnSelected = selectedRange.startColumn === null || selectedRange.startColumn <= column && column <= selectedRange.endColumn;
|
|
1101
|
+
function pasteValue(_x) {
|
|
1102
|
+
return _pasteValue.apply(this, arguments);
|
|
1103
|
+
}
|
|
1122
1104
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1105
|
+
return pasteValue;
|
|
1106
|
+
}()
|
|
1107
|
+
}, {
|
|
1108
|
+
key: "setValueForCell",
|
|
1109
|
+
value: function setValueForCell(column, row, value) {
|
|
1110
|
+
var model = this.props.model;
|
|
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);
|
|
1125
1116
|
}
|
|
1126
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
|
+
}
|
|
1127
1142
|
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
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) {
|
|
1143
|
+
return false;
|
|
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;
|
|
1142
1150
|
document.documentElement.classList.remove(this.documentCursor);
|
|
1143
|
-
|
|
1144
|
-
this.documentCursor
|
|
1151
|
+
this.documentCursor = Grid.getCursorClassName(cursor);
|
|
1152
|
+
document.documentElement.classList.add(this.documentCursor);
|
|
1153
|
+
document.documentElement.classList.add('grid-block-events');
|
|
1145
1154
|
}
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
stopDragTimer() {
|
|
1157
|
-
if (this.dragTimer) {
|
|
1158
|
-
clearTimeout(this.dragTimer);
|
|
1159
|
-
this.dragTimer = null;
|
|
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
|
+
}
|
|
1160
1163
|
}
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
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
|
-
}
|
|
1164
|
+
}, {
|
|
1165
|
+
key: "startDragTimer",
|
|
1166
|
+
value: function startDragTimer(event) {
|
|
1167
|
+
var _this5 = this;
|
|
1168
|
+
|
|
1169
|
+
this.stopDragTimer();
|
|
1170
|
+
var mouseEvent = new MouseEvent('custom', event);
|
|
1171
|
+
this.dragTimer = setTimeout(function () {
|
|
1172
|
+
_this5.handleMouseDrag(mouseEvent);
|
|
1173
|
+
}, Grid.dragTimeout);
|
|
1174
|
+
}
|
|
1175
|
+
}, {
|
|
1176
|
+
key: "stopDragTimer",
|
|
1177
|
+
value: function stopDragTimer() {
|
|
1178
|
+
if (this.dragTimer) {
|
|
1179
|
+
clearTimeout(this.dragTimer);
|
|
1180
|
+
this.dragTimer = null;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
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
|
+
*/
|
|
1231
1187
|
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1188
|
+
}, {
|
|
1189
|
+
key: "drawCanvas",
|
|
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
|
+
}
|
|
1235
1274
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1275
|
+
this.canvas.focus();
|
|
1276
|
+
}
|
|
1277
|
+
}, {
|
|
1278
|
+
key: "handleContextMenu",
|
|
1279
|
+
value: function handleContextMenu(event) {
|
|
1280
|
+
var gridPoint = this.getGridPointFromEvent(event);
|
|
1281
|
+
var mouseHandlers = this.getMouseHandlers();
|
|
1282
|
+
|
|
1283
|
+
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1284
|
+
var mouseHandler = mouseHandlers[i];
|
|
1285
|
+
|
|
1286
|
+
if (mouseHandler.onContextMenu(gridPoint, this, event)) {
|
|
1287
|
+
event.stopPropagation();
|
|
1288
|
+
event.preventDefault();
|
|
1289
|
+
break;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
}, {
|
|
1294
|
+
key: "handleKeyDown",
|
|
1295
|
+
value: function handleKeyDown(e) {
|
|
1296
|
+
var keyHandlers = this.getKeyHandlers();
|
|
1239
1297
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1298
|
+
for (var i = 0; i < keyHandlers.length; i += 1) {
|
|
1299
|
+
var keyHandler = keyHandlers[i];
|
|
1300
|
+
var result = keyHandler.onDown(e, this);
|
|
1243
1301
|
|
|
1244
|
-
|
|
1245
|
-
|
|
1302
|
+
if (result) {
|
|
1303
|
+
var _result$stopPropagati, _result$preventDefaul;
|
|
1246
1304
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1305
|
+
if ((_result$stopPropagati = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati !== void 0 ? _result$stopPropagati : true) e.stopPropagation();
|
|
1306
|
+
if ((_result$preventDefaul = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul !== void 0 ? _result$preventDefaul : true) e.preventDefault();
|
|
1307
|
+
break;
|
|
1308
|
+
}
|
|
1251
1309
|
}
|
|
1252
1310
|
}
|
|
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
|
+
*/
|
|
1253
1318
|
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1319
|
+
}, {
|
|
1320
|
+
key: "notifyMouseHandlers",
|
|
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;
|
|
1260
1327
|
|
|
1261
|
-
|
|
1262
|
-
|
|
1328
|
+
for (var i = 0; i < mouseHandlers.length; i += 1) {
|
|
1329
|
+
var mouseHandler = mouseHandlers[i];
|
|
1330
|
+
var result = mouseHandler[functionName] && mouseHandler[functionName](gridPoint, this, event);
|
|
1263
1331
|
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
event.preventDefault();
|
|
1267
|
-
break;
|
|
1268
|
-
}
|
|
1269
|
-
}
|
|
1270
|
-
}
|
|
1332
|
+
if (result) {
|
|
1333
|
+
var _result$stopPropagati2, _result$preventDefaul2;
|
|
1271
1334
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1335
|
+
if (mouseHandler.cursor != null) {
|
|
1336
|
+
cursor = mouseHandler.cursor;
|
|
1274
1337
|
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1338
|
+
if (addCursorToDocument) {
|
|
1339
|
+
this.addDocumentCursor(cursor);
|
|
1340
|
+
}
|
|
1341
|
+
} // result is bool or object, events are stopped by default
|
|
1278
1342
|
|
|
1279
|
-
if (result) {
|
|
1280
|
-
var _result$stopPropagati, _result$preventDefaul;
|
|
1281
1343
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1344
|
+
if ((_result$stopPropagati2 = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati2 !== void 0 ? _result$stopPropagati2 : true) event.stopPropagation();
|
|
1345
|
+
if ((_result$preventDefaul2 = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul2 !== void 0 ? _result$preventDefaul2 : true) event.preventDefault();
|
|
1346
|
+
break;
|
|
1347
|
+
}
|
|
1285
1348
|
}
|
|
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
|
|
1320
1349
|
|
|
1350
|
+
this.setState({
|
|
1351
|
+
cursor: cursor
|
|
1352
|
+
});
|
|
1321
1353
|
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1354
|
+
if (updateCoordinates) {
|
|
1355
|
+
var x = gridPoint.x,
|
|
1356
|
+
y = gridPoint.y;
|
|
1357
|
+
this.setState({
|
|
1358
|
+
mouseX: x,
|
|
1359
|
+
mouseY: y
|
|
1360
|
+
});
|
|
1325
1361
|
}
|
|
1326
1362
|
}
|
|
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
|
+
}
|
|
1327
1372
|
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1373
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOWN, event);
|
|
1374
|
+
this.startDragTimer(event);
|
|
1375
|
+
}
|
|
1376
|
+
}, {
|
|
1377
|
+
key: "handleDoubleClick",
|
|
1378
|
+
value: function handleDoubleClick(event) {
|
|
1379
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOUBLE_CLICK, event);
|
|
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);
|
|
1337
1390
|
this.setState({
|
|
1338
|
-
mouseX:
|
|
1339
|
-
mouseY:
|
|
1391
|
+
mouseX: null,
|
|
1392
|
+
mouseY: null
|
|
1340
1393
|
});
|
|
1341
1394
|
}
|
|
1342
|
-
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1395
|
+
}, {
|
|
1396
|
+
key: "handleMouseDrag",
|
|
1397
|
+
value: function handleMouseDrag(event) {
|
|
1398
|
+
this.setState({
|
|
1399
|
+
isDragging: true
|
|
1400
|
+
});
|
|
1401
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DRAG, event, true, true);
|
|
1402
|
+
this.stopDragTimer();
|
|
1350
1403
|
}
|
|
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
|
+
}
|
|
1351
1413
|
|
|
1352
|
-
|
|
1353
|
-
|
|
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;
|
|
1414
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.UP, event, false);
|
|
1415
|
+
this.stopDragTimer();
|
|
1416
|
+
this.removeDocumentCursor();
|
|
1386
1417
|
}
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
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;
|
|
1418
|
+
}, {
|
|
1419
|
+
key: "handleResize",
|
|
1420
|
+
value: function handleResize() {
|
|
1421
|
+
/**
|
|
1422
|
+
* We need to always redraw the canvas in the same frame as the updateCanvasScale
|
|
1423
|
+
* because it clears the canvas by nature of direct dom manipulation. However,
|
|
1424
|
+
* We also need to verify the state/metrics, which we currently have no way
|
|
1425
|
+
* of doing outside of a full componentDidUpdate() call, so we force the update.
|
|
1426
|
+
* Ideally, we could verify state/metrics without the forced update.
|
|
1427
|
+
*/
|
|
1428
|
+
this.updateCanvasScale();
|
|
1429
|
+
this.updateCanvas();
|
|
1430
|
+
this.forceUpdate();
|
|
1411
1431
|
}
|
|
1432
|
+
}, {
|
|
1433
|
+
key: "handleWheel",
|
|
1434
|
+
value: function handleWheel(e) {
|
|
1435
|
+
this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.WHEEL, e);
|
|
1412
1436
|
|
|
1413
|
-
|
|
1414
|
-
|
|
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;
|
|
1437
|
+
if (e.defaultPrevented) {
|
|
1438
|
+
return;
|
|
1442
1439
|
}
|
|
1443
1440
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1441
|
+
var metricCalculator = this.metricCalculator,
|
|
1442
|
+
metrics = this.metrics;
|
|
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();
|
|
1446
1451
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1452
|
+
var _GridUtils$getScrollD = GridUtils.getScrollDelta(e, metrics.barWidth, metrics.barHeight, metrics.rowHeight, metrics.rowHeight),
|
|
1453
|
+
deltaX = _GridUtils$getScrollD.deltaX,
|
|
1454
|
+
deltaY = _GridUtils$getScrollD.deltaY; // iterate through each column to determine column width and figure out how far to scroll
|
|
1455
|
+
// get column width of next column to scroll to, and subract it from the remaining distance to travel
|
|
1450
1456
|
|
|
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;
|
|
1463
1457
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1458
|
+
while (deltaX !== 0) {
|
|
1459
|
+
leftOffset += deltaX;
|
|
1460
|
+
deltaX = 0; // no scrolling needed, at directional edge
|
|
1467
1461
|
|
|
1468
|
-
if (
|
|
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;
|
|
1462
|
+
if (leftOffset > 0 && left >= lastLeft || leftOffset < 0 && left <= 0) {
|
|
1475
1463
|
leftOffset = 0;
|
|
1476
|
-
|
|
1464
|
+
break;
|
|
1477
1465
|
}
|
|
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
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
while (deltaY !== 0) {
|
|
1484
|
-
topOffset += deltaY;
|
|
1485
|
-
deltaY = 0; // no scrolling needed, at directional edge
|
|
1486
1466
|
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
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
|
|
1491
1504
|
|
|
1492
|
-
if (topOffset > 0) {
|
|
1493
|
-
var _metrics$visibleRowHe;
|
|
1494
1505
|
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1506
|
+
while (deltaY !== 0) {
|
|
1507
|
+
topOffset += deltaY;
|
|
1508
|
+
deltaY = 0; // no scrolling needed, at directional edge
|
|
1498
1509
|
|
|
1499
|
-
if (topOffset >=
|
|
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
|
|
1510
|
+
if (topOffset > 0 && top >= lastTop || topOffset < 0 && top <= 0) {
|
|
1506
1511
|
topOffset = 0;
|
|
1507
|
-
|
|
1512
|
+
break;
|
|
1508
1513
|
}
|
|
1509
|
-
} else if (topOffset < 0) {
|
|
1510
|
-
var _metrics$visibleRowHe2;
|
|
1511
|
-
|
|
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
1514
|
|
|
1516
|
-
if (
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
topOffset
|
|
1524
|
-
|
|
1515
|
+
if (topOffset > 0) {
|
|
1516
|
+
var _metrics$visibleRowHe;
|
|
1517
|
+
|
|
1518
|
+
// scroll direction down
|
|
1519
|
+
// get height of next row
|
|
1520
|
+
var rowHeight = (_metrics$visibleRowHe = metrics.visibleRowHeights.get(top)) !== null && _metrics$visibleRowHe !== void 0 ? _metrics$visibleRowHe : metricCalculator.getVisibleRowHeight(top, metricState);
|
|
1521
|
+
|
|
1522
|
+
if (topOffset >= rowHeight) {
|
|
1523
|
+
// remove height from balance and advance by 1 row
|
|
1524
|
+
deltaY = topOffset - rowHeight;
|
|
1525
|
+
topOffset = 0;
|
|
1526
|
+
top += 1;
|
|
1527
|
+
} else if (theme.scrollSnapToRow) {
|
|
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
|
+
}
|
|
1525
1549
|
}
|
|
1526
1550
|
}
|
|
1527
|
-
}
|
|
1528
1551
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1552
|
+
this.setViewState({
|
|
1553
|
+
top: top,
|
|
1554
|
+
left: left,
|
|
1555
|
+
leftOffset: leftOffset,
|
|
1556
|
+
topOffset: topOffset
|
|
1557
|
+
});
|
|
1558
|
+
e.stopPropagation();
|
|
1559
|
+
e.preventDefault();
|
|
1560
|
+
}
|
|
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
|
+
}
|
|
1538
1603
|
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
editingCell: null
|
|
1542
|
-
});
|
|
1543
|
-
this.focus();
|
|
1544
|
-
}
|
|
1604
|
+
return;
|
|
1605
|
+
}
|
|
1545
1606
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
}
|
|
1551
|
-
return {
|
|
1552
|
-
editingCell: _objectSpread(_objectSpread({}, editingCell), {}, {
|
|
1553
|
-
value
|
|
1554
|
-
})
|
|
1555
|
-
};
|
|
1556
|
-
});
|
|
1557
|
-
}
|
|
1607
|
+
if (fillRange) {
|
|
1608
|
+
this.setValueForRanges(selectedRanges, value);
|
|
1609
|
+
} else {
|
|
1610
|
+
this.setValueForCell(column, row, value);
|
|
1611
|
+
}
|
|
1558
1612
|
|
|
1559
|
-
|
|
1560
|
-
|
|
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
|
-
});
|
|
1613
|
+
if (direction != null) {
|
|
1614
|
+
this.moveCursorInDirection(direction);
|
|
1577
1615
|
}
|
|
1578
1616
|
|
|
1579
|
-
|
|
1617
|
+
this.setState({
|
|
1618
|
+
editingCell: null
|
|
1619
|
+
});
|
|
1620
|
+
this.focus();
|
|
1580
1621
|
}
|
|
1622
|
+
}, {
|
|
1623
|
+
key: "renderInputField",
|
|
1624
|
+
value: function renderInputField() {
|
|
1625
|
+
var model = this.props.model;
|
|
1626
|
+
var editingCell = this.state.editingCell;
|
|
1627
|
+
var metrics = this.metrics;
|
|
1628
|
+
|
|
1629
|
+
if (editingCell == null || metrics == null) {
|
|
1630
|
+
return null;
|
|
1631
|
+
}
|
|
1581
1632
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1633
|
+
var _editingCell$selectio = editingCell.selectionRange,
|
|
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
|
+
}));
|
|
1586
1682
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1683
|
+
}, {
|
|
1684
|
+
key: "render",
|
|
1685
|
+
value: function render() {
|
|
1686
|
+
var _this6 = this;
|
|
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());
|
|
1590
1703
|
}
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
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;
|
|
1704
|
+
}], [{
|
|
1705
|
+
key: "getScale",
|
|
1706
|
+
value: // use same constant as chrome source for windows
|
|
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;
|
|
1611
1712
|
}
|
|
1713
|
+
}, {
|
|
1714
|
+
key: "getCursorClassName",
|
|
1715
|
+
value: function getCursorClassName(cursor) {
|
|
1716
|
+
return cursor ? "grid-cursor-".concat(cursor) : null;
|
|
1717
|
+
}
|
|
1718
|
+
}]);
|
|
1612
1719
|
|
|
1613
|
-
|
|
1614
|
-
|
|
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
|
-
}
|
|
1720
|
+
return Grid;
|
|
1721
|
+
}(PureComponent);
|
|
1689
1722
|
|
|
1690
1723
|
_defineProperty(Grid, "pixelsPerLine", 100 / 3);
|
|
1691
1724
|
|
|
1692
1725
|
_defineProperty(Grid, "dragTimeout", 1000);
|
|
1693
1726
|
|
|
1694
|
-
_defineProperty(Grid, "getTheme", memoize(
|
|
1727
|
+
_defineProperty(Grid, "getTheme", memoize(function (userTheme) {
|
|
1728
|
+
return _objectSpread(_objectSpread({}, GridTheme), userTheme);
|
|
1729
|
+
}));
|
|
1695
1730
|
|
|
1696
1731
|
Grid.propTypes = {
|
|
1697
1732
|
canvasOptions: PropTypes.shape({}),
|
|
@@ -1732,11 +1767,11 @@ Grid.defaultProps = {
|
|
|
1732
1767
|
mouseHandlers: [],
|
|
1733
1768
|
movedColumns: [],
|
|
1734
1769
|
movedRows: [],
|
|
1735
|
-
onError: ()
|
|
1736
|
-
onSelectionChanged: ()
|
|
1737
|
-
onMovedColumnsChanged: ()
|
|
1738
|
-
onMoveColumnComplete: ()
|
|
1739
|
-
onViewChanged: ()
|
|
1770
|
+
onError: function onError() {},
|
|
1771
|
+
onSelectionChanged: function onSelectionChanged() {},
|
|
1772
|
+
onMovedColumnsChanged: function onMovedColumnsChanged() {},
|
|
1773
|
+
onMoveColumnComplete: function onMoveColumnComplete() {},
|
|
1774
|
+
onViewChanged: function onViewChanged() {},
|
|
1740
1775
|
renderer: null,
|
|
1741
1776
|
stateOverride: {},
|
|
1742
1777
|
theme: {
|