aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAUTOMATIC1111 <16777216c@gmail.com>2023-08-10 11:20:46 +0300
committerAUTOMATIC1111 <16777216c@gmail.com>2023-08-10 11:20:46 +0300
commit9199b6b7ebe96cdf09571ba874a103e8ed8c90ef (patch)
tree7616311d79e848b63864475d80dcae2b5ce6dabe
parent2c5106ed06044ba4b67b1c856756e33a1ca5eeea (diff)
add a custom UI element that combines accordion and checkbox
rework hires fix UI to use accordion prevent bogus progress output in console when calculating hires fix dimensions
-rw-r--r--javascript/inputAccordion.js37
-rw-r--r--modules/processing.py77
-rw-r--r--modules/ui.py23
-rw-r--r--modules/ui_components.py31
-rw-r--r--style.css15
5 files changed, 124 insertions, 59 deletions
diff --git a/javascript/inputAccordion.js b/javascript/inputAccordion.js
new file mode 100644
index 00000000..a5eef229
--- /dev/null
+++ b/javascript/inputAccordion.js
@@ -0,0 +1,37 @@
+var observerAccordionOpen = new MutationObserver(function(mutations) {
+ mutations.forEach(function(mutationRecord) {
+ var elem = mutationRecord.target;
+ var open = elem.classList.contains('open');
+
+ var accordion = elem.parentNode;
+ accordion.classList.toggle('input-accordion-open', open);
+
+ var checkbox = gradioApp().querySelector('#' + accordion.id + "-checkbox input");
+ checkbox.checked = open;
+ updateInput(checkbox);
+
+ extra = gradioApp().querySelector('#' + accordion.id + "-extra");
+ if(extra){
+ extra.style.display = open ? "" : "none";
+ }
+ });
+});
+
+function inputAccordionChecked(id, checked){
+ var label = gradioApp().querySelector('#' + id + " .label-wrap");
+ if(label.classList.contains('open') != checked){
+ label.click();
+ }
+}
+
+onUiLoaded(function() {
+ for (var accordion of gradioApp().querySelectorAll('.input-accordion')) {
+ var labelWrap = accordion.querySelector('.label-wrap');
+ observerAccordionOpen.observe(labelWrap, {attributes: true, attributeFilter: ['class']});
+
+ var extra = gradioApp().querySelector('#' + accordion.id + "-extra");
+ if(extra){
+ labelWrap.insertBefore(extra, labelWrap.lastElementChild)
+ }
+ }
+});
diff --git a/modules/processing.py b/modules/processing.py
index 6961b7b1..7819644c 100644
--- a/modules/processing.py
+++ b/modules/processing.py
@@ -924,6 +924,45 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
self.hr_c = None
self.hr_uc = None
+ def calculate_target_resolution(self):
+ if opts.use_old_hires_fix_width_height and self.applied_old_hires_behavior_to != (self.width, self.height):
+ self.hr_resize_x = self.width
+ self.hr_resize_y = self.height
+ self.hr_upscale_to_x = self.width
+ self.hr_upscale_to_y = self.height
+
+ self.width, self.height = old_hires_fix_first_pass_dimensions(self.width, self.height)
+ self.applied_old_hires_behavior_to = (self.width, self.height)
+
+ if self.hr_resize_x == 0 and self.hr_resize_y == 0:
+ self.extra_generation_params["Hires upscale"] = self.hr_scale
+ self.hr_upscale_to_x = int(self.width * self.hr_scale)
+ self.hr_upscale_to_y = int(self.height * self.hr_scale)
+ else:
+ self.extra_generation_params["Hires resize"] = f"{self.hr_resize_x}x{self.hr_resize_y}"
+
+ if self.hr_resize_y == 0:
+ self.hr_upscale_to_x = self.hr_resize_x
+ self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
+ elif self.hr_resize_x == 0:
+ self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
+ self.hr_upscale_to_y = self.hr_resize_y
+ else:
+ target_w = self.hr_resize_x
+ target_h = self.hr_resize_y
+ src_ratio = self.width / self.height
+ dst_ratio = self.hr_resize_x / self.hr_resize_y
+
+ if src_ratio < dst_ratio:
+ self.hr_upscale_to_x = self.hr_resize_x
+ self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
+ else:
+ self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
+ self.hr_upscale_to_y = self.hr_resize_y
+
+ self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
+ self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f
+
def init(self, all_prompts, all_seeds, all_subseeds):
if self.enable_hr:
if self.hr_checkpoint_name:
@@ -948,43 +987,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
if not any(x.name == self.hr_upscaler for x in shared.sd_upscalers):
raise Exception(f"could not find upscaler named {self.hr_upscaler}")
- if opts.use_old_hires_fix_width_height and self.applied_old_hires_behavior_to != (self.width, self.height):
- self.hr_resize_x = self.width
- self.hr_resize_y = self.height
- self.hr_upscale_to_x = self.width
- self.hr_upscale_to_y = self.height
-
- self.width, self.height = old_hires_fix_first_pass_dimensions(self.width, self.height)
- self.applied_old_hires_behavior_to = (self.width, self.height)
-
- if self.hr_resize_x == 0 and self.hr_resize_y == 0:
- self.extra_generation_params["Hires upscale"] = self.hr_scale
- self.hr_upscale_to_x = int(self.width * self.hr_scale)
- self.hr_upscale_to_y = int(self.height * self.hr_scale)
- else:
- self.extra_generation_params["Hires resize"] = f"{self.hr_resize_x}x{self.hr_resize_y}"
-
- if self.hr_resize_y == 0:
- self.hr_upscale_to_x = self.hr_resize_x
- self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
- elif self.hr_resize_x == 0:
- self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
- self.hr_upscale_to_y = self.hr_resize_y
- else:
- target_w = self.hr_resize_x
- target_h = self.hr_resize_y
- src_ratio = self.width / self.height
- dst_ratio = self.hr_resize_x / self.hr_resize_y
-
- if src_ratio < dst_ratio:
- self.hr_upscale_to_x = self.hr_resize_x
- self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
- else:
- self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
- self.hr_upscale_to_y = self.hr_resize_y
-
- self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
- self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f
+ self.calculate_target_resolution()
if not state.processing_has_refined_job_count:
if state.job_count == -1:
diff --git a/modules/ui.py b/modules/ui.py
index 4e1daa8d..cbad3afe 100644
--- a/modules/ui.py
+++ b/modules/ui.py
@@ -14,7 +14,7 @@ from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_grad
from modules import gradio_extensons # noqa: F401
from modules import sd_hijack, sd_models, script_callbacks, ui_extensions, deepbooru, extra_networks, ui_common, ui_postprocessing, progress, ui_loadsave, errors, shared_items, ui_settings, timer, sysinfo, ui_checkpoint_merger, ui_prompt_styles, scripts, sd_samplers, processing, devices, ui_extra_networks
-from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML
+from modules.ui_components import FormRow, FormGroup, ToolButton, FormHTML, InputAccordion
from modules.paths import script_path
from modules.ui_common import create_refresh_button
from modules.ui_gradio_extensions import reload_javascript
@@ -94,11 +94,9 @@ def calc_resolution_hires(enable, width, height, hr_scale, hr_resize_x, hr_resiz
return ""
p = processing.StableDiffusionProcessingTxt2Img(width=width, height=height, enable_hr=True, hr_scale=hr_scale, hr_resize_x=hr_resize_x, hr_resize_y=hr_resize_y)
+ p.calculate_target_resolution()
- with devices.autocast():
- p.init([""], [0], [0])
-
- return f"resize: from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
+ return f"from <span class='resolution'>{p.width}x{p.height}</span> to <span class='resolution'>{p.hr_resize_x or p.hr_upscale_to_x}x{p.hr_resize_y or p.hr_upscale_to_y}</span>"
def resize_from_to_html(width, height, scale_by):
@@ -436,11 +434,12 @@ def create_ui():
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")
- hr_final_resolution = FormHTML(value="", elem_id="txtimg_hr_finalres", label="Upscaled resolution", interactive=False)
elif category == "hires_fix":
- with FormGroup(visible=False, elem_id="txt2img_hires_fix") as hr_options:
+ with InputAccordion(False, label="Hires. fix") as enable_hr:
+ with enable_hr.extra():
+ hr_final_resolution = FormHTML(value="", elem_id="txtimg_hr_finalres", label="Upscaled resolution", interactive=False, min_width=0)
+
with FormRow(elem_id="txt2img_hires_fix_row1", variant="compact"):
hr_upscaler = gr.Dropdown(label="Upscaler", elem_id="txt2img_hr_upscaler", choices=[*shared.latent_upscale_modes, *[x.name for x in shared.sd_upscalers]], value=shared.latent_upscale_default_mode)
hr_second_pass_steps = gr.Slider(minimum=0, maximum=150, step=1, label='Hires steps', value=0, elem_id="txt2img_hires_steps")
@@ -568,13 +567,6 @@ def create_ui():
show_progress=False,
)
- enable_hr.change(
- fn=lambda x: gr_show(x),
- inputs=[enable_hr],
- outputs=[hr_options],
- show_progress = False,
- )
-
txt2img_paste_fields = [
(toprow.prompt, "Prompt"),
(toprow.negative_prompt, "Negative prompt"),
@@ -594,7 +586,6 @@ def create_ui():
(toprow.ui_styles.dropdown, lambda d: d["Styles array"] if isinstance(d.get("Styles array"), list) else gr.update()),
(denoising_strength, "Denoising strength"),
(enable_hr, lambda d: "Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d)),
- (hr_options, lambda d: gr.Row.update(visible="Denoising strength" in d and ("Hires upscale" in d or "Hires upscaler" in d or "Hires resize-1" in d))),
(hr_scale, "Hires upscale"),
(hr_upscaler, "Hires upscaler"),
(hr_second_pass_steps, "Hires steps"),
diff --git a/modules/ui_components.py b/modules/ui_components.py
index 8f8a7088..598ce738 100644
--- a/modules/ui_components.py
+++ b/modules/ui_components.py
@@ -72,3 +72,34 @@ class DropdownEditable(FormComponent, gr.Dropdown):
def get_block_name(self):
return "dropdown"
+
+class InputAccordion(gr.Checkbox):
+ global_index = 0
+
+ def __init__(self, value, **kwargs):
+ self.accordion_id = kwargs.get('elem_id')
+ if self.accordion_id is None:
+ self.accordion_id = f"input-accordion-{self.global_index}"
+ self.global_index += 1
+
+ kwargs['elem_id'] = self.accordion_id + "-checkbox"
+ kwargs['visible'] = False
+ super().__init__(value, **kwargs)
+
+ self.change(fn=None, _js='function(checked){ inputAccordionChecked("' + self.accordion_id + '", checked); }', inputs=[self])
+
+ self.accordion = gr.Accordion(kwargs.get('label', 'Accordion'), open=value, elem_id=self.accordion_id, elem_classes=['input-accordion'])
+
+ def extra(self):
+ return gr.Column(elem_id=self.accordion_id + '-extra', elem_classes='input-accordion-extra', min_width=0)
+
+ def __enter__(self):
+ self.accordion.__enter__()
+ return self
+
+ def __exit__(self, exc_type, exc_val, exc_tb):
+ self.accordion.__exit__(exc_type, exc_val, exc_tb)
+
+ def get_block_name(self):
+ return "checkbox"
+
diff --git a/style.css b/style.css
index dfd5ca36..5163e53c 100644
--- a/style.css
+++ b/style.css
@@ -329,12 +329,6 @@ div.gradio-accordion {
border-radius: 0 0.5rem 0.5rem 0;
}
-#txtimg_hr_finalres{
- min-height: 0 !important;
- padding: .625rem .75rem;
- margin-left: -0.75em
-}
-
#img2img_scale_resolution_preview.block{
display: flex;
align-items: end;
@@ -1016,3 +1010,12 @@ div.block.gradio-box.popup-dialog, .popup-dialog {
div.block.gradio-box.popup-dialog > div:last-child, .popup-dialog > div:last-child{
margin-top: 1em;
}
+
+div.block.input-accordion{
+ margin-bottom: 0.4em;
+}
+
+.input-accordion-extra{
+ flex: 0 0 auto !important;
+ margin: 0 0.5em 0 auto;
+}