|
1 | | -import { MAX_DELAY } from "../../helpers"; |
2 | | -import { SpreadsheetChildEnv } from "../../types/env"; |
3 | | -import { HeaderIndex } from "../../types/misc"; |
4 | | -import { gridOverlayPosition } from "./dom_helpers"; |
5 | | -type EventFn = (ev: MouseEvent) => void; |
| 1 | +type EventFn = (ev: PointerEvent) => void; |
6 | 2 |
|
7 | 3 | /** |
8 | 4 | * Start listening to pointer events and apply the given callbacks. |
9 | 5 | * |
10 | 6 | * @returns A function to remove the listeners. |
11 | 7 | */ |
12 | | -export function startDnd( |
13 | | - onMouseMove: EventFn, |
14 | | - onMouseUp: EventFn, |
15 | | - onMouseDown: EventFn = () => {} |
16 | | -) { |
| 8 | +export function startDnd(onPointerMove: EventFn, onPointerUp: EventFn) { |
17 | 9 | const removeListeners = () => { |
18 | | - window.removeEventListener("pointerdown", onMouseDown); |
19 | | - window.removeEventListener("pointerup", _onMouseUp); |
| 10 | + window.removeEventListener("pointerup", _onPointerUp); |
20 | 11 | window.removeEventListener("dragstart", _onDragStart); |
21 | | - window.removeEventListener("pointermove", onMouseMove); |
22 | | - window.removeEventListener("wheel", onMouseMove); |
| 12 | + window.removeEventListener("pointermove", onPointerMove); |
| 13 | + window.removeEventListener("wheel", onPointerMove); |
23 | 14 | }; |
24 | | - const _onMouseUp = (ev: MouseEvent) => { |
25 | | - onMouseUp(ev); |
| 15 | + const _onPointerUp = (ev: PointerEvent) => { |
| 16 | + onPointerUp(ev); |
26 | 17 | removeListeners(); |
27 | 18 | }; |
28 | 19 | function _onDragStart(ev: DragEvent) { |
29 | 20 | ev.preventDefault(); |
30 | 21 | } |
31 | | - window.addEventListener("pointerdown", onMouseDown); |
32 | | - window.addEventListener("pointerup", _onMouseUp); |
| 22 | + window.addEventListener("pointerup", _onPointerUp); |
33 | 23 | window.addEventListener("dragstart", _onDragStart); |
34 | | - window.addEventListener("pointermove", onMouseMove); |
| 24 | + window.addEventListener("pointermove", onPointerMove); |
35 | 25 | // mouse wheel on window is by default a passive event. |
36 | 26 | // preventDefault() is not allowed in passive event handler. |
37 | 27 | // https://chromestatus.com/feature/6662647093133312 |
38 | | - window.addEventListener("wheel", onMouseMove, { passive: false }); |
| 28 | + window.addEventListener("wheel", onPointerMove, { passive: false }); |
39 | 29 |
|
40 | 30 | return removeListeners; |
41 | 31 | } |
42 | | - |
43 | | -/** |
44 | | - * Function to be used during a pointerdown event, this function allows to |
45 | | - * perform actions related to the pointermove and pointerup events and adjusts the viewport |
46 | | - * when the new position related to the pointermove event is outside of it. |
47 | | - * Among inputs are two callback functions. First intended for actions performed during |
48 | | - * the pointermove event, it receives as parameters the current position of the pointermove |
49 | | - * (occurrence of the current column and the current row). Second intended for actions |
50 | | - * performed during the pointerup event. |
51 | | - */ |
52 | | -export function dragAndDropBeyondTheViewport( |
53 | | - env: SpreadsheetChildEnv, |
54 | | - cbMouseMove: (col: HeaderIndex, row: HeaderIndex, ev: MouseEvent) => void, |
55 | | - cbMouseUp: () => void, |
56 | | - only: "horizontal" | "vertical" | false = false |
57 | | -) { |
58 | | - let timeOutId: any = null; |
59 | | - let currentEv: MouseEvent; |
60 | | - let previousEv: MouseEvent; |
61 | | - let startingEv: MouseEvent; |
62 | | - let startingX: number; |
63 | | - let startingY: number; |
64 | | - const getters = env.model.getters; |
65 | | - const sheetId = getters.getActiveSheetId(); |
66 | | - const position = gridOverlayPosition(); |
67 | | - let colIndex: number; |
68 | | - let rowIndex: number; |
69 | | - const onMouseDown = (ev: MouseEvent) => { |
70 | | - previousEv = ev; |
71 | | - startingEv = ev; |
72 | | - startingX = startingEv.clientX - position.left; |
73 | | - startingY = startingEv.clientY - position.top; |
74 | | - }; |
75 | | - const onMouseMove = (ev: MouseEvent) => { |
76 | | - currentEv = ev; |
77 | | - if (timeOutId) { |
78 | | - return; |
79 | | - } |
80 | | - |
81 | | - const { x: offsetCorrectionX, y: offsetCorrectionY } = getters.getMainViewportCoordinates(); |
82 | | - let { top, left, bottom, right } = getters.getActiveMainViewport(); |
83 | | - let { scrollX, scrollY } = getters.getActiveSheetScrollInfo(); |
84 | | - const { xSplit, ySplit } = getters.getPaneDivisions(sheetId); |
85 | | - let canEdgeScroll = false; |
86 | | - let timeoutDelay = MAX_DELAY; |
87 | | - |
88 | | - const x = currentEv.clientX - position.left; |
89 | | - colIndex = getters.getColIndex(x); |
90 | | - |
91 | | - if (only !== "vertical") { |
92 | | - const previousX = previousEv.clientX - position.left; |
93 | | - const edgeScrollInfoX = getters.getEdgeScrollCol(x, previousX, startingX); |
94 | | - if (edgeScrollInfoX.canEdgeScroll) { |
95 | | - canEdgeScroll = true; |
96 | | - timeoutDelay = Math.min(timeoutDelay, edgeScrollInfoX.delay); |
97 | | - let newTarget: number; |
98 | | - switch (edgeScrollInfoX.direction) { |
99 | | - case "reset": |
100 | | - colIndex = xSplit; |
101 | | - newTarget = xSplit; |
102 | | - break; |
103 | | - case 1: |
104 | | - colIndex = right; |
105 | | - newTarget = left + 1; |
106 | | - break; |
107 | | - case -1: |
108 | | - colIndex = left - 1; |
109 | | - while (env.model.getters.isColHidden(sheetId, colIndex)) { |
110 | | - colIndex--; |
111 | | - } |
112 | | - newTarget = colIndex; |
113 | | - break; |
114 | | - } |
115 | | - scrollX = getters.getColDimensions(sheetId, newTarget!).start - offsetCorrectionX; |
116 | | - } |
117 | | - } |
118 | | - |
119 | | - const y = currentEv.clientY - position.top; |
120 | | - rowIndex = getters.getRowIndex(y); |
121 | | - |
122 | | - if (only !== "horizontal") { |
123 | | - const previousY = previousEv.clientY - position.top; |
124 | | - const edgeScrollInfoY = getters.getEdgeScrollRow(y, previousY, startingY); |
125 | | - if (edgeScrollInfoY.canEdgeScroll) { |
126 | | - canEdgeScroll = true; |
127 | | - timeoutDelay = Math.min(timeoutDelay, edgeScrollInfoY.delay); |
128 | | - let newTarget: number; |
129 | | - switch (edgeScrollInfoY.direction) { |
130 | | - case "reset": |
131 | | - rowIndex = ySplit; |
132 | | - newTarget = ySplit; |
133 | | - break; |
134 | | - case 1: |
135 | | - rowIndex = bottom; |
136 | | - newTarget = top + edgeScrollInfoY.direction; |
137 | | - break; |
138 | | - case -1: |
139 | | - rowIndex = top - 1; |
140 | | - while (env.model.getters.isRowHidden(sheetId, rowIndex)) { |
141 | | - rowIndex--; |
142 | | - } |
143 | | - newTarget = rowIndex; |
144 | | - break; |
145 | | - } |
146 | | - scrollY = env.model.getters.getRowDimensions(sheetId, newTarget!).start - offsetCorrectionY; |
147 | | - } |
148 | | - } |
149 | | - |
150 | | - if (!canEdgeScroll) { |
151 | | - if (rowIndex === -1) { |
152 | | - rowIndex = y < 0 ? 0 : getters.getNumberRows(sheetId) - 1; |
153 | | - } |
154 | | - if (colIndex === -1 && x < 0) { |
155 | | - colIndex = x < 0 ? 0 : getters.getNumberCols(sheetId) - 1; |
156 | | - } |
157 | | - } |
158 | | - |
159 | | - cbMouseMove(colIndex, rowIndex, currentEv); |
160 | | - if (canEdgeScroll) { |
161 | | - env.model.dispatch("SET_VIEWPORT_OFFSET", { offsetX: scrollX, offsetY: scrollY }); |
162 | | - timeOutId = setTimeout(() => { |
163 | | - timeOutId = null; |
164 | | - onMouseMove(currentEv); |
165 | | - }, Math.round(timeoutDelay)); |
166 | | - } |
167 | | - previousEv = currentEv; |
168 | | - }; |
169 | | - |
170 | | - const onMouseUp = () => { |
171 | | - clearTimeout(timeOutId); |
172 | | - cbMouseUp(); |
173 | | - }; |
174 | | - |
175 | | - startDnd(onMouseMove, onMouseUp, onMouseDown); |
176 | | -} |
0 commit comments