lllyasviel / Fooocus

Focus on prompting and generating
GNU General Public License v3.0
40.98k stars 5.75k forks source link

Styles Grouping/Sorting #1770

Closed hswlab closed 7 months ago

hswlab commented 9 months ago

Is your feature request related to a problem? Please describe. The list becomes somewhat confusing after you have tried out different styles, as the labels seem to be sorted according to their last use.

Describe the idea you'd like For the sorting issue I'm suggesting to exted code in style_sorter.py as follows.

Jut in case the style is not in a sorted position at load.

def try_load_sorted_styles(style_names, default_selected):
    ...
    unselected = [y for y in all_styles if y not in default_selected]
    unselected.sort()
    ...

After deselecting a style, it returnes back at its alphabetically sorted position

def sort_styles(selected):
    global all_styles
    unselected = [y for y in all_styles if y not in selected]
    unselected.sort()
    ...

As already mentioned in 1749 It helps to find the styles in the list if the labels are aligned in a row. Maybe you could extend the style as follows to have 2 columns?

#component-99 .wrap[data-testid="checkbox-group"] {
    flex-direction: row !important;
}

#component-99 .wrap[data-testid="checkbox-group"] label {
    flex: calc(50% - 5px) !important;
}

image

A grouping of the styles might also be helpful (see previous example). Since Python is unfortunately not my world, I cannot make a code suggestion for this. When grouping, you should note that the heading of a group should be hidden if all styles from this group are selected and are at the top of the list.

For the group title you could keep the HTML structure and just add another label for the title. image

Probably the Sorting/Grouping feature could be made optional by clicking on an icon next to the search field image

Edit: If possible, the free text filter must of course harmonize with the suggested extensions. If you are filtering for a style, the group names should of course be hidden

hswlab commented 9 months ago

I put the code temporary in my files for testing and worked with it a little bit and I have to say that it bothers me that the fooocus styles are harder to reach. I actually use them often and don't want to scroll to f every time^^.

Maybe you could add a favorite symbol to the labels, so that you can manually tell which should be listed at the top.

You could also add a button to reset the filter.

mashb1t commented 9 months ago

just for reference: this is the opposite approach of https://github.com/lllyasviel/Fooocus/issues/740 (adding a select for styles)

hswlab commented 9 months ago

In addition to styles filter: I notized, that the filtered styles results are going lost after pressing the generate button, but the text is still staying in the filter input field. It would be nice to keep the filtered results in the styles tab after submitting the text prompt, if there is still a text left in the search field.

It is not neccesary, but if you are new to this tool, you are going to try out different e.g. cinematic or art styles by filtering for such text. But after each rendering you need to interact with the filter field to get the filter results back.

xhoxye commented 9 months ago

I like it QQ截图20240107105832

hswlab commented 9 months ago

I exteded the style a little bit to have a scrolling area with a dynamix height of the label area, so that the image area at the left is always at the top if you are searching for a style.

image

if you activate the input image checkbox, the height of the styles box is also adjusted. However, it is a bit ugly that you now have a scrollbar for the whole page and a scrollbar in the box. Maybe not everyone likes that.

image

The customized style, if someone likes to try it out:

#component-99{
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

#component-99 .wrap[data-testid="checkbox-group"] {
    flex-direction: row !important;
    flex-grow:1;
    overflow: auto;
    padding-right: 2px;
    position: absolute;
    overflow: auto;
    max-height: 100%;
}

#component-99 .wrap[data-testid="checkbox-group"] label {
    flex: calc(50% - 5px) !important;
}

#component-187{
    display: flex;
    flex-direction: column;
    flex-grow:1;
}

#component-97{
    flex-grow:1;
}

#component-97 > div:first-child {
    height: 100%;
}
mashb1t commented 9 months ago

@hswlab Gradio doesn't currently support grouping / categorisation in CheckboxGroup element items.

Feel free to create a PR if you feel this is already worth contributing. One small thing: Please refrain from using hardcoded ids of elements (they may change in the future) but rather assign the elements css classes with elem_classes='xyz' in webui.py.

hswlab commented 9 months ago

