diff --git a/gui/src/client/utils.ts b/gui/src/client/utils.ts index 10d81600..6944141c 100644 --- a/gui/src/client/utils.ts +++ b/gui/src/client/utils.ts @@ -1,7 +1,8 @@ +import { doesExist } from '@apextoaster/js-utils'; import { ChainPipeline, HighresParams, ModelParams, Txt2ImgParams, UpscaleParams } from './types.js'; export interface PipelineVariable { - parameter: 'prompt' | 'cfg' | 'seed' | 'steps'; + parameter: 'prompt' | 'cfg' | 'seed' | 'steps' | 'eta' | 'scheduler' | 'token'; input: string; values: Array; } diff --git a/gui/src/components/control/VariableControl.tsx b/gui/src/components/control/VariableControl.tsx index 91ce6a26..a4752691 100644 --- a/gui/src/components/control/VariableControl.tsx +++ b/gui/src/components/control/VariableControl.tsx @@ -1,5 +1,5 @@ import { doesExist, mustExist } from '@apextoaster/js-utils'; -import { Checkbox, FormControl, InputLabel, MenuItem, Select, Stack, TextField } from '@mui/material'; +import { Checkbox, FormControl, FormControlLabel, InputLabel, MenuItem, Select, Stack, TextField } from '@mui/material'; import * as React from 'react'; import { useContext } from 'react'; import { useStore } from 'zustand'; @@ -18,78 +18,96 @@ export function VariableControl(props: VariableControlProps) { const store = mustExist(useContext(StateContext)); const grid = useStore(store, props.selectGrid); - return - - Grid Mode - props.setGrid({ - enabled: grid.enabled === false, - })} /> - + const stack = [ - Columns - props.setGrid({ + columns: { + parameter: event.target.value as VariableKey, + input: '', + values: [], + }, + })} value={grid.columns.parameter}> + {...parameterList([grid.rows.parameter])} + + + props.setGrid({ columns: { - parameter: event.target.value as VariableKey, - input: '', - values: [], + parameter: grid.columns.parameter, + input: event.target.value, + values: rangeSplit(grid.columns.parameter, event.target.value), }, - })} value={grid.columns.parameter}> - Prompt - Seed - Steps - - - props.setGrid({ - columns: { - parameter: grid.columns.parameter, - input: event.target.value, - values: rangeSplit(grid.columns.parameter, event.target.value), - }, - })} /> - - - - Rows - props.setGrid({ + rows: { + parameter: event.target.value as VariableKey, + input: '', + values: [], + } + })} value={grid.rows.parameter}> + {...parameterList([grid.columns.parameter])} + + + props.setGrid({ rows: { - parameter: event.target.value as VariableKey, - input: '', - values: [], + parameter: grid.rows.parameter, + input: event.target.value, + values: rangeSplit(grid.rows.parameter, event.target.value), } - })} value={grid.rows.parameter}> - Prompt - Seed - Steps - - - props.setGrid({ - rows: { - parameter: grid.rows.parameter, - input: event.target.value, - values: rangeSplit(grid.rows.parameter, event.target.value), - } - })} /> - - ; + })} /> + + ); + } + + return {...stack}; } export function rangeSplit(parameter: string, value: string): Array { - // string values - if (parameter === 'prompt') { - return value.split('\n'); + const csv = value.split(',').map((it) => it.trim()); + + if (STRING_PARAMETERS.includes(parameter)) { + return csv; } - return value.split(',').map((it) => it.trim()).flatMap((it) => expandRanges(it)); + return csv.flatMap((it) => expandRanges(it)); } -export const EXPR_STRICT_NUMBER = /^[0-9]+$/; +export const EXPR_STRICT_NUMBER = /^-?[0-9]+$/; export const EXPR_NUMBER_RANGE = /^([0-9]+)-([0-9]+)$/; export function expandRanges(range: string): Array { if (EXPR_STRICT_NUMBER.test(range)) { // entirely numeric, return without parsing - return [parseInt(range, 10)]; + const val = parseInt(range, 10); + + // eslint-disable-next-line @typescript-eslint/no-magic-numbers + if (val === -1) { + return [newSeed()]; + } + + return [val]; } if (EXPR_NUMBER_RANGE.test(range)) { @@ -105,3 +123,27 @@ export function expandRanges(range: string): Array { return []; } + +export const MAX_SEED_SIZE = 32; +export const MAX_SEED = (2**MAX_SEED_SIZE) - 1; + +export function newSeed(): number { + return Math.floor(Math.random() * MAX_SEED); +} + +export const VARIABLE_PARAMETERS = ['prompt', 'negativePrompt', 'seed', 'steps', 'cfg', 'scheduler', 'eta', 'token']; +export const STRING_PARAMETERS = ['prompt', 'negativePrompt', 'scheduler', 'token']; + +export function parameterList(exclude?: Array) { + const items = []; + + for (const variable of VARIABLE_PARAMETERS) { + if (variable !== 'token' && doesExist(exclude) && exclude.includes(variable)) { + continue; + } + + items.push({variable}); + } + + return items; +}