diff --git a/CHANGELOG.md b/CHANGELOG.md
index ce7e8aa5a..56461699b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,17 @@
# Change Log for SD.Next
+### TODO
+
+- *Separate init image* currently not functional
+
## Update for 2026-04-29
+- **UI**
+ - all ui panels can be minimized/maximized by clicking on their header
+ state is preserved across sessions and can be used to hide rarely used panels and declutter the workspace
- **Control**
- - remove buttons: input/control/process
+ - remove buttons: *input/control/process*
+ - move params *control input type* to control menu section
- remove "processed preview" from ui
preprocessor output can still be generated by clicking preview button in in control unit and it will render into normal output area
diff --git a/extensions-builtin/sdnext-kanvas b/extensions-builtin/sdnext-kanvas
index dbea4ea19..ae5dc5ee3 160000
--- a/extensions-builtin/sdnext-kanvas
+++ b/extensions-builtin/sdnext-kanvas
@@ -1 +1 @@
-Subproject commit dbea4ea19e0605e2158bef607dc423f12261f0a8
+Subproject commit ae5dc5ee374189b1d2ca1038e93da164b11f8223
diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui
index 4d92bce7e..146bd3643 160000
--- a/extensions-builtin/sdnext-modernui
+++ b/extensions-builtin/sdnext-modernui
@@ -1 +1 @@
-Subproject commit 4d92bce7e47276f85651478cb9619b5e6dd77d8b
+Subproject commit 146bd36431d3c38e3938054366934be91cce0ba6
diff --git a/modules/lora/lora_extract.py b/modules/lora/lora_extract.py
index e1536198a..19a55d209 100644
--- a/modules/lora/lora_extract.py
+++ b/modules/lora/lora_extract.py
@@ -238,7 +238,7 @@ def create_ui():
with gr.Tab(label="Extract LoRA"):
with gr.Row():
- gr.HTML('
 Extract currently loaded LoRA(s)
')
+ gr.HTML(' Extract currently loaded LoRA(s)
')
with gr.Row():
loaded = gr.Textbox(placeholder="Press refresh to query loaded LoRA", label="Loaded LoRA", interactive=False)
create_refresh_button(loaded, lambda: None, lambda: {'value': loaded_lora_str()}, "lora_extract_refresh")
diff --git a/modules/onnx_impl/pipelines/onnx_stable_diffusion_img2img_pipeline.py b/modules/onnx_impl/pipelines/onnx_stable_diffusion_img2img_pipeline.py
index 82c9740a8..87d6a746a 100644
--- a/modules/onnx_impl/pipelines/onnx_stable_diffusion_img2img_pipeline.py
+++ b/modules/onnx_impl/pipelines/onnx_stable_diffusion_img2img_pipeline.py
@@ -29,7 +29,7 @@ class OnnxStableDiffusionImg2ImgPipeline(diffusers.OnnxStableDiffusionImg2ImgPip
feature_extractor: Any,
requires_safety_checker: bool = True
):
- super().__init__(vae_encoder, vae_decoder, text_encoder, tokenizer, unet, scheduler, safety_checker, feature_extractor, requires_safety_checker)
+ super().__init__(vae_encoder, vae_decoder, text_encoder, tokenizer, unet, scheduler, safety_checker, feature_extractor, requires_safety_checker) # pylint: disable=too-many-function-args
self.image_processor = VaeImageProcessor(vae_scale_factor=64)
def __call__(
@@ -72,7 +72,7 @@ class OnnxStableDiffusionImg2ImgPipeline(diffusers.OnnxStableDiffusionImg2ImgPip
image = self.image_processor.preprocess(image).cpu().numpy()
- # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
+ # `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
# of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
# corresponds to doing no classifier free guidance.
do_classifier_free_guidance = guidance_scale > 1.0
diff --git a/modules/ui_control.py b/modules/ui_control.py
index 3ba7f08bb..e34f3bf07 100644
--- a/modules/ui_control.py
+++ b/modules/ui_control.py
@@ -167,7 +167,7 @@ def create_ui(_blocks: gr.Blocks=None):
with gr.Accordion(open=False, label="Input", elem_id="control_input", elem_classes=["small-accordion"]):
with gr.Row():
- input_type = gr.Radio(label="Control input type", choices=['Control only', 'Init image same as control', 'Separate init image'], value='Control only', type='index', elem_id='control_input_type')
+ input_type = gr.Radio(label="Use init image", choices=['No: Control only', '1st: Same as control', '2nd: Separate image'], value='No: Control only', type='index', elem_id='control_input_type')
with gr.Row():
denoising_strength = gr.Slider(minimum=0.00, maximum=0.99, step=0.01, label='Denoising strength', value=0.30, elem_id="control_input_denoising_strength")
@@ -238,9 +238,7 @@ def create_ui(_blocks: gr.Blocks=None):
input_folder = gr.File(label="Input", show_label=False, file_count='directory', file_types=['image'], interactive=True, height=gr_height)
with gr.Column(scale=9, elem_id='control-init-column', visible=False) as column_init:
gr.HTML('Init input')
- with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-init'):
- with gr.Tab('Image', id='init-image') as tab_image_init:
- init_image = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="editor", height=gr_height, elem_classes=['control-image'])
+ init_image = gr.Image(label="Input", show_label=False, type="pil", interactive=True, tool="editor", height=gr_height, elem_classes=['control-image'])
with gr.Column(scale=9, elem_id='control-output-column', visible=True) as _column_output:
gr.HTML('Output')
with gr.Tabs(elem_classes=['control-tabs'], elem_id='control-tab-output') as output_tabs:
@@ -298,7 +296,7 @@ def create_ui(_blocks: gr.Blocks=None):
prompt.submit(**select_dict)
negative.submit(**select_dict)
btn_generate.click(**select_dict)
- for ctrl in [input_image, input_video, input_batch, input_folder, init_image, tab_image, tab_video, tab_batch, tab_folder, tab_image_init]:
+ for ctrl in [input_image, input_video, input_batch, input_folder, init_image, tab_image, tab_video, tab_batch, tab_folder]:
if hasattr(ctrl, 'change'):
ctrl.change(**select_dict)
if hasattr(ctrl, 'clear'):
diff --git a/modules/ui_models.py b/modules/ui_models.py
index c8a981261..f02bfb9b3 100644
--- a/modules/ui_models.py
+++ b/modules/ui_models.py
@@ -181,7 +181,7 @@ def create_ui():
return ['None'] + sd_models.checkpoint_titles()
with gr.Row():
- gr.HTML(' Merge multiple models
')
+ gr.HTML(' Merge multiple models
')
with gr.Row(equal_height=False):
with gr.Column(variant='compact'):
with gr.Row():
@@ -422,7 +422,7 @@ def create_ui():
with gr.Tab(label="Replace", elem_id="models_replace_tab"):
with gr.Row():
- gr.HTML(' Replace model components
')
+ gr.HTML(' Replace model components
')
with gr.Row():
with gr.Column(scale=3):
model_type = gr.Dropdown(label="Base model type", choices=['sd15', 'sdxl', 'sd21', 'sd35', 'flux.1'], value='sdxl', interactive=False)
@@ -628,7 +628,7 @@ def create_ui():
from modules.models_hf import hf_search, hf_select, hf_download_model, hf_update_token
with gr.Column(scale=6):
with gr.Row():
- gr.HTML(' Download model from huggingface
')
+ gr.HTML(' Download model from huggingface
')
with gr.Row():
hf_search_text = gr.Textbox('', label='Search models', placeholder='search huggingface models')
hf_search_btn = ToolButton(value=ui_symbols.search, interactive=True, elem_id="hf_text_search")
diff --git a/modules/ui_models_load.py b/modules/ui_models_load.py
index 9e6ca45cf..9246a10d6 100644
--- a/modules/ui_models_load.py
+++ b/modules/ui_models_load.py
@@ -276,7 +276,7 @@ def create_ui(gr_status, gr_file):
return 'Save receipe not implemented yet'
with gr.Row():
- gr.HTML('')
+ gr.HTML(' Custom model loader
')
with gr.Row():
choices = list(shared_items.pipelines)
choices = ['Current' if x.startswith('Custom') else x for x in choices]