Skip to content

Commit 03763e1

Browse files
committed
fix: converted react image annotate to use react-hotkeys, fixed double
hotkeys
1 parent d3a9e15 commit 03763e1

File tree

6 files changed

+176
-10
lines changed

6 files changed

+176
-10
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"material-survey": "^1.0.34",
1313
"moment": "^2.23.0",
1414
"react-full-screen": "^0.2.4",
15+
"react-hotkeys": "^2.0.0",
1516
"react-json-view": "^1.19.1",
1617
"react-markdown": "^4.0.6",
1718
"react-monaco-editor": "^0.25.1",
@@ -68,7 +69,7 @@
6869
"babel-loader": "^8.0.5",
6970
"babel-preset-react-app": "^7.0.0",
7071
"gh-pages": "^2.0.1",
71-
"prettier": "^2.0.4",
72+
"prettier": "^2.0.5",
7273
"raw.macro": "^0.3.0",
7374
"react-github-btn": "^1.1.1",
7475
"react-scripts": "^2.1.8"

src/Annotator/index.js

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import generalReducer from "./reducers/general-reducer.js"
1717
import imageReducer from "./reducers/image-reducer.js"
1818
import videoReducer from "./reducers/video-reducer.js"
1919
import historyHandler from "./reducers/history-handler.js"
20+
import ShortcutsManager from "../ShortcutsManager"
2021

2122
import useEventCallback from "use-event-callback"
2223
import makeImmutable, { without } from "seamless-immutable"
@@ -131,13 +132,15 @@ export const Annotator = ({
131132

132133
return (
133134
<SettingsProvider>
134-
<MainLayout
135-
RegionEditLabel={RegionEditLabel}
136-
alwaysShowNextButton={Boolean(onNextImage)}
137-
alwaysShowPrevButton={Boolean(onPrevImage)}
138-
state={state}
139-
dispatch={dispatch}
140-
/>
135+
<ShortcutsManager dispatch={dispatch}>
136+
<MainLayout
137+
RegionEditLabel={RegionEditLabel}
138+
alwaysShowNextButton={Boolean(onNextImage)}
139+
alwaysShowPrevButton={Boolean(onPrevImage)}
140+
state={state}
141+
dispatch={dispatch}
142+
/>
143+
</ShortcutsManager>
141144
</SettingsProvider>
142145
)
143146
}

src/Annotator/index.story.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { action as actionAddon } from "@storybook/addon-actions"
77
import exampleImage from "../ImageCanvas/seves_desk.story.jpg"
88
import bikeImg1 from "./bike-pic.png"
99
import bikeImg2 from "./bike-pic2.png"
10+
import { HotKeys } from "react-hotkeys"
11+
import { defaultKeyMap } from "../ShortcutsManager"
1012

1113
import Annotator from "./"
1214

@@ -562,3 +564,44 @@ storiesOf("Annotator", module)
562564
/>
563565
)
564566
})
567+
.add("Two on sample page w/ hotkeys", () => {
568+
console.log({ defaultKeyMap })
569+
return (
570+
<HotKeys keyMap={defaultKeyMap}>
571+
<div>
572+
<Annotator
573+
onExit={actionAddon("onExit")}
574+
middlewares={[
575+
(store) => (next) => (action) => {
576+
actionAddon(action.type)(action)
577+
return next(action)
578+
},
579+
]}
580+
images={[
581+
{
582+
src: exampleImage,
583+
name: "Seve's Desk",
584+
regions: testRegions,
585+
},
586+
]}
587+
/>
588+
<Annotator
589+
onExit={actionAddon("onExit")}
590+
middlewares={[
591+
(store) => (next) => (action) => {
592+
actionAddon(action.type)(action)
593+
return next(action)
594+
},
595+
]}
596+
images={[
597+
{
598+
src: exampleImage,
599+
name: "Seve's Desk",
600+
regions: testRegions,
601+
},
602+
]}
603+
/>
604+
</div>
605+
</HotKeys>
606+
)
607+
})

