Lucky Robots Blog Open Roles

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.

Engine: Hazel/src/Hazel/Editor/ App: LuckyEditor/src/ EditorLayer.h PanelManager.h EditorLayer is protected
EditorLayer protected · do not modify PanelManager RegisterPanel<T> / GetPanel<T> SceneHierarchy EditorPanel ContentBrowser EditorPanel Properties / Inspector EditorPanel Your new panel EditorPanel SelectionManager static · multi-context EditorStack undo / redo drives OnImGuiRender
EditorLayer owns the panel registry; each panel derives 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 is a protected file

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

TypeHeaderRole
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.

RAII

Named colours only

Pull values from Colors::Theme::* and Colors::SimpleUX::*. Hardcoded IM_COL32(...) or ImVec4(...) literals are forbidden in panel code.

no IM_COL32no ImVec4

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:

  1. Derive from EditorPanel. Implement OnImGuiRender(bool& isOpen) and any of OnEvent, SetSceneContext you need.
  2. Add a stable identifier to EditorPanelIDs.
  3. In EditorLayer::OnAttach, call m_PanelManager->RegisterPanel<YourPanel>(EditorPanelIDs::YourPanel, /* isOpen */ true).
  4. Add a menu entry under Window (or the relevant submenu) that toggles the panel's open state.
More in the Playbook

Adding gizmos, menu items, and content-browser actions are documented step-by-step in the Playbook.