add a1111 compatibility items

This commit is contained in:
Vladimir Mandic
2023-10-20 08:19:37 -04:00
parent 52078069d2
commit 3794af95c5
7 changed files with 201 additions and 4 deletions
+17 -1
View File
@@ -35,6 +35,7 @@ class Script:
group = None
infotext_fields = None
paste_field_names = None
section = None
def title(self):
"""this function should return the title of the script. This is what will be displayed in the dropdown menu."""
@@ -332,7 +333,6 @@ class ScriptRunner:
self.paste_field_names.clear()
self.script_load_ctr = 0
self.is_img2img = is_img2img
self.scripts.clear()
self.alwayson_scripts.clear()
self.selectable_scripts.clear()
@@ -355,6 +355,22 @@ class ScriptRunner:
except Exception as e:
log.error(f'Script initialize: {path} {e}')
def setup_ui_for_section(self, section, scriptlist=None):
if scriptlist is None:
scriptlist = self.alwayson_scripts
for script in scriptlist:
if script.alwayson and script.section != section:
continue
if script.create_group:
with gr.Group(visible=script.alwayson) as group:
self.create_script_ui(script)
script.group = group
else:
self.create_script_ui(script)
def prepare_ui(self):
self.inputs = [None]
def setup_ui(self):
import modules.api.models as api_models
self.titles = [wrap_call(script.title, script.filename, "title") or f"{script.filename} [error]" for script in self.selectable_scripts]
+6 -1
View File
@@ -34,6 +34,11 @@ def find_sampler_config(name):
return config
def visible_sampler_names():
samplers = [x for x in all_samplers if x.name in shared.opts.show_samplers] if len(shared.opts.show_samplers) > 0 else all_samplers
return samplers
def create_sampler(name, model):
if name == 'Default' and hasattr(model, 'scheduler'):
config = {k: v for k, v in model.scheduler.config.items() if not k.startswith('_')}
@@ -64,7 +69,7 @@ def create_sampler(name, model):
def set_samplers():
global samplers # pylint: disable=global-statement
global samplers_for_img2img # pylint: disable=global-statement
samplers = [x for x in all_samplers if x.name in shared.opts.show_samplers] if len(shared.opts.show_samplers) > 0 else all_samplers
samplers = visible_sampler_names()
samplers_for_img2img = [x for x in samplers if x.name != "PLMS"]
samplers_map.clear()
for sampler in all_samplers:
+1
View File
@@ -425,6 +425,7 @@ options_templates.update(options_section(('ui', "User Interface"), {
"gradio_theme": OptionInfo("black-teal", "UI theme", gr.Dropdown, lambda: {"choices": theme.list_themes()}, refresh=theme.refresh_themes),
"theme_style": OptionInfo("Auto", "Theme mode", gr.Radio, {"choices": ["Auto", "Dark", "Light"]}),
"tooltips": OptionInfo("UI Tooltips", "UI tooltips", gr.Radio, {"choices": ["None", "Browser default", "UI tooltips"], "visible": False}),
"gallery_height": OptionInfo("", "Gallery height", gr.Textbox),
"compact_view": OptionInfo(False, "Compact view"),
"return_grid": OptionInfo(True, "Show grid in results"),
"return_mask": OptionInfo(False, "For inpainting, include the greyscale mask in results"),
+10 -1
View File
@@ -35,6 +35,15 @@ mimetypes.init()
mimetypes.add_type('application/javascript', '.js')
log = modules.shared.log
ui_system_tabs = None
switch_values_symbol = symbols.switch
detect_image_size_symbol = symbols.detect
paste_symbol = symbols.paste
clear_prompt_symbol = symbols.clear
restore_progress_symbol = symbols.apply
folder_symbol = symbols.folder
extra_networks_symbol = symbols.networks
apply_style_symbol = symbols.apply
save_style_symbol = symbols.save
if not cmd_opts.share and not cmd_opts.listen:
@@ -353,7 +362,7 @@ def get_value_for_setting(key):
def ordered_ui_categories():
return [] # dummy
return ['dimensions', 'sampler', 'seed', 'denoising', 'cfg', 'checkboxes', 'accordions', 'override_settings', 'scripts'] # TODO: a1111 compatibility item, not implemented
def create_override_settings_dropdown(tabname, row): # pylint: disable=unused-argument
+4 -1
View File
@@ -12,6 +12,9 @@ import modules.images
import modules.script_callbacks
folder_symbol = symbols.folder
def update_generation_info(generation_info, html_info, img_index):
try:
generation_info = json.loads(generation_info)
@@ -178,7 +181,7 @@ def create_output_panel(tabname):
with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
with gr.Group(elem_id=f"{tabname}_gallery_container"):
# columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=5, object_fit='scale-down')
result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=5, object_fit='scale-down', height=shared.opts.gallery_height or None)
with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"):
dummy_component = gr.Label(visible=False)
+57
View File
@@ -71,3 +71,60 @@ class DropdownEditable(FormComponent, gr.Dropdown):
def get_block_name(self):
return "dropdown"
class InputAccordion(gr.Checkbox):
"""A gr.Accordion that can be used as an input - returns True if open, False if closed.
Actaully just a hidden checkbox, but creates an accordion that follows and is followed by the state of the checkbox.
"""
global_index = 0
def __init__(self, value, **kwargs):
self.accordion_id = kwargs.get('elem_id')
if self.accordion_id is None:
self.accordion_id = f"input-accordion-{InputAccordion.global_index}"
InputAccordion.global_index += 1
kwargs_checkbox = {**kwargs, "elem_id": f"{self.accordion_id}-checkbox", "visible": False}
super().__init__(value, **kwargs_checkbox)
self.change(fn=None, _js='function(checked){ inputAccordionChecked("' + self.accordion_id + '", checked); }', inputs=[self])
kwargs_accordion = {
**kwargs,
"elem_id": self.accordion_id,
"label": kwargs.get('label', 'Accordion'),
"elem_classes": ['input-accordion'],
"open": value,
}
self.accordion = gr.Accordion(**kwargs_accordion)
def extra(self):
"""Allows you to put something into the label of the accordion.
Use it like this:
```
with InputAccordion(False, label="Accordion") as acc:
with acc.extra():
FormHTML(value="hello", min_width=0)
...
```
"""
return gr.Column(elem_id=self.accordion_id + '-extra', elem_classes='input-accordion-extra', min_width=0)
def __enter__(self):
self.accordion.__enter__()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.accordion.__exit__(exc_type, exc_val, exc_tb)
def get_block_name(self):
return "checkbox"
class ResizeHandleRow(gr.Row):
"""Same as gr.Row but fits inside gradio forms"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.elem_classes.append("resize-handle-row")
def get_block_name(self):
return "row"
+106
View File
@@ -0,0 +1,106 @@
# TODO: a1111 compatibility item, not used
import gradio as gr
from modules import shared, ui_common, ui_components, styles
styles_edit_symbol = '\U0001f58c\uFE0F' # 🖌️
styles_materialize_symbol = '\U0001f4cb' # 📋
def select_style(name):
style = shared.prompt_styles.styles.get(name)
existing = style is not None
empty = not name
prompt = style.prompt if style else gr.update()
negative_prompt = style.negative_prompt if style else gr.update()
return prompt, negative_prompt, gr.update(visible=existing), gr.update(visible=not empty)
def save_style(name, prompt, negative_prompt):
if not name:
return gr.update(visible=False)
style = styles.PromptStyle(name, prompt, negative_prompt)
shared.prompt_styles.styles[style.name] = style
shared.prompt_styles.save_styles(shared.styles_filename)
return gr.update(visible=True)
def delete_style(name):
if name == "":
return
shared.prompt_styles.styles.pop(name, None)
shared.prompt_styles.save_styles(shared.styles_filename)
return '', '', ''
def materialize_styles(prompt, negative_prompt, styles):
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles)
negative_prompt = shared.prompt_styles.apply_negative_styles_to_prompt(negative_prompt, styles)
return [gr.Textbox.update(value=prompt), gr.Textbox.update(value=negative_prompt), gr.Dropdown.update(value=[])]
def refresh_styles():
return gr.update(choices=list(shared.prompt_styles.styles)), gr.update(choices=list(shared.prompt_styles.styles))
class UiPromptStyles:
def __init__(self, tabname, main_ui_prompt, main_ui_negative_prompt):
self.dropdown = gr.Dropdown(label="Styles", elem_id=f"{tabname}_styles", choices=[style.name for style in shared.prompt_styles.styles.values()], value=[], multiselect=True)
"""
def __init__(self, tabname, main_ui_prompt, main_ui_negative_prompt):
self.tabname = tabname
with gr.Row(elem_id=f"{tabname}_styles_row"):
self.dropdown = gr.Dropdown(label="Styles", show_label=False, elem_id=f"{tabname}_styles", choices=list(shared.prompt_styles.styles), value=[], multiselect=True, tooltip="Styles")
edit_button = ui_components.ToolButton(value=styles_edit_symbol, elem_id=f"{tabname}_styles_edit_button", tooltip="Edit styles")
with gr.Box(elem_id=f"{tabname}_styles_dialog", elem_classes="popup-dialog") as styles_dialog:
with gr.Row():
self.selection = gr.Dropdown(label="Styles", elem_id=f"{tabname}_styles_edit_select", choices=list(shared.prompt_styles.styles), value=[], allow_custom_value=True, info="Styles allow you to add custom text to prompt. Use the {prompt} token in style text, and it will be replaced with user's prompt when applying style. Otherwise, style's text will be added to the end of the prompt.")
ui_common.create_refresh_button([self.dropdown, self.selection], shared.prompt_styles.reload, lambda: {"choices": list(shared.prompt_styles.styles)}, f"refresh_{tabname}_styles")
self.materialize = ui_components.ToolButton(value=styles_materialize_symbol, elem_id=f"{tabname}_style_apply", tooltip="Apply all selected styles from the style selction dropdown in main UI to the prompt.")
with gr.Row():
self.prompt = gr.Textbox(label="Prompt", show_label=True, elem_id=f"{tabname}_edit_style_prompt", lines=3)
with gr.Row():
self.neg_prompt = gr.Textbox(label="Negative prompt", show_label=True, elem_id=f"{tabname}_edit_style_neg_prompt", lines=3)
with gr.Row():
self.save = gr.Button('Save', variant='primary', elem_id=f'{tabname}_edit_style_save', visible=False)
self.delete = gr.Button('Delete', variant='primary', elem_id=f'{tabname}_edit_style_delete', visible=False)
self.close = gr.Button('Close', variant='secondary', elem_id=f'{tabname}_edit_style_close')
self.selection.change(
fn=select_style,
inputs=[self.selection],
outputs=[self.prompt, self.neg_prompt, self.delete, self.save],
show_progress=False,
)
self.save.click(
fn=save_style,
inputs=[self.selection, self.prompt, self.neg_prompt],
outputs=[self.delete],
show_progress=False,
).then(refresh_styles, outputs=[self.dropdown, self.selection], show_progress=False)
self.delete.click(
fn=delete_style,
_js='function(name){ if(name == "") return ""; return confirm("Delete style " + name + "?") ? name : ""; }',
inputs=[self.selection],
outputs=[self.selection, self.prompt, self.neg_prompt],
show_progress=False,
).then(refresh_styles, outputs=[self.dropdown, self.selection], show_progress=False)
self.materialize.click(
fn=materialize_styles,
inputs=[main_ui_prompt, main_ui_negative_prompt, self.dropdown],
outputs=[main_ui_prompt, main_ui_negative_prompt, self.dropdown],
show_progress=False,
).then(fn=None, _js="function(){update_"+tabname+"_tokens(); closePopup();}", show_progress=False)
ui_common.setup_dialog(button_show=edit_button, dialog=styles_dialog, button_close=self.close)
"""