change style dropdowns to multiselect
This commit is contained in:
parent
6eb72fd13f
commit
865228a837
6 changed files with 57 additions and 37 deletions
|
@ -10,10 +10,8 @@ ignore_ids_for_localization={
|
||||||
modelmerger_tertiary_model_name: 'OPTION',
|
modelmerger_tertiary_model_name: 'OPTION',
|
||||||
train_embedding: 'OPTION',
|
train_embedding: 'OPTION',
|
||||||
train_hypernetwork: 'OPTION',
|
train_hypernetwork: 'OPTION',
|
||||||
txt2img_style_index: 'OPTION',
|
txt2img_styles: 'OPTION',
|
||||||
txt2img_style2_index: 'OPTION',
|
img2img_styles 'OPTION',
|
||||||
img2img_style_index: 'OPTION',
|
|
||||||
img2img_style2_index: 'OPTION',
|
|
||||||
setting_random_artist_categories: 'SPAN',
|
setting_random_artist_categories: 'SPAN',
|
||||||
setting_face_restoration_model: 'SPAN',
|
setting_face_restoration_model: 'SPAN',
|
||||||
setting_realesrgan_enabled_models: 'SPAN',
|
setting_realesrgan_enabled_models: 'SPAN',
|
||||||
|
|
|
@ -59,7 +59,7 @@ def process_batch(p, input_dir, output_dir, args):
|
||||||
processed_image.save(os.path.join(output_dir, filename))
|
processed_image.save(os.path.join(output_dir, filename))
|
||||||
|
|
||||||
|
|
||||||
def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
|
def img2img(mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
|
||||||
is_batch = mode == 5
|
is_batch = mode == 5
|
||||||
|
|
||||||
if mode == 0: # img2img
|
if mode == 0: # img2img
|
||||||
|
@ -101,7 +101,7 @@ def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, pro
|
||||||
outpath_grids=opts.outdir_grids or opts.outdir_img2img_grids,
|
outpath_grids=opts.outdir_grids or opts.outdir_img2img_grids,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
negative_prompt=negative_prompt,
|
negative_prompt=negative_prompt,
|
||||||
styles=[prompt_style, prompt_style2],
|
styles=prompt_styles,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
subseed=subseed,
|
subseed=subseed,
|
||||||
subseed_strength=subseed_strength,
|
subseed_strength=subseed_strength,
|
||||||
|
|
|
@ -40,12 +40,18 @@ def apply_styles_to_prompt(prompt, styles):
|
||||||
class StyleDatabase:
|
class StyleDatabase:
|
||||||
def __init__(self, path: str):
|
def __init__(self, path: str):
|
||||||
self.no_style = PromptStyle("None", "", "")
|
self.no_style = PromptStyle("None", "", "")
|
||||||
self.styles = {"None": self.no_style}
|
self.styles = {}
|
||||||
|
self.path = path
|
||||||
|
|
||||||
if not os.path.exists(path):
|
self.reload()
|
||||||
|
|
||||||
|
def reload(self):
|
||||||
|
self.styles.clear()
|
||||||
|
|
||||||
|
if not os.path.exists(self.path):
|
||||||
return
|
return
|
||||||
|
|
||||||
with open(path, "r", encoding="utf-8-sig", newline='') as file:
|
with open(self.path, "r", encoding="utf-8-sig", newline='') as file:
|
||||||
reader = csv.DictReader(file)
|
reader = csv.DictReader(file)
|
||||||
for row in reader:
|
for row in reader:
|
||||||
# Support loading old CSV format with "name, text"-columns
|
# Support loading old CSV format with "name, text"-columns
|
||||||
|
|
|
@ -8,13 +8,13 @@ import modules.processing as processing
|
||||||
from modules.ui import plaintext_to_html
|
from modules.ui import plaintext_to_html
|
||||||
|
|
||||||
|
|
||||||
def txt2img(prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, *args):
|
def txt2img(prompt: str, negative_prompt: str, prompt_styles, steps: int, sampler_index: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, enable_hr: bool, denoising_strength: float, hr_scale: float, hr_upscaler: str, hr_second_pass_steps: int, hr_resize_x: int, hr_resize_y: int, *args):
|
||||||
p = StableDiffusionProcessingTxt2Img(
|
p = StableDiffusionProcessingTxt2Img(
|
||||||
sd_model=shared.sd_model,
|
sd_model=shared.sd_model,
|
||||||
outpath_samples=opts.outdir_samples or opts.outdir_txt2img_samples,
|
outpath_samples=opts.outdir_samples or opts.outdir_txt2img_samples,
|
||||||
outpath_grids=opts.outdir_grids or opts.outdir_txt2img_grids,
|
outpath_grids=opts.outdir_grids or opts.outdir_txt2img_grids,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
styles=[prompt_style, prompt_style2],
|
styles=prompt_styles,
|
||||||
negative_prompt=negative_prompt,
|
negative_prompt=negative_prompt,
|
||||||
seed=seed,
|
seed=seed,
|
||||||
subseed=subseed,
|
subseed=subseed,
|
||||||
|
|
|
@ -180,7 +180,7 @@ def add_style(name: str, prompt: str, negative_prompt: str):
|
||||||
# reserialize all styles every time we save them
|
# reserialize all styles every time we save them
|
||||||
shared.prompt_styles.save_styles(shared.styles_filename)
|
shared.prompt_styles.save_styles(shared.styles_filename)
|
||||||
|
|
||||||
return [gr.Dropdown.update(visible=True, choices=list(shared.prompt_styles.styles)) for _ in range(4)]
|
return [gr.Dropdown.update(visible=True, choices=list(shared.prompt_styles.styles)) for _ in range(2)]
|
||||||
|
|
||||||
|
|
||||||
def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y):
|
def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resize_y):
|
||||||
|
@ -197,11 +197,11 @@ def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resiz
|
||||||
return f"resize: from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
|
return f"resize: from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
|
||||||
|
|
||||||
|
|
||||||
def apply_styles(prompt, prompt_neg, style1_name, style2_name):
|
def apply_styles(prompt, prompt_neg, styles):
|
||||||
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, [style1_name, style2_name])
|
prompt = shared.prompt_styles.apply_styles_to_prompt(prompt, styles)
|
||||||
prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, [style1_name, style2_name])
|
prompt_neg = shared.prompt_styles.apply_negative_styles_to_prompt(prompt_neg, styles)
|
||||||
|
|
||||||
return [gr.Textbox.update(value=prompt), gr.Textbox.update(value=prompt_neg), gr.Dropdown.update(value="None"), gr.Dropdown.update(value="None")]
|
return [gr.Textbox.update(value=prompt), gr.Textbox.update(value=prompt_neg), gr.Dropdown.update(value=[])]
|
||||||
|
|
||||||
|
|
||||||
def interrogate(image):
|
def interrogate(image):
|
||||||
|
@ -374,13 +374,10 @@ def create_toprow(is_img2img):
|
||||||
)
|
)
|
||||||
|
|
||||||
with gr.Row():
|
with gr.Row():
|
||||||
with gr.Column(scale=1, elem_id="style_pos_col"):
|
prompt_styles = gr.Dropdown(label="Styles", elem_id=f"{id_part}_styles", choices=[k for k, v in shared.prompt_styles.styles.items()], value=[], multiselect=True)
|
||||||
prompt_style = gr.Dropdown(label="Style 1", elem_id=f"{id_part}_style_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys())))
|
create_refresh_button(prompt_styles, shared.prompt_styles.reload, lambda: {"choices": [k for k, v in shared.prompt_styles.styles.items()]}, f"refresh_{id_part}_styles")
|
||||||
|
|
||||||
with gr.Column(scale=1, elem_id="style_neg_col"):
|
return prompt, prompt_styles, negative_prompt, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button
|
||||||
prompt_style2 = gr.Dropdown(label="Style 2", elem_id=f"{id_part}_style2_index", choices=[k for k, v in shared.prompt_styles.styles.items()], value=next(iter(shared.prompt_styles.styles.keys())))
|
|
||||||
|
|
||||||
return prompt, prompt_style, negative_prompt, prompt_style2, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, token_counter, token_button
|
|
||||||
|
|
||||||
|
|
||||||
def setup_progressbar(*args, **kwargs):
|
def setup_progressbar(*args, **kwargs):
|
||||||
|
@ -590,7 +587,7 @@ def create_ui():
|
||||||
modules.scripts.scripts_txt2img.initialize_scripts(is_img2img=False)
|
modules.scripts.scripts_txt2img.initialize_scripts(is_img2img=False)
|
||||||
|
|
||||||
with gr.Blocks(analytics_enabled=False) as txt2img_interface:
|
with gr.Blocks(analytics_enabled=False) as txt2img_interface:
|
||||||
txt2img_prompt, txt2img_prompt_style, txt2img_negative_prompt, txt2img_prompt_style2, submit, _, _,txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False)
|
txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, submit, _, _,txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, token_counter, token_button = create_toprow(is_img2img=False)
|
||||||
|
|
||||||
dummy_component = gr.Label(visible=False)
|
dummy_component = gr.Label(visible=False)
|
||||||
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="bytes", visible=False)
|
txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="bytes", visible=False)
|
||||||
|
@ -684,8 +681,7 @@ def create_ui():
|
||||||
inputs=[
|
inputs=[
|
||||||
txt2img_prompt,
|
txt2img_prompt,
|
||||||
txt2img_negative_prompt,
|
txt2img_negative_prompt,
|
||||||
txt2img_prompt_style,
|
txt2img_prompt_styles,
|
||||||
txt2img_prompt_style2,
|
|
||||||
steps,
|
steps,
|
||||||
sampler_index,
|
sampler_index,
|
||||||
restore_faces,
|
restore_faces,
|
||||||
|
@ -780,7 +776,7 @@ def create_ui():
|
||||||
modules.scripts.scripts_img2img.initialize_scripts(is_img2img=True)
|
modules.scripts.scripts_img2img.initialize_scripts(is_img2img=True)
|
||||||
|
|
||||||
with gr.Blocks(analytics_enabled=False) as img2img_interface:
|
with gr.Blocks(analytics_enabled=False) as img2img_interface:
|
||||||
img2img_prompt, img2img_prompt_style, img2img_negative_prompt, img2img_prompt_style2, submit, img2img_interrogate, img2img_deepbooru, img2img_prompt_style_apply, img2img_save_style, img2img_paste,token_counter, token_button = create_toprow(is_img2img=True)
|
img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, submit, img2img_interrogate, img2img_deepbooru, img2img_prompt_style_apply, img2img_save_style, img2img_paste,token_counter, token_button = create_toprow(is_img2img=True)
|
||||||
|
|
||||||
with gr.Row(elem_id='img2img_progress_row'):
|
with gr.Row(elem_id='img2img_progress_row'):
|
||||||
img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="bytes", visible=False)
|
img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="bytes", visible=False)
|
||||||
|
@ -921,8 +917,7 @@ def create_ui():
|
||||||
dummy_component,
|
dummy_component,
|
||||||
img2img_prompt,
|
img2img_prompt,
|
||||||
img2img_negative_prompt,
|
img2img_negative_prompt,
|
||||||
img2img_prompt_style,
|
img2img_prompt_styles,
|
||||||
img2img_prompt_style2,
|
|
||||||
init_img,
|
init_img,
|
||||||
sketch,
|
sketch,
|
||||||
init_img_with_mask,
|
init_img_with_mask,
|
||||||
|
@ -977,7 +972,7 @@ def create_ui():
|
||||||
)
|
)
|
||||||
|
|
||||||
prompts = [(txt2img_prompt, txt2img_negative_prompt), (img2img_prompt, img2img_negative_prompt)]
|
prompts = [(txt2img_prompt, txt2img_negative_prompt), (img2img_prompt, img2img_negative_prompt)]
|
||||||
style_dropdowns = [(txt2img_prompt_style, txt2img_prompt_style2), (img2img_prompt_style, img2img_prompt_style2)]
|
style_dropdowns = [txt2img_prompt_styles, img2img_prompt_styles]
|
||||||
style_js_funcs = ["update_txt2img_tokens", "update_img2img_tokens"]
|
style_js_funcs = ["update_txt2img_tokens", "update_img2img_tokens"]
|
||||||
|
|
||||||
for button, (prompt, negative_prompt) in zip([txt2img_save_style, img2img_save_style], prompts):
|
for button, (prompt, negative_prompt) in zip([txt2img_save_style, img2img_save_style], prompts):
|
||||||
|
@ -987,15 +982,15 @@ def create_ui():
|
||||||
# Have to pass empty dummy component here, because the JavaScript and Python function have to accept
|
# Have to pass empty dummy component here, because the JavaScript and Python function have to accept
|
||||||
# the same number of parameters, but we only know the style-name after the JavaScript prompt
|
# the same number of parameters, but we only know the style-name after the JavaScript prompt
|
||||||
inputs=[dummy_component, prompt, negative_prompt],
|
inputs=[dummy_component, prompt, negative_prompt],
|
||||||
outputs=[txt2img_prompt_style, img2img_prompt_style, txt2img_prompt_style2, img2img_prompt_style2],
|
outputs=[txt2img_prompt_styles, img2img_prompt_styles],
|
||||||
)
|
)
|
||||||
|
|
||||||
for button, (prompt, negative_prompt), (style1, style2), js_func in zip([txt2img_prompt_style_apply, img2img_prompt_style_apply], prompts, style_dropdowns, style_js_funcs):
|
for button, (prompt, negative_prompt), styles, js_func in zip([txt2img_prompt_style_apply, img2img_prompt_style_apply], prompts, style_dropdowns, style_js_funcs):
|
||||||
button.click(
|
button.click(
|
||||||
fn=apply_styles,
|
fn=apply_styles,
|
||||||
_js=js_func,
|
_js=js_func,
|
||||||
inputs=[prompt, negative_prompt, style1, style2],
|
inputs=[prompt, negative_prompt, styles],
|
||||||
outputs=[prompt, negative_prompt, style1, style2],
|
outputs=[prompt, negative_prompt, styles],
|
||||||
)
|
)
|
||||||
|
|
||||||
token_button.click(fn=update_token_counter, inputs=[img2img_prompt, steps], outputs=[token_counter])
|
token_button.click(fn=update_token_counter, inputs=[img2img_prompt, steps], outputs=[token_counter])
|
||||||
|
@ -1530,6 +1525,7 @@ def create_ui():
|
||||||
|
|
||||||
previous_section = None
|
previous_section = None
|
||||||
current_tab = None
|
current_tab = None
|
||||||
|
current_row = None
|
||||||
with gr.Tabs(elem_id="settings"):
|
with gr.Tabs(elem_id="settings"):
|
||||||
for i, (k, item) in enumerate(opts.data_labels.items()):
|
for i, (k, item) in enumerate(opts.data_labels.items()):
|
||||||
section_must_be_skipped = item.section[0] is None
|
section_must_be_skipped = item.section[0] is None
|
||||||
|
@ -1538,10 +1534,14 @@ def create_ui():
|
||||||
elem_id, text = item.section
|
elem_id, text = item.section
|
||||||
|
|
||||||
if current_tab is not None:
|
if current_tab is not None:
|
||||||
|
current_row.__exit__()
|
||||||
current_tab.__exit__()
|
current_tab.__exit__()
|
||||||
|
|
||||||
|
gr.Group()
|
||||||
current_tab = gr.TabItem(elem_id="settings_{}".format(elem_id), label=text)
|
current_tab = gr.TabItem(elem_id="settings_{}".format(elem_id), label=text)
|
||||||
current_tab.__enter__()
|
current_tab.__enter__()
|
||||||
|
current_row = gr.Column(variant='compact')
|
||||||
|
current_row.__enter__()
|
||||||
|
|
||||||
previous_section = item.section
|
previous_section = item.section
|
||||||
|
|
||||||
|
@ -1556,6 +1556,7 @@ def create_ui():
|
||||||
components.append(component)
|
components.append(component)
|
||||||
|
|
||||||
if current_tab is not None:
|
if current_tab is not None:
|
||||||
|
current_row.__exit__()
|
||||||
current_tab.__exit__()
|
current_tab.__exit__()
|
||||||
|
|
||||||
with gr.TabItem("Actions"):
|
with gr.TabItem("Actions"):
|
||||||
|
@ -1774,7 +1775,13 @@ def create_ui():
|
||||||
apply_field(x, 'value')
|
apply_field(x, 'value')
|
||||||
|
|
||||||
if type(x) == gr.Dropdown:
|
if type(x) == gr.Dropdown:
|
||||||
apply_field(x, 'value', lambda val: val in x.choices, getattr(x, 'init_field', None))
|
def check_dropdown(val):
|
||||||
|
if x.multiselect:
|
||||||
|
return all([value in x.choices for value in val])
|
||||||
|
else:
|
||||||
|
return val in x.choices
|
||||||
|
|
||||||
|
apply_field(x, 'value', check_dropdown, getattr(x, 'init_field', None))
|
||||||
|
|
||||||
visit(txt2img_interface, loadsave, "txt2img")
|
visit(txt2img_interface, loadsave, "txt2img")
|
||||||
visit(img2img_interface, loadsave, "img2img")
|
visit(img2img_interface, loadsave, "img2img")
|
||||||
|
|
15
style.css
15
style.css
|
@ -114,6 +114,7 @@
|
||||||
min-width: unset !important;
|
min-width: unset !important;
|
||||||
flex-grow: 0 !important;
|
flex-grow: 0 !important;
|
||||||
padding: 0.4em 0;
|
padding: 0.4em 0;
|
||||||
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#roll_col > button {
|
#roll_col > button {
|
||||||
|
@ -141,10 +142,14 @@
|
||||||
min-width: 8em !important;
|
min-width: 8em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#txt2img_style_index, #txt2img_style2_index, #img2img_style_index, #img2img_style2_index{
|
#txt2img_styles, #img2img_styles{
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#txt2img_styles ul, #img2img_styles ul{
|
||||||
|
max-height: 35em;
|
||||||
|
}
|
||||||
|
|
||||||
.gr-form{
|
.gr-form{
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
|
@ -154,10 +159,14 @@
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toprow div{
|
#toprow div.gr-box, #toprow div.gr-form{
|
||||||
border: none;
|
border: none;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
#toprow div{
|
||||||
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#resize_mode{
|
#resize_mode{
|
||||||
|
@ -615,7 +624,7 @@ canvas[key="mask"] {
|
||||||
max-width: 2.5em;
|
max-width: 2.5em;
|
||||||
min-width: 2.5em !important;
|
min-width: 2.5em !important;
|
||||||
height: 2.4em;
|
height: 2.4em;
|
||||||
margin: 0.55em 0;
|
margin: 1.6em 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#quicksettings .gr-button-tool{
|
#quicksettings .gr-button-tool{
|
||||||
|
|
Loading…
Reference in a new issue