diff --git a/html/svg/infinity-fill.svg b/html/svg/infinity-fill.svg new file mode 100644 index 00000000..7204f234 --- /dev/null +++ b/html/svg/infinity-fill.svg @@ -0,0 +1,14 @@ + + + + + + diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js index 8c9a4d8e..cbe6a7b3 100644 --- a/javascript/contextMenus.js +++ b/javascript/contextMenus.js @@ -1,4 +1,4 @@ -contextMenuInit = function () { +/* contextMenuInit = function () { let eventListenerApplied = false; let menuSpecs = new Map(); @@ -189,3 +189,4 @@ addContextMenuEventListener = initResponse[2]; onUiUpdate(function () { addContextMenuEventListener(); }); + */ diff --git a/javascript/hints.js b/javascript/hints.js index d9e0399d..dbd99f42 100644 --- a/javascript/hints.js +++ b/javascript/hints.js @@ -26,6 +26,7 @@ titles = { "\u{1f5e8}": "Interogate Clip", "\u{1f5ea}": "Interogate Deepbooru", "\u{1F300}": "Restore progress", + "\u{267E}": "Toggle generate forever", "Inpaint a part of image": "Draw a mask over an image, and the script will regenerate the masked area with content according to prompt", diff --git a/javascript/ui.js b/javascript/ui.js index 6e3795f7..a6d8b6c0 100644 --- a/javascript/ui.js +++ b/javascript/ui.js @@ -174,10 +174,13 @@ function create_submit_args(args) { function showSubmitButtons(tabname, show) { gradioApp().getElementById(tabname + "_interrupt").style.display = show ? "none" - : "block"; + : "flex"; gradioApp().getElementById(tabname + "_skip").style.display = show ? "none" - : "block"; + : "flex"; + gradioApp().getElementById(tabname + "_generate").style.display = !show + ? "none" + : "flex"; } function showRestoreProgressButton(tabname, show) { @@ -672,8 +675,6 @@ onUiLoaded(function () { } } - - // close aside views function closeAsideViews(menu) { if (quick_menu != menu && quick_menu_open) quick_menu.click(); @@ -746,8 +747,12 @@ onUiLoaded(function () { // extra networks nav menu function clickedOutside(e) { //console.log(e.target.getAttribute('data-testid')); - if(e.target.getAttribute('data-testid') != "textbox" && e.target.getAttribute('data-testid')){ - if (net_menu_open && e.target.closest('[id$="2img_settings_scroll"]')) net_menu.click(); + if ( + e.target.getAttribute("data-testid") != "textbox" && + e.target.getAttribute("data-testid") + ) { + if (net_menu_open && e.target.closest('[id$="2img_settings_scroll"]')) + net_menu.click(); } } function toggleNetMenu(e) { @@ -800,6 +805,62 @@ onUiLoaded(function () { ); disabled_extensions(theme_ext.checked); + function generateOnRepeat(elem, isforever) { + if (elem.generateOnRepeatInterval != null) + clearInterval(elem.generateOnRepeatInterval); + if (isforever) { + const generate_button = elem.previousElementSibling; + elem.generateOnRepeatInterval = setInterval(function () { + if (window.getComputedStyle(generate_button).display !== "none") { + generate_button.click(); + console.log(elem.id); + } + }, 500); + } + } + + function toggleGenerateForever(e) { + e.target.classList.toggle("active"); + if (e.target.className.indexOf("active") != -1) { + generateOnRepeat(e.target, true); + } else { + generateOnRepeat(e.target, false); + } + e.preventDefault(); + e.stopPropagation(); + } + + gradioApp() + .querySelectorAll('button[id*="2img_generate_forever"]') + .forEach((elem) => { + elem.addEventListener("click", toggleGenerateForever); + }); + + /* let generateOnRepeat = function (genbuttonid, interruptbuttonid) { + let genbutton = gradioApp().querySelector(genbuttonid); + let interruptbutton = gradioApp().querySelector(interruptbuttonid); + if (!interruptbutton.offsetParent) { + genbutton.click(); + } + clearInterval(window.generateOnRepeatInterval); + window.generateOnRepeatInterval = setInterval(function () { + if (!interruptbutton.offsetParent) { + genbutton.click(); + } + }, 500); + }; + + appendContextMenuOption("#txt2img_generate", "Generate forever", function () { + generateOnRepeat("#txt2img_generate", "#txt2img_interrupt"); + }); + appendContextMenuOption("#img2img_generate", "Generate forever", function () { + generateOnRepeat("#img2img_generate", "#img2img_interrupt"); + }); + + let cancelGenerateForever = function () { + clearInterval(window.generateOnRepeatInterval); + }; */ + // /* function attachAccordionListeners(elem) { @@ -1238,7 +1299,7 @@ onUiLoaded(function () { setting_quicksettings.value = field_settings; //addModelCheckpoint(); saveQuickSettings(); - console.log(section + " - "+ id + " - " + checked); + console.log(section + " - " + id + " - " + checked); } gradioApp() .querySelectorAll('[id*="add2quick_"]') diff --git a/modules/ui.py b/modules/ui.py index 2983b120..9d8a9613 100644 --- a/modules/ui.py +++ b/modules/ui.py @@ -84,6 +84,7 @@ extra_networks_symbol = '\U0001F3B4' # 🎴 #switch_values_symbol = '\U000021C5' # ⇅ switch_values_symbol = '\u2B80' # ⮀ restore_progress_symbol = '\U0001F300' # 🌀 +generate_forever_symbol = '\u267E' # ♾ interogate_bubble_symbol = '\U0001F5E8' # 🗨 @@ -306,7 +307,8 @@ def create_generate(is_img2img): with gr.Row(elem_id=f"{id_part}_generate_box", elem_classes="generate-box"): interrupt = gr.Button('Interrupt', elem_id=f"{id_part}_interrupt", elem_classes="generate-box-interrupt") skip = gr.Button('Skip', elem_id=f"{id_part}_skip", elem_classes="generate-box-skip") - submit = gr.Button('Generate', elem_id=f"{id_part}_generate", variant='primary') + submit = gr.Button('Generate', elem_id=f"{id_part}_generate", variant='primary') + gr.Button(value=generate_forever_symbol, elem_id=f"{id_part}_generate_forever", variant='primary') skip.click( fn=lambda: shared.state.skip(), diff --git a/style.css b/style.css index 865b8811..025bd621 100644 --- a/style.css +++ b/style.css @@ -150,7 +150,7 @@ body { /*********/ /* Icons */ /*********/ - +[id*="2img_generate_forever"], [id^="refresh_"], [id$="_refresh"], [id$="_clear_prompt"], @@ -173,7 +173,7 @@ body { position: relative; font-size: 0 !important; } - +[id*="2img_generate_forever"]::before, [id$="_refresh"]::before, [id^="refresh_"]::before, [id$="_clear_prompt"]::before, @@ -207,7 +207,7 @@ body { background-color: var(--ae-icon-color); border-radius: var(--ae-panel-border-radius); } - +[id*="2img_generate_forever"]:hover::before, [id$="_refresh"]:hover::before, [id^="refresh_"]:hover::before, [id$="_clear_prompt"]:hover::before, @@ -244,7 +244,12 @@ body { -webkit-mask: url(./file=html/svg/refresh-line.svg) no-repeat 50% 50%; mask: url(./file=html/svg/refresh-line.svg) no-repeat 50% 50%; } - +[id$="2img_generate_forever"]::before { + -webkit-mask: url(./file=html/svg/infinity-fill.svg) no-repeat 50% 50%; + mask: url(./file=html/svg/infinity-fill.svg) no-repeat 50% 50%; + width: 90%; + height: 90%; +} [id$="_clear_prompt"]::before { -webkit-mask: url(./file=html/svg/delete-bin-5-line.svg) no-repeat 50% 50%; mask: url(./file=html/svg/delete-bin-5-line.svg) no-repeat 50% 50%; @@ -1884,12 +1889,29 @@ button.primary:hover { min-height: var(--ae-generate-button-height); } +button[id$="_generate_forever"] { + flex-grow: 0; + min-width: unset; +} + +button[id$="_generate_forever"].active { + background: var(--ae-primary-color) !important; + color: var(--ae-input-bg-color) !important; +} + +button[id$="_generate_forever"].active:before { + background: var(--ae-icon-hover-color) !important; +} + [id$="_interrupt"].secondary, [id$="_skip"].secondary { + min-height: var(--ae-generate-button-height); background-color: var(--ae-input-bg-color); + /* position: absolute; width: 50%; height: 100%; + */ display: none; }