Add a wrap option for horizontal groups
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:
Thanks for the huge work on dpg !