215 lines
8.0 KiB
Python
215 lines
8.0 KiB
Python
# pyright: reportGeneralTypeIssues=false
|
|
|
|
from collections.abc import Generator
|
|
from typing import cast
|
|
|
|
import dearpygui.dearpygui as dpg
|
|
import pytest
|
|
|
|
import dpg_gauges as dpgg
|
|
from dpg_gauges.state import clear_registry, get_gauge_state
|
|
|
|
|
|
def _children(item: int | str) -> dict[int, list[int | str]]:
|
|
return cast(dict[int, list[int | str]], dpg.get_item_children(item))
|
|
|
|
|
|
@pytest.fixture
|
|
def dpg_context() -> Generator[None]:
|
|
clear_registry()
|
|
dpgg.configure()
|
|
dpg.create_context()
|
|
try:
|
|
yield
|
|
finally:
|
|
clear_registry()
|
|
dpg.destroy_context()
|
|
|
|
|
|
def test_dpg_gauge_shell_registers_before_yield(dpg_context: None) -> None:
|
|
with (
|
|
dpg.window(label="Smoke"),
|
|
dpgg.digital_gauge(tag="speed", label="Speed", value=42, width=180, height=80) as config,
|
|
):
|
|
state = get_gauge_state("speed")
|
|
assert config.tag == "speed"
|
|
assert state.renderer is not None
|
|
assert dpg.does_item_exist(state.container_tag)
|
|
assert state.drawlist_tag is not None
|
|
assert dpg.does_item_exist(state.drawlist_tag)
|
|
|
|
|
|
def test_runtime_update_redraws_attached_gauge(dpg_context: None) -> None:
|
|
with dpg.window(label="Smoke"):
|
|
dpgg.digital_gauge(tag="rpm", label="RPM", value=1000, max_value=8000, width=200, height=90)
|
|
|
|
dpgg.set_value("rpm", 2500)
|
|
|
|
state = get_gauge_state("rpm")
|
|
debug = dpgg.get_gauge_debug_state("rpm")
|
|
assert state.displayed_value == 2500
|
|
assert state.dirty == 0
|
|
assert debug["renderer"]["drawlist_tag"] == "rpm__drawlist"
|
|
assert "rpm__value" in debug["renderer"]["layers"]["dynamic"]
|
|
|
|
|
|
def test_hidden_gauge_preserves_configured_size(dpg_context: None) -> None:
|
|
with dpg.window(label="Hidden"):
|
|
dpgg.digital_gauge(tag="hidden", value=1, width=160, height=70, show=False)
|
|
|
|
state = get_gauge_state("hidden")
|
|
assert state.measured_width == 160
|
|
assert state.measured_height == 70
|
|
assert state.last_nonzero_width == 160
|
|
assert state.last_nonzero_height == 70
|
|
|
|
dpgg.set_show("hidden", True)
|
|
assert dpg.does_item_exist(state.container_tag)
|
|
assert state.config.show is True
|
|
|
|
|
|
def test_panel_and_grid_are_lightweight_containers(dpg_context: None) -> None:
|
|
with (
|
|
dpg.window(label="Dashboard"),
|
|
dpgg.gauge_panel(tag="engine", label="Engine", width=300, height=180) as panel,
|
|
dpgg.gauge_grid(tag="engine_grid", columns=2) as grid,
|
|
):
|
|
assert panel == "engine"
|
|
assert grid == "engine_grid"
|
|
dpgg.digital_gauge(tag="temp", label="Temp", value=90, width=120, height=60)
|
|
|
|
assert dpg.does_item_exist("engine")
|
|
assert dpg.does_item_exist("engine_grid")
|
|
assert get_gauge_state("temp").renderer is not None
|
|
|
|
|
|
def test_grid_columns_wrap_gauges_into_rows(dpg_context: None) -> None:
|
|
with dpg.window(label="Dashboard", width=720), dpgg.gauge_grid(
|
|
tag="wrap_grid", columns=3, min_column_width=1
|
|
):
|
|
for index in range(5):
|
|
dpgg.digital_gauge(tag=f"metric_{index}", value=index, height=60)
|
|
|
|
children = _children("wrap_grid")
|
|
assert len(children[0]) == 3
|
|
assert len(children[1]) == 2
|
|
assert [len(_children(row)[1]) for row in children[1]] == [3, 2]
|
|
|
|
|
|
def test_grid_auto_reduces_columns_to_parent_width(dpg_context: None) -> None:
|
|
with dpg.window(label="Narrow", width=380), dpgg.gauge_grid(
|
|
tag="narrow_grid", columns=3, min_column_width=180
|
|
):
|
|
for index in range(5):
|
|
dpgg.digital_gauge(tag=f"narrow_metric_{index}", value=index, height=60)
|
|
|
|
children = _children("narrow_grid")
|
|
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:
|
|
with dpg.window(label="Nested", width=520), dpgg.gauge_grid(tag="nested_grid", columns=2):
|
|
with dpgg.gauge_panel(tag="nested_panel", height=120):
|
|
dpgg.digital_gauge(tag="inside_panel", value=1, height=60)
|
|
dpgg.digital_gauge(tag="beside_panel", value=2, height=60)
|
|
|
|
panel_cell = cast(int | str, dpg.get_item_parent("nested_panel"))
|
|
assert dpg.get_item_type(panel_cell) == "mvAppItemType::mvTableCell"
|
|
assert dpg.get_item_parent("inside_panel") == "nested_panel"
|
|
beside_cell = cast(int | str, dpg.get_item_parent("beside_panel"))
|
|
assert dpg.get_item_type(beside_cell) == "mvAppItemType::mvTableCell"
|
|
|
|
|
|
def test_grid_accepts_gauges_added_after_context(dpg_context: None) -> None:
|
|
with dpg.window(label="Late", width=520), dpgg.gauge_grid(tag="late_grid", columns=2):
|
|
dpgg.digital_gauge(tag="late_initial", value=1, height=60)
|
|
|
|
dpgg.digital_gauge(tag="late_second", parent="late_grid", value=2, height=60)
|
|
dpgg.digital_gauge(tag="late_third", parent="late_grid", value=3, height=60)
|
|
|
|
children = _children("late_grid")
|
|
assert [len(_children(row)[1]) for row in children[1]] == [2, 1]
|
|
|
|
for tag in ("late_initial", "late_second", "late_third"):
|
|
cell = cast(int | str, dpg.get_item_parent(tag))
|
|
assert dpg.get_item_type(cell) == "mvAppItemType::mvTableCell"
|
|
|
|
|
|
def test_auto_grid_in_autosize_panel_wraps_late_gauges(dpg_context: None) -> None:
|
|
with (
|
|
dpg.window(label="Autosize", width=1200),
|
|
dpgg.gauge_panel(
|
|
tag="autosize_panel", width=1000, height=600, autosize_x=True, autosize_y=True
|
|
),
|
|
):
|
|
dpgg.gauge_grid(tag="autosize_grid", columns="auto", min_column_width=180)
|
|
|
|
for index in range(7):
|
|
dpgg.digital_gauge(
|
|
tag=f"autosize_metric_{index}", parent="autosize_grid", value=index, height=60
|
|
)
|
|
|
|
children = _children("autosize_grid")
|
|
assert len(children[0]) == 5
|
|
assert [len(_children(row)[1]) for row in children[1]] == [5, 2]
|
|
assert 0 < get_gauge_state("autosize_metric_0").config.width < 200
|
|
|
|
|
|
def test_auto_grid_refreshes_when_autosize_width_becomes_known(dpg_context: None) -> None:
|
|
with (
|
|
dpg.window(label="Autosize"),
|
|
dpgg.gauge_panel(tag="late_width_panel", autosize_x=True, autosize_y=True),
|
|
):
|
|
grid = dpgg.gauge_grid(tag="late_width_grid", columns="auto", min_column_width=180)
|
|
|
|
assert grid.columns == 1
|
|
|
|
dpg.configure_item("late_width_panel", width=1000)
|
|
for index in range(6):
|
|
dpgg.digital_gauge(tag=f"late_width_metric_{index}", parent="late_width_grid", value=index)
|
|
|
|
children = _children("late_width_grid")
|
|
assert len(children[0]) == 5
|
|
assert [len(_children(row)[1]) for row in children[1]] == [5, 1]
|
|
|
|
|
|
def test_auto_grid_reflows_existing_gauges_when_panel_narrows(dpg_context: None) -> None:
|
|
with dpg.window(label="Resize"), dpgg.gauge_panel(
|
|
tag="resize_panel", width=1000, height=300
|
|
):
|
|
grid = dpgg.gauge_grid(tag="resize_grid", columns="auto", min_column_width=180)
|
|
with grid:
|
|
for index in range(6):
|
|
dpgg.digital_gauge(tag=f"resize_metric_{index}", value=index, height=60)
|
|
|
|
assert grid.columns == 5
|
|
children = _children("resize_grid")
|
|
assert [len(_children(row)[1]) for row in children[1]] == [5, 1]
|
|
|
|
dpg.configure_item("resize_panel", width=430)
|
|
grid.refresh_columns()
|
|
|
|
assert grid.columns == 2
|
|
children = _children("resize_grid")
|
|
assert len(children[0]) == 2
|
|
assert [len(_children(row)[1]) for row in children[1]] == [2, 2, 2]
|
|
for index in range(6):
|
|
cell = cast(int | str, dpg.get_item_parent(f"resize_metric_{index}"))
|
|
assert dpg.get_item_type(cell) == "mvAppItemType::mvTableCell"
|