Polyphase Game Engine
Loading...
Searching...
No Matches
EditorUIHooks.h
Go to the documentation of this file.
1#pragma once
2
14#if EDITOR
15
16#include <stdint.h>
17
18// ===== Callback Types =====
19
24typedef void (*MenuCallback)(void* userData);
25
30typedef void (*WindowDrawCallback)(void* userData);
31
37typedef void (*InspectorDrawCallback)(void* node, void* userData);
38
43typedef void (*EventCallback)(void* userData);
44
50typedef void (*StringEventCallback)(const char* str, void* userData);
51
57typedef void (*PlatformEventCallback)(int32_t platform, void* userData);
58
65typedef void (*PackageFinishedCallback)(int32_t platform, bool success, void* userData);
66
72typedef void (*PlayModeCallback)(int32_t state, void* userData);
73
80typedef void (*TopLevelMenuDrawCallback)(void* userData);
81
88typedef void (*ToolbarDrawCallback)(void* userData);
89
95typedef bool (*MenuValidationCallback)(void* userData);
96
102typedef void (*MenuSectionDrawCallback)(void* parentNode, void* userData);
103
112typedef void (*ViewportOverlayCallback)(float viewportX, float viewportY, float viewportW, float viewportH, void* userData);
113
118typedef void (*PreferencesPanelDrawCallback)(void* userData);
119
124typedef void (*PreferencesLoadCallback)(void* userData);
125typedef void (*PreferencesSaveCallback)(void* userData);
126
131typedef void (*ShortcutCallback)(void* userData);
132
141typedef bool (*PropertyDrawCallback)(const char* propertyName, void* propertyOwner, int32_t propertyType, void* userData);
142
152typedef void (*HierarchyItemGUICallback)(void* node, float rowX, float rowY, float rowW, float rowH, void* userData);
153
164typedef void (*AssetItemGUICallback)(const char* assetName, const char* assetType, float rowX, float rowY, float rowW, float rowH, void* userData);
165
172typedef void (*HierarchyChangedCallback)(int32_t changeType, void* node, void* userData);
173
182typedef bool (*DragDropHandlerCallback)(const char* payloadType, const void* payloadData, int32_t payloadSize, void* userData);
183
191typedef bool (*AssetImportCallback)(const char* filePath, const char* extension, void* userData);
192
199typedef bool (*PreImportCallback)(const char* filePath, void* userData);
200
207typedef bool (*PreBuildCallback)(int32_t platform, void* userData);
208
214typedef void (*EditorModeCallback)(int32_t newMode, void* userData);
215
221typedef void (*GizmoToolDrawCallback)(void* selectedNode, void* userData);
222
227typedef void (*PlayTargetCallback)(void* userData);
228
239typedef void (*SceneCreationCallback)(const char* sceneName, void* rootNode, void* userData);
240
241// ===== Controller Server Hooks =====
242
252typedef void (*ControllerRouteCallback)(const char* method, const char* path, const char* body, char* responseBuffer, int32_t bufferSize, void* userData);
253
259typedef void (*ControllerServerEventCallback)(int32_t state, void* userData);
260
267typedef uint64_t HookId;
268
275struct EditorUIHooks
276{
277 // ===== Menu Extensions =====
278
289 void (*AddMenuItem)(
290 HookId hookId,
291 const char* menuPath,
292 const char* itemPath,
293 MenuCallback callback,
294 void* userData,
295 const char* shortcut
296 );
297
304 void (*AddMenuSeparator)(HookId hookId, const char* menuPath);
305
313 void (*RemoveMenuItem)(HookId hookId, const char* menuPath, const char* itemPath);
314
315 // ===== Custom Windows =====
316
326 void (*RegisterWindow)(
327 HookId hookId,
328 const char* windowName,
329 const char* windowId,
330 WindowDrawCallback drawFunc,
331 void* userData
332 );
333
340 void (*UnregisterWindow)(HookId hookId, const char* windowId);
341
346 void (*OpenWindow)(const char* windowId);
347
352 void (*CloseWindow)(const char* windowId);
353
359 bool (*IsWindowOpen)(const char* windowId);
360
361 // ===== Inspector Extensions =====
362
371 void (*RegisterInspector)(
372 HookId hookId,
373 const char* nodeTypeName,
374 InspectorDrawCallback drawFunc,
375 void* userData
376 );
377
384 void (*UnregisterInspector)(HookId hookId, const char* nodeTypeName);
385
386 // ===== Context Menu Extensions =====
387
396 void (*AddNodeContextItem)(
397 HookId hookId,
398 const char* itemPath,
399 MenuCallback callback,
400 void* userData
401 );
402
412 void (*AddAssetContextItem)(
413 HookId hookId,
414 const char* itemPath,
415 const char* assetTypeFilter,
416 MenuCallback callback,
417 void* userData
418 );
419
420 // ===== Top-Level Menus =====
421
433 void (*AddTopLevelMenuItem)(HookId hookId, const char* menuName,
434 TopLevelMenuDrawCallback drawFunc, void* userData);
435
441 void (*RemoveTopLevelMenuItem)(HookId hookId, const char* menuName);
442
443 // ===== Toolbar =====
444
452 void (*AddToolbarItem)(HookId hookId, const char* itemName,
453 ToolbarDrawCallback drawFunc, void* userData);
454
460 void (*RemoveToolbarItem)(HookId hookId, const char* itemName);
461
462 // ===== Project Lifecycle Events =====
463
465 void (*RegisterOnProjectOpen)(HookId hookId, StringEventCallback cb, void* userData);
466
468 void (*RegisterOnProjectClose)(HookId hookId, StringEventCallback cb, void* userData);
469
471 void (*RegisterOnProjectSave)(HookId hookId, StringEventCallback cb, void* userData);
472
473 // ===== Scene Lifecycle Events =====
474
476 void (*RegisterOnSceneOpen)(HookId hookId, StringEventCallback cb, void* userData);
477
479 void (*RegisterOnSceneClose)(HookId hookId, StringEventCallback cb, void* userData);
480
481 // ===== Packaging/Build Events =====
482
484 void (*RegisterOnPackageStarted)(HookId hookId, PlatformEventCallback cb, void* userData);
485
487 void (*RegisterOnPackageFinished)(HookId hookId, PackageFinishedCallback cb, void* userData);
488
489 // ===== Editor State Events =====
490
492 void (*RegisterOnSelectionChanged)(HookId hookId, EventCallback cb, void* userData);
493
495 void (*RegisterOnPlayModeChanged)(HookId hookId, PlayModeCallback cb, void* userData);
496
498 void (*RegisterOnEditorShutdown)(HookId hookId, EventCallback cb, void* userData);
499
500 // ===== Asset Pipeline Events =====
501
503 void (*RegisterOnAssetImported)(HookId hookId, StringEventCallback cb, void* userData);
504
506 void (*RegisterOnAssetDeleted)(HookId hookId, StringEventCallback cb, void* userData);
507
509 void (*RegisterOnAssetSaved)(HookId hookId, StringEventCallback cb, void* userData);
510
511 // ===== Asset Open Events =====
512
514 void (*RegisterOnAssetOpen)(HookId hookId, StringEventCallback cb, void* userData);
515
517 void (*RegisterOnAssetOpened)(HookId hookId, StringEventCallback cb, void* userData);
518
519 // ===== Undo/Redo =====
520
522 void (*RegisterOnUndoRedo)(HookId hookId, EventCallback cb, void* userData);
523
524 // ===== Drag-and-Drop Events =====
525
527 void (*RegisterOnAssetDropHierarchy)(HookId hookId, StringEventCallback cb, void* userData);
528
530 void (*RegisterOnAssetDropViewport)(HookId hookId, StringEventCallback cb, void* userData);
531
532 // ===== Batch 1: Menu Positioning & Top-Level Menu Control =====
533
542 void (*AddTopLevelMenuItemEx)(
543 HookId hookId,
544 const char* menuName,
545 TopLevelMenuDrawCallback drawFunc,
546 void* userData,
547 int32_t position
548 );
549
560 void (*AddMenuItemEx)(
561 HookId hookId,
562 const char* menuPath,
563 const char* itemPath,
564 MenuCallback callback,
565 void* userData,
566 const char* shortcut,
567 MenuValidationCallback validateFunc
568 );
569
570 // ===== Batch 2: Create/Spawn Menu Extensions =====
571
579 void (*AddNodeMenuItems)(HookId hookId, const char* category, MenuSectionDrawCallback drawFunc, void* userData);
580
582 void (*RemoveNodeMenuItems)(HookId hookId, const char* category);
583
590 void (*AddCreateAssetItems)(HookId hookId, MenuSectionDrawCallback drawFunc, void* userData);
591
593 void (*RemoveCreateAssetItems)(HookId hookId);
594
601 void (*AddSpawnBasic3dItems)(HookId hookId, MenuSectionDrawCallback drawFunc, void* userData);
602
609 void (*AddSpawnBasicWidgetItems)(HookId hookId, MenuSectionDrawCallback drawFunc, void* userData);
610
611 // ===== Scene Type Registration =====
612
624 void (*RegisterSceneType)(HookId hookId, const char* typeName, SceneCreationCallback createFunc, void* userData);
625
627 void (*UnregisterSceneType)(HookId hookId, const char* typeName);
628
629 // ===== Batch 3: Viewport Context Menu & Overlay Drawing =====
630
638 void (*AddViewportContextItem)(HookId hookId, const char* itemPath, MenuCallback callback, void* userData);
639
641 void (*RemoveViewportContextItem)(HookId hookId, const char* itemPath);
642
650 void (*RegisterViewportOverlay)(HookId hookId, const char* overlayName, ViewportOverlayCallback drawFunc, void* userData);
651
653 void (*UnregisterViewportOverlay)(HookId hookId, const char* overlayName);
654
655 // ===== Batch 4: Custom Preferences/Settings Pages =====
656
667 void (*RegisterPreferencesPanel)(
668 HookId hookId,
669 const char* panelName,
670 const char* panelCategory,
671 PreferencesPanelDrawCallback drawFunc,
672 PreferencesLoadCallback loadFunc,
673 PreferencesSaveCallback saveFunc,
674 void* userData
675 );
676
678 void (*UnregisterPreferencesPanel)(HookId hookId, const char* panelName);
679
680 // ===== Batch 5: Custom Keyboard Shortcuts =====
681
691 void (*RegisterShortcut)(
692 HookId hookId,
693 const char* shortcutId,
694 const char* displayName,
695 const char* defaultBinding,
696 ShortcutCallback callback,
697 void* userData
698 );
699
701 void (*UnregisterShortcut)(HookId hookId, const char* shortcutId);
702
703 // ===== Batch 6: Property Drawer System =====
704
712 void (*RegisterPropertyDrawer)(HookId hookId, const char* propertyTypeName, PropertyDrawCallback drawFunc, void* userData);
713
715 void (*UnregisterPropertyDrawer)(HookId hookId, const char* propertyTypeName);
716
717 // ===== Batch 7: Hierarchy & Asset Browser Extensions =====
718
723 void (*RegisterHierarchyItemGUI)(HookId hookId, HierarchyItemGUICallback drawFunc, void* userData);
724
726 void (*UnregisterHierarchyItemGUI)(HookId hookId);
727
732 void (*RegisterAssetItemGUI)(HookId hookId, AssetItemGUICallback drawFunc, void* userData);
733
735 void (*UnregisterAssetItemGUI)(HookId hookId);
736
741 void (*RegisterOnHierarchyChanged)(HookId hookId, HierarchyChangedCallback cb, void* userData);
742
743 // ===== Batch 8: Additional Context Menus =====
744
746 void (*AddSceneTabContextItem)(HookId hookId, const char* itemPath, MenuCallback callback, void* userData);
747
749 void (*AddDebugLogContextItem)(HookId hookId, const char* itemPath, MenuCallback callback, void* userData);
750
752 void (*AddImportMenuItem)(HookId hookId, const char* itemPath, MenuCallback callback, void* userData);
753
755 void (*AddAddonsMenuItem)(HookId hookId, const char* itemPath, MenuCallback callback, void* userData);
756
765 void (*AddPlayTarget)(HookId hookId, const char* targetName, const char* iconText, PlayTargetCallback callback, void* userData);
766
768 void (*RemovePlayTarget)(HookId hookId, const char* targetName);
769
770 // ===== Batch 9: Drag-Drop Enhancement & Asset Pipeline =====
771
779 void (*RegisterDragDropHandler)(HookId hookId, const char* targetArea, DragDropHandlerCallback handler, void* userData);
780
788 void (*RegisterAssetImporter)(HookId hookId, const char* extension, AssetImportCallback importFunc, void* userData);
789
791 void (*UnregisterAssetImporter)(HookId hookId, const char* extension);
792
794 void (*RegisterOnPreAssetImport)(HookId hookId, PreImportCallback cb, void* userData);
795
797 void (*RegisterOnPostAssetImport)(HookId hookId, StringEventCallback cb, void* userData);
798
799 // ===== Batch 10: Build Pipeline & Editor State =====
800
802 void (*RegisterOnPreBuild)(HookId hookId, PreBuildCallback cb, void* userData);
803
805 void (*RegisterOnPostBuild)(HookId hookId, PackageFinishedCallback cb, void* userData);
806
808 void (*RegisterOnEditorModeChanged)(HookId hookId, EditorModeCallback cb, void* userData);
809
819 void (*RegisterGizmoTool)(
820 HookId hookId,
821 const char* toolName,
822 const char* iconText,
823 const char* tooltip,
824 GizmoToolDrawCallback drawFunc,
825 void* userData
826 );
827
829 void (*UnregisterGizmoTool)(HookId hookId, const char* toolName);
830
831 // ===== Game Preview Resolution Presets =====
832
840 void (*AddGamePreviewResolution)(HookId hookId, const char* name, uint32_t width, uint32_t height);
841
847 void (*RemoveGamePreviewResolution)(HookId hookId, const char* name);
848
849 // ===== Controller Server Extension =====
850
859 void (*RegisterControllerRoute)(HookId hookId, const char* method, const char* path, ControllerRouteCallback callback, void* userData);
860
866 void (*UnregisterControllerRoute)(HookId hookId, const char* path);
867
874 void (*RegisterOnControllerServerStateChanged)(HookId hookId, ControllerServerEventCallback callback, void* userData);
875
876 // ===== Profiling Window Extension =====
877
886 void (*RegisterProfilingStat)(HookId hookId, const char* statName, const char* category, float maxValue, bool showAsBar);
887
893 void (*UnregisterProfilingStat)(HookId hookId, const char* statName);
894
901 void (*SetProfilingStatValue)(const char* statName, float value);
902
907 typedef void (*ProfilingSectionDrawCallback)(void* userData);
908
917 void (*RegisterProfilingSection)(HookId hookId, const char* sectionName, void (*drawFunc)(void*), void* userData);
918
924 void (*UnregisterProfilingSection)(HookId hookId, const char* sectionName);
925
926 // ===== Cleanup =====
927
935 void (*RemoveAllHooks)(HookId hookId);
936
937 // ===== Late additions (appended to preserve ABI) ====================
938 //
939 // New function pointers must go AT THE END of this struct so prebuilt
940 // plugins compiled against older headers keep finding existing hooks
941 // at their original offsets. Plugin loaders must check each function
942 // pointer for nullptr before calling it — older engine binaries will
943 // leave fields they don't know about as nullptr.
944
969 void (*AddCreateAssetItem)(HookId hookId, const char* itemPath,
970 MenuCallback callback, void* userData);
971
972 // ===== Batch 11: Build Targets =====
973 //
974 // Lets an addon register an entire build/packaging target — compile,
975 // cook, finalize, run. See PolyphaseBuildTargetAPI.h for the descriptor
976 // shape. The descriptor is deep-copied; the addon may free its source
977 // strings immediately after this returns. The registration is scoped to
978 // hookId and is automatically cleared by RemoveAllHooks(hookId), so
979 // hot-reload is safe.
980 //
981 // Registering twice with the same targetId replaces the previous entry;
982 // this is what makes addon hot-reload swap in fresh function pointers
983 // without leaving stale ones in the registry.
984
986 void (*RegisterBuildTarget)(HookId hookId, const struct PolyphaseBuildTargetDesc* desc);
987
989 void (*UnregisterBuildTarget)(HookId hookId, const char* targetId);
990
991 // ===== Batch 12: Viewport input polling for addons =====
992 //
993 // Poll-style helpers for tools (e.g. Level Builder) that want to react
994 // to mouse hover and clicks inside the 3D viewport. There is no HookId
995 // because nothing is allocated — old engines simply leave these fields
996 // null and addons must null-check before calling.
997 //
998 // Both calls are intended to be invoked from inside a
999 // RegisterViewportOverlay callback (which fires mid-frame with the
1000 // viewport rect already laid out).
1001 //
1002 // Screen coordinates are unscaled ImGui pixels (i.e. ImGui::GetIO().MousePos);
1003 // the implementation multiplies by EngineConfig::mEditorInterfaceScale
1004 // internally to match Renderer pixel space.
1005
1025 bool (*Viewport_RaycastUnderMouse)(float screenX, float screenY,
1026 float fallbackPlaneY,
1027 float* outHitX, float* outHitY, float* outHitZ,
1028 float* outNormalX, float* outNormalY, float* outNormalZ,
1029 void** outHitNode);
1030
1040 void (*Viewport_GetMouseState)(float* outViewportX, float* outViewportY,
1041 float* outViewportW, float* outViewportH,
1042 float* outMouseX, float* outMouseY,
1043 int* outHovered, int* outLeftClicked,
1044 int* outLeftDown, int* outRightClicked);
1045
1046 // ===== Batch 13: Selection control (additive — safe for older addons) =====
1047
1064 void (*Viewport_SuppressNextSelectionClick)();
1065
1076 void (*Selection_Clear)();
1077
1078 // ===== Batch 14: File dialogs + OS file-drop dispatch ==================
1079 //
1080 // Thin wrappers over the existing SYS_OpenFileDialog / SYS_SaveFileDialog
1081 // / SYS_SelectFolderDialog calls + the SYS_DrainDroppedFiles polling
1082 // mechanism, exposed so plugins (Level Builder share UI, asset importers,
1083 // settings panels) don't have to vendor their own platform code.
1084 //
1085 // All dialogs are SYNCHRONOUS — the call blocks until the user picks or
1086 // cancels. UI threads call them from a button click; no callback needed.
1087 // The file-drop hook IS callback-based since drops can land any frame.
1088
1104 int (*ShowOpenFileDialog)(const char* title,
1105 const char* filter,
1106 const char* initialDir,
1107 char* outPath, int outPathSize);
1108
1120 int (*ShowSaveFileDialog)(const char* title,
1121 const char* filter,
1122 const char* defaultName,
1123 char* outPath, int outPathSize);
1124
1134 int (*ShowSelectFolderDialog)(const char* title,
1135 char* outPath, int outPathSize);
1136
1149 typedef bool (*FileDropCallback)(int count, const char** paths, void* userData);
1150 void (*RegisterFileDropHandler)(HookId hookId, FileDropCallback cb, void* userData);
1151 void (*UnregisterFileDropHandler)(HookId hookId);
1152
1153 // ===== Batch 15: Viewport Mode dropdown ============================
1154 //
1155 // Lets a native addon contribute a new entry to the top-of-editor mode
1156 // dropdown (Scene / 2D / 3D / Paint Colors / Paint Instances / Voxel /
1157 // Terrain / Tile Paint). When the user picks an addon mode the editor:
1158 // - switches EditorMode to Scene3D (and clears any built-in PaintMode)
1159 // - records the active addon mode id on EditorState
1160 // - fires OnActivate(userData)
1161 // Switching to a built-in entry (or another addon entry) fires
1162 // OnDeactivate(userData) on the previously-active addon mode first.
1163 //
1164 // While the addon mode is active the engine calls:
1165 // - Tick(deltaTime, userData) every frame inside the viewport update
1166 // - DrawPanel(userData) every frame in the mode-properties strip
1167 //
1168 // Hot-reload safety: re-registering with the same modeId replaces the
1169 // entry's callbacks (so a freshly reloaded DLL's function pointers
1170 // overwrite the stale ones). RemoveAllHooks(hookId) deactivates the
1171 // mode first if it's currently active, then erases the registration.
1172 //
1173 // All callbacks are optional — pass nullptr to skip. CanActivate is a
1174 // gating check: if it returns false the dropdown entry greys out and
1175 // the editor refuses to switch into the mode. Null CanActivate = always
1176 // available.
1177
1182 typedef bool (*ViewportModeCanActivateCallback)(void* userData);
1183
1185 typedef void (*ViewportModeActivateCallback)(void* userData);
1186
1188 typedef void (*ViewportModeDeactivateCallback)(void* userData);
1189
1191 typedef void (*ViewportModeTickCallback)(float deltaTime, void* userData);
1192
1194 typedef void (*ViewportModeDrawPanelCallback)(void* userData);
1195
1212 void (*AddViewportMode)(
1213 HookId hookId,
1214 const char* modeId,
1215 const char* displayName,
1216 int32_t sortOrder,
1217 ViewportModeCanActivateCallback canActivate,
1218 ViewportModeActivateCallback onActivate,
1219 ViewportModeDeactivateCallback onDeactivate,
1220 ViewportModeTickCallback tick,
1221 ViewportModeDrawPanelCallback drawPanel,
1222 void* userData
1223 );
1224
1232 void (*RemoveViewportMode)(HookId hookId, const char* modeId);
1233
1242 int (*GetActiveViewportMode)(char* outBuffer, int outBufferSize);
1243
1244 // ===== Batch 15 / v8: viewport math for plugin gizmos ==================
1245 //
1246 // Mouse → world ray. `mx`/`my` are window-space pixels (same units
1247 // Viewport_GetMouseState returns). `outOrigin` is the ray's starting
1248 // point in world space; `outDir` is the normalized direction.
1249 //
1250 // Used by plugins that need to roll their own scene intersection —
1251 // axis-constrained transform gizmos, arbitrary plane intersection,
1252 // line-to-line distance for rotation rings, etc. The simpler
1253 // Viewport_RaycastUnderMouse stays for the common "give me the
1254 // hit point on the scene OR a fallback Y plane" case.
1255 void (*Viewport_GetMouseWorldRay)(float mx, float my,
1256 float* outOriginX,
1257 float* outOriginY,
1258 float* outOriginZ,
1259 float* outDirX,
1260 float* outDirY,
1261 float* outDirZ);
1262
1263 // World → editor-viewport screen pixels. Returns 1 if the point
1264 // projects in front of the camera (sx/sy are usable window-space
1265 // coords); returns 0 if behind (sx/sy still filled but the caller
1266 // probably wants to skip drawing). The output coordinate system
1267 // matches Viewport_GetMouseState — i.e. the same window-space
1268 // pixels you'd hover-test against.
1269 //
1270 // Used by plugins that want to overlay ImGui labels / billboards
1271 // on top of scene objects (e.g. "Socket: Left" text floating
1272 // over the socket gizmo).
1273 int (*Viewport_WorldToScreen)(float wx, float wy, float wz,
1274 float* outSx, float* outSy);
1275};
1276
1286HookId GenerateHookId(const char* identifier);
1287
1288#endif // EDITOR