aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extensions-builtin/Lora/lora.py1
-rw-r--r--extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js15
-rw-r--r--html/licenses.html26
-rw-r--r--javascript/contextMenus.js2
-rw-r--r--javascript/edit-attention.js2
-rw-r--r--javascript/extraNetworks.js36
-rw-r--r--javascript/hints.js2
-rw-r--r--javascript/imageviewer.js70
-rw-r--r--javascript/progressbar.js67
-rw-r--r--javascript/ui.js3
-rw-r--r--modules/generation_parameters_copypaste.py7
-rw-r--r--modules/images.py4
-rw-r--r--modules/mac_specific.py9
-rw-r--r--modules/scripts.py14
-rw-r--r--modules/scripts_postprocessing.py2
-rw-r--r--modules/sd_hijack_optimizations.py4
-rw-r--r--modules/sd_hijack_unet.py2
-rw-r--r--modules/shared.py3
-rw-r--r--modules/textual_inversion/textual_inversion.py6
-rw-r--r--modules/ui.py49
-rw-r--r--modules/ui_common.py5
-rw-r--r--modules/ui_components.py36
-rw-r--r--modules/ui_extensions.py2
-rw-r--r--modules/ui_extra_networks.py49
-rw-r--r--requirements.txt2
-rw-r--r--requirements_versions.txt2
-rw-r--r--script.js6
-rw-r--r--scripts/postprocessing_upscale.py34
-rw-r--r--scripts/xyz_grid.py21
-rw-r--r--style.css762
-rw-r--r--webui.py2
31 files changed, 531 insertions, 714 deletions
diff --git a/extensions-builtin/Lora/lora.py b/extensions-builtin/Lora/lora.py
index 8937b585..7c371deb 100644
--- a/extensions-builtin/Lora/lora.py
+++ b/extensions-builtin/Lora/lora.py
@@ -178,6 +178,7 @@ def load_loras(names, multipliers=None):
def lora_forward(module, input, res):
+ input = devices.cond_cast_unet(input)
if len(loaded_loras) == 0:
return res
diff --git a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
index 4a85c8eb..f0918e26 100644
--- a/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
+++ b/extensions-builtin/prompt-bracket-checker/javascript/prompt-bracket-checker.js
@@ -89,22 +89,15 @@ function checkBrackets(evt, textArea, counterElt) {
function setupBracketChecking(id_prompt, id_counter){
var textarea = gradioApp().querySelector("#" + id_prompt + " > label > textarea");
var counter = gradioApp().getElementById(id_counter)
+
textarea.addEventListener("input", function(evt){
checkBrackets(evt, textarea, counter)
});
}
-var shadowRootLoaded = setInterval(function() {
- var shadowRoot = document.querySelector('gradio-app').shadowRoot;
- if(! shadowRoot) return false;
-
- var shadowTextArea = shadowRoot.querySelectorAll('#txt2img_prompt > label > textarea');
- if(shadowTextArea.length < 1) return false;
-
- clearInterval(shadowRootLoaded);
-
+onUiLoaded(function(){
setupBracketChecking('txt2img_prompt', 'txt2img_token_counter')
setupBracketChecking('txt2img_neg_prompt', 'txt2img_negative_token_counter')
- setupBracketChecking('img2img_prompt', 'imgimg_token_counter')
+ setupBracketChecking('img2img_prompt', 'img2img_token_counter')
setupBracketChecking('img2img_neg_prompt', 'img2img_negative_token_counter')
-}, 1000);
+}) \ No newline at end of file
diff --git a/html/licenses.html b/html/licenses.html
index bddbf466..bc995aa0 100644
--- a/html/licenses.html
+++ b/html/licenses.html
@@ -635,4 +635,30 @@ SOFTWARE.
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+</pre>
+
+<h2><a href="https://github.com/explosion/curated-transformers/blob/main/LICENSE">Curated transformers</a></h2>
+<small>The MPS workaround for nn.Linear on macOS 13.2.X is based on the MPS workaround for nn.Linear created by danieldk for Curated transformers</small>
+<pre>
+The MIT License (MIT)
+
+Copyright (C) 2021 ExplosionAI GmbH
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
</pre> \ No newline at end of file
diff --git a/javascript/contextMenus.js b/javascript/contextMenus.js
index 11bcce1b..06f505b0 100644
--- a/javascript/contextMenus.js
+++ b/javascript/contextMenus.js
@@ -43,7 +43,7 @@ contextMenuInit = function(){
})
- gradioApp().getRootNode().appendChild(contextMenu)
+ gradioApp().appendChild(contextMenu)
let menuWidth = contextMenu.offsetWidth + 4;
let menuHeight = contextMenu.offsetHeight + 4;
diff --git a/javascript/edit-attention.js b/javascript/edit-attention.js
index 619bb1fa..20a5aadf 100644
--- a/javascript/edit-attention.js
+++ b/javascript/edit-attention.js
@@ -1,6 +1,6 @@
function keyupEditAttention(event){
let target = event.originalTarget || event.composedPath()[0];
- if (!target.matches("[id*='_toprow'] textarea.gr-text-input[placeholder]")) return;
+ if (! target.matches("[id*='_toprow'] [id*='_prompt'] textarea")) return;
if (! (event.metaKey || event.ctrlKey)) return;
let isPlus = event.key == "ArrowUp"
diff --git a/javascript/extraNetworks.js b/javascript/extraNetworks.js
index 2fb87cd5..40818bb4 100644
--- a/javascript/extraNetworks.js
+++ b/javascript/extraNetworks.js
@@ -139,3 +139,39 @@ function extraNetworksShowMetadata(text){
popup(elem);
}
+
+function requestGet(url, data, handler, errorHandler){
+ var xhr = new XMLHttpRequest();
+ var args = Object.keys(data).map(function(k){ return encodeURIComponent(k) + '=' + encodeURIComponent(data[k]) }).join('&')
+ xhr.open("GET", url + "?" + args, true);
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ try {
+ var js = JSON.parse(xhr.responseText);
+ handler(js)
+ } catch (error) {
+ console.error(error);
+ errorHandler()
+ }
+ } else{
+ errorHandler()
+ }
+ }
+ };
+ var js = JSON.stringify(data);
+ xhr.send(js);
+}
+
+function extraNetworksRequestMetadata(extraPage, cardName){
+ showError = function(){ extraNetworksShowMetadata("there was an error getting metadata"); }
+
+ requestGet("./sd_extra_networks/metadata", {"page": extraPage, "item": cardName}, function(data){
+ if(data && data.metadata){
+ extraNetworksShowMetadata(data.metadata)
+ } else{
+ showError()
+ }
+ }, showError)
+}
diff --git a/javascript/hints.js b/javascript/hints.js
index 58e4a0a2..b3f3d08d 100644
--- a/javascript/hints.js
+++ b/javascript/hints.js
@@ -18,7 +18,7 @@ titles = {
"\u2199\ufe0f": "Read generation parameters from prompt or last generation if prompt is empty into user interface.",
"\u{1f4c2}": "Open images output directory",
"\u{1f4be}": "Save style",
- "\u{1f5d1}": "Clear prompt",
+ "\u{1f5d1}\ufe0f": "Clear prompt",
"\u{1f4cb}": "Apply selected styles to current prompt",
"\u{1f4d2}": "Paste available values into the field",
"\u{1f3b4}": "Show extra networks",
diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js
index 28e748b7..7547e771 100644
--- a/javascript/imageviewer.js
+++ b/javascript/imageviewer.js
@@ -50,7 +50,7 @@ function updateOnBackgroundChange() {
}
function modalImageSwitch(offset) {
- var allgalleryButtons = gradioApp().querySelectorAll(".gallery-item.transition-all")
+ var allgalleryButtons = gradioApp().querySelectorAll(".gradio-gallery .thumbnail-item")
var galleryButtons = []
allgalleryButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
@@ -59,7 +59,7 @@ function modalImageSwitch(offset) {
})
if (galleryButtons.length > 1) {
- var allcurrentButtons = gradioApp().querySelectorAll(".gallery-item.transition-all.\\!ring-2")
+ var allcurrentButtons = gradioApp().querySelectorAll(".gradio-gallery .thumbnail-item.selected")
var currentButton = null
allcurrentButtons.forEach(function(elem) {
if (elem.parentElement.offsetParent) {
@@ -136,37 +136,29 @@ function modalKeyHandler(event) {
}
}
-function showGalleryImage() {
- setTimeout(function() {
- fullImg_preview = gradioApp().querySelectorAll('img.w-full.object-contain')
-
- if (fullImg_preview != null) {
- fullImg_preview.forEach(function function_name(e) {
- if (e.dataset.modded)
- return;
- e.dataset.modded = true;
- if(e && e.parentElement.tagName == 'DIV'){
- e.style.cursor='pointer'
- e.style.userSelect='none'
-
- var isFirefox = isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
-
- // For Firefox, listening on click first switched to next image then shows the lightbox.
- // If you know how to fix this without switching to mousedown event, please.
- // For other browsers the event is click to make it possiblr to drag picture.
- var event = isFirefox ? 'mousedown' : 'click'
-
- e.addEventListener(event, function (evt) {
- if(!opts.js_modal_lightbox || evt.button != 0) return;
- modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
- evt.preventDefault()
- showModal(evt)
- }, true);
- }
- });
- }
+function setupImageForLightbox(e) {
+ if (e.dataset.modded)
+ return;
+
+ e.dataset.modded = true;
+ e.style.cursor='pointer'
+ e.style.userSelect='none'
+
+ var isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1
+
+ // For Firefox, listening on click first switched to next image then shows the lightbox.
+ // If you know how to fix this without switching to mousedown event, please.
+ // For other browsers the event is click to make it possiblr to drag picture.
+ var event = isFirefox ? 'mousedown' : 'click'
+
+ e.addEventListener(event, function (evt) {
+ if(!opts.js_modal_lightbox || evt.button != 0) return;
+
+ modalZoomSet(gradioApp().getElementById('modalImage'), opts.js_modal_lightbox_initially_zoomed)
+ evt.preventDefault()
+ showModal(evt)
+ }, true);
- }, 100);
}
function modalZoomSet(modalImage, enable) {
@@ -199,21 +191,21 @@ function modalTileImageToggle(event) {
}
function galleryImageHandler(e) {
- if (e && e.parentElement.tagName == 'BUTTON') {
+ //if (e && e.parentElement.tagName == 'BUTTON') {
e.onclick = showGalleryImage;
- }
+ //}
}
onUiUpdate(function() {
- fullImg_preview = gradioApp().querySelectorAll('img.w-full')
+ fullImg_preview = gradioApp().querySelectorAll('.gradio-gallery > div > img')
if (fullImg_preview != null) {
- fullImg_preview.forEach(galleryImageHandler);
+ fullImg_preview.forEach(setupImageForLightbox);
}
updateOnBackgroundChange();
})
document.addEventListener("DOMContentLoaded", function() {
- const modalFragment = document.createDocumentFragment();
+ //const modalFragment = document.createDocumentFragment();
const modal = document.createElement('div')
modal.onclick = closeModal;
modal.id = "lightboxModal";
@@ -277,9 +269,9 @@ document.addEventListener("DOMContentLoaded", function() {
modal.appendChild(modalNext)
+ gradioApp().appendChild(modal)
- gradioApp().getRootNode().appendChild(modal)
- document.body.appendChild(modalFragment);
+ document.body.appendChild(modal);
});
diff --git a/javascript/progressbar.js b/javascript/progressbar.js
index 9ccc9da4..4ac9b8db 100644
--- a/javascript/progressbar.js
+++ b/javascript/progressbar.js
@@ -1,78 +1,13 @@
// code related to showing and updating progressbar shown as the image is being made
-
-galleries = {}
-storedGallerySelections = {}
-galleryObservers = {}
-
function rememberGallerySelection(id_gallery){
- storedGallerySelections[id_gallery] = getGallerySelectedIndex(id_gallery)
-}
-function getGallerySelectedIndex(id_gallery){
- let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
- let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
-
- let currentlySelectedIndex = -1
- galleryButtons.forEach(function(v, i){ if(v==galleryBtnSelected) { currentlySelectedIndex = i } })
-
- return currentlySelectedIndex
}
-// this is a workaround for https://github.com/gradio-app/gradio/issues/2984
-function check_gallery(id_gallery){
- let gallery = gradioApp().getElementById(id_gallery)
- // if gallery has no change, no need to setting up observer again.
- if (gallery && galleries[id_gallery] !== gallery){
- galleries[id_gallery] = gallery;
- if(galleryObservers[id_gallery]){
- galleryObservers[id_gallery].disconnect();
- }
+function getGallerySelectedIndex(id_gallery){
- storedGallerySelections[id_gallery] = -1
-
- galleryObservers[id_gallery] = new MutationObserver(function (){
- let galleryButtons = gradioApp().querySelectorAll('#'+id_gallery+' .gallery-item')
- let galleryBtnSelected = gradioApp().querySelector('#'+id_gallery+' .gallery-item.\\!ring-2')
- let currentlySelectedIndex = getGallerySelectedIndex(id_gallery)
- prevSelectedIndex = storedGallerySelections[id_gallery]
- storedGallerySelections[id_gallery] = -1
-
- if (prevSelectedIndex !== -1 && galleryButtons.length>prevSelectedIndex && !galleryBtnSelected) {
- // automatically re-open previously selected index (if exists)
- activeElement = gradioApp().activeElement;
- let scrollX = window.scrollX;
- let scrollY = window.scrollY;
-
- galleryButtons[prevSelectedIndex].click();
- showGalleryImage();
-
- // When the gallery button is clicked, it gains focus and scrolls itself into view
- // We need to scroll back to the previous position
- setTimeout(function (){
- window.scrollTo(scrollX, scrollY);
- }, 50);
-
- if(activeElement){
- // i fought this for about an hour; i don't know why the focus is lost or why this helps recover it
- // if someone has a better solution please by all means
- setTimeout(function (){
- activeElement.focus({
- preventScroll: true // Refocus the element that was focused before the gallery was opened without scrolling to it
- })
- }, 1);
- }
- }
- })
- galleryObservers[id_gallery].observe( gallery, { childList:true, subtree:false })
- }
}
-onUiUpdate(function(){
- check_gallery('txt2img_gallery')
- check_gallery('img2img_gallery')
-})
-
function request(url, data, handler, errorHandler){
var xhr = new XMLHttpRequest();
var url = url;
diff --git a/javascript/ui.js b/javascript/ui.js
index b7a8268a..fcaf5608 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -86,7 +86,7 @@ function get_tab_index(tabId){
var res = 0
gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button').forEach(function(button, i){
- if(button.className.indexOf('bg-white') != -1)
+ if(button.className.indexOf('selected') != -1)
res = i
})
@@ -255,7 +255,6 @@ onUiUpdate(function(){
}
prompt.parentElement.insertBefore(counter, prompt)
- counter.classList.add("token-counter")
prompt.parentElement.style.position = "relative"
promptTokecountUpdateFuncs[id] = function(){ update_token_counter(id_button); }
diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py
index 7c0b5b4e..6df76858 100644
--- a/modules/generation_parameters_copypaste.py
+++ b/modules/generation_parameters_copypaste.py
@@ -401,9 +401,14 @@ def connect_paste(button, paste_fields, input_comp, override_settings_component,
button.click(
fn=paste_func,
- _js=f"recalculate_prompts_{tabname}",
inputs=[input_comp],
outputs=[x[0] for x in paste_fields],
)
+ button.click(
+ fn=None,
+ _js=f"recalculate_prompts_{tabname}",
+ inputs=[],
+ outputs=[],
+ )
diff --git a/modules/images.py b/modules/images.py
index 2da988ee..7030aaaa 100644
--- a/modules/images.py
+++ b/modules/images.py
@@ -645,6 +645,8 @@ Steps: {json_info["steps"]}, Sampler: {sampler}, CFG scale: {json_info["scale"]}
def image_data(data):
+ import gradio as gr
+
try:
image = Image.open(io.BytesIO(data))
textinfo, _ = read_info_from_image(image)
@@ -660,7 +662,7 @@ def image_data(data):
except Exception:
pass
- return '', None
+ return gr.update(), None
def flatten(img, bgcolor):
diff --git a/modules/mac_specific.py b/modules/mac_specific.py
index 18e6ff72..6fe8dea0 100644
--- a/modules/mac_specific.py
+++ b/modules/mac_specific.py
@@ -1,4 +1,5 @@
import torch
+import platform
from modules import paths
from modules.sd_hijack_utils import CondFunc
from packaging import version
@@ -32,6 +33,10 @@ if has_mps:
# MPS fix for randn in torchsde
CondFunc('torchsde._brownian.brownian_interval._randn', lambda _, size, dtype, device, seed: torch.randn(size, dtype=dtype, device=torch.device("cpu"), generator=torch.Generator(torch.device("cpu")).manual_seed(int(seed))).to(device), lambda _, size, dtype, device, seed: device.type == 'mps')
+ if platform.mac_ver()[0].startswith("13.2."):
+ # MPS workaround for https://github.com/pytorch/pytorch/issues/95188, thanks to danieldk (https://github.com/explosion/curated-transformers/pull/124)
+ CondFunc('torch.nn.functional.linear', lambda _, input, weight, bias: (torch.matmul(input, weight.t()) + bias) if bias is not None else torch.matmul(input, weight.t()), lambda _, input, weight, bias: input.numel() > 10485760)
+
if version.parse(torch.__version__) < version.parse("1.13"):
# PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working
@@ -49,4 +54,6 @@ if has_mps:
CondFunc('torch.cumsum', cumsum_fix_func, None)
CondFunc('torch.Tensor.cumsum', cumsum_fix_func, None)
CondFunc('torch.narrow', lambda orig_func, *args, **kwargs: orig_func(*args, **kwargs).clone(), None)
-
+ if version.parse(torch.__version__) == version.parse("2.0"):
+ # MPS workaround for https://github.com/pytorch/pytorch/issues/96113
+ CondFunc('torch.nn.functional.layer_norm', lambda orig_func, x, normalized_shape, weight, bias, eps, **kwargs: orig_func(x.float(), normalized_shape, weight.float() if weight is not None else None, bias.float() if bias is not None else bias, eps).to(x.dtype), lambda *args, **kwargs: len(args) == 6)
diff --git a/modules/scripts.py b/modules/scripts.py
index 8de19884..8f55cf24 100644
--- a/modules/scripts.py
+++ b/modules/scripts.py
@@ -513,6 +513,18 @@ def reload_scripts():
scripts_postproc = scripts_postprocessing.ScriptPostprocessingRunner()
+def add_classes_to_gradio_component(comp):
+ """
+ this adds gradio-* to the component for css styling (ie gradio-button to gr.Button), as well as some others
+ """
+
+ comp.elem_classes = ["gradio-" + comp.get_block_name(), *(comp.elem_classes or [])]
+
+ if getattr(comp, 'multiselect', False):
+ comp.elem_classes.append('multiselect')
+
+
+
def IOComponent_init(self, *args, **kwargs):
if scripts_current is not None:
scripts_current.before_component(self, **kwargs)
@@ -521,6 +533,8 @@ def IOComponent_init(self, *args, **kwargs):
res = original_IOComponent_init(self, *args, **kwargs)
+ add_classes_to_gradio_component(self)
+
script_callbacks.after_component_callback(self, **kwargs)
if scripts_current is not None:
diff --git a/modules/scripts_postprocessing.py b/modules/scripts_postprocessing.py
index ce0ebb61..b11568c0 100644
--- a/modules/scripts_postprocessing.py
+++ b/modules/scripts_postprocessing.py
@@ -109,7 +109,7 @@ class ScriptPostprocessingRunner:
inputs = []
for script in self.scripts_in_preferred_order():
- with gr.Box() as group:
+ with gr.Row() as group:
self.create_script_ui(script, inputs)
script.group = group
diff --git a/modules/sd_hijack_optimizations.py b/modules/sd_hijack_optimizations.py
index 2e307b5d..372555ff 100644
--- a/modules/sd_hijack_optimizations.py
+++ b/modules/sd_hijack_optimizations.py
@@ -337,7 +337,7 @@ def xformers_attention_forward(self, x, context=None, mask=None):
dtype = q.dtype
if shared.opts.upcast_attn:
- q, k = q.float(), k.float()
+ q, k, v = q.float(), k.float(), v.float()
out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None, op=get_xformers_flash_attention_op(q, k, v))
@@ -372,7 +372,7 @@ def scaled_dot_product_attention_forward(self, x, context=None, mask=None):
dtype = q.dtype
if shared.opts.upcast_attn:
- q, k = q.float(), k.float()
+ q, k, v = q.float(), k.float(), v.float()
# the output of sdp = (batch, num_heads, seq_len, head_dim)
hidden_states = torch.nn.functional.scaled_dot_product_attention(
diff --git a/modules/sd_hijack_unet.py b/modules/sd_hijack_unet.py
index 843ab66c..15858263 100644
--- a/modules/sd_hijack_unet.py
+++ b/modules/sd_hijack_unet.py
@@ -67,7 +67,7 @@ def hijack_ddpm_edit():
unet_needs_upcast = lambda *args, **kwargs: devices.unet_needs_upcast
CondFunc('ldm.models.diffusion.ddpm.LatentDiffusion.apply_model', apply_model, unet_needs_upcast)
CondFunc('ldm.modules.diffusionmodules.openaimodel.timestep_embedding', lambda orig_func, timesteps, *args, **kwargs: orig_func(timesteps, *args, **kwargs).to(torch.float32 if timesteps.dtype == torch.int64 else devices.dtype_unet), unet_needs_upcast)
-if version.parse(torch.__version__) <= version.parse("1.13.1"):
+if version.parse(torch.__version__) <= version.parse("1.13.2") or torch.cuda.is_available():
CondFunc('ldm.modules.diffusionmodules.util.GroupNorm32.forward', lambda orig_func, self, *args, **kwargs: orig_func(self.float(), *args, **kwargs), unet_needs_upcast)
CondFunc('ldm.modules.attention.GEGLU.forward', lambda orig_func, self, x: orig_func(self.float(), x.float()).to(devices.dtype_unet), unet_needs_upcast)
CondFunc('open_clip.transformer.ResidualAttentionBlock.__init__', lambda orig_func, *args, **kwargs: kwargs.update({'act_layer': GELUHijack}) and False or orig_func(*args, **kwargs), lambda _, *args, **kwargs: kwargs.get('act_layer') is None or kwargs['act_layer'] == torch.nn.GELU)
diff --git a/modules/shared.py b/modules/shared.py
index f28a12cc..0b70d104 100644
--- a/modules/shared.py
+++ b/modules/shared.py
@@ -107,7 +107,8 @@ parser.add_argument("--cors-allow-origins-regex", type=str, help="Allowed CORS o
parser.add_argument("--tls-keyfile", type=str, help="Partially enables TLS, requires --tls-certfile to fully function", default=None)
parser.add_argument("--tls-certfile", type=str, help="Partially enables TLS, requires --tls-keyfile to fully function", default=None)
parser.add_argument("--server-name", type=str, help="Sets hostname of server", default=None)
-parser.add_argument("--gradio-queue", action='store_true', help="Uses gradio queue; experimental option; breaks restart UI button")
+parser.add_argument("--gradio-queue", action='store_true', help="does not do anything", default=True)
+parser.add_argument("--no-gradio-queue", action='store_true', help="Disables gradio queue; causes the webpage to use http requests instead of websockets; was the defaul in earlier versions")
parser.add_argument("--skip-version-check", action='store_true', help="Do not check versions of torch and xformers")
parser.add_argument("--no-hashing", action='store_true', help="disable sha256 hashing of checkpoints to help loading performance", default=False)
parser.add_argument("--no-download-sd-model", action='store_true', help="don't download SD1.5 model even if no model is found in --ckpt-dir", default=False)
diff --git a/modules/textual_inversion/textual_inversion.py b/modules/textual_inversion/textual_inversion.py
index c63c7d1d..d2e62e58 100644
--- a/modules/textual_inversion/textual_inversion.py
+++ b/modules/textual_inversion/textual_inversion.py
@@ -152,7 +152,11 @@ class EmbeddingDatabase:
name = data.get('name', name)
else:
data = extract_image_data_embed(embed_image)
- name = data.get('name', name)
+ if data:
+ name = data.get('name', name)
+ else:
+ # if data is None, means this is not an embeding, just a preview image
+ return
elif ext in ['.BIN', '.PT']:
data = torch.load(path, map_location="cpu")
elif ext in ['.SAFETENSORS']:
diff --git a/modules/ui.py b/modules/ui.py
index 7e603332..9b9bfa8b 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -20,7 +20,7 @@ from PIL import Image, PngImagePlugin
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
from modules import sd_hijack, sd_models, localization, script_callbacks, ui_extensions, deepbooru, sd_vae, extra_networks, postprocessing, ui_components, ui_common, ui_postprocessing
-from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML
+from modules.ui_components import FormRow, FormColumn, FormGroup, ToolButton, FormHTML
from modules.paths import script_path, data_path
from modules.shared import opts, cmd_opts, restricted_opts
@@ -89,7 +89,7 @@ paste_symbol = '\u2199\ufe0f' # ↙
refresh_symbol = '\U0001f504' # 🔄
save_style_symbol = '\U0001f4be' # 💾
apply_style_symbol = '\U0001f4cb' # 📋
-clear_prompt_symbol = '\U0001F5D1' # 🗑️
+clear_prompt_symbol = '\U0001f5d1\ufe0f' # 🗑️
extra_networks_symbol = '\U0001F3B4' # 🎴
switch_values_symbol = '\U000021C5' # ⇅
@@ -179,14 +179,13 @@ def interrogate_deepbooru(image):
def create_seed_inputs(target_interface):
- with FormRow(elem_id=target_interface + '_seed_row'):
+ with FormRow(elem_id=target_interface + '_seed_row', variant="compact"):
seed = (gr.Textbox if cmd_opts.use_textbox_seed else gr.Number)(label='Seed', value=-1, elem_id=target_interface + '_seed')
seed.style(container=False)
- random_seed = gr.Button(random_symbol, elem_id=target_interface + '_random_seed')
- reuse_seed = gr.Button(reuse_symbol, elem_id=target_interface + '_reuse_seed')
+ random_seed = ToolButton(random_symbol, elem_id=target_interface + '_random_seed')
+ reuse_seed = ToolButton(reuse_symbol, elem_id=target_interface + '_reuse_seed')
- with gr.Group(elem_id=target_interface + '_subseed_show_box'):
- seed_checkbox = gr.Checkbox(label='Extra', elem_id=target_interface + '_subseed_show', value=False)
+ seed_checkbox = gr.Checkbox(label='Extra', elem_id=target_interface + '_subseed_show', value=False)
# Components to show/hide based on the 'Extra' checkbox
seed_extras = []
@@ -195,8 +194,8 @@ def create_seed_inputs(target_interface):
seed_extras.append(seed_extra_row_1)
subseed = gr.Number(label='Variation seed', value=-1, elem_id=target_interface + '_subseed')
subseed.style(container=False)
- random_subseed = gr.Button(random_symbol, elem_id=target_interface + '_random_subseed')
- reuse_subseed = gr.Button(reuse_symbol, elem_id=target_interface + '_reuse_subseed')
+ random_subseed = ToolButton(random_symbol, elem_id=target_interface + '_random_subseed')
+ reuse_subseed = ToolButton(reuse_symbol, elem_id=target_interface + '_reuse_subseed')
subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=target_interface + '_subseed_strength')
with FormRow(visible=False) as seed_extra_row_2:
@@ -291,19 +290,19 @@ def create_toprow(is_img2img):
with gr.Row():
with gr.Column(scale=80):
with gr.Row():
- negative_prompt = gr.Textbox(label="Negative prompt", elem_id=f"{id_part}_neg_prompt", show_label=False, lines=2, placeholder="Negative prompt (press Ctrl+Enter or Alt+Enter to generate)")
+ negative_prompt = gr.Textbox(label="Negative prompt", elem_id=f"{id_part}_neg_prompt", show_label=False, lines=3, placeholder="Negative prompt (press Ctrl+Enter or Alt+Enter to generate)")
button_interrogate = None
button_deepbooru = None
if is_img2img:
- with gr.Column(scale=1, elem_id="interrogate_col"):
+ with gr.Column(scale=1, elem_classes="interrogate-col"):
button_interrogate = gr.Button('Interrogate\nCLIP', elem_id="interrogate")
button_deepbooru = gr.Button('Interrogate\nDeepBooru', elem_id="deepbooru")
with gr.Column(scale=1, elem_id=f"{id_part}_actions_column"):
- with gr.Row(elem_id=f"{id_part}_generate_box"):
- interrupt = gr.Button('Interrupt', elem_id=f"{id_part}_interrupt")
- skip = gr.Button('Skip', elem_id=f"{id_part}_skip")
+ 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')
skip.click(
@@ -325,9 +324,9 @@ def create_toprow(is_img2img):
prompt_style_apply = ToolButton(value=apply_style_symbol, elem_id=f"{id_part}_style_apply")
save_style = ToolButton(value=save_style_symbol, elem_id=f"{id_part}_style_create")
- token_counter = gr.HTML(value="<span></span>", elem_id=f"{id_part}_token_counter")
+ token_counter = gr.HTML(value="<span>0/75</span>", elem_id=f"{id_part}_token_counter", elem_classes=["token-counter"])
token_button = gr.Button(visible=False, elem_id=f"{id_part}_token_button")
- negative_token_counter = gr.HTML(value="<span></span>", elem_id=f"{id_part}_negative_token_counter")
+ negative_token_counter = gr.HTML(value="<span>0/75</span>", elem_id=f"{id_part}_negative_token_counter", elem_classes=["token-counter"])
negative_token_button = gr.Button(visible=False, elem_id=f"{id_part}_negative_token_button")
clear_prompt_button.click(
@@ -479,7 +478,9 @@ def create_ui():
width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="txt2img_width")
height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="txt2img_height")
- res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="txt2img_res_switch_btn")
+ with gr.Column(elem_id="txt2img_dimensions_row", scale=1, elem_classes="dimensions-tools"):
+ res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="txt2img_res_switch_btn")
+
if opts.dimensions_and_batch_together:
with gr.Column(elem_id="txt2img_column_batch"):
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="txt2img_batch_count")
@@ -492,7 +493,7 @@ def create_ui():
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('txt2img')
elif category == "checkboxes":
- with FormRow(elem_id="txt2img_checkboxes", variant="compact"):
+ with FormRow(elem_classes="checkboxes-row", variant="compact"):
restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="txt2img_restore_faces")
tiling = gr.Checkbox(label='Tiling', value=False, elem_id="txt2img_tiling")
enable_hr = gr.Checkbox(label='Hires. fix', value=False, elem_id="txt2img_enable_hr")
@@ -586,7 +587,7 @@ def create_ui():
txt2img_prompt.submit(**txt2img_args)
submit.click(**txt2img_args)
- res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height])
+ res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
txt_prompt_img.change(
fn=modules.images.image_data,
@@ -757,7 +758,9 @@ def create_ui():
width = gr.Slider(minimum=64, maximum=2048, step=8, label="Width", value=512, elem_id="img2img_width")
height = gr.Slider(minimum=64, maximum=2048, step=8, label="Height", value=512, elem_id="img2img_height")
- res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="img2img_res_switch_btn")
+ with gr.Column(elem_id="img2img_dimensions_row", scale=1, elem_classes="dimensions-tools"):
+ res_switch_btn = ToolButton(value=switch_values_symbol, elem_id="img2img_res_switch_btn")
+
if opts.dimensions_and_batch_together:
with gr.Column(elem_id="img2img_column_batch"):
batch_count = gr.Slider(minimum=1, step=1, label='Batch count', value=1, elem_id="img2img_batch_count")
@@ -774,7 +777,7 @@ def create_ui():
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w, seed_checkbox = create_seed_inputs('img2img')
elif category == "checkboxes":
- with FormRow(elem_id="img2img_checkboxes", variant="compact"):
+ with FormRow(elem_classes="checkboxes-row", variant="compact"):
restore_faces = gr.Checkbox(label='Restore faces', value=False, visible=len(shared.face_restorers) > 1, elem_id="img2img_restore_faces")
tiling = gr.Checkbox(label='Tiling', value=False, elem_id="img2img_tiling")
@@ -904,7 +907,7 @@ def create_ui():
img2img_prompt.submit(**img2img_args)
submit.click(**img2img_args)
- res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height])
+ res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
img2img_interrogate.click(
fn=lambda *args: process_interrogate(interrogate, *args),
@@ -1598,11 +1601,13 @@ def create_ui():
for i, k, item in quicksettings_list:
component = component_dict[k]
+ info = opts.data_labels[k]
component.change(
fn=lambda value, k=k: run_settings_single(value, key=k),
inputs=[component],
outputs=[component, text_settings],
+ show_progress=info.refresh is not None,
)
text_settings.change(
diff --git a/modules/ui_common.py b/modules/ui_common.py
index a12433d2..7b752b45 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -129,8 +129,8 @@ Requested path was: {f}
generation_info = None
with gr.Column():
- with gr.Row(elem_id=f"image_buttons_{tabname}"):
- open_folder_button = gr.Button(folder_symbol, elem_id="hidden_element" if shared.cmd_opts.hide_ui_dir_config else f'open_folder_{tabname}')
+ with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
+ open_folder_button = gr.Button(folder_symbol, visible=not shared.cmd_opts.hide_ui_dir_config)
if tabname != "extras":
save = gr.Button('Save', elem_id=f'save_{tabname}')
@@ -160,6 +160,7 @@ Requested path was: {f}
_js="function(x, y, z){ return [x, y, selected_gallery_index()] }",
inputs=[generation_info, html_info, html_info],
outputs=[html_info, html_info],
+ show_progress=False,
)
save.click(
diff --git a/modules/ui_components.py b/modules/ui_components.py
index 284ca0cf..2b1da2cb 100644
--- a/modules/ui_components.py
+++ b/modules/ui_components.py
@@ -1,55 +1,61 @@
import gradio as gr
-class ToolButton(gr.Button, gr.components.FormComponent):
- """Small button with single emoji as text, fits inside gradio forms"""
+class FormComponent:
+ def get_expected_parent(self):
+ return gr.components.Form
- def __init__(self, **kwargs):
- super().__init__(variant="tool", **kwargs)
- def get_block_name(self):
- return "button"
+gr.Dropdown.get_expected_parent = FormComponent.get_expected_parent
-class ToolButtonTop(gr.Button, gr.components.FormComponent):
- """Small button with single emoji as text, with extra margin at top, fits inside gradio forms"""
+class ToolButton(FormComponent, gr.Button):
+ """Small button with single emoji as text, fits inside gradio forms"""
- def __init__(self, **kwargs):
- super().__init__(variant="tool-top", **kwargs)
+ def __init__(self, *args, **kwargs):
+ classes = kwargs.pop("elem_classes", [])
+ super().__init__(*args, elem_classes=["tool", *classes], **kwargs)
def get_block_name(self):
return "button"
-class FormRow(gr.Row, gr.components.FormComponent):
+class FormRow(FormComponent, gr.Row):
"""Same as gr.Row but fits inside gradio forms"""
def get_block_name(self):
return "row"
-class FormGroup(gr.Group, gr.components.FormComponent):
+class FormColumn(FormComponent, gr.Column):
+ """Same as gr.Column but fits inside gradio forms"""
+
+ def get_block_name(self):
+ return "column"
+
+
+class FormGroup(FormComponent, gr.Group):
"""Same as gr.Row but fits inside gradio forms"""
def get_block_name(self):
return "group"
-class FormHTML(gr.HTML, gr.components.FormComponent):
+class FormHTML(FormComponent, gr.HTML):
"""Same as gr.HTML but fits inside gradio forms"""
def get_block_name(self):
return "html"
-class FormColorPicker(gr.ColorPicker, gr.components.FormComponent):
+class FormColorPicker(FormComponent, gr.ColorPicker):
"""Same as gr.ColorPicker but fits inside gradio forms"""
def get_block_name(self):
return "colorpicker"
-class DropdownMulti(gr.Dropdown):
+class DropdownMulti(FormComponent, gr.Dropdown):
"""Same as gr.Dropdown but always multiselect"""
def __init__(self, **kwargs):
super().__init__(multiselect=True, **kwargs)
diff --git a/modules/ui_extensions.py b/modules/ui_extensions.py
index df75a925..50173e68 100644
--- a/modules/ui_extensions.py
+++ b/modules/ui_extensions.py
@@ -244,7 +244,7 @@ def refresh_available_extensions_from_data(hide_tags, sort_column):
hidden += 1
continue
- install_code = f"""<input onclick="install_extension_from_index(this, '{html.escape(url)}')" type="button" value="{"Install" if not existing else "Installed"}" {"disabled=disabled" if existing else ""} class="gr-button gr-button-lg gr-button-secondary">"""
+ install_code = f"""<button onclick="install_extension_from_index(this, '{html.escape(url)}')" {"disabled=disabled" if existing else ""} class="lg secondary gradio-button custom-button">{"Install" if not existing else "Installed"}</button>"""
tags_text = ", ".join([f"<span class='extension-tag' title='{tags.get(x, '')}'>{x}</span>" for x in extension_tags])
diff --git a/modules/ui_extra_networks.py b/modules/ui_extra_networks.py
index cdfd6f2a..3cf8fcb6 100644
--- a/modules/ui_extra_networks.py
+++ b/modules/ui_extra_networks.py
@@ -22,21 +22,37 @@ def register_page(page):
allowed_dirs.update(set(sum([x.allowed_directories_for_previews() for x in extra_pages], [])))
-def add_pages_to_demo(app):
- def fetch_file(filename: str = ""):
- from starlette.responses import FileResponse
+def fetch_file(filename: str = ""):
+ from starlette.responses import FileResponse
+
+ if not any([Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs]):
+ raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.")
+
+ ext = os.path.splitext(filename)[1].lower()
+ if ext not in (".png", ".jpg", ".webp"):
+ raise ValueError(f"File cannot be fetched: {filename}. Only png and jpg and webp.")
+
+ # would profit from returning 304
+ return FileResponse(filename, headers={"Accept-Ranges": "bytes"})
+
+
+def get_metadata(page: str = "", item: str = ""):
+ from starlette.responses import JSONResponse
- if not any([Path(x).absolute() in Path(filename).absolute().parents for x in allowed_dirs]):
- raise ValueError(f"File cannot be fetched: {filename}. Must be in one of directories registered by extra pages.")
+ page = next(iter([x for x in extra_pages if x.name == page]), None)
+ if page is None:
+ return JSONResponse({})
- ext = os.path.splitext(filename)[1].lower()
- if ext not in (".png", ".jpg", ".webp"):
- raise ValueError(f"File cannot be fetched: {filename}. Only png and jpg and webp.")
+ metadata = page.metadata.get(item)
+ if metadata is None:
+ return JSONResponse({})
- # would profit from returning 304
- return FileResponse(filename, headers={"Accept-Ranges": "bytes"})
+ return JSONResponse({"metadata": metadata})
+
+def add_pages_to_demo(app):
app.add_api_route("/sd_extra_networks/thumb", fetch_file, methods=["GET"])
+ app.add_api_route("/sd_extra_networks/metadata", get_metadata, methods=["GET"])
class ExtraNetworksPage:
@@ -45,6 +61,7 @@ class ExtraNetworksPage:
self.name = title.lower()
self.card_page = shared.html("extra-networks-card.html")
self.allow_negative_prompt = False
+ self.metadata = {}
def refresh(self):
pass
@@ -66,6 +83,8 @@ class ExtraNetworksPage:
view = shared.opts.extra_networks_default_view
items_html = ''
+ self.metadata = {}
+
subdirs = {}
for parentdir in [os.path.abspath(x) for x in self.allowed_directories_for_previews()]:
for x in glob.glob(os.path.join(parentdir, '**/*'), recursive=True):
@@ -86,12 +105,16 @@ class ExtraNetworksPage:
subdirs = {"": 1, **subdirs}
subdirs_html = "".join([f"""
-<button class='gr-button gr-button-lg gr-button-secondary{" search-all" if subdir=="" else ""}' onclick='extraNetworksSearchButton("{tabname}_extra_tabs", event)'>
+<button class='lg secondary gradio-button custom-button{" search-all" if subdir=="" else ""}' onclick='extraNetworksSearchButton("{tabname}_extra_tabs", event)'>
{html.escape(subdir if subdir!="" else "all")}
</button>
""" for subdir in subdirs])
for item in self.list_items():
+ metadata = item.get("metadata")
+ if metadata:
+ self.metadata[item["name"]] = metadata
+
items_html += self.create_html_for_item(item, tabname)
if items_html == '':
@@ -127,8 +150,7 @@ class ExtraNetworksPage:
metadata_button = ""
metadata = item.get("metadata")
if metadata:
- metadata_onclick = '"' + html.escape(f"""extraNetworksShowMetadata({json.dumps(metadata)}); return false;""") + '"'
- metadata_button = f"<div class='metadata-button' title='Show metadata' onclick={metadata_onclick}></div>"
+ metadata_button = f"<div class='metadata-button' title='Show metadata' onclick='extraNetworksRequestMetadata({json.dumps(self.name)}, {json.dumps(item['name'])})'></div>"
args = {
"preview_html": "style='background-image: url(\"" + html.escape(preview) + "\")'" if preview else '',
@@ -215,6 +237,7 @@ def create_ui(container, button, tabname):
with gr.Tabs(elem_id=tabname+"_extra_tabs") as tabs:
for page in ui.stored_extra_pages:
with gr.Tab(page.title):
+
page_elem = gr.HTML(page.create_html(ui.tabname))
ui.pages.append(page_elem)
diff --git a/requirements.txt b/requirements.txt
index 6d53f089..3c40fd07 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,7 +4,7 @@ basicsr
fonts
font-roboto
gfpgan
-gradio==3.16.2
+gradio==3.23
invisible-watermark
numpy
omegaconf
diff --git a/requirements_versions.txt b/requirements_versions.txt
index 0031c616..77e3da4e 100644
--- a/requirements_versions.txt
+++ b/requirements_versions.txt
@@ -3,7 +3,7 @@ transformers==4.25.1
accelerate==0.12.0
basicsr==1.4.2
gfpgan==1.3.8
-gradio==3.16.2
+gradio==3.23
numpy==1.23.3
Pillow==9.4.0
realesrgan==0.3.0
diff --git a/script.js b/script.js
index 97e0bfcf..978b948f 100644
--- a/script.js
+++ b/script.js
@@ -1,7 +1,9 @@
function gradioApp() {
const elems = document.getElementsByTagName('gradio-app')
- const gradioShadowRoot = elems.length == 0 ? null : elems[0].shadowRoot
- return !!gradioShadowRoot ? gradioShadowRoot : document;
+ const elem = elems.length == 0 ? document : elems[0]
+
+ elem.getElementById = function(id){ return document.getElementById(id) }
+ return elem.shadowRoot ? elem.shadowRoot : elem
}
function get_uiCurrentTab() {
diff --git a/scripts/postprocessing_upscale.py b/scripts/postprocessing_upscale.py
index 8842bd91..11eab31a 100644
--- a/scripts/postprocessing_upscale.py
+++ b/scripts/postprocessing_upscale.py
@@ -17,22 +17,24 @@ class ScriptPostprocessingUpscale(scripts_postprocessing.ScriptPostprocessing):
def ui(self):
selected_tab = gr.State(value=0)
- with gr.Tabs(elem_id="extras_resize_mode"):
- with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by:
- upscaling_resize = gr.Slider(minimum=1.0, maximum=8.0, step=0.05, label="Resize", value=4, elem_id="extras_upscaling_resize")
-
- with gr.TabItem('Scale to', elem_id="extras_scale_to_tab") as tab_scale_to:
- with FormRow():
- upscaling_resize_w = gr.Number(label="Width", value=512, precision=0, elem_id="extras_upscaling_resize_w")
- upscaling_resize_h = gr.Number(label="Height", value=512, precision=0, elem_id="extras_upscaling_resize_h")
- upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
-
- with FormRow():
- extras_upscaler_1 = gr.Dropdown(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
-
- with FormRow():
- extras_upscaler_2 = gr.Dropdown(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
- extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility")
+ with gr.Column():
+ with FormRow():
+ with gr.Tabs(elem_id="extras_resize_mode"):
+ with gr.TabItem('Scale by', elem_id="extras_scale_by_tab") as tab_scale_by:
+ upscaling_resize = gr.Slider(minimum=1.0, maximum=8.0, step=0.05, label="Resize", value=4, elem_id="extras_upscaling_resize")
+
+ with gr.TabItem('Scale to', elem_id="extras_scale_to_tab") as tab_scale_to:
+ with FormRow():
+ upscaling_resize_w = gr.Number(label="Width", value=512, precision=0, elem_id="extras_upscaling_resize_w")
+ upscaling_resize_h = gr.Number(label="Height", value=512, precision=0, elem_id="extras_upscaling_resize_h")
+ upscaling_crop = gr.Checkbox(label='Crop to fit', value=True, elem_id="extras_upscaling_crop")
+
+ with FormRow():
+ extras_upscaler_1 = gr.Dropdown(label='Upscaler 1', elem_id="extras_upscaler_1", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
+
+ with FormRow():
+ extras_upscaler_2 = gr.Dropdown(label='Upscaler 2', elem_id="extras_upscaler_2", choices=[x.name for x in shared.sd_upscalers], value=shared.sd_upscalers[0].name)
+ extras_upscaler_2_visibility = gr.Slider(minimum=0.0, maximum=1.0, step=0.001, label="Upscaler 2 visibility", value=0.0, elem_id="extras_upscaler_2_visibility")
tab_scale_by.select(fn=lambda: 0, inputs=[], outputs=[selected_tab])
tab_scale_to.select(fn=lambda: 1, inputs=[], outputs=[selected_tab])
diff --git a/scripts/xyz_grid.py b/scripts/xyz_grid.py
index ce584981..3551aca0 100644
--- a/scripts/xyz_grid.py
+++ b/scripts/xyz_grid.py
@@ -247,7 +247,7 @@ def draw_xyz_grid(p, xs, ys, zs, x_labels, y_labels, z_labels, cell, draw_legend
state.job = f"{index(ix, iy, iz) + 1} out of {list_size}"
- processed: Processed = cell(x, y, z)
+ processed: Processed = cell(x, y, z, ix, iy, iz)
if processed_result is None:
# Use our first processed result object as a template container to hold our full results
@@ -558,8 +558,6 @@ class Script(scripts.Script):
print(f"X/Y/Z plot will create {len(xs) * len(ys) * len(zs) * image_cell_count} images on {len(zs)} {len(xs)}x{len(ys)} grid{plural_s}{cell_console_text}. (Total steps to process: {total_steps})")
shared.total_tqdm.updateTotal(total_steps)
- grid_infotext = [None]
-
state.xyz_plot_x = AxisInfo(x_opt, xs)
state.xyz_plot_y = AxisInfo(y_opt, ys)
state.xyz_plot_z = AxisInfo(z_opt, zs)
@@ -588,7 +586,9 @@ class Script(scripts.Script):
else:
second_axes_processed = 'y'
- def cell(x, y, z):
+ grid_infotext = [None] * (1 + len(zs))
+
+ def cell(x, y, z, ix, iy, iz):
if shared.state.interrupted:
return Processed(p, [], p.seed, "")
@@ -600,7 +600,9 @@ class Script(scripts.Script):
res = process_images(pc)
- if grid_infotext[0] is None:
+ # Sets subgrid infotexts
+ subgrid_index = 1 + iz
+ if grid_infotext[subgrid_index] is None and ix == 0 and iy == 0:
pc.extra_generation_params = copy(pc.extra_generation_params)
pc.extra_generation_params['Script'] = self.title()
@@ -616,6 +618,12 @@ class Script(scripts.Script):
if y_opt.label in ["Seed", "Var. seed"] and not no_fixed_seeds:
pc.extra_generation_params["Fixed Y Values"] = ", ".join([str(y) for y in ys])
+ grid_infotext[subgrid_index] = processing.create_infotext(pc, pc.all_prompts, pc.all_seeds, pc.all_subseeds)
+
+ # Sets main grid infotext
+ if grid_infotext[0] is None and ix == 0 and iy == 0 and iz == 0:
+ pc.extra_generation_params = copy(pc.extra_generation_params)
+
if z_opt.label != 'Nothing':
pc.extra_generation_params["Z Type"] = z_opt.label
pc.extra_generation_params["Z Values"] = z_values
@@ -650,6 +658,9 @@ class Script(scripts.Script):
z_count = len(zs)
+ # Set the grid infotexts to the real ones with extra_generation_params (1 main grid + z_count sub-grids)
+ processed.infotexts[:1+z_count] = grid_infotext[:1+z_count]
+
if not include_lone_images:
# Don't need sub-images anymore, drop from list:
processed.images = processed.images[:z_count+1]
diff --git a/style.css b/style.css
index 3eac2b17..41d2859c 100644
--- a/style.css
+++ b/style.css
@@ -1,270 +1,313 @@
-.container {
- max-width: 100%;
-}
-.token-counter{
- position: absolute;
- display: inline-block;
- right: 2em;
- min-width: 0 !important;
- width: auto;
- z-index: 100;
-}
+/* general gradio fixes */
-.token-counter.error span{
- box-shadow: 0 0 0.0 0.3em rgba(255,0,0,0.15), inset 0 0 0.6em rgba(255,0,0,0.075);
- border: 2px solid rgba(255,0,0,0.4) !important;
+:root, .dark{
+ --checkbox-label-gap: 0.25em 0.1em;
+ --section-header-text-size: 12pt;
+ --block-background-fill: transparent;
}
-.token-counter div{
- display: inline;
+.block.padded{
+ padding: 0 !important;
}
-.token-counter span{
- padding: 0.1em 0.75em;
+div.gradio-container{
+ max-width: unset !important;
}
-#sh{
- min-width: 2em;
- min-height: 2em;
- max-width: 2em;
- max-height: 2em;
- flex-grow: 0;
- padding-left: 0.25em;
- padding-right: 0.25em;
- margin: 0.1em 0;
- opacity: 0%;
- cursor: default;
+.hidden{
+ display: none;
}
-.output-html p {margin: 0 0.5em;}
-
-.row > *,
-.row > .gr-form > * {
- min-width: min(120px, 100%);
- flex: 1 1 0%;
+.compact{
+ background: transparent !important;
+ padding: 0 !important;
}
-.performance {
- font-size: 0.85em;
- color: #444;
+div.form{
+ border-width: 0;
+ box-shadow: none;
+ background: transparent;
+ overflow: visible;
+ gap: 0.5em;
}
-.performance p{
- display: inline-block;
+.block.gradio-dropdown,
+.block.gradio-slider,
+.block.gradio-checkbox,
+.block.gradio-textbox,
+.block.gradio-radio,
+.block.gradio-checkboxgroup,
+.block.gradio-number,
+.block.gradio-colorpicker
+{
+ border-width: 0 !important;
+ box-shadow: none !important;
}
-.performance .time {
- margin-right: 0;
+.gap.compact{
+ padding: 0;
+ gap: 0.2em 0;
}
-.performance .vram {
+div.compact{
+ gap: 1em;
}
-#txt2img_generate, #img2img_generate {
- min-height: 4.5em;
+.gradio-dropdown ul.options{
+ z-index: 3000;
}
-@media screen and (min-width: 2500px) {
- #txt2img_gallery, #img2img_gallery {
- min-height: 768px;
- }
+.gradio-dropdown label span:not(.has-info),
+.gradio-textbox label span:not(.has-info),
+.gradio-number label span:not(.has-info)
+{
+ margin-bottom: 0;
}
-#txt2img_gallery img, #img2img_gallery img{
- object-fit: scale-down;
+.gradio-dropdown div.wrap.wrap.wrap.wrap{
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}
-#txt2img_actions_column, #img2img_actions_column {
- margin: 0.35rem 0.75rem 0.35rem 0;
+
+.gradio-dropdown .wrap-inner.wrap-inner.wrap-inner{
+ flex-wrap: unset;
}
-#script_list {
- padding: .625rem .75rem 0 .625rem;
+
+.gradio-dropdown .single-select{
+ white-space: nowrap;
+ overflow: hidden;
}
-.justify-center.overflow-x-scroll {
- justify-content: left;
+
+.gradio-dropdown .token-remove.remove-all.remove-all{
+ display: none;
}
-.justify-center.overflow-x-scroll button:first-of-type {
- margin-left: auto;
+.gradio-dropdown.multiselect .token-remove.remove-all.remove-all{
+ display: flex;
}
-.justify-center.overflow-x-scroll button:last-of-type {
- margin-right: auto;
+.gradio-slider input[type="number"]{
+ width: 6em;
}
-[id$=_random_seed], [id$=_random_subseed], [id$=_reuse_seed], [id$=_reuse_subseed], #open_folder{
- min-width: 2.3em;
- height: 2.5em;
- flex-grow: 0;
- padding-left: 0.25em;
- padding-right: 0.25em;
+.block.gradio-checkbox {
+ margin: 0.75em 1.5em 0 0;
}
-#hidden_element{
- display: none;
+.gradio-html div.wrap{
+ height: 100%;
+}
+div.gradio-html.min{
+ min-height: 0;
}
-[id$=_seed_row], [id$=_subseed_row]{
- gap: 0.5rem;
- padding: 0.6em;
+.block.gradio-gallery{
+ background: var(--input-background-fill);
}
-[id$=_subseed_show_box]{
- min-width: auto;
- flex-grow: 0;
+.gradio-container .prose a, .gradio-container .prose a:visited{
+ color: unset;
+ text-decoration: none;
}
-[id$=_subseed_show_box] > div{
- border: 0;
- height: 100%;
+
+
+/* general styled components */
+
+.gradio-button.tool{
+ max-width: 2.2em;
+ min-width: 2.2em !important;
+ height: 2.4em;
+ align-self: end;
+ line-height: 1em;
+ border-radius: 0.5em;
}
-[id$=_subseed_show]{
+.checkboxes-row{
+ margin-bottom: 0.5em;
+ margin-left: 0em;
+}
+.checkboxes-row > div{
+ flex: 0;
+ white-space: nowrap;
min-width: auto;
- flex-grow: 0;
- padding: 0;
}
-[id$=_subseed_show] label{
- height: 100%;
+button.custom-button{
+ border-radius: var(--button-large-radius);
+ padding: var(--button-large-padding);
+ font-weight: var(--button-large-text-weight);
+ border: var(--button-border-width) solid var(--button-secondary-border-color);
+ background: var(--button-secondary-background-fill);
+ color: var(--button-secondary-text-color);
+ font-size: var(--button-large-text-size);
+ display: inline-flex;
+ justify-content: center;
+ align-items: center;
+ transition: var(--button-transition);
+ box-shadow: var(--button-shadow);
+ text-align: center;
}
-#txt2img_actions_column, #img2img_actions_column{
- gap: 0;
- margin-right: .75rem;
-}
-#txt2img_tools, #img2img_tools{
- gap: 0.4em;
-}
+/* txt2img/img2img specific */
-#interrogate_col{
+.block.token-counter{
+ position: absolute;
+ display: inline-block;
+ right: 1em;
min-width: 0 !important;
- max-width: 8em !important;
- margin-right: 1em;
- gap: 0;
+ width: auto;
+ z-index: 100;
+ top: -0.75em;
}
-#interrogate, #deepbooru{
- margin: 0em 0.25em 0.5em 0.25em;
- min-width: 8em;
- max-width: 8em;
+
+.block.token-counter span{
+ background: var(--input-background-fill) !important;
+ box-shadow: 0 0 0.0 0.3em rgba(192,192,192,0.15), inset 0 0 0.6em rgba(192,192,192,0.075);
+ border: 2px solid rgba(192,192,192,0.4) !important;
+ border-radius: 0.4em;
}
-#style_pos_col, #style_neg_col{
- min-width: 8em !important;
+.block.token-counter.error span{
+ box-shadow: 0 0 0.0 0.3em rgba(255,0,0,0.15), inset 0 0 0.6em rgba(255,0,0,0.075);
+ border: 2px solid rgba(255,0,0,0.4) !important;
}
-#txt2img_styles_row, #img2img_styles_row{
- gap: 0.25em;
- margin-top: 0.3em;
+.block.token-counter div{
+ display: inline;
}
-#txt2img_styles_row > button, #img2img_styles_row > button{
- margin: 0;
+.block.token-counter span{
+ padding: 0.1em 0.75em;
}
-#txt2img_styles, #img2img_styles{
- padding: 0;
+[id$=_subseed_show]{
+ min-width: auto !important;
+ flex-grow: 0 !important;
+ display: flex;
}
-#txt2img_styles > label > div, #img2img_styles > label > div{
- min-height: 3.2em;
+[id$=_subseed_show] label{
+ margin-bottom: 0.5em;
+ align-self: end;
}
-ul.list-none{
- max-height: 35em;
- z-index: 2000;
+.performance {
+ font-size: 0.85em;
+ color: #444;
}
-.gr-form{
- background: transparent;
+.performance p{
+ display: inline-block;
}
-.my-4{
- margin-top: 0;
- margin-bottom: 0;
+.performance .time {
+ margin-right: 0;
}
-#resize_mode{
- flex: 1.5;
+.performance .vram {
}
-button{
- align-self: stretch !important;
+#txt2img_generate, #img2img_generate {
+ min-height: 4.5em;
}
-.overflow-hidden, .gr-panel{
- overflow: visible !important;
+@media screen and (min-width: 2500px) {
+ #txt2img_gallery, #img2img_gallery {
+ min-height: 768px;
+ }
}
-#x_type, #y_type{
- max-width: 10em;
+#txt2img_gallery img, #img2img_gallery img{
+ object-fit: scale-down;
+}
+#txt2img_actions_column, #img2img_actions_column {
+ gap: 0.5em;
+}
+#txt2img_tools, #img2img_tools{
+ gap: 0.4em;
}
-#txt2img_preview, #img2img_preview, #ti_preview{
+.interrogate-col{
+ min-width: 0 !important;
+ max-width: fit-content;
+ gap: 0.5em;
+}
+.interrogate-col > button{
+ flex: 1;
+}
+
+.generate-box{
+ position: relative;
+}
+.gradio-button.generate-box-skip, .gradio-button.generate-box-interrupt{
position: absolute;
- width: 320px;
+ width: 50%;
+ height: 100%;
+ display: none;
+ background: #b4c0cc;
+}
+.gradio-button.generate-box-skip:hover, .gradio-button.generate-box-interrupt:hover{
+ background: #c2cfdb;
+}
+.gradio-button.generate-box-interrupt{
left: 0;
+ border-radius: 0.5rem 0 0 0.5rem;
+}
+.gradio-button.generate-box-skip{
right: 0;
- margin-left: auto;
- margin-right: auto;
- margin-top: 34px;
- z-index: 100;
- border: none;
- border-top-left-radius: 0;
- border-top-right-radius: 0;
+ border-radius: 0 0.5rem 0.5rem 0;
}
-@media screen and (min-width: 768px) {
- #txt2img_preview, #img2img_preview, #ti_preview {
- position: absolute;
- }
+#txtimg_hr_finalres{
+ min-height: 0 !important;
+ padding: .625rem .75rem;
+ margin-left: -0.75em
}
-@media screen and (max-width: 767px) {
- #txt2img_preview, #img2img_preview, #ti_preview {
- position: relative;
- }
+#txtimg_hr_finalres .resolution{
+ font-weight: bold;
}
-#txt2img_preview div.left-0.top-0, #img2img_preview div.left-0.top-0, #ti_preview div.left-0.top-0{
- display: none;
+.inactive{
+ opacity: 0.5;
}
-fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block span{
- position: absolute;
- top: -0.7em;
- line-height: 1.2em;
- padding: 0;
- margin: 0 0.5em;
-
- background-color: white;
- box-shadow: 6px 0 6px 0px white, -6px 0 6px 0px white;
+[id$=_column_batch]{
+ min-width: min(13.5em, 100%) !important;
+}
- z-index: 300;
+div.dimensions-tools{
+ min-width: 0 !important;
+ max-width: fit-content;
+ flex-direction: row;
+ align-content: center;
}
-.dark fieldset span.text-gray-500, .dark .gr-block.gr-box span.text-gray-500, .dark label.block span{
- background-color: rgb(31, 41, 55);
- box-shadow: none;
- border: 1px solid rgba(128, 128, 128, 0.1);
- border-radius: 6px;
- padding: 0.1em 0.5em;
+#mode_img2img .gradio-image > div.fixed-height, #mode_img2img .gradio-image > div.fixed-height img{
+ height: 480px !important;
+ max-height: 480px !important;
+ min-height: 480px !important;
}
-#txt2img_column_batch, #img2img_column_batch{
- min-width: min(13.5em, 100%) !important;
+.image-buttons button{
+ min-width: auto;
}
-#settings fieldset span.text-gray-500, #settings .gr-block.gr-box span.text-gray-500, #settings label.block span{
- position: relative;
- border: none;
- margin-right: 8em;
+
+/* settings */
+#quicksettings {
+ width: fit-content;
}
-#settings .gr-panel div.flex-col div.justify-between div{
- position: relative;
- z-index: 200;
+#quicksettings > div, #quicksettings > fieldset{
+ max-width: 24em;
+ min-width: 24em;
+ padding: 0;
+ border: none;
+ box-shadow: none;
+ background: none;
}
#settings{
@@ -276,17 +319,18 @@ fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block s
margin-left: 10em;
}
-#settings > div.flex-wrap{
+#settings > div.tab-nav{
float: left;
display: block;
margin-left: 0;
width: 10em;
}
-#settings > div.flex-wrap button{
+#settings > div.tab-nav button{
display: block;
border: none;
text-align: left;
+ white-space: initial;
}
#settings_result{
@@ -294,29 +338,8 @@ fieldset span.text-gray-500, .gr-block.gr-box span.text-gray-500, label.block s
margin: 0 1.2em;
}
-input[type="range"]{
- margin: 0.5em 0 -0.3em 0;
-}
-
-#mask_bug_info {
- text-align: center;
- display: block;
- margin-top: -0.75em;
- margin-bottom: -0.75em;
-}
-
-#txt2img_negative_prompt, #img2img_negative_prompt{
-}
-
-/* gradio 3.8 adds opacity to progressbar which makes it blink; disable it here */
-.transition.opacity-20 {
- opacity: 1 !important;
-}
-
-/* more gradio's garbage cleanup */
-.min-h-\[4rem\] { min-height: unset !important; }
-.min-h-\[6rem\] { min-height: unset !important; }
+/* live preview */
.progressDiv{
position: relative;
height: 20px;
@@ -362,6 +385,8 @@ input[type="range"]{
height: 100%;
}
+/* fullscreen popup (ie in Lora's (i) button) */
+
.popup-metadata{
color: black;
background: white;
@@ -402,87 +427,54 @@ input[type="range"]{
padding: 2em;
}
+/* fullpage image viewer */
+
#lightboxModal{
- display: none;
- position: fixed;
- z-index: 1001;
- padding-top: 100px;
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- overflow: auto;
- background-color: rgba(20, 20, 20, 0.95);
- user-select: none;
- -webkit-user-select: none;
+ display: none;
+ position: fixed;
+ z-index: 1001;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+ background-color: rgba(20, 20, 20, 0.95);
+ user-select: none;
+ -webkit-user-select: none;
+ flex-direction: column;
}
.modalControls {
- display: grid;
- grid-template-columns: 32px 32px 32px 1fr 32px;
- grid-template-areas: "zoom tile save space close";
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- padding: 16px;
- gap: 16px;
+ display: flex;
+ gap: 1em;
+ padding: 1em;
background-color: rgba(0,0,0,0.2);
}
-
.modalClose {
- grid-area: close;
-}
-
-.modalZoom {
- grid-area: zoom;
-}
-
-.modalSave {
- grid-area: save;
-}
-
-.modalTileImage {
- grid-area: tile;
-}
-
-.modalClose,
-.modalZoom,
-.modalTileImage {
- color: white;
- font-size: 35px;
- font-weight: bold;
- cursor: pointer;
+ margin-left: auto;
}
-
-.modalSave {
+.modalControls span{
color: white;
- font-size: 28px;
- margin-top: 8px;
+ font-size: 35px;
font-weight: bold;
cursor: pointer;
+ width: 1em;
}
-.modalClose:hover,
-.modalClose:focus,
-.modalSave:hover,
-.modalSave:focus,
-.modalZoom:hover,
-.modalZoom:focus {
- color: #999;
- text-decoration: none;
- cursor: pointer;
+.modalControls span:hover, .modalControls span:focus{
+ color: #999;
+ text-decoration: none;
}
-#modalImage {
+#lightboxModal > img {
display: block;
margin: auto;
width: auto;
}
-.modalImageFullscreen {
+#lightboxModal > img.modalImageFullscreen{
object-fit: contain;
- height: 90%;
+ height: 100%;
}
.modalPrev,
@@ -512,45 +504,7 @@ input[type="range"]{
background-color: rgba(0, 0, 0, 0.8);
}
-#imageARPreview{
- position:absolute;
- top:0px;
- left:0px;
- border:2px solid red;
- background:rgba(255, 0, 0, 0.3);
- z-index: 900;
- pointer-events:none;
- display:none
-}
-
-#txt2img_generate_box, #img2img_generate_box{
- position: relative;
-}
-
-#txt2img_interrupt, #img2img_interrupt, #txt2img_skip, #img2img_skip{
- position: absolute;
- width: 50%;
- height: 100%;
- background: #b4c0cc;
- display: none;
-}
-
-#txt2img_interrupt, #img2img_interrupt{
- left: 0;
- border-radius: 0.5rem 0 0 0.5rem;
-}
-#txt2img_skip, #img2img_skip{
- right: 0;
- border-radius: 0 0.5rem 0.5rem 0;
-}
-
-.red {
- color: red;
-}
-
-.gallery-item {
- --tw-bg-opacity: 0 !important;
-}
+/* context menu (ie for the generate button) */
#context-menu{
z-index:9999;
@@ -579,61 +533,8 @@ input[type="range"]{
background: #a55000;
}
-#quicksettings {
- width: fit-content;
-}
-#quicksettings > div, #quicksettings > fieldset{
- max-width: 24em;
- min-width: 24em;
- padding: 0;
- border: none;
- box-shadow: none;
- background: none;
- margin-right: 10px;
-}
-
-#quicksettings > div > div > div > label > span {
- position: relative;
- margin-right: 9em;
- margin-bottom: -1em;
-}
-
-canvas[key="mask"] {
- z-index: 12 !important;
- filter: invert();
- mix-blend-mode: multiply;
- pointer-events: none;
-}
-
-
-/* gradio 3.4.1 stuff for editable scrollbar values */
-.gr-box > div > div > input.gr-text-input{
- position: absolute;
- right: 0.5em;
- top: -0.6em;
- z-index: 400;
- width: 6em;
-}
-#quicksettings .gr-box > div > div > input.gr-text-input {
- top: -1.12em;
-}
-
-.row.gr-compact{
- overflow: visible;
-}
-
-#img2img_image, #img2img_image > .h-60, #img2img_image > .h-60 > div, #img2img_image > .h-60 > div > img,
-#img2img_sketch, #img2img_sketch > .h-60, #img2img_sketch > .h-60 > div, #img2img_sketch > .h-60 > div > img,
-#img2maskimg, #img2maskimg > .h-60, #img2maskimg > .h-60 > div, #img2maskimg > .h-60 > div > img,
-#inpaint_sketch, #inpaint_sketch > .h-60, #inpaint_sketch > .h-60 > div, #inpaint_sketch > .h-60 > div > img
-{
- height: 480px !important;
- max-height: 480px !important;
- min-height: 480px !important;
-}
-
-/* Extensions */
+/* extensions */
#tab_extensions table{
border-collapse: collapse;
@@ -646,6 +547,7 @@ canvas[key="mask"] {
#tab_extensions table input[type="checkbox"]{
margin-right: 0.5em;
+ appearance: checkbox;
}
#tab_extensions button{
@@ -670,74 +572,7 @@ canvas[key="mask"] {
font-size: 90%;
}
-#image_buttons_txt2img button, #image_buttons_img2img button, #image_buttons_extras button{
- min-width: auto;
- padding-left: 0.5em;
- padding-right: 0.5em;
-}
-
-.gr-form{
- background-color: white;
-}
-
-.dark .gr-form{
- background-color: rgb(31 41 55 / var(--tw-bg-opacity));
-}
-
-.gr-button-tool, .gr-button-tool-top{
- max-width: 2.5em;
- min-width: 2.5em !important;
- height: 2.4em;
-}
-
-.gr-button-tool{
- margin: 0.6em 0em 0.55em 0;
-}
-
-.gr-button-tool-top, #settings .gr-button-tool{
- margin: 1.6em 0.7em 0.55em 0;
-}
-
-
-#modelmerger_results_container{
- margin-top: 1em;
- overflow: visible;
-}
-
-#modelmerger_models{
- gap: 0;
-}
-
-
-#quicksettings .gr-button-tool{
- margin: 0;
- border-color: unset;
- background-color: unset;
-}
-
-#modelmerger_interp_description>p {
- margin: 0!important;
- text-align: center;
-}
-#modelmerger_interp_description {
- margin: 0.35rem 0.75rem 1.23rem;
-}
-#img2img_settings > div.gr-form, #txt2img_settings > div.gr-form {
- padding-top: 0.9em;
- padding-bottom: 0.9em;
-}
-#txt2img_settings {
- padding-top: 1.16em;
- padding-bottom: 0.9em;
-}
-#img2img_settings {
- padding-bottom: 0.9em;
-}
-
-#img2img_settings div.gr-form .gr-form, #txt2img_settings div.gr-form .gr-form, #train_tabs div.gr-form .gr-form{
- border: none;
- padding-bottom: 0.5em;
-}
+/* replace original footer with ours */
footer {
display: none !important;
@@ -756,90 +591,7 @@ footer {
opacity: 0.85;
}
-#txtimg_hr_finalres{
- min-height: 0 !important;
- padding: .625rem .75rem;
- margin-left: -0.75em
-
-}
-
-#txtimg_hr_finalres .resolution{
- font-weight: bold;
-}
-
-#txt2img_checkboxes, #img2img_checkboxes{
- margin-bottom: 0.5em;
- margin-left: 0em;
-}
-#txt2img_checkboxes > div, #img2img_checkboxes > div{
- flex: 0;
- white-space: nowrap;
- min-width: auto;
-}
-
-#img2img_copy_to_img2img, #img2img_copy_to_sketch, #img2img_copy_to_inpaint, #img2img_copy_to_inpaint_sketch{
- margin-left: 0em;
-}
-
-#axis_options {
- margin-left: 0em;
-}
-
-.inactive{
- opacity: 0.5;
-}
-
-[id*='_prompt_container']{
- gap: 0;
-}
-
-[id*='_prompt_container'] > div{
- margin: -0.4em 0 0 0;
-}
-
-.gr-compact {
- border: none;
-}
-
-.dark .gr-compact{
- background-color: rgb(31 41 55 / var(--tw-bg-opacity));
- margin-left: 0;
-}
-
-.gr-compact{
- overflow: visible;
-}
-
-.gr-compact > *{
-}
-
-.gr-compact .gr-block, .gr-compact .gr-form{
- border: none;
- box-shadow: none;
-}
-
-.gr-compact .gr-box{
- border-radius: .5rem !important;
- border-width: 1px !important;
-}
-
-#mode_img2img > div > div{
- gap: 0 !important;
-}
-
-[id*='img2img_copy_to_'] {
- border: none;
-}
-
-[id*='img2img_copy_to_'] > button {
-}
-
-[id*='img2img_label_copy_to_'] {
- font-size: 1.0em;
- font-weight: bold;
- text-align: center;
- line-height: 2.4em;
-}
+/* extra networks UI */
.extra-networks > div > [id *= '_extra_']{
margin: 0.3em;
@@ -852,12 +604,12 @@ footer {
.extra-network-subdirs button{
margin: 0 0.15em;
}
-
-#txt2img_extra_networks .search, #img2img_extra_networks .search{
+.extra-networks .tab-nav .search{
display: inline-block;
max-width: 16em;
margin: 0.3em;
align-self: center;
+ width: 16em;
}
#txt2img_extra_view, #img2img_extra_view {
@@ -889,6 +641,7 @@ footer {
text-shadow: 2px 2px 3px black;
padding: 0.25em;
font-size: 22pt;
+ width: 1.5em;
}
.extra-network-cards .card:hover .metadata-button, .extra-network-thumbs .card:hover .metadata-button{
display: inline-block;
@@ -982,12 +735,15 @@ footer {
left: 0;
right: 0;
padding: 0.5em;
- color: white;
background: rgba(0,0,0,0.5);
box-shadow: 0 0 0.25em 0.25em rgba(0,0,0,0.5);
text-shadow: 0 0 0.2em black;
}
+.extra-network-cards .card .actions *{
+ color: white;
+}
+
.extra-network-cards .card .actions:hover{
box-shadow: 0 0 0.75em 0.75em rgba(0,0,0,0.5) !important;
}
@@ -1025,7 +781,3 @@ footer {
.extra-network-cards .card ul a:hover{
color: red;
}
-
-[id*='_prompt_container'] > div {
- margin: 0!important;
-}
diff --git a/webui.py b/webui.py
index aaec79fd..ca725b7d 100644
--- a/webui.py
+++ b/webui.py
@@ -240,7 +240,7 @@ def webui():
shared.demo = modules.ui.create_ui()
startup_timer.record("create ui")
- if cmd_opts.gradio_queue:
+ if not cmd_opts.no_gradio_queue:
shared.demo.queue(64)
gradio_auth_creds = []