Metadata-Version: 2.4
Name: object-tree
Version: 3.1.0
Summary: A zero-dependency, general-purpose nested selection and inspection framework
License-Expression: MIT
Project-URL: Homepage, https://github.com/GrayJou/object_tree
Project-URL: Repository, https://github.com/GrayJou/object_tree
Keywords: selection,inspection,viewport,editor,framework
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Provides-Extra: demo
Requires-Dist: dearpygui>=1.10; extra == "demo"

# object-tree

A zero-dependency Python framework for nested selection and inspection of hierarchical object trees. Framework-agnostic — no UI toolkit coupling.

## Installation

```bash
pip install object-tree
```

Core has zero runtime dependencies (stdlib only). Optional demo requires DearPyGui:

```bash
pip install "object-tree[demo]"
```

## Quick Start

```python
from core.node import InspectableObject, Property
from core.selection import SelectionState
from core.viewport import RectRegion, ViewportElement

# Build an object tree
root = InspectableObject(name="Root")
child = InspectableObject(name="Child")
root.add_child(child)

# Add properties
child.add_property(Property("color", "Literal", "#FF5722"))

# Selection
sel = SelectionState()
sel.select(child)
print(sel.is_selected(child))  # True

# Viewport element with click region
elem = ViewportElement(target=child, click_region=RectRegion(x=0, y=0, width=100, height=100))
```

See the [demo app](demo/app.py) for a complete DearPyGui example.

## Architecture

```
object-tree/
  core/              # Core framework (zero dependencies)
    node.py           InspectableObject tree, Property
    selection.py      SelectionState (single + multi)
    inspector.py      InspectorSystem, BoxSpec stack
    viewport.py       ViewportElement, click regions, Rule system
    viewport_system.py ViewportSystem with hit-testing
    hittest.py        point-in-rect/circle/polygon
    interaction.py    InteractionController (click → select → refresh)
    adapter.py        DictAdapter, InspectableAdapter protocol
  rules/             # Convenience rule builders
    boolean_flags.py  VisibilityFlags, SelectabilityFlags
    function.py       CustomRule, always_visible/hidden/selectable
  demo/              # DearPyGui demo app (optional dep)
    app.py            DPG window with canvas + inspector panel
    scene.py          4-level scene definition
```

## Key Concepts

### InspectableObject

Tree node with name, parent, children, properties, and `show_parent_box` flag (controls whether the inspector walks up to the parent).

### SelectionState

Tracks a primary selected object (with previous selection) and an optional multi-selection set.

### ViewportElement

Binds an `InspectableObject` to its on-screen representation. Controls visibility and selectability through composable rules:

| Rule | True when |
|------|-----------|
| `BooleanRule` | Always/never |
| `ParentSelectedRule` | The object's parent is selected |
| `SelfOrAncestorSelectedRule` | The object or an ancestor is the selection |
| `AncestorSelectedRule` | Any ancestor of the object is selected |
| `SiblingSelectedRule` | A sibling is selected |
| `SameGroupRule` | Same root tree as the selection |

Rules can be combined with `AndRule`, `OrRule`, `NotRule`.

### VisibilityFlags / SelectabilityFlags

High-level flag classes that translate boolean configuration into rule lists:

```python
from rules.boolean_flags import VisibilityFlags, SelectabilityFlags

flags = VisibilityFlags(
    visible_by_default=False,
    reveal_when_parent_selected=True,
    remain_visible_when_self_selected=True,
)
flags.apply(element)  # Sets element.visible_rules
```

## Roadmap

### v3.x — Current (Stabilization)

- [x] Core object tree, selection, inspector, viewport rules
- [x] Hit-testing (rect, circle, polygon)
- [x] Interaction controller
- [x] Dict adapter
- [x] DearPyGui demo
- [x] Ancestor selection rule

### v4.0 — Events & Observability

- [ ] Selection change events (`on_selected`, `on_deselected` callbacks)
- [ ] Property change events / observable properties
- [ ] Tree mutation events (child added/removed)
- [ ] `InspectorSystem` change notification

### v4.1 — Undo / Redo

- [ ] Command pattern for selection changes
- [ ] Command pattern for property edits
- [ ] Undo/redo stack with configurable depth
- [ ] Keyboard shortcuts integration

### v5.0 — Multi-Select & Viewport

- [ ] Drag-select box for multi-selection
- [ ] Modifier-key based toggle selection (Ctrl+click, Shift+click)
- [ ] Viewport scrolling / panning
- [ ] Zoom support with coordinate transforms

### v5.1 — Adapters & Interop

- [ ] Qt adapter (`QStandardItemModel` ↔ `InspectableObject`)
- [ ] Serialization adapter (JSON / YAML import/export)
- [ ] Property introspection from dataclasses / attrs
- [ ] Tree diff/patch for incremental updates

### v6.0 — Performance & Tooling

- [ ] Virtual viewport (lazy element evaluation for large trees)
- [ ] Object tree search / filter by name or property
- [ ] Property validation framework (type, range, regex)
- [ ] Profiling hooks for rule evaluation

### Future Ideas

- **Drag and drop** — Reorder objects within and across trees
- **Templates** — Reusable sub-tree blueprints
- **Documentation site** — mkdocs or readthedocs
- **CLI tool** — Inspect and manipulate object trees from the command line
- **Remote inspection** — WebSocket-based remote tree browser
- **Game engine adapters** — Godot, Unity, Unreal editor model adapters

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/my-feature`)
3. Make changes (zero-dependency core, please)
4. Run tests (`pytest tests/`)
5. Submit a pull request

## License

MIT
