2.10 · Editor
The desktop authoring app. Split between engine-side base classes that any tool can reuse and the LuckyEditor application itself, with a panel registry, selection contexts, and an undo stack on top of ImGui.
EditorPanel and is dispatched per frame.Overview
The engine side under Hazel/src/Hazel/Editor/ provides the base classes anything that wants
to be an editor tool reuses: EditorPanel, PanelManager,
SelectionManager, EditorCamera, EditorResources, the operation /
undo stack. The LuckyEditor app itself sits in LuckyEditor/src/ and wires these together via
EditorLayer.
EditorLayer.h/.cpp is on the protected list (see
send-pr/SKILL.md § 13). Do not add feature code here. Every new feature lives in its
own panel or system, with EditorLayer just registering it during
OnAttach. Touching this file will fail review.
Ownership & lifecycle
EditorLayer is created by the application as its only client layer. On attach it constructs
the editor scene, the viewport renderer, the PanelManager, and registers each panel by ID.
Each frame it forwards events to OnEvent overrides, calls PanelManager::OnUpdate
and finally OnImGuiRender, which iterates every registered panel and calls its
OnImGuiRender(bool& isOpen).
Key types
| Type | Header | Role |
|---|---|---|
EditorLayer |
LuckyEditor/src/EditorLayer.h |
Top-level orchestrator. Owns the editor scene, viewport, and panel manager. protected |
PanelManager |
PanelManager.h |
Template-based registry. RegisterPanel<T>(id, isOpen) creates and stores a panel; GetPanel<T>(id) retrieves it. Drives the per-frame ImGui pass. |
EditorPanel |
EditorPanel.h |
Abstract base. Override OnImGuiRender(bool& isOpen); optionally OnEvent and SetSceneContext. |
SelectionManager |
SelectionManager.h |
Static. Multi-context selection — Scene, ContentBrowser, and others. Panels read / write their own context. |
EditorOperation / EditorStack |
EditorOperation.h |
Undo / redo stack. Wrap user-visible mutations in an operation so they can be reversed. |
EditorCamera |
EditorCamera.h |
Viewport camera with arcball and flycam modes. |
EditorResources |
EditorResources.h |
100+ icons / textures loaded at startup. Reference these instead of loading your own. |
ImGui style
The editor follows a strict ImGui style that the linter and reviewers enforce. The rules exist so that themes, accessibility, and any future styling refactor stay one place.
Scoped helpers, not Push / Pop
Use ImGuiEx::ScopedStyle, ScopedColour, ScopedFont,
ScopedDisable, ScopedID. They unwind on scope exit and survive early
returns — raw PushStyleVar / PopStyleVar pairs are easy to leak.
Named colours only
Pull values from Colors::Theme::* and Colors::SimpleUX::*. Hardcoded
IM_COL32(...) or ImVec4(...) literals are forbidden in panel code.
Prefer ImGuiEx widgets
Reach for ImGuiEx::SetTooltip, FitPath, DrawSpinner, and the
rest of the helpers before reinventing one. If you do invent one, put it in ImGuiEx
instead of inline in your panel.
One panel, one ID
Panels register with a stable ID listed in EditorPanelIDs. The ID is the key used by
layout persistence and GetPanel<T>; renaming it breaks saved layouts.
Extending
To add a new panel:
- Derive from
EditorPanel. ImplementOnImGuiRender(bool& isOpen)and any ofOnEvent,SetSceneContextyou need. - Add a stable identifier to
EditorPanelIDs. - In
EditorLayer::OnAttach, callm_PanelManager->RegisterPanel<YourPanel>(EditorPanelIDs::YourPanel, /* isOpen */ true). - Add a menu entry under Window (or the relevant submenu) that toggles the panel's open state.
Adding gizmos, menu items, and content-browser actions are documented step-by-step in the Playbook.