From 7520be4874286ae491f2b9d674d2b88840502bd0 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 4 Apr 2025 09:05:32 -0400 Subject: [PATCH] styles resize and bring quick-ui forward on hover Signed-off-by: Vladimir Mandic --- CHANGELOG.md | 3 +++ extensions-builtin/sdnext-modernui | 2 +- javascript/sdnext.css | 1 + modules/images_grid.py | 30 +++++++++++++++++++++++------- modules/processing.py | 2 +- modules/shared.py | 4 +++- modules/ui_common.py | 4 ++-- 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e800e47ff..c059dc4a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ - Video: add FasterCache and PAB support to WanDB and LTX models - Progress: add additional fields to progress API - Progress: use batch-count for progress +- Grid: add of max-rows and max-columns in settings to control grid format +- Gallery: add max-columns in settings for gradio gallery components +- Styles: resize and bring quick-ui to forward on hover ## Update for 2025-04-03 diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui index 9bed415dc..777f6bdca 160000 --- a/extensions-builtin/sdnext-modernui +++ b/extensions-builtin/sdnext-modernui @@ -1 +1 @@ -Subproject commit 9bed415dccad1041e0573134d2f214e40bd310f1 +Subproject commit 777f6bdca27abe39cbfe050f83cbd5bd71f8f84a diff --git a/javascript/sdnext.css b/javascript/sdnext.css index 5ffc03d36..8b52b1a47 100644 --- a/javascript/sdnext.css +++ b/javascript/sdnext.css @@ -148,6 +148,7 @@ div#extras_scale_to_tab div.form { flex-direction: row; } #txt2img_prompt, #txt2img_neg_prompt, #img2img_prompt, #img2img_neg_prompt, #control_prompt, #control_neg_prompt, #video_prompt, #video_neg_prompt { background-color: var(--background-color); box-shadow: none !important; } #txt2img_prompt > label > textarea, #txt2img_neg_prompt > label > textarea, #img2img_prompt > label > textarea, #img2img_neg_prompt > label > textarea, #control_prompt > label > textarea, #control_neg_prompt > label > textarea, #video_prompt > label > textarea, #video_neg_prompt > label > textarea { font-size: 1.0em; line-height: 1.4em; } #txt2img_styles, #img2img_styles, #control_styles, #video_styles { padding: 0; margin-top: 2px; } +#txt2img_styles:hover, #img2img_styles:hover, #control_styles:hover, #video_styles:hover { z-index: 1000; } #txt2img_styles_refresh, #img2img_styles_refresh, #control_styles_refresh, #video_styles_refresh { padding: 0; margin-top: 1em; } /* settings */ diff --git a/modules/images_grid.py b/modules/images_grid.py index a7f10396e..262440f75 100644 --- a/modules/images_grid.py +++ b/modules/images_grid.py @@ -19,24 +19,40 @@ def check_grid_size(imgs): return ok -def get_grid_size(imgs, batch_size=1, rows=None): - if rows is None: +def get_grid_size(imgs, batch_size=1, rows=None, cols=None): + if rows and rows > len(imgs): + rows = len(imgs) + if cols and cols > len(imgs): + cols = len(imgs) + if rows is None and cols is None: if shared.opts.n_rows > 0: rows = shared.opts.n_rows + cols = math.ceil(len(imgs) / rows) elif shared.opts.n_rows == 0: rows = batch_size + cols = math.ceil(len(imgs) / rows) + elif shared.opts.n_cols > 0: + cols = shared.opts.n_cols + rows = math.ceil(len(imgs) / cols) + elif shared.opts.n_cols == 0: + cols = batch_size + rows = math.ceil(len(imgs) / cols) else: rows = math.floor(math.sqrt(len(imgs))) while len(imgs) % rows != 0: rows -= 1 - if rows > len(imgs): - rows = len(imgs) - cols = math.ceil(len(imgs) / rows) + cols = math.ceil(len(imgs) / rows) + elif cols is None: + cols = math.ceil(len(imgs) / rows) + elif rows is None: + rows = math.ceil(len(imgs) / cols) + else: + pass return rows, cols -def image_grid(imgs, batch_size=1, rows=None): - rows, cols = get_grid_size(imgs, batch_size, rows=rows) +def image_grid(imgs, batch_size:int=1, rows:int=None, cols:int=None): + rows, cols = get_grid_size(imgs, batch_size, rows=rows, cols=cols) params = script_callbacks.ImageGridLoopParams(imgs, cols, rows) script_callbacks.image_grid_callback(params) imgs = [i for i in imgs if i is not None] if imgs is not None else [] diff --git a/modules/processing.py b/modules/processing.py index 2728903a2..619b544dc 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -455,7 +455,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: p.color_corrections = None index_of_first_image = 0 - if (shared.opts.return_grid or shared.opts.grid_save) and not p.do_not_save_grid and len(output_images) > 1: + if (shared.opts.return_grid or shared.opts.grid_save) and (not p.do_not_save_grid) and (len(output_images) > 1): if images.check_grid_size(output_images): r, c = images.get_grid_size(output_images, p.batch_size) grid = images.image_grid(output_images, p.batch_size) diff --git a/modules/shared.py b/modules/shared.py index 1db4c2935..8e84c71eb 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -677,7 +677,8 @@ options_templates.update(options_section(('saving-images', "Image Options"), { "image_sep_grid": OptionInfo("

