diff --git a/frontend/css_and_js.py b/frontend/css_and_js.py index 94e04a5..03f6a63 100644 --- a/frontend/css_and_js.py +++ b/frontend/css_and_js.py @@ -1,4 +1,6 @@ from os import path +import json + def readTextFile(*args): dir = path.dirname(__file__) @@ -7,31 +9,25 @@ def readTextFile(*args): data = f.read() return data + def css(opt): styling = readTextFile("css", "styles.css") if not opt.no_progressbar_hiding: styling += readTextFile("css", "no_progress_bar.css") return styling + def js(opt): data = readTextFile("js", "index.js") data = "(z) => {" + data + "; return z ?? [] }" return data + # Wrap the typical SD method call into async closure for ease of use -# If you call frontend method without wrapping -# DONT FORGET to bind input argument if you need it: SD.with(x) -def w(sd_method_call): - return f"async (x) => {{ return await SD.with(x).{sd_method_call} ?? x ?? []; }}" - -def js_move_image(from_id, to_id): - return w(f"moveImageFromGallery('{from_id}', '{to_id}')") - -def js_copy_to_clipboard(from_id): - return w(f"copyImageFromGalleryToClipboard('{from_id}')") - -def js_painterro_launch(to_id): - return w(f"Painterro.init('{to_id}')") - -def js_img2img_submit(prompt_row_id): - return w(f"clickFirstVisibleButton('{prompt_row_id}')") +# Supplies the js function with a params object +# That includes all the passed arguments and input from Gradio: x +# Example call in Gradio component's event handler (pass the result to _js arg): +# _js=call_JS("myJsMethod", arg1="string", arg2=100, arg3=[]) +def call_JS(sd_method, **kwargs): + param_str = json.dumps(kwargs) + return f"async (x) => {{ return await SD.{sd_method}({{ x, ...{param_str} }}) ?? []; }}" diff --git a/frontend/frontend.py b/frontend/frontend.py index 69c0b04..4f1c46f 100644 --- a/frontend/frontend.py +++ b/frontend/frontend.py @@ -1,6 +1,5 @@ import gradio as gr -from frontend.css_and_js import * -from frontend.css_and_js import css +from frontend.css_and_js import css, js, call_JS import frontend.ui_functions as uifn def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaults={}, RealESRGAN=True, GFPGAN=True, @@ -47,10 +46,13 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul gr.Markdown( 'Select an image from the gallery, then click one of the buttons below to perform an action.') with gr.Row(): - output_txt2img_copy_clipboard = gr.Button("Copy to clipboard").click(fn=None, - inputs=output_txt2img_gallery, - outputs=[], - _js=js_copy_to_clipboard('txt2img_gallery_output')) + output_txt2img_copy_clipboard = gr.Button("Copy to clipboard")\ + .click(fn=None, + inputs=output_txt2img_gallery, + outputs=[], + _js=call_JS("copyImageFromGalleryToClipboard", + fromId="txt2img_gallery_output") + ) output_txt2img_copy_to_input_btn = gr.Button("Push to img2img") if RealESRGAN is not None: output_txt2img_to_upscale_esrgan = gr.Button("Upscale w/ ESRGAN") @@ -60,11 +62,13 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul with gr.Row(): output_txt2img_copy_params = gr.Button("Copy full parameters").click( inputs=output_txt2img_params, outputs=[], - _js='(x) => navigator.clipboard.writeText(x)', fn=None, show_progress=False) + fn=None, show_progress=False, + _js=call_JS("gradioInputToClipboard") + ) output_txt2img_seed = gr.Number(label='Seed', interactive=False, visible=False) output_txt2img_copy_seed = gr.Button("Copy only seed").click( inputs=output_txt2img_seed, outputs=[], - _js='(x) => navigator.clipboard.writeText(x)', fn=None, show_progress=False) + _js=call_JS("gradioInputToClipboard"), fn=None, show_progress=False) output_txt2img_stats = gr.HTML(label='Stats') with gr.Column(): @@ -153,7 +157,7 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul value=3, visible=False) img2img_resize = gr.Radio(label="Resize mode", - choices=["Just resize", "Crop and resize", "Resize and fill"], + choices=["Just resize"], type="index", value=img2img_resize_modes[img2img_defaults['resize_mode']]) @@ -172,17 +176,18 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul output_img2img_copy_to_clipboard_btn = gr.Button("Copy to clipboard") output_img2img_copy_to_input_btn = gr.Button("Push to img2img input") output_img2img_copy_to_mask_btn = gr.Button("Push to img2img input mask") + gr.Markdown("Warning: This will clear your current image and mask settings!") with gr.TabItem("Output info", id="img2img_output_info_tab"): output_img2img_params = gr.Textbox(label="Generation parameters") with gr.Row(): output_img2img_copy_params = gr.Button("Copy full parameters").click( inputs=output_img2img_params, outputs=[], - _js='(x) => navigator.clipboard.writeText(x)', fn=None, show_progress=False) + _js=call_JS("gradioInputToClipboard"), fn=None, show_progress=False) output_img2img_seed = gr.Number(label='Seed', interactive=False, visible=False) output_img2img_copy_seed = gr.Button("Copy only seed").click( inputs=output_img2img_seed, outputs=[], - _js='(x) => navigator.clipboard.writeText(x)', fn=None, show_progress=False) + _js=call_JS("gradioInputToClipboard"), fn=None, show_progress=False) output_img2img_stats = gr.HTML(label='Stats') gr.Markdown('# img2img settings') @@ -247,24 +252,32 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul uifn.copy_img_to_input, [output_txt2img_gallery], [img2img_image_editor, img2img_image_mask, tabs], - _js=js_move_image('txt2img_gallery_output', 'img2img_editor') + _js=call_JS("moveImageFromGallery", + fromId="txt2img_gallery_output", + toId="img2img_editor") ) output_img2img_copy_to_input_btn.click( uifn.copy_img_to_edit, [output_img2img_gallery], [img2img_image_editor, tabs, img2img_image_editor_mode], - _js=js_move_image('img2img_gallery_output', 'img2img_editor') + _js=call_JS("moveImageFromGallery", + fromId="img2img_gallery_output", + toId="img2img_editor") ) output_img2img_copy_to_mask_btn.click( uifn.copy_img_to_mask, [output_img2img_gallery], [img2img_image_mask, tabs, img2img_image_editor_mode], - _js=js_move_image('img2img_gallery_output', 'img2img_editor') + _js=call_JS("moveImageFromGallery", + fromId="img2img_gallery_output", + toId="img2img_editor") ) output_img2img_copy_to_clipboard_btn.click(fn=None, inputs=output_img2img_gallery, outputs=[], - _js=js_copy_to_clipboard('img2img_gallery_output')) + _js=call_JS("copyImageFromGalleryToClipboard", + fromId="img2img_gallery_output") + ) img2img_btn_mask.click( img2img, @@ -287,9 +300,14 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul # GENERATE ON ENTER img2img_prompt.submit(None, None, None, - _js=js_img2img_submit("prompt_row")) + _js=call_JS("clickFirstVisibleButton", + rowId="prompt_row")) - img2img_painterro_btn.click(None, [img2img_image_editor], [img2img_image_editor, img2img_image_mask], _js=js_painterro_launch('img2img_editor')) + img2img_painterro_btn.click(None, + [img2img_image_editor], + [img2img_image_editor, img2img_image_mask], + _js=call_JS("Painterro.init", toId="img2img_editor") + ) img2img_width.change(fn=uifn.update_dimensions_info, inputs=[img2img_width, img2img_height], outputs=img2img_dimensions_info_text_box) img2img_height.change(fn=uifn.update_dimensions_info, inputs=[img2img_width, img2img_height], outputs=img2img_dimensions_info_text_box) @@ -338,7 +356,10 @@ def draw_gradio_ui(opt, img2img=lambda x: x, txt2img=lambda x: x, txt2img_defaul uifn.copy_img_to_upscale_esrgan, output_txt2img_gallery, [realesrgan_source, tabs], - _js=js_move_image('txt2img_gallery_output', 'img2img_editor')) + _js=call_JS("moveImageFromGallery", + fromId="txt2img_gallery_output", + toId="img2img_editor") + ) gr.HTML("""