diff --git a/modules/shared_options.py b/modules/shared_options.py
index ac050c2e..770592e9 100644
--- a/modules/shared_options.py
+++ b/modules/shared_options.py
@@ -372,7 +372,7 @@ options_templates.update(
"show_refiner": OptionInfo(False, "Display the Refiner Accordion").info('"deprecated" feature for SDXL').needs_reload_ui(),
# "show_rescale_cfg": OptionInfo(False, "Display the Rescale CFG Slider").info("feature for v-pred checkpoints").needs_reload_ui(),
# "show_mahiro": OptionInfo(False, "Display the MaHiRo Toggle").info('see blue-arxiv - id: 2024-1208.1').needs_reload_ui(),
- # "paste_safe_guard": OptionInfo(False, 'Disable the "Read generation parameters" button (↙️) when negative prompt is not empty'),
+ "paste_safe_guard": OptionInfo(False, 'Disable the "Read generation parameters" button (↙️) when negative prompt is not empty'),
"div_classic": OptionDiv(),
"compact_prompt_box": OptionInfo(False, "Compact Prompt Layout").info("put prompts inside the Generate tab, leaving more space for the gallery").needs_reload_ui(),
"dimensions_and_batch_together": OptionInfo(True, "Show Width/Height and Batch sliders in same row").needs_reload_ui(),
diff --git a/modules/ui.py b/modules/ui.py
index 41643d5e..e10e70c6 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -511,6 +511,9 @@ def create_ui():
extra_tabs.__exit__()
+ if shared.opts.paste_safe_guard:
+ toprow.hook_paste_guard()
+
scripts.scripts_current = scripts.scripts_img2img
scripts.scripts_img2img.initialize_scripts(is_img2img=True)
@@ -857,6 +860,9 @@ def create_ui():
extra_tabs.__exit__()
+ if shared.opts.paste_safe_guard:
+ toprow.hook_paste_guard()
+
scripts.scripts_current = None
with gr.Blocks(analytics_enabled=False) as extras_interface:
diff --git a/modules/ui_toprow.py b/modules/ui_toprow.py
index 6a9055a4..432e4d00 100644
--- a/modules/ui_toprow.py
+++ b/modules/ui_toprow.py
@@ -1,8 +1,7 @@
import gradio as gr
-from modules import shared, ui_prompt_styles
import modules.images
-
+from modules import shared, ui_prompt_styles
from modules.ui_components import ToolButton
@@ -77,11 +76,11 @@ class Toprow:
def create_prompts(self):
with gr.Column(elem_id=f"{self.id_part}_prompt_container", elem_classes=["prompt-container-compact"] if self.is_compact else [], scale=6):
with gr.Row(elem_id=f"{self.id_part}_prompt_row", elem_classes=["prompt-row"]):
- self.prompt = gr.Textbox(label="Prompt", elem_id=f"{self.id_part}_prompt", show_label=False, lines=3, placeholder="Prompt\n(Press Ctrl+Enter to generate, Alt+Enter to skip, Esc to interrupt)", elem_classes=["prompt"], value='')
+ self.prompt = gr.Textbox(label="Prompt", elem_id=f"{self.id_part}_prompt", show_label=False, lines=3, placeholder="Prompt\n(Press Ctrl+Enter to generate, Alt+Enter to skip, Esc to interrupt)", elem_classes=["prompt"], value="")
self.prompt_img = gr.File(label="", elem_id=f"{self.id_part}_prompt_image", file_count="single", type="binary", visible=False)
with gr.Row(elem_id=f"{self.id_part}_neg_prompt_row", elem_classes=["prompt-row"]):
- self.negative_prompt = gr.Textbox(label="Negative prompt", elem_id=f"{self.id_part}_neg_prompt", show_label=False, lines=3, placeholder="Negative prompt\n(Press Ctrl+Enter to generate, Alt+Enter to skip, Esc to interrupt)", elem_classes=["prompt"], value='')
+ self.negative_prompt = gr.Textbox(label="Negative prompt", elem_id=f"{self.id_part}_neg_prompt", show_label=False, lines=3, placeholder="Negative prompt\n(Press Ctrl+Enter to generate, Alt+Enter to skip, Esc to interrupt)", elem_classes=["prompt"], value="")
self.prompt_img.change(
fn=modules.images.image_data,
@@ -94,10 +93,10 @@ class Toprow:
with gr.Row(elem_id=f"{self.id_part}_generate_box", elem_classes=["generate-box"] + (["generate-box-compact"] if self.is_compact else []), render=not self.is_compact) as submit_box:
self.submit_box = submit_box
- self.interrupt = gr.Button('Interrupt', elem_id=f"{self.id_part}_interrupt", elem_classes="generate-box-interrupt", tooltip="End generation immediately or after completing current batch")
- self.skip = gr.Button('Skip', elem_id=f"{self.id_part}_skip", elem_classes="generate-box-skip", tooltip="Stop generation of current batch and continues onto next batch")
- self.interrupting = gr.Button('Interrupting...', elem_id=f"{self.id_part}_interrupting", elem_classes="generate-box-interrupting", tooltip="Interrupting generation...")
- self.submit = gr.Button('Generate', elem_id=f"{self.id_part}_generate", variant='primary', tooltip="Right click generate forever menu")
+ self.interrupt = gr.Button("Interrupt", elem_id=f"{self.id_part}_interrupt", elem_classes="generate-box-interrupt", tooltip="End generation immediately or after completing current batch")
+ self.skip = gr.Button("Skip", elem_id=f"{self.id_part}_skip", elem_classes="generate-box-skip", tooltip="Stop generation of current batch and continues onto next batch")
+ self.interrupting = gr.Button("Interrupting...", elem_id=f"{self.id_part}_interrupting", elem_classes="generate-box-interrupting", tooltip="Interrupting generation...")
+ self.submit = gr.Button("Generate", elem_id=f"{self.id_part}_generate", variant="primary", tooltip="Right click generate forever menu")
def interrupt_function():
if not shared.state.stopping_generation and shared.state.job_count > 1 and shared.opts.interrupt_after_current:
@@ -112,7 +111,7 @@ class Toprow:
def create_tools_row(self):
with gr.Row(elem_id=f"{self.id_part}_tools"):
- from modules.ui import paste_symbol, clear_prompt_symbol, restore_progress_symbol
+ from modules.ui import clear_prompt_symbol, paste_symbol, restore_progress_symbol
self.paste = ToolButton(value=paste_symbol, elem_id="paste", tooltip="Read generation parameters from prompt or last generation if prompt is empty into user interface.")
self.clear_prompt_button = ToolButton(value=clear_prompt_symbol, elem_id=f"{self.id_part}_clear_prompt", tooltip="Clear prompt")
@@ -135,3 +134,17 @@ class Toprow:
def create_styles_ui(self):
self.ui_styles = ui_prompt_styles.UiPromptStyles(self.id_part, self.prompt, self.negative_prompt)
self.ui_styles.setup_apply_button(self.apply_styles)
+
+ def hook_paste_guard(self):
+ assert self.negative_prompt is not None and self.paste is not None
+
+ def guard(prompt: str) -> bool:
+ return gr.update(interactive=(not bool(prompt.strip())))
+
+ self.negative_prompt.change(
+ fn=guard,
+ inputs=[self.negative_prompt],
+ outputs=[self.paste],
+ show_progress="hidden",
+ queue=False,
+ )