@mashb1t With these id names I was already worried that it might be generic :) Unfortunately I'm not a python programmer, so I didn't risk changing anything in the python files. But I think I found the right place where I can add my own class, thanks for the hint with "elem_classes".

Extended wbui.py row 261: added elem_classes=['style_selections_tab'] after label

 with gr.Tab(label='Style', elem_classes=['style_selections_tab']):
     style_sorter.try_load_sorted_styles(
         style_names=legal_style_names,
         default_selected=modules.config.default_styles)

The new styles for styles.css looks like follows

/* scrollable box for style selections */
.contain .tabs {
    height: 100%;
}

.contain .tabs .tabitem.style_selections_tab {
    height: 100%;
}

.contain .tabs .tabitem.style_selections_tab > div:first-child {
    height: 100%;
}

.contain .tabs .tabitem.style_selections_tab .style_selections{
    min-height:200px;
    height: 100%;
}

.contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] {
    overflow: auto;
    padding-right: 2px;
    position: absolute;
    max-height: 100%;
}

.contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] label {
    /* max-width: calc(35% - 15px) !important; */      
    flex: calc(50% - 5px) !important;
    padding:2px 5px;    
}

.contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] label span {
    /* white-space:nowrap; */ 
    overflow:hidden;
    text-overflow:ellipsis;
}

I also reduced the padding of the buttons to shrink the scrollbar image

if you remove the comments for label and label span you get 3 columns without wrapped text, which is more compact but it is better to use, if you can use tooltips to show the whole text if it is cut off.

image

EDT: I want to wait until #1762 is productive before I'm trying a PR. Maybe it would be possible to display the complete label text in the tooltip of the image preview, then you could use the 3-column variant.

EDIT2: By the way it would also be possible to use hover on the labels to toggle between wrapped and unwrapped text. So you can see the whole text, if you hover the button with the cursor. But I don't like the jumps if you are hovering the whole list. Probably 2 Columns are better, I am still undecided yet^^'... image

mashb1t commented 9 months ago

Alright, thanks! More a fan of the 2 column layout and to see the whole name directly, but let's see.

xhoxye commented 9 months ago

I probably prefer two columns, no newlines, no second scroll bar.

QQ截图20240107222810

mashb1t commented 9 months ago

@hswlab https://github.com/lllyasviel/Fooocus/pull/1762 was merged a few days ago, so feel free to create the PR whenever you have time 👍

hswlab commented 9 months ago

Thanks, I currently tested how it looks, if you have a cutted labeltext with 3 rows but with a tooltip included inside the preview image. image

If the tooltip is not wrapping in the box it looks like this image

But for PR, I've kept the 2-column layout without the tooltip image

If you are using a language, where the text is not wrapping with 3 columns layout you can still enable it. Note the comments in the style

/* scrollable box for style selections */
.contain .tabs {
    height: 100%;
}

    .contain .tabs .tabitem.style_selections_tab {
        height: 100%;
    }

        .contain .tabs .tabitem.style_selections_tab > div:first-child {
            height: 100%;
        }

        .contain .tabs .tabitem.style_selections_tab .style_selections {
            min-height: 200px;
            height: 100%;
        }

            .contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] {
                position: absolute; /* remove this to disable scrolling within the checkbox-group */
                overflow: auto;
                padding-right: 2px;
                max-height: 100%;
            }

                .contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] label {
                    /* max-width: calc(35% - 15px) !important; */ /* add this to enable 3 columns layout */
                    flex: calc(50% - 5px) !important;
                    padding: 2px 5px;
                }

                    .contain .tabs .tabitem.style_selections_tab .style_selections .wrap[data-testid="checkbox-group"] label span {
                        /* white-space:nowrap; */ /* add this to disable text wrapping (better choice for 3 columns layout) */
                        overflow: hidden;
                        text-overflow: ellipsis;
                    }

/* styles preview tooltip */
.preview-tooltip {
    background-color: #fff8;
    font-family: monospace;
    text-align: center;
    border-radius-top: 5px;
    display: none; /* remove this to enable tooltip in preview image */
}
nrrm1 commented 5 months ago

https://github.com/lllyasviel/Fooocus/issues/1770