diff --git a/html/locale_en.json b/html/locale_en.json index 4e013b0e8..3b7a83718 100644 --- a/html/locale_en.json +++ b/html/locale_en.json @@ -15,6 +15,7 @@ {"id":"","label":"🗁","localized":"","hint":"Show/hide extra networks"}, {"id":"","label":"⇰","localized":"","hint":"Apply selected styles to current prompt"}, {"id":"","label":"⇩","localized":"","hint":"Save parameters from last generated image as style template"}, + {"id":"","label":"🕮","localized":"","hint":"Save parameters from last generated image as style template"}, {"id":"","label":"⟲","localized":"","hint":"Refresh"}, {"id":"","label":"✕","localized":"","hint":"Close"}, {"id":"","label":"⊜","localized":"","hint":"Fill"}, @@ -23,8 +24,8 @@ {"id":"","label":"🔍","localized":"","hint":"Search"} ], "prompts": [ - {"id":"","label":"Prompt","localized":"","hint":"Type what you want to see in the image"}, - {"id":"","label":"Negative prompt","localized":"","hint":"Type what you DON'T want to see in the image"} + {"id":"","label":"Prompt","localized":"","hint":"Describe image you want to generate"}, + {"id":"","label":"Negative prompt","localized":"","hint":"Describe what you don't want to see in generated image"} ], "common keywords": [ {"id":"","label":"fp16","localized":"","hint":"Number representation in 16-bit floating point format"}, @@ -57,6 +58,9 @@ {"id":"","label":"Skip","localized":"","hint":"Stop processing current job and continue processing"}, {"id":"","label":"Interrupt","localized":"","hint":"Interrupt current processing job"}, {"id":"","label":"Pause","localized":"","hint":"Pause processing"}, + {"id":"","label":"Apply","localized":"","hint":"Apply parameters from last known generated image"}, + {"id":"","label":"Clear","localized":"","hint":"Clear prompts"}, + {"id":"","label":"Networks","localized":"","hint":"Open extra network interface"}, {"id":"","label":"Interrogate\nCLIP","localized":"","hint":"Run interrogate using CLIP model"}, {"id":"","label":"Interrogate\nDeepBooru","localized":"","hint":"Run interrogate using DeepBooru model"} ], diff --git a/javascript/amethyst-nightfall.css b/javascript/amethyst-nightfall.css index 265112d13..a8119ed02 100644 --- a/javascript/amethyst-nightfall.css +++ b/javascript/amethyst-nightfall.css @@ -118,7 +118,6 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_subseed_strength { margin-top: 0; } #pnginfo_html2_info { margin-top: -18px; background-color: var(--input-background-fill); padding: var(--input-padding) } .gradio-button.tool { filter: hue-rotate(180deg) saturate(0.5); } -#txt2img_tools, #img2img_tools { margin-top: -4px; margin-bottom: -4px; } #txt2img_styles_row, #img2img_styles_row { margin-top: -6px; z-index: 200; } /* custom elements overrides */ diff --git a/javascript/black-orange.css b/javascript/black-orange.css index 39406d41c..e989d0aa6 100644 --- a/javascript/black-orange.css +++ b/javascript/black-orange.css @@ -113,7 +113,6 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_settings { min-width: var(--left-column); max-width: var(--left-column); background-color: #111111; padding-top: 16px; } #pnginfo_html2_info { margin-top: -18px; background-color: var(--input-background-fill); padding: var(--input-padding) } .gradio-button.tool { filter: hue-rotate(180deg) saturate(0.5); } -#txt2img_tools, #img2img_tools { margin-top: -4px; margin-bottom: -4px; } #txt2img_styles_row, #img2img_styles_row { margin-top: -6px; z-index: 200; } /* custom elements overrides */ diff --git a/javascript/black-teal.css b/javascript/black-teal.css index e7a7ae320..37b74cf3e 100644 --- a/javascript/black-teal.css +++ b/javascript/black-teal.css @@ -123,7 +123,6 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_results, #img2img_results, #extras_results { background-color: var(--background-color); padding: 0; } #txt2img_settings { min-width: var(--left-column); max-width: var(--left-column); background-color: #111111; padding-top: 16px; } #pnginfo_html2_info { margin-top: -18px; background-color: var(--input-background-fill); padding: var(--input-padding) } -#txt2img_tools, #img2img_tools { margin-top: -4px; margin-bottom: -4px; } #txt2img_styles_row, #img2img_styles_row { margin-top: -6px; } /* custom elements overrides */ diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index ff9c023a8..c591065ef 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -191,17 +191,15 @@ function setupExtraNetworksForTab(tabname) { const btnRefresh = gradioApp().getElementById(`${tabname}_extra_refresh`); const btnScan = gradioApp().getElementById(`${tabname}_extra_scan`); const btnSave = gradioApp().getElementById(`${tabname}_extra_save`); - const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`); const btnClose = gradioApp().getElementById(`${tabname}_extra_close`); txtSearch.classList.add('search'); txtDescription.classList.add('description'); const buttons = document.createElement('span'); buttons.classList.add('buttons'); - buttons.appendChild(btnRefresh); - buttons.appendChild(btnScan); - buttons.appendChild(btnSave); - buttons.appendChild(btnApply); - buttons.appendChild(btnClose); + if (btnRefresh) buttons.appendChild(btnRefresh); + if (btnScan) buttons.appendChild(btnScan); + if (btnSave) buttons.appendChild(btnSave); + if (btnClose) buttons.appendChild(btnClose); tabs.appendChild(buttons); const div = document.createElement('div'); div.classList.add('second-line'); diff --git a/javascript/light-teal.css b/javascript/light-teal.css index 20acfb9bc..13adf078c 100644 --- a/javascript/light-teal.css +++ b/javascript/light-teal.css @@ -120,7 +120,6 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_results, #img2img_results, #extras_results { background-color: var(--background-color); padding: 0; } #txt2img_settings { min-width: var(--left-column); max-width: var(--left-column); background-color: #111111; padding-top: 16px; } #pnginfo_html2_info { margin-top: -18px; background-color: var(--input-background-fill); padding: var(--input-padding) } -#txt2img_tools, #img2img_tools { margin-top: -4px; margin-bottom: -4px; } #txt2img_styles_row, #img2img_styles_row { margin-top: -6px; z-index: 200; } /* custom elements overrides */ diff --git a/javascript/midnight-barbie.css b/javascript/midnight-barbie.css index 1ee4d7f10..e031a3cd6 100644 --- a/javascript/midnight-barbie.css +++ b/javascript/midnight-barbie.css @@ -113,7 +113,6 @@ svg.feather.feather-image, .feather .feather-image { display: none } #txt2img_settings { min-width: var(--left-column); max-width: var(--left-column); background-color: #111111; padding-top: 16px; } #pnginfo_html2_info { margin-top: -18px; background-color: var(--input-background-fill); padding: var(--input-padding) } .gradio-button.tool { filter: hue-rotate(120deg) saturate(0.5); } -#txt2img_tools, #img2img_tools { margin-top: -4px; margin-bottom: -4px; } #txt2img_styles_row, #img2img_styles_row { margin-top: -6px; z-index: 200; } /* custom elements overrides */ diff --git a/javascript/style.css b/javascript/style.css index 30fd3fb9c..a6ec9ded5 100644 --- a/javascript/style.css +++ b/javascript/style.css @@ -83,10 +83,8 @@ button.custom-button{ #txt2img_generate_box, #img2img_generate_box { gap: 0.5em; flex-wrap: wrap-reverse; height: fit-content; } #txt2img_actions_column, #img2img_actions_column { gap: 0.5em; height: fit-content; } #txt2img_generate_box > button, #img2img_generate_box > button { min-height: 42px; max-height: 42px; } -#txt2img_generate_line2, #img2img_generate_line2 { display: flex; } -#txt2img_generate_line2 > button, #img2img_generate_line2 > button, #extras_generate_box > button { height: 2.2em; line-height: 0; min-width: unset; display: block !important; } -#txt2img_tools > div, #img2img_tools > div { justify-content: space-around; margin-top: 0.5em; margin-bottom: 0em; } -#txt2img_tools > div > button, #img2img_tools > div > button { scale: 120%; min-width: 1em !important; min-height: 1em !important; } +#txt2img_generate_line2, #img2img_generate_line2, #txt2img_tools, #img2img_tools { display: flex; } +#txt2img_generate_line2 > button, #img2img_generate_line2 > button, #extras_generate_box > button, #txt2img_tools > button, #img2img_tools > button { height: 2.2em; line-height: 0; font-size: 1em; min-width: unset; display: block !important; } #txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { display: contents; } .interrogate-col{ min-width: 0 !important; max-width: fit-content; gap: 0.5em; } .interrogate-col > button{ flex: 1; } diff --git a/javascript/ui.js b/javascript/ui.js index f03945179..b09d9170a 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -179,12 +179,7 @@ function modelmerger(...args) { return res; } -function ask_for_style_name(_, prompt_text, negative_prompt_text) { - const name = prompt('Style name:'); // eslint-disable-line no-alert - return [name, prompt_text, negative_prompt_text]; -} - -function confirm_clear_prompt(prompt, negative_prompt) { +function clearPrompts(prompt, negative_prompt) { prompt = ''; negative_prompt = ''; return [prompt, negative_prompt]; diff --git a/modules/ui.py b/modules/ui.py index 07deddeb8..aebbfda65 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -253,12 +253,10 @@ def create_toprow(is_img2img): pause = gr.Button('Pause', elem_id=f"{id_part}_pause") pause.click(fn=lambda: modules.shared.state.pause(), _js='checkPaused', inputs=[], outputs=[]) with gr.Row(elem_id=f"{id_part}_tools"): - paste = ToolButton(value=symbols.paste, elem_id="paste") - clear_prompt_button = ToolButton(value=symbols.clear, elem_id=f"{id_part}_clear_prompt_btn") - extra_networks_button = ToolButton(value=symbols.networks, elem_id=f"{id_part}_extra_networks_btn") - prompt_style_apply = ToolButton(value=symbols.apply, elem_id=f"{id_part}_style_apply_btn") - save_style = ToolButton(value=symbols.save, elem_id=f"{id_part}_style_create_btn") - clear_prompt_button.click(fn=lambda *x: x, _js="confirm_clear_prompt", inputs=[prompt, negative_prompt], outputs=[prompt, negative_prompt]) + button_paste = gr.Button(value='Apply', variant='secondary', elem_id="paste") # symbols.paste + button_clear = gr.Button(value='Clear', variant='secondary', elem_id=f"{id_part}_clear_prompt_btn") # symbols.clear + button_extra = gr.Button(value='Networks', variant='secondary', elem_id=f"{id_part}_extra_networks_btn") # symbols.networks + button_clear.click(fn=lambda *x: x, _js="clearPrompts", inputs=[prompt, negative_prompt], outputs=[prompt, negative_prompt]) with gr.Row(elem_id=f"{id_part}_counters"): token_counter = gr.HTML(value="0/75", elem_id=f"{id_part}_token_counter", elem_classes=["token-counter"]) token_button = gr.Button(visible=False, elem_id=f"{id_part}_token_button") @@ -268,7 +266,7 @@ def create_toprow(is_img2img): prompt_styles = gr.Dropdown(label="Styles", elem_id=f"{id_part}_styles", choices=[style.name for style in modules.shared.prompt_styles.styles.values()], value=[], multiselect=True) prompt_styles_btn = gr.Button('Apply', elem_id=f"{id_part}_styles_select", visible=False) prompt_styles_btn.click(_js="applyStyles", fn=parse_style, inputs=[prompt_styles], outputs=[prompt_styles]) - return prompt, prompt_styles, negative_prompt, submit, button_interrogate, button_deepbooru, prompt_style_apply, save_style, paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button + return prompt, prompt_styles, negative_prompt, submit, button_interrogate, button_deepbooru, button_paste, button_extra, token_counter, token_button, negative_token_counter, negative_token_button def setup_progressbar(*args, **kwargs): # pylint: disable=unused-argument @@ -377,7 +375,7 @@ def create_ui(startup_timer = None): modules.scripts.scripts_current = modules.scripts.scripts_txt2img modules.scripts.scripts_txt2img.initialize_scripts(is_img2img=False) with gr.Blocks(analytics_enabled=False) as txt2img_interface: - txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, submit, _interrogate, _deepbooru, txt2img_prompt_style_apply, txt2img_save_style, txt2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=False) + txt2img_prompt, txt2img_prompt_styles, txt2img_negative_prompt, submit, _interrogate, _deepbooru, txt2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=False) dummy_component = gr.Label(visible=False) txt_prompt_img = gr.File(label="", elem_id="txt2img_prompt_image", file_count="single", type="binary", visible=False) with FormRow(variant='compact', elem_id="txt2img_extra_networks", visible=False) as extra_networks_ui: @@ -561,7 +559,7 @@ def create_ui(startup_timer = None): modules.scripts.scripts_current = modules.scripts.scripts_img2img modules.scripts.scripts_img2img.initialize_scripts(is_img2img=True) with gr.Blocks(analytics_enabled=False) as img2img_interface: - img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, submit, img2img_interrogate, img2img_deepbooru, img2img_prompt_style_apply, img2img_save_style, img2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=True) + img2img_prompt, img2img_prompt_styles, img2img_negative_prompt, submit, img2img_interrogate, img2img_deepbooru, img2img_paste, extra_networks_button, token_counter, token_button, negative_token_counter, negative_token_button = create_toprow(is_img2img=True) img2img_prompt_img = gr.File(label="", elem_id="img2img_prompt_image", file_count="single", type="binary", visible=False) with FormRow(variant='compact', elem_id="img2img_extra_networks", visible=False) as extra_networks_ui: @@ -834,27 +832,7 @@ def create_ui(startup_timer = None): show_progress=False, ) - prompts = [(txt2img_prompt, txt2img_negative_prompt), (img2img_prompt, img2img_negative_prompt)] - style_dropdowns = [txt2img_prompt_styles, img2img_prompt_styles] - style_js_funcs = ["update_txt2img_tokens", "update_img2img_tokens"] - - for button, (prompt, negative_prompt) in zip([txt2img_save_style, img2img_save_style], prompts): - button.click( - fn=add_style, - _js="ask_for_style_name", - inputs=[dummy_component, prompt, negative_prompt], - outputs=[txt2img_prompt_styles, img2img_prompt_styles], - ) - - 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( - fn=apply_styles, - _js=js_func, - inputs=[prompt, negative_prompt, styles], - outputs=[prompt, negative_prompt, styles], - ) - - token_button.click(fn=update_token_counter, inputs=[img2img_prompt, steps], outputs=[token_counter]) + token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_prompt, steps], outputs=[token_counter]) negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[img2img_negative_prompt, steps], outputs=[negative_token_counter]) ui_extra_networks.setup_ui(extra_networks_ui_img2img, img2img_gallery) diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index 7aece8562..39419e516 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -168,16 +168,21 @@ class ExtraNetworksPage: fn = f'{fn}.thumb.jpg' if os.path.exists(fn): continue + img = None try: img = Image.open(f) - if img.width > 1024 or img.height > 1024 or os.path.getsize(f) > 65536: + except Exception: + shared.log.warning(f'Extra network removing invalid image: {f}') + os.remove(f) + try: + if img is not None and img.width > 1024 or img.height > 1024 or os.path.getsize(f) > 65536: img = img.convert('RGB') img.thumbnail((512, 512), Image.HAMMING) img.save(fn, quality=50) img.close() created += 1 except Exception as e: - shared.log.error(f'Extra network error creating thumbnail: {f} {e}') + shared.log.warning(f'Extra network error creating thumbnail: {f} {e}') if created > 0: shared.log.info(f"Extra network thumbnails: {self.name} created={created}") self.missing_thumbs.clear() @@ -442,13 +447,11 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): def ui_tab_change(page): scan_visible = page in ['Model', 'Lora', 'Hypernetwork', 'Embedding'] save_visible = page in ['Style'] - apply_visible = page in ['Style'] - return [gr.update(visible=scan_visible), gr.update(visible=save_visible), gr.update(visible=apply_visible)] + return [gr.update(visible=scan_visible), gr.update(visible=save_visible)] ui.button_refresh = ToolButton(symbols.refresh, elem_id=tabname+"_extra_refresh") ui.button_scan = ToolButton(symbols.scan, elem_id=tabname+"_extra_scan", visible=True) - ui.button_save = ToolButton(symbols.save, elem_id=tabname+"_extra_save", visible=False) - ui.button_apply = ToolButton(symbols.apply, elem_id=tabname+"_extra_apply", visible=False) + ui.button_save = ToolButton(symbols.book, elem_id=tabname+"_extra_save", visible=False) ui.button_close = ToolButton(symbols.close, elem_id=tabname+"_extra_close") ui.search = gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", elem_classes="textbox", lines=2) ui.description = gr.Textbox('', show_label=False, elem_id=tabname+"_description", elem_classes="textbox", lines=2, interactive=False) @@ -461,7 +464,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): with gr.Tab(page.title, id=page.title.lower().replace(" ", "_"), elem_classes="extra-networks-tab") as tab: hmtl = gr.HTML(page.html, elem_id=f'{tabname}{page.name}_extra_page', elem_classes="extra-networks-page") ui.pages.append(hmtl) - tab.select(ui_tab_change, _js="getENActivePage", inputs=[ui.button_details], outputs=[ui.button_scan, ui.button_save, ui.button_apply]) + tab.select(ui_tab_change, _js="getENActivePage", inputs=[ui.button_details], outputs=[ui.button_scan, ui.button_save]) # ui.tabs.change(fn=ui_tab_change, inputs=[], outputs=[ui.button_scan, ui.button_save]) diff --git a/modules/ui_symbols.py b/modules/ui_symbols.py index f5a51215e..22422f101 100644 --- a/modules/ui_symbols.py +++ b/modules/ui_symbols.py @@ -2,6 +2,7 @@ refresh = '⟲' close = '✕' load = '⇧' save = '⇩' +book = '🕮' apply = '⇰' clear = '⊗' fill = '⊜'