mirror of
https://github.com/vladmandic/automatic
synced 2026-09-15 02:58:44 +02:00
address selection filter review feedback
This commit is contained in:
@@ -1,17 +0,0 @@
|
||||
"""Helpers for filtering display-only UI choice lists."""
|
||||
|
||||
|
||||
def filter_ui_choices(choices: list[str], preferences: list[str] | None = None, selected: str | None = None) -> tuple[list[str], bool]:
|
||||
"""Return choices selected for display without changing the underlying catalog.
|
||||
|
||||
Empty or stale preferences leave the complete list visible. A current value is
|
||||
always retained so loading a saved workflow cannot silently replace it.
|
||||
"""
|
||||
available = list(dict.fromkeys(choices))
|
||||
preferred = set(preferences or [])
|
||||
filtered = [choice for choice in available if choice in preferred]
|
||||
if not filtered:
|
||||
return available, False
|
||||
if selected in available and selected not in filtered:
|
||||
filtered.append(selected)
|
||||
return filtered, len(filtered) < len(available)
|
||||
@@ -18,6 +18,21 @@ debug('Trace: PASTE')
|
||||
warn_once_set = WeakSet()
|
||||
|
||||
|
||||
def filter_ui_choices(choices: list[str], preferences: list[str] | None = None, selected: str | None = None) -> tuple[list[str], bool]:
|
||||
"""Return display choices while preserving the current selection."""
|
||||
available = list(dict.fromkeys(choices))
|
||||
preferred = set(preferences or [])
|
||||
filtered = [choice for choice in available if choice in preferred]
|
||||
if not filtered:
|
||||
return available, False
|
||||
if selected in available and selected not in filtered:
|
||||
filtered.append(selected)
|
||||
if 'None' in filtered:
|
||||
filtered.remove('None')
|
||||
filtered.insert(0, 'None')
|
||||
return filtered, len(filtered) < len(available)
|
||||
|
||||
|
||||
def gr_show(visible=True):
|
||||
return {"visible": visible, "__type__": "update"}
|
||||
|
||||
|
||||
@@ -596,6 +596,10 @@ def create_settings(cmd_opts):
|
||||
"quicksetting_sep_images": OptionInfo("<h2>Quicksettings</h2>", "", gr.HTML),
|
||||
"quicksettings_list": OptionInfo(["sd_model_checkpoint"], "Quicksettings list", gr.Dropdown, lambda: {"multiselect":True, "choices": list(options_templates.keys())}),
|
||||
|
||||
"selections_sep_ui": OptionInfo("<h2>Selections</h2>", "", gr.HTML),
|
||||
"show_samplers": OptionInfo([], "Show samplers in user interface", gr.Dropdown, lambda: {"multiselect": True, "choices": [x.name for x in list_samplers()]}, refresh=list_samplers),
|
||||
"show_upscalers": OptionInfo([], "Show upscalers in user interface", gr.Dropdown, lambda: {"multiselect": True, "choices": list_upscalers()}, refresh=refresh_upscalers),
|
||||
|
||||
"server_sep_ui": OptionInfo("<h2>Startup & Server Options</h2>", "", gr.HTML),
|
||||
"autolaunch": OptionInfo(False, "Autolaunch browser upon startup"),
|
||||
"motd": OptionInfo(False, "Show MOTD"),
|
||||
@@ -774,12 +778,6 @@ def create_settings(cmd_opts):
|
||||
"disable_all_extensions": OptionInfo("none", "Disable all extensions", gr.Radio, {"choices": ["none", "user", "all"]}),
|
||||
}))
|
||||
|
||||
# --- Sampler Settings ---
|
||||
options_templates.update(options_section(('sampler', "Sampler Settings"), {
|
||||
"show_samplers": OptionInfo([], "Show samplers in user interface", gr.CheckboxGroup, lambda: {"choices": [x.name for x in list_samplers()]}, refresh=list_samplers),
|
||||
"show_upscalers": OptionInfo([], "Show upscalers in user interface", gr.CheckboxGroup, lambda: {"choices": list_upscalers()}, refresh=refresh_upscalers),
|
||||
}))
|
||||
|
||||
# --- Hidden Options ---
|
||||
options_templates.update(
|
||||
options_section(
|
||||
|
||||
@@ -2,7 +2,6 @@ import gradio as gr
|
||||
from modules import shared, modelloader, ui_symbols, ui_common, sd_samplers
|
||||
from modules.logger import log
|
||||
from modules.ui_components import ToolButton
|
||||
from modules.ui_choices import filter_ui_choices
|
||||
from modules.caption import caption
|
||||
|
||||
|
||||
@@ -220,7 +219,7 @@ def sampler_choices(choices=None, selected='Default', same_as_primary=False):
|
||||
sd_samplers.set_samplers()
|
||||
choices = [sampler for sampler in sd_samplers.samplers if sampler.name != 'Same as primary']
|
||||
names = [choice.name if hasattr(choice, 'name') else choice for choice in choices]
|
||||
visible, filtered = filter_ui_choices(names, shared.opts.show_samplers, selected)
|
||||
visible, filtered = ui_common.filter_ui_choices(names, shared.opts.show_samplers, selected)
|
||||
if same_as_primary:
|
||||
visible.insert(0, 'Same as primary')
|
||||
value = selected if selected in visible else visible[0]
|
||||
@@ -229,14 +228,14 @@ def sampler_choices(choices=None, selected='Default', same_as_primary=False):
|
||||
|
||||
def upscaler_choices(choices, selected=None):
|
||||
"""Build display-only upscaler choices without changing available upscalers."""
|
||||
return filter_ui_choices(choices, shared.opts.show_upscalers, selected)
|
||||
return ui_common.filter_ui_choices(choices, shared.opts.show_upscalers, selected)
|
||||
|
||||
|
||||
def create_filter_indicator(tabname, kind, filtered):
|
||||
if not filtered:
|
||||
return None
|
||||
indicator = gr.Button(value=f'{kind} list filtered', elem_id=f'{tabname}_{kind.lower()}_filter_indicator', elem_classes=['filter-indicator'])
|
||||
indicator.click(fn=None, _js="() => openSettingsSection('sampler')", inputs=[], outputs=[], show_progress='hidden')
|
||||
indicator = ToolButton(value=ui_symbols.info, tooltip=f'{kind} list filtered', elem_id=f'{tabname}_{kind.lower()}_filter_indicator', elem_classes=['filter-indicator'])
|
||||
indicator.click(fn=None, _js="() => openSettingsSection('ui')", inputs=[], outputs=[], show_progress='hidden')
|
||||
return indicator
|
||||
|
||||
|
||||
@@ -247,8 +246,8 @@ def create_sampler_and_steps_selection(choices, tabname, default_steps:int=20):
|
||||
dropdown_choices, default_value, filtered = sampler_choices(choices)
|
||||
with gr.Row(elem_id=f"{tabname}_sampler_row", elem_classes=['flex-break', 'flexbox']):
|
||||
steps = gr.Slider(minimum=1, maximum=100, step=1, label="Steps", elem_id=f"{tabname}_steps", value=default_steps)
|
||||
create_filter_indicator(tabname, 'Sampler', filtered)
|
||||
sampler_index = gr.Dropdown(label='Sampling method', elem_id=f"{tabname}_sampling", choices=dropdown_choices, value=default_value, type="value")
|
||||
create_filter_indicator(tabname, 'Sampler', filtered)
|
||||
return steps, sampler_index
|
||||
|
||||
|
||||
@@ -372,8 +371,8 @@ def create_hires_inputs(tab):
|
||||
hr_force = gr.Checkbox(label='Force HiRes', value=False, elem_id=f"{tab}_hr_force")
|
||||
with gr.Row(elem_id=f"{tab}_hires_fix_row2"):
|
||||
dropdown_choices, _default_value, filtered = sampler_choices(selected='Same as primary', same_as_primary=True)
|
||||
create_filter_indicator(tab, 'Sampler', filtered)
|
||||
hr_sampler_index = gr.Dropdown(label='Refine sampler', elem_id=f"{tab}_sampling_alt", choices=dropdown_choices, value='Same as primary', type="value")
|
||||
create_filter_indicator(tab, 'Sampler', filtered)
|
||||
with gr.Row(elem_id=f"{tab}_hires_row2"):
|
||||
hr_second_pass_steps = gr.Slider(minimum=0, maximum=99, step=1, label='HiRes steps', elem_id=f"{tab}_steps_alt", value=20)
|
||||
denoising_strength = gr.Slider(minimum=0.0, maximum=0.99, step=0.01, label='Strength', value=0.3, elem_id=f"{tab}_denoising_strength")
|
||||
@@ -398,8 +397,8 @@ def create_resize_inputs(tab, images, accordion=True, latent=False, non_zero=Tru
|
||||
available_upscalers = [x for x in available_upscalers if not x.lower().startswith('latent')]
|
||||
available_upscalers, filtered = upscaler_choices(available_upscalers, available_upscalers[0])
|
||||
resize_mode = gr.Dropdown(label=f"Mode{prefix}" if non_zero else "Resize mode", elem_id=f"{tab}_resize_mode", choices=shared.resize_modes, type="index", value='Fixed')
|
||||
create_filter_indicator(tab, 'Upscaler', filtered)
|
||||
resize_name = gr.Dropdown(label=f"Method{prefix}" if non_zero else "Resize method", elem_id=f"{tab}_resize_name", choices=available_upscalers, value=available_upscalers[0], visible=True)
|
||||
create_filter_indicator(tab, 'Upscaler', filtered)
|
||||
resize_context_choices = ["Add with forward", "Remove with forward", "Add with backward", "Remove with backward"]
|
||||
resize_context = gr.Dropdown(label=f"Context{prefix}", elem_id=f"{tab}_resize_context", choices=resize_context_choices, value=resize_context_choices[0], visible=False)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, str(pathlib.Path(__file__).resolve().parents[1]))
|
||||
from modules.ui_choices import filter_ui_choices
|
||||
from modules.ui_common import filter_ui_choices
|
||||
|
||||
|
||||
class TestUiChoiceFilters(unittest.TestCase):
|
||||
@@ -32,6 +32,11 @@ class TestUiChoiceFilters(unittest.TestCase):
|
||||
self.assertEqual(visible, ['Euler', 'DPM++ 2M'])
|
||||
self.assertTrue(filtered)
|
||||
|
||||
def test_none_remains_the_first_choice(self):
|
||||
visible, filtered = filter_ui_choices(['Lanczos', 'None', 'Nearest'], ['Lanczos'], selected='None')
|
||||
self.assertEqual(visible, ['None', 'Lanczos'])
|
||||
self.assertTrue(filtered)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user