Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request]: Add generate forever/cancel generate forever options when right-clicking generate button in deforum #966

Open
1 task done
sdman88 opened this issue Apr 15, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@sdman88
Copy link

sdman88 commented Apr 15, 2024

Is there an existing issue for this?

  • I have searched the existing issues and checked the recent builds/commits

What would your feature do ?

If possible could the "generate forever/cancel generate forever" options found in txt2img of webui when right-clicking the generate button be added to the deforum generate button to allow for automatic continuous generations?

Proposed workflow

  1. Right-click the generate button to have pop-up box show the generate forever/cancel generate forever options
  2. Selecting "generate forever" will continuously generate animations automatically one after the other until cancelled without need to manually hit generate each time
  3. Selecting "cancel generate forever" would stop the automatic continuous generation and go back to manual mode

Additional information

Screenshot 2024-04-15 152244

Are you going to help adding it?

Did what I could, see my modified webui javascript>contextMenus.js code below to add generate forever/cancel generate forever functionality to deforum

@sdman88 sdman88 added the enhancement New feature or request label Apr 15, 2024
@sdman88
Copy link
Author

sdman88 commented Apr 16, 2024

Actually think I managed to figure this out via trial and error and some digging into the code of webui. Here is the code I added to my javascript>contextMenus.js file of webui for anyone else looking to add this functionality to deforum. Basically had to modify the contextMenus.js file in notepad and all I did was duplicate the existing txt2img_generate/txt2img_interrupt code and modified it to use deforum tags.

To Use: Copy all of the code that appears below after the colon and paste over all the existing code in contextMenus.js file using notepad. The file appears in javascript folder of webui. Make sure to replace all of the original existing code found in the contextMenus.js file since the code below contains all the original code + the added deforum code. (note: you might want to make backup of original contextMenus.js file and save it in different location not in the webui folder in case something goes wrong or breaks, but my limited testing seemed to work fine):

var contextMenuInit = function() {
let eventListenerApplied = false;
let menuSpecs = new Map();

const uid = function() {
    return Date.now().toString(36) + Math.random().toString(36).substring(2);
};

function showContextMenu(event, element, menuEntries) {
    let posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    let posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;

    let oldMenu = gradioApp().querySelector('#context-menu');
    if (oldMenu) {
        oldMenu.remove();
    }

    let baseStyle = window.getComputedStyle(uiCurrentTab);

    const contextMenu = document.createElement('nav');
    contextMenu.id = "context-menu";
    contextMenu.style.background = baseStyle.background;
    contextMenu.style.color = baseStyle.color;
    contextMenu.style.fontFamily = baseStyle.fontFamily;
    contextMenu.style.top = posy + 'px';
    contextMenu.style.left = posx + 'px';



    const contextMenuList = document.createElement('ul');
    contextMenuList.className = 'context-menu-items';
    contextMenu.append(contextMenuList);

    menuEntries.forEach(function(entry) {
        let contextMenuEntry = document.createElement('a');
        contextMenuEntry.innerHTML = entry['name'];
        contextMenuEntry.addEventListener("click", function() {
            entry['func']();
        });
        contextMenuList.append(contextMenuEntry);

    });

    gradioApp().appendChild(contextMenu);

    let menuWidth = contextMenu.offsetWidth + 4;
    let menuHeight = contextMenu.offsetHeight + 4;

    let windowWidth = window.innerWidth;
    let windowHeight = window.innerHeight;

    if ((windowWidth - posx) < menuWidth) {
        contextMenu.style.left = windowWidth - menuWidth + "px";
    }

    if ((windowHeight - posy) < menuHeight) {
        contextMenu.style.top = windowHeight - menuHeight + "px";
    }

}

function appendContextMenuOption(targetElementSelector, entryName, entryFunction) {

    var currentItems = menuSpecs.get(targetElementSelector);

    if (!currentItems) {
        currentItems = [];
        menuSpecs.set(targetElementSelector, currentItems);
    }
    let newItem = {
        id: targetElementSelector + '_' + uid(),
        name: entryName,
        func: entryFunction,
        isNew: true
    };

    currentItems.push(newItem);
    return newItem['id'];
}

function removeContextMenuOption(uid) {
    menuSpecs.forEach(function(v) {
        let index = -1;
        v.forEach(function(e, ei) {
            if (e['id'] == uid) {
                index = ei;
            }
        });
        if (index >= 0) {
            v.splice(index, 1);
        }
    });
}

function addContextMenuEventListener() {
    if (eventListenerApplied) {
        return;
    }
    gradioApp().addEventListener("click", function(e) {
        if (!e.isTrusted) {
            return;
        }

        let oldMenu = gradioApp().querySelector('#context-menu');
        if (oldMenu) {
            oldMenu.remove();
        }
    });
    gradioApp().addEventListener("contextmenu", function(e) {
        let oldMenu = gradioApp().querySelector('#context-menu');
        if (oldMenu) {
            oldMenu.remove();
        }
        menuSpecs.forEach(function(v, k) {
            if (e.composedPath()[0].matches(k)) {
                showContextMenu(e, e.composedPath()[0], v);
                e.preventDefault();
            }
        });
    });
    eventListenerApplied = true;

}

return [appendContextMenuOption, removeContextMenuOption, addContextMenuEventListener];

};

var initResponse = contextMenuInit();
var appendContextMenuOption = initResponse[0];
var removeContextMenuOption = initResponse[1];
var addContextMenuEventListener = initResponse[2];

(function() {
//Start example Context Menu Items
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);
};

let generateOnRepeat_deforum = function() {
generateOnRepeat('#deforum_generate', '#deforum_interrupt');
};

let generateOnRepeat_txt2img = function() {
    generateOnRepeat('#txt2img_generate', '#txt2img_interrupt');
};

let generateOnRepeat_img2img = function() {
    generateOnRepeat('#img2img_generate', '#img2img_interrupt');
};

appendContextMenuOption('#txt2img_generate', 'Generate forever', generateOnRepeat_txt2img);
appendContextMenuOption('#txt2img_interrupt', 'Generate forever', generateOnRepeat_txt2img);
appendContextMenuOption('#img2img_generate', 'Generate forever', generateOnRepeat_img2img);
appendContextMenuOption('#img2img_interrupt', 'Generate forever', generateOnRepeat_img2img);

appendContextMenuOption('#deforum_generate', 'Generate forever', generateOnRepeat_deforum);
appendContextMenuOption('#deforum_interrupt', 'Generate forever', generateOnRepeat_deforum);

let cancelGenerateForever = function() {
    clearInterval(window.generateOnRepeatInterval);
};

appendContextMenuOption('#txt2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#txt2img_generate', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#img2img_interrupt', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#img2img_generate', 'Cancel generate forever', cancelGenerateForever);

appendContextMenuOption('#deforum_interrupt', 'Cancel generate forever', cancelGenerateForever);
appendContextMenuOption('#deforum_generate', 'Cancel generate forever', cancelGenerateForever);

})();
//End example Context Menu Items

onAfterUiUpdate(addContextMenuEventListener);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant