add rerun last mask button

This commit is contained in:
Qing 2023-02-19 15:05:41 +08:00
parent 1a865810f5
commit 183334f8f7
4 changed files with 88 additions and 35 deletions

View File

@ -63,6 +63,7 @@ import emitter, {
EVENT_PROMPT, EVENT_PROMPT,
EVENT_CUSTOM_MASK, EVENT_CUSTOM_MASK,
EVENT_PAINT_BY_EXAMPLE, EVENT_PAINT_BY_EXAMPLE,
RERUN_LAST_MASK,
} from '../../event' } from '../../event'
import FileSelect from '../FileSelect/FileSelect' import FileSelect from '../FileSelect/FileSelect'
import InteractiveSeg from '../InteractiveSeg/InteractiveSeg' import InteractiveSeg from '../InteractiveSeg/InteractiveSeg'
@ -515,6 +516,28 @@ export default function Editor() {
} }
}, [runInpainting]) }, [runInpainting])
useEffect(() => {
emitter.on(RERUN_LAST_MASK, () => {
if (lastLineGroup.length !== 0) {
// 使用上一次手绘的 mask 生成
runInpainting(true, undefined, prevInteractiveSegMask)
} else if (prevInteractiveSegMask) {
// 使用上一次 IS 的 mask 生成
runInpainting(false, undefined, prevInteractiveSegMask)
} else {
setToastState({
open: true,
desc: 'No mask to reuse',
state: 'error',
duration: 1500,
})
}
})
return () => {
emitter.off(RERUN_LAST_MASK)
}
}, [runInpainting])
const hadRunInpainting = () => { const hadRunInpainting = () => {
return renders.length !== 0 return renders.length !== 0
} }

View File

@ -1,6 +1,6 @@
import { FolderIcon, PhotoIcon } from '@heroicons/react/24/outline' import { FolderIcon, PhotoIcon } from '@heroicons/react/24/outline'
import { PlayIcon } from '@radix-ui/react-icons' import { PlayIcon, ReloadIcon } from '@radix-ui/react-icons'
import React, { useState } from 'react' import React, { useCallback, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import * as PopoverPrimitive from '@radix-ui/react-popover' import * as PopoverPrimitive from '@radix-ui/react-popover'
import { import {
@ -19,7 +19,7 @@ import { ThemeChanger } from './ThemeChanger'
import SettingIcon from '../Settings/SettingIcon' import SettingIcon from '../Settings/SettingIcon'
import PromptInput from './PromptInput' import PromptInput from './PromptInput'
import CoffeeIcon from '../CoffeeIcon/CoffeeIcon' import CoffeeIcon from '../CoffeeIcon/CoffeeIcon'
import emitter, { EVENT_CUSTOM_MASK } from '../../event' import emitter, { EVENT_CUSTOM_MASK, RERUN_LAST_MASK } from '../../event'
import { useImage } from '../../utils' import { useImage } from '../../utils'
import useHotKey from '../../hooks/useHotkey' import useHotKey from '../../hooks/useHotkey'
@ -49,6 +49,21 @@ const Header = () => {
[showFileManager, enableFileManager, isInpainting] [showFileManager, enableFileManager, isInpainting]
) )
const handleRerunLastMask = useCallback(() => {
emitter.emit(RERUN_LAST_MASK)
}, [])
useHotKey(
'r',
() => {
if (!isInpainting) {
handleRerunLastMask()
}
},
{},
[isInpainting, handleRerunLastMask]
)
const renderHeader = () => { const renderHeader = () => {
return ( return (
<header> <header>
@ -57,7 +72,7 @@ const Header = () => {
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
gap: 8, gap: 4,
}} }}
> >
{enableFileManager ? ( {enableFileManager ? (
@ -136,41 +151,53 @@ const Header = () => {
</Button> </Button>
</label> </label>
<PopoverPrimitive.Root open={openMaskPopover}> {mask ? (
<PopoverPrimitive.Trigger <PopoverPrimitive.Root open={openMaskPopover}>
className="btn-primary side-panel-trigger" <PopoverPrimitive.Trigger
onMouseEnter={() => setOpenMaskPopover(true)} className="btn-primary side-panel-trigger"
onMouseLeave={() => setOpenMaskPopover(false)} onMouseEnter={() => setOpenMaskPopover(true)}
style={{ onMouseLeave={() => setOpenMaskPopover(false)}
visibility: mask ? 'visible' : 'hidden',
outline: 'none',
}}
onClick={() => {
if (mask) {
emitter.emit(EVENT_CUSTOM_MASK, { mask })
}
}}
>
<PlayIcon />
</PopoverPrimitive.Trigger>
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
style={{ style={{
visibility: mask ? 'visible' : 'hidden',
outline: 'none', outline: 'none',
}} }}
onClick={() => {
if (mask) {
emitter.emit(EVENT_CUSTOM_MASK, { mask })
}
}}
> >
{maskImageLoaded ? ( <PlayIcon />
<img </PopoverPrimitive.Trigger>
src={maskImage.src} <PopoverPrimitive.Portal>
alt="mask" <PopoverPrimitive.Content
className="mask-preview" style={{
/> outline: 'none',
) : ( }}
<></> >
)} {maskImageLoaded ? (
</PopoverPrimitive.Content> <img
</PopoverPrimitive.Portal> src={maskImage.src}
</PopoverPrimitive.Root> alt="mask"
className="mask-preview"
/>
) : (
<></>
)}
</PopoverPrimitive.Content>
</PopoverPrimitive.Portal>
</PopoverPrimitive.Root>
) : (
<></>
)}
<Button
icon={<ReloadIcon style={{ height: 16, width: 16 }} />}
style={{ border: 0, gap: 0 }}
disabled={isInpainting}
toolTip="Rerun last mask [r]"
onClick={handleRerunLastMask}
/>
</div> </div>
</div> </div>

View File

@ -64,6 +64,7 @@ export default function ShortcutsModal() {
</div> </div>
<div className="shortcut-options-column"> <div className="shortcut-options-column">
<ShortCut content="Rerun last mask" keys={['R']} />
<ShortCut content="Undo" keys={[CmdOrCtrl, 'Z']} /> <ShortCut content="Undo" keys={[CmdOrCtrl, 'Z']} />
<ShortCut content="Redo" keys={[CmdOrCtrl, 'Shift', 'Z']} /> <ShortCut content="Redo" keys={[CmdOrCtrl, 'Shift', 'Z']} />
<ShortCut content="Copy Result" keys={[CmdOrCtrl, 'C']} /> <ShortCut content="Copy Result" keys={[CmdOrCtrl, 'C']} />

View File

@ -12,6 +12,8 @@ export interface PaintByExampleEventData {
image: File image: File
} }
export const RERUN_LAST_MASK = 'rerun_last_mask'
const emitter = mitt() const emitter = mitt()
export default emitter export default emitter