From 75dde1dd759bafba0affe0dbe3393f2390a3f1d5 Mon Sep 17 00:00:00 2001 From: Sean Sube Date: Thu, 5 Jan 2023 01:14:27 -0600 Subject: [PATCH] add scheduler dropdown, wrap numeric input --- gui/src/api/client.ts | 30 ++++++++++++++--- gui/src/components/ImageControl.tsx | 51 +++++++++++++++-------------- gui/src/components/NumericField.tsx | 29 ++++++++++++++++ gui/src/components/Txt2Img.tsx | 22 +++++++++++-- 4 files changed, 100 insertions(+), 32 deletions(-) create mode 100644 gui/src/components/NumericField.tsx diff --git a/gui/src/api/client.ts b/gui/src/api/client.ts index 857aa4d1..5a07500e 100644 --- a/gui/src/api/client.ts +++ b/gui/src/api/client.ts @@ -4,8 +4,15 @@ export interface Txt2ImgParams { prompt: string; cfg: number; steps: number; - width: number; - height: number; + width?: number; + height?: number; + seed?: string; + scheduler?: string; +} + +export interface ApiResponse { + params: Txt2ImgParams; + path: string; } export interface ApiClient { @@ -34,8 +41,23 @@ export function makeClient(root: string, f = fetch): ApiClient { const url = new URL('/txt2img', root); url.searchParams.append('cfg', params.cfg.toFixed(0)); url.searchParams.append('steps', params.steps.toFixed(0)); - url.searchParams.append('width', params.width.toFixed(0)); - url.searchParams.append('height', params.height.toFixed(0)); + + if (doesExist(params.width)) { + url.searchParams.append('width', params.width.toFixed(0)); + } + + if (doesExist(params.height)) { + url.searchParams.append('height', params.height.toFixed(0)); + } + + if (doesExist(params.seed)) { + url.searchParams.append('seed', params.seed); + } + + if (doesExist(params.scheduler)) { + url.searchParams.append('scheduler', params.scheduler); + } + url.searchParams.append('prompt', params.prompt); pending = f(url).then((res) => { diff --git a/gui/src/components/ImageControl.tsx b/gui/src/components/ImageControl.tsx index a38b5c8f..e17a8d0e 100644 --- a/gui/src/components/ImageControl.tsx +++ b/gui/src/components/ImageControl.tsx @@ -1,6 +1,7 @@ import { doesExist } from '@apextoaster/js-utils'; -import { Container, Stack, TextField } from '@mui/material'; +import { Stack, TextField } from '@mui/material'; import * as React from 'react'; +import { NumericField } from './NumericField'; export interface ImageParams { cfg: number; @@ -19,64 +20,64 @@ export function ImageControl(props: ImageControlProps) { return - { + onChange={(cfg) => { if (doesExist(props.onChange)) { props.onChange({ ...params, - cfg: parseInt(event.target.value, 10), + cfg, }); } }} /> - { + onChange={(steps) => { if (doesExist(props.onChange)) { props.onChange({ ...params, - steps: parseInt(event.target.value, 10), + steps, }); } }} /> - { + onChange={(width) => { if (doesExist(props.onChange)) { props.onChange({ ...params, - width: parseInt(event.target.value, 10), + width, }); } }} /> - { + onChange={(height) => { if (doesExist(props.onChange)) { props.onChange({ ...params, - height: parseInt(event.target.value, 10), + height, }); } }} diff --git a/gui/src/components/NumericField.tsx b/gui/src/components/NumericField.tsx new file mode 100644 index 00000000..59af2f0d --- /dev/null +++ b/gui/src/components/NumericField.tsx @@ -0,0 +1,29 @@ +import { doesExist } from '@apextoaster/js-utils'; +import { TextField } from '@mui/material'; +import * as React from 'react'; + +export interface ImageControlProps { + label: string; + min: number; + max: number; + step: number; + value: number; + + onChange?: (value: number) => void; +} + +export function NumericField(props: ImageControlProps) { + const { label, min, max, step, value } = props; + return { + if (doesExist(props.onChange)) { + props.onChange(parseInt(event.target.value, 10)); + } + }} + />; +} diff --git a/gui/src/components/Txt2Img.tsx b/gui/src/components/Txt2Img.tsx index 1179f413..caea4a0b 100644 --- a/gui/src/components/Txt2Img.tsx +++ b/gui/src/components/Txt2Img.tsx @@ -1,4 +1,4 @@ -import { Box, Button, Stack, TextField } from '@mui/material'; +import { Box, Button, MenuItem, Select, Stack, TextField } from '@mui/material'; import * as React from 'react'; import { ApiClient } from '../api/client.js'; @@ -20,10 +20,11 @@ export function Txt2Img(props: Txt2ImgProps) { steps: 25, width: 512, height: 512, - }) + }); + const [scheduler, setScheduler] = useState('euler-a'); async function getImage() { - const image = await client.txt2img({ ...params, prompt }); + const image = await client.txt2img({ ...params, prompt, scheduler }); console.log(prompt, image); setImage(image); } @@ -41,6 +42,21 @@ export function Txt2Img(props: Txt2ImgProps) { txt2img mode + { setParams(params); }} />