Zyin055 / Config-Presets

Extension for Automatic1111
MIT License
276 stars 18 forks source link

FEATURE REQUEST: Checkbox groups #60

Open marcsyp opened 1 year ago

marcsyp commented 1 year ago

With my list of tracked elements growing very large, it has inspried me to request a new feature to make selecting which elements to store in any configuration much easier and far less painful. This would require a bit of UI work, here is an example of what I'm thinking:

CP-UI-proposal copy

Unchecking the main group header would enable/disable all the checkmarks for that group. Otherwise, you have to comb through dozens of checkmarks and disable a lot of things, for instance, if you want to save gen params but no control net, or vice versa. Thoughts?

Zyin055 commented 1 year ago

Likely won't happen.

Components do not have any association with other components other than their ID name. Even if we did manually create a grouping to make sets of components, this type of sorted layout in the GUI would require a bunch of work to get it working with the way Config Presets currently handles custom fields.

Symbiomatrix commented 1 year ago

A visual separation doesn't seem too difficult to achieve, fields_checkboxgroup is fairly standalone and might be rendered in a loop by grouping extension ids from the base list (the naming scheme is fairly reliable at least in the major ones). What I think might pose a problem is components affecting other components; not sure gradio supports this natively, had to use tabs in the past, Vlad's added some hide / unhide thing in recent versions, but I suspect it's some js hackery. Perhaps instead, if the group checkbox is unchecked then all children values are simply ignored without changing the check values themselves.

marcsyp commented 1 year ago

@Symbiomatrix not sure if this is still on your radar but I still yearn for this functionality fairly regularly -- did you do any exploration on this? Thanks!

enternalsaga commented 7 months ago

or just a master checkbox to toggle all checkboxes? Im tired turning off check boxes when my need is only few components among dozens I've produced. Any thought? Thanks.

Symbiomatrix commented 6 months ago

@marcsyp Sorry, never check notifications. What zyin said way back still holds true - getting a high level of polish on the particular layout and functionality you propose is a lot of gui work, and I daresay for a relatively esoteric QOL improvement. Adding js to the mix further complicates things (and I know too little js to predict what may arise or how to do it). A patchwork solution can be achieved with relative ease: as I'd suggested, creating group level checkboxes, dumping them together before all the component checkboxes, then using a group-components relation to ignore all the unchecked groups when saving.

bluelovers commented 1 month ago

https://github.com/Zyin055/Config-Presets/pull/96

bluelovers commented 1 month ago

image

import gradio as gr

def create_group_of_checkbox_group(*args, label="", **kwargs):
    elem = None
    label = f"{label}"

    with gr.Accordion(label) as acc:
        elem = gr.CheckboxGroup(*args, show_label=False, interactive=True, **kwargs)
    return {
        "Accordion": acc,
        "CheckboxGroup": elem,
    }

def create_components_output(components):
    components_output = []
    for item in components:
      components_output.append(item["Accordion"])
      components_output.append(item["CheckboxGroup"])

    return components_output

with gr.Blocks() as demo:

    checkbox_groups = [
        ["item1", "item2", "item3"],
        ["item4", "item5", "item1", "item2", "item3"],
        ["item2", "item1", "item6", "item3"]
    ]

    components = [create_group_of_checkbox_group(item) for item in checkbox_groups]
    components_output = create_components_output(components)

    def update_checkboxes(my_ids, *components):
      # components = [component for component in demo.children if isinstance(component, gr.CheckboxGroup)]

      d1=[]

      ids = my_ids.split(',') or []

      for i, val in enumerate(checkbox_groups):
        # updated_value = [item for item in val.choices if item in ids]
        updated_value = [item for item in val if item in ids] or ids

        d1.append(updated_value)

      return d1

    def update_checkboxes2(my_ids):
      d1=[]
      ids = my_ids.split(',') or []

      for i, val in enumerate(checkbox_groups):
        updated_value = [item for item in val if item in ids]
        bo = bool(len(updated_value) > 0)

        item = components[i]

        print(i, bo, updated_value, val)

        d1.append(gr.update(open=bo))
        d1.append(gr.update(value=updated_value))

      print(d1)

      return d1

    with gr.Row():
        my_ids_input = gr.Textbox(label="輸入需要勾選的項目ID (以逗號分隔)", value="item1,item3")
        update_button = gr.Button("更新2")

    # update_button.click(fn=update_checkboxes, inputs=[my_ids_input, *components_output], outputs=components_output, show_progress=False)
    update_button.click(fn=update_checkboxes2, inputs=[my_ids_input], outputs=components_output, show_progress=False)

if __name__ == "__main__":
    demo.launch()