Custom Dockable Panel
Register a dockable editor panel from a native C++ addon. The panel participates in the dock layout alongside built-in panels (Scene, Assets, Properties, etc.) and can be dragged, tabbed, and resized by the user.
API
// EditorUIHooks (passed to your addon via OnLoad)
void (*RegisterWindow)(
HookId hookId,
const char* windowName, // Display name shown on the dock tab
const char* windowId, // Unique ID for persistence / open-close tracking
WindowDrawCallback drawFunc,
void* userData
);
void (*UnregisterWindow)(HookId hookId, const char* windowId);
void (*OpenWindow)(const char* windowId);
void (*CloseWindow)(const char* windowId);
bool (*IsWindowOpen)(const char* windowId);
WindowDrawCallback signature:
typedef void (*WindowDrawCallback)(void* userData);
Your callback is invoked inside BeginDock / EndDock, so you can use any ImGui widgets directly -- no need to call Begin/End yourself.
Example
#include "Plugins/EditorUIHooks.h"
#include "imgui.h"
// Unique hook identifier for this addon
static HookId sHookId = 0;
// State for the panel content
struct MyPanelState
{
float mValue = 0.5f;
char mText[128] = "Hello from addon!";
};
static MyPanelState sState;
// Draw callback -- called every frame while the panel is open
static void DrawMyPanel(void* userData)
{
MyPanelState* state = static_cast<MyPanelState*>(userData);
ImGui::Text("My Custom Panel");
ImGui::Separator();
ImGui::SliderFloat("Value", &state->mValue, 0.0f, 1.0f);
ImGui::InputText("Label", state->mText, sizeof(state->mText));
if (ImGui::Button("Reset"))
{
state->mValue = 0.5f;
snprintf(state->mText, sizeof(state->mText), "Hello from addon!");
}
}
// Called by the engine when the addon is loaded
extern "C" void OnLoad(EditorUIHooks* hooks)
{
sHookId = GenerateHookId("com.example.my-panel");
// Register the dockable panel
hooks->RegisterWindow(
sHookId,
"My Panel", // Tab label
"my_panel", // Unique ID
DrawMyPanel,
&sState
);
// Open it immediately (optional)
hooks->OpenWindow("my_panel");
}
// Called by the engine when the addon is unloaded
extern "C" void OnUnload(EditorUIHooks* hooks)
{
hooks->RemoveAllHooks(sHookId);
}
Opening / Closing from a Menu
You can combine RegisterWindow with AddMenuItem to give users a toggle in the View menu:
static void ToggleMyPanel(void* userData)
{
EditorUIHooks* hooks = static_cast<EditorUIHooks*>(userData);
if (hooks->IsWindowOpen("my_panel"))
hooks->CloseWindow("my_panel");
else
hooks->OpenWindow("my_panel");
}
// Inside OnLoad:
hooks->AddMenuItem(sHookId, "View", "My Panel", ToggleMyPanel, hooks, "Ctrl+Shift+P");
Notes
- The panel is rendered inside the dock layout, so users can drag its tab to dock it next to any built-in panel (Scene, Assets, etc.).
- The
windowIdis used internally to track open/close state. Keep it stable across versions. - Call
RemoveAllHooksinOnUnloadto cleanly unregister the panel when your addon is unloaded. - Your draw callback receives the
userDatapointer you passed during registration.