refactoring the main tab
parent
b7376a61f1
commit
715e2ce6fe
5
enum.js
5
enum.js
|
|
@ -37,10 +37,6 @@ const BackgroundHistoryEnum = {
|
|||
NoBackground: 'no_background',
|
||||
}
|
||||
|
||||
const PresetTypeEnum = {
|
||||
SDPreset: 'sd_preset',
|
||||
ControlNetPreset: 'controlnet_preset',
|
||||
}
|
||||
module.exports = {
|
||||
clickTypeEnum,
|
||||
generationModeEnum,
|
||||
|
|
@ -49,5 +45,4 @@ module.exports = {
|
|||
RequestStateEnum,
|
||||
|
||||
BackgroundHistoryEnum,
|
||||
PresetTypeEnum,
|
||||
}
|
||||
|
|
|
|||
1759
index.html
1759
index.html
File diff suppressed because it is too large
Load Diff
148
psapi.js
148
psapi.js
|
|
@ -787,147 +787,6 @@ function layerNameToFileName(layer_name, layer_id, session_id) {
|
|||
return file_name
|
||||
}
|
||||
|
||||
async function silentSetInitImage(layer, session_id) {
|
||||
try {
|
||||
const html_manip = require('./utility/html_manip')
|
||||
const io = require('./utility/io')
|
||||
// const layer = await app.activeDocument.activeLayers[0]
|
||||
const old_name = layer.name
|
||||
|
||||
// image_name = await app.activeDocument.activeLayers[0].name
|
||||
|
||||
//convert layer name to a file name
|
||||
let image_name = layerNameToFileName(old_name, layer.id, session_id)
|
||||
image_name = `${image_name}.png`
|
||||
|
||||
//the width and height of the exported image
|
||||
const width = html_manip.getWidth()
|
||||
const height = html_manip.getHeight()
|
||||
|
||||
//get the selection from the canvas as base64 png, make sure to resize to the width and height slider
|
||||
const selectionInfo = g_generation_session.selectionInfo
|
||||
// const base64_image = await io.IO.getSelectionFromCanvasAsBase64Silent(
|
||||
// selectionInfo,
|
||||
// true,
|
||||
// width,
|
||||
// height
|
||||
// )
|
||||
|
||||
const use_silent_mode = html_manip.getUseSilentMode()
|
||||
// if (use_silent_mode) {
|
||||
// base64_image = await io.IO.getSelectionFromCanvasAsBase64Silent(
|
||||
// selectionInfo,
|
||||
// true,
|
||||
// width,
|
||||
// height
|
||||
// )
|
||||
// } else {
|
||||
// base64_image = await io.IO.getSelectionFromCanvasAsBase64NonSilent(
|
||||
// layer,
|
||||
|
||||
// image_name,
|
||||
// width,
|
||||
// height
|
||||
// )
|
||||
// }
|
||||
const base64_image =
|
||||
await io.IO.getSelectionFromCanvasAsBase64Interface(
|
||||
width,
|
||||
height,
|
||||
layer,
|
||||
selectionInfo,
|
||||
true,
|
||||
use_silent_mode,
|
||||
image_name
|
||||
)
|
||||
//save base64 as file in the init_images directory
|
||||
const init_entry = await getInitImagesDir()
|
||||
await io.IO.base64PngToPngFile(base64_image, init_entry, image_name)
|
||||
|
||||
g_init_image_name = image_name
|
||||
console.log(image_name)
|
||||
|
||||
const path = `${g_init_images_dir}/${image_name}`
|
||||
|
||||
//store the base64 init image and also set it as the active/latest init image
|
||||
g_generation_session.base64initImages[path] = base64_image
|
||||
g_generation_session.activeBase64InitImage = base64_image
|
||||
|
||||
const init_src = base64ToSrc(g_generation_session.activeBase64InitImage)
|
||||
html_manip.setInitImageSrc(init_src)
|
||||
|
||||
return (image_info = { name: image_name, base64: base64_image })
|
||||
} catch (e) {
|
||||
console.error(`psapi.js silentSetInitImage error:, ${e}`)
|
||||
}
|
||||
}
|
||||
async function silentSetInitImageMask(layer, session_id) {
|
||||
try {
|
||||
const html_manip = require('./utility/html_manip')
|
||||
|
||||
// const layer = await app.activeDocument.activeLayers[0]
|
||||
const old_name = layer.name
|
||||
|
||||
image_name = layerNameToFileName(old_name, layer.id, session_id)
|
||||
image_name = `${image_name}.png`
|
||||
const width = html_manip.getWidth()
|
||||
const height = html_manip.getHeight()
|
||||
|
||||
//get the selection from the canvas as base64 png, make sure to resize to the width and height slider
|
||||
const selectionInfo = g_generation_session.selectionInfo
|
||||
|
||||
const use_silent_mode = html_manip.getUseSilentMode()
|
||||
|
||||
const base64_image =
|
||||
await io.IO.getSelectionFromCanvasAsBase64Interface(
|
||||
width,
|
||||
height,
|
||||
layer,
|
||||
selectionInfo,
|
||||
true,
|
||||
use_silent_mode,
|
||||
image_name
|
||||
)
|
||||
|
||||
//save base64 as file in the init_images directory
|
||||
const init_entry = await getInitImagesDir()
|
||||
await io.IO.base64PngToPngFile(base64_image, init_entry, image_name)
|
||||
|
||||
g_init_image_mask_name = image_name // this is the name we will send to the server
|
||||
|
||||
console.log(image_name)
|
||||
|
||||
const path = `${g_init_images_dir}/${image_name}`
|
||||
g_generation_session.base64maskImage[path] = base64_image
|
||||
g_generation_session.activeBase64MaskImage = base64_image
|
||||
|
||||
const mask_src = base64ToSrc(g_generation_session.activeBase64MaskImage)
|
||||
html_manip.setInitImageMaskSrc(mask_src)
|
||||
return (image_info = { name: image_name, base64: base64_image })
|
||||
} catch (e) {
|
||||
console.error(`psapi.js setInitImageMask error: `, e)
|
||||
}
|
||||
}
|
||||
|
||||
// remove the generated mask related layers from the canvas and "layers" panel
|
||||
|
||||
// async function cleanSnapAndFill(layers){
|
||||
// // we can delete this function and use cleanLayers() instead
|
||||
// //delete init image group
|
||||
// //delete init image (snapshot layer)
|
||||
// //delete fill layer
|
||||
|
||||
// for (layer of layers){
|
||||
// try{
|
||||
|
||||
// await executeAsModal(async ()=>{await layer.delete()})
|
||||
// }catch(e){
|
||||
// console.warn("cleanSnapAndFill, issue deleting a layer",e)
|
||||
// }
|
||||
// }
|
||||
// return []
|
||||
// }
|
||||
|
||||
async function cleanLayers(layers) {
|
||||
// g_init_image_related_layers = {}
|
||||
// g_mask_related_layers = {}
|
||||
|
|
@ -1488,9 +1347,7 @@ module.exports = {
|
|||
|
||||
layerToFileName,
|
||||
layerNameToFileName,
|
||||
// cleanLayersOutpaint,
|
||||
// cleanLayersInpaint,
|
||||
// cleanSnapAndFill,
|
||||
|
||||
cleanLayers,
|
||||
createClippingMaskExe,
|
||||
checkIfSelectionAreaIsActive,
|
||||
|
|
@ -1505,8 +1362,7 @@ module.exports = {
|
|||
isSelectionValid,
|
||||
snapshot_layer_no_slide_Exe,
|
||||
setVisibleExe,
|
||||
silentSetInitImage,
|
||||
silentSetInitImageMask,
|
||||
|
||||
executeCommandExe,
|
||||
executeDescExe,
|
||||
getSelectionInfoCommand,
|
||||
|
|
|
|||
113
sdapi_py_re.js
113
sdapi_py_re.js
|
|
@ -1,6 +1,6 @@
|
|||
const { getDummyBase64, getDummyBase64_2 } = require('./utility/dummy')
|
||||
const { base64ToBase64Url } = require('./utility/general')
|
||||
const { getExtensionType } = require('./utility/html_manip')
|
||||
|
||||
const py_re = require('./utility/sdapi/python_replacement')
|
||||
const Enum = require('./enum')
|
||||
const { control_net } = require('./typescripts/dist/bundle')
|
||||
|
|
@ -72,60 +72,6 @@ async function requestProgress() {
|
|||
return null
|
||||
}
|
||||
|
||||
async function requestGetModels() {
|
||||
console.log('requestGetModels: ')
|
||||
let json = []
|
||||
const full_url = `${g_sd_url}/sdapi/v1/sd-models`
|
||||
try {
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
console.log('models json:')
|
||||
console.dir(json)
|
||||
} catch (e) {
|
||||
console.warn(`issues requesting from ${full_url}`, e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
async function requestGetSamplers() {
|
||||
let json = null
|
||||
try {
|
||||
console.log('requestGetSamplers: ')
|
||||
|
||||
const full_url = `${g_sd_url}/sdapi/v1/samplers`
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
// console.log('samplers json:', json)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
async function requestSwapModel(model_title) {
|
||||
console.log('requestSwapModel: ')
|
||||
|
||||
const full_url = `${g_sd_url}/sdapi/v1/options`
|
||||
payload = {
|
||||
sd_model_checkpoint: model_title,
|
||||
}
|
||||
let request = await fetch(full_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
|
||||
let json = await request.json()
|
||||
|
||||
console.log('models json:')
|
||||
console.dir(json)
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
async function requestInterrupt() {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/interrupt`
|
||||
try {
|
||||
|
|
@ -151,13 +97,6 @@ async function requestInterrupt() {
|
|||
}
|
||||
}
|
||||
|
||||
async function getVersionRequest() {
|
||||
console.log('requestGetSamplers: ')
|
||||
const current_version = g_version
|
||||
|
||||
return current_version
|
||||
}
|
||||
|
||||
async function changeSdUrl(new_sd_url) {
|
||||
// version = "v0.0.0"
|
||||
console.log('changeSdUrl: new_sd_url:', new_sd_url)
|
||||
|
|
@ -229,24 +168,6 @@ async function savePromptShortcut(prompt_shortcut) {
|
|||
|
||||
return json['prompt_shortcut']
|
||||
}
|
||||
async function setInpaintMaskWeight(value) {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/options`
|
||||
try {
|
||||
const payload = {
|
||||
inpainting_mask_weight: value,
|
||||
}
|
||||
await fetch(full_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async function requestGetConfig() {
|
||||
console.log('requestGetConfig: ')
|
||||
|
|
@ -439,21 +360,6 @@ async function requestExtraSingleImage(payload) {
|
|||
}
|
||||
}
|
||||
|
||||
async function requestGetUpscalers() {
|
||||
console.log('requestGetUpscalers: ')
|
||||
let json = []
|
||||
const full_url = `${g_sd_url}/sdapi/v1/upscalers`
|
||||
try {
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
console.log('upscalers json:')
|
||||
console.dir(json)
|
||||
} catch (e) {
|
||||
console.warn(`issues requesting from ${full_url}`, e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
//REFACTOR: reuse the same code for (requestControlNetTxt2Img,requestControlNetImg2Img)
|
||||
async function requestControlNetTxt2Img(plugin_settings) {
|
||||
console.log('requestControlNetTxt2Img: ')
|
||||
|
|
@ -649,26 +555,20 @@ async function isWebuiRunning() {
|
|||
}
|
||||
return true
|
||||
}
|
||||
async function requestLoraModels() {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/loras`
|
||||
const lora_models = (await api.requestGet(full_url)) ?? []
|
||||
return lora_models
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
requestTxt2Img,
|
||||
requestImg2Img,
|
||||
|
||||
requestProgress,
|
||||
requestGetModels,
|
||||
requestSwapModel,
|
||||
|
||||
requestInterrupt,
|
||||
requestGetSamplers,
|
||||
getVersionRequest,
|
||||
|
||||
changeSdUrl,
|
||||
loadPromptShortcut,
|
||||
savePromptShortcut,
|
||||
loadHistory,
|
||||
setInpaintMaskWeight,
|
||||
|
||||
requestGetConfig,
|
||||
requestGetOptions,
|
||||
imageSearch,
|
||||
|
|
@ -677,9 +577,8 @@ module.exports = {
|
|||
// requestHordeCheck,
|
||||
// requestHordeStatus,
|
||||
requestExtraSingleImage,
|
||||
requestGetUpscalers,
|
||||
|
||||
requestControlNetTxt2Img,
|
||||
requestControlNetImg2Img,
|
||||
isWebuiRunning,
|
||||
requestLoraModels,
|
||||
}
|
||||
|
|
|
|||
26
selection.js
26
selection.js
|
|
@ -767,25 +767,16 @@ class Selection {
|
|||
static reselectArea(selection_info) {}
|
||||
static isSameSelection(selection_info_1, selection_info_2) {}
|
||||
static async getImageToSelectionDifference() {
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
// const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
// const width = html_manip.getWidth()
|
||||
// const height = html_manip.getHeight()
|
||||
|
||||
const width = html_manip.getWidth()
|
||||
const height = html_manip.getHeight()
|
||||
const scale_info_str = `${parseInt(width)}x${parseInt(
|
||||
height
|
||||
)} => ${parseInt(selectionInfo.width)}x${parseInt(
|
||||
selectionInfo.height
|
||||
)} `
|
||||
const selectionInfo = session_store.data.current_selection_info
|
||||
const width = sd_tab_store.data.width
|
||||
const height = sd_tab_store.data.height
|
||||
let ratio =
|
||||
(width * height) / (selectionInfo.width * selectionInfo.height)
|
||||
|
||||
// const arrow = percentage >= 1 ? '↑' : '↓'
|
||||
// percentage = percentage >= 1 ? percentage : 1 / percentage
|
||||
|
||||
// const percentage_str = `${arrow}X${percentage.toFixed(2)}`
|
||||
|
||||
// console.log('scale_info_str: ', scale_info_str)
|
||||
// console.log('percentage_str: ', percentage_str)
|
||||
return ratio
|
||||
}
|
||||
static {}
|
||||
|
|
@ -1018,7 +1009,8 @@ async function black_white_layer_to_mask(mask_id, target_layer_id, mask_name) {
|
|||
async function black_white_layer_to_mask_multi_batchplay(
|
||||
mask_id,
|
||||
target_layer_id,
|
||||
mask_name
|
||||
mask_name,
|
||||
expand_by = 10
|
||||
) {
|
||||
let result
|
||||
let psAction = require('photoshop').action
|
||||
|
|
@ -1063,7 +1055,7 @@ async function black_white_layer_to_mask_multi_batchplay(
|
|||
_obj: 'expand',
|
||||
by: {
|
||||
_unit: 'pixelsUnit',
|
||||
_value: 10,
|
||||
_value: expand_by,
|
||||
},
|
||||
selectionModifyEffectAtCanvasBounds: true,
|
||||
_isCommand: true,
|
||||
|
|
|
|||
|
|
@ -10,24 +10,20 @@ import {
|
|||
SpMenu,
|
||||
SpSliderWithLabel,
|
||||
} from '../util/elements'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
// import * as sdapi from '../../sdapi_py_re'
|
||||
import { api } from '../util/oldSystem'
|
||||
import { AStore } from '../main/astore'
|
||||
import { ui_config, model_list } from './config'
|
||||
const { requestGet } = api
|
||||
import { requestControlNetModelList } from '../controlnet/entry'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import { ScriptMode } from '../util/ts/enum'
|
||||
|
||||
import './style/after_detailer.css'
|
||||
|
||||
declare let g_sd_url: string
|
||||
|
||||
export enum ScriptMode {
|
||||
Txt2Img = 'txt2img',
|
||||
Img2Img = 'img2img',
|
||||
Inpaint = 'inpaint',
|
||||
Outpaint = 'outpaint',
|
||||
}
|
||||
|
||||
export let script_mode = [
|
||||
ScriptMode.Img2Img,
|
||||
ScriptMode.Inpaint,
|
||||
|
|
@ -263,77 +259,6 @@ export class AfterDetailerComponent extends React.Component<{
|
|||
const domNode = document.getElementById('alwaysOnScriptsContainer')!
|
||||
const root = ReactDOM.createRoot(domNode)
|
||||
|
||||
import { useState, ReactNode } from 'react'
|
||||
import Locale from '../locale/locale'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
|
||||
interface CollapsibleProps {
|
||||
label: string
|
||||
labelStyle?: React.CSSProperties
|
||||
containerStyle?: React.CSSProperties
|
||||
defaultIsOpen?: boolean
|
||||
checked?: boolean
|
||||
checkboxCallback?: (checked: boolean) => void
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
function Collapsible({
|
||||
label,
|
||||
labelStyle,
|
||||
containerStyle,
|
||||
defaultIsOpen = false,
|
||||
checkboxCallback,
|
||||
checked,
|
||||
children,
|
||||
}: CollapsibleProps) {
|
||||
const [isOpen, setIsOpen] = useState(defaultIsOpen)
|
||||
|
||||
const handleToggle = () => {
|
||||
setIsOpen(!isOpen)
|
||||
}
|
||||
|
||||
return (
|
||||
/*useObserver(()=>*/ <div>
|
||||
<div
|
||||
className="collapsible"
|
||||
style={containerStyle}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
<span className="truncate" style={labelStyle}>
|
||||
{label}
|
||||
</span>
|
||||
|
||||
<span
|
||||
style={{ float: 'right', display: 'flex' }}
|
||||
className="triangle"
|
||||
>
|
||||
{checkboxCallback && checked !== void 0 ? (
|
||||
<input
|
||||
type="checkbox"
|
||||
className="minimal-checkbox"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
}}
|
||||
onChange={(event: any) => {
|
||||
checkboxCallback(event.target.checked)
|
||||
}}
|
||||
checked={checked}
|
||||
/>
|
||||
) : (
|
||||
void 0
|
||||
)}
|
||||
|
||||
<span>{isOpen ? '∨' : '<'}</span>
|
||||
</span>
|
||||
</div>
|
||||
{/* {isOpen && <div>{children}</div>} */}
|
||||
<div style={{ display: isOpen ? 'block' : 'none' }}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Collapsible
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
import { observer } from 'mobx-react'
|
||||
import React from 'react'
|
||||
import ControlNetUnit from './ControlNetUnit'
|
||||
import { store as ControlNetStore } from './main'
|
||||
|
||||
import ControlNetStore from './store'
|
||||
import { DefaultControlNetUnitData } from './store'
|
||||
import {
|
||||
Enum,
|
||||
controlnet_preset,
|
||||
note,
|
||||
preset,
|
||||
selection,
|
||||
} from '../util/oldSystem'
|
||||
import { SpMenuComponent } from '../util/elements'
|
||||
import { Enum, controlnet_preset, note, selection } from '../util/oldSystem'
|
||||
import { SpMenu, SpMenuComponent } from '../util/elements'
|
||||
import Locale from '../locale/locale'
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import { PresetTypeEnum } from '../util/ts/enum'
|
||||
import {
|
||||
store as preset_store,
|
||||
getAllCustomPresetsSettings,
|
||||
getCustomPresetsNames,
|
||||
} from '../preset/shared_ui_preset'
|
||||
|
||||
let g_controlnet_presets: any
|
||||
declare const g_generation_session: any
|
||||
|
|
@ -28,59 +29,57 @@ class ControlNetTab extends React.Component<{
|
|||
|
||||
// private presetMenuChildren: JSX.Element[] = []
|
||||
|
||||
onPresetMenuChange(evt: any) {
|
||||
const preset_index = evt.target.selectedIndex
|
||||
const preset_name = evt.target.options[preset_index].textContent
|
||||
ControlNetStore.controlNetUnitData.forEach((dataitem, index) => {
|
||||
const presetData = g_controlnet_presets[preset_name][index] || {}
|
||||
// onPresetMenuChange(evt: any) {
|
||||
// // const preset_index = evt.target.selectedIndex
|
||||
// // const preset_name = evt.target.options[preset_index].textContent
|
||||
// ControlNetStore.controlNetUnitData.forEach((dataitem, index) => {
|
||||
// const presetData = g_controlnet_presets[preset_name][index] || {}
|
||||
|
||||
dataitem.enabled =
|
||||
presetData.enabled || DefaultControlNetUnitData.enabled
|
||||
dataitem.input_image =
|
||||
presetData.input_image || DefaultControlNetUnitData.input_image
|
||||
dataitem.mask = presetData.mask || DefaultControlNetUnitData.mask
|
||||
// dataitem.enabled =
|
||||
// presetData.enabled || DefaultControlNetUnitData.enabled
|
||||
// dataitem.input_image =
|
||||
// presetData.input_image || DefaultControlNetUnitData.input_image
|
||||
// dataitem.mask = presetData.mask || DefaultControlNetUnitData.mask
|
||||
|
||||
dataitem.module =
|
||||
presetData.module || DefaultControlNetUnitData.module
|
||||
dataitem.model = presetData.model || DefaultControlNetUnitData.model
|
||||
dataitem.weight =
|
||||
presetData.weight || DefaultControlNetUnitData.weight
|
||||
dataitem.resize_mode =
|
||||
presetData.resize_mode || DefaultControlNetUnitData.resize_mode
|
||||
dataitem.lowvram =
|
||||
presetData.lowvram || DefaultControlNetUnitData.lowvram
|
||||
dataitem.processor_res =
|
||||
presetData.processor_res ||
|
||||
DefaultControlNetUnitData.processor_res
|
||||
dataitem.threshold_a =
|
||||
presetData.threshold_a || DefaultControlNetUnitData.threshold_a
|
||||
dataitem.threshold_b =
|
||||
presetData.threshold_b || DefaultControlNetUnitData.threshold_b
|
||||
dataitem.guidance_start =
|
||||
presetData.guidance_start ||
|
||||
DefaultControlNetUnitData.guidance_start
|
||||
dataitem.guidance_end =
|
||||
presetData.guidance_end ||
|
||||
DefaultControlNetUnitData.guidance_end
|
||||
dataitem.guessmode =
|
||||
presetData.guessmode || DefaultControlNetUnitData.guessmode
|
||||
// dataitem.module =
|
||||
// presetData.module || DefaultControlNetUnitData.module
|
||||
// dataitem.model = presetData.model || DefaultControlNetUnitData.model
|
||||
// dataitem.weight =
|
||||
// presetData.weight || DefaultControlNetUnitData.weight
|
||||
// dataitem.resize_mode =
|
||||
// presetData.resize_mode || DefaultControlNetUnitData.resize_mode
|
||||
// dataitem.lowvram =
|
||||
// presetData.lowvram || DefaultControlNetUnitData.lowvram
|
||||
// dataitem.processor_res =
|
||||
// presetData.processor_res ||
|
||||
// DefaultControlNetUnitData.processor_res
|
||||
// dataitem.threshold_a =
|
||||
// presetData.threshold_a || DefaultControlNetUnitData.threshold_a
|
||||
// dataitem.threshold_b =
|
||||
// presetData.threshold_b || DefaultControlNetUnitData.threshold_b
|
||||
// dataitem.guidance_start =
|
||||
// presetData.guidance_start ||
|
||||
// DefaultControlNetUnitData.guidance_start
|
||||
// dataitem.guidance_end =
|
||||
// presetData.guidance_end ||
|
||||
// DefaultControlNetUnitData.guidance_end
|
||||
// dataitem.guessmode =
|
||||
// presetData.guessmode || DefaultControlNetUnitData.guessmode
|
||||
|
||||
dataitem.control_mode =
|
||||
presetData.control_mode ||
|
||||
DefaultControlNetUnitData.control_mode
|
||||
dataitem.pixel_perfect =
|
||||
presetData.pixel_perfect ||
|
||||
DefaultControlNetUnitData.pixel_perfect
|
||||
})
|
||||
}
|
||||
// dataitem.control_mode =
|
||||
// presetData.control_mode ||
|
||||
// DefaultControlNetUnitData.control_mode
|
||||
// dataitem.pixel_perfect =
|
||||
// presetData.pixel_perfect ||
|
||||
// DefaultControlNetUnitData.pixel_perfect
|
||||
// })
|
||||
// }
|
||||
// function to update presetMenuChildren
|
||||
updatePresetMenuChildren(newChildren: any) {
|
||||
this.setState({ presetMenuChildren: newChildren })
|
||||
}
|
||||
async updatePresetMenuEvent() {
|
||||
const custom_presets = await preset.getAllCustomPresetsSettings(
|
||||
Enum.PresetTypeEnum['ControlNetPreset']
|
||||
)
|
||||
const custom_presets = await getAllCustomPresetsSettings()
|
||||
g_controlnet_presets = {
|
||||
'Select CtrlNet Preset': {},
|
||||
...controlnet_preset.ControlNetNativePresets,
|
||||
|
|
@ -147,25 +146,25 @@ class ControlNetTab extends React.Component<{
|
|||
render() {
|
||||
return (
|
||||
<div>
|
||||
<sp-picker
|
||||
title="auto fill the ControlNet with smart settings, to speed up your working process."
|
||||
size="s"
|
||||
label="ControlNet Preset"
|
||||
style={{
|
||||
width: '65%',
|
||||
{/* <SpMenu
|
||||
title="ControlNet Presets"
|
||||
items={getCustomPresetsNames({
|
||||
...preset_store.data.controlnet_native_presets,
|
||||
...preset_store.data.controlnet_presets,
|
||||
})}
|
||||
label_item="Select a Preset"
|
||||
selected_index={getCustomPresetsNames({
|
||||
...preset_store.data.controlnet_native_presets,
|
||||
...preset_store.data.controlnet_presets,
|
||||
}).indexOf(preset_store.data.current_controlnet_preset)}
|
||||
onChange={(id: any, value: any) => {
|
||||
console.log('value:', value)
|
||||
|
||||
preset_store.data.current_controlnet_preset = value.item
|
||||
// this.onPresetMenuChange()
|
||||
}}
|
||||
>
|
||||
<SpMenuComponent
|
||||
id="mControlNetPresetMenu"
|
||||
value="Select CtrlNet Preset"
|
||||
onChange={this.onPresetMenuChange.bind(this)}
|
||||
onUpdatePresetMenuEvent={this.updatePresetMenuEvent.bind(
|
||||
this
|
||||
)}
|
||||
>
|
||||
{this.state.presetMenuChildren.map((child) => child)}
|
||||
</SpMenuComponent>
|
||||
</sp-picker>
|
||||
></SpMenu> */}
|
||||
|
||||
<div></div>
|
||||
{this.props.appState.maxControlNet == 0 && (
|
||||
<sp-label
|
||||
|
|
|
|||
|
|
@ -808,7 +808,7 @@ export default class ControlNetUnit extends React.Component<
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ width: '50%', display: 'flex' }}>
|
||||
<SpMenu
|
||||
onChange={this.onFilterChange.bind(this)}
|
||||
items={this.props.appState.filterKeywords}
|
||||
|
|
@ -816,34 +816,38 @@ export default class ControlNetUnit extends React.Component<
|
|||
selected_index={this.props.appState.filterKeywords.indexOf(
|
||||
storeData.filter_keyword || 'All'
|
||||
)}
|
||||
style={{ width: '50%', display: 'flex' }}
|
||||
// style={{ width: '50%', display: 'flex' }}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
id={`menu-bar-control_net_${this.props.index}`}
|
||||
style={{ display: 'flex' }}
|
||||
>
|
||||
<SpMenu
|
||||
onChange={this.onPreprocsesorChange.bind(this)}
|
||||
id={`mModulesMenuControlNet_${this.props.index}`}
|
||||
items={storeData.module_list || ['none']}
|
||||
label_item={Locale('Select Module')}
|
||||
selected_index={storeData.module_list?.indexOf(
|
||||
storeData.module
|
||||
)}
|
||||
style={{ width: '100%', display: 'flex' }}
|
||||
/>
|
||||
{!pd.model_free && (
|
||||
<div style={{ width: '50%', display: 'flex' }}>
|
||||
<SpMenu
|
||||
onChange={this.onModelChange.bind(this)}
|
||||
id={`mModelsMenuControlNet_${this.props.index}`}
|
||||
items={storeData.model_list || []}
|
||||
onChange={this.onPreprocsesorChange.bind(this)}
|
||||
id={`mModulesMenuControlNet_${this.props.index}`}
|
||||
items={storeData.module_list || ['none']}
|
||||
label_item={Locale('Select Module')}
|
||||
selected_index={storeData.model_list?.indexOf(
|
||||
storeData.model
|
||||
selected_index={storeData.module_list?.indexOf(
|
||||
storeData.module
|
||||
)}
|
||||
style={{ width: '100%', display: 'flex' }}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
{!pd.model_free && (
|
||||
<div style={{ width: '50%', display: 'flex' }}>
|
||||
<SpMenu
|
||||
onChange={this.onModelChange.bind(this)}
|
||||
id={`mModelsMenuControlNet_${this.props.index}`}
|
||||
items={storeData.model_list || []}
|
||||
label_item={Locale('Select Module')}
|
||||
selected_index={storeData.model_list?.indexOf(
|
||||
storeData.model
|
||||
)}
|
||||
style={{ width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,14 @@
|
|||
import { setControlImageSrc } from '../../utility/html_manip'
|
||||
import { session_ts } from '../entry'
|
||||
// import { session_ts } from '../entry'
|
||||
// import * as session_ts from '../session/session'
|
||||
import { store as session_store } from '../session/session_store'
|
||||
import { Enum, api, python_replacement } from '../util/oldSystem'
|
||||
import { GenerationModeEnum } from '../util/ts/enum'
|
||||
import { store, versionCompare } from './main'
|
||||
import store, {
|
||||
DefaultControlNetUnitData,
|
||||
DefaultPresetControlNetUnitData,
|
||||
controlNetUnitData,
|
||||
} from './store'
|
||||
|
||||
const { getExtensionUrl } = python_replacement
|
||||
declare const g_sd_config_obj: any
|
||||
|
|
@ -122,13 +128,11 @@ function mapPluginSettingsToControlNet(plugin_settings: any) {
|
|||
let input_image = store.controlNetUnitData[index].input_image
|
||||
if (
|
||||
b_sync_input_image &&
|
||||
[GenerationModeEnum.Txt2Img].includes(
|
||||
session_ts.store.data.mode
|
||||
)
|
||||
[GenerationModeEnum.Txt2Img].includes(session_store.data.mode)
|
||||
) {
|
||||
//conditions: 1) txt2img mode 2)auto image on 3)first generation of session
|
||||
|
||||
input_image = session_ts.store.data.controlnet_input_image ?? ''
|
||||
input_image = session_store.data.controlnet_input_image ?? ''
|
||||
store.controlNetUnitData[index].input_image = input_image
|
||||
}
|
||||
if (
|
||||
|
|
@ -138,10 +142,10 @@ function mapPluginSettingsToControlNet(plugin_settings: any) {
|
|||
GenerationModeEnum.Inpaint,
|
||||
GenerationModeEnum.Outpaint,
|
||||
GenerationModeEnum.LassoInpaint,
|
||||
].includes(session_ts.store.data.mode)
|
||||
].includes(session_store.data.mode)
|
||||
) {
|
||||
// img2img mode
|
||||
input_image = session_ts.store.data.init_image
|
||||
input_image = session_store.data.init_image
|
||||
store.controlNetUnitData[index].input_image = input_image
|
||||
} else if (
|
||||
b_sync_input_image &&
|
||||
|
|
@ -160,7 +164,7 @@ function mapPluginSettingsToControlNet(plugin_settings: any) {
|
|||
// const b_sync_input_image =
|
||||
// store.controlNetUnitData[index].auto_image
|
||||
// let mask = store.controlNetUnitData[index].mask // the user created mask
|
||||
// if (b_sync_input_image && session_ts.store.data.expanded_mask) {
|
||||
// if (b_sync_input_image && session_store.data.expanded_mask) {
|
||||
// //use the mask from inpaint and outpaint mode
|
||||
// mask = '' // this will tell controlnet to use SD mask
|
||||
// store.controlNetUnitData[index].mask = ''
|
||||
|
|
@ -170,7 +174,7 @@ function mapPluginSettingsToControlNet(plugin_settings: any) {
|
|||
[
|
||||
GenerationModeEnum.Txt2Img,
|
||||
GenerationModeEnum.Img2Img,
|
||||
].includes(session_ts.store.data.mode)
|
||||
].includes(session_store.data.mode)
|
||||
) {
|
||||
//maskless mode
|
||||
} else {
|
||||
|
|
@ -190,7 +194,7 @@ function mapPluginSettingsToControlNet(plugin_settings: any) {
|
|||
module: store.controlNetUnitData[index].module,
|
||||
model: store.controlNetUnitData[index].model,
|
||||
weight: store.controlNetUnitData[index].weight,
|
||||
resize_mode: 'Scale to Fit (Inner Fit)',
|
||||
resize_mode: 'Crop and Resize',
|
||||
lowvram: store.controlNetUnitData[index].lowvram,
|
||||
processor_res: store.controlNetUnitData[index].processor_res || 512,
|
||||
threshold_a: store.controlNetUnitData[index].threshold_a,
|
||||
|
|
@ -234,6 +238,24 @@ function getControlNetMaxModelsNumber() {
|
|||
function getUnitsData() {
|
||||
return store.controlNetUnitData
|
||||
}
|
||||
|
||||
export function setUnitData(unitData: controlNetUnitData, index: number) {
|
||||
try {
|
||||
store.controlNetUnitData[index] = {
|
||||
...store.controlNetUnitData[index],
|
||||
...unitData,
|
||||
}
|
||||
|
||||
if (!unitData?.enabled) {
|
||||
store.controlNetUnitData[index] = {
|
||||
...store.controlNetUnitData[index],
|
||||
...DefaultPresetControlNetUnitData,
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
function setControlDetectMapSrc(base64: string, index: number) {
|
||||
// store.controlNetUnitData[index].mask = base64
|
||||
store.controlNetUnitData[index].detect_map = base64
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||
import ControlNetTab from './ControlNetTab'
|
||||
import store from './store'
|
||||
import { versionCompare } from './util'
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import Locale from '../locale/locale'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
|
||||
|
|
@ -48,51 +48,9 @@ if (elem2) {
|
|||
}
|
||||
function scrollToEnabledControlNetUnit() {}
|
||||
|
||||
const button = document.getElementById('scrollToControlNetUnitContainer')!
|
||||
const button_root = ReactDOM.createRoot(button)
|
||||
let controlnet_unit_index = 0
|
||||
button_root.render(
|
||||
<ErrorBoundary>
|
||||
<button
|
||||
className="btnSquare svgButton"
|
||||
onClick={() => {
|
||||
try {
|
||||
const units = document.querySelectorAll(
|
||||
'#controlNetTabParentContainer .collapsible'
|
||||
)
|
||||
const units_data = store.controlNetUnitData.map(
|
||||
(data, index) => ({
|
||||
enabled: data.enabled,
|
||||
index,
|
||||
})
|
||||
)
|
||||
// const button = document.getElementById('scrollToControlNetUnitContainer')!
|
||||
// const button_root = ReactDOM.createRoot(button)
|
||||
|
||||
// Find the next enabled unit
|
||||
let counter = 0
|
||||
while (
|
||||
!units_data[controlnet_unit_index % units.length]
|
||||
.enabled &&
|
||||
counter < units.length
|
||||
) {
|
||||
controlnet_unit_index += 1
|
||||
counter += 1
|
||||
}
|
||||
// button_root.render(<ErrorBoundary></ErrorBoundary>)
|
||||
|
||||
if (counter < units.length) {
|
||||
controlnet_unit_index =
|
||||
controlnet_unit_index % units.length
|
||||
units[controlnet_unit_index].scrollIntoView()
|
||||
controlnet_unit_index += 1
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}}
|
||||
title="Quickly jump to the active ControlNet Unit"
|
||||
>
|
||||
C
|
||||
</button>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
|
||||
export { store, versionCompare }
|
||||
export { versionCompare }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { observable, reaction } from 'mobx'
|
||||
|
||||
type ResizeMode = 'Just Resize' | 'Crop and Resize' | 'Resize and Fill'
|
||||
export const controlnetModes = [
|
||||
'Balanced',
|
||||
'My prompt is more important',
|
||||
'ControlNet is more important',
|
||||
] as const
|
||||
export type ControlnetMode = (typeof controlnetModes)[number]
|
||||
export const DefaultControlNetUnitData = {
|
||||
enabled: false,
|
||||
input_image: '',
|
||||
|
|
@ -8,7 +14,7 @@ export const DefaultControlNetUnitData = {
|
|||
module: '',
|
||||
model: '',
|
||||
weight: 1.0,
|
||||
resize_mode: 'Scale to Fit (Inner Fit)',
|
||||
resize_mode: 'Crop and Resize' as ResizeMode,
|
||||
lowvram: true,
|
||||
processor_res: 512,
|
||||
threshold_a: 0,
|
||||
|
|
@ -18,17 +24,37 @@ export const DefaultControlNetUnitData = {
|
|||
guidance_end: 1,
|
||||
guessmode: false,
|
||||
|
||||
control_mode: 'Balanced',
|
||||
control_mode: 'Balanced' as ControlnetMode,
|
||||
pixel_perfect: true,
|
||||
auto_image: true,
|
||||
}
|
||||
|
||||
export const controlnetModes = [
|
||||
'Balanced',
|
||||
'My prompt is more important',
|
||||
'ControlNet is more important',
|
||||
] as const
|
||||
export type ControlnetMode = (typeof controlnetModes)[number]
|
||||
export const DefaultPresetControlNetUnitData = {
|
||||
enabled: false,
|
||||
// input_image: '',
|
||||
// mask: '',
|
||||
// detect_map: '',
|
||||
module: '',
|
||||
model: '',
|
||||
filter_keyword: 'All',
|
||||
weight: 1.0,
|
||||
|
||||
resize_mode: 'Crop and Resize' as ResizeMode,
|
||||
|
||||
lowvram: true,
|
||||
|
||||
processor_res: 512,
|
||||
threshold_a: 0,
|
||||
threshold_b: 0,
|
||||
|
||||
guidance_start: 0,
|
||||
guidance_end: 1,
|
||||
guessmode: false,
|
||||
|
||||
control_mode: 'Balanced' as ControlnetMode,
|
||||
pixel_perfect: true,
|
||||
auto_image: true,
|
||||
}
|
||||
|
||||
export interface controlNetUnitData {
|
||||
enabled: boolean
|
||||
|
|
@ -41,7 +67,7 @@ export interface controlNetUnitData {
|
|||
model: string
|
||||
filter_keyword: string
|
||||
weight: number
|
||||
resize_mode: 'Just Resize' | 'Crop and Resize' | 'Resize and Fill'
|
||||
resize_mode: ResizeMode
|
||||
lowvram: boolean
|
||||
processor_res: number
|
||||
threshold_a: number
|
||||
|
|
|
|||
|
|
@ -1,24 +1,38 @@
|
|||
// import { configure } from 'mobx'
|
||||
// configure({
|
||||
// enforceActions: 'never', // disable mobx warning temporarily
|
||||
// })
|
||||
import { configure } from 'mobx'
|
||||
configure({
|
||||
enforceActions: 'never', // disable mobx warning temporarily
|
||||
})
|
||||
export * as control_net from './controlnet/entry'
|
||||
export * as after_detailer_script from './after_detailer/after_detailer'
|
||||
export * as ultimate_sd_upscaler from './ultimate_sd_upscaler/ultimate_sd_upscaler'
|
||||
export * as scripts from './ultimate_sd_upscaler/scripts'
|
||||
export * as main from './main/main'
|
||||
export * as controlnet_main from './controlnet/main'
|
||||
export * as logger from './util/logger'
|
||||
export * as image_search from './image_search/image_search'
|
||||
export * as history from './history/history'
|
||||
export * as viewer from './viewer/viewer'
|
||||
export * as session_ts from './session/session'
|
||||
export { store as session_store } from './session/session_store'
|
||||
export { store as sd_tab_store } from './sd_tab/util'
|
||||
|
||||
export * as progress from './session/progress'
|
||||
export * as preview from './viewer/preview'
|
||||
export * as generate from './session/generate'
|
||||
export * as sd_tab_ts from './sd_tab/sd_tab'
|
||||
export * as sd_tab_util from './sd_tab/util'
|
||||
export * as sam from './sam/sam'
|
||||
export * as settings_tab_ts from './settings/settings'
|
||||
export * as one_button_prompt from './one_button_prompt/one_button_prompt'
|
||||
export * as enum_ts from './util/ts/enum'
|
||||
export * as multiPrompts from './multiTextarea'
|
||||
export * as preset from './preset/preset'
|
||||
export * as preset_util from './preset/shared_ui_preset'
|
||||
export * as ui_ts from './util/ts/ui_ts'
|
||||
export * as io_ts from './util/ts/io'
|
||||
export * as tool_bar from './tool_bar/tool_bar'
|
||||
export * as extra_page from './extra_page/extra_page'
|
||||
export * as selection_ts from './util/ts/selection'
|
||||
export * as stores from './stores'
|
||||
export { toJS } from 'mobx'
|
||||
export { default as node_fs } from 'fs'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,267 @@
|
|||
import { observer } from 'mobx-react'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import { GenerateButtons } from '../session/generate'
|
||||
import { AStore } from '../main/astore'
|
||||
import { SpMenu, SpSlider } from '../util/elements'
|
||||
import { mapRange } from '../controlnet/util'
|
||||
import { requestGetUpscalers } from '../util/ts/sdapi'
|
||||
|
||||
export const store = new AStore({
|
||||
upscaling_resize: 2,
|
||||
upscaler_list: [] as string[],
|
||||
upscaler_1: '',
|
||||
upscaler_2: '',
|
||||
resize_mode: 0,
|
||||
show_extras_results: 0,
|
||||
gfpgan_visibility: 0,
|
||||
codeformer_visibility: 0,
|
||||
codeformer_weight: 0,
|
||||
upscaling_resize_w: 0,
|
||||
upscaling_resize_h: 0,
|
||||
upscaling_crop: true,
|
||||
extras_upscaler_2_visibility: 0,
|
||||
upscale_first: false,
|
||||
})
|
||||
|
||||
export async function refreshExtraUpscalers() {
|
||||
try {
|
||||
const upscalers = await requestGetUpscalers()
|
||||
if (upscalers) {
|
||||
store.data.upscaler_list = upscalers.map(
|
||||
(upscaler: { name: any }) => upscaler.name
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
@observer
|
||||
export class ExtraPage extends React.Component {
|
||||
componentDidMount(): void {}
|
||||
|
||||
render(): React.ReactNode {
|
||||
return (
|
||||
<div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<SpSlider
|
||||
style={{ display: 'block' }}
|
||||
show-value="false"
|
||||
id="slUpscaleSize"
|
||||
min="10"
|
||||
max="80"
|
||||
value={store.data.upscaling_resize * 10}
|
||||
title="Resize scale of current selection size"
|
||||
onInput={(evt: any) => {
|
||||
store.data.upscaling_resize = mapRange(
|
||||
evt.target.value,
|
||||
10,
|
||||
80,
|
||||
1,
|
||||
8,
|
||||
0.01
|
||||
)
|
||||
}}
|
||||
>
|
||||
<sp-label slot="label">Resize</sp-label>
|
||||
<sp-label
|
||||
class="labelNumber"
|
||||
slot="label"
|
||||
id="lUpscaleSize"
|
||||
>
|
||||
{store.data.upscaling_resize.toFixed(2)}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
<GenerateButtons></GenerateButtons>
|
||||
|
||||
<div
|
||||
id="progressContainerUpscale"
|
||||
style={{ paddingBottom: '5px' }}
|
||||
>
|
||||
<sp-label slot="label" class="lProgressLabel">
|
||||
No work in progress
|
||||
</sp-label>
|
||||
</div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '60px', display: 'inline-block' }}
|
||||
>
|
||||
Upscaler 1:
|
||||
</sp-label>
|
||||
<SpMenu
|
||||
size="m"
|
||||
title="Upscaler 1"
|
||||
items={store.data.upscaler_list}
|
||||
label_item="Select an Upscaler Model"
|
||||
selected_index={store.data.upscaler_list.indexOf(
|
||||
store.data.upscaler_1
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
store.data.upscaler_1 = value.item
|
||||
}}
|
||||
></SpMenu>
|
||||
|
||||
<div></div>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '60px', display: 'inline-block' }}
|
||||
>
|
||||
Upscaler 2:
|
||||
</sp-label>
|
||||
<SpMenu
|
||||
size="m"
|
||||
title="Upscaler 2"
|
||||
items={store.data.upscaler_list}
|
||||
label_item="Select an Upscaler Model"
|
||||
selected_index={store.data.upscaler_list.indexOf(
|
||||
store.data.upscaler_2
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
store.data.upscaler_2 = value.item
|
||||
}}
|
||||
></SpMenu>
|
||||
</div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<SpSlider
|
||||
style={{ display: 'block' }}
|
||||
show-value="false"
|
||||
id="slUpscaler2Visibility"
|
||||
min="0"
|
||||
max="10"
|
||||
value={store.data.extras_upscaler_2_visibility * 10}
|
||||
onInput={(evt: any) => {
|
||||
store.data.extras_upscaler_2_visibility =
|
||||
evt.target.value / 10
|
||||
}}
|
||||
>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '110px', display: 'inline-block' }}
|
||||
slot="label"
|
||||
>
|
||||
Upscaler 2 visibility:
|
||||
</sp-label>
|
||||
<sp-label
|
||||
style={{ display: 'inline-block' }}
|
||||
class="labelNumber"
|
||||
slot="label"
|
||||
id="lUpscaler2Visibility"
|
||||
>
|
||||
{store.data.extras_upscaler_2_visibility.toFixed(2)}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<SpSlider
|
||||
style={{ display: 'block' }}
|
||||
show-value="false"
|
||||
id="slGFPGANVisibility"
|
||||
min="0"
|
||||
max="10"
|
||||
value={store.data.gfpgan_visibility * 10}
|
||||
onInput={(evt: any) => {
|
||||
store.data.gfpgan_visibility = evt.target.value / 10
|
||||
}}
|
||||
>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '110px', display: 'inline-block' }}
|
||||
slot="label"
|
||||
>
|
||||
GFPGAN visibility:
|
||||
</sp-label>
|
||||
<sp-label
|
||||
style={{ display: 'inline-block' }}
|
||||
class="labelNumber"
|
||||
slot="label"
|
||||
id="lGFPGANVisibility"
|
||||
>
|
||||
{store.data.gfpgan_visibility.toFixed(2)}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<SpSlider
|
||||
style={{ display: 'block' }}
|
||||
show-value="false"
|
||||
id="slCodeFormerVisibility"
|
||||
min="0"
|
||||
max="10"
|
||||
value={store.data.codeformer_visibility * 10}
|
||||
onInput={(evt: any) => {
|
||||
store.data.codeformer_visibility =
|
||||
evt.target.value / 10
|
||||
}}
|
||||
>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '110px', display: 'inline-block' }}
|
||||
slot="label"
|
||||
>
|
||||
CodeFormer visibility:
|
||||
</sp-label>
|
||||
<sp-label
|
||||
style={{ display: 'inline-block' }}
|
||||
class="labelNumber"
|
||||
slot="label"
|
||||
id="lCodeFormerVisibility"
|
||||
>
|
||||
{store.data.codeformer_visibility.toFixed(2)}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
<div style={{ paddingBottom: '5px' }}>
|
||||
<SpSlider
|
||||
style={{ display: 'block' }}
|
||||
show-value="false"
|
||||
id="slCodeFormerWeight"
|
||||
min="0"
|
||||
max="10"
|
||||
value={store.data.codeformer_weight * 10}
|
||||
onInput={(evt: any) => {
|
||||
store.data.codeformer_weight = evt.target.value / 10
|
||||
}}
|
||||
>
|
||||
<sp-label
|
||||
class="title"
|
||||
style={{ width: '110px', display: 'inline-block' }}
|
||||
slot="label"
|
||||
>
|
||||
CodeFormer weight:
|
||||
</sp-label>
|
||||
<sp-label
|
||||
style={{ display: 'inline-block' }}
|
||||
class="labelNumber"
|
||||
slot="label"
|
||||
id="lCodeFormerWeight"
|
||||
>
|
||||
{store.data.codeformer_weight.toFixed(2)}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const containers = document.querySelectorAll('.extraPageContainer')!
|
||||
|
||||
containers.forEach((container) => {
|
||||
const root = ReactDOM.createRoot(container)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<div style={{ border: '2px solid #6d6c6c', padding: '3px' }}>
|
||||
<Collapsible defaultIsOpen={true} label={'Extra Page'}>
|
||||
<ExtraPage />
|
||||
</Collapsible>
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
})
|
||||
|
|
@ -8,10 +8,11 @@ import { MoveToCanvasSvg, PenSvg } from '../util/elements'
|
|||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import Locale from '../locale/locale'
|
||||
import { addWithHistory } from '../viewer/viewer'
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
//@ts-ignore
|
||||
import { storage } from 'uxp'
|
||||
import { _arrayBufferToBase64 } from '../util/ts/io'
|
||||
import { sd_tab_store } from '../stores'
|
||||
declare let g_ui_settings_object: any
|
||||
export const store = new AStore({
|
||||
images: [] as string[], //full resloution images
|
||||
|
|
@ -134,7 +135,7 @@ async function moveHistoryImageToLayer(
|
|||
// width,
|
||||
// height
|
||||
// )
|
||||
debugger
|
||||
|
||||
const layer = await addWithHistory(
|
||||
base64_image,
|
||||
metadata?.expanded_mask ?? void 0,
|
||||
|
|
@ -146,12 +147,12 @@ async function moveHistoryImageToLayer(
|
|||
}
|
||||
}
|
||||
|
||||
function historyMetadataToPreset(metadata: any) {}
|
||||
function getHistoryMetadata(metadata_json: any) {
|
||||
//auto fill the ui with metadata
|
||||
// const metadata_json = JSON.parse(img.dataset.metadata_json_string)
|
||||
|
||||
console.log('metadata_json: ', metadata_json)
|
||||
// document.querySelector('#tiSeed').value = metadata_json.Seed
|
||||
|
||||
//extract auto_metadata into the preset metadata
|
||||
function convertAutoMetadataToPreset(metadata_json: any) {
|
||||
|
|
@ -220,7 +221,7 @@ function segmentCombinedArray(combinedArray: CombinedElement[]) {
|
|||
const segmentedArray: CombinedElement[][] = []
|
||||
let currentSessionId = combinedArray[0].metadata_json.session_id
|
||||
let currentSegment: CombinedElement[] = []
|
||||
debugger
|
||||
|
||||
for (const element of combinedArray) {
|
||||
if (element.metadata_json.session_id === currentSessionId) {
|
||||
currentSegment.push(element)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
//TODO: delete lexical_tab.js and lexica tab from html
|
||||
import { observer } from 'mobx-react'
|
||||
import React from 'react'
|
||||
|
||||
@observer
|
||||
export class Lexical extends React.Component {
|
||||
componentDidMount(): void {}
|
||||
componentWillUnmount(): void {}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className="subTabOptionsContainer"></div>
|
||||
|
||||
<div className="flexContainer">
|
||||
<sp-label slot="label">
|
||||
Explore Lexica for prompts and inspiration
|
||||
</sp-label>
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<sp-textfield
|
||||
id="LexicaSearchField"
|
||||
type="text"
|
||||
placeholder="cute cats"
|
||||
value=""
|
||||
>
|
||||
<sp-label slot="label">Search:</sp-label>
|
||||
</sp-textfield>
|
||||
|
||||
<button
|
||||
className="btnSquare search-button"
|
||||
id="btnSearchLexica"
|
||||
title="user prompt(text) to Search Lexica"
|
||||
></button>
|
||||
|
||||
<button
|
||||
className="btnSquare reverse_image_serach"
|
||||
id="btnReverseSearchLexica"
|
||||
title="User the selected area (image) on canvas to Search Lexica"
|
||||
></button>
|
||||
</div>
|
||||
<sp-textarea
|
||||
id="lexicaPrompt"
|
||||
style="margin-bottom: 3px"
|
||||
></sp-textarea>
|
||||
<div className="viewer-container" id="divLexicaImagesContainer">
|
||||
<img
|
||||
className="history-image"
|
||||
id="history_image_test"
|
||||
data-metadata_json_string='{"a":1}'
|
||||
src="https://source.unsplash.com/random"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import React from 'react'
|
|||
import ReactDOM from 'react-dom/client'
|
||||
import { AStore } from './main/astore'
|
||||
import { ErrorBoundary } from './util/errorBoundary'
|
||||
import Collapsible from './after_detailer/after_detailer'
|
||||
import { Collapsible } from './util/collapsible'
|
||||
|
||||
interface AStoreData {
|
||||
positivePrompts: string[]
|
||||
|
|
@ -14,8 +14,8 @@ interface AStoreData {
|
|||
const defaultPositivePrompt = 'cute cat, {painterly_style_1}'
|
||||
const defaultNegativePrompt = '{ugly}'
|
||||
export const store = new AStore({
|
||||
positivePrompts: Array(4).fill(defaultPositivePrompt),
|
||||
negativePrompts: Array(4).fill(defaultNegativePrompt),
|
||||
positivePrompts: [defaultPositivePrompt, ...Array(3).fill('')],
|
||||
negativePrompts: [defaultNegativePrompt, ...Array(3).fill('')],
|
||||
|
||||
current_index: 0,
|
||||
})
|
||||
|
|
@ -134,20 +134,20 @@ export class MultiTextArea extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
const containers = document.querySelectorAll('.multiPromptsContainer')!
|
||||
// const containers = document.querySelectorAll('.multiPromptsContainer')!
|
||||
|
||||
containers.forEach((container) => {
|
||||
const root = ReactDOM.createRoot(container)
|
||||
// containers.forEach((container) => {
|
||||
// const root = ReactDOM.createRoot(container)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<div style={{ border: '2px solid #6d6c6c', padding: '3px' }}>
|
||||
<Collapsible defaultIsOpen={true} label={'Prompts'}>
|
||||
<MultiTextArea />
|
||||
</Collapsible>
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
})
|
||||
// root.render(
|
||||
// <React.StrictMode>
|
||||
// <ErrorBoundary>
|
||||
// <div style={{ border: '2px solid #6d6c6c', padding: '3px' }}>
|
||||
// <Collapsible defaultIsOpen={true} label={'Prompts'}>
|
||||
// <MultiTextArea />
|
||||
// </Collapsible>
|
||||
// </div>
|
||||
// </ErrorBoundary>
|
||||
// </React.StrictMode>
|
||||
// )
|
||||
// })
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import { observer } from 'mobx-react'
|
||||
import { AStore } from '../main/astore'
|
||||
|
||||
|
|
@ -154,45 +154,57 @@ class OneButtonPrompt extends React.Component {
|
|||
store.data.prompt_complexity = output_value
|
||||
}}
|
||||
/>
|
||||
<sp-label>Subject:</sp-label>
|
||||
<SpMenu
|
||||
title="subjects"
|
||||
items={store.data.subjects}
|
||||
label_item="Select a Subject"
|
||||
selected_index={store.data.subjects.indexOf(
|
||||
store.data.subject
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('subject', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<sp-label>Artist:</sp-label>
|
||||
<SpMenu
|
||||
title="artists"
|
||||
items={store.data.artists}
|
||||
label_item="Select an Artist"
|
||||
selected_index={store.data.artists.indexOf(
|
||||
store.data.artist
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('artist', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<sp-label>Image Type:</sp-label>
|
||||
<SpMenu
|
||||
title="image types"
|
||||
items={store.data.imagetypes}
|
||||
label_item="Select an Image Type"
|
||||
selected_index={store.data.imagetypes.indexOf(
|
||||
store.data.imagetype
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('imagetype', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<div>
|
||||
<SpMenu
|
||||
title="subjects"
|
||||
items={store.data.subjects}
|
||||
label_item="Select a Subject"
|
||||
selected_index={store.data.subjects.indexOf(
|
||||
store.data.subject
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('subject', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<sp-label style={{ marginLeft: '3px' }}>
|
||||
Subject
|
||||
</sp-label>
|
||||
</div>
|
||||
<div>
|
||||
<SpMenu
|
||||
title="artists"
|
||||
items={store.data.artists}
|
||||
label_item="Select an Artist"
|
||||
selected_index={store.data.artists.indexOf(
|
||||
store.data.artist
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('artist', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<sp-label style={{ marginLeft: '3px' }}>
|
||||
Artist
|
||||
</sp-label>
|
||||
</div>
|
||||
<div>
|
||||
<SpMenu
|
||||
title="image types"
|
||||
items={store.data.imagetypes}
|
||||
label_item="Select an Image Type"
|
||||
selected_index={store.data.imagetypes.indexOf(
|
||||
store.data.imagetype
|
||||
)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
store.updateProperty('imagetype', value.item)
|
||||
}}
|
||||
></SpMenu>
|
||||
<sp-label style={{ marginLeft: '3px' }}>
|
||||
Image Type
|
||||
</sp-label>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,285 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import { observer } from 'mobx-react'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import Locale from '../locale/locale'
|
||||
import { PresetTypeEnum } from '../util/ts/enum'
|
||||
import {
|
||||
getAllCustomPresetsSettings,
|
||||
getCustomPresetsNames,
|
||||
getLoadedPresets,
|
||||
// getPresetType,
|
||||
loadPresetSettingsFromFile,
|
||||
preset_tab_store,
|
||||
store,
|
||||
updatePresetMenuEvent,
|
||||
// updatePresetMenuEvent,
|
||||
} from './shared_ui_preset'
|
||||
import { controlnet_preset, general, html_manip, io } from '../util/oldSystem'
|
||||
import { AStore } from '../main/astore'
|
||||
import { reaction, toJS } from 'mobx'
|
||||
import { getUnitsData, setUnitData } from '../controlnet/entry'
|
||||
import { SpMenu } from '../util/elements'
|
||||
import { controlNetUnitData } from '../controlnet/store'
|
||||
import { sd_tab_store } from '../stores'
|
||||
import { storeToPreset, writePreset } from '../util/ts/io'
|
||||
declare let g_ui_settings_object: any
|
||||
|
||||
reaction(
|
||||
() => {
|
||||
return preset_tab_store.data.new_preset
|
||||
},
|
||||
(current_preset: any) => {
|
||||
try {
|
||||
const text = JSON.stringify(current_preset, undefined, 7) || ''
|
||||
const textarea_element = document.getElementById(
|
||||
'taPresetSettings'
|
||||
) as any
|
||||
textarea_element.value = text
|
||||
updateTextAreaHeight(textarea_element)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
function getPresetSettingsHtml() {
|
||||
//@ts-ignore
|
||||
const value_str = document.getElementById('taPresetSettings')!.value
|
||||
const value_json = JSON.parse(value_str)
|
||||
return value_json
|
||||
}
|
||||
|
||||
function updateTextAreaHeight(textarea_element: any) {
|
||||
try {
|
||||
//update the height of the text area to fit the settings in
|
||||
|
||||
const new_lines_count = general.countNewLines(textarea_element.value)
|
||||
let height = new_lines_count * 12 + 100
|
||||
height = Math.max(60, height)
|
||||
height = Math.min(500, height)
|
||||
textarea_element.style.height = height.toString() + 'px'
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// function setPresetName(preset_name: string) {
|
||||
// //@ts-ignore
|
||||
// document.getElementById('tiPresetName')!.value = preset_name
|
||||
// }
|
||||
|
||||
async function deletePreset() {
|
||||
try {
|
||||
const preset_file_name =
|
||||
preset_tab_store.data.selected_preset_name + '.json'
|
||||
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
'custom_preset'
|
||||
)
|
||||
|
||||
await io.IOJson.deleteFile(custom_preset_entry, preset_file_name)
|
||||
preset_tab_store.data.selected_preset_name = ''
|
||||
preset_tab_store.data.new_preset = {}
|
||||
store.data.custom_presets = await getAllCustomPresetsSettings()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
function filterControlnetUnitData(controlnet_units_data: controlNetUnitData[]) {
|
||||
const filtered_data = controlnet_units_data.map((unit) => {
|
||||
const {
|
||||
input_image,
|
||||
mask,
|
||||
detect_map,
|
||||
model_list,
|
||||
module_list,
|
||||
...rest
|
||||
} = unit
|
||||
return rest
|
||||
})
|
||||
return filtered_data
|
||||
}
|
||||
|
||||
export function onNewPreset() {
|
||||
const sd_tab_preset = storeToPreset(sd_tab_store)
|
||||
const controlnet_tab_preset = toJS(getUnitsData())
|
||||
|
||||
const units = controlnet_tab_preset.map((unit: controlNetUnitData) => {
|
||||
if (unit.enabled === false) return {}
|
||||
else {
|
||||
const {
|
||||
input_image,
|
||||
mask,
|
||||
detect_map,
|
||||
model_list,
|
||||
module_list,
|
||||
...rest
|
||||
} = unit
|
||||
return rest
|
||||
}
|
||||
})
|
||||
|
||||
const plugin_preset = {
|
||||
sd_tab_preset: sd_tab_preset,
|
||||
controlnet_tab_preset: units,
|
||||
}
|
||||
preset_tab_store.data.new_preset = plugin_preset
|
||||
return plugin_preset
|
||||
}
|
||||
|
||||
async function onSavePreset() {
|
||||
if (preset_tab_store.data.new_preset_name) {
|
||||
const preset_settings = getPresetSettingsHtml()
|
||||
const preset_name = preset_tab_store.data.new_preset_name.trim()
|
||||
const preset_file_name = preset_name + '.json' // will be used as file name
|
||||
//check if the file exist and prompt the user to override it or cancel
|
||||
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
'custom_preset'
|
||||
)
|
||||
await io.IOJson.saveJsonToFileExe(
|
||||
preset_settings,
|
||||
custom_preset_entry,
|
||||
preset_file_name
|
||||
)
|
||||
store.data.custom_presets = await getAllCustomPresetsSettings()
|
||||
|
||||
console.log('store.data.custom_presets: ', store.data.custom_presets)
|
||||
preset_tab_store.data.selected_preset_name = preset_name
|
||||
}
|
||||
}
|
||||
|
||||
@observer
|
||||
class PresetTab extends React.Component<{}> {
|
||||
async componentDidMount() {
|
||||
// await populatePresetMenu()
|
||||
try {
|
||||
store.data.custom_presets = await getAllCustomPresetsSettings()
|
||||
|
||||
// store.data.controlnet_native_presets = {
|
||||
// ...controlnet_preset.ControlNetNativePresets,
|
||||
// }
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
renderTab() {
|
||||
return (
|
||||
<div>
|
||||
<sp-textfield
|
||||
id="tiPresetName"
|
||||
type="text"
|
||||
placeholder="Preset Name"
|
||||
value={preset_tab_store.data.new_preset_name}
|
||||
style={{ width: '160px' }}
|
||||
onInput={(event: any) => {
|
||||
preset_tab_store.data.new_preset_name =
|
||||
event.target.value
|
||||
// console.log(store.data.preset_name)
|
||||
}}
|
||||
></sp-textfield>
|
||||
<button
|
||||
className="btnSquare"
|
||||
id="btnGeneratePreset"
|
||||
style={{ marginLeft: '5px' }}
|
||||
onClick={() => {
|
||||
onNewPreset()
|
||||
}}
|
||||
>
|
||||
Generate Preset
|
||||
</button>
|
||||
<div style={{ marginTop: '3px' }}>
|
||||
<button
|
||||
className="btnSquare"
|
||||
id="btnSavePreset"
|
||||
style={{}}
|
||||
onClick={async () => {
|
||||
await onSavePreset()
|
||||
}}
|
||||
>
|
||||
Save Preset
|
||||
</button>
|
||||
<button
|
||||
className="btnSquare"
|
||||
id="btnDeletePreset"
|
||||
style={{ marginLeft: '5px' }}
|
||||
onClick={async () => {
|
||||
await deletePreset()
|
||||
}}
|
||||
>
|
||||
Delete Preset
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ marginTop: '3px' }}>
|
||||
<SpMenu
|
||||
title="Custom Presets"
|
||||
items={Object.keys(store.data.custom_presets)}
|
||||
label_item="Select a Custom Preset"
|
||||
selected_index={Object.keys(
|
||||
store.data.custom_presets
|
||||
).indexOf(preset_tab_store.data.selected_preset_name)}
|
||||
onChange={(id: any, value: any) => {
|
||||
// console.log('onChange value: ', value)
|
||||
// store.updateProperty('subject', value.item)
|
||||
console.log('value:', value)
|
||||
preset_tab_store.data.selected_preset_name =
|
||||
value.item
|
||||
preset_tab_store.data.new_preset_name = value.item
|
||||
preset_tab_store.data.new_preset =
|
||||
store.data.custom_presets[value.item]
|
||||
}}
|
||||
></SpMenu>
|
||||
</div>
|
||||
<div>
|
||||
<sp-label id="lPresetName">
|
||||
{preset_tab_store.data.new_preset_name.trim()}
|
||||
</sp-label>
|
||||
</div>
|
||||
<div>
|
||||
<sp-textarea
|
||||
id="taPresetSettings"
|
||||
placeholder="{}"
|
||||
value={
|
||||
JSON.stringify(
|
||||
preset_tab_store.data.new_preset,
|
||||
undefined,
|
||||
7
|
||||
) || ''
|
||||
}
|
||||
onChange={(event: any) => {
|
||||
console.log('onChange:')
|
||||
updateTextAreaHeight(event.target)
|
||||
}}
|
||||
onInput={(event: any) => {
|
||||
console.log('onInput:')
|
||||
updateTextAreaHeight(event.target)
|
||||
}}
|
||||
></sp-textarea>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
render(): React.ReactNode {
|
||||
return this.renderTab()
|
||||
}
|
||||
}
|
||||
|
||||
const gridContainerNode = document.getElementById('PresetTabContainer')!
|
||||
const gridRoot = ReactDOM.createRoot(gridContainerNode)
|
||||
|
||||
gridRoot.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<div style={{ border: '2px solid #6d6c6c', padding: '3px' }}>
|
||||
<Collapsible
|
||||
defaultIsOpen={true}
|
||||
label={Locale('Custom Preset')}
|
||||
>
|
||||
<PresetTab></PresetTab>
|
||||
</Collapsible>
|
||||
</div>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
import { AStore } from '../main/astore'
|
||||
import { html_manip, io } from '../util/oldSystem'
|
||||
import { PresetTypeEnum } from '../util/ts/enum'
|
||||
// import { getNativeSDPresets } from '../util/ts/ui_ts'
|
||||
|
||||
export async function getLoadedPresets(ui_settings_obj: any) {
|
||||
let customPresets
|
||||
|
||||
customPresets = await mapCustomPresetsToLoaders(ui_settings_obj)
|
||||
console.log('customPresets: ', customPresets)
|
||||
let loadedPresets = {
|
||||
// ...getNativeSDPresets(),
|
||||
...customPresets,
|
||||
}
|
||||
return loadedPresets
|
||||
}
|
||||
export const store = new AStore({
|
||||
preset_name: '',
|
||||
custom_presets: [] as any,
|
||||
selected_preset_name: '',
|
||||
|
||||
sd_presets: [],
|
||||
sd_native_presets: [],
|
||||
|
||||
selected_sd_preset_name: '', // the selected sd preset in sd tab
|
||||
selected_sd_preset: {}, // the selected sd preset settings
|
||||
})
|
||||
|
||||
export const preset_tab_store = new AStore({
|
||||
new_preset_name: '', //for the textfield field and label
|
||||
new_preset: {} as any, // settings of the current preset tab preset
|
||||
selected_preset_name: '', // name of the selected in the menu
|
||||
selected_preset: {}, //settings of the selected preset in the menu
|
||||
})
|
||||
export async function getCustomPresetEntries(preset_folder_name: string) {
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
preset_folder_name
|
||||
)
|
||||
|
||||
const custom_preset_entries = await io.IOJson.getJsonEntries(
|
||||
custom_preset_entry
|
||||
)
|
||||
|
||||
return custom_preset_entries
|
||||
}
|
||||
export async function loadPresetSettingsFromFile(preset_file_name: string) {
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
'custom_preset'
|
||||
)
|
||||
let preset_settings = {}
|
||||
try {
|
||||
preset_settings = await io.IOJson.loadJsonFromFile(
|
||||
custom_preset_entry,
|
||||
preset_file_name
|
||||
)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
return preset_settings
|
||||
}
|
||||
|
||||
export async function getAllCustomPresetsSettings() {
|
||||
const custom_preset_entries = await getCustomPresetEntries('custom_preset')
|
||||
let custom_presets: any = {}
|
||||
for (const entry of custom_preset_entries) {
|
||||
const preset_name: string = entry.name.split('.json')[0]
|
||||
let preset_settings = await loadPresetSettingsFromFile(entry.name)
|
||||
|
||||
custom_presets[preset_name] = preset_settings
|
||||
}
|
||||
return custom_presets
|
||||
}
|
||||
|
||||
const updatePresetMenuEvent = new CustomEvent('updatePresetMenuEvent', {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
composed: false,
|
||||
})
|
||||
|
||||
export function loadPreset(ui_settings: any, preset: any) {
|
||||
console.log('preset:', preset)
|
||||
ui_settings.autoFillInSettings(preset)
|
||||
}
|
||||
export function loadCustomPreset(
|
||||
ui_settings_obj: any,
|
||||
custom_preset_settings: any
|
||||
) {
|
||||
loadPreset(ui_settings_obj, custom_preset_settings)
|
||||
}
|
||||
export async function mapCustomPresetsToLoaders(ui_settings_obj: any) {
|
||||
const name_to_settings_obj = await getAllCustomPresetsSettings()
|
||||
const preset_name_to_loader_obj: any = {}
|
||||
for (const [preset_name, preset_settings] of Object.entries(
|
||||
name_to_settings_obj
|
||||
)) {
|
||||
preset_name_to_loader_obj[preset_name] = () => {
|
||||
loadCustomPreset(ui_settings_obj, preset_settings)
|
||||
}
|
||||
}
|
||||
return preset_name_to_loader_obj
|
||||
}
|
||||
|
||||
export function getCustomPresetsNames(custom_presets: any) {
|
||||
let presets_names: any = []
|
||||
if (custom_presets) {
|
||||
presets_names = Object.keys(custom_presets)
|
||||
}
|
||||
return presets_names
|
||||
}
|
||||
|
||||
export function onLoadControlnetPreset() {}
|
||||
export function onLoadSDPreset() {}
|
||||
|
||||
//sd preset = {preset_name: settings_json}
|
||||
//sd_preset_loader(sd_preset)
|
||||
|
||||
//controlnet_preset = {preset_name: settings_json}
|
||||
|
||||
export { updatePresetMenuEvent }
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import { observer } from 'mobx-react'
|
||||
import { isScriptInstalled } from '../util/ts/api'
|
||||
import { api, general, io, psapi, selection } from '../util/oldSystem'
|
||||
|
|
@ -11,14 +11,12 @@ import {
|
|||
PenSvg,
|
||||
ScriptInstallComponent,
|
||||
} from '../util/elements'
|
||||
import {
|
||||
applyMaskFromBlackAndWhiteImage,
|
||||
selectionFromBlackAndWhiteImage,
|
||||
} from '../util/ts/selection'
|
||||
import { selectionFromBlackAndWhiteImage } from '../util/ts/selection'
|
||||
import { app } from 'photoshop'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import Locale from '../locale/locale'
|
||||
import { settings_tab_ts } from '../entry'
|
||||
// import { settings_tab_ts } from '../entry'
|
||||
import * as settings_tab_ts from '../settings/settings'
|
||||
import { SelectionInfoType } from '../util/ts/enum'
|
||||
declare let g_sd_url: string
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,652 @@
|
|||
import { control_net, main } from '../entry'
|
||||
import { AStore } from '../main/astore'
|
||||
import { script_store } from '../ultimate_sd_upscaler/scripts'
|
||||
import { ScriptMode } from '../ultimate_sd_upscaler/ultimate_sd_upscaler'
|
||||
import {
|
||||
dialog_box,
|
||||
general,
|
||||
html_manip,
|
||||
sampler_data,
|
||||
settings_tab,
|
||||
thumbnail,
|
||||
} from '../util/oldSystem'
|
||||
import { requestGet } from '../util/ts/api'
|
||||
|
||||
import { GenerationModeEnum, SelectionInfoType } from '../util/ts/enum'
|
||||
import {
|
||||
getVersionRequest,
|
||||
requestGetModels,
|
||||
requestGetSamplers,
|
||||
requestGetUpscalers,
|
||||
setInpaintMaskWeight,
|
||||
} from '../util/ts/sdapi'
|
||||
import { store as session_store } from '../session/session_store'
|
||||
import { setUnitData } from '../controlnet/entry'
|
||||
import { controlNetUnitData } from '../controlnet/store'
|
||||
import { presetToStore } from '../util/ts/io'
|
||||
import { refreshExtraUpscalers } from '../extra_page/extra_page'
|
||||
declare let g_models: any[]
|
||||
declare let g_automatic_status: any
|
||||
declare let g_sd_options_obj: any
|
||||
|
||||
declare let g_controlnet_max_models: number
|
||||
declare let g_sd_url: string
|
||||
|
||||
export const mode_config = [
|
||||
{
|
||||
name: 'txt2img',
|
||||
title: 'use this mode to generate images from text only',
|
||||
id: '',
|
||||
},
|
||||
{
|
||||
name: 'img2img',
|
||||
title: 'use this mode to generate variation of an image',
|
||||
id: '',
|
||||
},
|
||||
{
|
||||
name: 'inpaint',
|
||||
title: 'use this mode to generate variation of a small area of an image, while keeping the rest of the image intact',
|
||||
id: 'rbModeInpaint',
|
||||
},
|
||||
{
|
||||
name: 'outpaint',
|
||||
title: 'use this mode to (1) fill any missing area of an image,(2) expand an image',
|
||||
id: '',
|
||||
},
|
||||
]
|
||||
export const mask_content_config = [
|
||||
{
|
||||
name: 'fill',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
name: 'original',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
name: 'latent noise',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
name: 'latent nothing',
|
||||
value: 3,
|
||||
},
|
||||
]
|
||||
export enum SelectionModeEnum {
|
||||
Ratio = 'ratio',
|
||||
Precise = 'precise',
|
||||
Ignore = 'ignore',
|
||||
}
|
||||
export const selection_mode_config = [
|
||||
{
|
||||
name: 'ratio',
|
||||
value: 'ratio',
|
||||
title: '',
|
||||
},
|
||||
{
|
||||
name: 'precise',
|
||||
value: 'precise',
|
||||
title: 'use the selection area width and height to fill the width and height sliders',
|
||||
},
|
||||
{
|
||||
name: 'ignore',
|
||||
value: 'ignore',
|
||||
title: 'fill the width and height sliders manually',
|
||||
},
|
||||
]
|
||||
|
||||
export const store = new AStore({
|
||||
selected_model: '',
|
||||
is_lasso_mode: false,
|
||||
mode: GenerationModeEnum.Txt2Img,
|
||||
rb_mode: ScriptMode.Txt2Img,
|
||||
|
||||
batch_size: 1,
|
||||
batch_count: 1,
|
||||
steps: 20,
|
||||
width: 512,
|
||||
height: 512,
|
||||
ratio: 1.0,
|
||||
cfg: 7.0,
|
||||
b_width_height_link: true,
|
||||
denoising_strength: 0.7,
|
||||
hr_denoising_strength: 0.7,
|
||||
inpaint_full_res: false,
|
||||
enable_hr: false,
|
||||
sampler_name: 'Euler a',
|
||||
image_cfg_scale: 1.5,
|
||||
seed: '-1' as string,
|
||||
mask_blur: 0,
|
||||
mask_expansion: 0,
|
||||
inpaint_full_res_padding: 0,
|
||||
|
||||
hr_scale: 2.0,
|
||||
|
||||
hr_resize_x: 512,
|
||||
hr_resize_y: 512,
|
||||
hr_second_pass_steps: 0,
|
||||
restore_faces: false,
|
||||
inpainting_fill: mask_content_config[0].value,
|
||||
hr_upscaler: '',
|
||||
|
||||
selection_mode: selection_mode_config[0].value,
|
||||
})
|
||||
export const default_preset = {
|
||||
sd_tab_preset: {
|
||||
prompt: '',
|
||||
negative_prompt: '',
|
||||
// is_lasso_mode: false,
|
||||
|
||||
batch_size: 1,
|
||||
batch_count: 1,
|
||||
steps: 20,
|
||||
width: 512,
|
||||
height: 512,
|
||||
ratio: 1,
|
||||
cfg: 7,
|
||||
b_width_height_link: true,
|
||||
denoising_strength: 0.7,
|
||||
hr_denoising_strength: 0.7,
|
||||
// inpaint_full_res: false,
|
||||
// enable_hr: false,
|
||||
sampler_name: 'Euler a',
|
||||
image_cfg_scale: 1.5,
|
||||
seed: '-1',
|
||||
mask_blur: 0,
|
||||
mask_expansion: 0,
|
||||
inpaint_full_res_padding: 0,
|
||||
hr_scale: 2,
|
||||
hr_resize_x: 512,
|
||||
hr_resize_y: 512,
|
||||
hr_second_pass_steps: 0,
|
||||
// restore_faces: false,
|
||||
inpainting_fill: 0,
|
||||
hr_upscaler: '',
|
||||
selection_mode: 'ratio',
|
||||
},
|
||||
controlnet_tab_preset: [{}, {}, {}, {}, {}, {}, {}],
|
||||
}
|
||||
|
||||
export const helper_store = new AStore({
|
||||
b_show_sampler: false, //false when off, true when on,
|
||||
models: [] as any[],
|
||||
loras: [] as any[],
|
||||
sampler_list: [] as any[],
|
||||
hr_upscaler_list: [] as string[],
|
||||
previous_width: 512,
|
||||
previous_height: 512,
|
||||
})
|
||||
export async function refreshModels() {
|
||||
let b_result = false
|
||||
try {
|
||||
g_models = await requestGetModels()
|
||||
if (g_models.length > 0) {
|
||||
b_result = true
|
||||
}
|
||||
|
||||
helper_store.data.models = g_models
|
||||
|
||||
// for (let model of g_models) {
|
||||
// // console.log(model.title)//Log
|
||||
// // const menu_item_element = document.createElement('sp-menu-item')
|
||||
// // menu_item_element.className = 'mModelMenuItem'
|
||||
// menu_item_element.innerHTML = model.title
|
||||
// menu_item_element.dataset.model_hash = model.hash
|
||||
// menu_item_element.dataset.model_title = model.title
|
||||
// // document
|
||||
// // .getElementById('mModelsMenu')
|
||||
// // .appendChild(menu_item_element)
|
||||
// }
|
||||
} catch (e) {
|
||||
b_result = false
|
||||
console.warn(e)
|
||||
}
|
||||
return b_result
|
||||
}
|
||||
|
||||
async function promptForUpdate(header_message: any, long_message: any) {
|
||||
const shell = require('uxp').shell
|
||||
|
||||
;(async () => {
|
||||
const buttons = ['Cancel', 'OK']
|
||||
const r1 = await dialog_box.prompt(
|
||||
header_message,
|
||||
long_message,
|
||||
buttons
|
||||
// 'Please Update you Plugin. it will take about 10 seconds to update',
|
||||
// 'update from discord, update from github'[
|
||||
// ['Cancel', 'Discord', 'Github']
|
||||
// ('Cancel', 'OK')
|
||||
// ]
|
||||
)
|
||||
let url
|
||||
try {
|
||||
if (r1 === 'Cancel') {
|
||||
/* cancelled or No */
|
||||
console.log('cancel')
|
||||
} else if (r1 === 'Github') {
|
||||
url =
|
||||
'https://github.com/AbdullahAlfaraj/Auto-Photoshop-StableDiffusion-Plugin'
|
||||
// await py_re.openUrlRequest(url)
|
||||
} else if (r1 === 'Discord') {
|
||||
console.log('Discord')
|
||||
// url = 'https://discord.gg/3mVEtrddXJ'
|
||||
// url = 'https://discord.gg/YkUJXYWK3c'
|
||||
// await py_re.openUrlRequest(url)
|
||||
} else if (r1 === 'Ok') {
|
||||
}
|
||||
// console.log('url: ', url)
|
||||
} catch (e) {
|
||||
console.warn(e, url)
|
||||
}
|
||||
})()
|
||||
}
|
||||
export async function updateClickEventHandler(current_version: string) {
|
||||
try {
|
||||
const online_data = await general.requestOnlineData()
|
||||
const b_need_update = general.compareVersions(
|
||||
current_version,
|
||||
online_data.new_version
|
||||
)
|
||||
|
||||
let header_message = "You're Plugin is up to date."
|
||||
let long_message = ''
|
||||
if (b_need_update) {
|
||||
header_message = `New Version is Available (${online_data.new_version})`
|
||||
long_message = online_data.update_message
|
||||
}
|
||||
|
||||
await promptForUpdate(header_message, long_message)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function tempDisableElement(element: any, time: number) {
|
||||
element.classList.add('disableBtn')
|
||||
element.disabled = true
|
||||
// element.style.opacity = '0.65'
|
||||
// element.style.cursor = 'not-allowed'
|
||||
setTimeout(function () {
|
||||
element.disabled = false
|
||||
element.classList.remove('disableBtn')
|
||||
// element.style.opacity = '1.0'
|
||||
// element.style.cursor = 'default'
|
||||
}, time)
|
||||
}
|
||||
|
||||
async function updateVersionUI() {
|
||||
let bStatus = false
|
||||
try {
|
||||
const version = await getVersionRequest()
|
||||
document.getElementById('lVersionNumber')!.textContent = version
|
||||
if (version !== 'v0.0.0') {
|
||||
bStatus = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
document.getElementById('lVersionNumber')!.textContent = 'v0.0.0'
|
||||
bStatus = false
|
||||
}
|
||||
return bStatus
|
||||
}
|
||||
|
||||
//REFACTOR: move to generation_settings.js
|
||||
export async function initSamplers() {
|
||||
let bStatus = false
|
||||
try {
|
||||
// let sampler_group = document.getElementById('sampler_group')!
|
||||
// sampler_group.innerHTML = ''
|
||||
|
||||
let samplers = await requestGetSamplers()
|
||||
if (!samplers) {
|
||||
//if we failed to get the sampler list from auto1111, use the list stored in sampler.js
|
||||
samplers = sampler_data.samplers
|
||||
}
|
||||
helper_store.data.sampler_list = samplers
|
||||
|
||||
// for (let sampler of samplers) {
|
||||
// // console.log(sampler)//Log
|
||||
// // sampler.name
|
||||
// // <sp-radio class="rbSampler" value="Euler">Euler</sp-radio>
|
||||
// // const rbSampler = document.createElement('sp-radio')
|
||||
// // rbSampler.innerHTML = sampler.name
|
||||
// // rbSampler.setAttribute('class', 'rbSampler')
|
||||
// // rbSampler.setAttribute('value', sampler.name)
|
||||
// // sampler_group.appendChild(rbSampler)
|
||||
// //add click event on radio button for Sampler radio button, so that when a button is clicked it change g_sd_sampler globally
|
||||
// }
|
||||
// document
|
||||
// .getElementsByClassName('rbSampler')[0]
|
||||
// .setAttribute('checked', '')
|
||||
if (samplers.length > 0) {
|
||||
bStatus = true
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
return bStatus
|
||||
}
|
||||
|
||||
export async function refreshUI() {
|
||||
try {
|
||||
const b_proxy_server_status = await updateVersionUI()
|
||||
if (b_proxy_server_status) {
|
||||
html_manip.setProxyServerStatus('connected', 'disconnected')
|
||||
// g_automatic_status = Enum.AutomaticStatusEnum['RunningWithApi']
|
||||
} else {
|
||||
html_manip.setProxyServerStatus('disconnected', 'connected')
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
g_automatic_status = await checkAutoStatus()
|
||||
//@ts-ignore
|
||||
await displayNotification(g_automatic_status)
|
||||
|
||||
const bSamplersStatus = await initSamplers()
|
||||
|
||||
await refreshModels()
|
||||
helper_store.data.loras = await requestLoraModels()
|
||||
await refreshExtraUpscalers()
|
||||
|
||||
await setInpaintMaskWeight(1.0) //set the inpaint conditional mask to 1 when the on plugin start
|
||||
|
||||
//get the latest options
|
||||
|
||||
await g_sd_options_obj.getOptions()
|
||||
//get the selected model
|
||||
store.data.selected_model = g_sd_options_obj.getCurrentModel()
|
||||
//update the ui with that model title
|
||||
|
||||
// const current_model_hash =
|
||||
// html_manip.getModelHashByTitle(current_model_title)
|
||||
// html_manip.autoFillInModel(current_model_hash)
|
||||
|
||||
//fetch the inpaint mask weight from sd webui and update the slider with it.
|
||||
const inpainting_mask_weight =
|
||||
await g_sd_options_obj.getInpaintingMaskWeight()
|
||||
console.log('inpainting_mask_weight: ', inpainting_mask_weight)
|
||||
html_manip.autoFillInInpaintMaskWeight(inpainting_mask_weight)
|
||||
|
||||
//init ControlNet Tab
|
||||
|
||||
helper_store.data.hr_upscaler_list = await requestGetHiResUpscalers()
|
||||
|
||||
g_controlnet_max_models = await control_net.requestControlNetMaxUnits()
|
||||
await control_net.initializeControlNetTab(g_controlnet_max_models)
|
||||
await main.populateVAE()
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
export async function requestGetHiResUpscalers(): Promise<string[]> {
|
||||
try {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/upscalers`
|
||||
let upscalers = await requestGet(full_url)
|
||||
return [
|
||||
'Latent',
|
||||
'Latent (antialiased)',
|
||||
'Latent (bicubic)',
|
||||
'Latent (bicubic antialiased)',
|
||||
'Latent (nearest)',
|
||||
'Latent (nearest-exact)',
|
||||
...upscalers.map((upscaler: any) => upscaler.name),
|
||||
]
|
||||
} catch (e) {
|
||||
console.warn('requestGetHiResUpscalers:', e)
|
||||
return [
|
||||
'Latent',
|
||||
'Latent (antialiased)',
|
||||
'Latent (bicubic)',
|
||||
'Latent (bicubic antialiased)',
|
||||
'Latent (nearest)',
|
||||
'Latent (nearest-exact)',
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
export async function requestLoraModels() {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/loras`
|
||||
const lora_models = (await requestGet(full_url)) ?? []
|
||||
return lora_models
|
||||
}
|
||||
|
||||
export function getLoraModelPrompt(lora_model_name: string) {
|
||||
return `<lora:${lora_model_name}:1>`
|
||||
}
|
||||
|
||||
//add click event on radio button mode, so that when a button is clicked it change g_sd_mode globally
|
||||
//REFACTOR: move to events.js
|
||||
declare let g_sd_mode: string
|
||||
export async function onModeChange(new_mode: ScriptMode) {
|
||||
try {
|
||||
g_sd_mode = new_mode
|
||||
script_store.setMode(new_mode)
|
||||
store.data.rb_mode = new_mode
|
||||
store.data.mode = store.data.rb_mode as unknown as GenerationModeEnum
|
||||
// console.log(`You clicked: ${g_sd_mode}`)
|
||||
|
||||
//@ts-ignore
|
||||
await postModeSelection() // do things after selection
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function viewMaskExpansion() {
|
||||
if (session_store.data.expanded_mask) {
|
||||
const mask_src = general.base64ToBase64Url(
|
||||
session_store.data.expanded_mask
|
||||
)
|
||||
html_manip.setInitImageMaskSrc(mask_src)
|
||||
} else {
|
||||
console.log(
|
||||
'the mask has not been expanded, g_generation_session.base64maskExpansionImage is empty'
|
||||
)
|
||||
}
|
||||
}
|
||||
function viewDrawnMask() {
|
||||
//this is the generated mask or user drawn mask, but it's not the mask after expansion
|
||||
if (session_store.data.mask) {
|
||||
const mask_src = general.base64ToBase64Url(session_store.data.mask)
|
||||
html_manip.setInitImageMaskSrc(mask_src)
|
||||
} else {
|
||||
console.log('no mask is available')
|
||||
}
|
||||
}
|
||||
export function initInitMaskElement() {
|
||||
//make init mask image use the thumbnail class with buttons
|
||||
const mask_image_html = html_manip.getInitImageMaskElement()
|
||||
const mask_parent_element = mask_image_html.parentElement
|
||||
|
||||
const thumbnail_container = thumbnail.Thumbnail.wrapImgInContainer(
|
||||
mask_image_html,
|
||||
'viewer-image-container'
|
||||
)
|
||||
mask_parent_element.appendChild(thumbnail_container)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
thumbnail_container,
|
||||
'svg_sp_btn',
|
||||
'view original mask',
|
||||
|
||||
viewDrawnMask,
|
||||
null
|
||||
)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
thumbnail_container,
|
||||
'svg_sp_btn_expand',
|
||||
'view modified mask',
|
||||
|
||||
viewMaskExpansion,
|
||||
null
|
||||
)
|
||||
// populateLoraModelMenu() // no need for await
|
||||
}
|
||||
|
||||
function scaleToRatio(
|
||||
newValue1: number,
|
||||
oldValue1: number,
|
||||
newValue2: undefined, //get ignored
|
||||
oldValue2: number,
|
||||
maxValue: number,
|
||||
minValue: number
|
||||
) {
|
||||
const ratio = newValue1 / oldValue1
|
||||
let finalNewValue2 = Math.max(
|
||||
minValue,
|
||||
Math.min(maxValue, oldValue2 * ratio)
|
||||
)
|
||||
let finalNewValue1 = newValue1
|
||||
if (finalNewValue2 === maxValue || finalNewValue2 === minValue) {
|
||||
finalNewValue1 = oldValue1 * (finalNewValue2 / oldValue2)
|
||||
}
|
||||
return [finalNewValue1, finalNewValue2]
|
||||
}
|
||||
|
||||
export function widthSliderOnChangeEventHandler(
|
||||
new_value: number,
|
||||
min_value: number,
|
||||
max_value: number
|
||||
) {
|
||||
try {
|
||||
const b_link = store.data.b_width_height_link
|
||||
let final_width = new_value
|
||||
let final_height
|
||||
if (b_link) {
|
||||
;[final_width, final_height] = scaleToRatio(
|
||||
new_value,
|
||||
helper_store.data.previous_width,
|
||||
undefined,
|
||||
store.data.height,
|
||||
max_value,
|
||||
min_value
|
||||
)
|
||||
|
||||
store.data.width = final_width
|
||||
store.data.height = final_height
|
||||
|
||||
helper_store.data.previous_width = store.data.width
|
||||
helper_store.data.previous_height = store.data.height
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function heightSliderOnChangeEventHandler(
|
||||
new_value: number,
|
||||
min_value: number,
|
||||
max_value: number
|
||||
) {
|
||||
try {
|
||||
let new_height = new_value
|
||||
const b_link = store.data.b_width_height_link
|
||||
let final_height = new_height
|
||||
let final_width
|
||||
if (b_link) {
|
||||
;[final_height, final_width] = scaleToRatio(
|
||||
new_height,
|
||||
helper_store.data.previous_height,
|
||||
undefined,
|
||||
store.data.width,
|
||||
max_value,
|
||||
min_value
|
||||
)
|
||||
|
||||
store.data.width = final_width
|
||||
store.data.height = final_height
|
||||
|
||||
helper_store.data.previous_width = store.data.width
|
||||
helper_store.data.previous_height = store.data.height
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
export function calcLinkedValue(new_value: number) {}
|
||||
export async function initPlugin() {
|
||||
try {
|
||||
//*) load plugin settings
|
||||
//*) load horde settings
|
||||
//*)
|
||||
//*) initialize the samplers
|
||||
//*)
|
||||
await settings_tab.loadSettings()
|
||||
// await horde_native.HordeSettings.loadSettings()
|
||||
const bSamplersStatus = await initSamplers() //initialize the sampler
|
||||
await setInpaintMaskWeight(1.0) //set the inpaint conditional mask to 1 when the on plugin start
|
||||
await refreshUI()
|
||||
|
||||
//@ts-ignore
|
||||
await loadPromptShortcut()
|
||||
//@ts-ignore
|
||||
await refreshPromptMenu()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
export function scaleFromToLabel(width: number, height: number, scale: number) {
|
||||
const hr_width = Math.ceil(width * scale)
|
||||
const hr_height = Math.ceil(height * scale)
|
||||
return `${width}x${height} -> ${hr_width}x${hr_height}`
|
||||
}
|
||||
|
||||
export function onWidthSliderInput(new_value: number) {
|
||||
try {
|
||||
store.data.width = new_value
|
||||
|
||||
store.data.ratio = calcRatio(
|
||||
new_value,
|
||||
store.data.height,
|
||||
session_store.data.current_selection_info
|
||||
)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function onHeightSliderInput(new_value: number) {
|
||||
try {
|
||||
store.data.height = new_value
|
||||
store.data.ratio = calcRatio(
|
||||
store.data.width,
|
||||
new_value,
|
||||
session_store.data.current_selection_info
|
||||
)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function calcRatio(
|
||||
width: number,
|
||||
height: number,
|
||||
selectionInfo: SelectionInfoType | undefined
|
||||
) {
|
||||
let ratio = 1
|
||||
|
||||
if (selectionInfo) {
|
||||
ratio = (width * height) / (selectionInfo.width * selectionInfo.height)
|
||||
}
|
||||
return ratio
|
||||
}
|
||||
|
||||
export function loadPresetSettings(preset: any) {
|
||||
if (preset?.sd_tab_preset) {
|
||||
presetToStore(preset?.sd_tab_preset, store)
|
||||
}
|
||||
if (preset?.controlnet_tab_preset) {
|
||||
preset?.controlnet_tab_preset.forEach(
|
||||
(unit: controlNetUnitData, index: number) => {
|
||||
try {
|
||||
setUnitData(unit, index)
|
||||
} catch (e) {
|
||||
console.log('error at unit index: ', index)
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
)
|
||||
// io_ts.presetToStore(preset?.controlnet_tab_preset, store)
|
||||
}
|
||||
}
|
||||
|
|
@ -3,13 +3,24 @@ import ReactDOM from 'react-dom/client'
|
|||
|
||||
import { observer } from 'mobx-react'
|
||||
|
||||
import { sd_tab_ts, session_ts, viewer } from '../entry'
|
||||
// import { sd_tab_ts, session_ts, viewer } from '../entry'
|
||||
import { store as session_store } from '../session/session_store'
|
||||
import { Session } from '../session/session'
|
||||
// import * as sd_tab_ts from '../sd_tab/sd_tab'
|
||||
import { store as sd_tab_store } from '../sd_tab/util'
|
||||
import * as viewer from '../viewer/viewer'
|
||||
|
||||
import './style/generate.css'
|
||||
import { io, note, psapi, selection } from '../util/oldSystem'
|
||||
import { GenerationModeEnum } from '../util/ts/enum'
|
||||
import { initializeBackground } from '../util/ts/document'
|
||||
import Locale from '../locale/locale'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import {
|
||||
store as viewer_store,
|
||||
mask_store as viewer_mask_store,
|
||||
// init_store as viewer_init_store,
|
||||
} from '../viewer/viewer_util'
|
||||
declare let g_automatic_status: any
|
||||
declare let g_current_batch_index: number
|
||||
//example: take 'oI' in 'LassoInpaint' and replace it with 'o I' thus creating 'Lasso Inpaint'
|
||||
|
|
@ -20,7 +31,7 @@ const modeDisplayNames = Object.fromEntries(
|
|||
])
|
||||
)
|
||||
|
||||
const GenerateButtons = observer(() => {
|
||||
export const GenerateButtons = observer(() => {
|
||||
return (
|
||||
<div>
|
||||
<button
|
||||
|
|
@ -28,28 +39,26 @@ const GenerateButtons = observer(() => {
|
|||
className="btnSquare generateButtonMargin generateColor"
|
||||
onClick={handleGenerateBatch}
|
||||
style={{
|
||||
display: session_ts.store.data.can_generate
|
||||
? void 0
|
||||
: 'none',
|
||||
display: session_store.data.can_generate ? void 0 : 'none',
|
||||
}}
|
||||
>
|
||||
Generate {modeDisplayNames[sd_tab_ts.store.data.mode]}
|
||||
Generate {modeDisplayNames[sd_tab_store.data.mode]}
|
||||
</button>
|
||||
{session_ts.store.data.can_generate ? (
|
||||
{session_store.data.can_generate ? (
|
||||
<button
|
||||
onClick={handleGenerateMoreBatch}
|
||||
disabled={
|
||||
session_ts.store.data.can_generate_more ? void 0 : true
|
||||
session_store.data.can_generate_more ? void 0 : true
|
||||
}
|
||||
id="btnNewGenerateMore"
|
||||
className={
|
||||
'btnSquare generateButtonMargin generateMoreColor' +
|
||||
(session_ts.store.data.can_generate_more
|
||||
(session_store.data.can_generate_more
|
||||
? ''
|
||||
: 'disableBtn')
|
||||
}
|
||||
style={{
|
||||
display: session_ts.store.data.can_generate_more
|
||||
display: session_store.data.can_generate_more
|
||||
? 'inline-block'
|
||||
: 'none',
|
||||
}}
|
||||
|
|
@ -59,7 +68,7 @@ const GenerateButtons = observer(() => {
|
|||
) : (
|
||||
void 0
|
||||
)}
|
||||
{!session_ts.store.data.can_generate ? (
|
||||
{!session_store.data.can_generate ? (
|
||||
<button
|
||||
onClick={handleInterrupt}
|
||||
id="btnNewInterrupt"
|
||||
|
|
@ -80,15 +89,14 @@ const ToolbarGenerateButtons = observer(() => {
|
|||
height: '30px',
|
||||
marginBottom: '3px',
|
||||
}
|
||||
const generate_display = session_ts.store.data.can_generate
|
||||
const generate_display = session_store.data.can_generate
|
||||
? 'inline-flex'
|
||||
: 'none'
|
||||
const generate_more_display =
|
||||
session_ts.store.data.can_generate &&
|
||||
session_ts.store.data.can_generate_more
|
||||
session_store.data.can_generate && session_store.data.can_generate_more
|
||||
? 'inline-flex'
|
||||
: 'none'
|
||||
const interrupt_display = session_ts.store.data.can_generate
|
||||
const interrupt_display = session_store.data.can_generate
|
||||
? 'none'
|
||||
: 'inline-flex'
|
||||
return (
|
||||
|
|
@ -137,20 +145,18 @@ const canStartSession = async () => {
|
|||
const selection_info = await psapi.getSelectionInfoExe()
|
||||
|
||||
if (selection_info) {
|
||||
session_ts.Session.endSession()
|
||||
Session.endSession()
|
||||
|
||||
can_start_session = true
|
||||
} else {
|
||||
can_start_session = await note.Notification.inactiveSelectionArea(
|
||||
session_ts.store.data.is_active,
|
||||
session_store.data.is_active,
|
||||
'Reuse Selection'
|
||||
)
|
||||
if (can_start_session) {
|
||||
//end current session and start a new one
|
||||
session_ts.Session.endSession()
|
||||
await psapi.reSelectMarqueeExe(
|
||||
session_ts.store.data.selectionInfo
|
||||
)
|
||||
Session.endSession()
|
||||
await psapi.reSelectMarqueeExe(session_store.data.selectionInfo)
|
||||
}
|
||||
}
|
||||
//@ts-ignore
|
||||
|
|
@ -166,7 +172,7 @@ const canStartSession = async () => {
|
|||
|
||||
const resetBatch = () => {
|
||||
g_current_batch_index = -1
|
||||
session_ts.store.data.is_interrupted = false
|
||||
session_store.data.is_interrupted = false
|
||||
}
|
||||
// declare let g_sd_mode: any
|
||||
const handleGenerate = async () => {
|
||||
|
|
@ -175,15 +181,16 @@ const handleGenerate = async () => {
|
|||
await selection.selectionToChannel('mask')
|
||||
|
||||
await initializeBackground() //fix background if there is a need
|
||||
console.log('mode: ', sd_tab_ts.store.data.mode)
|
||||
console.log('mode: ', sd_tab_store.data.mode)
|
||||
try {
|
||||
if (!(await canStartSession())) {
|
||||
return void 0
|
||||
}
|
||||
var { output_images, response_json } =
|
||||
await session_ts.Session.generate(sd_tab_ts.store.data.mode)
|
||||
var { output_images, response_json } = await Session.generate(
|
||||
sd_tab_store.data.mode
|
||||
)
|
||||
|
||||
if (session_ts.store.data.is_interrupted) {
|
||||
if (session_store.data.is_interrupted) {
|
||||
return void 0
|
||||
}
|
||||
|
||||
|
|
@ -193,26 +200,23 @@ const handleGenerate = async () => {
|
|||
thumbnail_list.push(thumbnail)
|
||||
}
|
||||
|
||||
viewer.store.updateProperty('thumbnails', thumbnail_list)
|
||||
viewer.store.updateProperty('images', output_images)
|
||||
viewer_store.updateProperty('thumbnails', thumbnail_list)
|
||||
viewer_store.updateProperty('images', output_images)
|
||||
if (
|
||||
[
|
||||
GenerationModeEnum.Inpaint,
|
||||
GenerationModeEnum.LassoInpaint,
|
||||
GenerationModeEnum.Outpaint,
|
||||
].includes(session_ts.store.data.mode)
|
||||
].includes(session_store.data.mode)
|
||||
) {
|
||||
viewer.mask_store.updateProperty(
|
||||
viewer_mask_store.updateProperty(
|
||||
'output_images_masks',
|
||||
Array(output_images.length).fill(
|
||||
session_ts.store.data.expanded_mask
|
||||
session_store.data.expanded_mask
|
||||
)
|
||||
)
|
||||
}
|
||||
console.log(
|
||||
'session_ts.store.toJsFunc(): ',
|
||||
session_ts.store.toJsFunc()
|
||||
)
|
||||
console.log('session_store.toJsFunc(): ', session_store.toJsFunc())
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
console.warn('output_images: ', output_images)
|
||||
|
|
@ -222,10 +226,9 @@ const handleGenerate = async () => {
|
|||
|
||||
const handleGenerateMore = async () => {
|
||||
try {
|
||||
var { output_images, response_json } =
|
||||
await session_ts.Session.generateMore()
|
||||
var { output_images, response_json } = await Session.generateMore()
|
||||
|
||||
if (session_ts.store.data.is_interrupted) {
|
||||
if (session_store.data.is_interrupted) {
|
||||
return void 0
|
||||
}
|
||||
|
||||
|
|
@ -234,13 +237,13 @@ const handleGenerateMore = async () => {
|
|||
const thumbnail = await io.createThumbnail(base64, 300)
|
||||
thumbnail_list.push(thumbnail)
|
||||
}
|
||||
viewer.store.data.thumbnails = [
|
||||
...viewer.store.data.thumbnails,
|
||||
viewer_store.data.thumbnails = [
|
||||
...viewer_store.data.thumbnails,
|
||||
...thumbnail_list,
|
||||
]
|
||||
|
||||
viewer.store.data.images = [
|
||||
...viewer.store.data.images,
|
||||
viewer_store.data.images = [
|
||||
...viewer_store.data.images,
|
||||
...output_images,
|
||||
]
|
||||
|
||||
|
|
@ -249,19 +252,19 @@ const handleGenerateMore = async () => {
|
|||
GenerationModeEnum.Inpaint,
|
||||
GenerationModeEnum.LassoInpaint,
|
||||
GenerationModeEnum.Outpaint,
|
||||
].includes(session_ts.store.data.mode)
|
||||
].includes(session_store.data.mode)
|
||||
) {
|
||||
viewer.mask_store.updatePropertyArray(
|
||||
viewer_mask_store.updatePropertyArray(
|
||||
'output_images_masks',
|
||||
Array(output_images.length).fill(
|
||||
session_ts.store.data.expanded_mask
|
||||
session_store.data.expanded_mask
|
||||
)
|
||||
)
|
||||
}
|
||||
// viewer.store.updateProperty('images', output_images)
|
||||
// console.log(
|
||||
// 'session_ts.store.toJsFunc(): ',
|
||||
// session_ts.store.toJsFunc()
|
||||
// 'session_store.toJsFunc(): ',
|
||||
// session_store.toJsFunc()
|
||||
// )
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
|
|
@ -272,15 +275,14 @@ const handleGenerateMore = async () => {
|
|||
|
||||
const handleGenerateBatch = async () => {
|
||||
try {
|
||||
const numberOfBatchCount: number = parseInt(
|
||||
//@ts-ignore
|
||||
document.querySelector('#tiNumberOfBatchCount').value
|
||||
const numberOfBatchCount: number = Math.floor(
|
||||
sd_tab_store.data.batch_count
|
||||
)
|
||||
|
||||
await handleGenerate() //first generation is always use handleGenerate
|
||||
for (
|
||||
let i = 1;
|
||||
i < numberOfBatchCount && !session_ts.store.data.is_interrupted;
|
||||
i < numberOfBatchCount && !session_store.data.is_interrupted;
|
||||
i++
|
||||
) {
|
||||
// if (g_batch_count_interrupt_status === true) {
|
||||
|
|
@ -298,15 +300,14 @@ const handleGenerateBatch = async () => {
|
|||
}
|
||||
const handleGenerateMoreBatch = async () => {
|
||||
try {
|
||||
const numberOfBatchCount: number = parseInt(
|
||||
//@ts-ignore
|
||||
document.querySelector('#tiNumberOfBatchCount').value
|
||||
const numberOfBatchCount: number = Math.floor(
|
||||
sd_tab_store.data.batch_count
|
||||
)
|
||||
|
||||
// await handleGenerateMore() //first generation is always use handleGenerate
|
||||
for (
|
||||
let i = 0;
|
||||
i < numberOfBatchCount && !session_ts.store.data.is_interrupted;
|
||||
i < numberOfBatchCount && !session_store.data.is_interrupted;
|
||||
i++
|
||||
) {
|
||||
// if (g_batch_count_interrupt_status === true) {
|
||||
|
|
@ -325,35 +326,12 @@ const handleGenerateMoreBatch = async () => {
|
|||
}
|
||||
const handleInterrupt = async () => {
|
||||
try {
|
||||
// debugger
|
||||
await session_ts.Session.interrupt()
|
||||
await Session.interrupt()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.getElementById('generateButtonsContainer')!
|
||||
const root = ReactDOM.createRoot(container)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<GenerateButtons></GenerateButtons>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
const extraContainer = document.getElementById('extraGenerateButtonsContainer')!
|
||||
const extraRoot = ReactDOM.createRoot(extraContainer)
|
||||
|
||||
extraRoot.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<GenerateButtons></GenerateButtons>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
const toolBarButtonsContainer = document.getElementById(
|
||||
'toolbarGenerateButtonsContainer'
|
||||
)!
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import { control_net, scripts, session_ts } from '../entry'
|
||||
// import { control_net, scripts, session_ts } from '../entry'
|
||||
// import * as session_ts from '../session/session'
|
||||
import * as scripts from '../ultimate_sd_upscaler/scripts'
|
||||
import * as control_net from '../controlnet/entry'
|
||||
import { store as session_store } from '../session/session_store'
|
||||
|
||||
import {
|
||||
html_manip,
|
||||
|
|
@ -16,13 +20,15 @@ import {
|
|||
getModuleDetail,
|
||||
mapPluginSettingsToControlNet,
|
||||
} from '../controlnet/entry'
|
||||
|
||||
import { store as extra_page_store } from '../extra_page/extra_page'
|
||||
const executeAsModal = core.executeAsModal
|
||||
|
||||
declare let g_inpaint_mask_layer: any
|
||||
declare let g_sd_url: any
|
||||
declare let g_controlnet_max_models: any
|
||||
declare let g_generation_session: any
|
||||
declare let g_last_seed: any
|
||||
|
||||
interface SessionData {
|
||||
init_image?: string
|
||||
mask?: string
|
||||
|
|
@ -48,7 +54,7 @@ async function saveOutputImagesToDrive(images_info: any, settings: any) {
|
|||
) //save the settings
|
||||
index += 1
|
||||
}
|
||||
g_last_seed =
|
||||
session_store.data.last_seed =
|
||||
images_info?.length > 0 ? images_info[0]?.auto_metadata?.Seed : '-1'
|
||||
return base64OutputImages
|
||||
}
|
||||
|
|
@ -200,7 +206,7 @@ export class Txt2ImgMode extends Mode {
|
|||
//update the mask in controlNet tab
|
||||
const numOfImages = json['images'].length
|
||||
let numberOfAnnotations =
|
||||
numOfImages - session_ts.store.data.ui_settings.batch_size
|
||||
numOfImages - session_store.data.ui_settings.batch_size
|
||||
if (numberOfAnnotations < 0) numberOfAnnotations = 0
|
||||
|
||||
const base64_mask = json['images'].slice(
|
||||
|
|
@ -243,13 +249,13 @@ export class Txt2ImgMode extends Mode {
|
|||
|
||||
if (b_enable_control_net) {
|
||||
//use control net
|
||||
if (session_ts.store.data.generation_number === 1) {
|
||||
session_ts.store.data.controlnet_input_image =
|
||||
if (session_store.data.generation_number === 1) {
|
||||
session_store.data.controlnet_input_image =
|
||||
await io.getImg2ImgInitImage()
|
||||
}
|
||||
// console.log(
|
||||
// 'session_ts.store.data.controlnet_input_image: ',
|
||||
// session_ts.store.data.controlnet_input_image
|
||||
// 'session_store.data.controlnet_input_image: ',
|
||||
// session_store.data.controlnet_input_image
|
||||
// )
|
||||
|
||||
response_json = await this.requestControlNetTxt2Img(settings)
|
||||
|
|
@ -343,7 +349,7 @@ export class Img2ImgMode extends Mode {
|
|||
//update the mask in controlNet tab
|
||||
const numOfImages = json['images'].length
|
||||
let numberOfAnnotations =
|
||||
numOfImages - session_ts.store.data.ui_settings.batch_size
|
||||
numOfImages - session_store.data.ui_settings.batch_size
|
||||
if (numberOfAnnotations < 0) numberOfAnnotations = 0
|
||||
|
||||
// To fix a bug: when Ultimate SD Upscale is active and running, the detection maps won’t be retrieved.
|
||||
|
|
@ -535,39 +541,35 @@ export class UpscaleMode extends Img2ImgMode {
|
|||
|
||||
let payload: any = {}
|
||||
try {
|
||||
const upscaling_resize = html_manip.getUpscaleSize()
|
||||
const gfpgan_visibility = html_manip.getGFPGANVisibility()
|
||||
const codeformer_visibility = html_manip.getCodeFormerVisibility()
|
||||
const codeformer_weight = html_manip.getCodeFormerWeight()
|
||||
// const selection_info = await psapi.getSelectionInfoExe()
|
||||
const selection_info = session_data.selectionInfo
|
||||
const upscaling_resize = extra_page_store.data.upscaling_resize
|
||||
const width = selection_info.width * upscaling_resize
|
||||
const height = selection_info.height * upscaling_resize
|
||||
|
||||
//resize_mode = 0 means "resize to upscaling_resize"
|
||||
//resize_mode = 1 means "resize to width and height"
|
||||
payload['resize_mode'] = 0
|
||||
payload['show_extras_results'] = 0
|
||||
payload['gfpgan_visibility'] = gfpgan_visibility
|
||||
payload['codeformer_visibility'] = codeformer_visibility
|
||||
payload['codeformer_weight'] = codeformer_weight
|
||||
payload['resize_mode'] = extra_page_store.data.resize_mode
|
||||
payload['show_extras_results'] =
|
||||
extra_page_store.data.show_extras_results
|
||||
payload['gfpgan_visibility'] =
|
||||
extra_page_store.data.gfpgan_visibility
|
||||
payload['codeformer_visibility'] =
|
||||
extra_page_store.data.codeformer_visibility
|
||||
payload['codeformer_weight'] =
|
||||
extra_page_store.data.codeformer_weight
|
||||
payload['upscaling_resize'] = upscaling_resize
|
||||
payload['upscaling_resize_w'] = width
|
||||
payload['upscaling_resize_h'] = height
|
||||
payload['upscaling_crop'] = true
|
||||
const upscaler1 =
|
||||
//@ts-ignore
|
||||
document.querySelector('#hrModelsMenuUpscale1').value
|
||||
payload['upscaling_crop'] = extra_page_store.data.upscaling_crop
|
||||
|
||||
const upscaler1 = extra_page_store.data.upscaler_1
|
||||
const upscaler2 = extra_page_store.data.upscaler_2
|
||||
payload['upscaler_1'] = upscaler1 ? upscaler1 : 'None'
|
||||
payload['upscaler_2'] = upscaler2 ? upscaler2 : 'None'
|
||||
|
||||
payload['upscaler_1'] = upscaler1 === undefined ? 'None' : upscaler1
|
||||
const upscaler2 =
|
||||
//@ts-ignore
|
||||
document.querySelector('#hrModelsMenuUpscale2').value
|
||||
payload['upscaler_2'] = upscaler2 === undefined ? 'None' : upscaler2
|
||||
const extras_upscaler_2_visibility =
|
||||
html_manip.getUpscaler2Visibility()
|
||||
payload['extras_upscaler_2_visibility'] =
|
||||
extras_upscaler_2_visibility
|
||||
payload['upscale_first'] = false
|
||||
extra_page_store.data.extras_upscaler_2_visibility
|
||||
payload['upscale_first'] = extra_page_store.data.upscale_first
|
||||
|
||||
payload['image'] = session_data.init_image
|
||||
} catch (e) {
|
||||
|
|
@ -575,6 +577,7 @@ export class UpscaleMode extends Img2ImgMode {
|
|||
}
|
||||
return payload
|
||||
}
|
||||
|
||||
static async generate(settings: any): Promise<{
|
||||
output_images: any
|
||||
response_json: any
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@ import { reaction } from 'mobx'
|
|||
import { AStore } from '../main/astore'
|
||||
import { io, layer_util } from '../util/oldSystem'
|
||||
import Locale from '../locale/locale'
|
||||
import { session_ts } from '../entry'
|
||||
import { store as session_store } from '../session/session_store'
|
||||
// import { session_ts } from '../entry'
|
||||
// import * as session_ts from '../session/session'
|
||||
import { app, core } from 'photoshop'
|
||||
|
||||
const executeAsModal = core.executeAsModal
|
||||
|
|
@ -16,6 +18,7 @@ export const store = new AStore({
|
|||
progress_label: Locale('Progress..'),
|
||||
can_update: true,
|
||||
can_update_progress_layer: true,
|
||||
live_progress_image: true,
|
||||
})
|
||||
declare let g_sd_url: string
|
||||
|
||||
|
|
@ -31,7 +34,7 @@ async function updateProgressImage(progress_base64: string) {
|
|||
await Progress.deleteProgressLayer() // delete the old progress layer
|
||||
|
||||
//update the progress image
|
||||
const selection_info = await session_ts.store.data.selectionInfo
|
||||
const selection_info = await session_store.data.selectionInfo
|
||||
|
||||
const b_exsit = layer_util.Layer.doesLayerExist(
|
||||
store.data.progress_layer
|
||||
|
|
@ -70,12 +73,12 @@ reaction(
|
|||
const { width, height } = await io.getImageSize(progress_image)
|
||||
store.data.progress_image_height = height
|
||||
}
|
||||
const b_update_progress_layer: Boolean = (
|
||||
document.querySelector('.chLiveProgressImageClass') as any
|
||||
).checked
|
||||
const b_update_progress_layer = store.data.live_progress_image
|
||||
store.data.live_progress_image = b_update_progress_layer
|
||||
|
||||
if (
|
||||
b_update_progress_layer &&
|
||||
session_ts.store.data.ui_settings.batch_size === 1 &&
|
||||
session_store.data.ui_settings.batch_size === 1 &&
|
||||
store.data.can_update_progress_layer &&
|
||||
store.data.can_update // progress is still active
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
import { app } from 'photoshop'
|
||||
import { control_net, preview, viewer, progress } from '../entry'
|
||||
import Locale from '../locale/locale'
|
||||
import { AStore } from '../main/astore'
|
||||
// import { control_net, preview, viewer, progress } from '../entry'
|
||||
import * as progress from '../session/progress'
|
||||
|
||||
import {
|
||||
html_manip,
|
||||
io,
|
||||
psapi,
|
||||
python_replacement,
|
||||
sdapi,
|
||||
} from '../util/oldSystem'
|
||||
import { GenerationModeEnum, SelectionInfoType } from '../util/ts/enum'
|
||||
// store as viewer_store,
|
||||
mask_store as viewer_mask_store,
|
||||
init_store as viewer_init_store,
|
||||
} from '../viewer/viewer_util'
|
||||
import Locale from '../locale/locale'
|
||||
import { store } from './session_store'
|
||||
import { html_manip, io, python_replacement } from '../util/oldSystem'
|
||||
import { GenerationModeEnum } from '../util/ts/enum'
|
||||
import {
|
||||
Img2ImgMode,
|
||||
InpaintMode,
|
||||
|
|
@ -18,74 +19,18 @@ import {
|
|||
Txt2ImgMode,
|
||||
UpscaleMode,
|
||||
} from './modes'
|
||||
import { Progress } from './progress'
|
||||
|
||||
import { reaction } from 'mobx'
|
||||
import {
|
||||
resetViewer,
|
||||
updateViewerStoreImageAndThumbnail,
|
||||
} from '../viewer/viewer_util'
|
||||
import { sd_tab_store } from '../stores'
|
||||
|
||||
declare let g_inpaint_mask_layer: any
|
||||
declare const g_image_not_found_url: string
|
||||
declare let g_current_batch_index: number
|
||||
|
||||
interface AStoreUISettings {
|
||||
batch_size: number
|
||||
// add other properties here as needed
|
||||
}
|
||||
|
||||
interface AStoreData {
|
||||
// other properties...
|
||||
|
||||
init_image: string
|
||||
active_mask: string // this is the mask that is been used in the current generation
|
||||
mask: string // the user inputted mask, also can be the mask generated by photoshop dependant on the generation mode
|
||||
expanded_mask: string // mask after expanded
|
||||
monoMask: string //monochrome mask, no gradation
|
||||
preprocessed_mask: string //
|
||||
sd_mask: string // mask send to sd as payload[mask]
|
||||
mode: GenerationModeEnum
|
||||
|
||||
ui_settings: AStoreUISettings
|
||||
selectionInfo: SelectionInfoType | undefined //the session selection info
|
||||
current_selection_info: {} // any new selection, could be undefined too
|
||||
can_generate: boolean // is generation currently in progress
|
||||
can_generate_more: boolean //
|
||||
is_active: boolean // is session active
|
||||
is_interrupted: boolean // did we interrupt the generation
|
||||
generation_number: number // generation number per session, 0 mean first generation
|
||||
controlnet_input_image: string // the controlnet the image that will controlnet load
|
||||
|
||||
//plugin related state:
|
||||
auto_photoshop_sd_extension_status: boolean
|
||||
|
||||
doc_uuid: string
|
||||
current_session_id: number
|
||||
}
|
||||
|
||||
export const store = new AStore<AStoreData>({
|
||||
// activeBase64InitImage: '',
|
||||
// activeBase64Mask: '',
|
||||
init_image: '',
|
||||
active_mask: '', // this is the mask that is been used in the current generation
|
||||
mask: '', // the user inputted mask, also can be the mask generated by photoshop dependant on the generation mode
|
||||
expanded_mask: '', // mask after expanded
|
||||
monoMask: '', //monochrome mask, no gradation
|
||||
preprocessed_mask: '', //
|
||||
sd_mask: '', // mask send to sd as payload[mask]
|
||||
mode: GenerationModeEnum.Txt2Img,
|
||||
ui_settings: { batch_size: 1 },
|
||||
selectionInfo: undefined, //the session selection info
|
||||
current_selection_info: {}, // any new selection, could be undefined too
|
||||
can_generate: true, // is generation currently in progress
|
||||
can_generate_more: false, //
|
||||
is_active: false, // is session active
|
||||
is_interrupted: false, // did we interrupt the generation
|
||||
generation_number: 0, // generation number per session, 0 mean first generation
|
||||
controlnet_input_image: '', // the controlnet the image that will controlnet load
|
||||
|
||||
//plugin related state:
|
||||
auto_photoshop_sd_extension_status: true,
|
||||
doc_uuid: '',
|
||||
current_session_id: 0,
|
||||
})
|
||||
|
||||
reaction(
|
||||
() => {
|
||||
return [store.data.init_image, store.data.mask] as [string, string]
|
||||
|
|
@ -249,8 +194,8 @@ export class Session {
|
|||
store.data.init_image = init_image
|
||||
// store.data.init_image = opaque_init_image
|
||||
|
||||
await viewer.updateViewerStoreImageAndThumbnail(
|
||||
viewer.init_store,
|
||||
await updateViewerStoreImageAndThumbnail(
|
||||
viewer_init_store,
|
||||
[store.data.init_image]
|
||||
)
|
||||
}
|
||||
|
|
@ -262,11 +207,10 @@ export class Session {
|
|||
store.data.monoMask = mask_monochrome
|
||||
store.data.mask = mask
|
||||
|
||||
const expansion_value: number = parseInt(
|
||||
//@ts-ignore
|
||||
document.getElementById('slMaskExpansion').value
|
||||
)
|
||||
const mask_blur = html_manip.getMaskBlur()
|
||||
const expansion_value: number =
|
||||
sd_tab_store.data.mask_expansion
|
||||
|
||||
const mask_blur = sd_tab_store.data.mask_blur
|
||||
store.data.expanded_mask = await getExpandedMask(
|
||||
mask,
|
||||
expansion_value,
|
||||
|
|
@ -274,8 +218,8 @@ export class Session {
|
|||
)
|
||||
store.data.preprocessed_mask = mask
|
||||
|
||||
await viewer.updateViewerStoreImageAndThumbnail(
|
||||
viewer.mask_store,
|
||||
await updateViewerStoreImageAndThumbnail(
|
||||
viewer_mask_store,
|
||||
|
||||
[
|
||||
store.data.preprocessed_mask,
|
||||
|
|
@ -362,11 +306,8 @@ export class Session {
|
|||
GenerationModeEnum.Outpaint,
|
||||
].includes(mode)
|
||||
) {
|
||||
const expansion_value: number = parseInt(
|
||||
//@ts-ignore
|
||||
document.getElementById('slMaskExpansion').value
|
||||
)
|
||||
const mask_blur = html_manip.getMaskBlur()
|
||||
const expansion_value: number = sd_tab_store.data.mask_expansion
|
||||
const mask_blur = sd_tab_store.data.mask_blur
|
||||
store.data.expanded_mask = await getExpandedMask(
|
||||
mask,
|
||||
expansion_value,
|
||||
|
|
@ -415,11 +356,8 @@ export class Session {
|
|||
GenerationModeEnum.Outpaint,
|
||||
].includes(store.data.mode)
|
||||
) {
|
||||
const expansion_value: number = parseInt(
|
||||
//@ts-ignore
|
||||
document.getElementById('slMaskExpansion').value
|
||||
)
|
||||
const mask_blur = html_manip.getMaskBlur()
|
||||
const expansion_value: number = sd_tab_store.data.mask_expansion
|
||||
const mask_blur = sd_tab_store.data.mask_blur
|
||||
store.data.expanded_mask = await getExpandedMask(
|
||||
session_data.mask,
|
||||
expansion_value,
|
||||
|
|
@ -491,7 +429,7 @@ export class Session {
|
|||
})
|
||||
}
|
||||
static endSession() {
|
||||
viewer.resetViewer() //may cause circular dependency
|
||||
resetViewer() //may cause circular dependency
|
||||
store.data.is_active = false //
|
||||
store.data.init_image = ''
|
||||
store.data.mask = ''
|
||||
|
|
|
|||
|
|
@ -0,0 +1,65 @@
|
|||
import { AStore } from '../main/astore'
|
||||
import { GenerationModeEnum, SelectionInfoType } from '../util/ts/enum'
|
||||
|
||||
interface AStoreUISettings {
|
||||
batch_size: number
|
||||
// add other properties here as needed
|
||||
}
|
||||
|
||||
interface AStoreData {
|
||||
// other properties...
|
||||
|
||||
init_image: string
|
||||
active_mask: string // this is the mask that is been used in the current generation
|
||||
mask: string // the user inputted mask, also can be the mask generated by photoshop dependant on the generation mode
|
||||
expanded_mask: string // mask after expanded
|
||||
monoMask: string //monochrome mask, no gradation
|
||||
preprocessed_mask: string //
|
||||
sd_mask: string // mask send to sd as payload[mask]
|
||||
mode: GenerationModeEnum
|
||||
|
||||
ui_settings: AStoreUISettings
|
||||
selectionInfo: SelectionInfoType | undefined //the session selection info
|
||||
current_selection_info: SelectionInfoType | undefined // any new selection, could be undefined too
|
||||
can_generate: boolean // is generation currently in progress
|
||||
can_generate_more: boolean //
|
||||
is_active: boolean // is session active
|
||||
is_interrupted: boolean // did we interrupt the generation
|
||||
generation_number: number // generation number per session, 0 mean first generation
|
||||
controlnet_input_image: string // the controlnet the image that will controlnet load
|
||||
|
||||
//plugin related state:
|
||||
auto_photoshop_sd_extension_status: boolean
|
||||
|
||||
doc_uuid: string
|
||||
current_session_id: number
|
||||
last_seed: string
|
||||
}
|
||||
|
||||
export const store = new AStore<AStoreData>({
|
||||
// activeBase64InitImage: '',
|
||||
// activeBase64Mask: '',
|
||||
init_image: '',
|
||||
active_mask: '', // this is the mask that is been used in the current generation
|
||||
mask: '', // the user inputted mask, also can be the mask generated by photoshop dependant on the generation mode
|
||||
expanded_mask: '', // mask after expanded
|
||||
monoMask: '', //monochrome mask, no gradation
|
||||
preprocessed_mask: '', //
|
||||
sd_mask: '', // mask send to sd as payload[mask]
|
||||
mode: GenerationModeEnum.Txt2Img,
|
||||
ui_settings: { batch_size: 1 },
|
||||
selectionInfo: undefined, //the session selection info
|
||||
current_selection_info: undefined, // any new selection, could be undefined too
|
||||
can_generate: true, // is generation currently in progress
|
||||
can_generate_more: false, //
|
||||
is_active: false, // is session active
|
||||
is_interrupted: false, // did we interrupt the generation
|
||||
generation_number: 0, // generation number per session, 0 mean first generation
|
||||
controlnet_input_image: '', // the controlnet the image that will controlnet load
|
||||
|
||||
//plugin related state:
|
||||
auto_photoshop_sd_extension_status: true,
|
||||
doc_uuid: '',
|
||||
current_session_id: 0,
|
||||
last_seed: '-1',
|
||||
})
|
||||
|
|
@ -11,7 +11,9 @@ import { reaction } from 'mobx'
|
|||
//@ts-ignore
|
||||
import { storage } from 'uxp'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import { MaskModeEnum } from '../util/ts/enum'
|
||||
import { MaskModeEnum, ScriptMode } from '../util/ts/enum'
|
||||
import { store as progress_store } from '../session/progress'
|
||||
|
||||
// import { Jimp } from '../util/oldSystem'
|
||||
declare const Jimp: any // make sure you import jimp before importing settings.tsx
|
||||
|
||||
|
|
@ -37,11 +39,44 @@ const interpolationMethods: InterpolationMethod = {
|
|||
},
|
||||
}
|
||||
|
||||
enum ExtensionTypeEnum {
|
||||
ProxyServer = 'proxy_server',
|
||||
Auto1111Extension = 'auto1111_extension',
|
||||
None = 'none',
|
||||
}
|
||||
const config = {
|
||||
[ExtensionTypeEnum.ProxyServer]: {
|
||||
title: "use the proxy server, need to run 'start_server.bat' ",
|
||||
value: ExtensionTypeEnum.ProxyServer,
|
||||
label: 'Proxy Server',
|
||||
},
|
||||
[ExtensionTypeEnum.Auto1111Extension]: {
|
||||
title: 'use Automatic1111 Photoshop SD Extension, need to install the extension in Auto1111',
|
||||
value: ExtensionTypeEnum.Auto1111Extension,
|
||||
label: 'Auto1111 Extension',
|
||||
},
|
||||
[ExtensionTypeEnum.None]: {
|
||||
title: 'Use the Plugin Only No Additional Component',
|
||||
value: ExtensionTypeEnum.None,
|
||||
label: 'None',
|
||||
},
|
||||
}
|
||||
|
||||
function extensionTypeName(extension_type: ExtensionTypeEnum) {
|
||||
return extension_type
|
||||
.split('_')
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ')
|
||||
}
|
||||
interface AStoreData {
|
||||
scale_interpolation_method: typeof interpolationMethods.bilinear
|
||||
should_log_to_file: boolean
|
||||
delete_log_file_timer_id: ReturnType<typeof setInterval> | undefined
|
||||
b_borders_or_corners: MaskModeEnum
|
||||
use_image_cfg_scale_slider: boolean
|
||||
extension_type: ExtensionTypeEnum
|
||||
use_sharp_mask: boolean
|
||||
use_prompt_shortcut: boolean
|
||||
}
|
||||
export const store = new AStore<AStoreData>({
|
||||
scale_interpolation_method: interpolationMethods.bilinear,
|
||||
|
|
@ -49,6 +84,10 @@ export const store = new AStore<AStoreData>({
|
|||
JSON.parse(storage.localStorage.getItem('should_log_to_file')) || false,
|
||||
delete_log_file_timer_id: undefined,
|
||||
b_borders_or_corners: MaskModeEnum.Transparent,
|
||||
use_image_cfg_scale_slider: false,
|
||||
extension_type: ExtensionTypeEnum.Auto1111Extension,
|
||||
use_sharp_mask: false,
|
||||
use_prompt_shortcut: true,
|
||||
})
|
||||
|
||||
function onShouldLogToFileChange(event: any) {
|
||||
|
|
@ -180,6 +219,71 @@ export class Settings extends React.Component<{}> {
|
|||
)
|
||||
})}
|
||||
</sp-radio-group>
|
||||
<SpCheckBox
|
||||
style={{
|
||||
marginRight: '10px',
|
||||
}}
|
||||
onChange={(evt: any) => {
|
||||
progress_store.data.live_progress_image =
|
||||
evt.target.checked
|
||||
}}
|
||||
checked={progress_store.data.live_progress_image}
|
||||
>
|
||||
{
|
||||
//@ts-ignore
|
||||
Locale('Live Progress Image')
|
||||
}
|
||||
</SpCheckBox>
|
||||
<div>
|
||||
<sp-checkbox
|
||||
id="chUseImageCfgScaleSlider"
|
||||
title="image cfg slider for pix2pix mode"
|
||||
value={store.data.use_image_cfg_scale_slider}
|
||||
onClick={(evt: any) => {
|
||||
store.data.use_image_cfg_scale_slider =
|
||||
evt.target.checked
|
||||
}}
|
||||
style={{ display: 'inline-flex' }}
|
||||
>
|
||||
Image Cfg Scale Slider
|
||||
</sp-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<sp-checkbox
|
||||
id="chUseSharpMask"
|
||||
checked={store.data.use_sharp_mask}
|
||||
onClick={(evt: any) => {
|
||||
store.data.use_sharp_mask = evt.target.checked
|
||||
}}
|
||||
>
|
||||
use sharp mask
|
||||
</sp-checkbox>
|
||||
</div>
|
||||
<div>
|
||||
<sp-radio-group selected={store.data.extension_type}>
|
||||
<sp-label slot="label">Select Extension:</sp-label>
|
||||
{[
|
||||
ExtensionTypeEnum.ProxyServer,
|
||||
ExtensionTypeEnum.Auto1111Extension,
|
||||
ExtensionTypeEnum.None,
|
||||
].map((extension_type, index: number) => {
|
||||
return (
|
||||
<sp-radio
|
||||
key={index}
|
||||
title={config[extension_type].title}
|
||||
class="rbExtensionType"
|
||||
value={config[extension_type].value}
|
||||
onClick={(evt: any) => {
|
||||
store.data.extension_type =
|
||||
evt.target.value
|
||||
}}
|
||||
>
|
||||
{config[extension_type].label}
|
||||
</sp-radio>
|
||||
)
|
||||
})}
|
||||
</sp-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -194,3 +298,5 @@ root.render(
|
|||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
||||
progress_store.data.live_progress_image
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
export { store as session_store } from './session/session_store'
|
||||
export { store as sd_tab_store } from './sd_tab/util'
|
||||
export { mask_store } from './viewer/viewer_util'
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
/* styles.css */
|
||||
#_tool_bar_container button:not(:last-child) {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
import { observer } from 'mobx-react'
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
import { general, html_manip, io, psapi } from '../util/oldSystem'
|
||||
import {
|
||||
default_preset,
|
||||
loadPresetSettings,
|
||||
store as sd_tab_store,
|
||||
} from '../sd_tab/util'
|
||||
import { requestPost } from '../util/ts/api'
|
||||
import ControlNetStore from '../controlnet/store'
|
||||
import { AStore } from '../main/astore'
|
||||
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import './style/tool_bar.css'
|
||||
import { presetToStore } from '../util/ts/io'
|
||||
import { multiPrompts } from '../entry'
|
||||
import { activateSessionSelectionArea } from '../util/ts/selection'
|
||||
declare let g_sd_url: string
|
||||
|
||||
export const store = new AStore({
|
||||
at_controlnet_unit_index: 0,
|
||||
})
|
||||
async function clipInterrogate() {
|
||||
try {
|
||||
const width = sd_tab_store.data.width
|
||||
const height = sd_tab_store.data.height
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
|
||||
const base64 = await io.IO.getSelectionFromCanvasAsBase64Interface_New(
|
||||
width,
|
||||
height,
|
||||
selectionInfo,
|
||||
true
|
||||
)
|
||||
|
||||
const url = `${g_sd_url}/sdapi/v1/interrogate`
|
||||
|
||||
const payload = {
|
||||
image: base64,
|
||||
model: 'clip',
|
||||
}
|
||||
const result_json = await requestPost(url, payload)
|
||||
console.log(result_json)
|
||||
return result_json
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async function onInterrogate(evt: any) {
|
||||
// start sudo timer after 1 seconds delay
|
||||
let sudo_timer_id
|
||||
setTimeout(() => {
|
||||
sudo_timer_id = general.sudoTimer('Interrogate')
|
||||
}, 1000)
|
||||
const interrogate_result = await clipInterrogate()
|
||||
|
||||
if (interrogate_result.caption) {
|
||||
html_manip.autoFillInPrompt(interrogate_result.caption)
|
||||
}
|
||||
|
||||
// after the clipInterrogate finish stop the timer
|
||||
|
||||
html_manip.updateProgressBarsHtml(0, 'No work in progress')
|
||||
clearInterval(sudo_timer_id)
|
||||
sudo_timer_id = null
|
||||
}
|
||||
|
||||
function scrollToPreview() {
|
||||
try {
|
||||
document
|
||||
.querySelector('#search_second_panel > div.previewContainer')!
|
||||
.scrollIntoView()
|
||||
// document.getElementById('taPrompt').scrollIntoView()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
@observer
|
||||
class ToolBar extends React.Component<{}> {
|
||||
componentDidMount(): void {
|
||||
console.log('ToolBar did mount')
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div id="_tool_bar_container">
|
||||
<button
|
||||
className="btnSquare layerToSelection btnLayerToSelection"
|
||||
title="Move and reSize the highlighted layer to fit into the Selection Area "
|
||||
style={{ marginRight: '3px' }}
|
||||
onClick={async (evt: any) => {
|
||||
try {
|
||||
const isSelectionAreaValid =
|
||||
await psapi.checkIfSelectionAreaIsActive()
|
||||
if (isSelectionAreaValid) {
|
||||
const validSelection = isSelectionAreaValid
|
||||
await psapi.layerToSelection(validSelection)
|
||||
} else {
|
||||
await psapi.promptForMarqueeTool()
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
title="create a snapshot of what you see on the canvas and place on a new layer"
|
||||
className="btnSquare snapshotButton"
|
||||
style={{ marginRight: '3px' }}
|
||||
onClick={async (evt: any) => {
|
||||
try {
|
||||
await psapi.snapshot_layerExe()
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className="btnSquare resetButton"
|
||||
id="btnResetSettings"
|
||||
title="reset the ui settings to their default values"
|
||||
style={{ marginRight: '3px' }}
|
||||
onClick={(evt: any) => {
|
||||
try {
|
||||
multiPrompts.setPrompt({
|
||||
positive: '',
|
||||
negative: '',
|
||||
})
|
||||
loadPresetSettings(default_preset)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}}
|
||||
></button>
|
||||
<button
|
||||
className="btnSquare interrogateButton"
|
||||
id="btnInterrogate"
|
||||
title="Interrogate the selected area, convert Image to Prompt"
|
||||
style={{ marginRight: '3px' }}
|
||||
onClick={onInterrogate}
|
||||
></button>
|
||||
<button
|
||||
className="btnSquare svgButton selectionAreaButton"
|
||||
id="btnSelectionArea"
|
||||
style={{ marginRight: '3px' }}
|
||||
title="Reselect the selection area for the current session"
|
||||
onClick={activateSessionSelectionArea}
|
||||
></button>
|
||||
<button
|
||||
id="scrollToPreview"
|
||||
className="btnSquare svgButton"
|
||||
title="Quickly jump to the preview section"
|
||||
onClick={scrollToPreview}
|
||||
>
|
||||
P
|
||||
</button>
|
||||
<div id="scrollToControlNetUnitContainer">
|
||||
<button
|
||||
className="btnSquare svgButton"
|
||||
onClick={() => {
|
||||
try {
|
||||
const units = document.querySelectorAll(
|
||||
'#controlNetTabParentContainer .collapsible'
|
||||
)
|
||||
const units_data =
|
||||
ControlNetStore.controlNetUnitData.map(
|
||||
(data, index) => ({
|
||||
enabled: data.enabled,
|
||||
index,
|
||||
})
|
||||
)
|
||||
|
||||
// Find the next enabled unit
|
||||
let counter = 0
|
||||
while (
|
||||
!units_data[
|
||||
store.data.at_controlnet_unit_index %
|
||||
units.length
|
||||
].enabled &&
|
||||
counter < units.length
|
||||
) {
|
||||
store.data.at_controlnet_unit_index += 1
|
||||
counter += 1
|
||||
}
|
||||
|
||||
if (counter < units.length) {
|
||||
store.data.at_controlnet_unit_index =
|
||||
store.data.at_controlnet_unit_index %
|
||||
units.length
|
||||
units[
|
||||
store.data.at_controlnet_unit_index
|
||||
].scrollIntoView()
|
||||
store.data.at_controlnet_unit_index += 1
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}}
|
||||
title="Quickly jump to the active ControlNet Unit"
|
||||
>
|
||||
C
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.getElementById('toolBarContainer')!
|
||||
const root = ReactDOM.createRoot(container)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<ErrorBoundary>
|
||||
<ToolBar></ToolBar>
|
||||
</ErrorBoundary>
|
||||
</React.StrictMode>
|
||||
)
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import React, { CSSProperties, ComponentType } from 'react'
|
||||
// import ReactDOM from 'react-dom'
|
||||
|
||||
import { useState, ReactNode } from 'react'
|
||||
import Locale from '../locale/locale'
|
||||
interface CollapsibleProps {
|
||||
label: string
|
||||
labelStyle?: React.CSSProperties
|
||||
containerStyle?: React.CSSProperties
|
||||
defaultIsOpen?: boolean
|
||||
checked?: boolean
|
||||
checkboxCallback?: (checked: boolean) => void
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function Collapsible({
|
||||
label,
|
||||
labelStyle,
|
||||
containerStyle,
|
||||
defaultIsOpen = false,
|
||||
checkboxCallback,
|
||||
checked,
|
||||
children,
|
||||
}: CollapsibleProps) {
|
||||
const [isOpen, setIsOpen] = useState(defaultIsOpen)
|
||||
|
||||
const handleToggle = () => {
|
||||
setIsOpen(!isOpen)
|
||||
}
|
||||
|
||||
return (
|
||||
/*useObserver(()=>*/ <div>
|
||||
<div
|
||||
className="collapsible"
|
||||
style={containerStyle}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
<span className="truncate" style={labelStyle}>
|
||||
{label}
|
||||
</span>
|
||||
|
||||
<span
|
||||
style={{ float: 'right', display: 'flex' }}
|
||||
className="triangle"
|
||||
>
|
||||
{checkboxCallback && checked !== void 0 ? (
|
||||
<input
|
||||
type="checkbox"
|
||||
className="minimal-checkbox"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
}}
|
||||
onChange={(event: any) => {
|
||||
checkboxCallback(event.target.checked)
|
||||
}}
|
||||
checked={checked}
|
||||
/>
|
||||
) : (
|
||||
void 0
|
||||
)}
|
||||
|
||||
<span>{isOpen ? '∨' : '<'}</span>
|
||||
</span>
|
||||
</div>
|
||||
{/* {isOpen && <div>{children}</div>} */}
|
||||
<div style={{ display: isOpen ? 'block' : 'none' }}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -200,6 +200,7 @@ export class SpMenu extends React.Component<{
|
|||
label_item?: string
|
||||
onChange?: any
|
||||
selected_index?: number
|
||||
size?: string
|
||||
}> {
|
||||
state = {
|
||||
selectedItem: this.props.items ? this.props.items[0] : undefined,
|
||||
|
|
@ -232,49 +233,48 @@ export class SpMenu extends React.Component<{
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div style={this.props.style}>
|
||||
<sp-picker
|
||||
title={this.props.title}
|
||||
size="m"
|
||||
// style={{ width: '199px', marginRight: '5px' }}
|
||||
>
|
||||
<sp-menu id={this.props.id} slot="options">
|
||||
{this.props.label_item && (
|
||||
<sp-menu-item
|
||||
disabled="disabled"
|
||||
key={-1}
|
||||
data-index={-1}
|
||||
selected
|
||||
>
|
||||
{this.props.label_item}
|
||||
</sp-menu-item>
|
||||
)}
|
||||
{this.props.items?.map((item, index: number) => (
|
||||
<sp-menu-item
|
||||
key={item}
|
||||
data-index={index}
|
||||
selected={
|
||||
this.props.selected_index !== undefined &&
|
||||
this.props.selected_index !== null &&
|
||||
this.props.selected_index === index
|
||||
? 'selected'
|
||||
: undefined
|
||||
}
|
||||
disabled={
|
||||
this.props.disabled?.[index]
|
||||
? 'disabled'
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
this.handleItemClick(item, index)
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</sp-menu-item>
|
||||
))}
|
||||
</sp-menu>
|
||||
</sp-picker>
|
||||
</div>
|
||||
<sp-picker
|
||||
title={this.props.title}
|
||||
size={this.props.size || 'm'}
|
||||
style={this.props.style}
|
||||
// style={{ width: '199px', marginRight: '5px' }}
|
||||
>
|
||||
<sp-menu id={this.props.id} slot="options">
|
||||
{this.props.label_item && (
|
||||
<sp-menu-item
|
||||
disabled="disabled"
|
||||
key={-1}
|
||||
data-index={-1}
|
||||
selected
|
||||
>
|
||||
{this.props.label_item}
|
||||
</sp-menu-item>
|
||||
)}
|
||||
{this.props.items?.map((item, index: number) => (
|
||||
<sp-menu-item
|
||||
key={item}
|
||||
data-index={index}
|
||||
selected={
|
||||
this.props.selected_index !== undefined &&
|
||||
this.props.selected_index !== null &&
|
||||
this.props.selected_index === index
|
||||
? 'selected'
|
||||
: undefined
|
||||
}
|
||||
disabled={
|
||||
this.props.disabled?.[index]
|
||||
? 'disabled'
|
||||
: undefined
|
||||
}
|
||||
onClick={() => {
|
||||
this.handleItemClick(item, index)
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
</sp-menu-item>
|
||||
))}
|
||||
</sp-menu>
|
||||
</sp-picker>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -392,6 +392,17 @@ export class SpSlider extends PhotoshopElem {
|
|||
)
|
||||
}
|
||||
}
|
||||
export class SpTextfield extends PhotoshopElem {
|
||||
render() {
|
||||
const [attr] = this.splitProps(this.props)
|
||||
return (
|
||||
<sp-textfield
|
||||
ref={(elem: Element) => (this.elem = elem)}
|
||||
{...attr}
|
||||
></sp-textfield>
|
||||
)
|
||||
}
|
||||
}
|
||||
export class SpRadioGroup extends PhotoshopElem {
|
||||
render() {
|
||||
const [attr] = this.splitProps(this.props)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const req = window['require']
|
|||
const selection = req('./selection')
|
||||
const note = req('./utility/notification')
|
||||
const controlnet_preset = req('./utility/presets/controlnet_preset')
|
||||
const preset = req('./utility/presets/preset')
|
||||
|
||||
const Enum = req('./enum')
|
||||
const api = req('./utility/api')
|
||||
const python_replacement = req('./utility/sdapi/python_replacement')
|
||||
|
|
@ -19,7 +19,10 @@ const io = req('./utility/io')
|
|||
const settings_tab = req('./utility/tab/settings')
|
||||
const layer_util = req('./utility/layer')
|
||||
const session = req('./utility/session')
|
||||
const dialog_box = req('./dialog_box')
|
||||
const sampler_data = req('./utility/sampler')
|
||||
|
||||
const thumbnail = req('./thumbnail')
|
||||
interface _Jimp extends Jimp {}
|
||||
const _Jimp: typeof Jimp = (window as any)['Jimp']
|
||||
|
||||
|
|
@ -27,7 +30,6 @@ export {
|
|||
selection,
|
||||
note,
|
||||
controlnet_preset,
|
||||
preset,
|
||||
Enum,
|
||||
api,
|
||||
python_replacement,
|
||||
|
|
@ -39,5 +41,8 @@ export {
|
|||
settings_tab,
|
||||
layer_util,
|
||||
session,
|
||||
dialog_box,
|
||||
sampler_data,
|
||||
thumbnail,
|
||||
_Jimp as Jimp,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@ export enum GenerationModeEnum {
|
|||
LassoOutpaint = 'lasso_outpaint',
|
||||
}
|
||||
|
||||
export enum ScriptMode {
|
||||
Txt2Img = 'txt2img',
|
||||
Img2Img = 'img2img',
|
||||
Inpaint = 'inpaint',
|
||||
Outpaint = 'outpaint',
|
||||
}
|
||||
|
||||
export enum MaskModeEnum {
|
||||
Transparent = 'transparent',
|
||||
Borders = 'border',
|
||||
|
|
@ -22,3 +29,8 @@ export interface SelectionInfoType {
|
|||
width: number
|
||||
height: number
|
||||
}
|
||||
|
||||
export enum PresetTypeEnum {
|
||||
SDPreset = 'sd_preset',
|
||||
ControlNetPreset = 'controlnet_preset',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,10 @@ import { Jimp, io, psapi } from '../oldSystem'
|
|||
import { base64ToFileAndGetLayer } from './document'
|
||||
import { transformCurrentLayerTo } from './layer'
|
||||
import { Layer } from 'photoshop/dom/Layer'
|
||||
import { lstatSync, readFileSync, writeFileSync } from 'fs'
|
||||
import { AStore } from '../../main/astore'
|
||||
const executeAsModal = core.executeAsModal
|
||||
type KeyValuePair = { [key: string]: any }
|
||||
|
||||
//REFACTOR: move to psapi.js
|
||||
export function _arrayBufferToBase64(buffer: any) {
|
||||
|
|
@ -139,3 +142,31 @@ async function getBase64FromJimp(jimp_image: Jimp) {
|
|||
const base64 = dataURL.replace(/^data:image\/png;base64,/, '')
|
||||
return base64
|
||||
}
|
||||
|
||||
export function readPreset(path: string) {
|
||||
try {
|
||||
const content = readFileSync(path, 'utf-8')
|
||||
JSON.parse(content)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function writePreset(path: string, preset: KeyValuePair) {
|
||||
try {
|
||||
writeFileSync(path, JSON.stringify(preset))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function storeToPreset(store: any) {
|
||||
return store.toJsFunc().data
|
||||
}
|
||||
|
||||
export function presetToStore(preset: KeyValuePair, store: any) {
|
||||
store.data = {
|
||||
...store.data,
|
||||
...preset,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { app, core, action } from 'photoshop'
|
||||
import { layer_util, psapi } from '../oldSystem'
|
||||
import { settings_tab_ts } from '../../entry'
|
||||
// import { settings_tab_ts } from '../../entry'
|
||||
import * as settings_tab_ts from '../../settings/settings'
|
||||
const executeAsModal = core.executeAsModal
|
||||
const { batchPlay } = action
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
declare let g_version: any
|
||||
declare let g_sd_url: any
|
||||
|
||||
export async function getVersionRequest() {
|
||||
console.log('requestGetSamplers: ')
|
||||
const current_version = g_version
|
||||
|
||||
return current_version
|
||||
}
|
||||
export async function requestGetSamplers() {
|
||||
let json = null
|
||||
try {
|
||||
console.log('requestGetSamplers: ')
|
||||
|
||||
const full_url = `${g_sd_url}/sdapi/v1/samplers`
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
// console.log('samplers json:', json)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
export async function requestGetUpscalers() {
|
||||
console.log('requestGetUpscalers: ')
|
||||
let json = []
|
||||
const full_url = `${g_sd_url}/sdapi/v1/upscalers`
|
||||
try {
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
console.log('upscalers json:')
|
||||
console.dir(json)
|
||||
} catch (e) {
|
||||
console.warn(`issues requesting from ${full_url}`, e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
export async function setInpaintMaskWeight(value: number) {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/options`
|
||||
try {
|
||||
const payload = {
|
||||
inpainting_mask_weight: value,
|
||||
}
|
||||
await fetch(full_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
export async function requestGetModels() {
|
||||
console.log('requestGetModels: ')
|
||||
let json = []
|
||||
const full_url = `${g_sd_url}/sdapi/v1/sd-models`
|
||||
try {
|
||||
let request = await fetch(full_url)
|
||||
json = await request.json()
|
||||
console.log('models json:')
|
||||
console.dir(json)
|
||||
} catch (e) {
|
||||
console.warn(`issues requesting from ${full_url}`, e)
|
||||
}
|
||||
return json
|
||||
}
|
||||
|
||||
export async function requestSwapModel(model_title: string) {
|
||||
console.log('requestSwapModel: ')
|
||||
|
||||
const full_url = `${g_sd_url}/sdapi/v1/options`
|
||||
const payload = {
|
||||
sd_model_checkpoint: model_title,
|
||||
}
|
||||
let request = await fetch(full_url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
|
||||
let json = await request.json()
|
||||
|
||||
console.log('models json:')
|
||||
console.dir(json)
|
||||
|
||||
return json
|
||||
}
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
import { moveImageToLayer, moveImageToLayer_old } from './io'
|
||||
import { io, layer_util } from '../oldSystem'
|
||||
import { session_ts } from '../../entry'
|
||||
import { io, layer_util, psapi } from '../oldSystem'
|
||||
|
||||
import { action, core } from 'photoshop'
|
||||
import { MaskModeEnum } from './enum'
|
||||
import { session_store } from '../../stores'
|
||||
const executeAsModal = core.executeAsModal
|
||||
const batchPlay = action.batchPlay
|
||||
|
||||
|
|
@ -11,7 +11,8 @@ export async function applyMaskFromBlackAndWhiteImage(
|
|||
black_and_white_base64: string,
|
||||
layer_id: any,
|
||||
selectionInfo: any,
|
||||
b_borders_or_corners: MaskModeEnum = MaskModeEnum.Transparent
|
||||
b_borders_or_corners: MaskModeEnum = MaskModeEnum.Transparent,
|
||||
expand_by = 10
|
||||
) {
|
||||
let mask_layer
|
||||
try {
|
||||
|
|
@ -50,7 +51,7 @@ export async function applyMaskFromBlackAndWhiteImage(
|
|||
_obj: 'expand',
|
||||
by: {
|
||||
_unit: 'pixelsUnit',
|
||||
_value: 10,
|
||||
_value: expand_by,
|
||||
},
|
||||
selectionModifyEffectAtCanvasBounds: true,
|
||||
_isCommand: true,
|
||||
|
|
@ -156,3 +157,15 @@ export async function selectionFromBlackAndWhiteImage(
|
|||
await layer_util.deleteLayers([mask_layer])
|
||||
}
|
||||
}
|
||||
|
||||
export async function activateSessionSelectionArea() {
|
||||
try {
|
||||
if (psapi.isSelectionValid(session_store.data.selectionInfo)) {
|
||||
await psapi.reSelectMarqueeExe(session_store.data.selectionInfo)
|
||||
//@ts-ignore
|
||||
await eventHandler()
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,433 @@
|
|||
import { multiPrompts } from '../../entry'
|
||||
import {
|
||||
getAllCustomPresetsSettings,
|
||||
loadCustomPreset,
|
||||
loadPreset,
|
||||
} from '../../preset/shared_ui_preset'
|
||||
import { sd_tab_store } from '../../stores'
|
||||
import { html_manip } from '../oldSystem'
|
||||
import { PresetTypeEnum, ScriptMode } from './enum'
|
||||
|
||||
let LatentNoiseSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_size: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.92,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '2',
|
||||
}
|
||||
|
||||
let FillSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_size: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.7,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '0',
|
||||
}
|
||||
let OriginalSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_size: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.7,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '1',
|
||||
}
|
||||
let HealBrushSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_size: null,
|
||||
steps: '25',
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: '9',
|
||||
denoising_strength: 0.92,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: 1,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '2',
|
||||
mask_expansion: 2,
|
||||
}
|
||||
|
||||
class UI {
|
||||
constructor() {}
|
||||
}
|
||||
interface UIElements {
|
||||
[key: string]: UIElement
|
||||
|
||||
prompt: UIElement
|
||||
negative_prompt: UIElement
|
||||
mode: UIElement
|
||||
batch_size: UIElement
|
||||
batch_count: UIElement
|
||||
|
||||
steps: UIElement
|
||||
width: UIElement
|
||||
height: UIElement
|
||||
|
||||
cfg: UIElement
|
||||
denoising_strength: UIElement
|
||||
mask_content: UIElement
|
||||
seed: UIElement
|
||||
mask_blur: UIElement
|
||||
mask_expansion: UIElement
|
||||
samplers: UIElement
|
||||
}
|
||||
class UIElement {
|
||||
name: any
|
||||
html_elem: any
|
||||
sd_value: any
|
||||
constructor() {
|
||||
this.name
|
||||
this.html_elem
|
||||
this.sd_value
|
||||
}
|
||||
setValue(new_value: any) {}
|
||||
getValue(): any {}
|
||||
}
|
||||
function createUIElement(getter: any, setter: any) {
|
||||
let ui_element_obj = new UIElement()
|
||||
ui_element_obj.getValue = getter
|
||||
ui_element_obj.setValue = setter
|
||||
return ui_element_obj
|
||||
}
|
||||
class UISettings {
|
||||
prompt: UIElement
|
||||
negative_prompt: UIElement
|
||||
mode: UIElement
|
||||
steps: UIElement
|
||||
batch_size: UIElement
|
||||
batch_count: UIElement
|
||||
width: UIElement
|
||||
height: UIElement
|
||||
cfg: UIElement
|
||||
denoising_strength: UIElement
|
||||
mask_content: UIElement
|
||||
seed: UIElement
|
||||
mask_blur: UIElement
|
||||
mask_expansion: UIElement
|
||||
samplers: UIElement
|
||||
uiElements: UIElements
|
||||
// get and set the settings of the ui. the stable diffusion settings not the human friendly settings
|
||||
constructor() {
|
||||
const createUIElementWrapper = <T extends never>(
|
||||
getter: () => T,
|
||||
setter: (value: T) => void
|
||||
) => {
|
||||
return createUIElement(getter, setter)
|
||||
}
|
||||
|
||||
const sdTabStoreDataWrapper = <T extends never>(
|
||||
key: keyof typeof sd_tab_store.data
|
||||
) => {
|
||||
return createUIElementWrapper(
|
||||
() => sd_tab_store.data[key] as T,
|
||||
(value: T) => (sd_tab_store.data[key] = value)
|
||||
)
|
||||
}
|
||||
this.prompt = createUIElement(
|
||||
() => {
|
||||
return multiPrompts.getPrompt().positive
|
||||
},
|
||||
(value: string) => {
|
||||
multiPrompts.setPrompt({ positive: value })
|
||||
}
|
||||
)
|
||||
this.negative_prompt = createUIElement(
|
||||
() => {
|
||||
return multiPrompts.getPrompt().negative
|
||||
},
|
||||
(value: string) => {
|
||||
multiPrompts.setPrompt({ negative: value })
|
||||
}
|
||||
)
|
||||
|
||||
this.mode = sdTabStoreDataWrapper('rb_mode')
|
||||
this.batch_size = sdTabStoreDataWrapper('batch_size')
|
||||
this.batch_count = sdTabStoreDataWrapper('batch_count')
|
||||
this.steps = sdTabStoreDataWrapper('steps')
|
||||
this.width = sdTabStoreDataWrapper('width')
|
||||
this.height = sdTabStoreDataWrapper('height')
|
||||
this.cfg = sdTabStoreDataWrapper('cfg')
|
||||
// this.mask_blur =
|
||||
|
||||
this.denoising_strength = createUIElement(
|
||||
() => {
|
||||
return sd_tab_store.data.denoising_strength
|
||||
},
|
||||
(value: number) => {
|
||||
sd_tab_store.data.denoising_strength = value
|
||||
}
|
||||
)
|
||||
|
||||
this.mask_content = createUIElement(
|
||||
html_manip.getMaskContent,
|
||||
html_manip.setMaskContent
|
||||
)
|
||||
this.seed = createUIElement(
|
||||
() => {
|
||||
return sd_tab_store.data.seed
|
||||
},
|
||||
(value: string) => {
|
||||
sd_tab_store.data.seed = value
|
||||
}
|
||||
)
|
||||
|
||||
this.mask_blur = createUIElement(
|
||||
() => {
|
||||
return sd_tab_store.data.mask_blur
|
||||
},
|
||||
(value: number) => {
|
||||
sd_tab_store.data.mask_blur = value
|
||||
}
|
||||
)
|
||||
|
||||
this.mask_expansion = createUIElement(
|
||||
html_manip.getMaskExpansion,
|
||||
html_manip.setMaskExpansion
|
||||
)
|
||||
this.samplers = createUIElement(
|
||||
() => {
|
||||
return sd_tab_store.data.sampler_name
|
||||
},
|
||||
(value: string) => {
|
||||
sd_tab_store.data.sampler_name = value
|
||||
}
|
||||
)
|
||||
|
||||
this.uiElements = {
|
||||
// model: null,
|
||||
// prompt_shortcut: null,
|
||||
prompt: this.prompt,
|
||||
negative_prompt: this.negative_prompt,
|
||||
// selection_mode: null,
|
||||
mode: this.mode,
|
||||
batch_size: this.batch_size,
|
||||
batch_count: this.batch_count,
|
||||
steps: this.steps,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
|
||||
cfg_scale: this.cfg,
|
||||
denoising_strength: this.denoising_strength,
|
||||
// hi_res_denoising_strength:0.7,
|
||||
mask_blur: this.mask_blur,
|
||||
mask_expansion: this.mask_expansion,
|
||||
// inpaint_at_full_res: false,
|
||||
// hi_res_fix:false,
|
||||
// inpaint_padding:0,
|
||||
seed: this.seed,
|
||||
sampler_index: this.samplers,
|
||||
mask_content: this.mask_content,
|
||||
cfg: this.cfg,
|
||||
samplers: this.samplers,
|
||||
}
|
||||
}
|
||||
|
||||
autoFillInSettings(settings: any) {
|
||||
for (const [name, value] of Object.entries(settings)) {
|
||||
if (this.uiElements.hasOwnProperty(name) && value) {
|
||||
//get the values for debugging
|
||||
const old_value = this.uiElements[name].getValue()
|
||||
console.log(
|
||||
'(name,old_value) => newValue:',
|
||||
name,
|
||||
old_value,
|
||||
value
|
||||
)
|
||||
//set the value
|
||||
this.uiElements[name].setValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
getSettings() {
|
||||
let settings: any = {}
|
||||
for (const [name, ui_element] of Object.entries(this.uiElements)) {
|
||||
if (ui_element) {
|
||||
const value = ui_element.getValue()
|
||||
settings[name] = value
|
||||
}
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
||||
saveAsJson(json_file_name: string, settings: any) {
|
||||
for (const [name, value] of Object.entries(settings)) {
|
||||
if (this.uiElements.hasOwnProperty(name) && value) {
|
||||
//get the values for debugging
|
||||
const old_value = this.uiElements[name].getValue()
|
||||
console.log(
|
||||
'(name,old_value) => newValue:',
|
||||
name,
|
||||
old_value,
|
||||
value
|
||||
)
|
||||
|
||||
//set the value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// const ui_settings = new UISettings()
|
||||
|
||||
function loadLatentNoiseSettings(ui_settings: any) {
|
||||
loadPreset(ui_settings, LatentNoiseSettings)
|
||||
}
|
||||
|
||||
function loadFillSettings(ui_settings: any) {
|
||||
loadPreset(ui_settings, FillSettings)
|
||||
}
|
||||
function loadOriginalSettings(ui_settings: any) {
|
||||
loadPreset(ui_settings, OriginalSettings)
|
||||
}
|
||||
async function loadHealBrushSettings(ui_settings: any) {
|
||||
document.getElementById('rbModeInpaint')!.click()
|
||||
|
||||
loadPreset(ui_settings, HealBrushSettings)
|
||||
}
|
||||
|
||||
function loadCustomPresetsSettings() {}
|
||||
async function mapCustomPresetsToLoaders(ui_settings_obj: any) {
|
||||
const name_to_settings_obj = await getAllCustomPresetsSettings()
|
||||
const preset_name_to_loader_obj: any = {}
|
||||
for (const [preset_name, preset_settings] of Object.entries(
|
||||
name_to_settings_obj
|
||||
)) {
|
||||
preset_name_to_loader_obj[preset_name] = () => {
|
||||
loadCustomPreset(ui_settings_obj, preset_settings)
|
||||
}
|
||||
}
|
||||
return preset_name_to_loader_obj
|
||||
}
|
||||
|
||||
const g_nativePresets = {
|
||||
fill: loadFillSettings,
|
||||
original: loadOriginalSettings,
|
||||
'latent noise': loadLatentNoiseSettings,
|
||||
'Heal Brush': loadHealBrushSettings,
|
||||
}
|
||||
export function getNativeSDPresets() {
|
||||
return g_nativePresets
|
||||
}
|
||||
let g_ui_settings_object = new UISettings()
|
||||
function getUISettingsObject() {
|
||||
return g_ui_settings_object
|
||||
}
|
||||
|
||||
//REFACTOR: move to ui.js
|
||||
function addPresetMenuItem(preset_title: string) {
|
||||
// console.log(model_title,model_name)
|
||||
const menu_item_element = document.createElement('sp-menu-item')
|
||||
menu_item_element.className = 'mPresetMenuItem'
|
||||
menu_item_element.innerHTML = preset_title
|
||||
|
||||
// menu_item_element.addEventListener('select',()=>{
|
||||
// preset_func(g_ui_settings)
|
||||
// })
|
||||
return menu_item_element
|
||||
}
|
||||
//REFACTOR: move to ui.js
|
||||
// async function populatePresetMenu() {
|
||||
// document.getElementById('mPresetMenu')!.innerHTML = ''
|
||||
// const divider_elem = document.createElement('sp-menu-divider')
|
||||
// const preset_name = 'Select Smart Preset'
|
||||
// // const preset_func = () => {}
|
||||
// const dummy_preset_item = addPresetMenuItem(preset_name)
|
||||
// dummy_preset_item.setAttribute('selected', 'selected')
|
||||
// // dummy_preset_item.setAttribute('disabled')
|
||||
// document.getElementById('mPresetMenu')!.appendChild(dummy_preset_item)
|
||||
// document.getElementById('mPresetMenu')!.appendChild(divider_elem)
|
||||
// const presets = await getLoadedPresets(g_ui_settings_object)
|
||||
// for (const [key, value] of Object.entries(presets)) {
|
||||
// const preset_menu_item = addPresetMenuItem(key)
|
||||
// document.getElementById('mPresetMenu')!.appendChild(preset_menu_item)
|
||||
// }
|
||||
// }
|
||||
|
||||
// populatePresetMenu()
|
||||
//REFACTOR: move to preset_tab.js
|
||||
// document
|
||||
// .getElementById('mPresetMenu')!
|
||||
// .addEventListener('change', async (evt: any) => {
|
||||
// const preset_index = evt.target.selectedIndex
|
||||
// const preset_name: string = evt.target.options[preset_index].textContent
|
||||
// const presets: any = await getLoadedPresets(g_ui_settings_object)
|
||||
// if (presets.hasOwnProperty(preset_name)) {
|
||||
// const loader = presets[preset_name]
|
||||
// if (loader.constructor.name === 'AsyncFunction') {
|
||||
// await loader(g_ui_settings_object)
|
||||
// } else {
|
||||
// loader(g_ui_settings_object)
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
|
||||
// {
|
||||
// sd_tab:
|
||||
// controlnet_tab:
|
||||
// settings_tab:
|
||||
// }
|
||||
export {
|
||||
UI,
|
||||
UIElement,
|
||||
UISettings,
|
||||
loadLatentNoiseSettings,
|
||||
loadFillSettings,
|
||||
loadHealBrushSettings,
|
||||
getUISettingsObject,
|
||||
// populatePresetMenu,
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
import { observer } from 'mobx-react'
|
||||
import { AStore } from '../main/astore'
|
||||
import { progress } from '../entry'
|
||||
// import { progress } from '../entry'
|
||||
import * as progress from '../session/progress'
|
||||
|
||||
import './style/preview.css'
|
||||
import { reaction } from 'mobx'
|
||||
import Locale from '../locale/locale'
|
||||
|
|
|
|||
|
|
@ -16,8 +16,13 @@ import {
|
|||
moveImageToLayer_old,
|
||||
} from '../util/ts/io'
|
||||
import { io, layer_util, psapi, selection } from '../util/oldSystem'
|
||||
import Collapsible from '../after_detailer/after_detailer'
|
||||
import { progress, session_ts, settings_tab_ts } from '../entry'
|
||||
import { Collapsible } from '../util/collapsible'
|
||||
// import { progress } from '../entry'
|
||||
|
||||
import * as progress from '../session/progress'
|
||||
import * as settings_tab_ts from '../settings/settings'
|
||||
|
||||
import { store as session_store } from '../session/session_store'
|
||||
import { reaction } from 'mobx'
|
||||
import {
|
||||
GenerationModeEnum,
|
||||
|
|
@ -29,27 +34,19 @@ import { action, app, core } from 'photoshop'
|
|||
import Locale from '../locale/locale'
|
||||
import { applyMaskFromBlackAndWhiteImage } from '../util/ts/selection'
|
||||
import { ErrorBoundary } from '../util/errorBoundary'
|
||||
import { Session } from '../session/session'
|
||||
import {
|
||||
ClassNameEnum,
|
||||
ClickTypeEnum,
|
||||
init_store,
|
||||
mask_store,
|
||||
store,
|
||||
} from './viewer_util'
|
||||
|
||||
const executeAsModal = core.executeAsModal
|
||||
const batchPlay = action.batchPlay
|
||||
declare let g_generation_session: any
|
||||
|
||||
enum ClickTypeEnum {
|
||||
Click = 'click',
|
||||
ShiftClick = 'shift_click',
|
||||
AltClick = 'alt_click',
|
||||
SecondClick = 'second_click', //when we click a thumbnail that is active/ has orange border
|
||||
}
|
||||
|
||||
enum OutputImageStateEnum {
|
||||
Add = 'add',
|
||||
remove = 'remove',
|
||||
}
|
||||
enum ClassNameEnum {
|
||||
Green = 'viewerImgSelected',
|
||||
Orange = 'viewerImgActive',
|
||||
None = '',
|
||||
}
|
||||
function findClickType(event: any) {
|
||||
let click_type: ClickTypeEnum = ClickTypeEnum.Click
|
||||
|
||||
|
|
@ -61,46 +58,6 @@ function findClickType(event: any) {
|
|||
return click_type
|
||||
}
|
||||
|
||||
interface AStoreData {
|
||||
images: string[]
|
||||
thumbnails: string[]
|
||||
metadata: any[] // metadata for each image
|
||||
width: number
|
||||
height: number
|
||||
|
||||
prev_layer: any
|
||||
clicked_index: number | undefined
|
||||
|
||||
permanent_indices: number[]
|
||||
|
||||
prev_index: number
|
||||
is_stored: boolean[]
|
||||
layers: any[]
|
||||
class_name: ClassNameEnum[]
|
||||
can_click: boolean
|
||||
auto_mask: boolean
|
||||
}
|
||||
export const store = new AStore<AStoreData>({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
metadata: [], // metadata for each image
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
||||
prev_layer: null,
|
||||
clicked_index: undefined,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
auto_mask: true,
|
||||
})
|
||||
|
||||
const timer = (ms: any) => new Promise((res) => setTimeout(res, ms))
|
||||
//when a generation is done, add the last generated image from the viewer to tha canvas
|
||||
reaction(
|
||||
|
|
@ -134,71 +91,7 @@ reaction(
|
|||
}
|
||||
}
|
||||
)
|
||||
export const init_store = new AStore({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
||||
prev_layer: null,
|
||||
clicked_index: null,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
output_image_obj_list: [],
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
})
|
||||
export const mask_store = new AStore({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
output_images_masks: [],
|
||||
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
||||
prev_layer: null,
|
||||
clicked_index: null,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
output_image_obj_list: [],
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
})
|
||||
|
||||
interface AStoreDataWithImagesAndThumbnails {
|
||||
images: string[]
|
||||
thumbnails: string[]
|
||||
}
|
||||
|
||||
export async function updateViewerStoreImageAndThumbnail<
|
||||
T extends AStoreDataWithImagesAndThumbnails
|
||||
>(store: AStore<T>, images: string[]) {
|
||||
try {
|
||||
if (typeof images === 'undefined' || !images) {
|
||||
return null
|
||||
}
|
||||
store.data.images = images
|
||||
const thumbnail_list = []
|
||||
for (const base64 of images) {
|
||||
const thumbnail = await io.createThumbnail(base64, 300)
|
||||
thumbnail_list.push(thumbnail)
|
||||
}
|
||||
|
||||
store.data.thumbnails = thumbnail_list
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
console.warn('images: ', images)
|
||||
}
|
||||
}
|
||||
const add_new = async (
|
||||
base64: string,
|
||||
mask?: string,
|
||||
|
|
@ -239,7 +132,8 @@ const add_new = async (
|
|||
await selection.black_white_layer_to_mask_multi_batchplay(
|
||||
mask_layer.id,
|
||||
layer.id,
|
||||
'mask'
|
||||
'mask',
|
||||
mask_store.data.expand_by
|
||||
)
|
||||
await layer_util.deleteLayers([mask_layer])
|
||||
} else {
|
||||
|
|
@ -249,7 +143,8 @@ const add_new = async (
|
|||
channel_mask_monochrome.base64,
|
||||
layer.id,
|
||||
selectionInfo,
|
||||
settings_tab_ts.store.data.b_borders_or_corners
|
||||
settings_tab_ts.store.data.b_borders_or_corners,
|
||||
mask_store.data.expand_by
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -276,12 +171,12 @@ const add = async (
|
|||
store.data.auto_mask
|
||||
) {
|
||||
// const base64_monochrome_mask = await io.convertGrayscaleToMonochrome(
|
||||
// session_ts.store.data.selected_mask
|
||||
// session_store.data.selected_mask
|
||||
// )
|
||||
const timer = (ms: any) => new Promise((res) => setTimeout(res, ms))
|
||||
|
||||
const mask_monochrome = await io.convertGrayscaleToMonochrome(
|
||||
// session_ts.store.data.expanded_mask
|
||||
// session_store.data.expanded_mask
|
||||
mask
|
||||
)
|
||||
const channel_mask = mask_monochrome
|
||||
|
|
@ -292,7 +187,8 @@ const add = async (
|
|||
channel_mask,
|
||||
layer.id,
|
||||
selectionInfo,
|
||||
settings_tab_ts.store.data.b_borders_or_corners
|
||||
settings_tab_ts.store.data.b_borders_or_corners,
|
||||
mask_store.data.expand_by
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -339,21 +235,6 @@ const remove = async (layer: any) => {
|
|||
await layer_util.deleteLayers([layer]) // delete previous layer
|
||||
}
|
||||
|
||||
export const resetViewer = () => {
|
||||
store.updateProperty('images', [])
|
||||
store.data.thumbnails = []
|
||||
store.data.prev_index = -1
|
||||
store.data.is_stored = []
|
||||
store.data.layers = []
|
||||
store.data.class_name = []
|
||||
store.data.can_click = true
|
||||
|
||||
mask_store.data.images = []
|
||||
mask_store.data.thumbnails = []
|
||||
init_store.data.images = []
|
||||
init_store.data.thumbnails = []
|
||||
}
|
||||
|
||||
const addAll = async () => {
|
||||
let i = 0
|
||||
for (let i = 0; i < store.data.images.length; i++) {
|
||||
|
|
@ -366,22 +247,22 @@ const addAll = async () => {
|
|||
await addWithHistory(
|
||||
store.data.images[i],
|
||||
mask_store.data?.output_images_masks?.[i] ?? void 0,
|
||||
session_ts.store.data.selectionInfo,
|
||||
session_ts.store.data.mode
|
||||
session_store.data.selectionInfo,
|
||||
session_store.data.mode
|
||||
)
|
||||
}
|
||||
|
||||
session_ts.Session.endSession()
|
||||
Session.endSession()
|
||||
}
|
||||
const discardAll = async () => {
|
||||
for (let i = 0; i < store.data.images.length; i++) {
|
||||
await remove(store.data.layers[i])
|
||||
}
|
||||
|
||||
session_ts.Session.endSession()
|
||||
Session.endSession()
|
||||
}
|
||||
const onlySelected = () => {
|
||||
session_ts.Session.endSession()
|
||||
Session.endSession()
|
||||
}
|
||||
export const handleOutputImageThumbnailClick = async (
|
||||
index: number,
|
||||
|
|
@ -423,8 +304,8 @@ export const handleOutputImageThumbnailClick = async (
|
|||
const layer = await addWithHistory(
|
||||
image,
|
||||
mask_store.data?.output_images_masks?.[index] ?? void 0,
|
||||
session_ts.store.data.selectionInfo,
|
||||
session_ts.store.data.mode
|
||||
session_store.data.selectionInfo,
|
||||
session_store.data.mode
|
||||
)
|
||||
await remove(store.data.layers[index])
|
||||
console.log('layer:', layer)
|
||||
|
|
@ -458,8 +339,8 @@ export const handleOutputImageThumbnailClick = async (
|
|||
const layer = await addWithHistory(
|
||||
image,
|
||||
mask_store.data?.output_images_masks?.[index] ?? void 0,
|
||||
session_ts.store.data.selectionInfo,
|
||||
session_ts.store.data.mode
|
||||
session_store.data.selectionInfo,
|
||||
session_store.data.mode
|
||||
)
|
||||
await remove(store.data.layers[index])
|
||||
store.data.layers[index] = layer
|
||||
|
|
@ -512,7 +393,7 @@ export const handleOutputImageThumbnailClick = async (
|
|||
const Viewer = observer(() => {
|
||||
// console.log('rendered', store.toJsFunc())
|
||||
const display_button: Boolean =
|
||||
session_ts.store.data.is_active && session_ts.store.data.can_generate
|
||||
session_store.data.is_active && session_store.data.can_generate
|
||||
const button_style = {
|
||||
display: display_button ? 'block' : 'none',
|
||||
marginRight: '3px',
|
||||
|
|
@ -585,7 +466,7 @@ const Viewer = observer(() => {
|
|||
GenerationModeEnum.Inpaint,
|
||||
GenerationModeEnum.LassoInpaint,
|
||||
GenerationModeEnum.Outpaint,
|
||||
].includes(session_ts.store.data.mode)
|
||||
].includes(session_store.data.mode)
|
||||
? void 0
|
||||
: 'none',
|
||||
marginRight: '10px',
|
||||
|
|
@ -600,6 +481,21 @@ const Viewer = observer(() => {
|
|||
Locale('Apply Auto Masking')
|
||||
}
|
||||
</SpCheckBox>
|
||||
<SpSlider
|
||||
show-value="false"
|
||||
min={0}
|
||||
max={300}
|
||||
value={mask_store.data.expand_by}
|
||||
onInput={(evt: any) => {
|
||||
mask_store.data.expand_by = evt.target.value
|
||||
}}
|
||||
title="expand the Photoshop masking by x pixels"
|
||||
>
|
||||
<sp-label slot="label">{Locale('Expand by')}</sp-label>
|
||||
<sp-label slot="label">
|
||||
{mask_store.data.expand_by}
|
||||
</sp-label>
|
||||
</SpSlider>
|
||||
</div>
|
||||
<div style={{ border: '2px solid #6d6c6c', padding: '3px' }}>
|
||||
<Grid
|
||||
|
|
@ -633,7 +529,7 @@ const Viewer = observer(() => {
|
|||
callback: async (index: number) => {
|
||||
await moveImageToLayer(
|
||||
mask_store.data.images[index],
|
||||
session_ts.store.data.selectionInfo,
|
||||
session_store.data.selectionInfo,
|
||||
'mask'
|
||||
)
|
||||
},
|
||||
|
|
@ -675,7 +571,7 @@ const Viewer = observer(() => {
|
|||
|
||||
const ToolbarViewerButtons = observer(() => {
|
||||
const display_button: Boolean =
|
||||
session_ts.store.data.is_active && session_ts.store.data.can_generate
|
||||
session_store.data.is_active && session_store.data.can_generate
|
||||
const button_style = {
|
||||
display: display_button ? 'block' : 'none',
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,138 @@
|
|||
import { AStore } from '../main/astore'
|
||||
import { io } from '../util/oldSystem'
|
||||
|
||||
export enum ClickTypeEnum {
|
||||
Click = 'click',
|
||||
ShiftClick = 'shift_click',
|
||||
AltClick = 'alt_click',
|
||||
SecondClick = 'second_click', //when we click a thumbnail that is active/ has orange border
|
||||
}
|
||||
|
||||
export enum OutputImageStateEnum {
|
||||
Add = 'add',
|
||||
remove = 'remove',
|
||||
}
|
||||
export enum ClassNameEnum {
|
||||
Green = 'viewerImgSelected',
|
||||
Orange = 'viewerImgActive',
|
||||
None = '',
|
||||
}
|
||||
interface AStoreData {
|
||||
images: string[]
|
||||
thumbnails: string[]
|
||||
metadata: any[] // metadata for each image
|
||||
width: number
|
||||
height: number
|
||||
|
||||
prev_layer: any
|
||||
clicked_index: number | undefined
|
||||
|
||||
permanent_indices: number[]
|
||||
|
||||
prev_index: number
|
||||
is_stored: boolean[]
|
||||
layers: any[]
|
||||
class_name: ClassNameEnum[]
|
||||
can_click: boolean
|
||||
auto_mask: boolean
|
||||
}
|
||||
export const store = new AStore<AStoreData>({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
metadata: [], // metadata for each image
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
||||
prev_layer: null,
|
||||
clicked_index: undefined,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
auto_mask: true,
|
||||
})
|
||||
export const init_store = new AStore({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
|
||||
width: 50,
|
||||
height: 50,
|
||||
|
||||
prev_layer: null,
|
||||
clicked_index: null,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
output_image_obj_list: [],
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
})
|
||||
export const mask_store = new AStore({
|
||||
images: [],
|
||||
thumbnails: [],
|
||||
output_images_masks: [],
|
||||
|
||||
width: 50,
|
||||
height: 50,
|
||||
expand_by: 0,
|
||||
prev_layer: null,
|
||||
clicked_index: null,
|
||||
|
||||
permanent_indices: [],
|
||||
|
||||
prev_index: -1,
|
||||
output_image_obj_list: [],
|
||||
is_stored: [],
|
||||
layers: [],
|
||||
class_name: [],
|
||||
can_click: true,
|
||||
})
|
||||
|
||||
interface AStoreDataWithImagesAndThumbnails {
|
||||
images: string[]
|
||||
thumbnails: string[]
|
||||
}
|
||||
|
||||
export async function updateViewerStoreImageAndThumbnail<
|
||||
T extends AStoreDataWithImagesAndThumbnails
|
||||
>(store: AStore<T>, images: string[]) {
|
||||
try {
|
||||
if (typeof images === 'undefined' || !images) {
|
||||
return null
|
||||
}
|
||||
store.data.images = images
|
||||
const thumbnail_list = []
|
||||
for (const base64 of images) {
|
||||
const thumbnail = await io.createThumbnail(base64, 300)
|
||||
thumbnail_list.push(thumbnail)
|
||||
}
|
||||
|
||||
store.data.thumbnails = thumbnail_list
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
console.warn('images: ', images)
|
||||
}
|
||||
}
|
||||
|
||||
export const resetViewer = () => {
|
||||
store.updateProperty('images', [])
|
||||
store.data.thumbnails = []
|
||||
store.data.prev_index = -1
|
||||
store.data.is_stored = []
|
||||
store.data.layers = []
|
||||
store.data.class_name = []
|
||||
store.data.can_click = true
|
||||
|
||||
mask_store.data.images = []
|
||||
mask_store.data.thumbnails = []
|
||||
init_store.data.images = []
|
||||
init_store.data.thumbnails = []
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
const updatePresetMenuEvent = new CustomEvent('updatePresetMenuEvent', {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
composed: false,
|
||||
})
|
||||
function triggerEvent(query_selector, event) {
|
||||
document.querySelector(query_selector).dispatchEvent(event)
|
||||
}
|
||||
module.exports = {
|
||||
updatePresetMenuEvent,
|
||||
triggerEvent,
|
||||
}
|
||||
|
|
@ -51,41 +51,6 @@ function scaleToClosestKeepRatio(
|
|||
function mapRange(x, in_min, in_max, out_min, out_max) {
|
||||
return ((x - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
|
||||
}
|
||||
function scaleToRatio(
|
||||
new_value_1,
|
||||
old_value_1,
|
||||
new_value_2, //get ignored
|
||||
old_value_2,
|
||||
max_value,
|
||||
min_value
|
||||
) {
|
||||
const ratio = new_value_1 / old_value_1 // 1000/500 = 2
|
||||
let final_new_value_2 = old_value_2 * ratio // 500 * 2 = 1000
|
||||
let final_new_value_1 = new_value_1
|
||||
if (final_new_value_2 > max_value) {
|
||||
;[_, final_new_value_1] = scaleToRatio(
|
||||
max_value,
|
||||
old_value_2,
|
||||
new_value_1, //get ignored
|
||||
old_value_1,
|
||||
max_value,
|
||||
min_value
|
||||
)
|
||||
final_new_value_2 = max_value
|
||||
} else if (final_new_value_2 < min_value) {
|
||||
;[_, final_new_value_1] = scaleToRatio(
|
||||
min_value,
|
||||
old_value_2,
|
||||
new_value_1, //get ignored
|
||||
old_value_1,
|
||||
max_value,
|
||||
min_value
|
||||
)
|
||||
final_new_value_2 = min_value
|
||||
}
|
||||
|
||||
return [final_new_value_1, final_new_value_2]
|
||||
}
|
||||
|
||||
function compareVersions(version_1, version_2) {
|
||||
//remove the first character v
|
||||
|
|
@ -137,7 +102,7 @@ function sudoTimer(progress_text = 'Loading ControlNet...') {
|
|||
return timerId
|
||||
}
|
||||
function countNewLines(string) {
|
||||
const count = (string.match(/\n/g) || []).length
|
||||
const count = (string.match(/[\n\r]/g) || []).length
|
||||
// console.log(count)
|
||||
return count
|
||||
}
|
||||
|
|
@ -150,7 +115,7 @@ module.exports = {
|
|||
base64UrlToBase64,
|
||||
timer,
|
||||
scaleToClosestKeepRatio,
|
||||
scaleToRatio,
|
||||
|
||||
mapRange,
|
||||
compareVersions,
|
||||
requestOnlineData,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
////// Start Prompt//////////
|
||||
|
||||
function getPrompt() {
|
||||
// const prompt = document.getElementById('taPrompt').value
|
||||
const prompt = multiPrompts.getPrompt().positive
|
||||
return prompt
|
||||
}
|
||||
|
||||
function autoFillInPrompt(prompt_value) {
|
||||
// document.getElementById('taPrompt').value = prompt_value
|
||||
multiPrompts.setPrompt({ positive: prompt_value })
|
||||
|
|
@ -15,14 +9,6 @@ function autoFillInPrompt(prompt_value) {
|
|||
|
||||
////// Start Negative Prompt//////////
|
||||
|
||||
function getNegativePrompt() {
|
||||
// const negative_prompt = document.getElementById('taNegativePrompt').value
|
||||
|
||||
const negative_prompt = multiPrompts.getPrompt().negative
|
||||
|
||||
return negative_prompt
|
||||
}
|
||||
|
||||
function autoFillInNegativePrompt(negative_prompt_value) {
|
||||
// document.getElementById('taNegativePrompt').value = negative_prompt_value
|
||||
multiPrompts.setPrompt({ negative: negative_prompt_value })
|
||||
|
|
@ -32,103 +18,8 @@ function autoFillInNegativePrompt(negative_prompt_value) {
|
|||
|
||||
////// Start Width//////////
|
||||
|
||||
document.getElementById('slWidth').addEventListener('input', (evt) => {
|
||||
const width = evt.target.value * 64
|
||||
|
||||
document.getElementById('lWidth').textContent = parseInt(width)
|
||||
// widthSliderOnChangeEventHandler(evt)
|
||||
updateResDifferenceLabel()
|
||||
})
|
||||
|
||||
document.getElementById('slHeight').addEventListener('input', (evt) => {
|
||||
const height = evt.target.value * 64
|
||||
|
||||
document.getElementById('lHeight').textContent = parseInt(height)
|
||||
// heightSliderOnChangeEventHandler(evt)
|
||||
updateResDifferenceLabel()
|
||||
})
|
||||
|
||||
function widthSliderOnChangeEventHandler(evt) {
|
||||
let new_width = evt.target.value * 64
|
||||
const b_link = getLinkWidthHeightState()
|
||||
let final_width = new_width
|
||||
let final_height
|
||||
if (b_link) {
|
||||
const current_height = html_manip.getHeight()
|
||||
;[final_width, final_height] = general.scaleToRatio(
|
||||
new_width,
|
||||
g_old_slider_width,
|
||||
_,
|
||||
current_height,
|
||||
parseInt(evt.target.max * 64),
|
||||
parseInt(evt.target.min * 64)
|
||||
)
|
||||
|
||||
evt.target.value = parseInt(final_width / 64)
|
||||
html_manip.autoFillInHeight(final_height)
|
||||
}
|
||||
|
||||
g_old_slider_width = final_width // update the old value, so we can use it later
|
||||
document.getElementById('lWidth').textContent = parseInt(final_width)
|
||||
}
|
||||
document.getElementById('slWidth').addEventListener('change', (evt) => {
|
||||
widthSliderOnChangeEventHandler(evt)
|
||||
})
|
||||
// document.getElementById('slWidth').addEventListener('change', (evt) => {
|
||||
// let new_width = evt.target.value * 64
|
||||
// const b_link = getLinkWidthHeightState()
|
||||
// let final_width = new_width
|
||||
// let final_height
|
||||
// if (b_link) {
|
||||
// const current_height = html_manip.getHeight()
|
||||
// ;[final_width, final_height] = general.scaleToRatio(
|
||||
// new_width,
|
||||
// g_old_slider_width,
|
||||
// _,
|
||||
// current_height,
|
||||
// parseInt(evt.target.max * 64),
|
||||
// parseInt(evt.target.min * 64)
|
||||
// )
|
||||
|
||||
// evt.target.value = parseInt(final_width / 64)
|
||||
// html_manip.autoFillInHeight(final_height)
|
||||
// }
|
||||
|
||||
// g_old_slider_width = final_width // update the old value, so we can use it later
|
||||
// document.getElementById('lWidth').textContent = parseInt(final_width)
|
||||
// })
|
||||
|
||||
function heightSliderOnChangeEventHandler(evt) {
|
||||
let new_height = evt.target.value * 64
|
||||
|
||||
let final_width
|
||||
let final_height = new_height
|
||||
const b_link = getLinkWidthHeightState()
|
||||
if (b_link) {
|
||||
const current_width = html_manip.getWidth()
|
||||
;[final_height, final_width] = general.scaleToRatio(
|
||||
new_height,
|
||||
g_old_slider_height,
|
||||
_,
|
||||
current_width,
|
||||
parseInt(evt.target.max * 64),
|
||||
parseInt(evt.target.min * 64)
|
||||
)
|
||||
|
||||
evt.target.value = parseInt(final_height / 64)
|
||||
html_manip.autoFillInWidth(final_width)
|
||||
}
|
||||
g_old_slider_height = final_height // update the old value, so we can use it later
|
||||
document.getElementById('lHeight').textContent = parseInt(final_height)
|
||||
}
|
||||
document.getElementById('slHeight').addEventListener('change', (evt) => {
|
||||
heightSliderOnChangeEventHandler(evt)
|
||||
})
|
||||
|
||||
function getWidth() {
|
||||
slider_width = document.getElementById('slWidth').value
|
||||
const width = slider_width * 64
|
||||
return width
|
||||
return sd_tab_store.data.width
|
||||
}
|
||||
|
||||
function getHrWidth() {
|
||||
|
|
@ -142,147 +33,37 @@ function getHrHeight() {
|
|||
const width = slider_width * 64
|
||||
return width
|
||||
}
|
||||
function autoFillInWidth(width_value) {
|
||||
const width_slider = document.getElementById('slHeight')
|
||||
async function autoFillInWidth(width_value) {
|
||||
sd_tab_store.data.width = width_value
|
||||
sd_tab_util.helper_store.data.previous_width = width_value
|
||||
|
||||
// g_old_slider_width = width_slider.value * 64 //store the old value
|
||||
g_old_slider_width = width_value
|
||||
|
||||
document.getElementById('slWidth').value = `${width_value / 64}`
|
||||
//update the label
|
||||
document.getElementById('lWidth').innerHTML = `${parseInt(width_value)}`
|
||||
updateResDifferenceLabel()
|
||||
sd_tab_store.data.ratio =
|
||||
await selection.Selection.getImageToSelectionDifference()
|
||||
}
|
||||
////// End Width//////////
|
||||
|
||||
////// Start Height//////////
|
||||
|
||||
function getHeight() {
|
||||
slider_value = document.getElementById('slHeight').value
|
||||
const height = slider_value * 64
|
||||
return height
|
||||
// slider_value = document.getElementById('slHeight').value
|
||||
// const height = slider_value * 64
|
||||
return sd_tab_store.data.height
|
||||
}
|
||||
|
||||
function autoFillInHeight(height_value) {
|
||||
const height_slider = document.getElementById('slHeight')
|
||||
// g_old_slider_height = height_slider.value * 64
|
||||
g_old_slider_height = height_value //store the current value as old value. counterintuitive!. only use old value when the user directly manipulate the slider
|
||||
|
||||
height_slider.value = `${height_value / 64}`
|
||||
async function autoFillInHeight(height_value) {
|
||||
sd_tab_util.helper_store.data.previous_height = height_value
|
||||
sd_tab_store.data.height = height_value
|
||||
//update the label
|
||||
document.getElementById('lHeight').innerHTML = `${parseInt(height_value)}`
|
||||
updateResDifferenceLabel()
|
||||
sd_tab_store.data.ratio =
|
||||
await selection.Selection.getImageToSelectionDifference()
|
||||
}
|
||||
|
||||
function autoFillInHRHeight(height_value) {
|
||||
document.getElementById('hrHeight').value = `${height_value / 64}`
|
||||
//update the label
|
||||
document.getElementById('hHeight').innerHTML = `${height_value}`
|
||||
sd_tab_store.data.hr_resize_y = height_value
|
||||
}
|
||||
|
||||
function autoFillInHRWidth(height_value) {
|
||||
document.getElementById('hrWidth').value = `${height_value / 64}`
|
||||
//update the label
|
||||
document.getElementById('hWidth').innerHTML = `${height_value}`
|
||||
}
|
||||
|
||||
////// End Height//////////
|
||||
|
||||
////// Start Denoising Strength//////////
|
||||
document
|
||||
.querySelector('#slDenoisingStrength')
|
||||
.addEventListener('input', (evt) => {
|
||||
const label_value = evt.target.value / 100
|
||||
// console.log("label_value: ", label_value)
|
||||
document.getElementById(
|
||||
'lDenoisingStrength'
|
||||
).innerHTML = `${label_value}`
|
||||
})
|
||||
|
||||
//get the value that is relevant to stable diffusion
|
||||
function getDenoisingStrength() {
|
||||
const slider_value = document.getElementById('slDenoisingStrength').value
|
||||
const denoising_strength_value = slider_value / 100.0
|
||||
return denoising_strength_value
|
||||
}
|
||||
|
||||
// display the value the user need to see in all elements related to denoising strength attribute
|
||||
function autoFillInDenoisingStrength(denoising_strength_value) {
|
||||
//sd denoising strength value range from [0,1] slider range from [0, 100]
|
||||
//update the slider
|
||||
document.getElementById('slDenoisingStrength').value = `${
|
||||
denoising_strength_value * 100
|
||||
}`
|
||||
//update the label
|
||||
document.getElementById(
|
||||
'lDenoisingStrength'
|
||||
).innerHTML = `${denoising_strength_value}`
|
||||
}
|
||||
|
||||
////// End Denoising Strength//////////
|
||||
|
||||
////// Start Hi Res Fix//////////
|
||||
|
||||
document.getElementById('chInpaintFullRes').addEventListener('click', (ev) => {
|
||||
const inpaint_padding_slider = document.getElementById('slInpaintPadding')
|
||||
|
||||
if (ev.target.checked) {
|
||||
inpaint_padding_slider.style.display = 'block'
|
||||
} else {
|
||||
inpaint_padding_slider.style.display = 'none'
|
||||
}
|
||||
})
|
||||
document.getElementById('chHiResFixs').addEventListener('click', (ev) => {
|
||||
const container = document.getElementById('hi-res-sliders-container')
|
||||
|
||||
if (ev.target.checked) {
|
||||
container.style.display = 'flex'
|
||||
} else {
|
||||
container.style.display = 'none'
|
||||
}
|
||||
})
|
||||
//get the value that is relevant to stable diffusion
|
||||
function getHiResFixs() {
|
||||
const isChecked = document.getElementById('chHiResFixs').checked
|
||||
return isChecked
|
||||
}
|
||||
|
||||
function setHiResFixs(isChecked) {
|
||||
document.getElementById('chHiResFixs').checked = isChecked
|
||||
}
|
||||
|
||||
function sliderAddEventListener(
|
||||
slider_id,
|
||||
label_id,
|
||||
multiplier,
|
||||
fractionDigits = 2
|
||||
) {
|
||||
document.getElementById(slider_id).addEventListener('input', (evt) => {
|
||||
const sd_value = evt.target.value * multiplier // convert slider value to SD ready value
|
||||
document.getElementById(label_id).textContent =
|
||||
Number(sd_value).toFixed(fractionDigits)
|
||||
})
|
||||
}
|
||||
function sliderAddEventListener_new(
|
||||
slider_id,
|
||||
label_id,
|
||||
slider_start,
|
||||
slider_end,
|
||||
sd_start,
|
||||
sd_end
|
||||
) {
|
||||
document.getElementById(slider_id).addEventListener('input', (evt) => {
|
||||
const sd_value = general.mapRange(
|
||||
evt.target.value,
|
||||
slider_start,
|
||||
slider_end,
|
||||
sd_start,
|
||||
sd_end
|
||||
) // convert slider value to SD ready value
|
||||
|
||||
document.getElementById(label_id).textContent =
|
||||
Number(sd_value).toFixed(2)
|
||||
})
|
||||
function autoFillInHRWidth(width_value) {
|
||||
sd_tab_store.data.hr_resize_x = width_value
|
||||
}
|
||||
|
||||
//get the stable diffusion ready value from the slider with "slider_id"
|
||||
|
|
@ -383,13 +164,6 @@ function setSliderSdValueByElements(
|
|||
label_element.innerHTML = sd_value.toString()
|
||||
}
|
||||
|
||||
//hrWidth is from [1 to 32] * 64 => [64 to 2048]
|
||||
sliderAddEventListener('hrWidth', 'hWidth', 64)
|
||||
sliderAddEventListener('hrHeight', 'hHeight', 64)
|
||||
|
||||
//convert hrDenoisingStrength from [1, 100] * 0.01 => [0.01 to 1]
|
||||
sliderAddEventListener('hrDenoisingStrength', 'hDenoisingStrength', 0.01)
|
||||
|
||||
function autoFillInHiResFixs(firstphase_width, firstphase_height) {
|
||||
//update the firstphase width slider and label
|
||||
autoFillInSliderUi(firstphase_width, 'hrWidth', 'hWidth', 1.0 / 64)
|
||||
|
|
@ -442,23 +216,6 @@ function getSamplerElementByName(sampler_name) {
|
|||
}
|
||||
}
|
||||
|
||||
function getCheckedSamplerName() {
|
||||
//we assume that the samplers exist and loaded in html
|
||||
//return the name of the first checked sampler
|
||||
try {
|
||||
return [...document.getElementsByClassName('rbSampler')].filter(
|
||||
(elm) => elm.checked == true
|
||||
)[0].value
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
function getMode() {
|
||||
return [...document.getElementsByClassName('rbMode')].filter(
|
||||
(e) => e.checked == true
|
||||
)[0].value
|
||||
}
|
||||
|
||||
function getBackendType() {
|
||||
return [...document.getElementsByClassName('rbBackendType')].filter(
|
||||
(e) => e.checked == true
|
||||
|
|
@ -525,18 +282,6 @@ function selectModelUi(model_hash) {
|
|||
model_element.selected = true
|
||||
}
|
||||
|
||||
function autoFillInModel(model_hash) {
|
||||
try {
|
||||
// unCheckAllSamplers()
|
||||
model_element = getModelElementByHash(model_hash)
|
||||
selectModelUi(model_hash)
|
||||
// model_element.
|
||||
const model_title = model_element.dataset.model_title
|
||||
return model_title
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
////// End Models//////////
|
||||
|
||||
////// Start Init Image && Init Image Mask//////////
|
||||
|
|
@ -601,105 +346,8 @@ function setProxyServerStatus(newStatusClass, oldStatusClass) {
|
|||
}
|
||||
////// End Servers Status //////////
|
||||
|
||||
////// Start Extras //////////
|
||||
|
||||
sliderAddEventListener('slUpscaleSize', 'lUpscaleSize', 0.1, 1)
|
||||
|
||||
function getUpscaleSize() {
|
||||
slider_width = document.getElementById('slUpscaleSize').value
|
||||
const size = slider_width / 10
|
||||
return size
|
||||
}
|
||||
|
||||
sliderAddEventListener('slUpscaler2Visibility', 'lUpscaler2Visibility', 0.1, 1)
|
||||
|
||||
function getUpscaler2Visibility() {
|
||||
slider_width = document.getElementById('slUpscaler2Visibility').value
|
||||
const size = slider_width / 10
|
||||
return size
|
||||
}
|
||||
|
||||
sliderAddEventListener('slGFPGANVisibility', 'lGFPGANVisibility', 0.1, 1)
|
||||
|
||||
function getGFPGANVisibility() {
|
||||
slider_width = document.getElementById('slGFPGANVisibility').value
|
||||
const size = slider_width / 10
|
||||
return size
|
||||
}
|
||||
|
||||
sliderAddEventListener(
|
||||
'slCodeFormerVisibility',
|
||||
'lCodeFormerVisibility',
|
||||
0.1,
|
||||
1
|
||||
)
|
||||
|
||||
function getCodeFormerVisibility() {
|
||||
slider_width = document.getElementById('slCodeFormerVisibility').value
|
||||
const size = slider_width / 10
|
||||
return size
|
||||
}
|
||||
|
||||
sliderAddEventListener('slCodeFormerWeight', 'lCodeFormerWeight', 0.1, 1)
|
||||
|
||||
function getCodeFormerWeight() {
|
||||
slider_width = document.getElementById('slCodeFormerWeight').value
|
||||
const size = slider_width / 10
|
||||
return size
|
||||
}
|
||||
|
||||
////// End Extras //////////
|
||||
|
||||
////// Start Reset Settings Button //////////
|
||||
|
||||
const defaultSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: '',
|
||||
negative_prompt: '',
|
||||
selection_mode: null,
|
||||
batch_number: 1,
|
||||
steps: 20,
|
||||
width: 512,
|
||||
height: 512,
|
||||
firstphase_width: 512,
|
||||
firstphase_height: 512,
|
||||
cfg: 7,
|
||||
denoising_strength: 0.7,
|
||||
hi_res_denoising_strength: 0.7,
|
||||
mask_blur: 8,
|
||||
inpaint_at_full_res: false,
|
||||
hi_res_fix: false,
|
||||
inpaint_padding: 0,
|
||||
seed: -1,
|
||||
samplers: null,
|
||||
mask_content: null,
|
||||
}
|
||||
|
||||
const snapshot_btns = Array.from(
|
||||
document.getElementsByClassName('snapshotButton')
|
||||
)
|
||||
snapshot_btns.forEach((element) =>
|
||||
element.addEventListener('click', async () => {
|
||||
try {
|
||||
await psapi.snapshot_layerExe()
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const reset_btns = Array.from(document.getElementsByClassName('resetButton'))
|
||||
reset_btns.forEach((element) =>
|
||||
element.addEventListener('click', async () => {
|
||||
try {
|
||||
autoFillDefaultSettings(defaultSettings)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
function getBatchNumber() {
|
||||
// return document.getElementById('tiNumberOfImages').value
|
||||
return document.getElementById('tiNumberOfBatchSize').value
|
||||
|
|
@ -709,67 +357,45 @@ function autoFillInBatchNumber(batch_number) {
|
|||
document.getElementById('tiNumberOfBatchSize').value = String(batch_number)
|
||||
}
|
||||
|
||||
function getSteps() {
|
||||
return document.getElementById('tiNumberOfSteps').value
|
||||
}
|
||||
function autoFillInSteps(steps) {
|
||||
document.getElementById('tiNumberOfSteps').value = String(steps)
|
||||
}
|
||||
function autoFillDefaultSettings(default_settings) {
|
||||
autoFillSettings(default_settings)
|
||||
}
|
||||
|
||||
function setCFG(cfg_value) {
|
||||
document.getElementById('slCfgScale').value = cfg_value
|
||||
sd_tab_store.data.cfg = cfg_value
|
||||
}
|
||||
function getCFG() {
|
||||
return document.getElementById('slCfgScale').value
|
||||
return sd_tab_store.data.cfg
|
||||
}
|
||||
|
||||
function autoFillSettings(settings) {
|
||||
try {
|
||||
//reset all UI settings except model selection and sampler selection
|
||||
autoFillInPrompt(settings['positive_prompt'])
|
||||
autoFillInNegativePrompt(settings['negative_prompt'])
|
||||
|
||||
multiPrompts.setPrompt({ positive: settings['positive_prompt'] })
|
||||
multiPrompts.setPrompt({ negative: settings['negative_prompt'] })
|
||||
autoFillInBatchNumber(settings['batch_number'])
|
||||
autoFillInSteps(settings['steps'])
|
||||
sd_tab_store.data.steps = settings['steps']
|
||||
autoFillInWidth(settings['width'])
|
||||
autoFillInHeight(settings['height'])
|
||||
autoFillInHiResFixs(
|
||||
settings['firstphase_width'],
|
||||
settings['firstphase_height']
|
||||
)
|
||||
document.getElementById('slCfgScale').value = settings['cfg']
|
||||
autoFillInDenoisingStrength(settings['denoising_strength'])
|
||||
sd_tab_store.data.cfg = settings['cfg']
|
||||
sd_tab_store.data.denoising_strength = settings['denoising_strength']
|
||||
autoFillInSliderUi(
|
||||
settings['hi_res_denoising_strength'],
|
||||
'hrDenoisingStrength',
|
||||
'hDenoisingStrength',
|
||||
100
|
||||
)
|
||||
document.getElementById('slMaskBlur').value = settings['mask_blur']
|
||||
document.getElementById('chInpaintFullRes').checked =
|
||||
settings['inpaint_at_full_res']
|
||||
setHiResFixs(settings['hi_res_fix'])
|
||||
document.getElementById('tiSeed').value = String(settings['seed'])
|
||||
sd_tab_store.data.mask_blur = settings['mask_blur']
|
||||
sd_tab_store.data.inpaint_full_res = settings['inpaint_at_full_res']
|
||||
sd_tab_store.data.enable_hr = settings['hi_res_fix']
|
||||
sd_tab_store.data.seed = String(settings['seed'])
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
////// End Reset Settings Button //////////
|
||||
|
||||
function getMaskBlur() {
|
||||
const isDisabled = document
|
||||
.getElementById('slMaskBlur')
|
||||
.hasAttribute('disabled')
|
||||
let mask_blur = 0
|
||||
if (isDisabled) {
|
||||
mask_blur = 0
|
||||
} else {
|
||||
mask_blur = document.getElementById('slMaskBlur').value
|
||||
}
|
||||
return mask_blur
|
||||
}
|
||||
function setMaskBlur(mask_blur) {
|
||||
document.getElementById('slMaskBlur').value = mask_blur
|
||||
}
|
||||
|
|
@ -789,12 +415,6 @@ function setPromptShortcut(prompt_shortcut) {
|
|||
document.getElementById('taPromptShortcut').value = JSONInPrettyFormat
|
||||
}
|
||||
|
||||
////start selection mode/////
|
||||
function getSelectionMode() {
|
||||
return [...document.getElementsByClassName('rbSelectionMode')].filter(
|
||||
(e) => e.checked == true
|
||||
)[0].value
|
||||
}
|
||||
function getMaskContent() {
|
||||
return [...document.getElementsByClassName('rbMaskContent')].filter(
|
||||
(e) => e.checked == true
|
||||
|
|
@ -851,22 +471,6 @@ function addHistoryButtonsHtml(img_html) {
|
|||
|
||||
return container
|
||||
}
|
||||
function getSeed() {
|
||||
const seed = document.getElementById('tiSeed').value
|
||||
return seed
|
||||
}
|
||||
function setSeed(new_seed) {
|
||||
document.getElementById('tiSeed').value = new_seed
|
||||
}
|
||||
|
||||
function getMaskExpansion() {
|
||||
const mask_expansion = document.getElementById('slMaskExpansion').value
|
||||
return mask_expansion
|
||||
}
|
||||
|
||||
function setMaskExpansion(mask_expansion) {
|
||||
document.getElementById('slMaskExpansion').value = mask_expansion
|
||||
}
|
||||
|
||||
function updateProgressBarsHtml(new_value, progress_text = 'Progress...') {
|
||||
document.querySelectorAll('.pProgressBars').forEach((bar_elm) => {
|
||||
|
|
@ -888,14 +492,7 @@ function updateProgressBarsHtml(new_value, progress_text = 'Progress...') {
|
|||
// document.querySelector('#pProgressBar').value
|
||||
}
|
||||
///end selection mode////
|
||||
function getLinkWidthHeightState() {
|
||||
const state_str = document.getElementById('linkWidthHeight').dataset.b_link // sometime it's true and other time it's "true"
|
||||
const b_state = state_str.toString() === 'true' ? true : false
|
||||
return b_state
|
||||
}
|
||||
function setLinkWidthHeightState(state) {
|
||||
document.getElementById('linkWidthHeight').dataset.b_link = state
|
||||
}
|
||||
|
||||
function isSquareThumbnail() {
|
||||
return document.getElementById('chSquareThumbnail').checked
|
||||
}
|
||||
|
|
@ -1071,12 +668,10 @@ function getUseSilentMode() {
|
|||
}
|
||||
|
||||
module.exports = {
|
||||
getPrompt,
|
||||
autoFillInPrompt,
|
||||
getNegativePrompt,
|
||||
|
||||
autoFillInNegativePrompt,
|
||||
getDenoisingStrength,
|
||||
autoFillInDenoisingStrength,
|
||||
|
||||
getWidth,
|
||||
autoFillInWidth,
|
||||
getHeight,
|
||||
|
|
@ -1084,22 +679,19 @@ module.exports = {
|
|||
getSliderSdValue,
|
||||
setSliderSdValue,
|
||||
autoFillInHiResFixs,
|
||||
getHiResFixs,
|
||||
setHiResFixs,
|
||||
|
||||
autoFillInSliderUi,
|
||||
getCheckedSamplerName,
|
||||
|
||||
autoFillInSampler,
|
||||
autoFillInModel,
|
||||
getMode,
|
||||
|
||||
setInitImageSrc,
|
||||
setInitImageMaskSrc,
|
||||
|
||||
setAutomaticStatus,
|
||||
setProxyServerStatus,
|
||||
defaultSettings,
|
||||
autoFillDefaultSettings,
|
||||
|
||||
autoFillSettings,
|
||||
getMaskBlur,
|
||||
|
||||
setMaskBlur,
|
||||
|
||||
autoFillInHRHeight,
|
||||
|
|
@ -1107,10 +699,9 @@ module.exports = {
|
|||
getPromptShortcut,
|
||||
setPromptShortcut,
|
||||
getModelHashByTitle,
|
||||
getSelectionMode,
|
||||
|
||||
autoFillInInpaintMaskWeight,
|
||||
autoFillInSteps,
|
||||
getSteps,
|
||||
|
||||
getBatchNumber,
|
||||
autoFillInBatchNumber,
|
||||
getHrWidth,
|
||||
|
|
@ -1121,21 +712,11 @@ module.exports = {
|
|||
setMaskContent,
|
||||
addHistoryButtonsHtml,
|
||||
|
||||
getSeed,
|
||||
setSeed,
|
||||
getMaskExpansion,
|
||||
setMaskExpansion,
|
||||
getUpscaleSize,
|
||||
getUpscaler2Visibility,
|
||||
getCodeFormerVisibility,
|
||||
getGFPGANVisibility,
|
||||
getCodeFormerWeight,
|
||||
updateProgressBarsHtml,
|
||||
getBackendType,
|
||||
getHordeApiKey,
|
||||
setProgressImageSrc,
|
||||
getLinkWidthHeightState,
|
||||
setLinkWidthHeightState,
|
||||
|
||||
isSquareThumbnail,
|
||||
setControlImageSrc,
|
||||
|
||||
|
|
@ -1150,7 +731,7 @@ module.exports = {
|
|||
getSliderSdValue_Old,
|
||||
getSelectedRadioButtonElement,
|
||||
getInitImageMaskElement,
|
||||
sliderAddEventListener_new,
|
||||
|
||||
getSliderSdValueByElement,
|
||||
setSliderSdValueByElements,
|
||||
populateMenuByElement,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class Notification {
|
|||
static async webuiIsOffline() {
|
||||
const r1 = await dialog_box.prompt(
|
||||
'Automatic1111 is Offline',
|
||||
"make sure Automatic1111 is running in the background, or select the 'native horde' option from the horde tab",
|
||||
'make sure Automatic1111 is running in the background',
|
||||
['Cancel', 'OK']
|
||||
)
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ class Notification {
|
|||
psapi.selectMarqueeRectangularToolExe()
|
||||
return false // should this be false?! what does true and false means in this context?! Yes: it should be false since boolean value represent wither we have an active selection area or not
|
||||
} else if (r1 === button_label) {
|
||||
await activateSessionSelectionArea()
|
||||
await selection_ts.activateSessionSelectionArea()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -1,406 +0,0 @@
|
|||
const io = require('../io')
|
||||
const html_manip = require('../html_manip')
|
||||
const Enum = require('../../enum')
|
||||
const event = require('../event')
|
||||
|
||||
let settings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
selection_mode: null,
|
||||
batch_number: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: null,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: null,
|
||||
}
|
||||
|
||||
let LatentNoiseSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_number: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.92,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '2',
|
||||
}
|
||||
|
||||
let FillSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_number: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.7,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '0',
|
||||
}
|
||||
let OriginalSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_number: null,
|
||||
steps: null,
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: null,
|
||||
denoising_strength: 0.7,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: null,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '1',
|
||||
}
|
||||
let HealBrushSettings = {
|
||||
model: null,
|
||||
prompt_shortcut: null,
|
||||
positive_prompt: null,
|
||||
negative_prompt: null,
|
||||
generation_mode: null,
|
||||
batch_number: null,
|
||||
steps: '25',
|
||||
width: null,
|
||||
height: null,
|
||||
firstphase_width: null,
|
||||
firstphase_height: null,
|
||||
cfg: '9',
|
||||
denoising_strength: 0.92,
|
||||
hi_res_denoising_strength: null,
|
||||
mask_blur: 1,
|
||||
inpaint_at_full_res: null,
|
||||
hi_res_fix: null,
|
||||
inpaint_padding: null,
|
||||
seed: null,
|
||||
samplers: null,
|
||||
mask_content: '2',
|
||||
mask_expansion: 2,
|
||||
}
|
||||
|
||||
function nullAllSettings() {}
|
||||
|
||||
class Preset {
|
||||
constructor() {}
|
||||
|
||||
loadPresetFromJson(preset_path) {}
|
||||
savePresetToJson(preset_path, settings) {}
|
||||
}
|
||||
|
||||
function getPresetSettingsHtml() {
|
||||
const value_str = document.getElementById('taPresetSettings').value
|
||||
const value_json = JSON.parse(value_str)
|
||||
return value_json
|
||||
}
|
||||
function setPresetSettingsHtml(preset_settings) {
|
||||
const JSONInPrettyFormat = JSON.stringify(preset_settings, undefined, 7)
|
||||
preset_settings_element = document.getElementById('taPresetSettings')
|
||||
preset_settings_element.value = JSONInPrettyFormat
|
||||
|
||||
const new_lines_count = general.countNewLines(JSONInPrettyFormat)
|
||||
new_lines_count
|
||||
preset_settings_element.style.height =
|
||||
Math.min(new_lines_count * 12 + 100, 800).toString() + 'px'
|
||||
}
|
||||
|
||||
function getPresetName() {
|
||||
const preset_name = document.getElementById('tiPresetName').value
|
||||
return preset_name
|
||||
}
|
||||
function setPresetName(preset_name) {
|
||||
document.getElementById('tiPresetName').value = preset_name
|
||||
}
|
||||
|
||||
function getPresetSettings(preset_type) {
|
||||
let preset_settings
|
||||
if (preset_type === Enum.PresetTypeEnum['SDPreset']) {
|
||||
preset_settings = g_ui_settings_object.getSettings()
|
||||
} else if (preset_type === Enum.PresetTypeEnum['ControlNetPreset']) {
|
||||
const { getUnitsData } =
|
||||
require('../../typescripts/dist/bundle').control_net // only import ControlNetUnit to avoid circular dependency
|
||||
preset_settings = getUnitsData()
|
||||
}
|
||||
return preset_settings
|
||||
}
|
||||
|
||||
function getPresetType() {
|
||||
const presetType = document.getElementById('rgPresetType').selected
|
||||
|
||||
return presetType
|
||||
}
|
||||
|
||||
document.getElementById('btnNewPreset').addEventListener('click', () => {
|
||||
// const g_ui_settings_object = getUISettingsObject()
|
||||
|
||||
const preset_type = getPresetType()
|
||||
const preset_settings = getPresetSettings(preset_type)
|
||||
|
||||
// const settings = g_ui_settings_object.getSettings()
|
||||
|
||||
setPresetSettingsHtml(preset_settings)
|
||||
|
||||
const preset_name = getPresetName()
|
||||
setPresetNameLabel(preset_name)
|
||||
})
|
||||
|
||||
function getPresetNameLabel() {
|
||||
//use presetNameLabel as the final name for a preset
|
||||
const preset_name = document.getElementById('lPresetName').textContent
|
||||
return preset_name
|
||||
}
|
||||
function setPresetNameLabel(preset_name) {
|
||||
document.getElementById('lPresetName').textContent = preset_name.trim()
|
||||
}
|
||||
|
||||
async function populatePresetMenu() {
|
||||
// presets = ['preset_1', 'preset_2', 'preset_3']
|
||||
const preset_type = getPresetType()
|
||||
const presets = await getAllCustomPresetsSettings(preset_type)
|
||||
const presets_names = Object.keys(presets)
|
||||
html_manip.populateMenu(
|
||||
'mSettingTabPresetMenu',
|
||||
'mPresetMenuItemClass',
|
||||
presets_names,
|
||||
(item, item_html_element) => {
|
||||
item_html_element.innerHTML = item
|
||||
}
|
||||
)
|
||||
}
|
||||
async function deletePreset() {
|
||||
try {
|
||||
const preset_name = html_manip.getSelectedMenuItemTextContent(
|
||||
'mSettingTabPresetMenu'
|
||||
)
|
||||
const preset_file_name = preset_name + '.json'
|
||||
|
||||
const preset_type = getPresetType()
|
||||
const preset_folder_name = mapPresetTypeToPresetFolder(preset_type)
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
preset_folder_name
|
||||
)
|
||||
|
||||
await io.IOJson.deleteFile(custom_preset_entry, preset_file_name)
|
||||
html_manip.unselectMenuItem('mSettingTabPresetMenu') // unselect the custom preset menu
|
||||
setPresetSettingsHtml({}) //reset preset settings text area
|
||||
setPresetName('')
|
||||
setPresetNameLabel('')
|
||||
await populatePresetMenu() // update the custom preset Menu
|
||||
triggerUpdatePresetMenu(preset_type)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
async function getCustomPresetEntries(preset_folder_name) {
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
preset_folder_name
|
||||
)
|
||||
|
||||
const custom_preset_entries = await io.IOJson.getJsonEntries(
|
||||
custom_preset_entry
|
||||
)
|
||||
|
||||
return custom_preset_entries
|
||||
}
|
||||
|
||||
async function loadPresetSettingsFromFile(preset_file_name, preset_type) {
|
||||
// const preset_type = getPresetType()
|
||||
|
||||
const preset_folder_name = mapPresetTypeToPresetFolder(preset_type)
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
preset_folder_name
|
||||
)
|
||||
let preset_settings = {}
|
||||
try {
|
||||
preset_settings = await io.IOJson.loadJsonFromFile(
|
||||
custom_preset_entry,
|
||||
preset_file_name
|
||||
)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
return preset_settings
|
||||
}
|
||||
async function getAllCustomPresetsSettings(preset_type) {
|
||||
const preset_folder_name = mapPresetTypeToPresetFolder(preset_type)
|
||||
const custom_preset_entries = await getCustomPresetEntries(
|
||||
preset_folder_name
|
||||
)
|
||||
let custom_presets = {}
|
||||
for (const entry of custom_preset_entries) {
|
||||
const preset_name = entry.name.split('.json')[0]
|
||||
let preset_settings = await loadPresetSettingsFromFile(
|
||||
entry.name,
|
||||
preset_type
|
||||
)
|
||||
|
||||
custom_presets[preset_name] = preset_settings
|
||||
}
|
||||
return custom_presets
|
||||
}
|
||||
|
||||
function mapPresetTypeToPresetFolder(preset_type) {
|
||||
let preset_folder
|
||||
|
||||
if (preset_type === Enum.PresetTypeEnum['SDPreset']) {
|
||||
preset_folder = 'custom_preset'
|
||||
} else if (preset_type === Enum.PresetTypeEnum['ControlNetPreset']) {
|
||||
preset_folder = 'controlnet_preset'
|
||||
}
|
||||
return preset_folder
|
||||
}
|
||||
|
||||
function triggerUpdatePresetMenu(preset_type) {
|
||||
let menu_id
|
||||
if (preset_type === Enum.PresetTypeEnum['SDPreset']) {
|
||||
menu_id = '#mPresetMenu'
|
||||
} else if (preset_type === Enum.PresetTypeEnum['ControlNetPreset']) {
|
||||
menu_id = '#mControlNetPresetMenu'
|
||||
}
|
||||
event.triggerEvent(menu_id, event.updatePresetMenuEvent)
|
||||
}
|
||||
Array.from(document.getElementsByClassName('rbPresetType')).forEach((rb) => {
|
||||
rb.addEventListener('click', async () => {
|
||||
const preset_type = rb.value
|
||||
await populatePresetMenu()
|
||||
})
|
||||
})
|
||||
|
||||
document.getElementById('btnSavePreset').addEventListener('click', async () => {
|
||||
//save preset settings from textarea to json file
|
||||
//reload the preset menu
|
||||
const preset_type = getPresetType()
|
||||
const custom_preset_folder_name = mapPresetTypeToPresetFolder(preset_type)
|
||||
const custom_preset_entry = await io.IOFolder.getCustomPresetFolder(
|
||||
custom_preset_folder_name
|
||||
)
|
||||
const preset_settings = getPresetSettingsHtml()
|
||||
const preset_name = getPresetNameLabel()
|
||||
|
||||
//check if the file exist and prompt the user to override it or cancel
|
||||
await io.IOJson.saveJsonToFileExe(
|
||||
preset_settings,
|
||||
custom_preset_entry,
|
||||
preset_name + '.json'
|
||||
)
|
||||
await populatePresetMenu()
|
||||
triggerUpdatePresetMenu(preset_type)
|
||||
html_manip.selectMenuItem('mSettingTabPresetMenu', preset_name)
|
||||
})
|
||||
document
|
||||
.getElementById('btnDeletePreset')
|
||||
.addEventListener('click', async () => {
|
||||
await deletePreset()
|
||||
})
|
||||
|
||||
document.getElementById('tiPresetName').addEventListener('input', () => {
|
||||
//save preset settings from textarea to json file
|
||||
//reload the preset menu
|
||||
const preset_name = getPresetName()
|
||||
setPresetNameLabel(preset_name)
|
||||
//check if the file exist and prompt the user to override it or cancel
|
||||
})
|
||||
document
|
||||
.getElementById('mSettingTabPresetMenu')
|
||||
.addEventListener('input', () => {
|
||||
//Note: is this correct?! why use Input and change events together
|
||||
//save preset settings from textarea to json file
|
||||
//reload the preset menu
|
||||
const preset_name = getPresetName()
|
||||
setPresetNameLabel(preset_name)
|
||||
//check if the file exist and prompt the user to override it or cancel
|
||||
})
|
||||
|
||||
document
|
||||
.getElementById('mSettingTabPresetMenu')
|
||||
.addEventListener('change', async (evt) => {
|
||||
try {
|
||||
const preset_index = evt.target.selectedIndex
|
||||
const preset_name = evt.target.options[preset_index].textContent
|
||||
const preset_type = getPresetType()
|
||||
setPresetName(preset_name)
|
||||
setPresetNameLabel(preset_name)
|
||||
|
||||
const preset_settings = await loadPresetSettingsFromFile(
|
||||
preset_name + '.json',
|
||||
preset_type
|
||||
)
|
||||
setPresetSettingsHtml(preset_settings)
|
||||
} catch (e) {}
|
||||
})
|
||||
|
||||
document
|
||||
.getElementById('mPresetMenu')
|
||||
.addEventListener('updatePresetMenuEvent', async (event) => {
|
||||
// console.log("I'm listening on a custom event")
|
||||
const { populatePresetMenu } = require('../ui')
|
||||
await populatePresetMenu()
|
||||
})
|
||||
|
||||
async function initializePresetTab() {
|
||||
try {
|
||||
await populatePresetMenu()
|
||||
|
||||
const selected_rb =
|
||||
html_manip.getSelectedRadioButtonElement('rbPresetType')
|
||||
selected_rb.click() // to trigger the click event which will update the setting preset menu according to the preset type
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
initializePresetTab()
|
||||
module.exports = {
|
||||
LatentNoiseSettings,
|
||||
FillSettings,
|
||||
OriginalSettings,
|
||||
HealBrushSettings,
|
||||
populatePresetMenu,
|
||||
getCustomPresetEntries,
|
||||
loadPresetSettingsFromFile,
|
||||
getAllCustomPresetsSettings,
|
||||
initializePresetTab,
|
||||
}
|
||||
|
|
@ -222,7 +222,7 @@ async function txt2ImgRequest(payload) {
|
|||
// const request_path = '/sdapi/v1/txt2img'
|
||||
}
|
||||
function getExtensionUrl() {
|
||||
const extension_type = settings_tab.getExtensionType()
|
||||
const extension_type = settings_tab_ts.store.data.extension_type
|
||||
let extension_url
|
||||
|
||||
if (extension_type === 'auto1111_extension') {
|
||||
|
|
@ -305,31 +305,6 @@ async function img2ImgRequest(sd_url, payload) {
|
|||
payload['prompt'] = new_prompt
|
||||
payload['negative_prompt'] = new_negative_prompt
|
||||
}
|
||||
// init_img_dir = "./init_images"
|
||||
// init_img_name = payload['init_image_name']
|
||||
// init_img = Image.open(f"{init_img_dir}/{init_img_name}")
|
||||
// init_img_str = img_2_b64(init_img)
|
||||
// payload['init_images'] = [init_img_str]
|
||||
|
||||
// init_img_mask_name = payload.get('init_image_mask_name',"")
|
||||
|
||||
// #only if image exist then try to open it
|
||||
|
||||
// if(len(init_img_mask_name) > 0):
|
||||
// init_img_mask = Image.open(f"{init_img_dir}/{init_img_mask_name}")
|
||||
|
||||
// if (payload['use_sharp_mask'] === false && payload['mask']) {
|
||||
// //only if mask is available and sharp_mask is off
|
||||
// // use blurry and expanded mask
|
||||
// const iterations = payload['mask_expansion']
|
||||
// const mask = await maskExpansionRequest(payload['mask'], iterations)
|
||||
// if (mask) {
|
||||
// payload['mask'] = mask
|
||||
// }
|
||||
// }
|
||||
|
||||
// print(type(init_img_str))
|
||||
// #request the images to be generated
|
||||
|
||||
const endpoint = 'sdapi/v1/img2img'
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ const Enum = require('../enum')
|
|||
const { base64ToBase64Url } = require('./general')
|
||||
const html_manip = require('./html_manip')
|
||||
const layer_util = require('./layer')
|
||||
|
||||
const SessionState = {
|
||||
Active: 'active',
|
||||
Inactive: 'inactive',
|
||||
|
|
@ -181,21 +182,16 @@ async function getSettings(session_data) {
|
|||
let payload = {}
|
||||
|
||||
try {
|
||||
const extension_type = settings_tab.getExtensionType() // get the extension type
|
||||
const extension_type = settings_tab_ts.store.data.extension_type // get the extension type
|
||||
payload['selection_info'] = session_data.selectionInfo
|
||||
const numberOfBatchSize = parseInt(
|
||||
document.querySelector('#tiNumberOfBatchSize').value
|
||||
)
|
||||
const numberOfSteps = document.querySelector('#tiNumberOfSteps').value
|
||||
const prompt = html_manip.getPrompt()
|
||||
const negative_prompt = html_manip.getNegativePrompt()
|
||||
const hi_res_fix = html_manip.getHiResFixs()
|
||||
// console.log("prompt:",prompt)
|
||||
// console.log("negative_prompt:",negative_prompt)
|
||||
const model_index = document.querySelector('#mModelsMenu').selectedIndex
|
||||
const upscaler = document.querySelector('#hrModelsMenu').value
|
||||
const cfg_scale = document.querySelector('#slCfgScale').value
|
||||
// const model_index = document.querySelector("#")
|
||||
const numberOfBatchSize = parseInt(sd_tab_store.data.batch_size)
|
||||
|
||||
const prompt = multiPrompts.getPrompt().positive
|
||||
const negative_prompt = multiPrompts.getPrompt().negative
|
||||
const hi_res_fix = sd_tab_store.data.enable_hr
|
||||
|
||||
const upscaler = sd_tab_store.data.hr_upscaler
|
||||
const cfg_scale = sd_tab_store.data.cfg
|
||||
|
||||
function calculateSeed(init_seed, batch_index, batch_size) {
|
||||
if (init_seed === -1) return -1
|
||||
|
|
@ -203,25 +199,25 @@ async function getSettings(session_data) {
|
|||
return seed
|
||||
}
|
||||
|
||||
const init_seed = parseInt(document.querySelector('#tiSeed').value)
|
||||
const init_seed = parseInt(sd_tab_store.data.seed)
|
||||
const seed = calculateSeed(
|
||||
init_seed,
|
||||
g_current_batch_index,
|
||||
numberOfBatchSize
|
||||
)
|
||||
|
||||
// const mask_blur = document.querySelector('#slMaskBlur').value
|
||||
const use_sharp_mask = settings_tab.getUseSharpMask()
|
||||
const mask_blur = html_manip.getMaskBlur()
|
||||
const mask_expansion = document.getElementById('slMaskExpansion').value
|
||||
const use_sharp_mask = settings_tab_ts.store.data.extension_type
|
||||
const mask_blur = settings_tab_ts.store.data.use_sharp_mask
|
||||
? 0
|
||||
: sd_tab_store.data.mask_blur
|
||||
const mask_expansion = sd_tab_store.data.mask_expansion
|
||||
|
||||
const inpaint_full_res_padding =
|
||||
document.querySelector('#slInpaintPadding').value
|
||||
sd_tab_store.data.inpaint_full_res_padding
|
||||
|
||||
// console.dir(numberOfImages)
|
||||
const bUsePromptShortcut = document.getElementById(
|
||||
'chUsePromptShortcut'
|
||||
).checked
|
||||
const bUsePromptShortcut =
|
||||
settings_tab_ts.store.data.use_prompt_shortcut
|
||||
let prompt_shortcut_ui_dict = {}
|
||||
try {
|
||||
let prompt_shortcut_string =
|
||||
|
|
@ -236,46 +232,33 @@ async function getSettings(session_data) {
|
|||
|
||||
// const slider_width = document.getElementById("slWidth").value
|
||||
// gWidth = getWidthFromSlider(slider_width)
|
||||
const original_width = html_manip.getWidth()
|
||||
const original_height = html_manip.getHeight()
|
||||
const original_width = sd_tab_store.data.width
|
||||
const original_height = sd_tab_store.data.height
|
||||
|
||||
const width = general.nearestMultiple(original_width, 64)
|
||||
const height = general.nearestMultiple(original_height, 64)
|
||||
|
||||
const hWidth = html_manip.getSliderSdValue_Old('hrWidth', 64)
|
||||
const hHeight = html_manip.getSliderSdValue_Old('hrHeight', 64)
|
||||
const hSteps = html_manip.getSliderSdValue_Old('hrNumberOfSteps', 1)
|
||||
//const hScale = html_manip.getSliderSdValue_Old('hrScale',1)
|
||||
console.log('Check')
|
||||
|
||||
const uniqueDocumentId = await getUniqueDocumentId()
|
||||
const h_denoising_strength = html_manip.getSliderSdValue_Old(
|
||||
'hrDenoisingStrength',
|
||||
0.01
|
||||
)
|
||||
console.log('Check2')
|
||||
const h_denoising_strength = sd_tab_store.data.hr_denoising_strength
|
||||
|
||||
//Note: store the sampler names in json file if auto is offline or auto api is unmounted
|
||||
|
||||
const sampler_name = html_manip.getCheckedSamplerName()
|
||||
const sampler_name = sd_tab_store.data.sampler_name
|
||||
|
||||
const mode = html_manip.getMode()
|
||||
const b_restore_faces =
|
||||
document.getElementById('chRestoreFaces').checked
|
||||
const mode = sd_tab_store.data.rb_mode
|
||||
const b_restore_faces = sd_tab_store.data.restore_faces
|
||||
|
||||
let denoising_strength = h_denoising_strength
|
||||
if (mode == 'inpaint' || mode == 'outpaint') {
|
||||
var g_use_mask_image = true
|
||||
payload['inpaint_full_res'] =
|
||||
document.getElementById('chInpaintFullRes').checked
|
||||
payload['inpaint_full_res_padding'] = inpaint_full_res_padding * 4
|
||||
payload['inpaint_full_res'] = sd_tab_store.data.inpaint_full_res
|
||||
|
||||
console.log('g_use_mask_image is ', g_use_mask_image)
|
||||
console.log('g_init_image_mask_name is ', g_init_image_mask_name)
|
||||
payload['init_image_mask_name'] = g_init_image_mask_name
|
||||
payload['inpainting_fill'] = html_manip.getMaskContent()
|
||||
payload['inpaint_full_res_padding'] = inpaint_full_res_padding
|
||||
|
||||
payload['inpainting_fill'] = sd_tab_store.data.inpainting_fill
|
||||
payload['mask_expansion'] = mask_expansion
|
||||
// payload['mask'] = g_generation_session.activeBase64MaskImage
|
||||
|
||||
payload['mask'] = session_data?.mask
|
||||
payload['expanded_mask'] = session_data?.mask
|
||||
if (
|
||||
|
|
@ -294,16 +277,10 @@ async function getSettings(session_data) {
|
|||
if (expanded_mask) {
|
||||
payload['expanded_mask'] = expanded_mask
|
||||
payload['mask'] = expanded_mask
|
||||
session_ts.store.data.expanded_mask = expanded_mask
|
||||
session_store.data.expanded_mask = expanded_mask
|
||||
}
|
||||
}
|
||||
// viewer.store.mask = payload['mask'] // make sure
|
||||
} else if (mode == 'img2img') {
|
||||
var g_use_mask_image = false
|
||||
delete payload['inpaint_full_res'] // inpaint full res is not available in img2img mode
|
||||
delete payload['inpaint_full_res_padding']
|
||||
delete payload['init_image_mask_name']
|
||||
delete payload['inpainting_fill']
|
||||
}
|
||||
|
||||
if (
|
||||
|
|
@ -311,19 +288,14 @@ async function getSettings(session_data) {
|
|||
g_sd_mode == 'inpaint' ||
|
||||
g_sd_mode == 'outpaint'
|
||||
) {
|
||||
// const { init_image, mask } = io.getOutpaintInitImageAndMask()
|
||||
console.log(`g_use_mask_image:? ${g_use_mask_image}`)
|
||||
|
||||
denoising_strength = html_manip.getDenoisingStrength()
|
||||
denoising_strength = sd_tab_store.data.denoising_strength
|
||||
payload['denoising_strength'] = denoising_strength
|
||||
payload['init_image_name'] = g_init_image_name
|
||||
|
||||
payload['init_images'] = [session_data?.init_image]
|
||||
// payload['init_images'] = [
|
||||
// g_generation_session.activeBase64InitImage,
|
||||
// // init_image,
|
||||
// ]
|
||||
payload['image_cfg_scale'] = sd_tab.getImageCfgScaleSDValue() // we may need to check if model is pix2pix
|
||||
|
||||
if (settings_tab_ts.store.data.use_image_cfg_scale_slider) {
|
||||
payload['image_cfg_scale'] = sd_tab_store.data.image_cfg_scale // we may need to check if model is pix2pix
|
||||
}
|
||||
|
||||
if (
|
||||
scripts.script_store.isInstalled() &&
|
||||
|
|
@ -336,13 +308,8 @@ async function getSettings(session_data) {
|
|||
payload['script_name'] =
|
||||
scripts.script_store.selected_script_name //'Ultimate SD upscale'
|
||||
}
|
||||
} else {
|
||||
delete payload['script_args']
|
||||
delete payload['script_name']
|
||||
}
|
||||
|
||||
// payload['script_args'] = []
|
||||
|
||||
function setAlwaysOnScripts() {
|
||||
const data = after_detailer_script.store.toJsFunc().data
|
||||
// console.log('setAlwaysOnScripts=> data:', data)
|
||||
|
|
@ -405,37 +372,13 @@ async function getSettings(session_data) {
|
|||
}
|
||||
|
||||
if (hi_res_fix && width >= 512 && height >= 512) {
|
||||
const hr_scale = sd_tab.getHrScaleSliderSDValue()
|
||||
|
||||
payload['enable_hr'] = hi_res_fix
|
||||
// payload['firstphase_width'] = width
|
||||
// payload['firstphase_height'] = height
|
||||
// payload['hr_resize_x'] = hWidth
|
||||
// payload['hr_resize_y'] = hHeight
|
||||
payload['hr_scale'] = hr_scale // Scale
|
||||
payload['hr_scale'] = sd_tab_store.data.hr_scale // Scale
|
||||
payload['hr_upscaler'] = upscaler // Upscaler
|
||||
payload['hr_second_pass_steps'] = hSteps // Number of Steps
|
||||
} else {
|
||||
//fix hi res bug: if we include firstphase_width or firstphase_height in the payload,
|
||||
// sd api will use them instead of using width and height variables, even when enable_hr is set to "false"
|
||||
delete payload['enable_hr']
|
||||
// delete payload['firstphase_width']
|
||||
// delete payload['firstphase_height']
|
||||
payload['hr_second_pass_steps'] =
|
||||
sd_tab_store.data.hr_second_pass_steps
|
||||
}
|
||||
|
||||
//work with the hord
|
||||
|
||||
// const script_args_json = {
|
||||
// model: "Anything Diffusion",
|
||||
// nsfw: false,
|
||||
// shared_laion: false,
|
||||
// seed_variation: 1,
|
||||
// post_processing_1: "None",
|
||||
// post_processing_2: "None",
|
||||
// post_processing_3: "None"
|
||||
// }
|
||||
// const script_args = Object.values(script_args_json)
|
||||
|
||||
const backend_type = html_manip.getBackendType()
|
||||
if (backend_type === backendTypeEnum['Auto1111HordeExtension']) {
|
||||
payload['script_name'] = script_horde.script_name
|
||||
|
|
@ -477,7 +420,7 @@ async function getSettings(session_data) {
|
|||
...payload,
|
||||
// prompt: prompt,
|
||||
// negative_prompt: negative_prompt,
|
||||
steps: numberOfSteps,
|
||||
steps: sd_tab_store.data.steps,
|
||||
// n_iter: numberOfImages,
|
||||
sampler_index: sampler_name,
|
||||
width: width,
|
||||
|
|
|
|||
|
|
@ -1,411 +0,0 @@
|
|||
const general = require('../general')
|
||||
const thumbnail = require('../../thumbnail')
|
||||
const html_manip = require('../html_manip')
|
||||
const api = require('../api')
|
||||
const psapi = require('../../psapi')
|
||||
const sdapi = require('../../sdapi_py_re')
|
||||
const Enum = require('../../enum')
|
||||
//REFACTOR: move to notification.js
|
||||
|
||||
async function requestGetHiResUpscalers() {
|
||||
try {
|
||||
const full_url = `${g_sd_url}/sdapi/v1/upscalers`
|
||||
let upscalers = await api.requestGet(full_url)
|
||||
return [
|
||||
'Latent',
|
||||
'Latent (antialiased)',
|
||||
'Latent (bicubic)',
|
||||
'Latent (bicubic antialiased)',
|
||||
'Latent (nearest)',
|
||||
'Latent (nearest-exact)',
|
||||
...upscalers.map((upscaler) => upscaler.name),
|
||||
]
|
||||
} catch (e) {
|
||||
console.warn('requestGetHiResUpscalers:', e)
|
||||
return [
|
||||
'Latent',
|
||||
'Latent (antialiased)',
|
||||
'Latent (bicubic)',
|
||||
'Latent (bicubic antialiased)',
|
||||
'Latent (nearest)',
|
||||
'Latent (nearest-exact)',
|
||||
]
|
||||
}
|
||||
}
|
||||
async function promptForUpdate(header_message, long_message) {
|
||||
const shell = require('uxp').shell
|
||||
|
||||
;(async () => {
|
||||
const buttons = ['Cancel', 'OK']
|
||||
const r1 = await dialog_box.prompt(
|
||||
header_message,
|
||||
long_message,
|
||||
buttons
|
||||
// 'Please Update you Plugin. it will take about 10 seconds to update',
|
||||
// 'update from discord, update from github'[
|
||||
// ['Cancel', 'Discord', 'Github']
|
||||
// ('Cancel', 'OK')
|
||||
// ]
|
||||
)
|
||||
try {
|
||||
let url
|
||||
if (r1 === 'Cancel') {
|
||||
/* cancelled or No */
|
||||
console.log('cancel')
|
||||
} else if (r1 === 'Github') {
|
||||
url =
|
||||
'https://github.com/AbdullahAlfaraj/Auto-Photoshop-StableDiffusion-Plugin'
|
||||
// await py_re.openUrlRequest(url)
|
||||
} else if (r1 === 'Discord') {
|
||||
console.log('Discord')
|
||||
// url = 'https://discord.gg/3mVEtrddXJ'
|
||||
// url = 'https://discord.gg/YkUJXYWK3c'
|
||||
// await py_re.openUrlRequest(url)
|
||||
} else if (r1 === 'Ok') {
|
||||
}
|
||||
// console.log('url: ', url)
|
||||
} catch (e) {
|
||||
console.warn(e, url)
|
||||
}
|
||||
})()
|
||||
}
|
||||
|
||||
async function updateClickEventHandler(current_version) {
|
||||
try {
|
||||
const online_data = await general.requestOnlineData()
|
||||
const b_need_update = general.compareVersions(
|
||||
current_version,
|
||||
online_data.new_version
|
||||
)
|
||||
|
||||
let header_message = "You're Plugin is up to date."
|
||||
let long_message = ''
|
||||
if (b_need_update) {
|
||||
header_message = `New Version is Available (${online_data.new_version})`
|
||||
long_message = online_data.update_message
|
||||
}
|
||||
|
||||
await promptForUpdate(header_message, long_message)
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
function viewMaskExpansion() {
|
||||
if (session_ts.store.data.expanded_mask) {
|
||||
const mask_src = general.base64ToBase64Url(
|
||||
session_ts.store.data.expanded_mask
|
||||
)
|
||||
html_manip.setInitImageMaskSrc(mask_src)
|
||||
} else {
|
||||
console.log(
|
||||
'the mask has not been expanded, g_generation_session.base64maskExpansionImage is empty'
|
||||
)
|
||||
}
|
||||
}
|
||||
function viewDrawnMask() {
|
||||
//this is the generated mask or user drawn mask, but it's not the mask after expansion
|
||||
if (session_ts.store.data.mask) {
|
||||
const mask_src = general.base64ToBase64Url(session_ts.store.data.mask)
|
||||
html_manip.setInitImageMaskSrc(mask_src)
|
||||
} else {
|
||||
console.log('no mask is available')
|
||||
}
|
||||
}
|
||||
|
||||
async function clipInterrogate() {
|
||||
try {
|
||||
const width = html_manip.getWidth()
|
||||
const height = html_manip.getHeight()
|
||||
const selectionInfo = await psapi.getSelectionInfoExe()
|
||||
|
||||
const base64 = await io.IO.getSelectionFromCanvasAsBase64Interface_New(
|
||||
width,
|
||||
height,
|
||||
selectionInfo,
|
||||
true
|
||||
)
|
||||
|
||||
const url = `${g_sd_url}/sdapi/v1/interrogate`
|
||||
|
||||
const payload = {
|
||||
image: base64,
|
||||
model: 'clip',
|
||||
}
|
||||
const result_json = await api.requestPost(url, payload)
|
||||
console.log(result_json)
|
||||
return result_json
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
}
|
||||
|
||||
function getHrScaleSliderSDValue() {
|
||||
sd_value = html_manip.getSliderSdValue('hrScaleSlider', 1, 100, 1, 4)
|
||||
return sd_value
|
||||
}
|
||||
function setHrScaleSliderSDValue(sd_value) {
|
||||
const slider_id = 'hrScaleSlider'
|
||||
const label_id = 'hrScaleLabel'
|
||||
html_manip.setSliderSdValue(slider_id, label_id, sd_value, 1, 100, 1, 4)
|
||||
}
|
||||
function getImageCfgScaleSDValue() {
|
||||
sd_value = html_manip.getSliderSdValue('slImageCfgScale', 0, 30, 0, 3)
|
||||
return sd_value
|
||||
}
|
||||
function setImageCfgScaleSDValue(sd_value) {
|
||||
const slider_id = 'slImageCfgScale'
|
||||
const label_id = 'lImageCfgScale'
|
||||
|
||||
html_manip.setSliderSdValue(slider_id, label_id, sd_value, 0, 30, 0, 3)
|
||||
}
|
||||
|
||||
function updateHrScaleFromToLabel() {
|
||||
//get width and height
|
||||
//get hr scale by
|
||||
//find the hr scale and height
|
||||
|
||||
const hr_scale = getHrScaleSliderSDValue()
|
||||
const [width, height] = [html_manip.getWidth(), html_manip.getHeight()]
|
||||
const [hr_width, hr_height] = [
|
||||
parseInt(width * hr_scale),
|
||||
parseInt(height * hr_scale),
|
||||
]
|
||||
document.getElementById(
|
||||
'lHrScaleFromTo'
|
||||
).textContent = `${width}x${height} -> ${hr_width}x${hr_height}`
|
||||
}
|
||||
function getLoraModelPrompt(lora_model_name) {
|
||||
return `<lora:${lora_model_name}:1>`
|
||||
}
|
||||
async function populateLoraModelMenu() {
|
||||
try {
|
||||
const lora_models = await sdapi.requestLoraModels()
|
||||
const lora_models_names = lora_models.map(
|
||||
(model_data) => model_data.name
|
||||
)
|
||||
|
||||
document.getElementById('mLoraModelMenu').innerHTML = ''
|
||||
|
||||
html_manip.populateMenu(
|
||||
'mLoraModelMenu',
|
||||
'mLoraModelItemClass',
|
||||
lora_models_names,
|
||||
(item, item_html_element) => {
|
||||
item_html_element.innerHTML = item
|
||||
item_html_element.onclick = () => {
|
||||
const lora_prompt = getLoraModelPrompt(item)
|
||||
const prompt = html_manip.getPrompt()
|
||||
html_manip.autoFillInPrompt(`${prompt} ${lora_prompt}`)
|
||||
}
|
||||
},
|
||||
false,
|
||||
'Select Lora'
|
||||
)
|
||||
} catch (e) {
|
||||
console.warn('populateLoraModelMenu error: ', e)
|
||||
}
|
||||
}
|
||||
|
||||
function displayImageCfgScaleSlider(mode) {
|
||||
const b_slider_enabled = document.getElementById(
|
||||
'chUseImageCfgScaleSlider'
|
||||
).checked
|
||||
if (b_slider_enabled) {
|
||||
if (mode === Enum.generationModeEnum['Txt2Img']) {
|
||||
document.getElementById('slImageCfgScale').style.display = 'none'
|
||||
} else if (mode === Enum.generationModeEnum['Img2Img']) {
|
||||
document.getElementById('slImageCfgScale').style.display = 'block'
|
||||
} else if (mode === Enum.generationModeEnum['Inpaint']) {
|
||||
document.getElementById('slImageCfgScale').style.display = 'block'
|
||||
} else if (mode === Enum.generationModeEnum['Outpaint']) {
|
||||
document.getElementById('slImageCfgScale').style.display = 'none'
|
||||
} else {
|
||||
document.getElementById('slImageCfgScale').style.display = 'none'
|
||||
}
|
||||
} else {
|
||||
document.getElementById('slImageCfgScale').style.display = 'none'
|
||||
}
|
||||
}
|
||||
function initInitMaskElement() {
|
||||
//make init mask image use the thumbnail class with buttons
|
||||
const mask_image_html = html_manip.getInitImageMaskElement()
|
||||
const mask_parent_element = mask_image_html.parentElement
|
||||
|
||||
this.thumbnail_container = thumbnail.Thumbnail.wrapImgInContainer(
|
||||
mask_image_html,
|
||||
'viewer-image-container'
|
||||
)
|
||||
mask_parent_element.appendChild(thumbnail_container)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
this.thumbnail_container,
|
||||
'svg_sp_btn',
|
||||
'view original mask',
|
||||
|
||||
viewDrawnMask,
|
||||
null
|
||||
)
|
||||
thumbnail.Thumbnail.addSPButtonToContainer(
|
||||
this.thumbnail_container,
|
||||
'svg_sp_btn_expand',
|
||||
'view modified mask',
|
||||
|
||||
viewMaskExpansion,
|
||||
null
|
||||
)
|
||||
populateLoraModelMenu() // no need for await
|
||||
}
|
||||
|
||||
async function refreshSDTab() {
|
||||
populateLoraModelMenu()
|
||||
}
|
||||
document.getElementById('hrScaleSlider').addEventListener('input', (evt) => {
|
||||
const sd_value = getHrScaleSliderSDValue()
|
||||
setHrScaleSliderSDValue(sd_value.toFixed(2))
|
||||
updateHrScaleFromToLabel()
|
||||
})
|
||||
document.getElementById('btnUpdate').addEventListener('click', async () => {
|
||||
await updateClickEventHandler(g_version)
|
||||
})
|
||||
|
||||
document
|
||||
.getElementById('slMaskExpansion')
|
||||
.addEventListener('change', async (evt) => {
|
||||
const mask = session_ts.store.data.preprocessed_mask
|
||||
const iterations = parseInt(evt.target.value)
|
||||
|
||||
const mask_blur = html_manip.getMaskBlur()
|
||||
session_ts.store.data.expanded_mask = await session_ts.getExpandedMask(
|
||||
mask,
|
||||
iterations,
|
||||
mask_blur
|
||||
)
|
||||
if (session_ts.store.data.expanded_mask) {
|
||||
viewMaskExpansion()
|
||||
}
|
||||
})
|
||||
|
||||
document
|
||||
.getElementById('slMaskBlur')
|
||||
.addEventListener('change', async (evt) => {
|
||||
const mask = session_ts.store.data.preprocessed_mask
|
||||
const iterations = parseInt(
|
||||
document.getElementById('slMaskExpansion').value
|
||||
)
|
||||
const mask_blur = parseInt(evt.target.value)
|
||||
session_ts.store.data.expanded_mask = await session_ts.getExpandedMask(
|
||||
mask,
|
||||
iterations,
|
||||
mask_blur
|
||||
)
|
||||
if (session_ts.store.data.expanded_mask) {
|
||||
viewMaskExpansion()
|
||||
}
|
||||
})
|
||||
document
|
||||
.getElementById('btnInterrogate')
|
||||
.addEventListener('click', async () => {
|
||||
// start sudo timer after 1 seconds delay
|
||||
setTimeout(() => {
|
||||
g_generation_session.sudo_timer_id =
|
||||
general.sudoTimer('Interrogate')
|
||||
}, 1000)
|
||||
const interrogate_result = await clipInterrogate()
|
||||
|
||||
if (interrogate_result.caption) {
|
||||
html_manip.autoFillInPrompt(interrogate_result.caption)
|
||||
}
|
||||
|
||||
// after the clipInterrogate finish stop the timer
|
||||
|
||||
html_manip.updateProgressBarsHtml(0, 'No work in progress')
|
||||
g_generation_session.sudo_timer_id = clearInterval(
|
||||
g_generation_session.sudo_timer_id
|
||||
)
|
||||
})
|
||||
|
||||
function ctrlBackspaceDelete(text) {
|
||||
try {
|
||||
let index = text.indexOf(String.fromCharCode(127))
|
||||
let new_text = text
|
||||
if (index >= 0) {
|
||||
// Ctrl + Enter pressed
|
||||
console.log('Ctrl + Enter pressed')
|
||||
|
||||
function ctrlBackspaceDeleteLogic(string, index) {
|
||||
// if (index < 1) {
|
||||
// return string
|
||||
// }
|
||||
// let i = index - 1
|
||||
// while (
|
||||
// i > 0 &&
|
||||
// /\s/.test(string[i - 1]) === /\s/.test(string[i])
|
||||
// ) {
|
||||
// i--
|
||||
// }
|
||||
// return string.slice(0, i) + string.slice(index)
|
||||
|
||||
if (index < 1) {
|
||||
return string
|
||||
}
|
||||
let i = index - 1
|
||||
if (/\s/.test(string[i])) {
|
||||
while (i > 0 && /\s/.test(string[i - 1])) {
|
||||
i--
|
||||
}
|
||||
} else {
|
||||
while (
|
||||
i > 0 &&
|
||||
/\s/.test(string[i - 1]) === /\s/.test(string[i])
|
||||
) {
|
||||
i--
|
||||
}
|
||||
}
|
||||
return string.slice(0, i) + string.slice(index)
|
||||
}
|
||||
new_text = ctrlBackspaceDeleteLogic(text, index + 1) //+ 1 to also delete the backspace delete char
|
||||
}
|
||||
|
||||
return new_text
|
||||
} catch (error) {
|
||||
console.warn(error)
|
||||
}
|
||||
}
|
||||
|
||||
// document.getElementById('taPrompt').addEventListener('input', (event) => {
|
||||
//
|
||||
// const value = event.target.value
|
||||
// console.log('value: ', value)
|
||||
// let index = value.indexOf(String.fromCharCode(127))
|
||||
// console.log('index:', index)
|
||||
// const new_text = ctrlBackspaceDelete(value)
|
||||
// event.target.value = new_text
|
||||
// console.log('new_text: ', new_text)
|
||||
// })
|
||||
function initSDTab() {
|
||||
initInitMaskElement()
|
||||
html_manip.sliderAddEventListener_new(
|
||||
'slImageCfgScale',
|
||||
'lImageCfgScale',
|
||||
0,
|
||||
30,
|
||||
0,
|
||||
3
|
||||
)
|
||||
}
|
||||
|
||||
initSDTab()
|
||||
module.exports = {
|
||||
updateClickEventHandler,
|
||||
viewMaskExpansion,
|
||||
viewDrawnMask,
|
||||
clipInterrogate,
|
||||
getHrScaleSliderSDValue,
|
||||
getLoraModelPrompt,
|
||||
populateLoraModelMenu,
|
||||
getImageCfgScaleSDValue,
|
||||
setImageCfgScaleSDValue,
|
||||
refreshSDTab,
|
||||
displayImageCfgScaleSlider,
|
||||
requestGetHiResUpscalers,
|
||||
}
|
||||
|
|
@ -1,27 +1,9 @@
|
|||
const io = require('../io')
|
||||
|
||||
function getUseSharpMask() {
|
||||
const isChecked = document.getElementById('chUseSharpMask').checked
|
||||
return isChecked
|
||||
}
|
||||
function setUseSharpMask() {
|
||||
console.warn('setUseSharpMask is not setup')
|
||||
}
|
||||
|
||||
function getUseLiveProgressImage() {
|
||||
const b_live_update = document.getElementById('chLiveProgressImage').checked
|
||||
return b_live_update
|
||||
}
|
||||
function setUseLiveProgressImage(b_live_update) {
|
||||
document.getElementById('chLiveProgressImage').checked = b_live_update
|
||||
}
|
||||
|
||||
function getExtensionType() {
|
||||
return [...document.getElementsByClassName('rbExtensionType')].filter(
|
||||
(e) => e.checked == true
|
||||
)[0].value
|
||||
}
|
||||
|
||||
document.getElementById('btnGetDocPath').addEventListener('click', async () => {
|
||||
const docPath = await io.IOFolder.getDocumentFolderNativePath()
|
||||
document.getElementById('tiDocPath').value = docPath
|
||||
|
|
@ -65,8 +47,8 @@ async function changeSdUrl(sd_url) {
|
|||
|
||||
async function saveSettings() {
|
||||
const settings_tab_settings = {
|
||||
use_sharp_mask: getUseSharpMask(),
|
||||
extension_type: getExtensionType(),
|
||||
use_sharp_mask: settings_tab_ts.store.data.use_sharp_mask,
|
||||
extension_type: settings_tab_ts.store.data.extension_type,
|
||||
sd_url: getSdUrlHtml(),
|
||||
}
|
||||
|
||||
|
|
@ -91,15 +73,6 @@ async function loadSettings() {
|
|||
}
|
||||
}
|
||||
|
||||
document.getElementById('chUseSharpMask').addEventListener('change', (ev) => {
|
||||
const isChecked = ev.target.checked
|
||||
if (isChecked) {
|
||||
document.getElementById('slMaskBlur').setAttribute('disabled')
|
||||
} else {
|
||||
document.getElementById('slMaskBlur').removeAttribute('disabled')
|
||||
}
|
||||
})
|
||||
|
||||
document.getElementById('chUseSmartObject').addEventListener('change', (ev) => {
|
||||
const isChecked = ev.target.checked
|
||||
if (isChecked) {
|
||||
|
|
@ -123,15 +96,13 @@ document
|
|||
})
|
||||
|
||||
module.exports = {
|
||||
getUseSharpMask,
|
||||
setUseSharpMask,
|
||||
getExtensionType,
|
||||
|
||||
getSdUrlHtml,
|
||||
setSdUrlHtml,
|
||||
changeSdUrl,
|
||||
loadSettings,
|
||||
saveSettings,
|
||||
getUseLiveProgressImage,
|
||||
setUseLiveProgressImage,
|
||||
|
||||
getUseOriginalPrompt,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
const chLiveProgressImageElements = document.getElementsByClassName(
|
||||
'chLiveProgressImageClass'
|
||||
)
|
||||
|
||||
const default_preview_value = document.getElementById(
|
||||
'chLiveProgressImage'
|
||||
).checked
|
||||
|
||||
chLiveProgressImageElements.forEach((element) => {
|
||||
element.checked = default_preview_value
|
||||
element.addEventListener('click', (event) => {
|
||||
value = element.checked
|
||||
chLiveProgressImageElements.forEach((element) => {
|
||||
element.checked = value
|
||||
})
|
||||
})
|
||||
})
|
||||
282
utility/ui.js
282
utility/ui.js
|
|
@ -1,282 +0,0 @@
|
|||
const html_manip = require('./html_manip')
|
||||
const presets = require('./presets/preset')
|
||||
const layer_util = require('../utility/layer')
|
||||
const psapi = require('../psapi')
|
||||
const Enum = require('../enum')
|
||||
const { executeAsModal } = require('photoshop').core
|
||||
|
||||
class UI {
|
||||
constructor() {}
|
||||
}
|
||||
|
||||
class UIElement {
|
||||
constructor() {
|
||||
this.name
|
||||
this.html_elem
|
||||
this.sd_value
|
||||
}
|
||||
setValue() {}
|
||||
getValue() {}
|
||||
}
|
||||
function createUIElement(getter, setter) {
|
||||
let ui_element_obj = new UIElement()
|
||||
ui_element_obj.getValue = getter
|
||||
ui_element_obj.setValue = setter
|
||||
return ui_element_obj
|
||||
}
|
||||
class UISettings {
|
||||
// get and set the settings of the ui. the stable diffusion settings not the human friendly settings
|
||||
constructor() {
|
||||
// this.width = new ui.UIElement()
|
||||
// this.width.getValue = html_manip.getWidth
|
||||
// this.width.setValue = html_manip.autoFillInWidth
|
||||
this.width = createUIElement(
|
||||
html_manip.getWidth,
|
||||
html_manip.autoFillInWidth
|
||||
)
|
||||
this.height = createUIElement(
|
||||
html_manip.getHeight,
|
||||
html_manip.autoFillInHeight
|
||||
)
|
||||
this.steps = createUIElement(
|
||||
html_manip.getSteps,
|
||||
html_manip.autoFillInSteps
|
||||
)
|
||||
this.batch_number = createUIElement(
|
||||
html_manip.getBatchNumber,
|
||||
html_manip.autoFillInBatchNumber
|
||||
)
|
||||
this.firstphase_width = createUIElement(
|
||||
html_manip.getHrWidth,
|
||||
html_manip.autoFillInHRWidth
|
||||
)
|
||||
this.firstphase_height = createUIElement(
|
||||
html_manip.getHrHeight,
|
||||
html_manip.autoFillInHRHeight
|
||||
)
|
||||
this.cfg = createUIElement(html_manip.getCFG, html_manip.setCFG)
|
||||
this.denoising_strength = createUIElement(
|
||||
html_manip.getDenoisingStrength,
|
||||
html_manip.autoFillInDenoisingStrength
|
||||
)
|
||||
|
||||
this.mask_content = createUIElement(
|
||||
html_manip.getMaskContent,
|
||||
html_manip.setMaskContent
|
||||
)
|
||||
this.seed = createUIElement(html_manip.getSeed, html_manip.setSeed)
|
||||
this.prompt = createUIElement(
|
||||
html_manip.getPrompt,
|
||||
html_manip.autoFillInPrompt
|
||||
)
|
||||
this.negative_prompt = createUIElement(
|
||||
html_manip.getNegativePrompt,
|
||||
html_manip.autoFillInNegativePrompt
|
||||
)
|
||||
this.mask_blur = createUIElement(
|
||||
html_manip.getMaskBlur,
|
||||
html_manip.setMaskBlur
|
||||
)
|
||||
this.mask_expansion = createUIElement(
|
||||
html_manip.getMaskExpansion,
|
||||
html_manip.setMaskExpansion
|
||||
)
|
||||
this.samplers = createUIElement(
|
||||
html_manip.getCheckedSamplerName,
|
||||
html_manip.autoFillInSampler
|
||||
)
|
||||
|
||||
this.uiElements = {
|
||||
// model: null,
|
||||
// prompt_shortcut: null,
|
||||
prompt: this.prompt,
|
||||
negative_prompt: this.negative_prompt,
|
||||
// selection_mode: null,
|
||||
batch_size: this.batch_number,
|
||||
steps: this.steps,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
firstphase_width: this.firstphase_width,
|
||||
firstphase_height: this.firstphase_height,
|
||||
cfg_scale: this.cfg,
|
||||
denoising_strength: this.denoising_strength,
|
||||
// hi_res_denoising_strength:0.7,
|
||||
mask_blur: this.mask_blur,
|
||||
mask_expansion: this.mask_expansion,
|
||||
// inpaint_at_full_res: false,
|
||||
// hi_res_fix:false,
|
||||
// inpaint_padding:0,
|
||||
seed: this.seed,
|
||||
sampler_index: this.samplers,
|
||||
mask_content: this.mask_content,
|
||||
}
|
||||
}
|
||||
|
||||
autoFillInSettings(settings) {
|
||||
for (const [name, value] of Object.entries(settings)) {
|
||||
if (this.uiElements.hasOwnProperty(name) && value) {
|
||||
//get the values for debugging
|
||||
const old_value = this.uiElements[name].getValue()
|
||||
console.log(
|
||||
'(name,old_value) => newValue:',
|
||||
name,
|
||||
old_value,
|
||||
value
|
||||
)
|
||||
//set the value
|
||||
this.uiElements[name].setValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
getSettings() {
|
||||
let settings = {}
|
||||
for (const [name, ui_element] of Object.entries(this.uiElements)) {
|
||||
if (ui_element) {
|
||||
const value = ui_element.getValue()
|
||||
settings[name] = value
|
||||
}
|
||||
}
|
||||
return settings
|
||||
}
|
||||
|
||||
saveAsJson(json_file_name, settings) {
|
||||
for (const [name, value] of Object.entries(settings)) {
|
||||
if (this.uiElements.hasOwnProperty(name) && value) {
|
||||
//get the values for debugging
|
||||
const old_value = this.uiElements[name].getValue()
|
||||
console.log(
|
||||
'(name,old_value) => newValue:',
|
||||
name,
|
||||
old_value,
|
||||
value
|
||||
)
|
||||
|
||||
//set the value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// const ui_settings = new UISettings()
|
||||
|
||||
function loadPreset(ui_settings, preset) {
|
||||
console.log('preset:', preset)
|
||||
ui_settings.autoFillInSettings(preset)
|
||||
}
|
||||
|
||||
function loadLatentNoiseSettings(ui_settings) {
|
||||
loadPreset(ui_settings, presets.LatentNoiseSettings)
|
||||
}
|
||||
|
||||
function loadFillSettings(ui_settings) {
|
||||
loadPreset(ui_settings, presets.FillSettings)
|
||||
}
|
||||
function loadOriginalSettings(ui_settings) {
|
||||
loadPreset(ui_settings, presets.OriginalSettings)
|
||||
}
|
||||
async function loadHealBrushSettings(ui_settings) {
|
||||
document.getElementById('rbModeInpaint').click()
|
||||
|
||||
loadPreset(ui_settings, presets.HealBrushSettings)
|
||||
}
|
||||
function loadCustomPreset(ui_settings_obj, custom_preset_settings) {
|
||||
loadPreset(ui_settings_obj, custom_preset_settings)
|
||||
}
|
||||
|
||||
function loadCustomPresetsSettings() {}
|
||||
async function mapCustomPresetsToLoaders(ui_settings_obj) {
|
||||
const name_to_settings_obj = await presets.getAllCustomPresetsSettings(
|
||||
Enum.PresetTypeEnum['SDPreset']
|
||||
)
|
||||
const preset_name_to_loader_obj = {}
|
||||
for (const [preset_name, preset_settings] of Object.entries(
|
||||
name_to_settings_obj
|
||||
)) {
|
||||
preset_name_to_loader_obj[preset_name] = () => {
|
||||
loadCustomPreset(ui_settings_obj, preset_settings)
|
||||
}
|
||||
}
|
||||
return preset_name_to_loader_obj
|
||||
}
|
||||
|
||||
const g_nativePresets = {
|
||||
fill: loadFillSettings,
|
||||
original: loadOriginalSettings,
|
||||
'latent noise': loadLatentNoiseSettings,
|
||||
'Heal Brush': loadHealBrushSettings,
|
||||
}
|
||||
|
||||
async function getLoadedPresets(ui_settings_obj) {
|
||||
let customPresets
|
||||
|
||||
customPresets = await mapCustomPresetsToLoaders(ui_settings_obj)
|
||||
console.log('customPresets: ', customPresets)
|
||||
let loadedPresets = {
|
||||
...g_nativePresets,
|
||||
...customPresets,
|
||||
}
|
||||
return loadedPresets
|
||||
}
|
||||
let g_ui_settings_object = new UISettings()
|
||||
function getUISettingsObject() {
|
||||
return g_ui_settings_object
|
||||
}
|
||||
|
||||
//REFACTOR: move to ui.js
|
||||
function addPresetMenuItem(preset_title) {
|
||||
// console.log(model_title,model_name)
|
||||
const menu_item_element = document.createElement('sp-menu-item')
|
||||
menu_item_element.className = 'mPresetMenuItem'
|
||||
menu_item_element.innerHTML = preset_title
|
||||
|
||||
// menu_item_element.addEventListener('select',()=>{
|
||||
// preset_func(g_ui_settings)
|
||||
// })
|
||||
return menu_item_element
|
||||
}
|
||||
//REFACTOR: move to ui.js
|
||||
async function populatePresetMenu() {
|
||||
document.getElementById('mPresetMenu').innerHTML = ''
|
||||
const divider_elem = document.createElement('sp-menu-divider')
|
||||
const preset_name = 'Select Smart Preset'
|
||||
const preset_func = () => {}
|
||||
const dummy_preset_item = addPresetMenuItem(preset_name, preset_func)
|
||||
dummy_preset_item.setAttribute('selected', 'selected')
|
||||
// dummy_preset_item.setAttribute('disabled')
|
||||
document.getElementById('mPresetMenu').appendChild(dummy_preset_item)
|
||||
document.getElementById('mPresetMenu').appendChild(divider_elem)
|
||||
const presets = await getLoadedPresets(g_ui_settings_object)
|
||||
for ([key, value] of Object.entries(presets)) {
|
||||
const preset_menu_item = addPresetMenuItem(key, value)
|
||||
document.getElementById('mPresetMenu').appendChild(preset_menu_item)
|
||||
}
|
||||
}
|
||||
|
||||
populatePresetMenu()
|
||||
//REFACTOR: move to preset_tab.js
|
||||
document
|
||||
.getElementById('mPresetMenu')
|
||||
.addEventListener('change', async (evt) => {
|
||||
const preset_index = evt.target.selectedIndex
|
||||
const preset_name = evt.target.options[preset_index].textContent
|
||||
const presets = await getLoadedPresets(g_ui_settings_object)
|
||||
if (presets.hasOwnProperty(preset_name)) {
|
||||
const loader = presets[preset_name]
|
||||
if (loader.constructor.name === 'AsyncFunction') {
|
||||
await loader(g_ui_settings_object)
|
||||
} else {
|
||||
loader(g_ui_settings_object)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = {
|
||||
UI,
|
||||
UIElement,
|
||||
UISettings,
|
||||
loadLatentNoiseSettings,
|
||||
loadFillSettings,
|
||||
loadHealBrushSettings,
|
||||
getLoadedPresets,
|
||||
getUISettingsObject,
|
||||
populatePresetMenu,
|
||||
}
|
||||
Loading…
Reference in New Issue