Clarify grid autobreak behavior
This commit is contained in:
@@ -43,9 +43,11 @@ with dpg.window(label="Engine"):
|
||||
dpgg.status_light(tag="ecu", label="ECU", state=True)
|
||||
```
|
||||
|
||||
`gauge_grid` is a wrapping, table-backed layout. `columns` is a maximum; if the parent is too
|
||||
narrow for `columns * min_column_width`, the grid uses fewer columns and continues on the next row
|
||||
instead of creating a horizontal scrollbar. Gauges with `width=0` or `width=-1` fill their grid cell.
|
||||
`gauge_grid` is a wrapping, table-backed layout. An integer `columns` value is a maximum; if the
|
||||
parent is too narrow for `columns * min_column_width`, the grid uses fewer columns and continues on
|
||||
the next row instead of creating a horizontal scrollbar. Use `columns="auto"` for autobreak mode,
|
||||
where the grid derives the column count from the available width. Gauges with `width=0` or
|
||||
`width=-1` fill their grid cell.
|
||||
|
||||
Gauges also accept Dear PyGui's usual `parent` argument for adding a gauge to an
|
||||
existing container after that container has already been created:
|
||||
|
||||
@@ -24,10 +24,14 @@ Creation functions are context managers and accept common options such as `tag`,
|
||||
## Layout Helpers
|
||||
|
||||
- `gauge_panel(**config)`: child-window panel for grouped gauges.
|
||||
- `gauge_grid(columns=1, min_column_width=180, fit_gauges=True, **config)`: table-backed
|
||||
wrapping gauge grid. `columns` is the maximum number of columns. If the parent is narrower than
|
||||
`columns * min_column_width`, the grid uses fewer columns and wraps gauges onto later rows to
|
||||
avoid horizontal scrolling. Gauges without an explicit positive width fill their grid cell.
|
||||
- `gauge_grid(columns=1, min_column_width=180, fit_gauges=True, cell_padding=12, **config)`:
|
||||
table-backed
|
||||
wrapping gauge grid. Pass an integer `columns` to set the maximum column count; if the parent is
|
||||
narrower than `columns * min_column_width`, the grid uses fewer columns and wraps gauges onto
|
||||
later rows to avoid horizontal scrolling. Pass `columns="auto"` for autobreak mode, where the
|
||||
column count is derived entirely from the available width and `min_column_width`. Gauges without
|
||||
an explicit positive width fill their grid cell. Increase `cell_padding` if a custom Dear PyGui
|
||||
theme uses wider table padding or borders.
|
||||
|
||||
## Runtime API
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ def main() -> None:
|
||||
dpg.create_context()
|
||||
try:
|
||||
with dpg.window(label="Grid layout", width=820, height=620):
|
||||
dpg.add_text("Three-column grid: fixed column cap, automatic rows")
|
||||
dpg.add_text("Max columns: columns=3 wraps onto new rows after every third gauge")
|
||||
with dpgg.gauge_panel(label="Wide panel", width=-1, height=270), dpgg.gauge_grid(
|
||||
columns=3, min_column_width=190
|
||||
):
|
||||
@@ -26,9 +26,10 @@ def main() -> None:
|
||||
dpgg.battery_gauge(tag="grid_battery", label="Battery", value=74, height=160)
|
||||
|
||||
dpg.add_spacer(height=8)
|
||||
dpg.add_text("Narrow panel: columns=3 auto-reduces to avoid horizontal scrolling")
|
||||
with dpgg.gauge_panel(label="Narrow panel", width=390, height=250), dpgg.gauge_grid(
|
||||
columns=3, min_column_width=180
|
||||
dpg.add_text("Autobreak: columns='auto' chooses columns from available width")
|
||||
with (
|
||||
dpgg.gauge_panel(label="Autobreak narrow panel", width=430, height=285),
|
||||
dpgg.gauge_grid(columns="auto", min_column_width=180),
|
||||
):
|
||||
for index, value in enumerate((18, 42, 67, 91, 55), start=1):
|
||||
dpgg.digital_gauge(
|
||||
|
||||
@@ -134,6 +134,7 @@ class GridLayoutContext:
|
||||
columns: int
|
||||
min_column_width: int
|
||||
fit_gauges: bool
|
||||
cell_padding: int = 12
|
||||
row_height: int = 0
|
||||
available_width: int = 0
|
||||
_next_index: int = 0
|
||||
@@ -169,7 +170,7 @@ class GridLayoutContext:
|
||||
def cell_width(self) -> int | None:
|
||||
if self.available_width <= 0:
|
||||
return None
|
||||
return max(int(self.available_width / self.columns), 1)
|
||||
return max(int(self.available_width / self.columns) - self.cell_padding, 1)
|
||||
|
||||
|
||||
def create_gauge_context(gauge_type: str, config: ConfigT) -> GaugeContext[ConfigT]:
|
||||
@@ -257,9 +258,15 @@ def _available_layout_width(parent: Tag | None, width: int) -> int:
|
||||
return 0
|
||||
|
||||
|
||||
def _resolved_columns(columns: int, min_column_width: int, available_width: int) -> int:
|
||||
columns = max(int(columns), 1)
|
||||
def _resolved_columns(
|
||||
columns: int | Literal["auto"], min_column_width: int, available_width: int
|
||||
) -> int:
|
||||
min_column_width = max(int(min_column_width), 0)
|
||||
if columns == "auto":
|
||||
if available_width > 0 and min_column_width > 0:
|
||||
return max(1, available_width // min_column_width)
|
||||
return 1
|
||||
columns = max(int(columns), 1)
|
||||
if available_width > 0 and min_column_width > 0:
|
||||
columns = min(columns, max(1, available_width // min_column_width))
|
||||
return columns
|
||||
@@ -305,9 +312,10 @@ def gauge_panel(
|
||||
|
||||
def gauge_grid(
|
||||
*,
|
||||
columns: int = 1,
|
||||
columns: int | Literal["auto"] = 1,
|
||||
min_column_width: int = 180,
|
||||
fit_gauges: bool = True,
|
||||
cell_padding: int = 12,
|
||||
row_height: int = 0,
|
||||
tag: Tag | None = None,
|
||||
parent: Tag | None = None,
|
||||
@@ -318,7 +326,7 @@ def gauge_grid(
|
||||
) -> GridLayoutContext:
|
||||
"""Create a lightweight wrapping gauge layout container."""
|
||||
if not _dpg_context_active:
|
||||
return GridLayoutContext(None, 1, min_column_width, fit_gauges)
|
||||
return GridLayoutContext(None, 1, min_column_width, fit_gauges, cell_padding)
|
||||
layout_parent, layout_width = _next_layout_cell(parent)
|
||||
if layout_parent is not None:
|
||||
parent = layout_parent
|
||||
@@ -340,7 +348,13 @@ def gauge_grid(
|
||||
for _ in range(columns):
|
||||
dpg.add_table_column(parent=container, width_stretch=True, init_width_or_weight=1.0)
|
||||
return GridLayoutContext(
|
||||
container, columns, min_column_width, fit_gauges, row_height, available_width
|
||||
container,
|
||||
columns,
|
||||
min_column_width,
|
||||
fit_gauges,
|
||||
cell_padding,
|
||||
row_height,
|
||||
available_width,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -107,6 +107,20 @@ def test_grid_auto_reduces_columns_to_parent_width(dpg_context: None) -> None:
|
||||
assert len(children[0]) == 2
|
||||
assert len(children[1]) == 3
|
||||
assert [len(_children(row)[1]) for row in children[1]] == [2, 2, 1]
|
||||
assert 0 < get_gauge_state("narrow_metric_0").config.width < 190
|
||||
|
||||
|
||||
def test_grid_auto_columns_uses_available_width(dpg_context: None) -> None:
|
||||
with dpg.window(label="Auto", width=640), dpgg.gauge_grid(
|
||||
tag="auto_grid", columns="auto", min_column_width=180
|
||||
):
|
||||
for index in range(7):
|
||||
dpgg.digital_gauge(tag=f"auto_metric_{index}", value=index, height=60)
|
||||
|
||||
children = _children("auto_grid")
|
||||
assert len(children[0]) == 3
|
||||
assert len(children[1]) == 3
|
||||
assert [len(_children(row)[1]) for row in children[1]] == [3, 3, 1]
|
||||
|
||||
|
||||
def test_grid_routes_panels_without_stealing_panel_children(dpg_context: None) -> None:
|
||||
|
||||
Reference in New Issue
Block a user