Grid Options

", "", gr.HTML), "grid_save": OptionInfo(True, "Save all generated image grids"), "grid_format": OptionInfo('jpg', 'File format', gr.Dropdown, {"choices": ["jpg", "png", "webp", "tiff", "jp2", "jxl"]}), - "n_rows": OptionInfo(-1, "Row count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}), + "n_rows": OptionInfo(-1, "Grid max rows count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}), + "n_cols": OptionInfo(-1, "Grid max columns count", gr.Slider, {"minimum": -1, "maximum": 16, "step": 1}), "grid_background": OptionInfo("#000000", "Grid background color", gr.ColorPicker, {}), "font": OptionInfo("", "Font file"), "font_color": OptionInfo("#FFFFFF", "Font color", gr.ColorPicker, {}), @@ -745,6 +746,7 @@ options_templates.update(options_section(('ui', "User Interface"), { "ui_request_timeout": OptionInfo(30000, "UI request timeout", gr.Slider, {"minimum": 1000, "maximum": 120000, "step": 10}), "motd": OptionInfo(False, "Show MOTD"), "compact_view": OptionInfo(False, "Compact view"), + "ui_columns": OptionInfo(4, "Gallery view columns", gr.Slider, {"minimum": 1, "maximum": 8, "step": 1}), "return_grid": OptionInfo(True, "Show grid in results"), "return_mask": OptionInfo(False, "Inpainting include greyscale mask in results"), "return_mask_composite": OptionInfo(False, "Inpainting include masked composite in results"), diff --git a/modules/ui_common.py b/modules/ui_common.py index f5260d10c..84e0c888d 100644 --- a/modules/ui_common.py +++ b/modules/ui_common.py @@ -242,7 +242,6 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None, transfe with gr.Group(elem_id=f"{tabname}_gallery_container"): if tabname == "txt2img": gr.HTML(value="", elem_id="main_info", visible=False, elem_classes=["main-info"]) - # columns are for <576px, <768px, <992px, <1200px, <1400px, >1400px result_gallery = gr.Gallery(value=[], label='Output', show_label=False, @@ -250,12 +249,13 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None, transfe allow_preview=True, container=False, preview=preview, - columns=4, + columns=shared.opts.ui_columns, object_fit='scale-down', height=height, elem_id=f"{tabname}_gallery", elem_classes=["gallery_main"], ) + print('HERE', shared.opts.ui_columns) if prompt is not None: ui_sections.create_interrogate_button(tab=tabname, inputs=result_gallery, outputs=prompt)