src/DemoSite/index.story.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ import { action } from "@storybook/addon-actions"
77

88
import DemoSite from "./"
99

10-
storiesOf("DemoSite", module).add("Basic", () => <DemoSite />)
10+
storiesOf("DemoSite", module)
11+
.add("Basic", () => <DemoSite />)

src/ShortcutsManager/index.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import React, { useMemo } from "react"
2+
import { HotKeys } from "react-hotkeys"
3+
4+
export const defaultHotkeys = [
5+
{
6+
id: "select_tool",
7+
description: "Switch to the Select Tool",
8+
binding: "escape",
9+
},
10+
{
11+
id: "zoom_tool",
12+
description: "Select the Zoom Tool",
13+
binding: "z",
14+
},
15+
{
16+
id: "create_point",
17+
description: "Create a point",
18+
},
19+
{
20+
id: "pan_tool",
21+
description: "Select the Pan Tool",
22+
},
23+
{
24+
id: "create_polygon",
25+
description: "Create a Polygon",
26+
},
27+
{
28+
id: "create_pixel",
29+
description: "Create a Pixel Mask",
30+
},
31+
{
32+
id: "save_and_previous_sample",
33+
description: "Save and go to previous sample",
34+
},
35+
{
36+
id: "save_and_next_sample",
37+
description: "Save and go to next sample",
38+
},
39+
{
40+
id: "save_and_exit_sample",
41+
description: "Save and exit current sample",
42+
},
43+
{
44+
id: "exit_sample",
45+
description: "Exit sample without saving",
46+
},
47+
]
48+
export const defaultKeyMap = {}
49+
for (const { id, binding } of defaultHotkeys) defaultKeyMap[id] = binding
50+
51+
export default ({ children, dispatch }) => {
52+
const handlers = useMemo(
53+
() => ({
54+
select_tool: () => {
55+
dispatch({
56+
type: "SELECT_TOOL",
57+
selectedTool: "select-tool",
58+
})
59+
},
60+
zoom_tool: () => {
61+
dispatch({
62+
type: "SELECT_TOOL",
63+
selectedTool: "zoom",
64+
})
65+
},
66+
create_point: () => {
67+
dispatch({
68+
type: "SELECT_TOOL",
69+
selectedTool: "create-point",
70+
})
71+
},
72+
pan_tool: () => {
73+
dispatch({
74+
type: "SELECT_TOOL",
75+
selectedTool: "pan",
76+
})
77+
},
78+
create_polygon: () => {
79+
dispatch({
80+
type: "SELECT_TOOL",
81+
selectedTool: "create-polygon",
82+
})
83+
},
84+
create_pixel: () => {
85+
dispatch({
86+
type: "SELECT_TOOL",
87+
selectedTool: "create-pixel",
88+
})
89+
},
90+
save_and_previous_sample: () => {
91+
dispatch({
92+
type: "HEADER_BUTTON_CLICKED",
93+
buttonName: "Prev",
94+
})
95+
},
96+
save_and_next_sample: () => {
97+
dispatch({
98+
type: "HEADER_BUTTON_CLICKED",
99+
buttonName: "Next",
100+
})
101+
},
102+
save_and_exit_sample: () => {
103+
dispatch({
104+
type: "HEADER_BUTTON_CLICKED",
105+
buttonName: "Save",
106+
})
107+
},
108+
// TODO
109+
// exit_sample: () => {
110+
// dispatch({
111+
// type: "",
112+
// })
113+
// }
114+
}),
115+
[dispatch]
116+
)
117+
return <HotKeys handlers={handlers}>{children}</HotKeys>
118+
}

src/Sidebar/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ export const Sidebar = ({
105105
/>
106106
)}
107107
<History history={history} onRestoreHistory={() => onRestoreHistory()} />
108-
<Shortcuts onShortcutActionDispatched={onShortcutActionDispatched} />
108+
{/* <Shortcuts onShortcutActionDispatched={onShortcutActionDispatched} /> */}
109109
</div>
110110
)
111111
}

0 commit comments

Comments
 (0)