This commit is contained in:
Qing 2022-06-14 22:32:24 +08:00
parent 19e7e816af
commit 689d61968c

View File

@ -106,6 +106,11 @@ export default function Editor(props: EditorProps) {
const [sliderPos, setSliderPos] = useState<number>(0) const [sliderPos, setSliderPos] = useState<number>(0)
// redo 相关
const [redoRenders, setRedoRenders] = useState<HTMLImageElement[]>([])
const [redoCurLines, setRedoCurLines] = useState<Line[]>([])
const [redoLineGroups, setRedoLineGroups] = useState<LineGroup[]>([])
const draw = useCallback( const draw = useCallback(
(render: HTMLImageElement, lineGroup: LineGroup) => { (render: HTMLImageElement, lineGroup: LineGroup) => {
if (!context) { if (!context) {
@ -175,6 +180,9 @@ export default function Editor(props: EditorProps) {
draw(newRender, []) draw(newRender, [])
// Only append new LineGroup after inpainting success // Only append new LineGroup after inpainting success
setLineGroups(newLineGroups) setLineGroups(newLineGroups)
// clear redo stack
resetRedoState()
} catch (e: any) { } catch (e: any) {
setToastState({ setToastState({
open: true, open: true,
@ -303,10 +311,19 @@ export default function Editor(props: EditorProps) {
setPanned(false) setPanned(false)
}, [viewportRef, windowSize, original.width, windowSize.height, minScale]) }, [viewportRef, windowSize, original.width, windowSize.height, minScale])
const resetRedoState = () => {
setRedoCurLines([])
setRedoLineGroups([])
setRedoRenders([])
}
useEffect(() => { useEffect(() => {
setLineGroups([]) setLineGroups([])
setCurLineGroup([]) setCurLineGroup([])
setRenders([]) setRenders([])
resetRedoState()
resetZoom() resetZoom()
const imageSizeLimit = Math.max(original.width, original.height) const imageSizeLimit = Math.max(original.width, original.height)
setSizeLimit(imageSizeLimit) setSizeLimit(imageSizeLimit)
@ -445,28 +462,43 @@ export default function Editor(props: EditorProps) {
if (curLineGroup.length === 0) { if (curLineGroup.length === 0) {
return return
} }
const newLineGroup = curLineGroup.slice(0, curLineGroup.length - 1)
const lastLine = curLineGroup.pop()!
const newRedoCurLines = [...redoCurLines, lastLine]
setRedoCurLines(newRedoCurLines)
const newLineGroup = [...curLineGroup]
setCurLineGroup(newLineGroup) setCurLineGroup(newLineGroup)
drawOnCurrentRender(newLineGroup) drawOnCurrentRender(newLineGroup)
}, [curLineGroup, drawOnCurrentRender]) }, [curLineGroup, redoCurLines, drawOnCurrentRender])
const undoRender = useCallback(() => { const undoRender = useCallback(() => {
if (!renders.length) { if (!renders.length) {
return return
} }
const groups = lineGroups.slice(0, lineGroups.length - 1) // save line Group
setLineGroups(groups) const lastLineGroup = lineGroups.pop()!
setRedoLineGroups([...redoLineGroups, lastLineGroup])
// If render is undo, clear strokes
setRedoCurLines([])
setLineGroups([...lineGroups])
setCurLineGroup([]) setCurLineGroup([])
setIsDraging(false) setIsDraging(false)
const newRenders = renders.slice(0, renders.length - 1)
// save render
const lastRender = renders.pop()!
setRedoRenders([...redoRenders, lastRender])
const newRenders = [...renders]
setRenders(newRenders) setRenders(newRenders)
if (newRenders.length === 0) { if (newRenders.length === 0) {
draw(original, []) draw(original, [])
} else { } else {
draw(newRenders[newRenders.length - 1], []) draw(newRenders[newRenders.length - 1], [])
} }
}, [draw, renders, lineGroups, original]) }, [draw, renders, redoRenders, redoLineGroups, lineGroups, original])
const undo = () => { const undo = () => {
if (settings.runInpaintingManually && curLineGroup.length !== 0) { if (settings.runInpaintingManually && curLineGroup.length !== 0) {
@ -478,13 +510,15 @@ export default function Editor(props: EditorProps) {
// Handle Cmd+Z // Handle Cmd+Z
const undoPredicate = (event: KeyboardEvent) => { const undoPredicate = (event: KeyboardEvent) => {
const isCmdZ = (event.metaKey || event.ctrlKey) && event.key === 'z' const isCmdZ =
(event.metaKey || event.ctrlKey) && !event.shiftKey && event.key === 'z'
// Handle tab switch // Handle tab switch
if (event.key === 'Tab') { if (event.key === 'Tab') {
event.preventDefault() event.preventDefault()
} }
if (isCmdZ) { if (isCmdZ) {
event.preventDefault() event.preventDefault()
console.log('undo')
return true return true
} }
return false return false
@ -493,6 +527,9 @@ export default function Editor(props: EditorProps) {
useKey(undoPredicate, undo, undefined, [undoStroke, undoRender]) useKey(undoPredicate, undo, undefined, [undoStroke, undoRender])
const disableUndo = () => { const disableUndo = () => {
if (isInpaintingLoading) {
return true
}
if (renders.length > 0) { if (renders.length > 0) {
return false return false
} }
@ -508,6 +545,80 @@ export default function Editor(props: EditorProps) {
return false return false
} }
const redoStroke = useCallback(() => {
if (redoCurLines.length === 0) {
return
}
const line = redoCurLines.pop()!
setRedoCurLines([...redoCurLines])
const newLineGroup = [...curLineGroup, line]
setCurLineGroup(newLineGroup)
drawOnCurrentRender(newLineGroup)
}, [curLineGroup, redoCurLines, drawOnCurrentRender])
const redoRender = useCallback(() => {
if (redoRenders.length === 0) {
return
}
const lineGroup = redoLineGroups.pop()!
setRedoLineGroups([...redoLineGroups])
setLineGroups([...lineGroups, lineGroup])
setCurLineGroup([])
setIsDraging(false)
const render = redoRenders.pop()!
const newRenders = [...renders, render]
setRenders(newRenders)
draw(newRenders[newRenders.length - 1], [])
}, [draw, renders, redoRenders, redoLineGroups, lineGroups, original])
const redo = () => {
if (settings.runInpaintingManually && redoCurLines.length !== 0) {
redoStroke()
} else {
redoRender()
}
}
// Handle Cmd+shift+Z
const redoPredicate = (event: KeyboardEvent) => {
const isCmdZ =
(event.metaKey || event.ctrlKey) && event.shiftKey && event.key === 'z'
// Handle tab switch
if (event.key === 'Tab') {
event.preventDefault()
}
if (isCmdZ) {
event.preventDefault()
console.log('redo')
return true
}
return false
}
useKey(redoPredicate, redo, undefined, [redoStroke, redoRender])
const disableRedo = () => {
if (isInpaintingLoading) {
return true
}
if (redoRenders.length > 0) {
return false
}
if (settings.runInpaintingManually) {
if (redoCurLines.length === 0) {
return true
}
} else if (redoRenders.length === 0) {
return true
}
return false
}
useKeyPressEvent( useKeyPressEvent(
'Tab', 'Tab',
ev => { ev => {
@ -781,6 +892,27 @@ export default function Editor(props: EditorProps) {
onClick={undo} onClick={undo}
disabled={disableUndo()} disabled={disableUndo()}
/> />
<Button
toolTip="Redo"
tooltipPosition="top"
icon={
<svg
width="19"
height="9"
viewBox="0 0 19 9"
fill="none"
xmlns="http://www.w3.org/2000/svg"
transform="scale(-1,1)"
>
<path
d="M2 1C2 0.447715 1.55228 0 1 0C0.447715 0 0 0.447715 0 1H2ZM1 8H0V9H1V8ZM8 9C8.55228 9 9 8.55229 9 8C9 7.44771 8.55228 7 8 7V9ZM16.5963 7.42809C16.8327 7.92721 17.429 8.14016 17.9281 7.90374C18.4272 7.66731 18.6402 7.07103 18.4037 6.57191L16.5963 7.42809ZM16.9468 5.83205L17.8505 5.40396L16.9468 5.83205ZM0 1V8H2V1H0ZM1 9H8V7H1V9ZM1.66896 8.74329L6.66896 4.24329L5.33104 2.75671L0.331035 7.25671L1.66896 8.74329ZM16.043 6.26014L16.5963 7.42809L18.4037 6.57191L17.8505 5.40396L16.043 6.26014ZM6.65079 4.25926C9.67554 1.66661 14.3376 2.65979 16.043 6.26014L17.8505 5.40396C15.5805 0.61182 9.37523 -0.710131 5.34921 2.74074L6.65079 4.25926Z"
fill="currentColor"
/>
</svg>
}
onClick={redo}
disabled={disableRedo()}
/>
<Button <Button
toolTip="Show Original" toolTip="Show Original"
tooltipPosition="top" tooltipPosition="top"