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;
}