diff --git a/resources/python/live-painting/main.py b/resources/python/live-painting/main.py index ae64493a0..1128ea356 100644 --- a/resources/python/live-painting/main.py +++ b/resources/python/live-painting/main.py @@ -149,9 +149,9 @@ def load_image_with_retry(file_path, max_retries=25, delay=0.003): return None -def calculate_min_inference_steps(strength): +def calculate_min_inference_steps(steps, strength): # Calculate the minimal number of inference steps - return math.ceil(1.0 / strength) + return math.ceil(steps / strength) def prepare_pipeline(model_path, vae_path, disable_stablefast=False): @@ -234,10 +234,11 @@ def warmup(pipe, input_image_path): def main(pipe, input_image_path, output_image_path, shutdown_event): # Initial/default values for parameters - prompt = "a person, incredible watercolor paining" + prompt = "a person, incredible watercolor painting, high quality" seed = 1 - strength = 0.99 - guidance_scale = None + strength = 0.95 + steps = 3 + guidance_scale = 1.5 # When was the input image last modified last_modified_time = None @@ -260,6 +261,8 @@ def main(pipe, input_image_path, output_image_path, shutdown_event): seed = parameters.get("seed", seed) strength = parameters.get("strength", strength) guidance_scale = parameters.get("guidance_scale", guidance_scale) + steps = parameters.get("steps", steps) + print(f"Updated parameters {parameters}") except queue.Empty: pass # No new parameters, proceed with the existing ones @@ -283,18 +286,18 @@ def main(pipe, input_image_path, output_image_path, shutdown_event): continue strength_ = float(strength) - # guidance_scale_ = float(guidance_scale) - # denoise_steps_ = calculate_min_inference_steps(strength_) + guidance_scale_ = float(guidance_scale) + denoise_steps_ = calculate_min_inference_steps(steps, strength_) image = pipe( prompt, image=init_image, height=512, width=512, - num_inference_steps=3, + num_inference_steps=denoise_steps_, num_images_per_prompt=1, strength=strength_, - guidance_scale=1.5, + guidance_scale=guidance_scale_, ).images[0] # Save file diff --git a/src/client/ions/swr/fetcher.ts b/src/client/ions/swr/fetcher.ts index 2711333be..ecfd0588c 100644 --- a/src/client/ions/swr/fetcher.ts +++ b/src/client/ions/swr/fetcher.ts @@ -1,3 +1,3 @@ export async function fetcher(key: string) { - return window.ipc.fetch(key); + console.log(key); } diff --git a/src/client/organisms/layout/index.tsx b/src/client/organisms/layout/index.tsx index 80e022223..6cd65084f 100644 --- a/src/client/organisms/layout/index.tsx +++ b/src/client/organisms/layout/index.tsx @@ -27,7 +27,7 @@ export function Layout({ children }: { children?: ReactNode }) { overflow: "hidden", display: "grid", gridTemplateColumns: { - xs: "36px 1fr", + xs: "44px 1fr", xl: "228px 1fr", }, gridTemplateRows: "36px 1fr", diff --git a/src/client/organisms/sidebar-button/index.tsx b/src/client/organisms/sidebar-button/index.tsx index c8e8980bd..829da861f 100644 --- a/src/client/organisms/sidebar-button/index.tsx +++ b/src/client/organisms/sidebar-button/index.tsx @@ -42,6 +42,9 @@ export function SidebarButton({ size="lg" component="a" color={isActive ? "primary" : "neutral"} + slotProps={{ + startDecorator: { sx: { "--Icon-margin": "0 0 0 -2px" } }, + }} sx={{ justifyContent: "flex-start", pl: 1.5, @@ -61,12 +64,18 @@ export function SidebarButton({ component={href ? "a" : "button"} href={href} target={target} + slotProps={{ + startDecorator: { sx: { "--Icon-margin": "0 0 0 -2px" } }, + }} sx={{ justifyContent: "flex-start", pl: 1.5, flex: 1, whiteSpace: "nowrap", overflow: "hidden", + ".JoyButton-startDecorator": { + "--Icon-margin": "0 0 0 -1px", + }, }} > {children} diff --git a/src/client/organisms/title-bar/index.tsx b/src/client/organisms/title-bar/index.tsx index 163c24c63..6cfe5e198 100644 --- a/src/client/organisms/title-bar/index.tsx +++ b/src/client/organisms/title-bar/index.tsx @@ -87,13 +87,19 @@ export function TitleBar({ disableMaximize = true }) { p: 1, display: "flex", alignItems: "center", + justifyContent: "center", + width: 44, + bgcolor: "primary.500", + "--Icon-color": "common.white", }} > - v{package_.version} + + v{package_.version} + diff --git a/src/client/pages/[locale]/dashboard.tsx b/src/client/pages/[locale]/dashboard.tsx index 5bba34671..79477b0c9 100644 --- a/src/client/pages/[locale]/dashboard.tsx +++ b/src/client/pages/[locale]/dashboard.tsx @@ -25,7 +25,7 @@ export default function Page(_properties: InferGetStaticPropsType diff --git a/src/client/pages/[locale]/live-painting.tsx b/src/client/pages/[locale]/live-painting.tsx index 6b937cfeb..8fa760842 100644 --- a/src/client/pages/[locale]/live-painting.tsx +++ b/src/client/pages/[locale]/live-painting.tsx @@ -1,8 +1,18 @@ +import { ClickAwayListener } from "@mui/base"; +import BrushIcon from "@mui/icons-material/Brush"; +import ClearIcon from "@mui/icons-material/Clear"; +import PaletteIcon from "@mui/icons-material/Palette"; +import PhotoFilterIcon from "@mui/icons-material/PhotoFilter"; +import PlayArrowIcon from "@mui/icons-material/PlayArrow"; +import StopIcon from "@mui/icons-material/Stop"; import Box from "@mui/joy/Box"; -import Button from "@mui/joy/Button"; +import IconButton from "@mui/joy/IconButton"; import Sheet from "@mui/joy/Sheet"; +import Slider from "@mui/joy/Slider"; import Stack from "@mui/joy/Stack"; +import SvgIcon from "@mui/joy/SvgIcon"; import ToggleButtonGroup from "@mui/joy/ToggleButtonGroup"; +import Tooltip from "@mui/joy/Tooltip"; import Typography from "@mui/joy/Typography"; import { atom, useAtom } from "jotai"; import type { InferGetStaticPropsType } from "next"; @@ -14,16 +24,22 @@ import { useEffect, useRef, useState } from "react"; import { buildKey } from "#/build-key"; import { ID } from "#/enums"; import { makeStaticProperties } from "@/ions/i18n/get-static"; - +import { getContrastColor } from "@/ions/utils/color"; export type ViewType = "side-by-side" | "overlay"; +const livePaintingOptionsAtom = atom({ + brushSize: 10, + color: "#20827c", +}); -const imageAtom = atom(""); +const clearCounterAtom = atom(0); -function DrawingArea() { +function DrawingArea({ isOverlay }: { isOverlay?: boolean }) { const canvas = useRef(null); const context = useRef(null); const isDrawing = useRef(false); - const [, setImage] = useAtom(imageAtom); + const [livePaintingOptions] = useAtom(livePaintingOptionsAtom); + const [clearCounter] = useAtom(clearCounterAtom); + const canvasContainerReference = useRef(null); function startDrawing(event: ReactPointerEvent) { if (!canvas.current) { @@ -43,20 +59,40 @@ function DrawingArea() { return; } - canvasElement.height = 512; - canvasElement.width = 512; + const dpr = window.devicePixelRatio || 1; + canvasElement.height = 512 * dpr; + canvasElement.width = 512 * dpr; context.current = canvasElement.getContext("2d"); + if (context.current) { + context.current.scale(dpr, dpr); + } function draw(event: MouseEvent) { - if (!isDrawing.current || !canvas.current) { + if (!canvas.current) { return; } const rect = canvas.current.getBoundingClientRect(); + if (canvasContainerReference.current) { + canvasContainerReference.current.style.setProperty( + "--brushX", + `${event.clientX - rect.left}px` + ); + canvasContainerReference.current.style.setProperty( + "--brushY", + `${event.clientY - rect.top}px` + ); + } + + if (!isDrawing.current) { + return; + } + + console.log("ing"); + context.current?.lineTo(event.clientX - rect.left, event.clientY - rect.top); context.current?.stroke(); const dataUrl = canvas.current.toDataURL(); - setImage(dataUrl); window.ipc.send(buildKey([ID.LIVE_PAINT], { suffix: ":dataUrl" }), dataUrl); } @@ -79,8 +115,7 @@ function DrawingArea() { context.current.fillStyle = "#ffffff"; context.current.rect(0, 0, canvasElement.width, canvasElement.height); context.current.fill(); - context.current.strokeStyle = "#000000"; - context.current.lineWidth = 5; + context.current.lineJoin = "round"; context.current.lineCap = "round"; @@ -93,17 +128,76 @@ function DrawingArea() { document.removeEventListener("mouseup", handleMouseUp); cancelAnimationFrame(animationFame); }; - }, [setImage]); + }, []); + + useEffect(() => { + if (context.current) { + context.current.strokeStyle = livePaintingOptions.color; + context.current.shadowColor = livePaintingOptions.color; + const shadowBlur = Math.min(livePaintingOptions.brushSize, 10); + context.current.lineWidth = livePaintingOptions.brushSize - shadowBlur; + context.current.shadowBlur = shadowBlur / 2; + if (canvasContainerReference.current) { + canvasContainerReference.current.style.setProperty( + "--brushSize", + `${livePaintingOptions.brushSize}px` + ); + canvasContainerReference.current.style.setProperty( + "--brushColor", + livePaintingOptions.color + ); + } + } + }, [livePaintingOptions]); + + useEffect(() => { + if (context.current && canvas.current) { + context.current.fillStyle = "#ffffff"; + context.current.clearRect(0, 0, canvas.current.width, canvas.current.height); + context.current.fillRect(0, 0, canvas.current.width, canvas.current.height); + const dataUrl = canvas.current.toDataURL(); + window.ipc.send(buildKey([ID.LIVE_PAINT], { suffix: ":dataUrl" }), dataUrl); + } + }, [clearCounter]); return ( - - + + + ); } function RenderingArea() { - const [image, setImage] = useState(""); + const [image, setImage] = useState( + "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR4nGP4//8/AAX+Av4N70a4AAAAAElFTkSuQmCC" + ); useEffect(() => { const unsubscribe = window.ipc.on( @@ -124,46 +218,184 @@ function RenderingArea() { ); } +export function ImageEditIcon() { + return ( + + + + ); +} + +export function OverlayEditIcon() { + return ( + + + + ); +} + export function LivePainting() { + const { t } = useTranslation(["common", "labels"]); const [value, setValue] = useState("side-by-side"); + const [livePaintingOptions, setLivePaintingOptions] = useAtom(livePaintingOptionsAtom); + const [, setClearCounter] = useAtom(clearCounterAtom); + const [brushSizeOpen, setBrushSizeOpen] = useState(false); + const isOverlay = value === "overlay"; + return ( - + { if (newValue) { setValue(newValue); } }} > - - + + + + + + + + + + + + + + + { + setLivePaintingOptions(previousState => ({ + ...previousState, + color: event.target.value, + })); + }} + /> + + + + { + setBrushSizeOpen(false); + }} + > + { + setBrushSizeOpen(false); + }} + > + { + setLivePaintingOptions(previousState => ({ + ...previousState, + brushSize: value as number, + })); + }} + /> + + + } + > + + { + setBrushSizeOpen(true); + }} + > + + + + + + + { + setClearCounter(previousState => previousState + 1); + }} + > + + + - + - + ) { const { t } = useTranslation(["common", "labels"]); + const [running, setRunning] = useState(false); + + useEffect(() => { + const unsubscribeStarted = window.ipc.on( + buildKey([ID.LIVE_PAINT], { suffix: ":started" }), + () => { + setRunning(true); + } + ); + + const unsubscribeStopped = window.ipc.on( + buildKey([ID.LIVE_PAINT], { suffix: ":stopped" }), + () => { + setRunning(false); + } + ); + + return () => { + unsubscribeStarted(); + unsubscribeStopped(); + }; + }, []); + return ( <> @@ -193,7 +448,7 @@ export default function Page(_properties: InferGetStaticPropsType @@ -202,21 +457,28 @@ export default function Page(_properties: InferGetStaticPropsType - - + + { + if (running) { + window.ipc.send( + buildKey([ID.LIVE_PAINT], { suffix: ":stop" }) + ); + } else { + window.ipc.send( + buildKey([ID.LIVE_PAINT], { suffix: ":start" }) + ); + } + }} + > + {running ? : } + + diff --git a/src/client/preload.d.ts b/src/client/preload.d.ts index 05ad7c85c..d7ab78533 100644 --- a/src/client/preload.d.ts +++ b/src/client/preload.d.ts @@ -1,7 +1,7 @@ -import { IpcHandler } from "../main/preload"; +import { IpcHandler } from "../electron/preload"; declare global { - interface Window { - ipc: IpcHandler; - } + interface Window { + ipc: IpcHandler; + } } diff --git a/src/client/public/locales/de/labels.json b/src/client/public/locales/de/labels.json index 9cd71b33b..462c4c685 100644 --- a/src/client/public/locales/de/labels.json +++ b/src/client/public/locales/de/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Barrierefreiheit", "back": "Zurück", + "brushSize": "Pinselgröße", + "clear": "Löschen", "close": "Schließen", + "color": "Farbe", "dashboard": "Dashboard", "downloading": "Herunterladen", "livePainting": "Live-Malerei", "maximize": "Maximieren", "minimize": "Minimieren", + "overlay": "Überlagerung", "privacy": "Datenschutz", "security": "Sicherheit", + "sideBySide": "Nebeneinander", + "start": "Start", + "stop": "Stopp", "unpacking": "Entpacken" } diff --git a/src/client/public/locales/en/labels.json b/src/client/public/locales/en/labels.json index 256a700a7..20ef2bc54 100644 --- a/src/client/public/locales/en/labels.json +++ b/src/client/public/locales/en/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Accessibility", "back": "Back", + "brushSize": "Brush Size", + "clear": "Clear", "close": "Close", + "color": "Color", "dashboard": "Dashboard", "downloading": "Downloading", "livePainting": "Live Painting", "maximize": "Maximize", "minimize": "Minimize", + "overlay": "Overlay", "privacy": "Privacy", "security": "Security", + "sideBySide": "Side by Side", + "start": "Start", + "stop": "Stop", "unpacking": "Unpacking" } diff --git a/src/client/public/locales/es/labels.json b/src/client/public/locales/es/labels.json index 9eb82c2e4..bbb2065b7 100644 --- a/src/client/public/locales/es/labels.json +++ b/src/client/public/locales/es/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Accesibilidad", "back": "Atrás", + "brushSize": "Tamaño Pincel", + "clear": "Limpiar", "close": "Cerrar", + "color": "Color", "dashboard": "Tablero", "downloading": "Descargando", "livePainting": "Pintura en Vivo", "maximize": "Maximizar", "minimize": "Minimizar", + "overlay": "Superposición", "privacy": "Privacidad", "security": "Seguridad", + "sideBySide": "Lado a Lado", + "start": "Iniciar", + "stop": "Detener", "unpacking": "Desempaquetando" } diff --git a/src/client/public/locales/fr/labels.json b/src/client/public/locales/fr/labels.json index 4b4d0dc65..e3520757d 100644 --- a/src/client/public/locales/fr/labels.json +++ b/src/client/public/locales/fr/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Accessibilité", "back": "Retour", + "brushSize": "Taille Pinceau", + "clear": "Effacer", "close": "Fermer", + "color": "Couleur", "dashboard": "Tableau de bord", "downloading": "Téléchargement", "livePainting": "Peinture en Direct", "maximize": "Maximiser", "minimize": "Minimiser", + "overlay": "Superposition", "privacy": "Confidentialité", "security": "Sécurité", + "sideBySide": "Côte à Côte", + "start": "Démarrer", + "stop": "Arrêter", "unpacking": "Déballage" } diff --git a/src/client/public/locales/he/labels.json b/src/client/public/locales/he/labels.json index 13f3df05b..f6749fc36 100644 --- a/src/client/public/locales/he/labels.json +++ b/src/client/public/locales/he/labels.json @@ -1,13 +1,20 @@ { "accessibility": "נגישות", "back": "חזרה", + "brushSize": "גודל מברשת", + "clear": "נקה", "close": "סגור", + "color": "צבע", "dashboard": "לוח בקרה", "downloading": "מוריד", "livePainting": "ציור חי", "maximize": "הגדל", "minimize": "מזער", + "overlay": "שכבה", "privacy": "פרטיות", "security": "ביטחון", + "sideBySide": "צד לצד", + "start": "התחל", + "stop": "עצור", "unpacking": "פותח" } diff --git a/src/client/public/locales/it/labels.json b/src/client/public/locales/it/labels.json index 1fc03f8bb..abc94ffe5 100644 --- a/src/client/public/locales/it/labels.json +++ b/src/client/public/locales/it/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Accessibilità", "back": "Indietro", + "brushSize": "Dimensione Pennello", + "clear": "Cancella", "close": "Chiudi", + "color": "Colore", "dashboard": "Cruscotto", "downloading": "Scaricamento", "livePainting": "Pittura Dal Vivo", "maximize": "Massimizza", "minimize": "Minimizza", + "overlay": "Sovrapposizione", "privacy": "Privacy", "security": "Sicurezza", + "sideBySide": "Fianco a Fianco", + "start": "Avvia", + "stop": "Ferma", "unpacking": "Estrazione" } diff --git a/src/client/public/locales/ja/labels.json b/src/client/public/locales/ja/labels.json index 2e057b922..b549434ff 100644 --- a/src/client/public/locales/ja/labels.json +++ b/src/client/public/locales/ja/labels.json @@ -1,13 +1,20 @@ { "accessibility": "アクセシビリティ", "back": "戻る", + "brushSize": "ブラシサイズ", + "clear": "クリア", "close": "閉じる", + "color": "色", "dashboard": "ダッシュボード", "downloading": "ダウンロード中", "livePainting": "ライブペインティング", "maximize": "最大化", "minimize": "最小化", + "overlay": "オーバーレイ", "privacy": "プライバシー", "security": "セキュリティ", + "sideBySide": "並列", + "start": "開始", + "stop": "停止", "unpacking": "解凍中" } diff --git a/src/client/public/locales/nl/labels.json b/src/client/public/locales/nl/labels.json index 1d0f78c82..bb077231b 100644 --- a/src/client/public/locales/nl/labels.json +++ b/src/client/public/locales/nl/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Toegankelijkheid", "back": "Terug", + "brushSize": "Penseelgrootte", + "clear": "Wissen", "close": "Sluiten", + "color": "Kleur", "dashboard": "Dashboard", "downloading": "Downloaden", "livePainting": "Live Schilderen", "maximize": "Maximaliseren", "minimize": "Minimaliseren", + "overlay": "Overlay", "privacy": "Privacy", "security": "Beveiliging", + "sideBySide": "Zij aan Zij", + "start": "Start", + "stop": "Stop", "unpacking": "Uitpakken" } diff --git a/src/client/public/locales/pl/labels.json b/src/client/public/locales/pl/labels.json index 46427bf5b..75bf3022b 100644 --- a/src/client/public/locales/pl/labels.json +++ b/src/client/public/locales/pl/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Dostępność", "back": "Wstecz", + "brushSize": "Rozmiar Pędzla", + "clear": "Wyczyść", "close": "Zamknij", + "color": "Kolor", "dashboard": "Pulpit", "downloading": "Pobieranie", "livePainting": "Malowanie na Żywo", "maximize": "Zmaksymalizuj", "minimize": "Zminimalizuj", + "overlay": "Nakładka", "privacy": "Prywatność", "security": "Bezpieczeństwo", + "sideBySide": "Obok Siebie", + "start": "Start", + "stop": "Stop", "unpacking": "Rozpakowywanie" } diff --git a/src/client/public/locales/pt/labels.json b/src/client/public/locales/pt/labels.json index 2b01b86fd..370e3a490 100644 --- a/src/client/public/locales/pt/labels.json +++ b/src/client/public/locales/pt/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Acessibilidade", "back": "Voltar", + "brushSize": "Tamanho Pincel", + "clear": "Limpar", "close": "Fechar", + "color": "Cor", "dashboard": "Painel de Controle", "downloading": "Baixando", "livePainting": "Pintura ao Vivo", "maximize": "Maximizar", "minimize": "Minimizar", + "overlay": "Sobreposição", "privacy": "Privacidade", "security": "Segurança", + "sideBySide": "Lado a Lado", + "start": "Iniciar", + "stop": "Parar", "unpacking": "Desembalando" } diff --git a/src/client/public/locales/ru/labels.json b/src/client/public/locales/ru/labels.json index 3a5354bd7..d0d506f3b 100644 --- a/src/client/public/locales/ru/labels.json +++ b/src/client/public/locales/ru/labels.json @@ -1,13 +1,20 @@ { "accessibility": "Доступность", "back": "Назад", + "brushSize": "Размер Кисти", + "clear": "Очистить", "close": "Закрыть", + "color": "Цвет", "dashboard": "Панель управления", "downloading": "Загрузка", "livePainting": "Живая Живопись", "maximize": "Развернуть", "minimize": "Свернуть", + "overlay": "Наложение", "privacy": "Конфиденциальность", "security": "Безопасность", + "sideBySide": "Бок о Бок", + "start": "Старт", + "stop": "Стоп", "unpacking": "Распаковка" } diff --git a/src/client/public/locales/zh/labels.json b/src/client/public/locales/zh/labels.json index c8d75a16a..be822beb0 100644 --- a/src/client/public/locales/zh/labels.json +++ b/src/client/public/locales/zh/labels.json @@ -1,13 +1,20 @@ { "accessibility": "可访问性", "back": "返回", + "brushSize": "笔刷大小", + "clear": "清除", "close": "关闭", + "color": "颜色", "dashboard": "仪表板", "downloading": "下载中", "livePainting": "实时绘画", "maximize": "最大化", "minimize": "最小化", + "overlay": "叠加", "privacy": "隐私", "security": "安全", + "sideBySide": "并排", + "start": "开始", + "stop": "停止", "unpacking": "解压中" } diff --git a/src/electron/future/ipc/listeners.ts b/src/electron/future/ipc/listeners.ts index d96a765aa..c2f4ecd32 100644 --- a/src/electron/future/ipc/listeners.ts +++ b/src/electron/future/ipc/listeners.ts @@ -90,7 +90,7 @@ ipcMain.on(buildKey([ID.USER], { suffix: ":language" }), (_event, language) => { userStore.set("language", language); }); -let process: ExecaChildProcess | undefined; +let process_: ExecaChildProcess | undefined; let cache = ""; ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":dataUrl" }), async (_event, dataUrl) => { @@ -107,7 +107,7 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { return; } - if (!process) { + if (!process_) { const pythonBinaryPath = getCaptainData("python-embedded/python.exe"); const scriptPath = getDirectory("python/live-painting/main.py"); const scriptArguments = [ @@ -123,10 +123,10 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { "--debug", ]; - process = execa(pythonBinaryPath, ["-u", scriptPath, ...scriptArguments]); + process_ = execa(pythonBinaryPath, ["-u", scriptPath, ...scriptArguments]); - if (process.stdout && process.stderr) { - process.stdout.on("data", async data => { + if (process_.stdout && process_.stderr) { + process_.stdout.on("data", async data => { const dataString = data.toString(); try { @@ -134,14 +134,14 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { console.log(`live-painting: ${JSON.stringify(jsonData)}`); - if (process && jsonData.status === "starting") { + if (process_ && jsonData.status === "starting") { window_.webContents.send( buildKey([ID.LIVE_PAINT], { suffix: ":starting" }), true ); } - if (process && jsonData.status === "started") { + if (process_ && jsonData.status === "started") { window_.webContents.send( buildKey([ID.LIVE_PAINT], { suffix: ":started" }), true @@ -149,24 +149,24 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { } if ( - process && + process_ && (jsonData.status === "shutdown" || jsonData.status === "stopped") ) { - if (process) { - if (process.stdout) { - process.stdout.removeAllListeners("data"); + if (process_) { + if (process_.stdout) { + process_.stdout.removeAllListeners("data"); } - if (process.stderr) { - process.stderr.removeAllListeners("data"); + if (process_.stderr) { + process_.stderr.removeAllListeners("data"); } - if (process && !process.killed) { - process.kill(); + if (process_ && !process_.killed) { + process_.kill(); } } - process = undefined; + process_ = undefined; window_.webContents.send( buildKey([ID.LIVE_PAINT], { suffix: ":stopped" }), @@ -200,7 +200,7 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { } }); - process.stderr.on("data", data => { + process_.stderr.on("data", data => { console.error(`error: ${data}`); window_.webContents.send(buildKey([ID.LIVE_PAINT], { suffix: ":error" }), data); @@ -210,7 +210,13 @@ ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":start" }), () => { }); ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":stop" }), () => { - if (process && process.stdin) { - process.stdin.write(JSON.stringify({ command: "shutdown" }) + "\n"); + if (process_ && process_.stdin) { + process_.stdin.write(JSON.stringify({ command: "shutdown" }) + "\n"); + } +}); + +ipcMain.on(buildKey([ID.LIVE_PAINT], { suffix: ":settings" }), (_event, data) => { + if (process_ && process_.stdin) { + process_.stdin.write(JSON.stringify(data) + "\n"); } });