Explorar el Código

Adds undo redo

main
Steve Ruiz hace 4 años
padre
commit
9bca2dd646

+ 0
- 1
components/canvas/canvas.tsx Ver fichero

1
 import styled from "styles"
1
 import styled from "styles"
2
-import { getPointerEventInfo } from "utils/utils"
3
 import React, { useCallback, useRef } from "react"
2
 import React, { useCallback, useRef } from "react"
4
 import useZoomEvents from "hooks/useZoomEvents"
3
 import useZoomEvents from "hooks/useZoomEvents"
5
 import useCamera from "hooks/useCamera"
4
 import useCamera from "hooks/useCamera"

+ 0
- 1
components/canvas/shape.tsx Ver fichero

1
 import React, { useCallback, useRef, memo } from "react"
1
 import React, { useCallback, useRef, memo } from "react"
2
 import state, { useSelector } from "state"
2
 import state, { useSelector } from "state"
3
-import { getPointerEventInfo } from "utils/utils"
4
 import inputs from "state/inputs"
3
 import inputs from "state/inputs"
5
 import shapes from "lib/shapes"
4
 import shapes from "lib/shapes"
6
 import styled from "styles"
5
 import styled from "styles"

+ 7
- 1
hooks/useKeyboardEvents.ts Ver fichero

1
 import { useEffect } from "react"
1
 import { useEffect } from "react"
2
 import state from "state"
2
 import state from "state"
3
-import { getKeyboardEventInfo } from "utils/utils"
3
+import { getKeyboardEventInfo, isDarwin } from "utils/utils"
4
 
4
 
