mirror of
https://github.com/Sygil-Dev/sygil-webui.git
synced 2024-12-15 22:42:14 +03:00
refactor: Painterro UI code is moved to index.js (#316)
* decouple python from js
* bring the painterro btn back
* refactor painterro code
replicate 7ddbd6533a
as close as possible
* improve reliability
* fix big brain import
Co-authored-by: hlky <106811348+hlky@users.noreply.github.com>
This commit is contained in:
parent
fe173407fe
commit
bdac53c5a1
@ -1,9 +1,8 @@
|
|||||||
import os
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
def readTextFile(*args):
|
def readTextFile(*args):
|
||||||
dir = os.path.dirname(__file__)
|
dir = path.dirname(__file__)
|
||||||
entry = os.path.join(dir, *args)
|
entry = path.join(dir, *args)
|
||||||
with open(entry, "r", encoding="utf8") as f:
|
with open(entry, "r", encoding="utf8") as f:
|
||||||
data = f.read()
|
data = f.read()
|
||||||
return data
|
return data
|
||||||
@ -31,8 +30,6 @@ def js_move_image(from_id, to_id):
|
|||||||
def js_copy_to_clipboard(from_id):
|
def js_copy_to_clipboard(from_id):
|
||||||
return w(f"copyImageFromGalleryToClipboard('{from_id}')")
|
return w(f"copyImageFromGalleryToClipboard('{from_id}')")
|
||||||
|
|
||||||
def js_painterro_launch():
|
def js_painterro_launch(to_id):
|
||||||
return w("Painterro.init(SD.x)")
|
return w(f"Painterro.init('{to_id}')")
|
||||||
|
|
||||||
def js_painterro_load_image(to_id):
|
|
||||||
return w(f"Painterro.loadImage('{to_id}')")
|
|
||||||
|
@ -92,8 +92,10 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul
|
|||||||
visible=RealESRGAN is not None) # TODO: Feels like I shouldnt slot it in here.
|
visible=RealESRGAN is not None) # TODO: Feels like I shouldnt slot it in here.
|
||||||
txt2img_ddim_eta = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="DDIM ETA",
|
txt2img_ddim_eta = gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label="DDIM ETA",
|
||||||
value=txt2img_defaults['ddim_eta'], visible=False)
|
value=txt2img_defaults['ddim_eta'], visible=False)
|
||||||
txt2img_variant_amount = gr.Slider(minimum=0.0, maximum=1.0, label='Variation Amount',value=txt2img_defaults['variant_amount'])
|
txt2img_variant_amount = gr.Slider(minimum=0.0, maximum=1.0, label='Variation Amount',
|
||||||
txt2img_variant_seed = gr.Textbox(label="Variant Seed (blank to randomize)", lines=1, max_lines=1,value=txt2img_defaults["variant_seed"])
|
value=txt2img_defaults['variant_amount'])
|
||||||
|
txt2img_variant_seed = gr.Textbox(label="Variant Seed (blank to randomize)", lines=1,
|
||||||
|
max_lines=1, value=txt2img_defaults["variant_seed"])
|
||||||
txt2img_embeddings = gr.File(label="Embeddings file for textual inversion",
|
txt2img_embeddings = gr.File(label="Embeddings file for textual inversion",
|
||||||
visible=show_embeddings)
|
visible=show_embeddings)
|
||||||
|
|
||||||
@ -139,7 +141,6 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul
|
|||||||
value="Crop", elem_id='edit_mode_select')
|
value="Crop", elem_id='edit_mode_select')
|
||||||
|
|
||||||
img2img_painterro_btn = gr.Button("Advanced Editor")
|
img2img_painterro_btn = gr.Button("Advanced Editor")
|
||||||
img2img_copy_from_painterro_btn = gr.Button(value="Get Image from Advanced Editor")
|
|
||||||
img2img_show_help_btn = gr.Button("Show Hints")
|
img2img_show_help_btn = gr.Button("Show Hints")
|
||||||
img2img_hide_help_btn = gr.Button("Hide Hints", visible=False)
|
img2img_hide_help_btn = gr.Button("Hide Hints", visible=False)
|
||||||
img2img_help = gr.Markdown(visible=False, value="")
|
img2img_help = gr.Markdown(visible=False, value="")
|
||||||
@ -224,7 +225,7 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul
|
|||||||
uifn.change_image_editor_mode,
|
uifn.change_image_editor_mode,
|
||||||
[img2img_image_editor_mode, img2img_image_editor, img2img_resize, img2img_width, img2img_height],
|
[img2img_image_editor_mode, img2img_image_editor, img2img_resize, img2img_width, img2img_height],
|
||||||
[img2img_image_editor, img2img_image_mask, img2img_btn_editor, img2img_btn_mask,
|
[img2img_image_editor, img2img_image_mask, img2img_btn_editor, img2img_btn_mask,
|
||||||
img2img_painterro_btn, img2img_copy_from_painterro_btn, img2img_mask, img2img_mask_blur_strength]
|
img2img_painterro_btn, img2img_mask, img2img_mask_blur_strength]
|
||||||
)
|
)
|
||||||
|
|
||||||
img2img_image_editor.edit(
|
img2img_image_editor.edit(
|
||||||
@ -288,9 +289,7 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul
|
|||||||
img2img_btn_editor.click(*img2img_submit_params())
|
img2img_btn_editor.click(*img2img_submit_params())
|
||||||
img2img_prompt.submit(*img2img_submit_params())
|
img2img_prompt.submit(*img2img_submit_params())
|
||||||
|
|
||||||
img2img_painterro_btn.click(None, [img2img_image_editor], None, _js=js_painterro_launch())
|
img2img_painterro_btn.click(None, [img2img_image_editor], [img2img_image_editor, img2img_image_mask], _js=js_painterro_launch('img2img_editor'))
|
||||||
|
|
||||||
img2img_copy_from_painterro_btn.click(None, None, [img2img_image_editor, img2img_image_mask], _js=js_painterro_load_image("img2img_editor"))
|
|
||||||
|
|
||||||
if GFPGAN is not None:
|
if GFPGAN is not None:
|
||||||
gfpgan_defaults = {
|
gfpgan_defaults = {
|
||||||
|
@ -1,19 +1,78 @@
|
|||||||
window.SD = (() => {
|
window.SD = (() => {
|
||||||
|
/*
|
||||||
|
* Painterro is made a field of the SD global object
|
||||||
|
* To provide convinience when using w() method in css_and_js.py
|
||||||
|
*/
|
||||||
class PainterroClass {
|
class PainterroClass {
|
||||||
static init (img) {
|
static isOpen = false;
|
||||||
Painterro({
|
static async init (toId) {
|
||||||
hiddenTools: ['arrow'],
|
const img = SD.x;
|
||||||
saveHandler: function (image, done) {
|
const originalImage = Array.isArray(img) ? img[0] : img;
|
||||||
localStorage.setItem('painterro-image', image.asDataURL());
|
|
||||||
done(true);
|
|
||||||
},
|
|
||||||
}).show(Array.isArray(img) ? img[0] : img);
|
|
||||||
}
|
|
||||||
static loadImage (toId) {
|
|
||||||
window.SD.clearImageInput(window.SD.el.get(`#${toId}`));
|
|
||||||
|
|
||||||
const image = localStorage.getItem('painterro-image')
|
if (window.Painterro === undefined) {
|
||||||
return [image, image];
|
try {
|
||||||
|
await this.load();
|
||||||
|
} catch (e) {
|
||||||
|
SDClass.error(e);
|
||||||
|
|
||||||
|
return this.fallback(originalImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isOpen) {
|
||||||
|
return this.fallback(originalImage);
|
||||||
|
}
|
||||||
|
this.isOpen = true;
|
||||||
|
|
||||||
|
let resolveResult;
|
||||||
|
const paintClient = Painterro({
|
||||||
|
hiddenTools: ['arrow'],
|
||||||
|
onHide: () => {
|
||||||
|
resolveResult?.(null);
|
||||||
|
},
|
||||||
|
saveHandler: (image, done) => {
|
||||||
|
const data = image.asDataURL();
|
||||||
|
|
||||||
|
// ensures stable performance even
|
||||||
|
// when the editor is in interactive mode
|
||||||
|
SD.clearImageInput(SD.el.get(`#${toId}`));
|
||||||
|
|
||||||
|
resolveResult(data);
|
||||||
|
|
||||||
|
done(true);
|
||||||
|
paintClient.hide();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await new Promise((resolve) => {
|
||||||
|
resolveResult = resolve;
|
||||||
|
paintClient.show(originalImage);
|
||||||
|
});
|
||||||
|
this.isOpen = false;
|
||||||
|
|
||||||
|
return result ? this.success(result) : this.fallback(originalImage);
|
||||||
|
}
|
||||||
|
static success (result) { return [result, result]; }
|
||||||
|
static fallback (image) { return [image, image]; }
|
||||||
|
static load () {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
/* Ensure Painterro window is always on top */
|
||||||
|
const style = document.createElement('style');
|
||||||
|
style.setAttribute('type', 'text/css');
|
||||||
|
style.appendChild(document.createTextNode(`
|
||||||
|
.ptro-holder-wrapper {
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
`));
|
||||||
|
document.head.appendChild(style);
|
||||||
|
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.id = '__painterro-script';
|
||||||
|
script.src = 'https://unpkg.com/painterro@1.2.78/build/painterro.min.js';
|
||||||
|
script.onload = () => resolve(true);
|
||||||
|
script.onerror = () => reject(false);
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +94,7 @@ window.SD = (() => {
|
|||||||
* The main helper class to incapsulate functions
|
* The main helper class to incapsulate functions
|
||||||
* that change gradio ui functionality
|
* that change gradio ui functionality
|
||||||
*/
|
*/
|
||||||
class SD {
|
class SDClass {
|
||||||
el = new ElementCache();
|
el = new ElementCache();
|
||||||
x;
|
x;
|
||||||
Painterro = PainterroClass;
|
Painterro = PainterroClass;
|
||||||
@ -64,9 +123,7 @@ window.SD = (() => {
|
|||||||
try {
|
try {
|
||||||
navigator.clipboard.write([item]);
|
navigator.clipboard.write([item]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO: graceful error messaing
|
SDClass.error(e);
|
||||||
console.error(e);
|
|
||||||
alert(e.message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.x;
|
return this.x;
|
||||||
@ -74,19 +131,19 @@ window.SD = (() => {
|
|||||||
clearImageInput (imageEditor) {
|
clearImageInput (imageEditor) {
|
||||||
imageEditor?.querySelector('.modify-upload button:last-child')?.click();
|
imageEditor?.querySelector('.modify-upload button:last-child')?.click();
|
||||||
}
|
}
|
||||||
|
static error (e) {
|
||||||
|
console.error(e);
|
||||||
|
if (typeof e === 'string') {
|
||||||
|
alert(e);
|
||||||
|
} else if(typeof e === 'object' && Object.hasOwn(e, 'message')) {
|
||||||
|
alert(e.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
#getGallerySelectedIndex (gallery) {
|
#getGallerySelectedIndex (gallery) {
|
||||||
const selected = gallery.querySelector(`.\\!ring-2`);
|
const selected = gallery.querySelector(`.\\!ring-2`);
|
||||||
return selected ? [...selected.parentNode.children].indexOf(selected) : 0;
|
return selected ? [...selected.parentNode.children].indexOf(selected) : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Painterro stuff
|
return new SDClass();
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = 'https://unpkg.com/painterro@1.2.78/build/painterro.min.js';
|
|
||||||
document.head.appendChild(script);
|
|
||||||
const style = document.createElement('style');
|
|
||||||
style.appendChild(document.createTextNode('.ptro-holder-wrapper { z-index: 9999 !important; }'));
|
|
||||||
document.head.appendChild(style);
|
|
||||||
|
|
||||||
return new SD();
|
|
||||||
})();
|
})();
|
||||||
|
Loading…
Reference in New Issue
Block a user