12 KiB
dpg-gauges Build Steps
There is no Step 0. Initial setup is listed separately, then implementation starts at Step 1.
Workflow rules
- Use
uvfor all Python package and dependency management. - Always read
codex/FEATURES.md,codex/ARCHITECTURE.md, andcodex/AGENTS.mdbefore making code changes. - Keep
codex/AGENTS.mdas a rolling log of what has been done, what is broken, and what comes next. - Update
README.mdanddocs/whenever public behaviour or examples change. - After every step, update
codex/AGENTS.md, run relevant checks, and commit if working in git. - Do not casually change public API once introduced.
- Dear PyGui calls must happen on the GUI thread only.
- Runtime gauge updates are GUI-thread-only unless explicitly documented otherwise.
- Prefer stable, boring implementation over clever drawing tricks.
- Keep each step shippable and tested before moving to the next.
Initial setup instructions
Run these before Step 1 when starting from a clean repository:
mkdir dpg-gauges
cd dpg-gauges
git init
uv init --package dpg-gauges
uv add dearpygui
uv add --dev pytest ruff pyright
Create this structure:
src/dpg_gauges/
__init__.py
api.py
widget.py
state.py
renderer.py
draw_layers.py
sizing.py
animation.py
smoothing.py
scales.py
themes.py
gauges.py
diagnostics.py
types.py
exceptions.py
examples/
tests/
docs/
codex/FEATURES.md
codex/ARCHITECTURE.md
codex/STEPS.md
codex/AGENTS.md
README.md
Recommended pyproject.toml additions:
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM"]
[tool.pyright]
typeCheckingMode = "basic"
Initial checks:
uv run python -c "import dpg_gauges; print(dpg_gauges.__name__)"
uv run ruff check .
uv run ruff format .
Step 1 - Public API contract and pure core
Goal: lock the public API surface and implement pure non-DPG components first.
Tasks:
- Define public exports in
__init__.py.
Required API names:
configure
GaugeTheme
GaugeStyle
AnimationConfig
SmoothingConfig
ThresholdBand
GaugeMarker
StatusState
GaugeStats
analog_gauge
digital_gauge
bar_gauge
level_gauge
status_light
segmented_gauge
compass_gauge
thermometer_gauge
battery_gauge
multi_value_gauge
gauge_panel
gauge_grid
set_value
get_value
update_gauge
configure_gauge
set_thresholds
set_markers
set_show
delete_gauge
get_gauge_debug_state
- Add exceptions in
exceptions.py. - Add shared dataclasses and types in
types.py. - Implement configuration normalization dataclasses in
gauges.py. - Implement pure scale helpers in
scales.py. - Implement lightweight theme/style presets in
themes.py. - Stub GUI-dependent public functions so imports succeed.
- Add tests for imports, dataclass construction, clamp/normalize math, tick generation, threshold validation, and formatting.
Checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- public API imports cleanly
- pure gauge config can be created and validated
- value clamping and formatting are tested
- no Dear PyGui context is required for Step 1 tests
- API names are fixed before renderer work begins
Commit:
git add .
git commit -m "step 1: lock public api and pure core"
Step 2 - State, sizing, animation, and smoothing model
Goal: build the logical model before rendering final visuals.
Tasks:
- Implement
DpgGaugesConfigandconfigure(...). - Implement
GaugeStateand global gauge registry. - Implement
DirtyFlags. - Implement sizing helpers:
- requested size vs measured size
- last non-zero size preservation
- square gauge rect
- stretch gauge rect
- Implement animation interpolation in
animation.py. - Implement smoothing helpers in
smoothing.py. - Implement runtime state functions for
set_value,get_value,update_gauge,set_thresholds,set_markers,set_show, anddelete_gaugewithout final drawing complexity. - Add tests for registry behaviour, value/clamped/displayed separation, dirty flags, sizing transitions, animation interpolation, smoothing progression, and invalid values.
Checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- values clamp to min/max
- non-finite values do not crash pure state helpers
- dirty flags distinguish value, static, dynamic, text, size, and style changes
- smoothing and animation are optional and testable without Dear PyGui
- hidden/zero-size state does not erase last non-zero size
Commit:
git add .
git commit -m "step 2: add gauge state sizing and animation model"
Step 3 - Widget shell and renderer foundation
Goal: create stable Dear PyGui gauge shells and a renderer that can draw placeholders without flicker.
Tasks:
- Implement gauge creation context managers in
widget.py. - Create internal group/child/drawlist structures for gauge widgets.
- Register each gauge before yielding from the context manager.
- Implement
GaugeRendererfoundation:- measure size
- schedule frame callbacks where animation is active
- draw placeholder background/frame/value text
- expose debug state
- Implement
draw_layers.pybookkeeping. - Implement
gauge_panelandgauge_gridas lightweight layout helpers. - Add examples:
examples/basic_digital.pyexamples/basic_analog.pyexamples/sizing.pyexamples/dashboard.py
- Add Dear PyGui context smoke tests where feasible.
Manual checks:
uv run python examples/basic_digital.py
uv run python examples/basic_analog.py
uv run python examples/sizing.py
uv run python examples/dashboard.py
Automated checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- gauge shells appear inside Dear PyGui windows
- widgets respect basic width/height options
- hidden/show-later layout does not permanently collapse sizes
- debug state reports useful state
- no flicker through empty drawlists on simple value changes
Commit:
git add .
git commit -m "step 3: add widget shell and renderer foundation"
Step 4 - Digital, bar, level, and status gauges
Goal: implement the simplest high-value gauges first.
Tasks:
- Implement
digital_gaugerendering. - Implement
bar_gaugerendering with horizontal/vertical orientation. - Implement
level_gaugerendering. - Implement
status_lightrendering. - Implement threshold and marker drawing for bar/level where applicable.
- Implement optional tooltips and callbacks.
- Add examples:
examples/basic_digital.pyexamples/basic_bar.pyexamples/basic_level.pyexamples/basic_status.pyexamples/thresholds_markers.py
- Add tests for pure geometry and runtime update state.
Manual checks:
uv run python examples/basic_digital.py
uv run python examples/basic_bar.py
uv run python examples/basic_level.py
uv run python examples/basic_status.py
uv run python examples/thresholds_markers.py
Automated checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- digital values format correctly
- bar/level fill fraction is correct and clamped
- status states display configured colors/text
- thresholds and markers render visually without events
- stretchable gauges behave in resizable layouts
Commit:
git add .
git commit -m "step 4: add digital bar level and status gauges"
Step 5 - Analog, segmented, compass, thermometer, battery, and multi-value gauges
Goal: complete the first-release gauge catalogue.
Tasks:
- Implement
analog_gauge:- arcs
- ticks
- tick labels
- needle
- redline
- markers
- Implement
segmented_gauge. - Implement
compass_gauge. - Implement
thermometer_gauge. - Implement
battery_gauge. - Implement
multi_value_gauge. - Ensure square gauges maintain aspect ratio by default.
- Add examples:
examples/basic_segmented.pyexamples/basic_compass.pyexamples/basic_thermometer.pyexamples/basic_battery.pyexamples/basic_multi_value.py
- Add tests for value-to-angle math, tick generation, compass wraparound, segment activation, battery clamp, and multi-value config validation.
Manual checks:
uv run python examples/basic_analog.py
uv run python examples/basic_segmented.py
uv run python examples/basic_compass.py
uv run python examples/basic_thermometer.py
uv run python examples/basic_battery.py
uv run python examples/basic_multi_value.py
Automated checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- all MVP gauge types render
- analog redline and markers render correctly
- compass wraps heading values sensibly
- segmented gauges support dense shift-light style displays
- square gauges do not distort in common layouts
Commit:
git add .
git commit -m "step 5: complete first gauge catalogue"
Step 6 - High-rate updates, animation, and stress examples
Goal: prove gauges remain readable and stable under fast telemetry.
Tasks:
- Integrate animation into renderer scheduling.
- Integrate optional smoothing into value rendering.
- Ensure repeated GUI-thread
set_valuecalls coalesce naturally to the newest target. - Add examples:
examples/animations.pyexamples/live_high_rate.pyexamples/live_worst_case.py
- High-rate examples should use a producer thread for data generation and GUI-thread frame callbacks for Dear PyGui updates.
- Add debug fields for animation/smoothing state.
- Add tests for animation convergence, smoothing reset behaviour, and latest-target wins.
Manual stress checks:
uv run python examples/animations.py
uv run python examples/live_high_rate.py
uv run python examples/live_worst_case.py
While examples run:
- drive updates above 60 Hz where possible
- verify gauges do not flicker
- verify values remain human-readable with smoothing enabled
- verify animation can be disabled for immediate response
- verify UI remains responsive
Automated checks:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- high-rate examples remain stable
- smoothing and animation are configurable per gauge
- no unbounded update queue exists
- renderer only schedules continuous frames while needed
Commit:
git add .
git commit -m "step 6: add animation and high rate update stress tests"
Step 7 - Documentation, hardening, and beta release
Goal: make the package usable as a dependency in DataFlux and public projects.
Tasks:
- Write
README.mdwith:- install
- minimal analog/digital examples
- dashboard example
- GUI-thread update contract
- animation/smoothing explanation
- threshold/marker examples
- Write docs:
docs/GETTING_STARTED.mddocs/EXAMPLES.mddocs/API_REFERENCE.md
- Add docstrings for all public functions.
- Review public API exports.
- Add hardening tests for:
- unknown gauge
- duplicate tag
- invalid range
- invalid threshold
- invalid marker
- non-finite value
- deleted gauge updates
- hidden layout sizing
- animation disabled/enabled
- Run all examples manually.
- Test local editable install from another project:
uv add --editable ../dpg-gauges
uv run python -c "import dpg_gauges as dpgg; print(dpgg.__name__)"
- Bump version.
Suggested initial beta:
0.1.0b1
Final checks:
uv sync
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
Acceptance criteria:
- all examples run
- local editable dependency works
- docs cover all public gauge types
- high-rate examples are stable
- README clearly documents Dear PyGui GUI-thread expectations
codex/AGENTS.mdaccurately describes status
Commit:
git add .
git commit -m "step 7: harden docs and prepare beta"
git tag v0.1.0b1