mirror of https://github.com/vladmandic/automatic
add extra networks list view
parent
da3d5d0fc7
commit
8432e68d30
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -572,6 +572,7 @@ options_templates.update(options_section(('interrogate', "Interrogate"), {
|
|||
options_templates.update(options_section(('extra_networks', "Extra Networks"), {
|
||||
"extra_networks_sep1": OptionInfo("<h2>Extra networks UI</h2>", "", 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):
|
||||
|
|
|
|||
|
|
@ -273,7 +273,10 @@ def create_toprow(is_img2img):
|
|||
negative_token_counter = gr.HTML(value="<span>0/75</span>", 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)
|
||||
|
|
|
|||
|
|
@ -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 = '''
|
||||
<div class='card' onclick={card_click} title='{name}' data-tab='{tabname}' data-page='{page}' data-name='{name}' data-filename='{filename}' data-tags='{tags}' data-mtime='{mtime}' data-size='{size}'>
|
||||
<div class='overlay'>
|
||||
<span style="display:none" class='search_term'>{search_term}</span>
|
||||
<div class='tags'></div>
|
||||
<div class='name'>{title}</div>
|
||||
</div>
|
||||
<div class='actions'>
|
||||
<span class='details' title="Get details" onclick="showCardDetails(event)">🛈</span>
|
||||
<div class='additional'><ul></ul></div>
|
||||
</div>
|
||||
<img class='preview' src='{preview}' style='width: {width}px; height: {height}px; object-fit: {fit}' loading='lazy'></img>
|
||||
</div>
|
||||
'''
|
||||
card_list = '''
|
||||
<div class='card card-list' onclick={card_click} title='{name}' data-tab='{tabname}' data-page='{page}' data-name='{name}' data-filename='{filename}' data-tags='{tags}' data-mtime='{mtime}' data-size='{size}'>
|
||||
<span class='details' title="Get details" onclick="showCardDetails(event)">🛈</span>
|
||||
<div class='name'>{title}</div>
|
||||
<div class='tags tags-list'></div>
|
||||
<span style="display:none" class='search_term'>{search_term}</span>
|
||||
</div>
|
||||
'''
|
||||
|
||||
|
||||
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 = '''
|
||||
<div class='card' onclick={card_click} title='{name}' data-tab='{tabname}' data-page='{page}' data-name='{name}' data-filename='{filename}' data-tags='{tags}' data-mtime='{mtime}' data-size='{size}'>
|
||||
<div class='overlay'>
|
||||
<span style="display:none" class='search_term'>{search_term}</span>
|
||||
<div class='tags'></div>
|
||||
<div class='name'>{title}</div>
|
||||
</div>
|
||||
<div class='actions'>
|
||||
<span class='details' title="Get details" onclick="showCardDetails(event)">🛈</span>
|
||||
<div class='additional'><ul></ul></div>
|
||||
</div>
|
||||
<img class='preview' src='{preview}' style='width: {width}px; height: {height}px; object-fit: {fit}' loading='lazy'></img>
|
||||
</div>
|
||||
'''
|
||||
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])
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ book = '🕮'
|
|||
apply = '⇰'
|
||||
clear = '⊗'
|
||||
fill = '⊜'
|
||||
scan = '🕸️'
|
||||
scan = '🔎︎'
|
||||
view = '☲'
|
||||
networks = '🌐'
|
||||
paste = '⇦'
|
||||
refine = '⌾'
|
||||
|
|
|
|||
Loading…
Reference in New Issue