mirror of
https://github.com/vladmandic/automatic
synced 2026-08-26 15:16:01 +02:00
context menus
This commit is contained in:
@@ -75,6 +75,8 @@
|
||||
//extraNetworks.js
|
||||
"requestGet": "readonly",
|
||||
"getENActiveTab": "readonly",
|
||||
"quickApplyStyle": "readonly",
|
||||
"quickSaveStyle": "readonly",
|
||||
// from python
|
||||
"localization": "readonly",
|
||||
// progressbar.js
|
||||
|
||||
+25
-17
@@ -86,25 +86,33 @@ const removeContextMenuOption = initResponse[1];
|
||||
const addContextMenuEventListener = initResponse[2];
|
||||
|
||||
function initContextMenu() {
|
||||
// Start example Context Menu Items
|
||||
const generateOnRepeat = (genbuttonid, interruptbuttonid) => {
|
||||
const genbutton = gradioApp().querySelector(genbuttonid);
|
||||
const busy = document.getElementById('progressbar')?.style.display === 'block';
|
||||
if (!busy) genbutton.click();
|
||||
clearInterval(window.generateOnRepeatInterval);
|
||||
window.generateOnRepeatInterval = setInterval(() => {
|
||||
const pbBusy = document.getElementById('progressbar')?.style.display === 'block';
|
||||
if (!pbBusy) genbutton.click();
|
||||
}, 500);
|
||||
const generateForever = (genbuttonid, interruptbuttonid) => {
|
||||
if (window.generateOnRepeatInterval) {
|
||||
log('generateForever: cancel');
|
||||
clearInterval(window.generateOnRepeatInterval);
|
||||
window.generateOnRepeatInterval = null;
|
||||
} else {
|
||||
log('generateForever: start');
|
||||
const genbutton = gradioApp().querySelector(genbuttonid);
|
||||
const busy = document.getElementById('progressbar')?.style.display === 'block';
|
||||
if (!busy) genbutton.click();
|
||||
window.generateOnRepeatInterval = setInterval(() => {
|
||||
const pbBusy = document.getElementById('progressbar')?.style.display === 'block';
|
||||
if (!pbBusy) genbutton.click();
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
const cancelGenerateForever = () => clearInterval(window.generateOnRepeatInterval);
|
||||
|
||||
appendContextMenuOption('#txt2img_generate', 'Generate forever', () => generateOnRepeat('#txt2img_generate', '#txt2img_interrupt'));
|
||||
appendContextMenuOption('#img2img_generate', 'Generate forever', () => generateOnRepeat('#img2img_generate', '#img2img_interrupt'));
|
||||
appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
|
||||
appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);
|
||||
appendContextMenuOption('#txt2img_generate', 'Show NVML overlay', initNVML);
|
||||
appendContextMenuOption('#txt2img_generate', 'Hide NVML overlay', disableNVML);
|
||||
for (const tab of ['txt2img', 'img2img']) {
|
||||
for (const el of ['prompt > label > textarea', 'generate']) {
|
||||
const id = `#${tab}_${el}`;
|
||||
appendContextMenuOption(id, 'Copy to clipboard', () => navigator.clipboard.writeText(document.querySelector(`#${tab}_prompt > label > textarea`).value));
|
||||
appendContextMenuOption(id, 'Generate forever', () => generateForever(`#${tab}_generate`));
|
||||
appendContextMenuOption(id, 'Apply selected style', quickApplyStyle);
|
||||
appendContextMenuOption(id, 'Quick save style', quickSaveStyle);
|
||||
appendContextMenuOption(id, 'nVidia overlay', initNVML);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onUiLoaded(initContextMenu);
|
||||
|
||||
@@ -216,6 +216,18 @@ function applyStyles(styles) {
|
||||
return newStyles.join('|');
|
||||
}
|
||||
|
||||
function quickApplyStyle() {
|
||||
const tabname = getENActiveTab();
|
||||
const btnApply = gradioApp().getElementById(`${tabname}_extra_apply`);
|
||||
if (btnApply) btnApply.click();
|
||||
}
|
||||
|
||||
function quickSaveStyle() {
|
||||
const tabname = getENActiveTab();
|
||||
const btnSave = gradioApp().getElementById(`${tabname}_extra_quicksave`);
|
||||
if (btnSave) btnSave.click();
|
||||
}
|
||||
|
||||
// init
|
||||
|
||||
function setupExtraNetworksForTab(tabname) {
|
||||
@@ -243,6 +255,14 @@ function setupExtraNetworksForTab(tabname) {
|
||||
btnModel.onclick = () => btnModel.classList.toggle('toolbutton-selected');
|
||||
tabs.appendChild(buttons);
|
||||
|
||||
// details
|
||||
const detailsImg = gradioApp().getElementById(`${tabname}_extra_details_img`);
|
||||
const detailsClose = gradioApp().getElementById(`${tabname}_extra_details_close`);
|
||||
if (detailsImg && detailsClose) {
|
||||
detailsImg.title = 'Close details';
|
||||
detailsImg.onclick = () => detailsClose.click();
|
||||
}
|
||||
|
||||
// search and description
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('second-line');
|
||||
|
||||
+8
-2
@@ -1,4 +1,4 @@
|
||||
let nvmlInterval = true; // eslint-disable-line prefer-const
|
||||
let nvmlInterval = null; // eslint-disable-line prefer-const
|
||||
let nvmlEl = null;
|
||||
let nvmlTable = null;
|
||||
|
||||
@@ -60,7 +60,13 @@ async function initNVML() {
|
||||
gradioApp().appendChild(nvmlEl);
|
||||
log('initNVML');
|
||||
}
|
||||
nvmlInterval = setInterval(updateNVML, 1000);
|
||||
if (nvmlInterval) {
|
||||
clearInterval(nvmlInterval);
|
||||
nvmlInterval = null;
|
||||
nvmlEl.style.display = 'none';
|
||||
} else {
|
||||
nvmlInterval = setInterval(updateNVML, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
async function disableNVML() {
|
||||
|
||||
@@ -157,7 +157,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt
|
||||
|
||||
/* context menu (ie for the generate button) */
|
||||
#context-menu { z-index: 9999; position: absolute; display: block; padding: var(--spacing-md); border: 2px solid var(--highlight-color); background: var(--background-fill-primary); color: var(--body-text-color); }
|
||||
.context-menu-items { list-style: none; margin: 0; padding: 0; }
|
||||
.context-menu-items { list-style: none; margin: 0; padding: 0; font-size: 0.9em; }
|
||||
.context-menu-items a { display: block; padding: var(--spacing-md); cursor: pointer; font-weight: normal; }
|
||||
.context-menu-items a:hover { background: var(--highlight-color) }
|
||||
|
||||
@@ -204,6 +204,7 @@ 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-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 }
|
||||
|
||||
|
||||
@@ -879,7 +879,7 @@ def load_diffuser(checkpoint_info=None, already_loaded_state_dict=None, timer=No
|
||||
shared.log.error(f'Failed loading {op}: {checkpoint_info.path} auto={err1} diffusion={err2}')
|
||||
return
|
||||
elif os.path.isfile(checkpoint_info.path) and checkpoint_info.path.lower().endswith('.safetensors'):
|
||||
diffusers_load_config["local_files_only"] = True
|
||||
# diffusers_load_config["local_files_only"] = True
|
||||
diffusers_load_config["extract_ema"] = shared.opts.diffusers_extract_ema
|
||||
pipeline, model_type = detect_pipeline(checkpoint_info.path, op)
|
||||
if pipeline is None:
|
||||
|
||||
+4
-1
@@ -126,7 +126,7 @@ def process_interrogate(interrogation_function, mode, ii_input_files, ii_input_d
|
||||
images = [f.name for f in ii_input_files]
|
||||
else:
|
||||
if not os.path.isdir(ii_input_dir):
|
||||
log.error(f"Input directory not found: {ii_input_dir}")
|
||||
log.error(f"Interrogate: Input directory not found: {ii_input_dir}")
|
||||
return [gr.update(), None]
|
||||
images = modules.shared.listfiles(ii_input_dir)
|
||||
if ii_output_dir != "":
|
||||
@@ -142,6 +142,9 @@ def process_interrogate(interrogation_function, mode, ii_input_files, ii_input_d
|
||||
|
||||
|
||||
def interrogate(image):
|
||||
if image is None:
|
||||
log.error("Interrogate: no image selected")
|
||||
return gr.update()
|
||||
prompt = modules.shared.interrogator.interrogate(image.convert("RGB"))
|
||||
return gr.update() if prompt is None else prompt
|
||||
|
||||
|
||||
@@ -393,6 +393,7 @@ class ExtraNetworksUi:
|
||||
self.button_details: gr.Button = None
|
||||
self.button_refresh: gr.Button = None
|
||||
self.button_scan: gr.Button = None
|
||||
self.button_quicksave: gr.Button = None
|
||||
self.button_save: gr.Button = None
|
||||
self.button_sort: gr.Button = None
|
||||
self.button_apply: gr.Button = None
|
||||
@@ -449,14 +450,14 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
return is_visible, gr.update(visible=is_visible), gr.update(variant=("secondary-down" if is_visible else "secondary"))
|
||||
|
||||
with ui.details:
|
||||
details_close = ToolButton(symbols.close, elem_id=tabname+"_extra_details_close")
|
||||
details_close = ToolButton(symbols.close, elem_id=tabname+"_extra_details_close", elem_classes=['extra-details-close'])
|
||||
details_close.click(fn=lambda: gr.update(visible=False), inputs=[], outputs=[ui.details])
|
||||
with gr.Row():
|
||||
with gr.Column(scale=1):
|
||||
text = gr.HTML('<div>title</div>')
|
||||
ui.details_components.append(text)
|
||||
with gr.Column(scale=1):
|
||||
img = gr.Image(value=None, show_label=False, interactive=False, container=True)
|
||||
img = gr.Image(value=None, show_label=False, interactive=False, container=False, show_download_button=False, show_info=False, elem_id=tabname+"_extra_details_img", elem_classes=['extra-details-img'])
|
||||
ui.details_components.append(img)
|
||||
with gr.Row():
|
||||
btn_save_img = gr.Button('Replace', elem_classes=['small-button'])
|
||||
@@ -468,12 +469,16 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
with gr.Row():
|
||||
btn_save_desc = gr.Button('Save', elem_classes=['small-button'])
|
||||
btn_delete_desc = gr.Button('Delete', elem_classes=['small-button'])
|
||||
btn_close_info = gr.Button('Close', elem_classes=['small-button'])
|
||||
btn_close_info.click(fn=lambda: gr.update(visible=False), inputs=[], outputs=[ui.details])
|
||||
with gr.Tab('Model metadata'):
|
||||
info = gr.JSON({}, show_label=False)
|
||||
ui.details_components.append(info)
|
||||
with gr.Row():
|
||||
btn_save_info = gr.Button('Save', elem_classes=['small-button'])
|
||||
btn_delete_info = gr.Button('Delete', elem_classes=['small-button'])
|
||||
btn_close_info = gr.Button('Close', elem_classes=['small-button'])
|
||||
btn_close_info.click(fn=lambda: gr.update(visible=False), inputs=[], outputs=[ui.details])
|
||||
with gr.Tab('Embedded metadata'):
|
||||
meta = gr.JSON({}, show_label=False)
|
||||
ui.details_components.append(meta)
|
||||
@@ -487,6 +492,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
|
||||
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_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_close = ToolButton(symbols.close, elem_id=tabname+"_extra_close", visible=True)
|
||||
@@ -531,9 +537,9 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
image.thumbnail((512, 512), Image.HAMMING)
|
||||
try:
|
||||
image.save(ui.last_item.local_preview, quality=50)
|
||||
shared.log.debug(f'Extra network save image: item={ui.last_item.name} filename={ui.last_item.local_preview}')
|
||||
shared.log.debug(f'Extra network save image: item={ui.last_item.name} filename="{ui.last_item.local_preview}"')
|
||||
except Exception as e:
|
||||
shared.log.error(f'Extra network save image: item={ui.last_item.name} filename={ui.last_item.local_preview} {e}')
|
||||
shared.log.error(f'Extra network save image: item={ui.last_item.name} filename="{ui.last_item.local_preview}" {e}')
|
||||
return image
|
||||
|
||||
def fn_delete_img():
|
||||
@@ -542,7 +548,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
for file in [f'{fn}{mid}{ext}' for ext in preview_extensions for mid in ['.thumb.', '.preview.', '.']]:
|
||||
if os.path.exists(file):
|
||||
os.remove(file)
|
||||
shared.log.debug(f'Extra network delete image: item={ui.last_item.name} filename={file}')
|
||||
shared.log.debug(f'Extra network delete image: item={ui.last_item.name} filename="{file}"')
|
||||
return 'html/card-no-preview.png'
|
||||
|
||||
def fn_save_desc(desc):
|
||||
@@ -554,7 +560,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
fn = os.path.splitext(ui.last_item.filename)[0] + '.txt'
|
||||
with open(fn, 'w', encoding='utf-8') as f:
|
||||
f.write(desc)
|
||||
shared.log.debug(f'Extra network save desc: item={ui.last_item.name} filename={fn}')
|
||||
shared.log.debug(f'Extra network save desc: item={ui.last_item.name} filename="{fn}"')
|
||||
return desc
|
||||
|
||||
def fn_delete_desc(desc):
|
||||
@@ -565,7 +571,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
else:
|
||||
fn = os.path.splitext(ui.last_item.filename)[0] + '.txt'
|
||||
if os.path.exists(fn):
|
||||
shared.log.debug(f'Extra network delete desc: item={ui.last_item.name} filename={fn}')
|
||||
shared.log.debug(f'Extra network delete desc: item={ui.last_item.name} filename="{fn}"')
|
||||
os.remove(fn)
|
||||
return ''
|
||||
return desc
|
||||
@@ -573,7 +579,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
def fn_save_info(info):
|
||||
fn = os.path.splitext(ui.last_item.filename)[0] + '.json'
|
||||
shared.writefile(info, fn, silent=True)
|
||||
shared.log.debug(f'Extra network save info: item={ui.last_item.name} filename={fn}')
|
||||
shared.log.debug(f'Extra network save info: item={ui.last_item.name} filename="{fn}"')
|
||||
return info
|
||||
|
||||
def fn_delete_info(info):
|
||||
@@ -581,7 +587,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
return info
|
||||
fn = os.path.splitext(ui.last_item.filename)[0] + '.json'
|
||||
if os.path.exists(fn):
|
||||
shared.log.debug(f'Extra network delete info: item={ui.last_item.name} filename={fn}')
|
||||
shared.log.debug(f'Extra network delete info: item={ui.last_item.name} filename="{fn}"')
|
||||
os.remove(fn)
|
||||
return ''
|
||||
return info
|
||||
@@ -656,7 +662,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
'''
|
||||
desc = f'Name: {os.path.basename(item.name)}\nDescription: {item.description}\nPrompt: {item.prompt}\nNegative: {item.negative}\nExtra: {item.extra}\n'
|
||||
text = f'''
|
||||
<h2 style="border-bottom: 1px solid var(--button-primary-border-color); margin-bottom: 1em; margin-top: -1.3em !important;">{item.name}</h2>
|
||||
<h2 style="border-bottom: 1px solid var(--button-primary-border-color); margin: 0em 0px 1em 0 !important">{item.name}</h2>
|
||||
<table style="width: 100%; line-height: 1.3em;"><tbody>
|
||||
<tr><td>Type</td><td>{page.title}</td></tr>
|
||||
<tr><td>Alias</td><td>{getattr(item, 'alias', 'N/A')}</td></tr>
|
||||
@@ -704,6 +710,32 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
res = show_details(text=None, img=None, desc=None, info=None, meta=None, params=params)
|
||||
return res
|
||||
|
||||
def ui_quicksave_click(name):
|
||||
from modules import paths, generation_parameters_copypaste
|
||||
fn = os.path.join(paths.data_path, "params.txt")
|
||||
if os.path.exists(fn):
|
||||
with open(fn, "r", encoding="utf8") as file:
|
||||
prompt = file.read()
|
||||
else:
|
||||
prompt = ''
|
||||
params = generation_parameters_copypaste.parse_generation_parameters(prompt)
|
||||
fn = os.path.join(shared.opts.styles_dir, os.path.splitext(name)[0] + '.json')
|
||||
item = {
|
||||
"type": 'Style',
|
||||
"name": name,
|
||||
"title": name,
|
||||
"filename": fn,
|
||||
"search_term": None,
|
||||
"preview": None,
|
||||
"description": '',
|
||||
"prompt": params.get('Prompt', ''),
|
||||
"negative": params.get('Negative prompt', ''),
|
||||
"extra": '',
|
||||
"local_preview": None,
|
||||
}
|
||||
shared.writefile(item, fn, silent=True)
|
||||
shared.log.debug(f"Extra network quick save style: item={item['name']} filename='{fn}'")
|
||||
|
||||
def ui_sort_cards(msg):
|
||||
shared.log.debug(f'Extra networks: {msg}')
|
||||
return msg
|
||||
@@ -715,6 +747,7 @@ def create_ui(container, button_parent, tabname, skip_indexing = False):
|
||||
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])
|
||||
ui.button_quicksave.click(fn=ui_quicksave_click, _js="() => prompt('Prompt name', '')", inputs=[ui.search], outputs=[])
|
||||
ui.button_details.click(show_details, _js="getCardDetails", inputs=ui.details_components + [dummy_state], outputs=ui.details_components + [ui.details])
|
||||
ui.state.change(state_change, inputs=[ui.state], outputs=[])
|
||||
return ui
|
||||
|
||||
Reference in New Issue
Block a user