Add ImGui Scene Explorer (F4) for runtime object inspection (#136)

New Features:
- Scene Explorer window (F4) displays hierarchical tree of all scenes
- Shows UIDrawable hierarchy with type, name, and visibility status
- Click scene name to switch active scene
- Double-click drawables to toggle visibility
- Displays Python repr() for cached objects, enabling custom class debugging
- Entity display within Grid nodes

Bug Fixes:
- Fix PythonObjectCache re-registration: when retrieving objects from
  collections, newly created Python wrappers are now re-registered in
  the cache. Previously, inline-created objects (e.g.,
  scene.children.append(Frame(...))) would lose their cache entry when
  the temporary Python object was GC'd, causing repeated wrapper
  allocation on each access.
- Fix console focus stealing: removed aggressive focus reclaim that
  caused title bar flashing when clicking in Scene Explorer

Infrastructure:
- Add GameEngine::getSceneNames() to expose scene list for explorer
- Scene Explorer uses same enabled flag as console (ImGuiConsole::isEnabled())

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John McCardle 2026-01-21 23:26:33 -05:00
commit 5e45ab015c
7 changed files with 378 additions and 3 deletions

46
src/ImGuiSceneExplorer.h Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include <string>
#include <memory>
class GameEngine;
class UIDrawable;
class UIEntity;
class UIFrame;
class UIGrid;
/**
* @brief ImGui-based scene tree explorer for debugging
*
* Displays hierarchical view of all scenes and their UI elements.
* Allows switching between scenes and collapsing/expanding the tree.
* Activated by F4 key. Mutually exclusive with the console (grave key).
*/
class ImGuiSceneExplorer {
public:
ImGuiSceneExplorer() = default;
// Core functionality
void render(GameEngine& engine);
void toggle();
bool isVisible() const { return visible; }
void setVisible(bool v) { visible = v; }
// Configuration - uses same enabled flag as console
static bool isEnabled();
private:
bool visible = false;
// Tree rendering helpers
void renderSceneNode(GameEngine& engine, const std::string& sceneName, bool isActive);
void renderDrawableNode(std::shared_ptr<UIDrawable> drawable, int depth = 0);
void renderEntityNode(std::shared_ptr<UIEntity> entity);
// Get display name for a drawable (name or type + address)
std::string getDisplayName(UIDrawable* drawable);
std::string getEntityDisplayName(UIEntity* entity);
// Get type name string
const char* getTypeName(UIDrawable* drawable);
};