| class ForgeCouple { |
|
|
| static previewRes = {}; |
| static previewBtn = {}; |
| static mappingTable = {}; |
| static manualIndex = {}; |
| static row_btns = {}; |
| static row_btns_containers = {}; |
| static bbox = {}; |
|
|
| static coords = [[-1, -1], [-1, -1]]; |
|
|
| static COLORS = [ |
| "hsl(0, 36%, 36%)", |
| "hsl(30, 36%, 36%)", |
| "hsl(60, 36%, 36%)", |
| "hsl(120, 36%, 36%)", |
| "hsl(240, 36%, 36%)", |
| "hsl(280, 36%, 36%)", |
| "hsl(320, 36%, 36%)" |
| ]; |
|
|
| |
| |
| |
| |
| static updateColors(mode) { |
| const selection = parseInt(this.manualIndex[mode].value); |
|
|
| const rows = this.mappingTable[mode].querySelectorAll("tr"); |
| rows.forEach((row, i) => { |
| const bg = (selection === i) ? |
| "var(--table-row-focus)" : |
| `var(--table-${(i % 2 == 0) ? "odd" : "even"}-background-fill)`; |
| row.style.background = `linear-gradient(to right, ${bg} 80%, ${this.COLORS[i % this.COLORS.length]})`; |
| }); |
|
|
| if (selection < 0 || selection >= rows.length) { |
| ForgeCouple.bbox[mode].hideBox(); |
| this.row_btns[mode].style.display = "none"; |
| } |
| else |
| ForgeCouple.bbox[mode].showBox(this.COLORS[selection], rows[selection]); |
| } |
|
|
| |
| |
| |
| |
| static async preview(mode) { |
| if (!mode) |
| return; |
|
|
| if (mode.length === 3) { |
| const input = ForgeCouple.mappingTable[mode].querySelector("input"); |
| if (input != null && input.type != "file") |
| return; |
| } |
|
|
| setTimeout(async () => { |
| var res = null; |
| var file = null; |
|
|
| if (mode === "t2i") { |
| const w = parseInt(gradioApp().getElementById("txt2img_width").querySelector("input").value); |
| const h = parseInt(gradioApp().getElementById("txt2img_height").querySelector("input").value); |
| res = `${w}x${h}`; |
| } else { |
| const i2i_size = gradioApp().getElementById("img2img_column_size").querySelector(".tab-nav"); |
|
|
| if (mode !== "i2i") { |
| file = mode; |
| mode = "i2i"; |
| } |
|
|
| if (i2i_size.children[0].classList.contains("selected")) { |
| |
| const w = parseInt(gradioApp().getElementById("img2img_width").querySelector("input").value); |
| const h = parseInt(gradioApp().getElementById("img2img_height").querySelector("input").value); |
| res = `${w}x${h}`; |
| } else { |
| |
| if (file) { |
| const dim = await this.img2resolution(file); |
| res = `${dim.w}x${dim.h}`; |
| } else { |
| res = gradioApp().getElementById("img2img_scale_resolution_preview")?.querySelector(".resolution")?.textContent; |
| if (!res) |
| res = "1024x1024"; |
| } |
| } |
| } |
|
|
| this.previewRes[mode].value = res; |
| updateInput(this.previewRes[mode]); |
|
|
| this.previewBtn[mode].click(); |
|
|
| }, (mode === "t2i") ? 16 : 32); |
| } |
|
|
| |
| |
| |
| |
| static onSelect(mode) { |
| const rows = this.mappingTable[mode].querySelectorAll("tr"); |
| rows.forEach((row, i) => { |
| if (row.querySelector(":focus-within") != null) { |
| if (this.manualIndex[mode].value == i) { |
| this.manualIndex[mode].value = -1; |
| this.row_btns[mode].style.display = "none"; |
| } |
| else { |
| this.manualIndex[mode].value = i; |
| const bounding = row.querySelector("td").getBoundingClientRect(); |
| const bounding_container = this.row_btns_containers[mode].getBoundingClientRect(); |
| this.row_btns[mode].style.top = `calc(${bounding.top - bounding_container.top}px - 1em)`; |
| this.row_btns[mode].style.display = "block"; |
| } |
| updateInput(this.manualIndex[mode]); |
| } |
| }); |
|
|
| this.updateColors(mode); |
| } |
|
|
| |
| |
| |
| |
| |
| static registerHovering(mode, separator) { |
| const promptHint = document.createElement("div"); |
| promptHint.classList.add("prompt-hint"); |
|
|
| const table = ForgeCouple.mappingTable[mode].parentElement.parentElement.parentElement; |
| table.appendChild(promptHint); |
|
|
| var showHint = true; |
|
|
| table.addEventListener('contextmenu', (e) => { |
| if (e.ctrlKey) { |
| e.preventDefault(); |
| showHint = !showHint; |
| } |
| }); |
|
|
| ForgeCouple.mappingTable[mode].addEventListener('mousemove', (e) => { |
| if (!showHint) { |
| promptHint.style.display = 'none'; |
| return; |
| } |
|
|
| var el = e.target; |
|
|
| while (el.tagName !== 'TR') { |
| el = el.parentElement; |
| if (el.tagName === 'TABLE') { |
| promptHint.style.display = 'none'; |
| return; |
| } |
| } |
|
|
| const prompt = gradioApp().getElementById(`${mode === "t2i" ? "txt" : "img"}2img_prompt`).querySelector("textarea").value; |
| var sep = separator.value.trim(); |
|
|
| if (!sep) |
| sep = "\n"; |
|
|
| const rows = [...ForgeCouple.mappingTable[mode].querySelectorAll("tr")]; |
| const rowIndex = rows.indexOf(el); |
|
|
| if (!prompt.trim()) { |
| promptHint.style.display = 'none'; |
| return; |
| } |
|
|
| if (rowIndex < prompt.split(sep).length) |
| promptHint.innerHTML = prompt.split(sep)[rowIndex].replaceAll("<", "<").replaceAll(">", ">"); |
| else |
| promptHint.innerHTML = '<p style="color:red;"><i>missing...</i></p>'; |
|
|
| promptHint.style.left = `calc(${e.clientX}px + 1em)`; |
| promptHint.style.top = `calc(${e.clientY}px + 1em)`; |
|
|
| promptHint.style.display = 'block'; |
| }); |
|
|
| ForgeCouple.mappingTable[mode].addEventListener('mouseleave', (e) => { |
| promptHint.style.display = 'none'; |
| }); |
| } |
|
|
| |
| static registerResolutionHandles() { |
|
|
| [["txt2img", "t2i"], ["img2img", "i2i"]].forEach(([tab, mode]) => { |
| const btns = gradioApp().getElementById(`${tab}_dimensions_row`)?.querySelectorAll("button"); |
| if (btns != null) |
| btns.forEach((btn) => { btn.onclick = () => { ForgeCouple.preview(mode); } }); |
|
|
| const width = gradioApp().getElementById(`${tab}_width`).querySelectorAll("input"); |
| const height = gradioApp().getElementById(`${tab}_height`).querySelectorAll("input"); |
|
|
| [...width, ...height].forEach((slider) => { |
| slider.addEventListener("change", () => { ForgeCouple.preview(mode); }); |
| }); |
| }); |
|
|
| const i2i_size_btns = gradioApp().getElementById("img2img_column_size").querySelector(".tab-nav"); |
| i2i_size_btns.addEventListener("click", () => { ForgeCouple.preview("i2i"); }); |
|
|
| const tabs = gradioApp().querySelector('#tabs').querySelector('.tab-nav'); |
| tabs.addEventListener("click", () => { |
| if (tabs.children[0].classList.contains("selected")) |
| ForgeCouple.preview("t2i"); |
| if (tabs.children[1].classList.contains("selected")) |
| ForgeCouple.preview("i2i"); |
| }); |
|
|
| } |
|
|
| |
| |
| |
| |
| |
| static img2resolution(b64) { |
| return new Promise(function (resolved, rejected) { |
|
|
| var i = new Image() |
| i.onload = function () { |
| resolved({ w: i.width, h: i.height }) |
| }; |
| i.src = b64; |
|
|
| }); |
| } |
|
|
| } |
|
|
| onUiLoaded(async () => { |
| ["t2i", "i2i"].forEach((mode) => { |
| const ex = gradioApp().getElementById(`forge_couple_${mode}`); |
|
|
| ForgeCouple.previewRes[mode] = ex.querySelector(".fc_preview_res").querySelector("input"); |
| ForgeCouple.previewBtn[mode] = ex.querySelector(".fc_preview_real"); |
| ForgeCouple.mappingTable[mode] = ex.querySelector(".fc_mapping").querySelector("tbody"); |
| ForgeCouple.manualIndex[mode] = ex.querySelector(".fc_index").querySelector("input"); |
| ForgeCouple.row_btns[mode] = ex.querySelector(".fc_row_btns"); |
| ForgeCouple.registerHovering(mode, ex.querySelector(".fc_separator").querySelector("input")); |
|
|
| ForgeCouple.row_btns[mode].style.display = "none"; |
| ForgeCouple.row_btns[mode].querySelectorAll("button").forEach((btn) => { |
| btn.setAttribute("style", |
| "width: 2em; height: 2em; min-width: unset !important;" |
| ); |
| }) |
|
|
| ForgeCouple.row_btns_containers[mode] = ex.querySelector(".fc_mapping").querySelector(".table-wrap").parentElement; |
| ForgeCouple.row_btns_containers[mode].appendChild(ForgeCouple.row_btns[mode]); |
|
|
| const row = ex.querySelector(".controls-wrap"); |
| row.remove(); |
|
|
| const mapping_div = ex.querySelector(".fc_mapping").children[1]; |
| const btns = ex.querySelector(".fc_map_btns"); |
| const temp = btns.parentElement; |
|
|
| mapping_div.insertBefore(btns, mapping_div.children[1]); |
| temp.remove(); |
|
|
| const preview_img = ex.querySelector("img"); |
| preview_img.ondragstart = (e) => { e.preventDefault(); return false; }; |
|
|
| const manual_field = ex.querySelector(".fc_manual_field").querySelector("input"); |
|
|
| ForgeCouple.bbox[mode] = new ForgeCoupleBox(preview_img, manual_field, mode); |
| while (preview_img.parentElement.firstElementChild.tagName === "DIV") |
| preview_img.parentElement.firstElementChild.remove(); |
|
|
| const bg_btns = ex.querySelector(".fc_bg_btns"); |
| preview_img.parentElement.style.overflow = "visible"; |
| preview_img.parentElement.appendChild(bg_btns); |
|
|
| ForgeCoupleImageLoader.setup(preview_img, bg_btns.querySelectorAll("button")) |
|
|
| setTimeout(() => { |
| ForgeCouple.preview(mode); |
| }, 50); |
| }); |
|
|
| ForgeCouple.registerResolutionHandles(); |
|
|
| }) |
|
|