DearPyGui icon indicating copy to clipboard operation
DearPyGui copied to clipboard

Add a wrap option for horizontal groups

Open grybouilli opened this issue 1 year ago • 0 comments

Is your feature request related to a problem? Please describe. I find that having a wrap option for horizontal groups would make a lot of sense since the option exists for items such as a text item. It would particularily be fit for groups containing items that will be dynamically shown/hidden and/or added/removed.

Describe the solution you'd like The possiblity to write :

with dpg.group(horizontal=True, wrap=150):
    # add some items
   # items will wrap on new line if exceeding wrap limit

or alternatively, wrap group if the last item comes out of the viewport :

with dpg.group(horizontal=True, wrap=True):
    # add some items
   # items will autowrap on a new line if coming off viewport

Describe alternatives you've considered So far, I have the following code which will create or remove new horizontal groups upon checkboxes creation :

import dearpygui.dearpygui as dpg

dpg.create_context()
dpg.create_viewport(title='Custom Title', width=600, height=300)

def get_last_checkbox_parent() -> int | str:
    parent_groups = dpg.get_item_children("checkbox_root")
    for idx in parent_groups:
        if len(parent_groups[idx]) > 0:
            return "checkbox_parent"+str(len(parent_groups[idx])-1)
        
def get_hgroup_width(group_id : str | int) -> int | float:
    total_width = 0
    checkboxes = dpg.get_item_children(group_id)
    for idx in checkboxes:
        if len(checkboxes[idx]) > 0:
            for checkbox in checkboxes[idx]:
                item_width = dpg.get_item_rect_size(checkbox)[0]
                total_width += item_width
    return total_width
                
def get_checkbox_parent(allowance=50) -> str:
    dpg.render_dearpygui_frame()
    parent_groups = dpg.get_item_children("checkbox_root")
    window_size = dpg.get_viewport_width()
    
    return_tag = ""
    for idx in parent_groups:
        if len(parent_groups[idx]) > 0:
            id = len(parent_groups[idx])-1
            parent_group = parent_groups[idx][-1]
            last_group_width = get_hgroup_width(parent_group)
            if last_group_width+allowance >= window_size:
                id += 1
                dpg.add_group(horizontal=True, tag="checkbox_parent"+str(id), parent="checkbox_root")
            return_tag = "checkbox_parent"+str(id)
    return return_tag
    
def clean_checkbox_parent():
    parent_groups = dpg.get_item_children("checkbox_root")
    for idx in parent_groups:
        if len(parent_groups[idx]) > 0:
            last_parent_group = parent_groups[idx][-1]
            checkboxes = dpg.get_item_children(last_parent_group)
            for idx in checkboxes:
                if len(checkboxes[idx]) > 0:
                    return
            dpg.delete_item(last_parent_group)
            
def add_checkbox(sender, app_data, user_data : list) -> None:
    
    label = "THIS IS A VERY LONG LABEL"
    parent = get_last_checkbox_parent()
    user_data.append(dpg.add_checkbox(label=label, parent=parent, tag="ch"+str(len(user_data))))
    new_parent = get_checkbox_parent()
    if new_parent != parent:
        dpg.move_item(user_data[-1], parent=new_parent)
    
def remove_checkbox(sender, app_data, user_data : list) -> None:
    if len(user_data) > 0:
        dpg.delete_item(user_data.pop())
    
    clean_checkbox_parent()
 
with dpg.window(label="Example Window", tag="prime"):
    dpg.add_text("Hello, world")
    checkbox_list = []
    with dpg.group(horizontal=True):
        dpg.add_button(label="Add", callback=add_checkbox, user_data=checkbox_list)
        dpg.add_button(label="Remove", callback=remove_checkbox, user_data=checkbox_list)
        
    with dpg.group(tag="checkbox_root"):
        with dpg.group(tag="checkbox_parent0", horizontal=True):
            print()
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.set_primary_window("prime", True)

dpg.start_dearpygui()
dpg.destroy_context()

You can see it is quite the amount of work to get to our ends. Here is a preview of the behavior of this code:

visu

Thanks for the huge work on dpg !

grybouilli avatar Nov 06 '24 10:11 grybouilli