5
 export default function useKeyboardEvents() {
5
 export default function useKeyboardEvents() {
6
   useEffect(() => {
6
   useEffect(() => {
7
     function handleKeyDown(e: KeyboardEvent) {
7
     function handleKeyDown(e: KeyboardEvent) {
8
       if (e.key === "Escape") {
8
       if (e.key === "Escape") {
9
         state.send("CANCELLED")
9
         state.send("CANCELLED")
10
+      } else if (e.key === "z" && (isDarwin() ? e.metaKey : e.ctrlKey)) {
11
+        if (e.shiftKey) {
12
+          state.send("REDO")
13
+        } else {
14
+          state.send("UNDO")
15
+        }
10
       }
16
       }
11
 
17
 
12
       state.send("PRESSED_KEY", getKeyboardEventInfo(e))
18
       state.send("PRESSED_KEY", getKeyboardEventInfo(e))

+ 3
- 3
hooks/useZoomEvents.ts Ver fichero

1
 import React, { useEffect, useRef } from "react"
1
 import React, { useEffect, useRef } from "react"
2
 import state from "state"
2
 import state from "state"
3
-import { getPointerEventInfo } from "utils/utils"
3
+import inputs from "state/inputs"
4
 import * as vec from "utils/vec"
4
 import * as vec from "utils/vec"
5
 
5
 
6
 /**
6
 /**
24
       if (e.ctrlKey) {
24
       if (e.ctrlKey) {
25
         state.send("ZOOMED_CAMERA", {
25
         state.send("ZOOMED_CAMERA", {
26
           delta: e.deltaY,
26
           delta: e.deltaY,
27
-          ...getPointerEventInfo(e),
27
+          ...inputs.wheel(e),
28
         })
28
         })
29
         return
29
         return
30
       }
30
       }
31
 
31
 
32
       state.send("PANNED_CAMERA", {
32
       state.send("PANNED_CAMERA", {
33
         delta: [e.deltaX, e.deltaY],
33
         delta: [e.deltaX, e.deltaY],
34
-        ...getPointerEventInfo(e),
34
+        ...inputs.wheel(e),
35
       })
35
       })
36
     }
36
     }
37
 
37
 

+ 1
- 1
state/commands/translate-command.ts Ver fichero

1
 import Command from "./command"
1
 import Command from "./command"
2
-import history from "./history"
2
+import history from "../history"
3
 import { TranslateSnapshot } from "state/sessions/translate-session"
3
 import { TranslateSnapshot } from "state/sessions/translate-session"
4
 import { Data } from "types"
4
 import { Data } from "types"
5
 
5
 

state/commands/history.ts → state/history.ts Ver fichero

1
 import { Data } from "types"
1
 import { Data } from "types"
2
-import { BaseCommand } from "./command"
2
+import { BaseCommand } from "./commands/command"
3
 
3
 
4
 // A singleton to manage history changes.
4
 // A singleton to manage history changes.
5
 
5
 

+ 34
- 13
state/inputs.tsx Ver fichero

1
 import { PointerInfo } from "types"
1
 import { PointerInfo } from "types"
2
+import { isDarwin } from "utils/utils"
2
 
3
 
3
 class Inputs {
4
 class Inputs {
4
   points: Record<string, PointerInfo> = {}
5
   points: Record<string, PointerInfo> = {}
6
   pointerDown(e: PointerEvent | React.PointerEvent) {
7
   pointerDown(e: PointerEvent | React.PointerEvent) {
7
     const { shiftKey, ctrlKey, metaKey, altKey } = e
8
     const { shiftKey, ctrlKey, metaKey, altKey } = e
8
 
9
 
9
-    this.points[e.pointerId] = {
10
+    const info = {
10
       pointerId: e.pointerId,
11
       pointerId: e.pointerId,
11
       origin: [e.clientX, e.clientY],
12
       origin: [e.clientX, e.clientY],
12
       point: [e.clientX, e.clientY],
13
       point: [e.clientX, e.clientY],
13
       shiftKey,
14
       shiftKey,
14
       ctrlKey,
15
       ctrlKey,
15
-      metaKey,
16
+      metaKey: isDarwin() ? metaKey : ctrlKey,
16
       altKey,
17
       altKey,
17
     }
18
     }
18
 
19
 
19
-    return this.points[e.pointerId]
20
+    this.points[e.pointerId] = info
21
+
22
+    return info
20
   }
23
   }
21
 
24
 
22
   pointerMove(e: PointerEvent | React.PointerEvent) {
25
   pointerMove(e: PointerEvent | React.PointerEvent) {
23
-    if (this.points[e.pointerId]) {
24
-      this.points[e.pointerId].point = [e.clientX, e.clientY]
25
-      return this.points[e.pointerId]
26
-    }
27
-
28
     const { shiftKey, ctrlKey, metaKey, altKey } = e
26
     const { shiftKey, ctrlKey, metaKey, altKey } = e
29
 
27
 
30
-    return {
28
+    const prev = this.points[e.pointerId]
29
+
30
+    const info = {
31
       pointerId: e.pointerId,
31
       pointerId: e.pointerId,
32
-      origin: [e.clientX, e.clientY],
32
+      origin: prev?.origin || [e.clientX, e.clientY],
33
       point: [e.clientX, e.clientY],
33
       point: [e.clientX, e.clientY],
34
       shiftKey,
34
       shiftKey,
35
       ctrlKey,
35
       ctrlKey,
36
-      metaKey,
36
+      metaKey: isDarwin() ? metaKey : ctrlKey,
37
       altKey,
37
       altKey,
38
     }
38
     }
39
+
40
+    if (this.points[e.pointerId]) {
41
+      this.points[e.pointerId] = info
42
+    }
43
+
44
+    return info
39
   }
45
   }
40
 
46
 
41
   pointerUp(e: PointerEvent | React.PointerEvent) {
47
   pointerUp(e: PointerEvent | React.PointerEvent) {
42
-    this.points[e.pointerId].point = [e.clientX, e.clientY]
48
+    const { shiftKey, ctrlKey, metaKey, altKey } = e
43
 
49
 
44
-    const info = this.points[e.pointerId]
50
+    const prev = this.points[e.pointerId]
51
+
52
+    const info = {
53
+      pointerId: e.pointerId,
54
+      origin: prev?.origin || [e.clientX, e.clientY],
55
+      point: [e.clientX, e.clientY],
56
+      shiftKey,
57
+      ctrlKey,
58
+      metaKey: isDarwin() ? metaKey : ctrlKey,
59
+      altKey,
60
+    }
45
 
61
 
46
     delete this.points[e.pointerId]
62
     delete this.points[e.pointerId]
47
 
63
 
48
     return info
64
     return info
49
   }
65
   }
66
+
67
+  wheel(e: WheelEvent) {
68
+    const { shiftKey, ctrlKey, metaKey, altKey } = e
69
+    return { point: [e.clientX, e.clientY], shiftKey, ctrlKey, metaKey, altKey }
70
+  }
50
 }
71
 }
51
 
72
 
52
 export default new Inputs()
73
 export default new Inputs()

+ 21
- 0
state/state.ts Ver fichero

4
 import { Bounds, Data, PointerInfo, Shape, ShapeType } from "types"
4
 import { Bounds, Data, PointerInfo, Shape, ShapeType } from "types"
5
 import { defaultDocument } from "./data"
5
 import { defaultDocument } from "./data"
6
 import Shapes from "lib/shapes"
6
 import Shapes from "lib/shapes"
7
+import history from "state/history"
7
 import * as Sessions from "./sessions"
8
 import * as Sessions from "./sessions"
8
 
9
 
9
 const initialData: Data = {
10
 const initialData: Data = {
32
   initial: "selecting",
33
   initial: "selecting",
33
   states: {
34
   states: {
34
     selecting: {
35
     selecting: {
36
+      on: {
37
+        UNDO: { do: "undo" },
38
+        REDO: { do: "redo" },
39
+      },
35
       initial: "notPointing",
40
       initial: "notPointing",
36
       states: {
41
       states: {
37
         notPointing: {
42
         notPointing: {
118
     },
123
     },
119
   },
124
   },
120
   actions: {
125
   actions: {
126
+    // History
127
+    enableHistory() {
128
+      history.enable()
129
+    },
130
+    disableHistory() {
131
+      history.disable()
132
+    },
133
+    undo(data) {
134
+      history.undo(data)
135
+    },
136
+    redo(data) {
137
+      history.redo(data)
138
+    },
139
+
140
+    // Sessions
121
     cancelSession(data) {
141
     cancelSession(data) {
122
       session.cancel(data)
142
       session.cancel(data)
123
       session = undefined
143
       session = undefined
126
       session.complete(data)
146
       session.complete(data)
127
       session = undefined
147
       session = undefined
128
     },
148
     },
149
+
129
     // Brushing
150
     // Brushing
130
     startBrushSession(data, payload: { point: number[] }) {
151
     startBrushSession(data, payload: { point: number[] }) {
131
       session = new Sessions.BrushSession(
152
       session = new Sessions.BrushSession(

+ 10
- 7
utils/utils.ts Ver fichero

877
   return await d.json()
877
   return await d.json()
878
 }
878
 }
879
 
879
 
880
-export function getPointerEventInfo(
881
-  e: PointerEvent | React.PointerEvent | WheelEvent
882
-) {
880
+export function getKeyboardEventInfo(e: KeyboardEvent | React.KeyboardEvent) {
883
   const { shiftKey, ctrlKey, metaKey, altKey } = e
881
   const { shiftKey, ctrlKey, metaKey, altKey } = e
884
-  return { point: [e.clientX, e.clientY], shiftKey, ctrlKey, metaKey, altKey }
882
+  return {
883
+    key: e.key,
884
+    shiftKey,
885
+    ctrlKey,
886
+    metaKey: isDarwin() ? metaKey : ctrlKey,
887
+    altKey,
888
+  }
885
 }
889
 }
886
 
890
 
887
-export function getKeyboardEventInfo(e: KeyboardEvent | React.KeyboardEvent) {
888
-  const { shiftKey, ctrlKey, metaKey, altKey } = e
889
-  return { key: e.key, shiftKey, ctrlKey, metaKey, altKey }
891
+export function isDarwin() {
892
+  return /Mac|iPod|iPhone|iPad/.test(window.navigator.platform)
890
 }
893
 }

Loading…
Cancelar
Guardar