diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ac992e30..5995dcf3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,16 +42,20 @@ Some highlights: [OpenVINO](https://github.com/vladmandic/automatic/wiki/OpenVIN - **compile** option, thanks @disty0 - **chaiNNer** add high quality models from [Helaman](https://openmodeldb.info/users/helaman) - redesigned **Progress bar** with full details on current operation - - **Extra networks** sort by name, size, date, etc. - new option: *settings -> images -> keep incomplete* can be used to skip vae decode on aborted/skipped/interrupted image generations - new option: *settings -> system paths -> models* can be used to set custom base path for *all* models (previously only as cli option) - remove external clone of items in `/repositories` -- **UI** +- **UI** - UI tweaks for default themes - UI switch core font in default theme to **noto-sans** previously default font was simply *system-ui*, but it lead to too much variations between browsers and platforms + - updated **Context menu** + right-click on prompt or generate button +- **Extra networks** + - sort by name, size, date, etc. + - switch between *gallery* and *list* views - **Packages** - updated `diffusers` to 0.22.0, `transformers` to 4.34.1 - update **openvino**, thanks @disty0 diff --git a/html/locale_en.json b/html/locale_en.json index 8100e8525..e2480b253 100644 --- a/html/locale_en.json +++ b/html/locale_en.json @@ -21,7 +21,8 @@ {"id":"","label":"✕","localized":"","hint":"Close"}, {"id":"","label":"⊜","localized":"","hint":"Fill"}, {"id":"","label":"⌾","localized":"","hint":"Load model as refiner model when selected, otherwise load as base model"}, - {"id":"","label":"🕸️","localized":"","hint":"Scan CivitAI for missing metadata and previews"}, + {"id":"","label":"🔎︎","localized":"","hint":"Scan CivitAI for missing metadata and previews"}, + {"id":"","label":"☲","localized":"","hint":"Change view type"}, {"id":"","label":"📐","localized":"","hint":"Measure"}, {"id":"","label":"🔍","localized":"","hint":"Search"} ], diff --git a/javascript/black-teal.css b/javascript/black-teal.css index 5bbc81f8c..a9094fe31 100644 --- a/javascript/black-teal.css +++ b/javascript/black-teal.css @@ -108,7 +108,8 @@ svg.feather.feather-image, .feather .feather-image { display: none } #img2img_label_copy_to_img2img { font-weight: normal; } #txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; } #txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; } -#txt2img_styles, #img2img_styles { margin-top: -5px; } +#txt2img_styles, #img2img_styles { padding: 0; } +#txt2img_styles_refresh, #img2img_styles_refresh { padding: 0; margin-top: 1em; } #img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; } #interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; } #quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; } diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js index 432da7980..a0773514a 100644 --- a/javascript/extraNetworks.js +++ b/javascript/extraNetworks.js @@ -241,6 +241,7 @@ function setupExtraNetworksForTab(tabname) { const btnSave = gradioApp().getElementById(`${tabname}_extra_save`); const btnClose = gradioApp().getElementById(`${tabname}_extra_close`); const btnSort = gradioApp().getElementById(`${tabname}_extra_sort`); + const btnView = gradioApp().getElementById(`${tabname}_extra_view`); const btnModel = gradioApp().getElementById(`${tabname}_extra_model`); const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`); const buttons = document.createElement('span'); @@ -251,6 +252,7 @@ function setupExtraNetworksForTab(tabname) { if (btnScan) buttons.appendChild(btnScan); if (btnSave) buttons.appendChild(btnSave); if (btnSort) buttons.appendChild(btnSort); + if (btnView) buttons.appendChild(btnView); if (btnClose) buttons.appendChild(btnClose); btnModel.onclick = () => btnModel.classList.toggle('toolbutton-selected'); tabs.appendChild(buttons); diff --git a/javascript/light-teal.css b/javascript/light-teal.css index dcccc5894..9b34212ec 100644 --- a/javascript/light-teal.css +++ b/javascript/light-teal.css @@ -106,7 +106,8 @@ svg.feather.feather-image, .feather .feather-image { display: none } #img2img_label_copy_to_img2img { font-weight: normal; } #txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt { background-color: var(--background-color); box-shadow: 4px 4px 4px 0px #333333 !important; } #txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; } -#txt2img_styles, #img2img_styles { margin-top: -5px; } +#txt2img_styles, #img2img_styles { padding: 0; } +#txt2img_styles_refresh, #img2img_styles_refresh { padding: 0; margin-top: 1em; } #img2img_settings { min-width: calc(2 * var(--left-column)); max-width: calc(2 * var(--left-column)); background-color: #111111; padding-top: 16px; } #interrogate, #deepbooru { margin: 0 0px 10px 0px; max-width: 80px; max-height: 80px; font-weight: normal; font-size: 0.95em; } #quicksettings .gr-button-tool { font-size: 1.6rem; box-shadow: none; margin-left: -20px; margin-top: -2px; height: 2.4em; } diff --git a/javascript/sdnext.css b/javascript/sdnext.css index 4fef1203f..273224479 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -34,7 +34,8 @@ textarea { overflow-y: auto !important; } .gradio-dropdown ul.options { z-index: 1000; min-width: fit-content; max-height: 33vh !important; white-space: nowrap; } .gradio-dropdown ul.options li.item { padding: var(--spacing-xs); } .gradio-dropdown ul.options li.item:not(:has(.hide)) { background-color: var(--primary-500); } -.gradio-dropdown span { margin-bottom: 0 !important; } +.gradio-dropdown .token { padding: var(--spacing-xs); } +.gradio-dropdown span { margin-bottom: 0 !important; font-size: 0.9em; } .gradio-dropdown .reference { margin-bottom: var(--spacing-sm) !important; } .gradio-html { color: var(--body-text-color); } .gradio-html .min { min-height: 0; } @@ -183,7 +184,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt .extra-networks .description { flex: 3; } .extra-networks .tab-nav > button { margin-right: 0; height: 24px; padding: 2px 4px 2px 4px; } .extra-networks .buttons { position: absolute; right: 0; margin: -4px; background: var(--background-color); } -.extra-networks .buttons>button { height: 1.2em; margin-top: var(--spacing-md); } +.extra-networks .buttons > button { margin-left: -0.4em; height: 1.4em; color: var(--primary-300) !important; } .extra-networks .custom-button { width: 120px; width: 100%; background: none; justify-content: left; text-align: left; padding: 2px 8px 2px 16px; text-indent: -8px; box-shadow: none; line-break: auto; } .extra-networks .custom-button:hover { background: var(--button-primary-background-fill) } .extra-networks-tab { padding: 0 !important; } @@ -204,6 +205,8 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt .extra-network-cards .card:hover .actions { display: block; } .extra-network-cards .card:hover .overlay .tags { display: block; } .extra-network-cards .card .actions { font-size: 3em; display: none; text-align-last: right; cursor: pointer; font-variant: unicase; position: absolute; z-index: 100; right: 0; height: 0.7em; width: 100%; background: rgba(0, 0, 0, 0.40); } +.extra-network-cards .card-list { display: flex; margin: 0.3em; padding: 0.3em; background: var(--input-background-fill); cursor: pointer; border-radius: var(--button-large-radius); } +.extra-network-cards .card-list .tag { color: var(--primary-500); margin-left: 0.8em; } .extra-details-close { position: fixed; top: 0.2em; right: 0.2em; z-index: 99; background: var(--button-secondary-background-fill) !important; } #txt2img_description, #img2img_description { max-height: 63px; overflow-y: auto !important; } #txt2img_description > label > textarea, #img2img_description > label > textarea { font-size: 0.9em } diff --git a/modules/shared.py b/modules/shared.py index 9998133ef..61b1236da 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -572,6 +572,7 @@ options_templates.update(options_section(('interrogate', "Interrogate"), { options_templates.update(options_section(('extra_networks', "Extra Networks"), { "extra_networks_sep1": OptionInfo("

Extra networks UI

", "", gr.HTML), "extra_networks": OptionInfo(["All"], "Extra networks", ui_components.DropdownMulti, lambda: {"choices": ['All'] + [en.title for en in extra_networks]}), + "extra_networks_view": OptionInfo("gallery", "UI view", gr.Radio, {"choices": ["gallery", "list"]}), "extra_networks_card_cover": OptionInfo("sidebar", "UI position", gr.Radio, {"choices": ["cover", "inline", "sidebar"]}), "extra_networks_height": OptionInfo(53, "UI height (%)", gr.Slider, {"minimum": 10, "maximum": 100, "step": 1}), "extra_networks_sidebar_width": OptionInfo(35, "UI sidebar width (%)", gr.Slider, {"minimum": 10, "maximum": 80, "step": 1}), @@ -784,7 +785,6 @@ mem_mon = modules.memmon.MemUsageMonitor("MemMon", devices.device) if devices.backend == "directml": directml_do_hijack() - class TotalTQDM: # compatibility with previous global-tqdm # import tqdm def __init__(self): diff --git a/modules/ui.py b/modules/ui.py index 3ded98772..f80ad290c 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -273,7 +273,10 @@ def create_toprow(is_img2img): negative_token_counter = gr.HTML(value="0/75", elem_id=f"{id_part}_negative_token_counter", elem_classes=["token-counter"]) negative_token_button = gr.Button(visible=False, elem_id=f"{id_part}_negative_token_button") with gr.Row(elem_id=f"{id_part}_styles_row"): - 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 = 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 = gr.Dropdown(label="Styles", elem_id=f"{id_part}_styles", choices=['aaa'], value=[], multiselect=True) + prompt_styles_btn_refresh = ToolButton(symbols.refresh, elem_id=f"{id_part}_styles_refresh", visible=True) + prompt_styles_btn_refresh.click(fn=lambda: gr.update(choices=[style.name for style in modules.shared.prompt_styles.styles.values()]), inputs=[], outputs=[prompt_styles]) prompt_styles_btn_select = gr.Button('Select', elem_id=f"{id_part}_styles_select", visible=False) prompt_styles_btn_select.click(_js="applyStyles", fn=parse_style, inputs=[prompt_styles], outputs=[prompt_styles]) prompt_styles_btn_apply = ToolButton(symbols.apply, elem_id=f"{id_part}_extra_apply", visible=False) diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py index ea702d542..9cc5c24cc 100644 --- a/modules/ui_extra_networks.py +++ b/modules/ui_extra_networks.py @@ -24,6 +24,28 @@ dir_cache = {} # key=path, value=(mtime, listdir(path)) refresh_time = 0 extra_pages = shared.extra_networks debug = shared.log.info if os.environ.get('SD_EN_DEBUG', None) is not None else lambda *args, **kwargs: None +card_full = ''' +
+
+ +
+
{title}
+
+
+ 🛈 +
    +
    + +
    +''' +card_list = ''' +
    + 🛈  +
    {title}
      +
    + +
    +''' def listdir(path): @@ -116,21 +138,8 @@ class ExtraNetworksPage: self.refresh_time = 0 self.page_time = 0 self.list_time = 0 - # class additional is to keep old extensions happy - self.card = ''' -
    -
    - -
    -
    {title}
    -
    -
    - 🛈 -
      -
      - -
      - ''' + self.view = shared.opts.extra_networks_view + self.card = card_full if shared.opts.extra_networks_view == 'gallery' else card_list def refresh(self): pass @@ -219,7 +228,7 @@ class ExtraNetworksPage: def create_page(self, tabname, skip = False): debug(f'EN create-page: {self.name}') - if self.page_time > refresh_time: # cached page + if self.page_time > refresh_time and len(self.html) > 0: # cached page return self.html self_name_id = self.name.replace(" ", "_") if skip: @@ -393,6 +402,7 @@ class ExtraNetworksUi: self.button_details: gr.Button = None self.button_refresh: gr.Button = None self.button_scan: gr.Button = None + self.button_view: gr.Button = None self.button_quicksave: gr.Button = None self.button_save: gr.Button = None self.button_sort: gr.Button = None @@ -495,6 +505,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): ui.button_quicksave = ToolButton(symbols.book, elem_id=tabname+"_extra_quicksave", visible=False) ui.button_save = ToolButton(symbols.book, elem_id=tabname+"_extra_save", visible=False) ui.button_sort = ToolButton(symbols.sort, elem_id=tabname+"_extra_sort", visible=True) + ui.button_view = ToolButton(symbols.view, elem_id=tabname+"_extra_view", visible=True) ui.button_close = ToolButton(symbols.close, elem_id=tabname+"_extra_close", visible=True) ui.button_model = ToolButton(symbols.refine, elem_id=tabname+"_extra_model", visible=True) ui.search = gr.Textbox('', show_label=False, elem_id=tabname+"_extra_search", placeholder="Search...", elem_classes="textbox", lines=2, container=False) @@ -692,6 +703,20 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): ui.search.update(value = ui.search.value) return pages + def ui_view_cards(title): + pages = [] + for page in get_pages(): + if title is None or title == '' or title == page.title or len(page.html) == 0: + shared.opts.extra_networks_view = page.view + page.view = 'gallery' if page.view == 'list' else 'list' + page.card = card_full if page.view == 'gallery' else card_list + page.html = '' + page.create_page(ui.tabname) + shared.log.debug(f"Refreshing Extra networks: page='{page.title}' items={len(page.items)} tab={ui.tabname} view={page.view}") + pages.append(page.html) + ui.search.update(value = ui.search.value) + return pages + def ui_scan_click(title): from modules import ui_models if ui_models.search_metadata_civit is not None: @@ -744,6 +769,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False): button_parent.click(fn=toggle_visibility, inputs=[ui.visible], outputs=[ui.visible, container, button_parent]) ui.button_close.click(fn=toggle_visibility, inputs=[ui.visible], outputs=[ui.visible, container]) ui.button_sort.click(fn=ui_sort_cards, _js='sortExtraNetworks', inputs=[ui.search], outputs=[ui.description]) + ui.button_view.click(fn=ui_view_cards, inputs=[ui.search], outputs=ui.pages) ui.button_refresh.click(fn=ui_refresh_click, _js='getENActivePage', inputs=[ui.search], outputs=ui.pages) ui.button_scan.click(fn=ui_scan_click, _js='getENActivePage', inputs=[ui.search], outputs=ui.pages) ui.button_save.click(fn=ui_save_click, inputs=[], outputs=ui.details_components + [ui.details]) diff --git a/modules/ui_symbols.py b/modules/ui_symbols.py index 2da7945b0..0e80508ec 100644 --- a/modules/ui_symbols.py +++ b/modules/ui_symbols.py @@ -6,7 +6,8 @@ book = '🕮' apply = '⇰' clear = '⊗' fill = '⊜' -scan = '🕸️' +scan = '🔎︎' +view = '☲' networks = '🌐' paste = '⇦' refine = '⌾'