diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0fd5bd560..d624a94a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
# Change Log for SD.Next
-## Update for 2023-12-14
+## Update for 2023-12-16
*Note*: based on `diffusers==0.25.0.dev0`
@@ -57,7 +57,8 @@
- **Other**
- **Inpaint** add option `apply_overlay` to control if inpaint result should be applied as overlay or as-is
can remove artifacts and hard edges of inpaint area but also remove some details from original
- - **chaiNNer** fix NaN issues due to autocast
+ - **chaiNNer** fix `NaN` issues due to autocast
+ - **Upscale** increase limit from 4x to 8x given the quality of some upscalers
- **Extra Networks** fix sort
- disable google fonts check on server startup
- fix torchvision/basicsr compatibility
diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet
index a13bd2feb..102449bf1 160000
--- a/extensions-builtin/sd-webui-controlnet
+++ b/extensions-builtin/sd-webui-controlnet
@@ -1 +1 @@
-Subproject commit a13bd2febe4fae1184b548504957d19a65425a89
+Subproject commit 102449bf16974baf9fff9a2ecec528755e1ba5e2
diff --git a/javascript/control.js b/javascript/control.js
index 4d3afcc9e..090afb11a 100644
--- a/javascript/control.js
+++ b/javascript/control.js
@@ -1,7 +1,16 @@
-const getControlActiveTab = (...args) => {
- const selectedTab = gradioApp().querySelector('#control-tabs > .tab-nav > .selected');
- let activeTab = '';
- if (selectedTab) activeTab = selectedTab.innerText.toLowerCase();
- args.shift();
- return [activeTab, ...args];
-};
+function setupControlUI() {
+ const tabs = ['input', 'output', 'preview'];
+ for (const tab of tabs) {
+ const btn = gradioApp().getElementById(`control-${tab}-button`);
+ btn.style.cursor = 'pointer';
+ btn.onclick = () => {
+ const t = gradioApp().getElementById(`control-tab-${tab}`);
+ t.style.display = t.style.display === 'none' ? 'block' : 'none';
+ const c = gradioApp().getElementById(`control-${tab}-column`);
+ c.style.flexGrow = c.style.flexGrow === '0' ? '9' : '0';
+ };
+ }
+ log('initControlUI');
+}
+
+onUiLoaded(setupControlUI);
diff --git a/javascript/progressBar.js b/javascript/progressBar.js
index 0133d3c1f..85c339f26 100644
--- a/javascript/progressBar.js
+++ b/javascript/progressBar.js
@@ -40,7 +40,7 @@ function checkPaused(state) {
}
function setProgress(res) {
- const elements = ['txt2img_generate', 'img2img_generate', 'extras_generate'];
+ const elements = ['txt2img_generate', 'img2img_generate', 'extras_generate', 'control_generate'];
const progress = (res?.progress || 0);
const job = res?.job || '';
const perc = res && (progress > 0) ? `${Math.round(100.0 * progress)}%` : '';
@@ -57,10 +57,12 @@ function setProgress(res) {
document.title = `SD.Next ${perc}`;
for (const elId of elements) {
const el = document.getElementById(elId);
- el.innerText = (res ? `${job} ${perc} ${eta}` : 'Generate');
- el.style.background = res && (progress > 0)
- ? `linear-gradient(to right, var(--primary-500) 0%, var(--primary-800) ${perc}, var(--neutral-700) ${perc})`
- : 'var(--button-primary-background-fill)';
+ if (el) {
+ el.innerText = (res ? `${job} ${perc} ${eta}` : 'Generate');
+ el.style.background = res && (progress > 0)
+ ? `linear-gradient(to right, var(--primary-500) 0%, var(--primary-800) ${perc}, var(--neutral-700) ${perc})`
+ : 'var(--button-primary-background-fill)';
+ }
}
}
diff --git a/javascript/sdnext.css b/javascript/sdnext.css
index afc3f9095..2b3954bc3 100644
--- a/javascript/sdnext.css
+++ b/javascript/sdnext.css
@@ -70,9 +70,10 @@ button.custom-button{ border-radius: var(--button-large-radius); padding: var(--
.performance { font-size: 0.85em; color: #444; }
.performance p { display: inline-block; color: var(--body-text-color-subdued) !important }
.performance .time { margin-right: 0; }
+#control_gallery { height: 564px; }
+#control-inputs { margin-top: 1em; }
#txt2img_prompt_container, #img2img_prompt_container, #control_prompt_container { margin-right: var(--layout-gap) }
-#txt2img_footer, #img2img_footer, #extras_footer { height: fit-content; }
-#txt2img_footer, #img2img_footer { height: fit-content; display: none; }
+#txt2img_footer, #img2img_footer, #extras_footer, #control_footer { height: fit-content; display: none; }
#txt2img_generate_box, #img2img_generate_box, #control_general_box { gap: 0.5em; flex-wrap: wrap-reverse; height: fit-content; }
#txt2img_actions_column, #img2img_actions_column, #control_actions_column { gap: 0.3em; height: fit-content; }
#txt2img_generate_box>button, #img2img_generate_box>button, #control_generate_box>button, #txt2img_enqueue, #img2img_enqueue { min-height: 42px; max-height: 42px; line-height: 1em; }
@@ -92,7 +93,6 @@ button.custom-button{ border-radius: var(--button-large-radius); padding: var(--
div#extras_scale_to_tab div.form{ flex-direction: row; }
#img2img_unused_scale_by_slider { visibility: hidden; width: 0.5em; max-width: 0.5em; min-width: 0.5em; }
.inactive{ opacity: 0.5; }
-div.dimensions-tools { min-width: 0 !important; max-width: fit-content; flex-direction: row; align-content: center; }
div#extras_scale_to_tab div.form{ flex-direction: row; }
#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; }
#img2img_sketch, #img2maskimg, #inpaint_sketch { overflow: overlay !important; resize: auto; background: var(--panel-background-fill); z-index: 5; }
@@ -307,7 +307,7 @@ table.settings-value-table td { padding: 0.4em; border: 1px solid #ccc; max-widt
#img2img_actions_column {display: flex; min-width: fit-content !important; flex-direction: row;justify-content: space-evenly; align-items: center;}
#txt2img_generate_box, #img2img_generate_box, #txt2img_enqueue_wrapper,#img2img_enqueue_wrapper {display: flex;flex-direction: column;height: 4em !important;align-items: stretch;justify-content: space-evenly;}
#img2img_interface, #img2img_results, #img2img_footer p {text-wrap: wrap; min-width: 100% !important; max-width: 100% !important;} /* maintain single column for from image operations on larger mobile devices */
- #img2img_sketch, #img2maskimg, #inpaint_sketch {display: flex; alignment-baseline:after-edge !important; overflow: auto !important; resize: none !important; } /* fix inpaint image display being too large for mobile displays */
+ #img2img_sketch, #img2maskimg, #inpaint_sketch {display: flex; overflow: auto !important; resize: none !important; } /* fix inpaint image display being too large for mobile displays */
#img2maskimg canvas { width: auto !important; max-height: 100% !important; height: auto !important; }
#txt2img_sampler, #txt2img_batch, #txt2img_seed_group, #txt2img_advanced, #txt2img_second_pass, #img2img_sampling_group, #img2img_resize_group, #img2img_batch_group, #img2img_seed_group, #img2img_denoise_group, #img2img_advanced_group { width: 100% !important; } /* fix from text/image UI elements to prevent them from moving around within the UI */
#img2img_resize_group .gradio-radio>div { display: flex; flex-direction: column; width: unset !important; }
diff --git a/javascript/ui.js b/javascript/ui.js
index e192c5935..845402f99 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -101,6 +101,13 @@ function switch_to_extras(...args) {
return Array.from(arguments);
}
+function switch_to_control(...args) {
+ const tabs = Array.from(gradioApp().querySelector('#tabs').querySelectorAll('button'));
+ const btn = tabs.find((el) => el.innerText.toLowerCase() === 'control');
+ btn.click();
+ return Array.from(arguments);
+}
+
function get_tab_index(tabId) {
let res = 0;
gradioApp().getElementById(tabId).querySelector('div').querySelectorAll('button')
@@ -164,6 +171,17 @@ function submit_img2img(...args) {
return res;
}
+function submit_control(...args) {
+ log('submitControl');
+ clearGallery('control');
+ const id = randomId();
+ requestProgress(id, null, gradioApp().getElementById('control_gallery'));
+ const res = create_submit_args(args);
+ res[0] = id;
+ res[1] = gradioApp().querySelector('#control-tabs > .tab-nav > .selected')?.innerText.toLowerCase() || ''; // selected tab name
+ return res;
+}
+
function submit_postprocessing(...args) {
log('SubmitExtras');
clearGallery('extras');
@@ -211,6 +229,12 @@ function recalculate_prompts_inpaint(...args) {
return Array.from(arguments);
}
+function recalculate_prompts_control(...args) {
+ recalculatePromptTokens('control_prompt');
+ recalculatePromptTokens('control_neg_prompt');
+ return Array.from(arguments);
+}
+
function registerDragDrop() {
const qs = gradioApp().getElementById('quicksettings');
if (!qs) return;
diff --git a/modules/call_queue.py b/modules/call_queue.py
index 21f94352d..7da6dddc8 100644
--- a/modules/call_queue.py
+++ b/modules/call_queue.py
@@ -77,6 +77,7 @@ def wrap_gradio_call(func, extra_outputs=None, add_stats=False, name=None):
vram = {k: -(v//-(1024*1024)) for k, v in shared.mem_mon.read().items()}
if vram.get('active_peak', 0) > 0:
vram_html = f" |
GPU active {max(vram['active_peak'], vram['reserved_peak'])} MB reserved {vram['reserved']} | used {vram['used']} MB free {vram['free']} MB total {vram['total']} MB | retries {vram['retries']} oom {vram['oom']}
"
- res[-1] += f""
+ if isinstance(res, list):
+ res[-1] += f""
return tuple(res)
return f
diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py
index 8dd589772..d26317fc9 100644
--- a/modules/generation_parameters_copypaste.py
+++ b/modules/generation_parameters_copypaste.py
@@ -28,6 +28,7 @@ class ParamBinding:
self.source_tabname = source_tabname
self.override_settings_component = override_settings_component
self.paste_field_names = paste_field_names or []
+ debug(f'ParamBinding: {vars(self)}')
def reset():
@@ -112,6 +113,8 @@ def create_buttons(tabs_list):
name = 'Inpaint'
elif name == 'extras':
name = 'Process'
+ elif name == 'control':
+ name = 'Control'
buttons[tab] = gr.Button(f"➠ {name}", elem_id=f"{tab}_tab")
return buttons
@@ -131,6 +134,9 @@ def register_paste_params_button(binding: ParamBinding):
def connect_paste_params_buttons():
binding: ParamBinding
for binding in registered_param_bindings:
+ if binding.tabname not in paste_fields:
+ debug(f"Not not registered: tab={binding.tabname}")
+ continue
destination_image_component = paste_fields[binding.tabname]["init_img"]
fields = paste_fields[binding.tabname]["fields"]
override_settings_component = binding.override_settings_component or paste_fields[binding.tabname]["override_settings_component"]
diff --git a/modules/processing.py b/modules/processing.py
index bb9753e72..3ae023fbe 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -1200,7 +1200,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
- def __init__(self, init_images: list = None, resize_mode: int = 0, resize_name: str = 'None', denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs):
+ def __init__(self, init_images: list = None, resize_mode: int = 0, resize_name: str = 'None', denoising_strength: float = 0.3, image_cfg_scale: float = None, mask: Any = None, mask_blur: int = 4, inpainting_fill: int = 0, inpaint_full_res: bool = True, inpaint_full_res_padding: int = 0, inpainting_mask_invert: int = 0, initial_noise_multiplier: float = None, scale_by: float = 1, refiner_steps: int = 5, refiner_start: float = 0, refiner_prompt: str = '', refiner_negative: str = '', **kwargs):
super().__init__(**kwargs)
self.init_images = init_images
self.resize_mode: int = resize_mode
@@ -1226,7 +1226,7 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
self.refiner_negative = refiner_negative
self.enable_hr = None
self.is_batch = False
- self.scale_by = 1.0
+ self.scale_by = scale_by
self.sampler = None
self.scripts = None
self.script_args = []
diff --git a/modules/ui.py b/modules/ui.py
index 4100e290b..217e284ec 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -166,16 +166,16 @@ def create_batch_inputs(tab):
return batch_count, batch_size
-def create_seed_inputs(tab):
+def create_seed_inputs(tab, reuse_visible=True):
with gr.Accordion(open=False, label="Seed", elem_id=f"{tab}_seed_group", elem_classes=["small-accordion"]):
with FormRow(elem_id=f"{tab}_seed_row", variant="compact"):
seed = gr.Number(label='Initial seed', value=-1, elem_id=f"{tab}_seed", container=True)
random_seed = ToolButton(symbols.random, elem_id=f"{tab}_random_seed", label='Random seed')
- reuse_seed = ToolButton(symbols.reuse, elem_id=f"{tab}_reuse_seed", label='Reuse seed')
+ reuse_seed = ToolButton(symbols.reuse, elem_id=f"{tab}_reuse_seed", label='Reuse seed', visible=reuse_visible)
with FormRow(visible=True, elem_id=f"{tab}_subseed_row", variant="compact"):
subseed = gr.Number(label='Variation', value=-1, elem_id=f"{tab}_subseed", container=True)
random_subseed = ToolButton(symbols.random, elem_id=f"{tab}_random_subseed")
- reuse_subseed = ToolButton(symbols.reuse, elem_id=f"{tab}_reuse_subseed")
+ reuse_subseed = ToolButton(symbols.reuse, elem_id=f"{tab}_reuse_subseed", visible=reuse_visible)
subseed_strength = gr.Slider(label='Variation strength', value=0.0, minimum=0, maximum=1, step=0.01, elem_id=f"{tab}_subseed_strength")
with FormRow(visible=False):
seed_resize_from_w = gr.Slider(minimum=0, maximum=4096, step=8, label="Resize seed from width", value=0, elem_id=f"{tab}_seed_resize_from_w")
@@ -215,41 +215,41 @@ def create_advanced_inputs(tab):
return cfg_scale, clip_skip, image_cfg_scale, diffusers_guidance_rescale, full_quality, restore_faces, tiling, hdr_clamp, hdr_boundary, hdr_threshold, hdr_center, hdr_channel_shift, hdr_full_shift, hdr_maximize, hdr_max_center, hdr_max_boundry
-def create_resize_inputs(tab, images):
+def create_resize_inputs(tab, images, time_selector=False, scale_visible=True):
dummy_component = gr.Number(visible=False, value=0)
with gr.Accordion(open=False, label="Resize", elem_classes=["small-accordion"], elem_id=f"{tab}_resize_group"):
with gr.Row():
resize_mode = gr.Radio(label="Resize mode", elem_id=f"{tab}_resize_mode", choices=modules.shared.resize_modes, type="index", value="None")
+ resize_time = gr.Radio(label="Resize order", elem_id=f"{tab}_resize_order", choices=['Before', 'After'], value="Before", visible=time_selector)
with gr.Row():
resize_name = gr.Dropdown(label="Resize method", elem_id=f"{tab}_resize_name", choices=[x.name for x in modules.shared.sd_upscalers], value=opts.upscaler_for_img2img)
with FormRow(visible=True) as _resize_group:
- with gr.Column(elem_id=f"{tab}_column_size", scale=4):
+ with gr.Column(elem_id=f"{tab}_column_size"):
selected_scale_tab = gr.State(value=0) # pylint: disable=abstract-class-instantiated
with gr.Tabs():
with gr.Tab(label="Resize to") as tab_scale_to:
with FormRow():
- with gr.Column(elem_id=f"{tab}_column_size", scale=4):
- with FormRow():
- width = gr.Slider(minimum=64, maximum=4096, step=8, label="Width", value=512, elem_id=f"{tab}_width")
- height = gr.Slider(minimum=64, maximum=4096, step=8, label="Height", value=512, elem_id=f"{tab}_height")
- with gr.Column(elem_id=f"{tab}_column_dim", scale=1, elem_classes="dimensions-tools"):
+ with gr.Column(elem_id=f"{tab}_column_size"):
with FormRow():
+ width = gr.Slider(minimum=64, maximum=8192, step=8, label="Width", value=512, elem_id=f"{tab}_width")
+ height = gr.Slider(minimum=64, maximum=8192, step=8, label="Height", value=512, elem_id=f"{tab}_height")
res_switch_btn = ToolButton(value=symbols.switch, elem_id=f"{tab}_res_switch_btn")
res_switch_btn.click(lambda w, h: (h, w), inputs=[width, height], outputs=[width, height], show_progress=False)
detect_image_size_btn = ToolButton(value=symbols.detect, elem_id=f"{tab}_detect_image_size_btn")
detect_image_size_btn.click(fn=lambda w, h, _: (w or gr.update(), h or gr.update()), _js="currentImg2imgSourceResolution", inputs=[dummy_component, dummy_component, dummy_component], outputs=[width, height], show_progress=False)
with gr.Tab(label="Resize by") as tab_scale_by:
- scale_by = gr.Slider(minimum=0.05, maximum=4.0, step=0.05, label="Scale", value=1.0, elem_id=f"{tab}_scale")
- with FormRow():
- scale_by_html = FormHTML(resize_from_to_html(0, 0, 0.0), elem_id=f"{tab}_scale_resolution_preview")
- gr.Slider(label="Unused", elem_id=f"{tab}_unused_scale_by_slider")
- button_update_resize_to = gr.Button(visible=False, elem_id=f"{tab}_update_resize_to")
+ scale_by = gr.Slider(minimum=0.05, maximum=8.0, step=0.05, label="Scale", value=1.0, elem_id=f"{tab}_scale")
+ if scale_visible:
+ with FormRow():
+ scale_by_html = FormHTML(resize_from_to_html(0, 0, 0.0), elem_id=f"{tab}_scale_resolution_preview")
+ gr.Slider(label="Unused", elem_id=f"{tab}_unused_scale_by_slider")
+ button_update_resize_to = gr.Button(visible=False, elem_id=f"{tab}_update_resize_to")
- on_change_args = dict(fn=resize_from_to_html, _js="currentImg2imgSourceResolution", inputs=[dummy_component, dummy_component, scale_by], outputs=scale_by_html, show_progress=False)
- scale_by.release(**on_change_args)
- button_update_resize_to.click(**on_change_args)
+ on_change_args = dict(fn=resize_from_to_html, _js="currentImg2imgSourceResolution", inputs=[dummy_component, dummy_component, scale_by], outputs=scale_by_html, show_progress=False)
+ scale_by.release(**on_change_args)
+ button_update_resize_to.click(**on_change_args)
for component in images:
component.change(fn=lambda: None, _js="updateImg2imgResizeToTextAfterChangingImage", inputs=[], outputs=[], show_progress=False)
@@ -257,7 +257,7 @@ def create_resize_inputs(tab, images):
tab_scale_to.select(fn=lambda: 0, inputs=[], outputs=[selected_scale_tab])
tab_scale_by.select(fn=lambda: 1, inputs=[], outputs=[selected_scale_tab])
# resize_mode.change(fn=lambda x: gr.update(visible=x != 0), inputs=[resize_mode], outputs=[_resize_group])
- return resize_mode, resize_name, width, height, scale_by, selected_scale_tab
+ return resize_mode, resize_name, width, height, scale_by, selected_scale_tab, resize_time
def connect_clear_prompt(button): # pylint: disable=unused-argument
@@ -637,7 +637,8 @@ def create_ui(startup_timer = None):
*modules.scripts.scripts_txt2img.infotext_fields
]
parameters_copypaste.add_paste_fields("txt2img", None, txt2img_paste_fields, override_settings)
- parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=txt2img_paste, tabname="txt2img", source_text_component=txt2img_prompt, source_image_component=None))
+ txt2img_bindings = parameters_copypaste.ParamBinding(paste_button=txt2img_paste, tabname="txt2img", source_text_component=txt2img_prompt, source_image_component=None)
+ parameters_copypaste.register_paste_params_button(txt2img_bindings)
txt2img_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_prompt, steps], outputs=[txt2img_token_counter])
txt2img_negative_token_button.click(fn=wrap_queued_call(update_token_counter), inputs=[txt2img_negative_prompt, steps], outputs=[txt2img_negative_token_counter])
@@ -731,7 +732,7 @@ def create_ui(startup_timer = None):
with FormGroup(elem_classes="settings-accordion"):
steps, sampler_index = create_sampler_inputs('img2img')
- resize_mode, resize_name, width, height, scale_by, selected_scale_tab = create_resize_inputs('img2img', [init_img, sketch])
+ resize_mode, resize_name, width, height, scale_by, selected_scale_tab, _resize_time = create_resize_inputs('img2img', [init_img, sketch])
batch_count, batch_size = create_batch_inputs('img2img')
seed, reuse_seed, subseed, reuse_subseed, subseed_strength, seed_resize_from_h, seed_resize_from_w = create_seed_inputs('img2img')
@@ -892,9 +893,8 @@ def create_ui(startup_timer = None):
]
parameters_copypaste.add_paste_fields("img2img", init_img, img2img_paste_fields, override_settings)
parameters_copypaste.add_paste_fields("inpaint", init_img_with_mask, img2img_paste_fields, override_settings)
- parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(
- paste_button=img2img_paste, tabname="img2img", source_text_component=img2img_prompt, source_image_component=None,
- ))
+ img2img_bindings = parameters_copypaste.ParamBinding(paste_button=img2img_paste, tabname="img2img", source_text_component=img2img_prompt, source_image_component=None)
+ parameters_copypaste.register_paste_params_button(img2img_bindings)
timer.startup.record("ui-img2img")
diff --git a/modules/ui_common.py b/modules/ui_common.py
index bd34e475e..368f61730 100644
--- a/modules/ui_common.py
+++ b/modules/ui_common.py
@@ -195,13 +195,13 @@ def open_folder(result_gallery, gallery_index = 0):
subprocess.Popen(["xdg-open", path]) # pylint: disable=consider-using-with
-def create_output_panel(tabname):
+def create_output_panel(tabname, preview=True):
import modules.generation_parameters_copypaste as parameters_copypaste
with gr.Column(variant='panel', elem_id=f"{tabname}_results"):
with gr.Group(elem_id=f"{tabname}_gallery_container"):
# columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px
- result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=True, columns=5, object_fit='scale-down', height=shared.opts.gallery_height or None)
+ result_gallery = gr.Gallery(value=[], label='Output', show_label=False, show_download_button=True, allow_preview=True, elem_id=f"{tabname}_gallery", container=False, preview=preview, columns=5, object_fit='scale-down', height=shared.opts.gallery_height or None)
with gr.Column(elem_id=f"{tabname}_footer", elem_classes="gallery_footer"):
dummy_component = gr.Label(visible=False)
@@ -214,7 +214,7 @@ def create_output_panel(tabname):
clip_files.click(fn=None, _js='clip_gallery_urls', inputs=[result_gallery], outputs=[])
save = gr.Button('Save', elem_id=f'save_{tabname}')
delete = gr.Button('Delete', elem_id=f'delete_{tabname}')
- buttons = parameters_copypaste.create_buttons(["img2img", "inpaint", "extras"])
+ buttons = parameters_copypaste.create_buttons(["img2img", "inpaint", "extras", "control"])
download_files = gr.File(None, file_count="multiple", interactive=False, show_label=False, visible=False, elem_id=f'download_files_{tabname}')
with gr.Group():
diff --git a/modules/ui_postprocessing.py b/modules/ui_postprocessing.py
index de0b71d3f..0fb103859 100644
--- a/modules/ui_postprocessing.py
+++ b/modules/ui_postprocessing.py
@@ -31,7 +31,7 @@ def create_ui():
extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.", elem_id="extras_batch_output_dir")
show_extras_results = gr.Checkbox(label='Show result images', value=True, elem_id="extras_show_extras_results")
with gr.Row():
- buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint"])
+ buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint", "control"])
with gr.Row():
save_output = gr.Checkbox(label='Save output', value=True, elem_id="extras_save_output")
script_inputs = scripts.scripts_postproc.setup_ui()
diff --git a/wiki b/wiki
index 240a7339c..faa2defd1 160000
--- a/wiki
+++ b/wiki
@@ -1 +1 @@
-Subproject commit 240a7339ca1199c7735e279e7ea4cdbac0163ec6
+Subproject commit faa2defd19badfef74a1e4f54b695a68c7651224