From ef41c4446472a34740d32daef4aa89ea92b2dcb5 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sat, 25 Apr 2026 16:46:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=B3=E9=94=AE=E8=8A=82=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 5 +- {new_editor => editor}/CMakeLists.txt | 61 +- .../app/Bootstrap/Application.cpp | 83 +- .../app/Bootstrap/Application.h | 6 +- .../app/Bootstrap/EditorApp.rc | 0 .../app/Bootstrap/EditorResources.h | 0 .../app/Commands/EditorEditCommandRoute.h | 0 .../app/Commands/EditorHostCommandBridge.cpp | 0 .../app/Commands/EditorHostCommandBridge.h | 0 .../app/Composition/EditorContext.cpp | 20 +- .../app/Composition/EditorContext.h | 13 +- .../app/Composition/EditorPanelIds.h | 0 .../Composition/EditorShellAssetBuilder.cpp | 2 +- .../app/Composition/EditorShellAssetBuilder.h | 0 .../Composition/EditorShellDrawComposer.cpp | 0 .../app/Composition/EditorShellDrawComposer.h | 0 .../EditorShellHostedPanelCoordinator.cpp | 5 - .../EditorShellHostedPanelCoordinator.h | 8 - .../EditorShellInteractionEngine.cpp | 0 .../EditorShellInteractionEngine.h | 0 .../app/Composition/EditorShellRuntime.cpp | 13 +- .../app/Composition/EditorShellRuntime.h | 14 +- .../EditorShellSessionCoordinator.cpp | 0 .../EditorShellSessionCoordinator.h | 0 .../app/Composition/EditorShellVariant.h | 0 .../EditorWindowWorkspaceStore.cpp | 0 .../Composition/EditorWindowWorkspaceStore.h | 2 +- .../app/Composition/WorkspaceEventSync.cpp | 0 .../app/Composition/WorkspaceEventSync.h | 0 .../Features/ColorPicker/ColorPickerPanel.cpp | 46 +- .../Features/ColorPicker/ColorPickerPanel.h | 11 +- .../app/Features/Console/ConsolePanel.cpp | 0 .../app/Features/Console/ConsolePanel.h | 0 .../app/Features/Hierarchy/HierarchyModel.cpp | 0 .../app/Features/Hierarchy/HierarchyModel.h | 0 .../app/Features/Hierarchy/HierarchyPanel.cpp | 0 .../app/Features/Hierarchy/HierarchyPanel.h | 0 .../Features/Inspector/AddComponentPanel.cpp | 66 +- .../Features/Inspector/AddComponentPanel.h | 16 +- .../AudioListenerInspectorComponentEditor.h | 0 .../AudioSourceInspectorComponentEditor.h | 0 .../BoxColliderInspectorComponentEditor.h | 0 .../CameraInspectorComponentEditor.h | 0 .../CapsuleColliderInspectorComponentEditor.h | 0 .../ColliderInspectorComponentEditorUtils.h | 0 .../Components/IInspectorComponentEditor.h | 0 .../InspectorBindingComponentEditor.cpp | 0 .../InspectorBindingComponentEditor.h | 0 .../InspectorComponentEditorRegistry.cpp | 0 .../InspectorComponentEditorRegistry.h | 0 .../InspectorComponentEditorUtils.h | 0 .../LightInspectorComponentEditor.h | 0 .../MeshFilterInspectorComponentEditor.h | 0 .../MeshRendererInspectorComponentEditor.h | 0 .../RigidbodyInspectorComponentEditor.h | 0 .../SphereColliderInspectorComponentEditor.h | 0 .../TransformInspectorComponentEditor.cpp | 0 .../TransformInspectorComponentEditor.h | 0 .../VolumeRendererInspectorComponentEditor.h | 0 .../app/Features/Inspector/InspectorPanel.cpp | 120 +- .../app/Features/Inspector/InspectorPanel.h | 38 +- .../Inspector/InspectorPresentationModel.cpp | 0 .../Inspector/InspectorPresentationModel.h | 0 .../Features/Inspector/InspectorSubject.cpp | 0 .../app/Features/Inspector/InspectorSubject.h | 0 .../Features/Project/ProjectBrowserModel.cpp | 0 .../Features/Project/ProjectBrowserModel.h | 0 .../app/Features/Project/ProjectPanel.cpp | 2 +- .../app/Features/Project/ProjectPanel.h | 0 .../Features/Scene/SceneEditCommandRoute.cpp | 0 .../Features/Scene/SceneEditCommandRoute.h | 0 .../Scene/SceneViewportController.cpp | 0 .../Features/Scene/SceneViewportController.h | 0 .../Features/Scene/SceneViewportFeature.cpp | 0 .../app/Features/Scene/SceneViewportFeature.h | 0 .../Scene/SceneViewportSceneOverlay.cpp | 0 .../Scene/SceneViewportSceneOverlay.h | 0 .../Scene/SceneViewportToolOverlay.cpp | 2 +- .../Features/Scene/SceneViewportToolOverlay.h | 0 .../Scene/SceneViewportTransformGizmo.cpp | 0 .../Scene/SceneViewportTransformGizmo.h | 0 .../SceneViewportTransformGizmoSupport.cpp | 0 .../SceneViewportTransformGizmoSupport.h | 0 .../Win32/Chrome/BorderlessWindowChrome.cpp | 0 .../Win32/Chrome/BorderlessWindowChrome.h | 0 .../Win32/Chrome/BorderlessWindowFrame.cpp | 0 .../Win32/Chrome/BorderlessWindowFrame.h | 0 .../Chrome/EditorWindowChromeController.cpp | 542 +++---- .../Chrome/EditorWindowChromeController.h | 119 +- .../Platform/Win32/Chrome/HostRuntimeState.h | 88 ++ .../EditorUtilityWindowContentController.cpp | 103 ++ .../EditorUtilityWindowContentController.h | 44 + .../Content/EditorWindowContentController.h | 163 +++ ...EditorWorkspaceWindowContentController.cpp | 198 +++ .../EditorWorkspaceWindowContentController.h | 79 + .../Win32/Runtime/EditorWindowFrameDriver.cpp | 46 + .../Win32/Runtime/EditorWindowFrameDriver.h | 29 + .../EditorWindowFrameOrchestrator.cpp | 176 +-- .../Runtime}/EditorWindowFrameOrchestrator.h | 27 +- .../Runtime/EditorWindowInputController.cpp | 51 +- .../Runtime/EditorWindowInputController.h | 14 +- .../Runtime/EditorWindowRuntimeController.cpp | 402 ++++++ .../Runtime/EditorWindowRuntimeController.h | 82 +- .../EditorWindowScreenshotController.cpp | 0 .../EditorWindowScreenshotController.h | 0 .../Win32/Runtime/InputModifierTracker.h | 0 .../System/Win32SystemInteractionHost.cpp | 0 .../Win32/System/Win32SystemInteractionHost.h | 0 .../EditorFloatingWindowPlacement.cpp | 46 + .../Windowing/EditorFloatingWindowPlacement.h | 18 + .../EditorUtilityWindowCoordinator.cpp | 150 ++ .../EditorUtilityWindowCoordinator.h | 34 + .../Platform/Win32/Windowing/EditorWindow.cpp | 900 ++++++++++++ .../Platform/Win32/Windowing/EditorWindow.h | 192 +++ .../Windowing/EditorWindowHostRuntime.cpp | 286 ++++ .../Win32/Windowing/EditorWindowHostRuntime.h | 87 ++ .../EditorWindowLifecycleCoordinator.cpp | 248 ++++ .../EditorWindowLifecycleCoordinator.h | 33 + .../Win32/Windowing/EditorWindowManager.cpp | 124 ++ .../Win32/Windowing/EditorWindowManager.h | 101 ++ .../EditorWindowMessageDispatcher.cpp | 585 ++++++++ .../Windowing/EditorWindowMessageDispatcher.h | 79 + .../Windowing/EditorWindowPointerCapture.h | 0 .../Win32/Windowing/EditorWindowSession.cpp | 126 ++ .../Win32/Windowing/EditorWindowSession.h | 47 + .../Win32/Windowing/EditorWindowState.h | 36 - .../Win32/Windowing/EditorWindowSupport.h | 24 +- .../Windowing/EditorWindowTransferRequests.h | 48 + .../EditorWindowWorkspaceCoordinator.cpp | 843 +++++++++++ .../EditorWindowWorkspaceCoordinator.h | 108 ++ .../app/Project/EditorProjectRuntime.cpp | 0 .../app/Project/EditorProjectRuntime.h | 0 .../app/Rendering/Assets/BuiltInIcons.cpp | 0 .../app/Rendering/Assets/BuiltInIcons.h | 0 .../app/Rendering/D3D12/D3D12HostDevice.cpp | 136 +- .../app/Rendering/D3D12/D3D12HostDevice.h | 6 +- ...D3D12ShaderResourceDescriptorAllocator.cpp | 0 .../D3D12ShaderResourceDescriptorAllocator.h | 0 .../app/Rendering/D3D12/D3D12UiRenderer.cpp | 0 .../app/Rendering/D3D12/D3D12UiRenderer.h | 0 .../app/Rendering/D3D12/D3D12UiTextSystem.cpp | 0 .../app/Rendering/D3D12/D3D12UiTextSystem.h | 0 .../Rendering/D3D12/D3D12UiTextureHost.cpp | 0 .../app/Rendering/D3D12/D3D12UiTextureHost.h | 0 .../Rendering/D3D12/D3D12WindowCapture.cpp | 0 .../app/Rendering/D3D12/D3D12WindowCapture.h | 0 .../Rendering/D3D12/D3D12WindowRenderLoop.cpp | 0 .../Rendering/D3D12/D3D12WindowRenderLoop.h | 0 .../Rendering/D3D12/D3D12WindowRenderer.cpp | 0 .../app/Rendering/D3D12/D3D12WindowRenderer.h | 0 .../D3D12/D3D12WindowSwapChainPresenter.cpp | 5 +- .../D3D12/D3D12WindowSwapChainPresenter.h | 0 .../app/Rendering/Host/HostFwd.h | 0 .../app/Rendering/Host/UiTextureHost.h | 0 .../app/Rendering/Host/ViewportRenderHost.h | 0 .../Viewport/Passes/SceneViewportGridPass.cpp | 0 .../Viewport/Passes/SceneViewportGridPass.h | 0 .../SceneViewportSelectedHelpersPass.cpp | 0 .../Passes/SceneViewportSelectedHelpersPass.h | 0 .../SceneViewportSelectionOutlinePass.cpp | 0 .../SceneViewportSelectionOutlinePass.h | 0 .../Viewport/SceneViewportPassSpecs.h | 0 .../SceneViewportRenderPassBundle.cpp | 0 .../Viewport/SceneViewportRenderPassBundle.h | 0 .../Viewport/SceneViewportRenderPlan.h | 0 .../Viewport/SceneViewportRenderRequest.h | 0 .../Viewport/SceneViewportRenderService.cpp | 0 .../Viewport/SceneViewportRenderService.h | 0 .../Viewport/SceneViewportResourcePaths.h | 2 +- .../Viewport/ViewportContentRenderer.h | 0 .../Viewport/ViewportHostService.cpp | 0 .../Rendering/Viewport/ViewportHostService.h | 0 .../Viewport/ViewportObjectIdPicker.h | 0 .../Viewport/ViewportObjectPickerService.h | 0 .../Viewport/ViewportRenderTargetUtils.cpp | 0 .../Viewport/ViewportRenderTargetUtils.h | 0 .../Viewport/ViewportRenderTargets.cpp | 0 .../Viewport/ViewportRenderTargets.h | 0 .../app/Rendering/Viewport/ViewportTypes.h | 0 .../app/Scene/EditorSceneBridge.cpp | 0 .../app/Scene/EditorSceneBridge.h | 0 .../app/Scene/EditorSceneRuntime.cpp | 19 +- .../app/Scene/EditorSceneRuntime.h | 6 +- .../app/Scene/SceneToolState.h | 0 .../app/Scene/SceneViewportCameraController.h | 0 .../app/State/EditorColorPickerToolState.cpp | 59 + editor/app/State/EditorColorPickerToolState.h | 39 + .../app/State/EditorCommandFocusService.h | 0 .../app/State/EditorSelectionService.h | 0 .../app/State/EditorSelectionStamp.h | 0 .../app/State/EditorSession.cpp | 0 .../app/State/EditorSession.h | 0 .../State/EditorUtilityWindowRequestState.cpp | 26 + .../State/EditorUtilityWindowRequestState.h | 20 + .../app/Support/EmbeddedPngLoader.cpp | 0 .../app/Support/EmbeddedPngLoader.h | 0 .../app/Support/EnvironmentFlags.h | 0 .../app/Support/ExecutablePath.h | 0 .../app/Support/StringEncoding.h | 0 .../app/Support/TextFormat.h | 0 .../app/System/SystemInteractionService.h | 0 .../UtilityWindows/EditorUtilityWindowKind.h | 2 +- .../UtilityWindows/EditorUtilityWindowPanel.h | 34 + .../EditorUtilityWindowRegistry.cpp | 56 + .../EditorUtilityWindowRegistry.h | 27 + {new_editor => editor}/app/main.cpp | 0 .../Collections/UIEditorDragDropInteraction.h | 0 .../Collections/UIEditorFilterableTreeHost.h | 0 .../Collections/UIEditorGridDragDrop.h | 0 .../Collections/UIEditorInlineRenameSession.h | 0 .../XCEditor/Collections/UIEditorListView.h | 0 .../Collections/UIEditorListViewInteraction.h | 0 .../XCEditor/Collections/UIEditorScrollView.h | 0 .../UIEditorScrollViewInteraction.h | 0 .../XCEditor/Collections/UIEditorTabStrip.h | 0 .../Collections/UIEditorTabStripInteraction.h | 0 .../Collections/UIEditorTreeDragDrop.h | 0 .../XCEditor/Collections/UIEditorTreeView.h | 0 .../Collections/UIEditorTreeViewInteraction.h | 0 .../XCEditor/Docking/UIEditorDockHost.h | 0 .../Docking/UIEditorDockHostInteraction.h | 0 .../Docking/UIEditorDockHostTransfer.h | 0 .../XCEditor/Fields/UIEditorAssetField.h | 0 .../Fields/UIEditorAssetFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorBoolField.h | 0 .../Fields/UIEditorBoolFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorColorField.h | 0 .../Fields/UIEditorColorFieldInteraction.h | 0 .../Fields/UIEditorEditableFieldCore.h | 0 .../XCEditor/Fields/UIEditorEnumField.h | 0 .../Fields/UIEditorEnumFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorFieldStyle.h | 0 .../XCEditor/Fields/UIEditorNumberField.h | 0 .../Fields/UIEditorNumberFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorObjectField.h | 0 .../Fields/UIEditorObjectFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorPropertyGrid.h | 0 .../Fields/UIEditorPropertyGridInteraction.h | 0 .../XCEditor/Fields/UIEditorTextField.h | 0 .../Fields/UIEditorTextFieldInteraction.h | 0 .../XCEditor/Fields/UIEditorVector2Field.h | 0 .../Fields/UIEditorVector2FieldInteraction.h | 0 .../XCEditor/Fields/UIEditorVector3Field.h | 0 .../Fields/UIEditorVector3FieldInteraction.h | 0 .../XCEditor/Fields/UIEditorVector4Field.h | 0 .../Fields/UIEditorVector4FieldInteraction.h | 0 .../Foundation/UIEditorCommandDispatcher.h | 0 .../Foundation/UIEditorCommandRegistry.h | 0 .../Foundation/UIEditorPanelInputFilter.h | 0 .../Foundation/UIEditorRuntimeTrace.h | 0 .../Foundation/UIEditorShortcutManager.h | 0 .../XCEditor/Foundation/UIEditorTextLayout.h | 0 .../Foundation/UIEditorTextMeasurement.h | 0 .../XCEditor/Foundation/UIEditorTheme.h | 0 .../include/XCEditor/Menu/UIEditorMenuBar.h | 0 .../include/XCEditor/Menu/UIEditorMenuModel.h | 0 .../include/XCEditor/Menu/UIEditorMenuPopup.h | 0 .../XCEditor/Menu/UIEditorMenuSession.h | 0 .../Panels/UIEditorHostedPanelDispatch.h | 0 .../Panels/UIEditorPanelContentHost.h | 0 .../XCEditor/Panels/UIEditorPanelFrame.h | 0 .../Panels/UIEditorPanelHostLifecycle.h | 0 .../XCEditor/Panels/UIEditorPanelRegistry.h | 0 .../XCEditor/Shell/UIEditorShellAsset.h | 0 .../Shell/UIEditorShellCapturePolicy.h | 0 .../XCEditor/Shell/UIEditorShellCompose.h | 0 .../XCEditor/Shell/UIEditorShellInteraction.h | 0 .../XCEditor/Shell/UIEditorStatusBar.h | 0 .../XCEditor/Shell/UIEditorStructuredShell.h | 0 .../Viewport/UIEditorViewportInputBridge.h | 0 .../XCEditor/Viewport/UIEditorViewportShell.h | 0 .../XCEditor/Viewport/UIEditorViewportSlot.h | 0 .../Widgets/UIEditorCollectionPrimitives.h | 0 .../XCEditor/Widgets/UIEditorColorUtils.h | 0 .../XCEditor/Widgets/UIEditorFieldRowLayout.h | 0 .../XCEditor/Widgets/UIEditorTextLayout.h | 0 .../Workspace/UIEditorDetachedWindowPolicy.h | 0 .../UIEditorWindowWorkspaceController.h | 2 +- .../Workspace/UIEditorWindowWorkspaceModel.h | 0 .../Workspace/UIEditorWorkspaceCompose.h | 0 .../Workspace/UIEditorWorkspaceController.h | 0 .../Workspace/UIEditorWorkspaceInputOwner.h | 0 .../Workspace/UIEditorWorkspaceInteraction.h | 0 .../UIEditorWorkspaceLayoutPersistence.h | 0 .../Workspace/UIEditorWorkspaceModel.h | 0 .../Workspace/UIEditorWorkspaceMutation.h | 0 .../Workspace/UIEditorWorkspaceQueries.h | 0 .../Workspace/UIEditorWorkspaceSession.h | 0 .../UIEditorWorkspaceSplitterDragCorrection.h | 0 .../Workspace/UIEditorWorkspaceTransfer.h | 0 .../Workspace/UIEditorWorkspaceValidation.h | 0 .../resources/Icons/camera_gizmo.png | Bin .../Icons/directional_light_gizmo.png | Bin .../resources/Icons/folder_icon.png | Bin .../resources/Icons/gameobject_icon.png | Bin .../resources/Icons/logo.ico | Bin .../resources/Icons/logo.png | Bin .../resources/Icons/logo_icon.ico | Bin .../resources/Icons/logo_icon.png | Bin .../resources/Icons/move_tool.png | Bin .../resources/Icons/move_tool_on.png | Bin .../resources/Icons/pause_button.png | Bin .../resources/Icons/play_button.png | Bin .../resources/Icons/point_light_gizmo.png | Bin .../resources/Icons/rotate_tool.png | Bin .../resources/Icons/rotate_tool_on.png | Bin .../resources/Icons/scale_tool.png | Bin .../resources/Icons/scale_tool_on.png | Bin .../resources/Icons/scene_icon.png | Bin .../resources/Icons/spot_light_gizmo.png | Bin .../resources/Icons/step_button.png | Bin .../resources/Icons/transform_tool.png | Bin .../resources/Icons/transform_tool_on.png | Bin .../resources/Icons/view_move_tool.png | Bin .../resources/Icons/view_move_tool_on.png | Bin .../infinite-grid/infinite-grid.shader | 0 .../selection-mask/selection-mask.shader | 0 .../selection-outline.shader | 0 .../UIEditorFilterableTreeHost.cpp | 0 .../UIEditorInlineRenameSession.cpp | 0 .../src/Collections/UIEditorListView.cpp | 0 .../UIEditorListViewInteraction.cpp | 0 .../src/Collections/UIEditorScrollView.cpp | 0 .../UIEditorScrollViewInteraction.cpp | 0 .../src/Collections/UIEditorTabStrip.cpp | 0 .../UIEditorTabStripInteraction.cpp | 0 .../src/Collections/UIEditorTreeView.cpp | 0 .../UIEditorTreeViewInteraction.cpp | 0 .../src/Docking/DockHostHitTest.cpp | 0 .../Docking/DockHostInteractionHelpers.cpp | 0 .../src/Docking/DockHostInteractionInternal.h | 0 .../src/Docking/DockHostMeasure.cpp | 0 .../src/Docking/DockHostMeasureInternal.h | 0 .../src/Docking/DockHostRendering.cpp | 0 .../src/Docking/UIEditorDockHost.cpp | 0 .../Docking/UIEditorDockHostInteraction.cpp | 0 .../src/Docking/UIEditorDockHostTransfer.cpp | 0 .../src/Fields/ColorFieldInternal.h | 0 .../src/Fields/ColorFieldRendering.cpp | 0 .../Fields/PropertyGridInteractionInternal.h | 0 .../src/Fields/PropertyGridInternal.h | 0 .../src/Fields/UIEditorAssetField.cpp | 0 .../Fields/UIEditorAssetFieldInteraction.cpp | 0 .../src/Fields/UIEditorBoolField.cpp | 0 .../Fields/UIEditorBoolFieldInteraction.cpp | 0 .../src/Fields/UIEditorColorField.cpp | 0 .../Fields/UIEditorColorFieldInteraction.cpp | 0 .../src/Fields/UIEditorEditableFieldCore.cpp | 0 .../src/Fields/UIEditorEnumField.cpp | 0 .../Fields/UIEditorEnumFieldInteraction.cpp | 0 .../src/Fields/UIEditorFieldStyle.cpp | 0 .../src/Fields/UIEditorNumberField.cpp | 0 .../Fields/UIEditorNumberFieldInteraction.cpp | 0 .../src/Fields/UIEditorObjectField.cpp | 0 .../Fields/UIEditorObjectFieldInteraction.cpp | 0 .../src/Fields/UIEditorPropertyGrid.cpp | 0 .../UIEditorPropertyGridInteraction.cpp | 0 .../src/Fields/UIEditorTextField.cpp | 0 .../Fields/UIEditorTextFieldInteraction.cpp | 0 .../src/Fields/UIEditorVector2Field.cpp | 0 .../UIEditorVector2FieldInteraction.cpp | 0 .../src/Fields/UIEditorVector3Field.cpp | 0 .../UIEditorVector3FieldInteraction.cpp | 0 .../src/Fields/UIEditorVector4Field.cpp | 0 .../UIEditorVector4FieldInteraction.cpp | 0 .../UIEditorVectorFieldInteractionShared.h | 0 .../src/Fields/UIEditorVectorFieldShared.h | 0 .../Foundation/UIEditorCommandDispatcher.cpp | 0 .../Foundation/UIEditorCommandRegistry.cpp | 0 .../src/Foundation/UIEditorRuntimeTrace.cpp | 0 .../Foundation/UIEditorShortcutManager.cpp | 0 .../src/Foundation/UIEditorTheme.cpp | 0 .../src/Menu/UIEditorMenuBar.cpp | 0 .../src/Menu/UIEditorMenuModel.cpp | 0 .../src/Menu/UIEditorMenuPopup.cpp | 0 .../src/Menu/UIEditorMenuSession.cpp | 0 .../Panels/UIEditorHostedPanelDispatch.cpp | 0 .../src/Panels/UIEditorPanelContentHost.cpp | 0 .../src/Panels/UIEditorPanelFrame.cpp | 0 .../src/Panels/UIEditorPanelHostLifecycle.cpp | 0 .../src/Panels/UIEditorPanelRegistry.cpp | 0 .../src/Shell/ShellInteractionInternal.h | 0 .../src/Shell/UIEditorShellAsset.cpp | 0 .../src/Shell/UIEditorShellCapturePolicy.cpp | 0 .../src/Shell/UIEditorShellCompose.cpp | 0 .../src/Shell/UIEditorShellInteraction.cpp | 0 .../src/Shell/UIEditorStatusBar.cpp | 0 .../src/Shell/UIEditorStructuredShell.cpp | 0 .../Viewport/UIEditorViewportInputBridge.cpp | 0 .../src/Viewport/UIEditorViewportShell.cpp | 0 .../src/Viewport/UIEditorViewportSlot.cpp | 0 .../Widgets/UIEditorCollectionPrimitives.cpp | 0 .../src/Widgets/UIEditorColorUtils.cpp | 0 .../src/Widgets/UIEditorFieldRowLayout.cpp | 0 .../SplitterDragCorrection/Chain.cpp | 0 .../SplitterDragCorrection/Correction.cpp | 0 .../SplitterDragCorrection/Internal.h | 0 .../UIEditorDetachedWindowPolicy.cpp | 2 +- .../UIEditorWindowWorkspaceController.cpp | 2 +- .../UIEditorWindowWorkspaceModel.cpp | 2 +- .../Workspace/UIEditorWorkspaceCompose.cpp | 0 .../Workspace/UIEditorWorkspaceController.cpp | 0 .../Workspace/UIEditorWorkspaceInputOwner.cpp | 0 .../UIEditorWorkspaceInteraction.cpp | 0 .../UIEditorWorkspaceLayoutPersistence.cpp | 0 .../src/Workspace/UIEditorWorkspaceModel.cpp | 0 .../Workspace/UIEditorWorkspaceSession.cpp | 0 .../Workspace/UIEditorWorkspaceTransfer.cpp | 0 .../Workspace/WorkspaceControllerInternal.h | 0 .../src/Workspace/WorkspaceModelInternal.h | 0 .../EditorUtilityWindowPanelComposition.cpp | 21 - .../EditorUtilityWindowPanelComposition.h | 13 - .../EditorWindowApplicationComposition.cpp | 41 - .../EditorWindowApplicationComposition.h | 40 - .../Win32/Adapter/Win32WindowMessageAdapter.h | 27 - .../Win32/Adapter/Win32WindowMessageSink.h | 22 - .../Adapter/Win32WindowMessageTranslator.h | 201 --- .../Backend/Win32NativeWindowBackend.cpp | 360 ----- .../Win32/Backend/Win32NativeWindowBackend.h | 77 - .../Chrome/EditorWindowChromeProjection.h | 18 - .../Win32WindowCommandProjector.cpp | 85 -- .../Projection/Win32WindowCommandProjector.h | 39 - .../Win32/Rendering/D3D12WindowRenderHost.cpp | 224 --- .../Win32/Rendering/D3D12WindowRenderHost.h | 82 -- .../Runtime/EditorWindowRuntimeController.cpp | 297 ---- .../Platform/Win32/Windowing/EditorWindow.cpp | 1270 ----------------- .../Platform/Win32/Windowing/EditorWindow.h | 308 ---- .../Windowing/EditorWindowCreateParams.h | 29 - .../Windowing/EditorWindowFramePumpMode.h | 10 - .../EditorWindowFramePumpRuntime.cpp | 133 -- .../Windowing/EditorWindowFramePumpRuntime.h | 32 - .../EditorWindowInputMessageExecutor.cpp | 223 --- .../EditorWindowInputMessageExecutor.h | 36 - .../EditorWindowLifecycleEventRuntime.cpp | 191 --- .../EditorWindowLifecycleEventRuntime.h | 37 - ...itorWindowLifecycleFinalizationRuntime.cpp | 238 --- ...EditorWindowLifecycleFinalizationRuntime.h | 48 - .../EditorWindowMessagePumpRuntime.cpp | 243 ---- .../EditorWindowMessagePumpRuntime.h | 38 - .../Windowing/EditorWindowPlatformRuntime.cpp | 279 ---- .../Windowing/EditorWindowPlatformRuntime.h | 112 -- .../Windowing/EditorWindowRegistryRuntime.cpp | 330 ----- .../Windowing/EditorWindowRegistryRuntime.h | 92 -- .../Win32/Windowing/EditorWindowSession.cpp | 331 ----- .../Win32/Windowing/EditorWindowSession.h | 91 -- .../Win32/Windowing/EditorWindowSupport.h | 35 - .../Win32WindowApplicationRuntime.cpp | 117 -- .../Windowing/Win32WindowApplicationRuntime.h | 67 - .../Windowing/Win32WindowRuntimeGraph.cpp | 98 -- .../Win32/Windowing/Win32WindowRuntimeGraph.h | 55 - .../EditorWindowApplicationRuntime.cpp | 112 -- .../EditorWindowApplicationRuntime.h | 62 - .../EditorWindowApplicationStateRuntime.cpp | 208 --- .../EditorWindowApplicationStateRuntime.h | 64 - .../Application/EditorWindowCommandSink.h | 19 - .../Application/EditorWindowContentSpec.h | 27 - .../EditorWindowContentUpdateResult.h | 28 - .../EditorWindowFrameRequestSource.h | 20 - .../Application/EditorWindowGeometry.cpp | 53 - .../Application/EditorWindowGeometry.h | 29 - .../EditorWindowLifecycleRelay.cpp | 33 - .../Application/EditorWindowLifecycleRelay.h | 20 - .../EditorWindowPostFrameRuntime.cpp | 156 -- .../EditorWindowPostFrameRuntime.h | 88 -- .../Windowing/Application/FrameScheduler.cpp | 190 --- .../Windowing/Application/FrameScheduler.h | 54 - .../Windowing/Application/WindowSession.cpp | 154 -- .../app/Windowing/Application/WindowSession.h | 45 - .../Application/WindowTopologyService.h | 478 ------- .../Application/WindowTopologyState.h | 37 - .../Content/EditorWindowContentRuntime.cpp | 364 ----- .../Content/EditorWindowContentRuntime.h | 164 --- .../Windowing/Host/EditorWindowDirectory.h | 33 - .../Windowing/Host/EditorWindowHostAdapters.h | 26 - .../Windowing/Host/EditorWindowTraceSink.h | 14 - .../Host/EditorWindowUtilitySessionHost.h | 18 - .../Ports/EditorWindowHostCreationPort.h | 45 - .../Ports/EditorWindowLifecyclePort.h | 16 - .../Ports/EditorWindowNativeQueryPort.h | 23 - .../Ports/EditorWindowWorkspaceContentPort.h | 23 - .../Ports/EditorWindowWorkspaceHostPort.h | 34 - .../Utility/EditorUtilityWindowCatalog.cpp | 86 -- .../Utility/EditorUtilityWindowCatalog.h | 30 - .../EditorUtilityWindowFeatureCommands.h | 39 - .../EditorUtilityWindowFrameWorkflow.cpp | 112 -- .../EditorUtilityWindowFrameWorkflow.h | 57 - .../Utility/EditorUtilityWindowPanel.h | 81 -- .../EditorUtilityWindowPanelProvider.h | 19 - .../EditorUtilityWindowRequestSink.cpp | 54 - .../Utility/EditorUtilityWindowRequestSink.h | 44 - .../Utility/EditorUtilityWindowResultState.h | 56 - .../Utility/EditorUtilityWindowSession.cpp | 21 - .../Utility/EditorUtilityWindowSession.h | 64 - .../Utility/EditorWindowUtilityRuntime.cpp | 285 ---- .../Utility/EditorWindowUtilityRuntime.h | 61 - .../Windowing/Utility/WindowUtilityRequest.h | 22 - ...ditorWindowWorkspaceInteractionRuntime.cpp | 593 -------- .../EditorWindowWorkspaceInteractionRuntime.h | 110 -- .../EditorWindowWorkspaceMutationRuntime.cpp | 284 ---- .../EditorWindowWorkspaceMutationRuntime.h | 72 - ...EditorWindowWorkspaceProjectionRuntime.cpp | 148 -- .../EditorWindowWorkspaceProjectionRuntime.h | 51 - .../Workspace/WindowWorkspaceTransferQueue.h | 85 -- .../XCEditor/Windowing/FrameDispatchMode.h | 12 - .../XCEditor/Windowing/FramePriority.h | 14 - .../include/XCEditor/Windowing/FrameReason.h | 17 - .../XCEditor/Windowing/WindowCaptureDemand.h | 14 - .../XCEditor/Windowing/WindowCommand.h | 37 - .../XCEditor/Windowing/WindowContentOutput.h | 22 - .../XCEditor/Windowing/WindowCursorType.h | 20 - .../include/XCEditor/Windowing/WindowEvent.h | 34 - .../include/XCEditor/Windowing/WindowId.h | 30 - .../include/XCEditor/Windowing/WindowIntent.h | 21 - .../include/XCEditor/Windowing/WindowState.h | 72 - .../XCEditor/Windowing/WindowTitleBarMode.h | 12 - .../include/XCEditor/Windowing/WindowType.h | 14 - 516 files changed, 6175 insertions(+), 12401 deletions(-) rename {new_editor => editor}/CMakeLists.txt (82%) rename {new_editor => editor}/app/Bootstrap/Application.cpp (76%) rename {new_editor => editor}/app/Bootstrap/Application.h (83%) rename {new_editor => editor}/app/Bootstrap/EditorApp.rc (100%) rename {new_editor => editor}/app/Bootstrap/EditorResources.h (100%) rename {new_editor => editor}/app/Commands/EditorEditCommandRoute.h (100%) rename {new_editor => editor}/app/Commands/EditorHostCommandBridge.cpp (100%) rename {new_editor => editor}/app/Commands/EditorHostCommandBridge.h (100%) rename {new_editor => editor}/app/Composition/EditorContext.cpp (94%) rename {new_editor => editor}/app/Composition/EditorContext.h (87%) rename {new_editor => editor}/app/Composition/EditorPanelIds.h (100%) rename {new_editor => editor}/app/Composition/EditorShellAssetBuilder.cpp (99%) rename {new_editor => editor}/app/Composition/EditorShellAssetBuilder.h (100%) rename {new_editor => editor}/app/Composition/EditorShellDrawComposer.cpp (100%) rename {new_editor => editor}/app/Composition/EditorShellDrawComposer.h (100%) rename {new_editor => editor}/app/Composition/EditorShellHostedPanelCoordinator.cpp (97%) rename {new_editor => editor}/app/Composition/EditorShellHostedPanelCoordinator.h (84%) rename {new_editor => editor}/app/Composition/EditorShellInteractionEngine.cpp (100%) rename {new_editor => editor}/app/Composition/EditorShellInteractionEngine.h (100%) rename {new_editor => editor}/app/Composition/EditorShellRuntime.cpp (96%) rename {new_editor => editor}/app/Composition/EditorShellRuntime.h (92%) rename {new_editor => editor}/app/Composition/EditorShellSessionCoordinator.cpp (100%) rename {new_editor => editor}/app/Composition/EditorShellSessionCoordinator.h (100%) rename {new_editor => editor}/app/Composition/EditorShellVariant.h (100%) rename {new_editor => editor}/app/Composition/EditorWindowWorkspaceStore.cpp (100%) rename {new_editor => editor}/app/Composition/EditorWindowWorkspaceStore.h (88%) rename {new_editor => editor}/app/Composition/WorkspaceEventSync.cpp (100%) rename {new_editor => editor}/app/Composition/WorkspaceEventSync.h (100%) rename {new_editor => editor}/app/Features/ColorPicker/ColorPickerPanel.cpp (83%) rename {new_editor => editor}/app/Features/ColorPicker/ColorPickerPanel.h (84%) rename {new_editor => editor}/app/Features/Console/ConsolePanel.cpp (100%) rename {new_editor => editor}/app/Features/Console/ConsolePanel.h (100%) rename {new_editor => editor}/app/Features/Hierarchy/HierarchyModel.cpp (100%) rename {new_editor => editor}/app/Features/Hierarchy/HierarchyModel.h (100%) rename {new_editor => editor}/app/Features/Hierarchy/HierarchyPanel.cpp (100%) rename {new_editor => editor}/app/Features/Hierarchy/HierarchyPanel.h (100%) rename {new_editor => editor}/app/Features/Inspector/AddComponentPanel.cpp (83%) rename {new_editor => editor}/app/Features/Inspector/AddComponentPanel.h (78%) rename {new_editor => editor}/app/Features/Inspector/Components/AudioListenerInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/AudioSourceInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/BoxColliderInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/CameraInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/CapsuleColliderInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/ColliderInspectorComponentEditorUtils.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/IInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/InspectorBindingComponentEditor.cpp (100%) rename {new_editor => editor}/app/Features/Inspector/Components/InspectorBindingComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/InspectorComponentEditorRegistry.cpp (100%) rename {new_editor => editor}/app/Features/Inspector/Components/InspectorComponentEditorRegistry.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/InspectorComponentEditorUtils.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/LightInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/MeshFilterInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/MeshRendererInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/RigidbodyInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/SphereColliderInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/TransformInspectorComponentEditor.cpp (100%) rename {new_editor => editor}/app/Features/Inspector/Components/TransformInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/Components/VolumeRendererInspectorComponentEditor.h (100%) rename {new_editor => editor}/app/Features/Inspector/InspectorPanel.cpp (91%) rename {new_editor => editor}/app/Features/Inspector/InspectorPanel.h (77%) rename {new_editor => editor}/app/Features/Inspector/InspectorPresentationModel.cpp (100%) rename {new_editor => editor}/app/Features/Inspector/InspectorPresentationModel.h (100%) rename {new_editor => editor}/app/Features/Inspector/InspectorSubject.cpp (100%) rename {new_editor => editor}/app/Features/Inspector/InspectorSubject.h (100%) rename {new_editor => editor}/app/Features/Project/ProjectBrowserModel.cpp (100%) rename {new_editor => editor}/app/Features/Project/ProjectBrowserModel.h (100%) rename {new_editor => editor}/app/Features/Project/ProjectPanel.cpp (99%) rename {new_editor => editor}/app/Features/Project/ProjectPanel.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneEditCommandRoute.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneEditCommandRoute.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportController.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportController.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportFeature.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportFeature.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportSceneOverlay.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportSceneOverlay.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportToolOverlay.cpp (99%) rename {new_editor => editor}/app/Features/Scene/SceneViewportToolOverlay.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportTransformGizmo.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportTransformGizmo.h (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportTransformGizmoSupport.cpp (100%) rename {new_editor => editor}/app/Features/Scene/SceneViewportTransformGizmoSupport.h (100%) rename {new_editor => editor}/app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp (100%) rename {new_editor => editor}/app/Platform/Win32/Chrome/BorderlessWindowChrome.h (100%) rename {new_editor => editor}/app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp (100%) rename {new_editor => editor}/app/Platform/Win32/Chrome/BorderlessWindowFrame.h (100%) rename {new_editor => editor}/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp (62%) rename {new_editor => editor}/app/Platform/Win32/Chrome/EditorWindowChromeController.h (58%) rename {new_editor => editor}/app/Platform/Win32/Chrome/HostRuntimeState.h (62%) create mode 100644 editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp create mode 100644 editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.h create mode 100644 editor/app/Platform/Win32/Content/EditorWindowContentController.h create mode 100644 editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp create mode 100644 editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.h create mode 100644 editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp create mode 100644 editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.h rename {new_editor/app/Windowing/Content => editor/app/Platform/Win32/Runtime}/EditorWindowFrameOrchestrator.cpp (55%) rename {new_editor/app/Windowing/Content => editor/app/Platform/Win32/Runtime}/EditorWindowFrameOrchestrator.h (72%) rename {new_editor => editor}/app/Platform/Win32/Runtime/EditorWindowInputController.cpp (87%) rename {new_editor => editor}/app/Platform/Win32/Runtime/EditorWindowInputController.h (78%) create mode 100644 editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp rename {new_editor => editor}/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h (51%) rename {new_editor => editor}/app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp (100%) rename {new_editor => editor}/app/Platform/Win32/Runtime/EditorWindowScreenshotController.h (100%) rename {new_editor => editor}/app/Platform/Win32/Runtime/InputModifierTracker.h (100%) rename {new_editor => editor}/app/Platform/Win32/System/Win32SystemInteractionHost.cpp (100%) rename {new_editor => editor}/app/Platform/Win32/System/Win32SystemInteractionHost.h (100%) create mode 100644 editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindow.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindow.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowManager.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowManager.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h rename {new_editor => editor}/app/Platform/Win32/Windowing/EditorWindowPointerCapture.h (100%) create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowSession.h rename {new_editor => editor}/app/Platform/Win32/Windowing/EditorWindowState.h (51%) rename new_editor/app/Windowing/Content/EditorWindowContentStyle.h => editor/app/Platform/Win32/Windowing/EditorWindowSupport.h (52%) create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowTransferRequests.h create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp create mode 100644 editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h rename {new_editor => editor}/app/Project/EditorProjectRuntime.cpp (100%) rename {new_editor => editor}/app/Project/EditorProjectRuntime.h (100%) rename {new_editor => editor}/app/Rendering/Assets/BuiltInIcons.cpp (100%) rename {new_editor => editor}/app/Rendering/Assets/BuiltInIcons.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12HostDevice.cpp (70%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12HostDevice.h (94%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiRenderer.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiRenderer.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiTextSystem.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiTextSystem.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiTextureHost.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12UiTextureHost.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowCapture.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowCapture.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowRenderLoop.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowRenderLoop.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowRenderer.cpp (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowRenderer.h (100%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp (99%) rename {new_editor => editor}/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.h (100%) rename {new_editor => editor}/app/Rendering/Host/HostFwd.h (100%) rename {new_editor => editor}/app/Rendering/Host/UiTextureHost.h (100%) rename {new_editor => editor}/app/Rendering/Host/ViewportRenderHost.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportGridPass.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportPassSpecs.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderPassBundle.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderPassBundle.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderPlan.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderRequest.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderService.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportRenderService.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/SceneViewportResourcePaths.h (98%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportContentRenderer.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportHostService.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportHostService.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportObjectIdPicker.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportObjectPickerService.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportRenderTargetUtils.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportRenderTargetUtils.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportRenderTargets.cpp (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportRenderTargets.h (100%) rename {new_editor => editor}/app/Rendering/Viewport/ViewportTypes.h (100%) rename {new_editor => editor}/app/Scene/EditorSceneBridge.cpp (100%) rename {new_editor => editor}/app/Scene/EditorSceneBridge.h (100%) rename {new_editor => editor}/app/Scene/EditorSceneRuntime.cpp (98%) rename {new_editor => editor}/app/Scene/EditorSceneRuntime.h (98%) rename {new_editor => editor}/app/Scene/SceneToolState.h (100%) rename {new_editor => editor}/app/Scene/SceneViewportCameraController.h (100%) create mode 100644 editor/app/State/EditorColorPickerToolState.cpp create mode 100644 editor/app/State/EditorColorPickerToolState.h rename {new_editor => editor}/app/State/EditorCommandFocusService.h (100%) rename {new_editor => editor}/app/State/EditorSelectionService.h (100%) rename {new_editor => editor}/app/State/EditorSelectionStamp.h (100%) rename {new_editor => editor}/app/State/EditorSession.cpp (100%) rename {new_editor => editor}/app/State/EditorSession.h (100%) create mode 100644 editor/app/State/EditorUtilityWindowRequestState.cpp create mode 100644 editor/app/State/EditorUtilityWindowRequestState.h rename {new_editor => editor}/app/Support/EmbeddedPngLoader.cpp (100%) rename {new_editor => editor}/app/Support/EmbeddedPngLoader.h (100%) rename {new_editor => editor}/app/Support/EnvironmentFlags.h (100%) rename {new_editor => editor}/app/Support/ExecutablePath.h (100%) rename {new_editor => editor}/app/Support/StringEncoding.h (100%) rename {new_editor => editor}/app/Support/TextFormat.h (100%) rename {new_editor => editor}/app/System/SystemInteractionService.h (100%) rename new_editor/app/Windowing/Utility/EditorUtilityWindowType.h => editor/app/UtilityWindows/EditorUtilityWindowKind.h (76%) create mode 100644 editor/app/UtilityWindows/EditorUtilityWindowPanel.h create mode 100644 editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp create mode 100644 editor/app/UtilityWindows/EditorUtilityWindowRegistry.h rename {new_editor => editor}/app/main.cpp (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorDragDropInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorFilterableTreeHost.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorGridDragDrop.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorInlineRenameSession.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorListView.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorListViewInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorScrollView.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorScrollViewInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorTabStrip.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorTabStripInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorTreeDragDrop.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorTreeView.h (100%) rename {new_editor => editor}/include/XCEditor/Collections/UIEditorTreeViewInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Docking/UIEditorDockHost.h (100%) rename {new_editor => editor}/include/XCEditor/Docking/UIEditorDockHostInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Docking/UIEditorDockHostTransfer.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorAssetField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorAssetFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorBoolField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorBoolFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorColorField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorColorFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorEditableFieldCore.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorEnumField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorEnumFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorFieldStyle.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorNumberField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorNumberFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorObjectField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorObjectFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorPropertyGrid.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorPropertyGridInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorTextField.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorTextFieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector2Field.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector2FieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector3Field.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector3FieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector4Field.h (100%) rename {new_editor => editor}/include/XCEditor/Fields/UIEditorVector4FieldInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorCommandDispatcher.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorCommandRegistry.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorPanelInputFilter.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorRuntimeTrace.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorShortcutManager.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorTextLayout.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorTextMeasurement.h (100%) rename {new_editor => editor}/include/XCEditor/Foundation/UIEditorTheme.h (100%) rename {new_editor => editor}/include/XCEditor/Menu/UIEditorMenuBar.h (100%) rename {new_editor => editor}/include/XCEditor/Menu/UIEditorMenuModel.h (100%) rename {new_editor => editor}/include/XCEditor/Menu/UIEditorMenuPopup.h (100%) rename {new_editor => editor}/include/XCEditor/Menu/UIEditorMenuSession.h (100%) rename {new_editor => editor}/include/XCEditor/Panels/UIEditorHostedPanelDispatch.h (100%) rename {new_editor => editor}/include/XCEditor/Panels/UIEditorPanelContentHost.h (100%) rename {new_editor => editor}/include/XCEditor/Panels/UIEditorPanelFrame.h (100%) rename {new_editor => editor}/include/XCEditor/Panels/UIEditorPanelHostLifecycle.h (100%) rename {new_editor => editor}/include/XCEditor/Panels/UIEditorPanelRegistry.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorShellAsset.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorShellCapturePolicy.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorShellCompose.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorShellInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorStatusBar.h (100%) rename {new_editor => editor}/include/XCEditor/Shell/UIEditorStructuredShell.h (100%) rename {new_editor => editor}/include/XCEditor/Viewport/UIEditorViewportInputBridge.h (100%) rename {new_editor => editor}/include/XCEditor/Viewport/UIEditorViewportShell.h (100%) rename {new_editor => editor}/include/XCEditor/Viewport/UIEditorViewportSlot.h (100%) rename {new_editor => editor}/include/XCEditor/Widgets/UIEditorCollectionPrimitives.h (100%) rename {new_editor => editor}/include/XCEditor/Widgets/UIEditorColorUtils.h (100%) rename {new_editor => editor}/include/XCEditor/Widgets/UIEditorFieldRowLayout.h (100%) rename {new_editor => editor}/include/XCEditor/Widgets/UIEditorTextLayout.h (100%) rename {new_editor/app/Windowing => editor/include/XCEditor}/Workspace/UIEditorDetachedWindowPolicy.h (100%) rename {new_editor/app/Windowing => editor/include/XCEditor}/Workspace/UIEditorWindowWorkspaceController.h (97%) rename {new_editor/app/Windowing => editor/include/XCEditor}/Workspace/UIEditorWindowWorkspaceModel.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceController.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceInputOwner.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceLayoutPersistence.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceModel.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceMutation.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceQueries.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceSession.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceSplitterDragCorrection.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceTransfer.h (100%) rename {new_editor => editor}/include/XCEditor/Workspace/UIEditorWorkspaceValidation.h (100%) rename {new_editor => editor}/resources/Icons/camera_gizmo.png (100%) rename {new_editor => editor}/resources/Icons/directional_light_gizmo.png (100%) rename {new_editor => editor}/resources/Icons/folder_icon.png (100%) rename {new_editor => editor}/resources/Icons/gameobject_icon.png (100%) rename {new_editor => editor}/resources/Icons/logo.ico (100%) rename {new_editor => editor}/resources/Icons/logo.png (100%) rename {new_editor => editor}/resources/Icons/logo_icon.ico (100%) rename {new_editor => editor}/resources/Icons/logo_icon.png (100%) rename {new_editor => editor}/resources/Icons/move_tool.png (100%) rename {new_editor => editor}/resources/Icons/move_tool_on.png (100%) rename {new_editor => editor}/resources/Icons/pause_button.png (100%) rename {new_editor => editor}/resources/Icons/play_button.png (100%) rename {new_editor => editor}/resources/Icons/point_light_gizmo.png (100%) rename {new_editor => editor}/resources/Icons/rotate_tool.png (100%) rename {new_editor => editor}/resources/Icons/rotate_tool_on.png (100%) rename {new_editor => editor}/resources/Icons/scale_tool.png (100%) rename {new_editor => editor}/resources/Icons/scale_tool_on.png (100%) rename {new_editor => editor}/resources/Icons/scene_icon.png (100%) rename {new_editor => editor}/resources/Icons/spot_light_gizmo.png (100%) rename {new_editor => editor}/resources/Icons/step_button.png (100%) rename {new_editor => editor}/resources/Icons/transform_tool.png (100%) rename {new_editor => editor}/resources/Icons/transform_tool_on.png (100%) rename {new_editor => editor}/resources/Icons/view_move_tool.png (100%) rename {new_editor => editor}/resources/Icons/view_move_tool_on.png (100%) rename {new_editor => editor}/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader (100%) rename {new_editor => editor}/resources/shaders/scene-viewport/selection-mask/selection-mask.shader (100%) rename {new_editor => editor}/resources/shaders/scene-viewport/selection-outline/selection-outline.shader (100%) rename {new_editor => editor}/src/Collections/UIEditorFilterableTreeHost.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorInlineRenameSession.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorListView.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorListViewInteraction.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorScrollView.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorScrollViewInteraction.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorTabStrip.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorTabStripInteraction.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorTreeView.cpp (100%) rename {new_editor => editor}/src/Collections/UIEditorTreeViewInteraction.cpp (100%) rename {new_editor => editor}/src/Docking/DockHostHitTest.cpp (100%) rename {new_editor => editor}/src/Docking/DockHostInteractionHelpers.cpp (100%) rename {new_editor => editor}/src/Docking/DockHostInteractionInternal.h (100%) rename {new_editor => editor}/src/Docking/DockHostMeasure.cpp (100%) rename {new_editor => editor}/src/Docking/DockHostMeasureInternal.h (100%) rename {new_editor => editor}/src/Docking/DockHostRendering.cpp (100%) rename {new_editor => editor}/src/Docking/UIEditorDockHost.cpp (100%) rename {new_editor => editor}/src/Docking/UIEditorDockHostInteraction.cpp (100%) rename {new_editor => editor}/src/Docking/UIEditorDockHostTransfer.cpp (100%) rename {new_editor => editor}/src/Fields/ColorFieldInternal.h (100%) rename {new_editor => editor}/src/Fields/ColorFieldRendering.cpp (100%) rename {new_editor => editor}/src/Fields/PropertyGridInteractionInternal.h (100%) rename {new_editor => editor}/src/Fields/PropertyGridInternal.h (100%) rename {new_editor => editor}/src/Fields/UIEditorAssetField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorAssetFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorBoolField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorBoolFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorColorField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorColorFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorEditableFieldCore.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorEnumField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorEnumFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorFieldStyle.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorNumberField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorNumberFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorObjectField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorObjectFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorPropertyGrid.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorPropertyGridInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorTextField.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorTextFieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector2Field.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector2FieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector3Field.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector3FieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector4Field.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVector4FieldInteraction.cpp (100%) rename {new_editor => editor}/src/Fields/UIEditorVectorFieldInteractionShared.h (100%) rename {new_editor => editor}/src/Fields/UIEditorVectorFieldShared.h (100%) rename {new_editor => editor}/src/Foundation/UIEditorCommandDispatcher.cpp (100%) rename {new_editor => editor}/src/Foundation/UIEditorCommandRegistry.cpp (100%) rename {new_editor => editor}/src/Foundation/UIEditorRuntimeTrace.cpp (100%) rename {new_editor => editor}/src/Foundation/UIEditorShortcutManager.cpp (100%) rename {new_editor => editor}/src/Foundation/UIEditorTheme.cpp (100%) rename {new_editor => editor}/src/Menu/UIEditorMenuBar.cpp (100%) rename {new_editor => editor}/src/Menu/UIEditorMenuModel.cpp (100%) rename {new_editor => editor}/src/Menu/UIEditorMenuPopup.cpp (100%) rename {new_editor => editor}/src/Menu/UIEditorMenuSession.cpp (100%) rename {new_editor => editor}/src/Panels/UIEditorHostedPanelDispatch.cpp (100%) rename {new_editor => editor}/src/Panels/UIEditorPanelContentHost.cpp (100%) rename {new_editor => editor}/src/Panels/UIEditorPanelFrame.cpp (100%) rename {new_editor => editor}/src/Panels/UIEditorPanelHostLifecycle.cpp (100%) rename {new_editor => editor}/src/Panels/UIEditorPanelRegistry.cpp (100%) rename {new_editor => editor}/src/Shell/ShellInteractionInternal.h (100%) rename {new_editor => editor}/src/Shell/UIEditorShellAsset.cpp (100%) rename {new_editor => editor}/src/Shell/UIEditorShellCapturePolicy.cpp (100%) rename {new_editor => editor}/src/Shell/UIEditorShellCompose.cpp (100%) rename {new_editor => editor}/src/Shell/UIEditorShellInteraction.cpp (100%) rename {new_editor => editor}/src/Shell/UIEditorStatusBar.cpp (100%) rename {new_editor => editor}/src/Shell/UIEditorStructuredShell.cpp (100%) rename {new_editor => editor}/src/Viewport/UIEditorViewportInputBridge.cpp (100%) rename {new_editor => editor}/src/Viewport/UIEditorViewportShell.cpp (100%) rename {new_editor => editor}/src/Viewport/UIEditorViewportSlot.cpp (100%) rename {new_editor => editor}/src/Widgets/UIEditorCollectionPrimitives.cpp (100%) rename {new_editor => editor}/src/Widgets/UIEditorColorUtils.cpp (100%) rename {new_editor => editor}/src/Widgets/UIEditorFieldRowLayout.cpp (100%) rename {new_editor => editor}/src/Workspace/SplitterDragCorrection/Chain.cpp (100%) rename {new_editor => editor}/src/Workspace/SplitterDragCorrection/Correction.cpp (100%) rename {new_editor => editor}/src/Workspace/SplitterDragCorrection/Internal.h (100%) rename {new_editor/app/Windowing => editor/src}/Workspace/UIEditorDetachedWindowPolicy.cpp (97%) rename {new_editor/app/Windowing => editor/src}/Workspace/UIEditorWindowWorkspaceController.cpp (99%) rename {new_editor/app/Windowing => editor/src}/Workspace/UIEditorWindowWorkspaceModel.cpp (98%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceCompose.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceController.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceInputOwner.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceInteraction.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceModel.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceSession.cpp (100%) rename {new_editor => editor}/src/Workspace/UIEditorWorkspaceTransfer.cpp (100%) rename {new_editor => editor}/src/Workspace/WorkspaceControllerInternal.h (100%) rename {new_editor => editor}/src/Workspace/WorkspaceModelInternal.h (100%) delete mode 100644 new_editor/app/Composition/EditorUtilityWindowPanelComposition.cpp delete mode 100644 new_editor/app/Composition/EditorUtilityWindowPanelComposition.h delete mode 100644 new_editor/app/Composition/EditorWindowApplicationComposition.cpp delete mode 100644 new_editor/app/Composition/EditorWindowApplicationComposition.h delete mode 100644 new_editor/app/Platform/Win32/Adapter/Win32WindowMessageAdapter.h delete mode 100644 new_editor/app/Platform/Win32/Adapter/Win32WindowMessageSink.h delete mode 100644 new_editor/app/Platform/Win32/Adapter/Win32WindowMessageTranslator.h delete mode 100644 new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.cpp delete mode 100644 new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.h delete mode 100644 new_editor/app/Platform/Win32/Chrome/EditorWindowChromeProjection.h delete mode 100644 new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.cpp delete mode 100644 new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.h delete mode 100644 new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.cpp delete mode 100644 new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.h delete mode 100644 new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindow.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowCreateParams.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpMode.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/EditorWindowSupport.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.h delete mode 100644 new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.cpp delete mode 100644 new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.cpp delete mode 100644 new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.cpp delete mode 100644 new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowCommandSink.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowContentSpec.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowContentUpdateResult.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowFrameRequestSource.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowGeometry.cpp delete mode 100644 new_editor/app/Windowing/Application/EditorWindowGeometry.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.cpp delete mode 100644 new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.h delete mode 100644 new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.cpp delete mode 100644 new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.h delete mode 100644 new_editor/app/Windowing/Application/FrameScheduler.cpp delete mode 100644 new_editor/app/Windowing/Application/FrameScheduler.h delete mode 100644 new_editor/app/Windowing/Application/WindowSession.cpp delete mode 100644 new_editor/app/Windowing/Application/WindowSession.h delete mode 100644 new_editor/app/Windowing/Application/WindowTopologyService.h delete mode 100644 new_editor/app/Windowing/Application/WindowTopologyState.h delete mode 100644 new_editor/app/Windowing/Content/EditorWindowContentRuntime.cpp delete mode 100644 new_editor/app/Windowing/Content/EditorWindowContentRuntime.h delete mode 100644 new_editor/app/Windowing/Host/EditorWindowDirectory.h delete mode 100644 new_editor/app/Windowing/Host/EditorWindowHostAdapters.h delete mode 100644 new_editor/app/Windowing/Host/EditorWindowTraceSink.h delete mode 100644 new_editor/app/Windowing/Host/EditorWindowUtilitySessionHost.h delete mode 100644 new_editor/app/Windowing/Ports/EditorWindowHostCreationPort.h delete mode 100644 new_editor/app/Windowing/Ports/EditorWindowLifecyclePort.h delete mode 100644 new_editor/app/Windowing/Ports/EditorWindowNativeQueryPort.h delete mode 100644 new_editor/app/Windowing/Ports/EditorWindowWorkspaceContentPort.h delete mode 100644 new_editor/app/Windowing/Ports/EditorWindowWorkspaceHostPort.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.cpp delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowFeatureCommands.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.cpp delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowPanel.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowPanelProvider.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.cpp delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowResultState.h delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowSession.cpp delete mode 100644 new_editor/app/Windowing/Utility/EditorUtilityWindowSession.h delete mode 100644 new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.cpp delete mode 100644 new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.h delete mode 100644 new_editor/app/Windowing/Utility/WindowUtilityRequest.h delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.cpp delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.cpp delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.cpp delete mode 100644 new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h delete mode 100644 new_editor/app/Windowing/Workspace/WindowWorkspaceTransferQueue.h delete mode 100644 new_editor/include/XCEditor/Windowing/FrameDispatchMode.h delete mode 100644 new_editor/include/XCEditor/Windowing/FramePriority.h delete mode 100644 new_editor/include/XCEditor/Windowing/FrameReason.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowCaptureDemand.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowCommand.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowContentOutput.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowCursorType.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowEvent.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowId.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowIntent.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowState.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowTitleBarMode.h delete mode 100644 new_editor/include/XCEditor/Windowing/WindowType.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 413e4f7d..b9885446 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,9 +242,6 @@ endif() add_subdirectory(engine) add_subdirectory(managed) -if(EXISTS "${CMAKE_SOURCE_DIR}/editor/CMakeLists.txt") - add_subdirectory(editor) -endif() -add_subdirectory(new_editor) +add_subdirectory(editor) add_subdirectory(mvs/RenderDoc) add_subdirectory(tests) diff --git a/new_editor/CMakeLists.txt b/editor/CMakeLists.txt similarity index 82% rename from new_editor/CMakeLists.txt rename to editor/CMakeLists.txt index 7a09dad5..4cca2f57 100644 --- a/new_editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -117,6 +117,7 @@ set(XCUI_EDITOR_VIEWPORT_SOURCES set(XCUI_EDITOR_WORKSPACE_SOURCES src/Workspace/UIEditorWorkspaceCompose.cpp src/Workspace/UIEditorWorkspaceController.cpp + src/Workspace/UIEditorDetachedWindowPolicy.cpp src/Workspace/UIEditorWorkspaceInteraction.cpp src/Workspace/UIEditorWorkspaceInputOwner.cpp src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp @@ -125,6 +126,8 @@ set(XCUI_EDITOR_WORKSPACE_SOURCES src/Workspace/SplitterDragCorrection/Correction.cpp src/Workspace/UIEditorWorkspaceSession.cpp src/Workspace/UIEditorWorkspaceTransfer.cpp + src/Workspace/UIEditorWindowWorkspaceController.cpp + src/Workspace/UIEditorWindowWorkspaceModel.cpp ) set(XCUI_EDITOR_WIDGET_SUPPORT_SOURCES @@ -172,6 +175,8 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) ) set(XCUI_EDITOR_APP_STATE_SOURCES + app/State/EditorColorPickerToolState.cpp + app/State/EditorUtilityWindowRequestState.cpp app/State/EditorSession.cpp ) @@ -187,9 +192,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) app/Composition/EditorShellInteractionEngine.cpp app/Composition/EditorShellRuntime.cpp app/Composition/EditorShellSessionCoordinator.cpp - app/Composition/EditorWindowApplicationComposition.cpp app/Composition/EditorWindowWorkspaceStore.cpp - app/Composition/EditorUtilityWindowPanelComposition.cpp app/Composition/WorkspaceEventSync.cpp ) @@ -214,6 +217,7 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) app/Features/Scene/SceneViewportFeature.cpp app/Features/Scene/SceneViewportToolOverlay.cpp app/Features/Scene/SceneViewportController.cpp + app/UtilityWindows/EditorUtilityWindowRegistry.cpp ) set(XCUI_EDITOR_APP_RENDERING_SOURCES @@ -235,48 +239,24 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) app/Scene/EditorSceneBridge.cpp ) - set(XCUI_EDITOR_APP_WINDOWING_SOURCES - app/Windowing/Application/EditorWindowApplicationRuntime.cpp - app/Windowing/Application/EditorWindowApplicationStateRuntime.cpp - app/Windowing/Application/EditorWindowGeometry.cpp - app/Windowing/Application/EditorWindowLifecycleRelay.cpp - app/Windowing/Application/EditorWindowPostFrameRuntime.cpp - app/Windowing/Application/FrameScheduler.cpp - app/Windowing/Application/WindowSession.cpp - app/Windowing/Content/EditorWindowContentRuntime.cpp - app/Windowing/Content/EditorWindowFrameOrchestrator.cpp - app/Windowing/Utility/EditorUtilityWindowCatalog.cpp - app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.cpp - app/Windowing/Utility/EditorUtilityWindowRequestSink.cpp - app/Windowing/Utility/EditorUtilityWindowSession.cpp - app/Windowing/Utility/EditorWindowUtilityRuntime.cpp - app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.cpp - app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.cpp - app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.cpp - app/Windowing/Workspace/UIEditorDetachedWindowPolicy.cpp - app/Windowing/Workspace/UIEditorWindowWorkspaceController.cpp - app/Windowing/Workspace/UIEditorWindowWorkspaceModel.cpp - ) - set(XCUI_EDITOR_APP_PLATFORM_SOURCES app/Platform/Win32/Windowing/EditorWindow.cpp + app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp app/Platform/Win32/Windowing/EditorWindowSession.cpp + app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp app/Platform/Win32/Chrome/EditorWindowChromeController.cpp - app/Platform/Win32/Rendering/D3D12WindowRenderHost.cpp + app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp + app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.cpp app/Platform/Win32/Runtime/EditorWindowInputController.cpp app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp + app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp app/Platform/Win32/System/Win32SystemInteractionHost.cpp - app/Platform/Win32/Backend/Win32NativeWindowBackend.cpp - app/Platform/Win32/Projection/Win32WindowCommandProjector.cpp - app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.cpp - app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.cpp - app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.cpp - app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.cpp - app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.cpp - app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.cpp - app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.cpp - app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.cpp - app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.cpp + app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp + app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.cpp + app/Platform/Win32/Windowing/EditorWindowManager.cpp + app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp + app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.cpp + app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp ) set(XCUI_EDITOR_APP_CORE_SOURCES @@ -286,7 +266,6 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP) ${XCUI_EDITOR_APP_FEATURE_SOURCES} ${XCUI_EDITOR_APP_RENDERING_SOURCES} ${XCUI_EDITOR_APP_SUPPORT_SOURCES} - ${XCUI_EDITOR_APP_WINDOWING_SOURCES} ) set(XCUI_EDITOR_APP_INTERNAL_SOURCES @@ -354,9 +333,3 @@ endif() - - - - - - diff --git a/new_editor/app/Bootstrap/Application.cpp b/editor/app/Bootstrap/Application.cpp similarity index 76% rename from new_editor/app/Bootstrap/Application.cpp rename to editor/app/Bootstrap/Application.cpp index 419c36ac..6ebfdbbe 100644 --- a/new_editor/app/Bootstrap/Application.cpp +++ b/editor/app/Bootstrap/Application.cpp @@ -2,12 +2,12 @@ #include "Bootstrap/EditorResources.h" #include "System/SystemInteractionService.h" #include "Composition/EditorContext.h" -#include "Composition/EditorWindowApplicationComposition.h" +#include "Platform/Win32/Windowing/EditorWindowManager.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Content/EditorWorkspaceWindowContentController.h" #include "Platform/Win32/System/Win32SystemInteractionHost.h" #include "Support/EnvironmentFlags.h" #include "Support/ExecutablePath.h" -#include "Platform/Win32/Windowing/EditorWindowPlatformRuntime.h" -#include "Platform/Win32/Windowing/Win32WindowApplicationRuntime.h" #include #include @@ -123,46 +123,35 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { hostConfig.windowStyle = kBorderlessWindowStyle; hostConfig.primaryWindowTitle = kWindowTitle; hostConfig.windowUserData = this; - auto platformRuntime = std::make_unique( + m_windowManager = std::make_unique( hostConfig, m_repoRoot, *m_editorContext); - App::EditorWindowHostAdapters hostAdapters = - platformRuntime->CreateWindowHostAdapters(); - m_windowApplicationComposition = - std::make_unique( - kWindowTitle, - hostAdapters, - *m_editorContext); - m_windowRuntime = std::make_unique( - std::move(platformRuntime), - m_windowApplicationComposition->GetRuntime(), - *m_editorContext); - m_editorContext->SetExitRequestHandler([this]() { - if (m_windowRuntime == nullptr) { + if (m_windowManager == nullptr) { return; } - m_windowRuntime->RequestClosePrimaryWindow(); + if (App::EditorWindow* primaryWindow = m_windowManager->FindPrimaryWindow(); + primaryWindow != nullptr && + primaryWindow->GetHwnd() != nullptr) { + PostMessageW(primaryWindow->GetHwnd(), WM_CLOSE, 0, 0); + } }); m_editorContext->SetReadyStatus(); - App::EditorWindowCreateParams createParams = {}; + App::EditorWindowManager::CreateParams createParams = {}; createParams.windowId = "main"; - createParams.windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::PrimaryWorkspace; createParams.title = kWindowTitle; createParams.showCommand = nCmdShow; createParams.primary = true; createParams.autoCaptureOnStartup = App::IsEnvironmentFlagEnabled("XCUI_AUTO_CAPTURE_ON_STARTUP"); - if (!m_windowRuntime->CreateWindowHost( - App::EditorWorkspaceWindowContentSpec{ - .workspaceController = m_editorContext->BuildWorkspaceController(), - }, - createParams)) { + if (m_windowManager->CreateEditorWindow( + App::CreateEditorWorkspaceWindowContentController( + m_editorContext->BuildWorkspaceController()), + createParams) == nullptr) { AppendUIEditorRuntimeTrace("app", "primary window creation failed"); return false; } @@ -174,36 +163,21 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) { void Application::Shutdown() { AppendUIEditorRuntimeTrace("app", "shutdown begin"); - if (m_windowRuntime != nullptr) { - AppendUIEditorRuntimeTrace("app", "shutdown stage=WindowManager begin"); - m_windowRuntime->Shutdown(); - m_windowRuntime.reset(); - AppendUIEditorRuntimeTrace("app", "shutdown stage=WindowManager end"); - } - if (m_windowApplicationComposition != nullptr) { - AppendUIEditorRuntimeTrace("app", "shutdown stage=WindowApplicationComposition begin"); - m_windowApplicationComposition.reset(); - AppendUIEditorRuntimeTrace("app", "shutdown stage=WindowApplicationComposition end"); + if (m_windowManager != nullptr) { + m_windowManager->Shutdown(); + m_windowManager.reset(); } if (m_editorContext != nullptr) { - AppendUIEditorRuntimeTrace("app", "shutdown stage=EditorContext begin"); m_editorContext->SetSystemInteractionHost(nullptr); - AppendUIEditorRuntimeTrace("app", "shutdown stage=EditorContext end"); } - AppendUIEditorRuntimeTrace("app", "shutdown stage=SystemInteractionHost begin"); m_systemInteractionHost.reset(); - AppendUIEditorRuntimeTrace("app", "shutdown stage=SystemInteractionHost end"); - AppendUIEditorRuntimeTrace("app", "shutdown stage=ResourceManager begin"); ::XCEngine::Resources::ResourceManager::Get().Shutdown(); - AppendUIEditorRuntimeTrace("app", "shutdown stage=ResourceManager end"); if (m_windowClassAtom != 0 && m_hInstance != nullptr) { - AppendUIEditorRuntimeTrace("app", "shutdown stage=UnregisterClass begin"); UnregisterClassW(kWindowClassName, m_hInstance); m_windowClassAtom = 0; - AppendUIEditorRuntimeTrace("app", "shutdown stage=UnregisterClass end"); } AppendUIEditorRuntimeTrace("app", "shutdown end"); @@ -255,21 +229,17 @@ int Application::Run(HINSTANCE hInstance, int nCmdShow) { TranslateMessage(&message); DispatchMessageW(&message); - if (m_windowRuntime != nullptr) { - m_windowRuntime->PumpFrames( - App::EditorWindowFramePumpMode::AfterMessage); - } ++processedMessageCount; } - if (m_windowRuntime != nullptr) { + if (m_windowManager != nullptr) { ::XCEngine::Resources::ResourceManager::Get().UpdateAsyncLoads(); - m_windowRuntime->DestroyClosedWindows(); - if (!m_windowRuntime->HasWindows()) { + m_windowManager->DestroyClosedWindows(); + if (!m_windowManager->HasWindows()) { break; } - m_windowRuntime->PumpFrames(App::EditorWindowFramePumpMode::SteadyTick); + m_windowManager->RenderAllWindows(); } else { break; } @@ -356,8 +326,8 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP ? reinterpret_cast(createStruct->lpCreateParams) : nullptr; SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast(application)); - if (application != nullptr && application->m_windowRuntime != nullptr) { - application->m_windowRuntime->HandlePendingNativeWindowCreated(hwnd); + if (application != nullptr && application->m_windowManager != nullptr) { + application->m_windowManager->HandlePendingNativeWindowCreated(hwnd); } return TRUE; } @@ -365,8 +335,8 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP Application* application = GetApplicationFromWindowUserData(hwnd); LRESULT dispatcherResult = 0; if (application != nullptr && - application->m_windowRuntime != nullptr && - application->m_windowRuntime->TryDispatchWindowMessage( + application->m_windowManager != nullptr && + application->m_windowManager->TryDispatchWindowMessage( hwnd, message, wParam, @@ -380,4 +350,3 @@ LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP } // namespace XCEngine::UI::Editor - diff --git a/new_editor/app/Bootstrap/Application.h b/editor/app/Bootstrap/Application.h similarity index 83% rename from new_editor/app/Bootstrap/Application.h rename to editor/app/Bootstrap/Application.h index 7db1d6e6..f9eed748 100644 --- a/new_editor/app/Bootstrap/Application.h +++ b/editor/app/Bootstrap/Application.h @@ -12,8 +12,7 @@ namespace XCEngine::UI::Editor { namespace App { class EditorContext; -class EditorWindowApplicationComposition; -class Win32WindowApplicationRuntime; +class EditorWindowManager; } namespace System { @@ -48,8 +47,7 @@ private: ATOM m_windowClassAtom = 0; std::filesystem::path m_repoRoot = {}; std::unique_ptr m_editorContext = {}; - std::unique_ptr m_windowApplicationComposition = {}; - std::unique_ptr m_windowRuntime = {}; + std::unique_ptr m_windowManager = {}; std::unique_ptr m_systemInteractionHost = {}; }; diff --git a/new_editor/app/Bootstrap/EditorApp.rc b/editor/app/Bootstrap/EditorApp.rc similarity index 100% rename from new_editor/app/Bootstrap/EditorApp.rc rename to editor/app/Bootstrap/EditorApp.rc diff --git a/new_editor/app/Bootstrap/EditorResources.h b/editor/app/Bootstrap/EditorResources.h similarity index 100% rename from new_editor/app/Bootstrap/EditorResources.h rename to editor/app/Bootstrap/EditorResources.h diff --git a/new_editor/app/Commands/EditorEditCommandRoute.h b/editor/app/Commands/EditorEditCommandRoute.h similarity index 100% rename from new_editor/app/Commands/EditorEditCommandRoute.h rename to editor/app/Commands/EditorEditCommandRoute.h diff --git a/new_editor/app/Commands/EditorHostCommandBridge.cpp b/editor/app/Commands/EditorHostCommandBridge.cpp similarity index 100% rename from new_editor/app/Commands/EditorHostCommandBridge.cpp rename to editor/app/Commands/EditorHostCommandBridge.cpp diff --git a/new_editor/app/Commands/EditorHostCommandBridge.h b/editor/app/Commands/EditorHostCommandBridge.h similarity index 100% rename from new_editor/app/Commands/EditorHostCommandBridge.h rename to editor/app/Commands/EditorHostCommandBridge.h diff --git a/new_editor/app/Composition/EditorContext.cpp b/editor/app/Composition/EditorContext.cpp similarity index 94% rename from new_editor/app/Composition/EditorContext.cpp rename to editor/app/Composition/EditorContext.cpp index 0e99bc15..843b7a5e 100644 --- a/new_editor/app/Composition/EditorContext.cpp +++ b/editor/app/Composition/EditorContext.cpp @@ -70,6 +70,8 @@ bool EditorContext::Initialize(const std::filesystem::path& repoRoot) { m_sceneRuntime.Initialize(m_session.projectRoot); AppendUIEditorRuntimeTrace("startup", "EditorSceneRuntime::Initialize end"); m_sceneRuntime.BindSelectionService(&m_selectionService); + ResetEditorColorPickerToolState(m_colorPickerToolState); + ResetEditorUtilityWindowRequestState(m_utilityWindowRequestState); SyncSessionFromSelectionService(); m_hostCommandBridge.BindSession(m_session); m_hostCommandBridge.BindCommandFocusService(m_commandFocusService); @@ -157,6 +159,21 @@ const EditorSceneRuntime& EditorContext::GetSceneRuntime() const { return m_sceneRuntime; } +EditorColorPickerToolState& EditorContext::GetColorPickerToolState() { + return m_colorPickerToolState; +} + +const EditorColorPickerToolState& EditorContext::GetColorPickerToolState() const { + return m_colorPickerToolState; +} + +void EditorContext::RequestOpenUtilityWindow(EditorUtilityWindowKind kind) { + RequestEditorUtilityWindow(m_utilityWindowRequestState, kind); +} + +std::optional EditorContext::ConsumeOpenUtilityWindowRequest() { + return ConsumeEditorUtilityWindowRequest(m_utilityWindowRequestState); +} void EditorContext::SetSelection(EditorSelectionState selection) { m_selectionService.SetSelection(std::move(selection)); @@ -366,6 +383,3 @@ void EditorContext::AppendConsoleEntry( } // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Composition/EditorContext.h b/editor/app/Composition/EditorContext.h similarity index 87% rename from new_editor/app/Composition/EditorContext.h rename to editor/app/Composition/EditorContext.h index e59cffbd..14b5e1ec 100644 --- a/new_editor/app/Composition/EditorContext.h +++ b/editor/app/Composition/EditorContext.h @@ -3,11 +3,14 @@ #include "Composition/EditorShellVariant.h" #include "Project/EditorProjectRuntime.h" #include "Scene/EditorSceneRuntime.h" +#include "UtilityWindows/EditorUtilityWindowKind.h" #include "Commands/EditorHostCommandBridge.h" +#include "State/EditorColorPickerToolState.h" #include "State/EditorCommandFocusService.h" #include "State/EditorSelectionService.h" #include "State/EditorSession.h" +#include "State/EditorUtilityWindowRequestState.h" #include #include #include @@ -18,7 +21,6 @@ #include #include #include -#include namespace XCEngine::UI::Editor::System { class SystemInteractionService; @@ -51,6 +53,10 @@ public: const EditorProjectRuntime& GetProjectRuntime() const; EditorSceneRuntime& GetSceneRuntime(); const EditorSceneRuntime& GetSceneRuntime() const; + EditorColorPickerToolState& GetColorPickerToolState(); + const EditorColorPickerToolState& GetColorPickerToolState() const; + void RequestOpenUtilityWindow(EditorUtilityWindowKind kind); + std::optional ConsumeOpenUtilityWindowRequest(); void SetSelection(EditorSelectionState selection); void ClearSelection(); void SyncSessionFromSelectionService(); @@ -87,6 +93,8 @@ private: EditorSelectionService m_selectionService = {}; EditorProjectRuntime m_projectRuntime = {}; EditorSceneRuntime m_sceneRuntime = {}; + EditorColorPickerToolState m_colorPickerToolState = {}; + EditorUtilityWindowRequestState m_utilityWindowRequestState = {}; EditorHostCommandBridge m_hostCommandBridge = {}; System::SystemInteractionService* m_systemInteractionHost = nullptr; std::string m_lastStatus = {}; @@ -94,6 +102,3 @@ private: }; } // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Composition/EditorPanelIds.h b/editor/app/Composition/EditorPanelIds.h similarity index 100% rename from new_editor/app/Composition/EditorPanelIds.h rename to editor/app/Composition/EditorPanelIds.h diff --git a/new_editor/app/Composition/EditorShellAssetBuilder.cpp b/editor/app/Composition/EditorShellAssetBuilder.cpp similarity index 99% rename from new_editor/app/Composition/EditorShellAssetBuilder.cpp rename to editor/app/Composition/EditorShellAssetBuilder.cpp index 0d3a9f78..9e411d00 100644 --- a/new_editor/app/Composition/EditorShellAssetBuilder.cpp +++ b/editor/app/Composition/EditorShellAssetBuilder.cpp @@ -569,7 +569,7 @@ namespace XCEngine::UI::Editor::App { EditorShellAsset BuildEditorApplicationShellAsset(const std::filesystem::path& repoRoot) { EditorShellAsset asset = {}; asset.screenId = "editor.shell"; - asset.captureRootPath = (repoRoot / "new_editor/captures").lexically_normal(); + asset.captureRootPath = (repoRoot / "editor/captures").lexically_normal(); asset.panelRegistry = BuildEditorPanelRegistry(); asset.workspace = BuildEditorWorkspaceModel(asset.panelRegistry); asset.workspaceSession = diff --git a/new_editor/app/Composition/EditorShellAssetBuilder.h b/editor/app/Composition/EditorShellAssetBuilder.h similarity index 100% rename from new_editor/app/Composition/EditorShellAssetBuilder.h rename to editor/app/Composition/EditorShellAssetBuilder.h diff --git a/new_editor/app/Composition/EditorShellDrawComposer.cpp b/editor/app/Composition/EditorShellDrawComposer.cpp similarity index 100% rename from new_editor/app/Composition/EditorShellDrawComposer.cpp rename to editor/app/Composition/EditorShellDrawComposer.cpp diff --git a/new_editor/app/Composition/EditorShellDrawComposer.h b/editor/app/Composition/EditorShellDrawComposer.h similarity index 100% rename from new_editor/app/Composition/EditorShellDrawComposer.h rename to editor/app/Composition/EditorShellDrawComposer.h diff --git a/new_editor/app/Composition/EditorShellHostedPanelCoordinator.cpp b/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp similarity index 97% rename from new_editor/app/Composition/EditorShellHostedPanelCoordinator.cpp rename to editor/app/Composition/EditorShellHostedPanelCoordinator.cpp index 73ac5ddd..d5f26469 100644 --- a/new_editor/app/Composition/EditorShellHostedPanelCoordinator.cpp +++ b/editor/app/Composition/EditorShellHostedPanelCoordinator.cpp @@ -69,8 +69,6 @@ void EditorShellHostedPanelCoordinator::Update( hostedContentEvents); context.inspectorPanel.Update( context.context, - context.utilityWindowResultState, - context.utilityRequestSink, inspectorDispatchEntry, hostedContentEvents); context.context.SyncSessionFromCommandFocusService(); @@ -80,6 +78,3 @@ void EditorShellHostedPanelCoordinator::Update( } } // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Composition/EditorShellHostedPanelCoordinator.h b/editor/app/Composition/EditorShellHostedPanelCoordinator.h similarity index 84% rename from new_editor/app/Composition/EditorShellHostedPanelCoordinator.h rename to editor/app/Composition/EditorShellHostedPanelCoordinator.h index 1eded250..03354c4c 100644 --- a/new_editor/app/Composition/EditorShellHostedPanelCoordinator.h +++ b/editor/app/Composition/EditorShellHostedPanelCoordinator.h @@ -19,8 +19,6 @@ namespace XCEngine::UI::Editor::App { class ConsolePanel; class EditorContext; -class EditorUtilityWindowRequestSink; -struct EditorUtilityWindowResultState; class HierarchyPanel; class InspectorPanel; class ProjectPanel; @@ -28,8 +26,6 @@ class SceneViewportFeature; struct EditorShellHostedPanelCoordinatorContext { EditorContext& context; - EditorUtilityWindowResultState& utilityWindowResultState; - EditorUtilityWindowRequestSink& utilityRequestSink; UIEditorShellInteractionFrame& shellFrame; UIEditorShellInteractionState& shellInteractionState; const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents; @@ -47,7 +43,3 @@ public: }; } // namespace XCEngine::UI::Editor::App - - - - diff --git a/new_editor/app/Composition/EditorShellInteractionEngine.cpp b/editor/app/Composition/EditorShellInteractionEngine.cpp similarity index 100% rename from new_editor/app/Composition/EditorShellInteractionEngine.cpp rename to editor/app/Composition/EditorShellInteractionEngine.cpp diff --git a/new_editor/app/Composition/EditorShellInteractionEngine.h b/editor/app/Composition/EditorShellInteractionEngine.h similarity index 100% rename from new_editor/app/Composition/EditorShellInteractionEngine.h rename to editor/app/Composition/EditorShellInteractionEngine.h diff --git a/new_editor/app/Composition/EditorShellRuntime.cpp b/editor/app/Composition/EditorShellRuntime.cpp similarity index 96% rename from new_editor/app/Composition/EditorShellRuntime.cpp rename to editor/app/Composition/EditorShellRuntime.cpp index 7d4f16b6..1504459f 100644 --- a/new_editor/app/Composition/EditorShellRuntime.cpp +++ b/editor/app/Composition/EditorShellRuntime.cpp @@ -1,4 +1,4 @@ -#include "Composition/EditorShellRuntime.h" +#include "Composition/EditorShellRuntime.h" #include "Rendering/Host/UiTextureHost.h" #include "Rendering/Host/ViewportRenderHost.h" #include "Composition/EditorContext.h" @@ -91,11 +91,11 @@ void EditorShellRuntime::ClearExternalDockHostDropPreview() { .dockHostState.dropPreview = {}; } -ProjectPanel::CursorKind EditorShellRuntime::GetHostedContentCursorType() const { +ProjectPanel::CursorKind EditorShellRuntime::GetHostedContentCursorKind() const { return m_projectPanel.GetCursorKind(); } -Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorType() const { +Widgets::UIEditorDockHostCursorKind EditorShellRuntime::GetDockCursorKind() const { return Widgets::ResolveUIEditorDockHostCursorKind( m_shellFrame.workspaceInteractionFrame.dockHostFrame.layout); } @@ -163,8 +163,6 @@ namespace XCEngine::UI::Editor::App { void EditorShellRuntime::Update( EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, UIEditorWorkspaceController& workspaceController, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, @@ -208,8 +206,6 @@ void EditorShellRuntime::Update( m_hostedPanelCoordinator.Update( EditorShellHostedPanelCoordinatorContext{ .context = context, - .utilityWindowResultState = utilityWindowResultState, - .utilityRequestSink = utilityRequestSink, .shellFrame = m_shellFrame, .shellInteractionState = m_shellInteractionState, .inputEvents = inputEvents, @@ -229,6 +225,3 @@ void EditorShellRuntime::Update( } // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Composition/EditorShellRuntime.h b/editor/app/Composition/EditorShellRuntime.h similarity index 92% rename from new_editor/app/Composition/EditorShellRuntime.h rename to editor/app/Composition/EditorShellRuntime.h index a692fb15..2f198fbe 100644 --- a/new_editor/app/Composition/EditorShellRuntime.h +++ b/editor/app/Composition/EditorShellRuntime.h @@ -30,8 +30,6 @@ namespace XCEngine::UI::Editor::App { class EditorContext; -class EditorUtilityWindowRequestSink; -struct EditorUtilityWindowResultState; } // namespace XCEngine::UI::Editor::App @@ -44,7 +42,7 @@ class ViewportRenderHost; namespace XCEngine::Rendering { -struct RenderContext; +class RenderContext; } // namespace XCEngine::Rendering @@ -64,8 +62,6 @@ public: void Update( EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, UIEditorWorkspaceController& workspaceController, const ::XCEngine::UI::UIRect& bounds, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, @@ -86,8 +82,8 @@ public: const Widgets::UIEditorDockHostDropPreviewState& preview); void ClearExternalDockHostDropPreview(); - ProjectPanel::CursorKind GetHostedContentCursorType() const; - Widgets::UIEditorDockHostCursorKind GetDockCursorType() const; + ProjectPanel::CursorKind GetHostedContentCursorKind() const; + Widgets::UIEditorDockHostCursorKind GetDockCursorKind() const; bool TryResolveDockTabDragHotspot( std::string_view nodeId, std::string_view panelId, @@ -122,7 +118,3 @@ private: } // namespace XCEngine::UI::Editor::App - - - - diff --git a/new_editor/app/Composition/EditorShellSessionCoordinator.cpp b/editor/app/Composition/EditorShellSessionCoordinator.cpp similarity index 100% rename from new_editor/app/Composition/EditorShellSessionCoordinator.cpp rename to editor/app/Composition/EditorShellSessionCoordinator.cpp diff --git a/new_editor/app/Composition/EditorShellSessionCoordinator.h b/editor/app/Composition/EditorShellSessionCoordinator.h similarity index 100% rename from new_editor/app/Composition/EditorShellSessionCoordinator.h rename to editor/app/Composition/EditorShellSessionCoordinator.h diff --git a/new_editor/app/Composition/EditorShellVariant.h b/editor/app/Composition/EditorShellVariant.h similarity index 100% rename from new_editor/app/Composition/EditorShellVariant.h rename to editor/app/Composition/EditorShellVariant.h diff --git a/new_editor/app/Composition/EditorWindowWorkspaceStore.cpp b/editor/app/Composition/EditorWindowWorkspaceStore.cpp similarity index 100% rename from new_editor/app/Composition/EditorWindowWorkspaceStore.cpp rename to editor/app/Composition/EditorWindowWorkspaceStore.cpp diff --git a/new_editor/app/Composition/EditorWindowWorkspaceStore.h b/editor/app/Composition/EditorWindowWorkspaceStore.h similarity index 88% rename from new_editor/app/Composition/EditorWindowWorkspaceStore.h rename to editor/app/Composition/EditorWindowWorkspaceStore.h index 6c462d08..5b58c8fc 100644 --- a/new_editor/app/Composition/EditorWindowWorkspaceStore.h +++ b/editor/app/Composition/EditorWindowWorkspaceStore.h @@ -1,6 +1,6 @@ #pragma once -#include "Windowing/Workspace/UIEditorWindowWorkspaceController.h" +#include #include diff --git a/new_editor/app/Composition/WorkspaceEventSync.cpp b/editor/app/Composition/WorkspaceEventSync.cpp similarity index 100% rename from new_editor/app/Composition/WorkspaceEventSync.cpp rename to editor/app/Composition/WorkspaceEventSync.cpp diff --git a/new_editor/app/Composition/WorkspaceEventSync.h b/editor/app/Composition/WorkspaceEventSync.h similarity index 100% rename from new_editor/app/Composition/WorkspaceEventSync.h rename to editor/app/Composition/WorkspaceEventSync.h diff --git a/new_editor/app/Features/ColorPicker/ColorPickerPanel.cpp b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp similarity index 83% rename from new_editor/app/Features/ColorPicker/ColorPickerPanel.cpp rename to editor/app/Features/ColorPicker/ColorPickerPanel.cpp index 8d69256e..d4a92ff0 100644 --- a/new_editor/app/Features/ColorPicker/ColorPickerPanel.cpp +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.cpp @@ -1,5 +1,8 @@ #include "ColorPickerPanel.h" +#include "Composition/EditorContext.h" +#include "State/EditorColorPickerToolState.h" + #include #include @@ -84,14 +87,13 @@ void ColorPickerPanel::ResetInteractionState() { m_frame = {}; } -EditorUtilityWindowPanelOutput ColorPickerPanel::Update( - EditorUtilityWindowPanelServices services, +void ColorPickerPanel::Update( + EditorContext& context, const EditorUtilityWindowHostContext& hostContext, - const EditorUtilityWindowSession& session, const std::vector& inputEvents) { if (!hostContext.mounted) { ResetPanelState(); - return {}; + return; } m_visible = true; @@ -99,30 +101,33 @@ EditorUtilityWindowPanelOutput ColorPickerPanel::Update( m_metrics = BuildColorPickerPanelMetrics(m_bounds); m_palette = BuildColorPickerPanelPalette(); - const EditorUtilityWindowColorPickerPayload* payload = TryGetColorPickerPayload(session); - m_hasActiveTarget = payload != nullptr && payload->IsValid(); + EditorColorPickerToolState& toolState = context.GetColorPickerToolState(); + m_hasActiveTarget = + toolState.active && + !toolState.inspectorTarget.subjectKey.empty() && + !toolState.inspectorTarget.fieldId.empty(); if (!m_hasActiveTarget) { m_targetSubjectKey.clear(); m_targetFieldId.clear(); m_spec = {}; m_frame = {}; m_interactionState = {}; - return {}; + return; } const bool targetChanged = - m_targetSubjectKey != payload->targetSubjectKey || - m_targetFieldId != payload->targetFieldId; + m_targetSubjectKey != toolState.inspectorTarget.subjectKey || + m_targetFieldId != toolState.inspectorTarget.fieldId; if (targetChanged) { ResetInteractionState(); - m_targetSubjectKey = payload->targetSubjectKey; - m_targetFieldId = payload->targetFieldId; + m_targetSubjectKey = toolState.inspectorTarget.subjectKey; + m_targetFieldId = toolState.inspectorTarget.fieldId; } m_spec = {}; m_spec.fieldId = m_targetFieldId; - m_spec.value = payload->initialColor; - m_spec.showAlpha = payload->showAlpha; + m_spec.value = toolState.color; + m_spec.showAlpha = toolState.showAlpha; m_spec.readOnly = false; m_spec.embeddedEditor = true; @@ -162,19 +167,7 @@ EditorUtilityWindowPanelOutput ColorPickerPanel::Update( m_bounds); } - if (m_frame.result.colorChanged) { - return EditorUtilityWindowPanelOutput{ - .result = EditorUtilityWindowPanelResult{ - .type = EditorUtilityWindowPanelResult::Type::ColorPickerValueChanged, - .targetSubjectKey = m_targetSubjectKey, - .targetFieldId = m_targetFieldId, - .color = m_spec.value, - .showAlpha = payload->showAlpha, - }, - }; - } - - return {}; + UpdateEditorColorPickerToolColor(toolState, m_spec.value); } void ColorPickerPanel::Append(UIDrawList& drawList) const { @@ -213,4 +206,3 @@ void ColorPickerPanel::Append(UIDrawList& drawList) const { } } // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Features/ColorPicker/ColorPickerPanel.h b/editor/app/Features/ColorPicker/ColorPickerPanel.h similarity index 84% rename from new_editor/app/Features/ColorPicker/ColorPickerPanel.h rename to editor/app/Features/ColorPicker/ColorPickerPanel.h index 492fdf81..f9bb93fe 100644 --- a/new_editor/app/Features/ColorPicker/ColorPickerPanel.h +++ b/editor/app/Features/ColorPicker/ColorPickerPanel.h @@ -1,6 +1,6 @@ #pragma once -#include "Windowing/Utility/EditorUtilityWindowPanel.h" +#include "UtilityWindows/EditorUtilityWindowPanel.h" #include @@ -14,10 +14,9 @@ public: return "XCEditorUtility.ColorPicker"; } void ResetInteractionState() override; - EditorUtilityWindowPanelOutput Update( - EditorUtilityWindowPanelServices services, + void Update( + EditorContext& context, const EditorUtilityWindowHostContext& hostContext, - const EditorUtilityWindowSession& session, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; @@ -37,7 +36,3 @@ private: }; } // namespace XCEngine::UI::Editor::App - - - - diff --git a/new_editor/app/Features/Console/ConsolePanel.cpp b/editor/app/Features/Console/ConsolePanel.cpp similarity index 100% rename from new_editor/app/Features/Console/ConsolePanel.cpp rename to editor/app/Features/Console/ConsolePanel.cpp diff --git a/new_editor/app/Features/Console/ConsolePanel.h b/editor/app/Features/Console/ConsolePanel.h similarity index 100% rename from new_editor/app/Features/Console/ConsolePanel.h rename to editor/app/Features/Console/ConsolePanel.h diff --git a/new_editor/app/Features/Hierarchy/HierarchyModel.cpp b/editor/app/Features/Hierarchy/HierarchyModel.cpp similarity index 100% rename from new_editor/app/Features/Hierarchy/HierarchyModel.cpp rename to editor/app/Features/Hierarchy/HierarchyModel.cpp diff --git a/new_editor/app/Features/Hierarchy/HierarchyModel.h b/editor/app/Features/Hierarchy/HierarchyModel.h similarity index 100% rename from new_editor/app/Features/Hierarchy/HierarchyModel.h rename to editor/app/Features/Hierarchy/HierarchyModel.h diff --git a/new_editor/app/Features/Hierarchy/HierarchyPanel.cpp b/editor/app/Features/Hierarchy/HierarchyPanel.cpp similarity index 100% rename from new_editor/app/Features/Hierarchy/HierarchyPanel.cpp rename to editor/app/Features/Hierarchy/HierarchyPanel.cpp diff --git a/new_editor/app/Features/Hierarchy/HierarchyPanel.h b/editor/app/Features/Hierarchy/HierarchyPanel.h similarity index 100% rename from new_editor/app/Features/Hierarchy/HierarchyPanel.h rename to editor/app/Features/Hierarchy/HierarchyPanel.h diff --git a/new_editor/app/Features/Inspector/AddComponentPanel.cpp b/editor/app/Features/Inspector/AddComponentPanel.cpp similarity index 83% rename from new_editor/app/Features/Inspector/AddComponentPanel.cpp rename to editor/app/Features/Inspector/AddComponentPanel.cpp index 7c4df42c..811afb78 100644 --- a/new_editor/app/Features/Inspector/AddComponentPanel.cpp +++ b/editor/app/Features/Inspector/AddComponentPanel.cpp @@ -1,6 +1,6 @@ #include "Features/Inspector/AddComponentPanel.h" -#include "Windowing/Utility/EditorUtilityWindowFeatureCommands.h" +#include "Composition/EditorContext.h" #include "Features/Inspector/Components/IInspectorComponentEditor.h" #include "Features/Inspector/Components/InspectorComponentEditorRegistry.h" @@ -122,15 +122,8 @@ void AddComponentPanel::RebuildEntries( } bool AddComponentPanel::TryActivateEntry( - const EditorUtilityWindowSession& session, - std::size_t entryIndex, - EditorUtilityWindowPanelResult& outResult) const { - outResult = {}; - const EditorUtilityWindowAddComponentPayload* payload = TryGetAddComponentPayload(session); - if (payload == nullptr || !payload->IsValid()) { - return false; - } - + EditorContext& context, + std::size_t entryIndex) { if (entryIndex >= m_entries.size()) { return false; } @@ -140,9 +133,13 @@ bool AddComponentPanel::TryActivateEntry( return false; } - outResult.type = EditorUtilityWindowPanelResult::Type::AddComponent; - outResult.targetItemId = payload->targetItemId; - outResult.componentTypeName = entry.componentTypeName; + if (!context.GetSceneRuntime().AddComponentToSelectedGameObject(entry.componentTypeName)) { + return false; + } + + m_hasTarget = context.GetSceneRuntime().GetSelectedGameObject() != nullptr; + m_targetDisplayName = context.GetSceneRuntime().GetSelectedDisplayName(); + RebuildEntries(context.GetSceneRuntime().GetSelectedGameObject()); return true; } @@ -156,33 +153,20 @@ std::size_t AddComponentPanel::HitTestEntry(const UIPoint& point) const { return kInvalidEntryIndex; } -EditorUtilityWindowPanelOutput AddComponentPanel::Update( - EditorUtilityWindowPanelServices services, +void AddComponentPanel::Update( + EditorContext& context, const EditorUtilityWindowHostContext& hostContext, - const EditorUtilityWindowSession& session, const std::vector& inputEvents) { if (!hostContext.mounted) { ResetPanelState(); - return {}; + return; } m_visible = true; - const EditorUtilityWindowAddComponentPayload* payload = TryGetAddComponentPayload(session); - m_hasTarget = payload != nullptr && payload->IsValid(); - if (!m_hasTarget) { - m_targetDisplayName.clear(); - m_entries.clear(); - ResetInteractionState(); - return {}; - } m_bounds = hostContext.bounds; - const ::XCEngine::Components::GameObject* gameObject = - services.addComponentQueries != nullptr - ? services.addComponentQueries->FindTargetGameObject(payload->targetItemId) - : nullptr; - m_hasTarget = gameObject != nullptr; - m_targetDisplayName = payload->targetDisplayName; - RebuildEntries(gameObject); + m_hasTarget = context.GetSceneRuntime().GetSelectedGameObject() != nullptr; + m_targetDisplayName = context.GetSceneRuntime().GetSelectedDisplayName(); + RebuildEntries(context.GetSceneRuntime().GetSelectedGameObject()); if (hostContext.focusLost) { ResetInteractionState(); @@ -220,13 +204,7 @@ EditorUtilityWindowPanelOutput AddComponentPanel::Update( m_hoveredEntryIndex = HitTestEntry(event.position); if (m_pressedEntryIndex != kInvalidEntryIndex && m_pressedEntryIndex == m_hoveredEntryIndex) { - EditorUtilityWindowPanelResult result = {}; - if (TryActivateEntry(session, m_pressedEntryIndex, result)) { - return EditorUtilityWindowPanelOutput{ - .closeRequested = true, - .result = std::move(result), - }; - } + TryActivateEntry(context, m_pressedEntryIndex); } m_pressedEntryIndex = kInvalidEntryIndex; break; @@ -235,8 +213,6 @@ EditorUtilityWindowPanelOutput AddComponentPanel::Update( break; } } - - return {}; } void AddComponentPanel::Append(UIDrawList& drawList) const { @@ -326,11 +302,3 @@ void AddComponentPanel::Append(UIDrawList& drawList) const { } } // namespace XCEngine::UI::Editor::App - - - - - - - - diff --git a/new_editor/app/Features/Inspector/AddComponentPanel.h b/editor/app/Features/Inspector/AddComponentPanel.h similarity index 78% rename from new_editor/app/Features/Inspector/AddComponentPanel.h rename to editor/app/Features/Inspector/AddComponentPanel.h index 3414a13b..e21bcd27 100644 --- a/new_editor/app/Features/Inspector/AddComponentPanel.h +++ b/editor/app/Features/Inspector/AddComponentPanel.h @@ -1,6 +1,6 @@ #pragma once -#include "Windowing/Utility/EditorUtilityWindowPanel.h" +#include "UtilityWindows/EditorUtilityWindowPanel.h" #include #include @@ -18,10 +18,9 @@ public: return "XCEditorUtility.AddComponent"; } void ResetInteractionState() override; - EditorUtilityWindowPanelOutput Update( - EditorUtilityWindowPanelServices services, + void Update( + EditorContext& context, const EditorUtilityWindowHostContext& hostContext, - const EditorUtilityWindowSession& session, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override; void Append(::XCEngine::UI::UIDrawList& drawList) const override; @@ -36,10 +35,7 @@ private: void ResetPanelState(); void RebuildEntries(const ::XCEngine::Components::GameObject* gameObject); - bool TryActivateEntry( - const EditorUtilityWindowSession& session, - std::size_t entryIndex, - EditorUtilityWindowPanelResult& outResult) const; + bool TryActivateEntry(EditorContext& context, std::size_t entryIndex); std::size_t HitTestEntry(const ::XCEngine::UI::UIPoint& point) const; bool m_visible = false; @@ -52,7 +48,3 @@ private: }; } // namespace XCEngine::UI::Editor::App - - - - diff --git a/new_editor/app/Features/Inspector/Components/AudioListenerInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/AudioListenerInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/AudioListenerInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/AudioListenerInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/AudioSourceInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/AudioSourceInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/AudioSourceInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/AudioSourceInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/BoxColliderInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/BoxColliderInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/BoxColliderInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/BoxColliderInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/CameraInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/CameraInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/CameraInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/CameraInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/CapsuleColliderInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/CapsuleColliderInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/CapsuleColliderInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/CapsuleColliderInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/ColliderInspectorComponentEditorUtils.h b/editor/app/Features/Inspector/Components/ColliderInspectorComponentEditorUtils.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/ColliderInspectorComponentEditorUtils.h rename to editor/app/Features/Inspector/Components/ColliderInspectorComponentEditorUtils.h diff --git a/new_editor/app/Features/Inspector/Components/IInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/IInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/IInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/IInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.cpp b/editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.cpp similarity index 100% rename from new_editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.cpp rename to editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.cpp diff --git a/new_editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.h b/editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.h rename to editor/app/Features/Inspector/Components/InspectorBindingComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.cpp b/editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.cpp similarity index 100% rename from new_editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.cpp rename to editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.cpp diff --git a/new_editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.h b/editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.h rename to editor/app/Features/Inspector/Components/InspectorComponentEditorRegistry.h diff --git a/new_editor/app/Features/Inspector/Components/InspectorComponentEditorUtils.h b/editor/app/Features/Inspector/Components/InspectorComponentEditorUtils.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/InspectorComponentEditorUtils.h rename to editor/app/Features/Inspector/Components/InspectorComponentEditorUtils.h diff --git a/new_editor/app/Features/Inspector/Components/LightInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/LightInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/LightInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/LightInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/MeshFilterInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/MeshFilterInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/MeshFilterInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/MeshFilterInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/MeshRendererInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/MeshRendererInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/MeshRendererInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/MeshRendererInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/RigidbodyInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/RigidbodyInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/RigidbodyInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/RigidbodyInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/SphereColliderInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/SphereColliderInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/SphereColliderInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/SphereColliderInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.cpp b/editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.cpp similarity index 100% rename from new_editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.cpp rename to editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.cpp diff --git a/new_editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/TransformInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/Components/VolumeRendererInspectorComponentEditor.h b/editor/app/Features/Inspector/Components/VolumeRendererInspectorComponentEditor.h similarity index 100% rename from new_editor/app/Features/Inspector/Components/VolumeRendererInspectorComponentEditor.h rename to editor/app/Features/Inspector/Components/VolumeRendererInspectorComponentEditor.h diff --git a/new_editor/app/Features/Inspector/InspectorPanel.cpp b/editor/app/Features/Inspector/InspectorPanel.cpp similarity index 91% rename from new_editor/app/Features/Inspector/InspectorPanel.cpp rename to editor/app/Features/Inspector/InspectorPanel.cpp index 6ad4bac6..1f337e62 100644 --- a/new_editor/app/Features/Inspector/InspectorPanel.cpp +++ b/editor/app/Features/Inspector/InspectorPanel.cpp @@ -1,8 +1,7 @@ #include "InspectorPanel.h" #include "Composition/EditorContext.h" -#include "Windowing/Utility/EditorUtilityWindowResultState.h" -#include "Windowing/Utility/EditorUtilityWindowRequestSink.h" +#include "State/EditorColorPickerToolState.h" #include #include #include @@ -15,7 +14,6 @@ #include #include -#include namespace XCEngine::UI::Editor::App { @@ -241,6 +239,7 @@ void InspectorPanel::ResetInteractionState() { m_scrollVerticalOffset = 0.0f; m_interactionState = {}; m_gridFrame = {}; + m_lastAppliedColorPickerRevision = 0u; ResetAddComponentButtonState(); } @@ -555,66 +554,32 @@ void InspectorPanel::RefreshPresentation( } } -bool InspectorPanel::ApplyColorPickerToolValue( - EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState) { - const EditorUtilityWindowColorPickerResult& result = - utilityWindowResultState.colorPickerResult; - if (!result.active || - !IsEditorUtilityWindowColorPickerResultTarget( - utilityWindowResultState, +bool InspectorPanel::ApplyColorPickerToolValue(EditorContext& context) { + EditorColorPickerToolState& toolState = context.GetColorPickerToolState(); + if (m_sceneRuntime == nullptr || + !toolState.active || + toolState.revision == m_lastAppliedColorPickerRevision || + !IsEditorColorPickerToolTarget( + toolState, m_subjectKey, - result.targetFieldId)) { + toolState.inspectorTarget.fieldId)) { return false; } - const bool applied = TryApplyColorPickerResult( - context, - result.targetSubjectKey, - result.targetFieldId, - result.color); - ClearEditorUtilityWindowColorPickerResult(utilityWindowResultState); - return applied; -} -bool InspectorPanel::TryApplyColorPickerValue( - std::string_view targetSubjectKey, - std::string_view targetFieldId, - const UIColor& color) { - if (m_sceneRuntime == nullptr) { - return false; - } - - EditorContext* context = m_currentContext; - if (context == nullptr) { - return false; - } - - return TryApplyColorPickerResult( - *context, - targetSubjectKey, - targetFieldId, - color); -} -bool InspectorPanel::TryApplyColorPickerResult( - EditorContext& context, - std::string_view targetSubjectKey, - std::string_view targetFieldId, - const UIColor& color) { - if (m_sceneRuntime == nullptr || targetSubjectKey != m_subjectKey) { - return false; - } - - Widgets::UIEditorPropertyGridField* field = FindMutableField(targetFieldId); + Widgets::UIEditorPropertyGridField* field = + FindMutableField(toolState.inspectorTarget.fieldId); if (field == nullptr || field->kind != Widgets::UIEditorPropertyGridFieldKind::Color) { return false; } - if (AreColorsEqual(field->colorValue.value, color)) { + if (AreColorsEqual(field->colorValue.value, toolState.color)) { + m_lastAppliedColorPickerRevision = toolState.revision; return false; } - field->colorValue.value = color; + field->colorValue.value = toolState.color; const bool applied = ApplyChangedField(field->fieldId); + m_lastAppliedColorPickerRevision = toolState.revision; if (!applied) { ForceResyncPresentation(context); return false; @@ -625,8 +590,7 @@ bool InspectorPanel::TryApplyColorPickerResult( } void InspectorPanel::RequestColorPicker( - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, + EditorContext& context, std::string_view fieldId) { const Widgets::UIEditorPropertyGridField* field = FindField(fieldId); if (field == nullptr || @@ -635,15 +599,13 @@ void InspectorPanel::RequestColorPicker( return; } - EditorUtilityWindowSession session = {}; - session.type = EditorUtilityWindowType::ColorPicker; - session.payload = EditorUtilityWindowColorPickerPayload{ - .targetSubjectKey = m_subjectKey, - .targetFieldId = field->fieldId, - .initialColor = field->colorValue.value, - .showAlpha = field->colorValue.showAlpha, - }; - utilityRequestSink.Request(std::move(session)); + OpenEditorColorPickerToolForInspectorField( + context.GetColorPickerToolState(), + m_subjectKey, + field->fieldId, + field->colorValue.value, + field->colorValue.showAlpha); + context.RequestOpenUtilityWindow(EditorUtilityWindowKind::ColorPicker); } void InspectorPanel::ResetAddComponentButtonState() { @@ -653,7 +615,6 @@ void InspectorPanel::ResetAddComponentButtonState() { void InspectorPanel::UpdateAddComponentButton( EditorContext& context, - EditorUtilityWindowRequestSink& utilityRequestSink, const std::vector& inputEvents) { if (!ShouldShowAddComponentButton()) { ResetAddComponentButtonState(); @@ -694,13 +655,7 @@ void InspectorPanel::UpdateAddComponentButton( if (m_addComponentButtonPressed && ContainsPoint(buttonRect, event.position)) { - EditorUtilityWindowSession session = {}; - session.type = EditorUtilityWindowType::AddComponent; - session.payload = EditorUtilityWindowAddComponentPayload{ - .targetItemId = context.GetSceneRuntime().GetSelectedItemId(), - .targetDisplayName = context.GetSceneRuntime().GetSelectedDisplayName(), - }; - utilityRequestSink.Request(std::move(session)); + context.RequestOpenUtilityWindow(EditorUtilityWindowKind::AddComponent); } m_addComponentButtonHovered = ContainsPoint(buttonRect, event.position); @@ -769,8 +724,6 @@ bool InspectorPanel::ApplyChangedField(std::string_view fieldId) { void InspectorPanel::Update( EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, const UIEditorHostedPanelDispatchEntry& dispatchEntry, const std::vector& inputEvents) { if (!dispatchEntry.mounted) { @@ -781,7 +734,6 @@ void InspectorPanel::Update( m_visible = true; m_bounds = dispatchEntry.bounds; m_sceneRuntime = &context.GetSceneRuntime(); - m_currentContext = &context; m_textMeasurer = context.GetShellServices().textMeasurer; m_subject = BuildInspectorSubject(context.GetSession(), context.GetSceneRuntime()); @@ -793,7 +745,7 @@ void InspectorPanel::Update( } RefreshPresentation(context, subjectChanged); - ApplyColorPickerToolValue(context, utilityWindowResultState); + ApplyColorPickerToolValue(context); const std::vector filteredEvents = BuildUIEditorPanelInputEvents( @@ -862,10 +814,7 @@ void InspectorPanel::Update( m_gridFrame.result = interactionFrame.result; if (interactionFrame.result.pickerRequested && !interactionFrame.result.requestedFieldId.empty()) { - RequestColorPicker( - utilityWindowResultState, - utilityRequestSink, - interactionFrame.result.requestedFieldId); + RequestColorPicker(context, interactionFrame.result.requestedFieldId); } if (interactionFrame.result.fieldValueChanged && @@ -879,7 +828,7 @@ void InspectorPanel::Update( } RebuildScrollableLayout(); - UpdateAddComponentButton(context, utilityRequestSink, filteredEvents); + UpdateAddComponentButton(context, filteredEvents); } void InspectorPanel::Append(UIDrawList& drawList) const { @@ -1047,16 +996,3 @@ UIEditorHostCommandDispatchResult InspectorPanel::DispatchEditCommand( } } // namespace XCEngine::UI::Editor::App - - - - - - - - - - - - - diff --git a/new_editor/app/Features/Inspector/InspectorPanel.h b/editor/app/Features/Inspector/InspectorPanel.h similarity index 77% rename from new_editor/app/Features/Inspector/InspectorPanel.h rename to editor/app/Features/Inspector/InspectorPanel.h index 639b7e3f..6bce7cbc 100644 --- a/new_editor/app/Features/Inspector/InspectorPanel.h +++ b/editor/app/Features/Inspector/InspectorPanel.h @@ -2,7 +2,6 @@ #include "Features/Inspector/InspectorPresentationModel.h" #include "Features/Inspector/InspectorSubject.h" -#include "Windowing/Utility/EditorUtilityWindowFeatureCommands.h" #include "Commands/EditorEditCommandRoute.h" #include @@ -25,18 +24,12 @@ namespace XCEngine::UI::Editor::App { class EditorCommandFocusService; class EditorContext; class EditorSceneRuntime; -class EditorUtilityWindowRequestSink; -struct EditorUtilityWindowResultState; -class InspectorPanel final - : public EditorEditCommandRoute - , public EditorUtilityWindowColorPickerCommandPort { +class InspectorPanel final : public EditorEditCommandRoute { public: void SetCommandFocusService(EditorCommandFocusService* commandFocusService); void Update( EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, const UIEditorHostedPanelDispatchEntry& dispatchEntry, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents); void Append(::XCEngine::UI::UIDrawList& drawList) const; @@ -45,10 +38,6 @@ public: std::string_view commandId) const override; UIEditorHostCommandDispatchResult DispatchEditCommand( std::string_view commandId) override; - bool TryApplyColorPickerValue( - std::string_view targetSubjectKey, - std::string_view targetFieldId, - const ::XCEngine::UI::UIColor& color) override; private: void ResetPanelState(); @@ -73,28 +62,16 @@ private: void RebuildPresentation(EditorContext& context, bool subjectChanged); void RefreshPresentation(EditorContext& context, bool subjectChanged); void ForceResyncPresentation(EditorContext& context); - bool ApplyColorPickerToolValue( - EditorContext& context, - EditorUtilityWindowResultState& utilityWindowResultState); - bool TryApplyColorPickerResult( - EditorContext& context, - std::string_view targetSubjectKey, - std::string_view targetFieldId, - const ::XCEngine::UI::UIColor& color); - void RequestColorPicker( - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - std::string_view fieldId); + bool ApplyColorPickerToolValue(EditorContext& context); + void RequestColorPicker(EditorContext& context, std::string_view fieldId); void ResetAddComponentButtonState(); void UpdateAddComponentButton( EditorContext& context, - EditorUtilityWindowRequestSink& utilityRequestSink, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents); bool ApplyChangedField(std::string_view fieldId); EditorCommandFocusService* m_commandFocusService = nullptr; EditorSceneRuntime* m_sceneRuntime = nullptr; - EditorContext* m_currentContext = nullptr; bool m_visible = false; ::XCEngine::UI::UIRect m_bounds = {}; InspectorSubject m_subject = {}; @@ -112,17 +89,10 @@ private: std::uint64_t m_lastSceneSelectionStamp = 0u; std::uint64_t m_lastProjectSelectionStamp = 0u; std::uint64_t m_lastSceneInspectorRevision = 0u; + std::uint64_t m_lastAppliedColorPickerRevision = 0u; const ::XCEngine::UI::Editor::UIEditorTextMeasurer* m_textMeasurer = nullptr; bool m_addComponentButtonHovered = false; bool m_addComponentButtonPressed = false; }; } // namespace XCEngine::UI::Editor::App - - - - - - - - diff --git a/new_editor/app/Features/Inspector/InspectorPresentationModel.cpp b/editor/app/Features/Inspector/InspectorPresentationModel.cpp similarity index 100% rename from new_editor/app/Features/Inspector/InspectorPresentationModel.cpp rename to editor/app/Features/Inspector/InspectorPresentationModel.cpp diff --git a/new_editor/app/Features/Inspector/InspectorPresentationModel.h b/editor/app/Features/Inspector/InspectorPresentationModel.h similarity index 100% rename from new_editor/app/Features/Inspector/InspectorPresentationModel.h rename to editor/app/Features/Inspector/InspectorPresentationModel.h diff --git a/new_editor/app/Features/Inspector/InspectorSubject.cpp b/editor/app/Features/Inspector/InspectorSubject.cpp similarity index 100% rename from new_editor/app/Features/Inspector/InspectorSubject.cpp rename to editor/app/Features/Inspector/InspectorSubject.cpp diff --git a/new_editor/app/Features/Inspector/InspectorSubject.h b/editor/app/Features/Inspector/InspectorSubject.h similarity index 100% rename from new_editor/app/Features/Inspector/InspectorSubject.h rename to editor/app/Features/Inspector/InspectorSubject.h diff --git a/new_editor/app/Features/Project/ProjectBrowserModel.cpp b/editor/app/Features/Project/ProjectBrowserModel.cpp similarity index 100% rename from new_editor/app/Features/Project/ProjectBrowserModel.cpp rename to editor/app/Features/Project/ProjectBrowserModel.cpp diff --git a/new_editor/app/Features/Project/ProjectBrowserModel.h b/editor/app/Features/Project/ProjectBrowserModel.h similarity index 100% rename from new_editor/app/Features/Project/ProjectBrowserModel.h rename to editor/app/Features/Project/ProjectBrowserModel.h diff --git a/new_editor/app/Features/Project/ProjectPanel.cpp b/editor/app/Features/Project/ProjectPanel.cpp similarity index 99% rename from new_editor/app/Features/Project/ProjectPanel.cpp rename to editor/app/Features/Project/ProjectPanel.cpp index 16135cae..013387a4 100644 --- a/new_editor/app/Features/Project/ProjectPanel.cpp +++ b/editor/app/Features/Project/ProjectPanel.cpp @@ -1,4 +1,4 @@ -#include "ProjectPanel.h" +#include "ProjectPanel.h" #include "Rendering/Assets/BuiltInIcons.h" #include #include diff --git a/new_editor/app/Features/Project/ProjectPanel.h b/editor/app/Features/Project/ProjectPanel.h similarity index 100% rename from new_editor/app/Features/Project/ProjectPanel.h rename to editor/app/Features/Project/ProjectPanel.h diff --git a/new_editor/app/Features/Scene/SceneEditCommandRoute.cpp b/editor/app/Features/Scene/SceneEditCommandRoute.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneEditCommandRoute.cpp rename to editor/app/Features/Scene/SceneEditCommandRoute.cpp diff --git a/new_editor/app/Features/Scene/SceneEditCommandRoute.h b/editor/app/Features/Scene/SceneEditCommandRoute.h similarity index 100% rename from new_editor/app/Features/Scene/SceneEditCommandRoute.h rename to editor/app/Features/Scene/SceneEditCommandRoute.h diff --git a/new_editor/app/Features/Scene/SceneViewportController.cpp b/editor/app/Features/Scene/SceneViewportController.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportController.cpp rename to editor/app/Features/Scene/SceneViewportController.cpp diff --git a/new_editor/app/Features/Scene/SceneViewportController.h b/editor/app/Features/Scene/SceneViewportController.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportController.h rename to editor/app/Features/Scene/SceneViewportController.h diff --git a/new_editor/app/Features/Scene/SceneViewportFeature.cpp b/editor/app/Features/Scene/SceneViewportFeature.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportFeature.cpp rename to editor/app/Features/Scene/SceneViewportFeature.cpp diff --git a/new_editor/app/Features/Scene/SceneViewportFeature.h b/editor/app/Features/Scene/SceneViewportFeature.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportFeature.h rename to editor/app/Features/Scene/SceneViewportFeature.h diff --git a/new_editor/app/Features/Scene/SceneViewportSceneOverlay.cpp b/editor/app/Features/Scene/SceneViewportSceneOverlay.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportSceneOverlay.cpp rename to editor/app/Features/Scene/SceneViewportSceneOverlay.cpp diff --git a/new_editor/app/Features/Scene/SceneViewportSceneOverlay.h b/editor/app/Features/Scene/SceneViewportSceneOverlay.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportSceneOverlay.h rename to editor/app/Features/Scene/SceneViewportSceneOverlay.h diff --git a/new_editor/app/Features/Scene/SceneViewportToolOverlay.cpp b/editor/app/Features/Scene/SceneViewportToolOverlay.cpp similarity index 99% rename from new_editor/app/Features/Scene/SceneViewportToolOverlay.cpp rename to editor/app/Features/Scene/SceneViewportToolOverlay.cpp index 8654eecf..3efe9b53 100644 --- a/new_editor/app/Features/Scene/SceneViewportToolOverlay.cpp +++ b/editor/app/Features/Scene/SceneViewportToolOverlay.cpp @@ -206,7 +206,7 @@ bool SceneViewportToolOverlay::Initialize( Shutdown(renderer); const std::filesystem::path iconRoot = - (repoRoot / "new_editor" / "resources" / "Icons").lexically_normal(); + (repoRoot / "editor" / "resources" / "Icons").lexically_normal(); bool loadedAnyTexture = false; for (std::size_t index = 0; index < kToolButtonSpecs.size(); ++index) { const ToolButtonSpec& path = kToolButtonSpecs[index]; diff --git a/new_editor/app/Features/Scene/SceneViewportToolOverlay.h b/editor/app/Features/Scene/SceneViewportToolOverlay.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportToolOverlay.h rename to editor/app/Features/Scene/SceneViewportToolOverlay.h diff --git a/new_editor/app/Features/Scene/SceneViewportTransformGizmo.cpp b/editor/app/Features/Scene/SceneViewportTransformGizmo.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportTransformGizmo.cpp rename to editor/app/Features/Scene/SceneViewportTransformGizmo.cpp diff --git a/new_editor/app/Features/Scene/SceneViewportTransformGizmo.h b/editor/app/Features/Scene/SceneViewportTransformGizmo.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportTransformGizmo.h rename to editor/app/Features/Scene/SceneViewportTransformGizmo.h diff --git a/new_editor/app/Features/Scene/SceneViewportTransformGizmoSupport.cpp b/editor/app/Features/Scene/SceneViewportTransformGizmoSupport.cpp similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportTransformGizmoSupport.cpp rename to editor/app/Features/Scene/SceneViewportTransformGizmoSupport.cpp diff --git a/new_editor/app/Features/Scene/SceneViewportTransformGizmoSupport.h b/editor/app/Features/Scene/SceneViewportTransformGizmoSupport.h similarity index 100% rename from new_editor/app/Features/Scene/SceneViewportTransformGizmoSupport.h rename to editor/app/Features/Scene/SceneViewportTransformGizmoSupport.h diff --git a/new_editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp b/editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp similarity index 100% rename from new_editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp rename to editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp diff --git a/new_editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.h b/editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.h similarity index 100% rename from new_editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.h rename to editor/app/Platform/Win32/Chrome/BorderlessWindowChrome.h diff --git a/new_editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp b/editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp similarity index 100% rename from new_editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp rename to editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp diff --git a/new_editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.h b/editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.h similarity index 100% rename from new_editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.h rename to editor/app/Platform/Win32/Chrome/BorderlessWindowFrame.h diff --git a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp b/editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp similarity index 62% rename from new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp rename to editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp index 574ece04..7f41ac94 100644 --- a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp +++ b/editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp @@ -1,25 +1,26 @@ #include "Platform/Win32/Chrome/EditorWindowChromeController.h" -#include "Platform/Win32/Backend/Win32NativeWindowBackend.h" -#include "Platform/Win32/Chrome/EditorWindowChromeProjection.h" #include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" +#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" +#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" #include "Platform/Win32/Windowing/EditorWindowSupport.h" -#include #include #include +#include #include #include #include #include +#include #include namespace XCEngine::UI::Editor::App { using namespace EditorWindowSupport; +using ::XCEngine::UI::Layout::MeasureUITabStripHeaderWidth; using ::XCEngine::UI::UIColor; using ::XCEngine::UI::UIDrawList; using ::XCEngine::UI::UIPoint; @@ -27,8 +28,6 @@ using ::XCEngine::UI::UIRect; namespace { -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - constexpr float kTitleBarLogoExtent = 16.0f; constexpr float kTitleBarLogoInsetLeft = 8.0f; constexpr float kTitleBarLogoTextGap = 8.0f; @@ -39,6 +38,20 @@ bool IsVerboseResizeTraceEnabled() { return s_enabled; } +float ResolveDetachedTabWidth( + std::string_view text, + const UIEditorTextMeasurer* textMeasurer) { + const Widgets::UIEditorTabStripMetrics& metrics = ResolveUIEditorTabStripMetrics(); + Widgets::UIEditorTabStripItem item = {}; + item.title = std::string(text); + const float measuredLabelWidth = + Widgets::ResolveUIEditorTabStripMeasuredLabelWidth( + item, + metrics, + textMeasurer); + return MeasureUITabStripHeaderWidth(measuredLabelWidth, metrics.layoutMetrics); +} + UIRect BuildDetachedTitleLogoRect(const Host::BorderlessWindowChromeLayout& layout) { const float availableLeft = layout.titleBarRect.x; const float availableRight = layout.minimizeButtonRect.x; @@ -53,173 +66,165 @@ UIRect BuildDetachedTitleLogoRect(const Host::BorderlessWindowChromeLayout& layo return UIRect(clampedX, logoY, kTitleBarLogoExtent, kTitleBarLogoExtent); } -Host::BorderlessWindowChromeLayout BuildChromeLayout( - const EditorWindowChromeProjection& projection, - float clientWidthDips) { - return Host::BuildBorderlessWindowChromeLayout( - UIRect(0.0f, 0.0f, clientWidthDips, kBorderlessTitleBarHeightDips), - projection.useDetachedTitleBarTabStrip - ? projection.detachedTabStripLeadingWidth - : 0.0f); -} - -Domain::WindowCommand BuildSetWindowBoundsCommand( - const RECT& rect, - Domain::WindowCommand::BoundsMode boundsMode = - Domain::WindowCommand::BoundsMode::Default) { - return Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::SetWindowBounds, - .boundsMode = boundsMode, - .x = rect.left, - .y = rect.top, - .width = rect.right - rect.left, - .height = rect.bottom - rect.top, - }; -} - } // namespace -EditorWindowChromeController::EditorWindowChromeController( - Win32NativeWindowBackend& nativeWindowBackend, - Win32WindowCommandProjector& windowCommandProjector) - : m_nativeWindowBackend(nativeWindowBackend) - , m_windowCommandProjector(windowCommandProjector) { +void EditorWindowChromeController::Reset() { + m_chromeState = {}; + m_runtimeState.Reset(); } -void EditorWindowChromeController::Reset(EditorWindow& window) { - window.ResetChromeWindowState(); - window.ResetChromeState(); +void EditorWindowChromeController::SetWindowDpi(UINT dpi) { + m_runtimeState.SetWindowDpi(dpi); } -void EditorWindowChromeController::BeginInteractiveResize(EditorWindow& window) { - window.BeginInteractiveResize(); +UINT EditorWindowChromeController::GetWindowDpi() const { + return m_runtimeState.GetWindowDpi(); } -void EditorWindowChromeController::EndInteractiveResize(EditorWindow& window) { - window.EndInteractiveResize(); +float EditorWindowChromeController::GetDpiScale(float baseDpiScale) const { + return m_runtimeState.GetDpiScale(baseDpiScale); +} + +void EditorWindowChromeController::BeginInteractiveResize() { + m_runtimeState.BeginInteractiveResize(); +} + +void EditorWindowChromeController::EndInteractiveResize() { + m_runtimeState.EndInteractiveResize(); } void EditorWindowChromeController::BeginBorderlessResize( - EditorWindow& window, Host::BorderlessWindowResizeEdge edge, const POINT& initialScreenPoint, const RECT& initialWindowRect) { - window.BeginBorderlessResize(edge, initialScreenPoint, initialWindowRect); + m_runtimeState.BeginBorderlessResize(edge, initialScreenPoint, initialWindowRect); } -void EditorWindowChromeController::EndBorderlessResize(EditorWindow& window) { - window.EndBorderlessResize(); +void EditorWindowChromeController::EndBorderlessResize() { + m_runtimeState.EndBorderlessResize(); } -bool EditorWindowChromeController::IsBorderlessResizeActive( - const EditorWindow& window) const { - return window.IsBorderlessResizeActive(); +bool EditorWindowChromeController::IsBorderlessResizeActive() const { + return m_runtimeState.IsBorderlessResizeActive(); } -Host::BorderlessWindowResizeEdge EditorWindowChromeController::GetBorderlessResizeEdge( - const EditorWindow& window) const { - return window.GetBorderlessResizeEdge(); +Host::BorderlessWindowResizeEdge EditorWindowChromeController::GetBorderlessResizeEdge() const { + return m_runtimeState.GetBorderlessResizeEdge(); } -const POINT& EditorWindowChromeController::GetBorderlessResizeInitialScreenPoint( - const EditorWindow& window) const { - return window.GetBorderlessResizeInitialScreenPoint(); +const POINT& EditorWindowChromeController::GetBorderlessResizeInitialScreenPoint() const { + return m_runtimeState.GetBorderlessResizeInitialScreenPoint(); } -const RECT& EditorWindowChromeController::GetBorderlessResizeInitialWindowRect( - const EditorWindow& window) const { - return window.GetBorderlessResizeInitialWindowRect(); +const RECT& EditorWindowChromeController::GetBorderlessResizeInitialWindowRect() const { + return m_runtimeState.GetBorderlessResizeInitialWindowRect(); } void EditorWindowChromeController::SetHoveredBorderlessResizeEdge( - EditorWindow& window, Host::BorderlessWindowResizeEdge edge) { - window.SetHoveredBorderlessResizeEdge(edge); + m_runtimeState.SetHoveredBorderlessResizeEdge(edge); } -Host::BorderlessWindowResizeEdge EditorWindowChromeController::GetHoveredBorderlessResizeEdge( - const EditorWindow& window) const { - return window.GetHoveredBorderlessResizeEdge(); +Host::BorderlessWindowResizeEdge EditorWindowChromeController::GetHoveredBorderlessResizeEdge() + const { + return m_runtimeState.GetHoveredBorderlessResizeEdge(); } -void EditorWindowChromeController::SetBorderlessWindowMaximized( - EditorWindow& window, - bool maximized) { - window.SetBorderlessWindowMaximized(maximized); +void EditorWindowChromeController::SetPredictedClientPixelSize(UINT width, UINT height) { + m_runtimeState.SetPredictedClientPixelSize(width, height); } -bool EditorWindowChromeController::IsBorderlessWindowMaximized( - const EditorWindow& window) const { - return window.IsBorderlessWindowMaximized(); +void EditorWindowChromeController::ClearPredictedClientPixelSize() { + m_runtimeState.ClearPredictedClientPixelSize(); } -void EditorWindowChromeController::SetBorderlessWindowRestoreRect( - EditorWindow& window, - const RECT& rect) { - window.SetBorderlessWindowRestoreRect(rect); +bool EditorWindowChromeController::TryGetPredictedClientPixelSize( + UINT& outWidth, + UINT& outHeight) const { + return m_runtimeState.TryGetPredictedClientPixelSize(outWidth, outHeight); } -bool EditorWindowChromeController::TryGetBorderlessWindowRestoreRect( - const EditorWindow& window, - RECT& outRect) const { - return window.TryGetBorderlessWindowRestoreRect(outRect); +void EditorWindowChromeController::MarkPredictedClientPixelSizePresented() { + m_runtimeState.MarkPredictedClientPixelSizePresented(); +} + +bool EditorWindowChromeController::ConsumePresentedPredictedClientPixelSizeMatch( + UINT width, + UINT height) { + return m_runtimeState.ConsumePresentedPredictedClientPixelSizeMatch(width, height); +} + +void EditorWindowChromeController::RequestSkipNextSteadyStateFrame() { + m_runtimeState.RequestSkipNextSteadyStateFrame(); +} + +bool EditorWindowChromeController::ConsumeSkipNextSteadyStateFrame() { + return m_runtimeState.ConsumeSkipNextSteadyStateFrame(); +} + +void EditorWindowChromeController::SetBorderlessWindowMaximized(bool maximized) { + m_runtimeState.SetBorderlessWindowMaximized(maximized); +} + +bool EditorWindowChromeController::IsBorderlessWindowMaximized() const { + return m_runtimeState.IsBorderlessWindowMaximized(); +} + +void EditorWindowChromeController::SetBorderlessWindowRestoreRect(const RECT& rect) { + m_runtimeState.SetBorderlessWindowRestoreRect(rect); +} + +bool EditorWindowChromeController::TryGetBorderlessWindowRestoreRect(RECT& outRect) const { + return m_runtimeState.TryGetBorderlessWindowRestoreRect(outRect); } void EditorWindowChromeController::BeginBorderlessWindowDragRestore( - EditorWindow& window, const POINT& initialScreenPoint) { - window.BeginBorderlessWindowDragRestore(initialScreenPoint); + m_runtimeState.BeginBorderlessWindowDragRestore(initialScreenPoint); } -void EditorWindowChromeController::EndBorderlessWindowDragRestore( - EditorWindow& window) { - window.EndBorderlessWindowDragRestore(); +void EditorWindowChromeController::EndBorderlessWindowDragRestore() { + m_runtimeState.EndBorderlessWindowDragRestore(); } -bool EditorWindowChromeController::IsBorderlessWindowDragRestoreArmed( - const EditorWindow& window) const { - return window.IsBorderlessWindowDragRestoreArmed(); +bool EditorWindowChromeController::IsBorderlessWindowDragRestoreArmed() const { + return m_runtimeState.IsBorderlessWindowDragRestoreArmed(); } -const POINT& EditorWindowChromeController::GetBorderlessWindowDragRestoreInitialScreenPoint( - const EditorWindow& window) const { - return window.GetBorderlessWindowDragRestoreInitialScreenPoint(); +const POINT& EditorWindowChromeController::GetBorderlessWindowDragRestoreInitialScreenPoint() + const { + return m_runtimeState.GetBorderlessWindowDragRestoreInitialScreenPoint(); } -Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::GetHoveredChromeTarget( - const EditorWindow& window) const { - return window.GetHoveredChromeTarget(); +Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::GetHoveredChromeTarget() const { + return m_chromeState.hoveredTarget; } void EditorWindowChromeController::SetHoveredChromeTarget( - EditorWindow& window, Host::BorderlessWindowChromeHitTarget target) { - window.SetHoveredChromeTarget(target); + m_chromeState.hoveredTarget = target; } -Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::GetPressedChromeTarget( - const EditorWindow& window) const { - return window.GetPressedChromeTarget(); +Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::GetPressedChromeTarget() const { + return m_chromeState.pressedTarget; } void EditorWindowChromeController::SetPressedChromeTarget( - EditorWindow& window, Host::BorderlessWindowChromeHitTarget target) { - window.SetPressedChromeTarget(target); + m_chromeState.pressedTarget = target; } -void EditorWindowChromeController::ResetChromeState(EditorWindow& window) { - window.ResetChromeState(); +void EditorWindowChromeController::ResetChromeState() { + m_chromeState = {}; } -bool EditorWindowChromeController::IsChromeStateClear( - const EditorWindow& window) const { - return window.IsChromeStateClear(); +bool EditorWindowChromeController::IsChromeStateClear() const { + return m_chromeState.hoveredTarget == Host::BorderlessWindowChromeHitTarget::None && + m_chromeState.pressedTarget == Host::BorderlessWindowChromeHitTarget::None; } -const Host::BorderlessWindowChromeState& EditorWindowChromeController::GetChromeState( - const EditorWindow& window) const { - return window.GetChromeState(); +const Host::BorderlessWindowChromeState& EditorWindowChromeController::GetChromeState() const { + return m_chromeState; } bool EditorWindowChromeController::HandleSystemCommand( @@ -233,7 +238,7 @@ bool EditorWindowChromeController::HandleSystemCommand( ToggleMaximizeRestore(window, editorContext, globalTabDragActive); return true; case SC_RESTORE: - if (hwnd != nullptr && !m_nativeWindowBackend.IsWindowMinimized(hwnd)) { + if (hwnd != nullptr && !IsIconic(hwnd)) { ToggleMaximizeRestore(window, editorContext, globalTabDragActive); return true; } @@ -246,7 +251,7 @@ bool EditorWindowChromeController::HandleSystemCommand( bool EditorWindowChromeController::HandleGetMinMaxInfo( const EditorWindow& window, LPARAM lParam) const { - const ::XCEngine::UI::UISize minimumOuterSize = window.ResolveMinimumOuterSize(); + const ::XCEngine::UI::UISize minimumOuterSize = window.m_runtime->ResolveMinimumOuterSize(); return Host::HandleBorderlessWindowGetMinMaxInfo( window.GetHwnd(), lParam, @@ -262,25 +267,21 @@ LRESULT EditorWindowChromeController::HandleNcCalcSize( window.GetHwnd(), wParam, lParam, - window.GetWindowDpi()); + GetWindowDpi()); } -bool EditorWindowChromeController::UpdateResizeHover( - EditorWindow& window, - LPARAM lParam) { +bool EditorWindowChromeController::UpdateResizeHover(EditorWindow& window, LPARAM lParam) { const Host::BorderlessWindowResizeEdge hoveredEdge = HitTestResizeEdge(window, lParam); - if (GetHoveredBorderlessResizeEdge(window) == hoveredEdge) { + if (GetHoveredBorderlessResizeEdge() == hoveredEdge) { return false; } - SetHoveredBorderlessResizeEdge(window, hoveredEdge); - ApplyResizeCursorHoverPriority(window); + SetHoveredBorderlessResizeEdge(hoveredEdge); + ApplyResizeCursorHoverPriority(); return true; } -bool EditorWindowChromeController::HandleResizeButtonDown( - EditorWindow& window, - LPARAM lParam) { +bool EditorWindowChromeController::HandleResizeButtonDown(EditorWindow& window, LPARAM lParam) { const Host::BorderlessWindowResizeEdge edge = HitTestResizeEdge(window, lParam); const HWND hwnd = window.GetHwnd(); if (edge == Host::BorderlessWindowResizeEdge::None || hwnd == nullptr) { @@ -288,28 +289,27 @@ bool EditorWindowChromeController::HandleResizeButtonDown( } POINT screenPoint = {}; - if (!m_nativeWindowBackend.TryGetCursorScreenPoint(screenPoint)) { + if (!GetCursorPos(&screenPoint)) { return false; } RECT windowRect = {}; - if (!m_nativeWindowBackend.TryGetWindowRect(hwnd, windowRect)) { + if (!GetWindowRect(hwnd, &windowRect)) { return false; } - BeginBorderlessResize(window, edge, screenPoint, windowRect); + BeginBorderlessResize(edge, screenPoint, windowRect); window.AcquirePointerCapture(EditorWindowPointerCaptureOwner::BorderlessResize); window.InvalidateHostWindow(); return true; } bool EditorWindowChromeController::HandleResizeButtonUp(EditorWindow& window) { - if (!IsBorderlessResizeActive(window)) { + if (!IsBorderlessResizeActive()) { return false; } - EndBorderlessResize(window); - window.ClearPredictedClientPixelSize(); + EndBorderlessResize(); window.ReleasePointerCapture(EditorWindowPointerCaptureOwner::BorderlessResize); window.InvalidateHostWindow(); return true; @@ -317,24 +317,24 @@ bool EditorWindowChromeController::HandleResizeButtonUp(EditorWindow& window) { bool EditorWindowChromeController::HandleResizePointerMove( EditorWindow& window, - EditorContext&, - bool) { + EditorContext& editorContext, + bool globalTabDragActive) { const HWND hwnd = window.GetHwnd(); - if (!IsBorderlessResizeActive(window) || hwnd == nullptr) { + if (!IsBorderlessResizeActive() || hwnd == nullptr) { return false; } POINT currentScreenPoint = {}; - if (!m_nativeWindowBackend.TryGetCursorScreenPoint(currentScreenPoint)) { + if (!GetCursorPos(¤tScreenPoint)) { return false; } - const ::XCEngine::UI::UISize minimumOuterSize = window.ResolveMinimumOuterSize(); + const ::XCEngine::UI::UISize minimumOuterSize = window.m_runtime->ResolveMinimumOuterSize(); RECT targetRect = Host::ComputeBorderlessWindowResizeRect( - GetBorderlessResizeInitialWindowRect(window), - GetBorderlessResizeInitialScreenPoint(window), + GetBorderlessResizeInitialWindowRect(), + GetBorderlessResizeInitialScreenPoint(), currentScreenPoint, - GetBorderlessResizeEdge(window), + GetBorderlessResizeEdge(), static_cast(minimumOuterSize.width), static_cast(minimumOuterSize.height)); const int width = targetRect.right - targetRect.left; @@ -344,15 +344,19 @@ bool EditorWindowChromeController::HandleResizePointerMove( } const auto resizeStepBegin = std::chrono::steady_clock::now(); - window.SetPredictedClientPixelSize( + SetPredictedClientPixelSize( static_cast(width), static_cast(height)); const auto applyResizeBegin = std::chrono::steady_clock::now(); if (window.ApplyWindowResize(static_cast(width), static_cast(height))) { const auto immediateFrameBegin = std::chrono::steady_clock::now(); - window.RequestInteractionFrame(); + window.QueueCompletedImmediateFrame( + EditorWindowFrameDriver::DriveImmediateFrame( + window, + editorContext, + globalTabDragActive)); const auto immediateFrameEnd = std::chrono::steady_clock::now(); - window.MarkPredictedClientPixelSizePresented(); + MarkPredictedClientPixelSizePresented(); if (IsVerboseResizeTraceEnabled()) { const auto totalEnd = std::chrono::steady_clock::now(); const auto applyResizeMs = @@ -375,11 +379,15 @@ bool EditorWindowChromeController::HandleResizePointerMove( } const auto setWindowPosBegin = std::chrono::steady_clock::now(); - m_windowCommandProjector.ProjectCommand( + SetWindowPos( hwnd, - BuildSetWindowBoundsCommand( - targetRect, - Domain::WindowCommand::BoundsMode::InteractiveResizeNoRedraw)); + nullptr, + targetRect.left, + targetRect.top, + width, + height, + SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOREDRAW); + ValidateRect(hwnd, nullptr); if (IsVerboseResizeTraceEnabled()) { const auto totalEnd = std::chrono::steady_clock::now(); const auto setWindowPosMs = @@ -399,27 +407,26 @@ bool EditorWindowChromeController::HandleResizePointerMove( } void EditorWindowChromeController::ClearResizeState(EditorWindow& window) { - if (IsBorderlessResizeActive(window)) { + if (IsBorderlessResizeActive()) { return; } - if (GetHoveredBorderlessResizeEdge(window) == Host::BorderlessWindowResizeEdge::None) { + if (GetHoveredBorderlessResizeEdge() == Host::BorderlessWindowResizeEdge::None) { return; } - SetHoveredBorderlessResizeEdge(window, Host::BorderlessWindowResizeEdge::None); + SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge::None); window.InvalidateHostWindow(); } void EditorWindowChromeController::ForceClearResizeState(EditorWindow& window) { - if (GetHoveredBorderlessResizeEdge(window) == Host::BorderlessWindowResizeEdge::None && - !IsBorderlessResizeActive(window)) { + if (GetHoveredBorderlessResizeEdge() == Host::BorderlessWindowResizeEdge::None && + !IsBorderlessResizeActive()) { return; } - SetHoveredBorderlessResizeEdge(window, Host::BorderlessWindowResizeEdge::None); - EndBorderlessResize(window); - window.ClearPredictedClientPixelSize(); + SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge::None); + EndBorderlessResize(); window.ReleasePointerCapture(EditorWindowPointerCaptureOwner::BorderlessResize); window.InvalidateHostWindow(); } @@ -428,12 +435,12 @@ Host::BorderlessWindowResizeEdge EditorWindowChromeController::HitTestResizeEdge const EditorWindow& window, LPARAM lParam) const { const HWND hwnd = window.GetHwnd(); - if (hwnd == nullptr || IsBorderlessWindowMaximized(window)) { + if (hwnd == nullptr || IsBorderlessWindowMaximized()) { return Host::BorderlessWindowResizeEdge::None; } RECT clientRect = {}; - if (!m_nativeWindowBackend.TryGetClientRect(hwnd, clientRect)) { + if (!GetClientRect(hwnd, &clientRect)) { return Host::BorderlessWindowResizeEdge::None; } @@ -446,14 +453,12 @@ Host::BorderlessWindowResizeEdge EditorWindowChromeController::HitTestResizeEdge window.ConvertClientPixelsToDips(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); } -bool EditorWindowChromeController::UpdateChromeHover( - EditorWindow& window, - LPARAM lParam) { - if (GetHoveredBorderlessResizeEdge(window) != Host::BorderlessWindowResizeEdge::None || - IsBorderlessResizeActive(window)) { +bool EditorWindowChromeController::UpdateChromeHover(EditorWindow& window, LPARAM lParam) { + if (GetHoveredBorderlessResizeEdge() != Host::BorderlessWindowResizeEdge::None || + IsBorderlessResizeActive()) { const bool changed = - GetHoveredChromeTarget(window) != Host::BorderlessWindowChromeHitTarget::None; - SetHoveredChromeTarget(window, Host::BorderlessWindowChromeHitTarget::None); + GetHoveredChromeTarget() != Host::BorderlessWindowChromeHitTarget::None; + SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget::None); return changed; } @@ -464,19 +469,17 @@ bool EditorWindowChromeController::UpdateChromeHover( hitTarget == Host::BorderlessWindowChromeHitTarget::CloseButton ? hitTarget : Host::BorderlessWindowChromeHitTarget::None; - if (GetHoveredChromeTarget(window) == buttonTarget) { + if (GetHoveredChromeTarget() == buttonTarget) { return false; } - SetHoveredChromeTarget(window, buttonTarget); + SetHoveredChromeTarget(buttonTarget); return true; } -bool EditorWindowChromeController::HandleChromeButtonDown( - EditorWindow& window, - LPARAM lParam) { - if (GetHoveredBorderlessResizeEdge(window) != Host::BorderlessWindowResizeEdge::None || - IsBorderlessResizeActive(window)) { +bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window, LPARAM lParam) { + if (GetHoveredBorderlessResizeEdge() != Host::BorderlessWindowResizeEdge::None || + IsBorderlessResizeActive()) { return false; } @@ -486,27 +489,23 @@ bool EditorWindowChromeController::HandleChromeButtonDown( case Host::BorderlessWindowChromeHitTarget::MinimizeButton: case Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton: case Host::BorderlessWindowChromeHitTarget::CloseButton: - SetPressedChromeTarget(window, hitTarget); + SetPressedChromeTarget(hitTarget); window.AcquirePointerCapture(EditorWindowPointerCaptureOwner::BorderlessChrome); window.InvalidateHostWindow(); return true; case Host::BorderlessWindowChromeHitTarget::DragRegion: if (hwnd != nullptr) { - if (IsBorderlessWindowMaximized(window)) { + if (IsBorderlessWindowMaximized()) { POINT screenPoint = {}; - if (m_nativeWindowBackend.TryGetCursorScreenPoint(screenPoint)) { - BeginBorderlessWindowDragRestore(window, screenPoint); + if (GetCursorPos(&screenPoint)) { + BeginBorderlessWindowDragRestore(screenPoint); window.AcquirePointerCapture(EditorWindowPointerCaptureOwner::BorderlessChrome); return true; } } window.ForceReleasePointerCapture(); - m_windowCommandProjector.ProjectCommand( - hwnd, - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::BeginCaptionDrag, - }); + SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); } return true; case Host::BorderlessWindowChromeHitTarget::None: @@ -520,12 +519,12 @@ bool EditorWindowChromeController::HandleChromeButtonUp( EditorContext& editorContext, bool globalTabDragActive, LPARAM lParam) { - if (IsBorderlessWindowDragRestoreArmed(window)) { + if (IsBorderlessWindowDragRestoreArmed()) { ClearChromeDragRestoreState(window); return true; } - const Host::BorderlessWindowChromeHitTarget pressedTarget = GetPressedChromeTarget(window); + const Host::BorderlessWindowChromeHitTarget pressedTarget = GetPressedChromeTarget(); if (pressedTarget != Host::BorderlessWindowChromeHitTarget::MinimizeButton && pressedTarget != Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton && pressedTarget != Host::BorderlessWindowChromeHitTarget::CloseButton) { @@ -533,7 +532,7 @@ bool EditorWindowChromeController::HandleChromeButtonUp( } const Host::BorderlessWindowChromeHitTarget releasedTarget = HitTestChrome(window, lParam); - SetPressedChromeTarget(window, Host::BorderlessWindowChromeHitTarget::None); + SetPressedChromeTarget(Host::BorderlessWindowChromeHitTarget::None); window.ReleasePointerCapture(EditorWindowPointerCaptureOwner::BorderlessChrome); window.InvalidateHostWindow(); @@ -548,7 +547,7 @@ bool EditorWindowChromeController::HandleChromeDoubleClick( EditorContext& editorContext, bool globalTabDragActive, LPARAM lParam) { - if (IsBorderlessWindowDragRestoreArmed(window)) { + if (IsBorderlessWindowDragRestoreArmed()) { ClearChromeDragRestoreState(window); } @@ -569,28 +568,29 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove( EditorContext& editorContext, bool globalTabDragActive) { const HWND hwnd = window.GetHwnd(); - if (!IsBorderlessWindowDragRestoreArmed(window) || hwnd == nullptr) { + if (!IsBorderlessWindowDragRestoreArmed() || hwnd == nullptr) { return false; } POINT currentScreenPoint = {}; - if (!m_nativeWindowBackend.TryGetCursorScreenPoint(currentScreenPoint)) { + if (!GetCursorPos(¤tScreenPoint)) { return true; } - const POINT initialScreenPoint = GetBorderlessWindowDragRestoreInitialScreenPoint(window); - const POINT dragThreshold = m_nativeWindowBackend.QueryPointerDragThreshold(); + const POINT initialScreenPoint = GetBorderlessWindowDragRestoreInitialScreenPoint(); + const int dragThresholdX = (std::max)(GetSystemMetrics(SM_CXDRAG), 1); + const int dragThresholdY = (std::max)(GetSystemMetrics(SM_CYDRAG), 1); const LONG deltaX = currentScreenPoint.x - initialScreenPoint.x; const LONG deltaY = currentScreenPoint.y - initialScreenPoint.y; - if (std::abs(deltaX) < dragThreshold.x && - std::abs(deltaY) < dragThreshold.y) { + if (std::abs(deltaX) < dragThresholdX && + std::abs(deltaY) < dragThresholdY) { return true; } RECT restoreRect = {}; RECT currentRect = {}; RECT workAreaRect = {}; - if (!TryGetBorderlessWindowRestoreRect(window, restoreRect) || + if (!TryGetBorderlessWindowRestoreRect(restoreRect) || !QueryCurrentWindowRect(window, currentRect) || !QueryBorderlessWindowWorkAreaRect(window, workAreaRect)) { ClearChromeDragRestoreState(window); @@ -629,33 +629,28 @@ bool EditorWindowChromeController::HandleChromeDragRestorePointerMove( newTop + restoreHeight }; - SetBorderlessWindowMaximized(window, false); + SetBorderlessWindowMaximized(false); ApplyPredictedWindowRectTransition(window, editorContext, globalTabDragActive, targetRect); ClearChromeDragRestoreState(window); - m_windowCommandProjector.ProjectCommand( - hwnd, - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::BeginCaptionDrag, - }); + SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); return true; } -void EditorWindowChromeController::ClearChromeDragRestoreState( - EditorWindow& window) { - if (!IsBorderlessWindowDragRestoreArmed(window)) { +void EditorWindowChromeController::ClearChromeDragRestoreState(EditorWindow& window) { + if (!IsBorderlessWindowDragRestoreArmed()) { return; } - EndBorderlessWindowDragRestore(window); + EndBorderlessWindowDragRestore(); window.ReleasePointerCapture(EditorWindowPointerCaptureOwner::BorderlessChrome); } void EditorWindowChromeController::ClearChromeState(EditorWindow& window) { - if (IsChromeStateClear(window)) { + if (IsChromeStateClear()) { return; } - ResetChromeState(window); + ResetChromeState(); window.InvalidateHostWindow(); } @@ -668,7 +663,7 @@ Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::HitTestChrom } RECT clientRect = {}; - if (!m_nativeWindowBackend.TryGetClientRect(hwnd, clientRect)) { + if (!GetClientRect(hwnd, &clientRect)) { return Host::BorderlessWindowChromeHitTarget::None; } @@ -684,22 +679,37 @@ Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::HitTestChrom Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLayout( const EditorWindow& window, float clientWidthDips) const { - return BuildChromeLayout(window.BuildChromeProjection(), clientWidthDips); + float leadingOccupiedRight = 0.0f; + if (ShouldUseDetachedTitleBarTabStrip(window)) { + const EditorWindowTitleBarBinding* titleBarBinding = + window.m_runtime->TryGetTitleBarBinding(); + leadingOccupiedRight = ResolveDetachedTabWidth( + titleBarBinding != nullptr + ? titleBarBinding->ResolveTabStripTitleText("Panel") + : std::string("Panel"), + &window.m_runtime->GetTextMeasurer()); + } + + return Host::BuildBorderlessWindowChromeLayout( + UIRect(0.0f, 0.0f, clientWidthDips, kBorderlessTitleBarHeightDips), + leadingOccupiedRight); } bool EditorWindowChromeController::ShouldUseDetachedTitleBarTabStrip( const EditorWindow& window) const { - return window.BuildChromeProjection().useDetachedTitleBarTabStrip; + const EditorWindowTitleBarBinding* titleBarBinding = window.m_runtime->TryGetTitleBarBinding(); + return !window.IsPrimary() && + titleBarBinding != nullptr && + titleBarBinding->ShouldUseDetachedTitleBarTabStrip(); } void EditorWindowChromeController::AppendChrome( const EditorWindow& window, UIDrawList& drawList, float clientWidthDips) const { - const EditorWindowChromeProjection projection = window.BuildChromeProjection(); const Host::BorderlessWindowChromeLayout layout = - BuildChromeLayout(projection, clientWidthDips); - const bool useDetachedTitleBarTabStrip = projection.useDetachedTitleBarTabStrip; + ResolveChromeLayout(window, clientWidthDips); + const bool useDetachedTitleBarTabStrip = ShouldUseDetachedTitleBarTabStrip(window); if (!useDetachedTitleBarTabStrip) { drawList.AddFilledRect(layout.titleBarRect, kShellSurfaceColor); drawList.AddLine( @@ -713,10 +723,10 @@ void EditorWindowChromeController::AppendChrome( if (!window.IsPrimary()) { if (useDetachedTitleBarTabStrip) { - if (projection.titleBarLogoIcon.IsValid()) { + if (window.m_runtime->GetTitleBarLogoIcon().IsValid()) { drawList.AddImage( BuildDetachedTitleLogoRect(layout), - projection.titleBarLogoIcon, + window.m_runtime->GetTitleBarLogoIcon(), UIColor(1.0f, 1.0f, 1.0f, 1.0f)); } } else { @@ -724,17 +734,17 @@ void EditorWindowChromeController::AppendChrome( const float iconY = layout.titleBarRect.y + (std::max)(0.0f, (layout.titleBarRect.height - kTitleBarLogoExtent) * 0.5f); - if (projection.titleBarLogoIcon.IsValid()) { + if (window.m_runtime->GetTitleBarLogoIcon().IsValid()) { drawList.AddImage( UIRect(iconX, iconY, kTitleBarLogoExtent, kTitleBarLogoExtent), - projection.titleBarLogoIcon, + window.m_runtime->GetTitleBarLogoIcon(), UIColor(1.0f, 1.0f, 1.0f, 1.0f)); } drawList.AddText( UIPoint( iconX + - (projection.titleBarLogoIcon.IsValid() + (window.m_runtime->GetTitleBarLogoIcon().IsValid() ? (kTitleBarLogoExtent + kTitleBarLogoTextGap) : 4.0f), layout.titleBarRect.y + @@ -742,7 +752,18 @@ void EditorWindowChromeController::AppendChrome( 0.0f, (layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f - 1.0f)), - projection.titleText, + [&window]() { + const std::string_view cachedTitleText = window.GetCachedTitleText(); + const std::string_view fallbackWindowTitle = + cachedTitleText.empty() + ? std::string_view("XCEngine Editor") + : cachedTitleText; + const EditorWindowTitleBarBinding* titleBarBinding = + window.m_runtime->TryGetTitleBarBinding(); + return titleBarBinding != nullptr + ? titleBarBinding->ResolveDetachedWindowTitleText(fallbackWindowTitle) + : std::string(fallbackWindowTitle); + }(), kShellTextColor, kBorderlessTitleBarFontSize); } @@ -751,30 +772,40 @@ void EditorWindowChromeController::AppendChrome( const float iconY = layout.titleBarRect.y + (std::max)(0.0f, (layout.titleBarRect.height - kTitleBarLogoExtent) * 0.5f); - if (projection.titleBarLogoIcon.IsValid()) { + if (window.m_runtime->GetTitleBarLogoIcon().IsValid()) { drawList.AddImage( UIRect(iconX, iconY, kTitleBarLogoExtent, kTitleBarLogoExtent), - projection.titleBarLogoIcon, + window.m_runtime->GetTitleBarLogoIcon(), UIColor(1.0f, 1.0f, 1.0f, 1.0f)); } + const std::string_view cachedTitleText = window.GetCachedTitleText(); + const std::string titleText = cachedTitleText.empty() + ? std::string("XCEngine Editor") + : std::string(cachedTitleText); + const std::string frameRateText = window.m_runtime->BuildFrameRateText(); drawList.AddText( UIPoint( iconX + - (projection.titleBarLogoIcon.IsValid() + (window.m_runtime->GetTitleBarLogoIcon().IsValid() ? (kTitleBarLogoExtent + kTitleBarLogoTextGap) : 4.0f), layout.titleBarRect.y + (std::max)( 0.0f, (layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f - 1.0f)), - projection.titleText, + titleText, kShellTextColor, kBorderlessTitleBarFontSize); - if (!projection.frameRateText.empty()) { + if (!frameRateText.empty()) { + const float frameRateTextWidth = + window.m_runtime->GetTextMeasurer().MeasureTextWidth( + UIEditorTextMeasureRequest{ + frameRateText, + kBorderlessTitleBarFontSize }); const float frameRateX = layout.dragRect.x + layout.dragRect.width - - kTitleBarFrameStatsInsetRight - projection.frameRateTextWidth; + kTitleBarFrameStatsInsetRight - frameRateTextWidth; drawList.AddText( UIPoint( (std::max)(frameRateX, layout.dragRect.x + kTitleBarLogoInsetLeft), @@ -783,7 +814,7 @@ void EditorWindowChromeController::AppendChrome( 0.0f, (layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f - 1.0f)), - projection.frameRateText, + frameRateText, kShellMutedTextColor, kBorderlessTitleBarFontSize); } @@ -792,33 +823,53 @@ void EditorWindowChromeController::AppendChrome( Host::AppendBorderlessWindowChrome( drawList, layout, - GetChromeState(window), - IsBorderlessWindowMaximized(window)); + GetChromeState(), + IsBorderlessWindowMaximized()); } -void EditorWindowChromeController::ApplyResizeCursorHoverPriority(EditorWindow& window) { - if (GetHoveredBorderlessResizeEdge(window) != Host::BorderlessWindowResizeEdge::None || - IsBorderlessResizeActive(window)) { - SetHoveredChromeTarget(window, Host::BorderlessWindowChromeHitTarget::None); +void EditorWindowChromeController::ApplyResizeCursorHoverPriority() { + if (GetHoveredBorderlessResizeEdge() != Host::BorderlessWindowResizeEdge::None || + IsBorderlessResizeActive()) { + SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget::None); } } bool EditorWindowChromeController::QueryCurrentWindowRect( const EditorWindow& window, RECT& outRect) const { - return m_nativeWindowBackend.TryGetWindowRect(window.GetHwnd(), outRect); + outRect = {}; + const HWND hwnd = window.GetHwnd(); + return hwnd != nullptr && GetWindowRect(hwnd, &outRect) != FALSE; } bool EditorWindowChromeController::QueryBorderlessWindowWorkAreaRect( const EditorWindow& window, RECT& outRect) const { - return m_nativeWindowBackend.TryGetMonitorWorkArea(window.GetHwnd(), outRect); + outRect = {}; + const HWND hwnd = window.GetHwnd(); + if (hwnd == nullptr) { + return false; + } + + const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + if (monitor == nullptr) { + return false; + } + + MONITORINFO monitorInfo = {}; + monitorInfo.cbSize = sizeof(monitorInfo); + if (!GetMonitorInfoW(monitor, &monitorInfo)) { + return false; + } + + outRect = monitorInfo.rcWork; + return true; } bool EditorWindowChromeController::ApplyPredictedWindowRectTransition( EditorWindow& window, - EditorContext&, - bool, + EditorContext& editorContext, + bool globalTabDragActive, const RECT& targetRect) { const HWND hwnd = window.GetHwnd(); if (hwnd == nullptr) { @@ -831,12 +882,23 @@ bool EditorWindowChromeController::ApplyPredictedWindowRectTransition( return false; } - window.SetPredictedClientPixelSize(static_cast(width), static_cast(height)); + SetPredictedClientPixelSize(static_cast(width), static_cast(height)); if (window.ApplyWindowResize(static_cast(width), static_cast(height))) { - window.RequestInteractionFrame(); - window.MarkPredictedClientPixelSizePresented(); + window.QueueCompletedImmediateFrame( + EditorWindowFrameDriver::DriveImmediateFrame( + window, + editorContext, + globalTabDragActive)); + MarkPredictedClientPixelSizePresented(); } - m_windowCommandProjector.ProjectCommand(hwnd, BuildSetWindowBoundsCommand(targetRect)); + SetWindowPos( + hwnd, + nullptr, + targetRect.left, + targetRect.top, + width, + height, + SWP_NOZORDER | SWP_NOACTIVATE); window.InvalidateHostWindow(); return true; } @@ -849,7 +911,7 @@ void EditorWindowChromeController::ToggleMaximizeRestore( return; } - if (!IsBorderlessWindowMaximized(window)) { + if (!IsBorderlessWindowMaximized()) { RECT currentRect = {}; RECT workAreaRect = {}; if (!QueryCurrentWindowRect(window, currentRect) || @@ -857,18 +919,18 @@ void EditorWindowChromeController::ToggleMaximizeRestore( return; } - SetBorderlessWindowRestoreRect(window, currentRect); - SetBorderlessWindowMaximized(window, true); + SetBorderlessWindowRestoreRect(currentRect); + SetBorderlessWindowMaximized(true); ApplyPredictedWindowRectTransition(window, editorContext, globalTabDragActive, workAreaRect); return; } RECT restoreRect = {}; - if (!TryGetBorderlessWindowRestoreRect(window, restoreRect)) { + if (!TryGetBorderlessWindowRestoreRect(restoreRect)) { return; } - SetBorderlessWindowMaximized(window, false); + SetBorderlessWindowMaximized(false); ApplyPredictedWindowRectTransition(window, editorContext, globalTabDragActive, restoreRect); } @@ -884,21 +946,13 @@ void EditorWindowChromeController::ExecuteChromeAction( switch (target) { case Host::BorderlessWindowChromeHitTarget::MinimizeButton: - m_windowCommandProjector.ProjectCommand( - hwnd, - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::MinimizeWindow, - }); + ShowWindow(hwnd, SW_MINIMIZE); break; case Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton: ToggleMaximizeRestore(window, editorContext, globalTabDragActive); break; case Host::BorderlessWindowChromeHitTarget::CloseButton: - m_windowCommandProjector.ProjectCommand( - hwnd, - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::CloseWindow, - }); + PostMessageW(hwnd, WM_CLOSE, 0, 0); break; case Host::BorderlessWindowChromeHitTarget::DragRegion: case Host::BorderlessWindowChromeHitTarget::None: diff --git a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h b/editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h similarity index 58% rename from new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h rename to editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h index 28da6685..74b4807d 100644 --- a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h +++ b/editor/app/Platform/Win32/Chrome/EditorWindowChromeController.h @@ -1,8 +1,7 @@ #pragma once #include -#include -#include +#include namespace XCEngine::UI { @@ -14,8 +13,6 @@ namespace XCEngine::UI::Editor::App { class EditorContext; class EditorWindow; -class Win32NativeWindowBackend; -class Win32WindowCommandProjector; } // namespace XCEngine::UI::Editor::App @@ -23,9 +20,7 @@ namespace XCEngine::UI::Editor::App { class EditorWindowChromeController final { public: - EditorWindowChromeController( - Win32NativeWindowBackend& nativeWindowBackend, - Win32WindowCommandProjector& windowCommandProjector); + EditorWindowChromeController() = default; ~EditorWindowChromeController() = default; EditorWindowChromeController(const EditorWindowChromeController&) = delete; @@ -33,23 +28,52 @@ public: EditorWindowChromeController(EditorWindowChromeController&&) = delete; EditorWindowChromeController& operator=(EditorWindowChromeController&&) = delete; - void Reset(EditorWindow& window); + void Reset(); - void BeginInteractiveResize(EditorWindow& window); - void EndInteractiveResize(EditorWindow& window); - void EndBorderlessResize(EditorWindow& window); - bool IsBorderlessResizeActive(const EditorWindow& window) const; - Host::BorderlessWindowResizeEdge GetBorderlessResizeEdge( - const EditorWindow& window) const; - void SetHoveredBorderlessResizeEdge( - EditorWindow& window, - Host::BorderlessWindowResizeEdge edge); - Host::BorderlessWindowResizeEdge GetHoveredBorderlessResizeEdge( - const EditorWindow& window) const; + void SetWindowDpi(UINT dpi); + UINT GetWindowDpi() const; + float GetDpiScale(float baseDpiScale) const; - void EndBorderlessWindowDragRestore(EditorWindow& window); - bool IsBorderlessWindowDragRestoreArmed(const EditorWindow& window) const; - void ResetChromeState(EditorWindow& window); + void BeginInteractiveResize(); + void EndInteractiveResize(); + + void BeginBorderlessResize( + Host::BorderlessWindowResizeEdge edge, + const POINT& initialScreenPoint, + const RECT& initialWindowRect); + void EndBorderlessResize(); + bool IsBorderlessResizeActive() const; + Host::BorderlessWindowResizeEdge GetBorderlessResizeEdge() const; + const POINT& GetBorderlessResizeInitialScreenPoint() const; + const RECT& GetBorderlessResizeInitialWindowRect() const; + void SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge edge); + Host::BorderlessWindowResizeEdge GetHoveredBorderlessResizeEdge() const; + + void SetPredictedClientPixelSize(UINT width, UINT height); + void ClearPredictedClientPixelSize(); + bool TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const; + void MarkPredictedClientPixelSizePresented(); + bool ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height); + void RequestSkipNextSteadyStateFrame(); + bool ConsumeSkipNextSteadyStateFrame(); + + void SetBorderlessWindowMaximized(bool maximized); + bool IsBorderlessWindowMaximized() const; + void SetBorderlessWindowRestoreRect(const RECT& rect); + bool TryGetBorderlessWindowRestoreRect(RECT& outRect) const; + + void BeginBorderlessWindowDragRestore(const POINT& initialScreenPoint); + void EndBorderlessWindowDragRestore(); + bool IsBorderlessWindowDragRestoreArmed() const; + const POINT& GetBorderlessWindowDragRestoreInitialScreenPoint() const; + + Host::BorderlessWindowChromeHitTarget GetHoveredChromeTarget() const; + void SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget target); + Host::BorderlessWindowChromeHitTarget GetPressedChromeTarget() const; + void SetPressedChromeTarget(Host::BorderlessWindowChromeHitTarget target); + void ResetChromeState(); + bool IsChromeStateClear() const; + const Host::BorderlessWindowChromeState& GetChromeState() const; bool HandleSystemCommand( EditorWindow& window, @@ -57,10 +81,7 @@ public: bool globalTabDragActive, WPARAM wParam); bool HandleGetMinMaxInfo(const EditorWindow& window, LPARAM lParam) const; - LRESULT HandleNcCalcSize( - const EditorWindow& window, - WPARAM wParam, - LPARAM lParam) const; + LRESULT HandleNcCalcSize(const EditorWindow& window, WPARAM wParam, LPARAM lParam) const; bool UpdateResizeHover(EditorWindow& window, LPARAM lParam); bool HandleResizeButtonDown(EditorWindow& window, LPARAM lParam); @@ -104,46 +125,9 @@ public: const EditorWindow& window, ::XCEngine::UI::UIDrawList& drawList, float clientWidthDips) const; - -private: - void BeginBorderlessResize( - EditorWindow& window, - Host::BorderlessWindowResizeEdge edge, - const POINT& initialScreenPoint, - const RECT& initialWindowRect); - const POINT& GetBorderlessResizeInitialScreenPoint( - const EditorWindow& window) const; - const RECT& GetBorderlessResizeInitialWindowRect( - const EditorWindow& window) const; - void SetBorderlessWindowMaximized(EditorWindow& window, bool maximized); - bool IsBorderlessWindowMaximized(const EditorWindow& window) const; - void SetBorderlessWindowRestoreRect(EditorWindow& window, const RECT& rect); - bool TryGetBorderlessWindowRestoreRect( - const EditorWindow& window, - RECT& outRect) const; - void BeginBorderlessWindowDragRestore( - EditorWindow& window, - const POINT& initialScreenPoint); - const POINT& GetBorderlessWindowDragRestoreInitialScreenPoint( - const EditorWindow& window) const; - Host::BorderlessWindowChromeHitTarget GetHoveredChromeTarget( - const EditorWindow& window) const; - void SetHoveredChromeTarget( - EditorWindow& window, - Host::BorderlessWindowChromeHitTarget target); - Host::BorderlessWindowChromeHitTarget GetPressedChromeTarget( - const EditorWindow& window) const; - void SetPressedChromeTarget( - EditorWindow& window, - Host::BorderlessWindowChromeHitTarget target); - bool IsChromeStateClear(const EditorWindow& window) const; - const Host::BorderlessWindowChromeState& GetChromeState( - const EditorWindow& window) const; - void ApplyResizeCursorHoverPriority(EditorWindow& window); + void ApplyResizeCursorHoverPriority(); bool QueryCurrentWindowRect(const EditorWindow& window, RECT& outRect) const; - bool QueryBorderlessWindowWorkAreaRect( - const EditorWindow& window, - RECT& outRect) const; + bool QueryBorderlessWindowWorkAreaRect(const EditorWindow& window, RECT& outRect) const; bool ApplyPredictedWindowRectTransition( EditorWindow& window, EditorContext& editorContext, @@ -159,8 +143,9 @@ private: bool globalTabDragActive, Host::BorderlessWindowChromeHitTarget target); - Win32NativeWindowBackend& m_nativeWindowBackend; - Win32WindowCommandProjector& m_windowCommandProjector; +private: + Host::BorderlessWindowChromeState m_chromeState = {}; + Host::HostRuntimeState m_runtimeState = {}; }; } // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Chrome/HostRuntimeState.h b/editor/app/Platform/Win32/Chrome/HostRuntimeState.h similarity index 62% rename from new_editor/app/Platform/Win32/Chrome/HostRuntimeState.h rename to editor/app/Platform/Win32/Chrome/HostRuntimeState.h index d7a3f55d..1d5f81aa 100644 --- a/new_editor/app/Platform/Win32/Chrome/HostRuntimeState.h +++ b/editor/app/Platform/Win32/Chrome/HostRuntimeState.h @@ -14,6 +14,13 @@ struct BorderlessWindowResizeState { BorderlessWindowResizeEdge hoveredEdge = BorderlessWindowResizeEdge::None; }; +struct PredictedClientPixelSize { + bool active = false; + UINT width = 0u; + UINT height = 0u; + bool presented = false; +}; + struct BorderlessWindowPlacementState { bool maximized = false; bool hasRestoreRect = false; @@ -28,10 +35,27 @@ struct BorderlessWindowDragRestoreState { class HostRuntimeState { public: void Reset() { + m_windowDpi = 96u; m_inInteractiveResize = false; m_borderlessResizeState = {}; + m_predictedClientPixelSize = {}; m_borderlessWindowPlacementState = {}; m_borderlessWindowDragRestoreState = {}; + m_skipNextSteadyStateFrame = false; + } + + void SetWindowDpi(UINT dpi) { + m_windowDpi = dpi == 0u ? 96u : dpi; + } + + UINT GetWindowDpi() const { + return m_windowDpi; + } + + float GetDpiScale(float baseDpiScale) const { + return baseDpiScale > 0.0f + ? static_cast(m_windowDpi) / baseDpiScale + : 1.0f; } void BeginInteractiveResize() { @@ -62,6 +86,7 @@ public: m_borderlessResizeState.active = false; m_borderlessResizeState.edge = BorderlessWindowResizeEdge::None; m_inInteractiveResize = false; + m_predictedClientPixelSize = {}; } bool IsBorderlessResizeActive() const { @@ -88,6 +113,66 @@ public: return m_borderlessResizeState.hoveredEdge; } + void SetPredictedClientPixelSize(UINT width, UINT height) { + if (width == 0u || height == 0u) { + m_predictedClientPixelSize = {}; + return; + } + + m_predictedClientPixelSize.active = true; + m_predictedClientPixelSize.width = width; + m_predictedClientPixelSize.height = height; + m_predictedClientPixelSize.presented = false; + } + + void ClearPredictedClientPixelSize() { + m_predictedClientPixelSize = {}; + } + + bool TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const { + outWidth = 0u; + outHeight = 0u; + if (!m_predictedClientPixelSize.active || + m_predictedClientPixelSize.width == 0u || + m_predictedClientPixelSize.height == 0u) { + return false; + } + + outWidth = m_predictedClientPixelSize.width; + outHeight = m_predictedClientPixelSize.height; + return true; + } + + void MarkPredictedClientPixelSizePresented() { + if (!m_predictedClientPixelSize.active) { + return; + } + + m_predictedClientPixelSize.presented = true; + } + + bool ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height) { + if (!m_predictedClientPixelSize.active || + !m_predictedClientPixelSize.presented || + m_predictedClientPixelSize.width != width || + m_predictedClientPixelSize.height != height) { + return false; + } + + m_predictedClientPixelSize = {}; + return true; + } + + void RequestSkipNextSteadyStateFrame() { + m_skipNextSteadyStateFrame = true; + } + + bool ConsumeSkipNextSteadyStateFrame() { + const bool skipFrame = m_skipNextSteadyStateFrame; + m_skipNextSteadyStateFrame = false; + return skipFrame; + } + void SetBorderlessWindowMaximized(bool maximized) { m_borderlessWindowPlacementState.maximized = maximized; } @@ -129,10 +214,13 @@ public: } private: + UINT m_windowDpi = 96u; bool m_inInteractiveResize = false; BorderlessWindowResizeState m_borderlessResizeState = {}; + PredictedClientPixelSize m_predictedClientPixelSize = {}; BorderlessWindowPlacementState m_borderlessWindowPlacementState = {}; BorderlessWindowDragRestoreState m_borderlessWindowDragRestoreState = {}; + bool m_skipNextSteadyStateFrame = false; }; } // namespace XCEngine::UI::Editor::Host diff --git a/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp b/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp new file mode 100644 index 00000000..da51ebca --- /dev/null +++ b/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp @@ -0,0 +1,103 @@ +#include "Platform/Win32/Content/EditorUtilityWindowContentController.h" + +#include "UtilityWindows/EditorUtilityWindowPanel.h" +#include "UtilityWindows/EditorUtilityWindowRegistry.h" + +#include + +namespace XCEngine::UI::Editor::App { + +using ::XCEngine::UI::UIInputEvent; +using ::XCEngine::UI::UIInputEventType; + +EditorUtilityWindowContentController::EditorUtilityWindowContentController( + std::unique_ptr panel, + const ::XCEngine::UI::UISize& minimumOuterSize) + : m_panel(std::move(panel)), + m_minimumOuterSize(minimumOuterSize) {} + +EditorUtilityWindowContentController::~EditorUtilityWindowContentController() = default; + +void EditorUtilityWindowContentController::Shutdown() { + if (m_panel != nullptr) { + m_panel->ResetInteractionState(); + } + m_shellInteractionState = {}; + m_shellFrame = {}; + m_windowFocused = false; +} + +void EditorUtilityWindowContentController::ResetInteractionState() { + if (m_panel != nullptr) { + m_panel->ResetInteractionState(); + } +} + +EditorWindowFrameTransferRequests +EditorUtilityWindowContentController::UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) { + bool focusGained = false; + bool focusLost = false; + for (const UIInputEvent& event : context.inputEvents) { + if (event.type == UIInputEventType::FocusGained) { + m_windowFocused = true; + focusGained = true; + } else if (event.type == UIInputEventType::FocusLost) { + m_windowFocused = false; + focusLost = true; + } + } + + m_shellInteractionState.focused = m_windowFocused; + m_shellFrame.focused = m_windowFocused; + + if (m_panel == nullptr) { + return {}; + } + + m_panel->Update( + context.editorContext, + EditorUtilityWindowHostContext{ + .mounted = true, + .bounds = context.bounds, + .allowInteraction = true, + .focused = m_windowFocused, + .focusGained = focusGained, + .focusLost = focusLost, + }, + context.inputEvents); + + ::XCEngine::UI::UIDrawList& drawList = + drawData.EmplaceDrawList(std::string(m_panel->GetDrawListId())); + m_panel->Append(drawList); + return {}; +} + +const UIEditorShellInteractionFrame& EditorUtilityWindowContentController::GetShellFrame() const { + return m_shellFrame; +} + +const UIEditorShellInteractionState& +EditorUtilityWindowContentController::GetShellInteractionState() const { + return m_shellInteractionState; +} + +::XCEngine::UI::UISize EditorUtilityWindowContentController::ResolveMinimumOuterSize() const { + return m_minimumOuterSize; +} + +std::unique_ptr CreateEditorUtilityWindowContentController( + const EditorUtilityWindowDescriptor& descriptor) { + std::unique_ptr panel = + CreateEditorUtilityWindowPanel(descriptor.kind); + if (panel == nullptr) { + return nullptr; + } + + return std::make_unique( + std::move(panel), + descriptor.minimumOuterSize); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.h b/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.h new file mode 100644 index 00000000..2b31125d --- /dev/null +++ b/editor/app/Platform/Win32/Content/EditorUtilityWindowContentController.h @@ -0,0 +1,44 @@ +#pragma once + +#include "Platform/Win32/Content/EditorWindowContentController.h" + +#include + +#include + +#include + +namespace XCEngine::UI::Editor::App { + +class EditorUtilityWindowPanel; +struct EditorUtilityWindowDescriptor; + +class EditorUtilityWindowContentController final + : public EditorWindowContentController { +public: + EditorUtilityWindowContentController( + std::unique_ptr panel, + const ::XCEngine::UI::UISize& minimumOuterSize); + ~EditorUtilityWindowContentController() override; + + void Shutdown() override; + void ResetInteractionState() override; + EditorWindowFrameTransferRequests UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) override; + const UIEditorShellInteractionFrame& GetShellFrame() const override; + const UIEditorShellInteractionState& GetShellInteractionState() const override; + ::XCEngine::UI::UISize ResolveMinimumOuterSize() const override; + +private: + std::unique_ptr m_panel = {}; + ::XCEngine::UI::UISize m_minimumOuterSize = {}; + UIEditorShellInteractionState m_shellInteractionState = {}; + UIEditorShellInteractionFrame m_shellFrame = {}; + bool m_windowFocused = true; +}; + +std::unique_ptr CreateEditorUtilityWindowContentController( + const EditorUtilityWindowDescriptor& descriptor); + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Content/EditorWindowContentController.h b/editor/app/Platform/Win32/Content/EditorWindowContentController.h new file mode 100644 index 00000000..5a883f9b --- /dev/null +++ b/editor/app/Platform/Win32/Content/EditorWindowContentController.h @@ -0,0 +1,163 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include +#include + +#include +#include +#include +#include +#include + +namespace XCEngine::Rendering { + +class RenderContext; + +} // namespace XCEngine::Rendering + +namespace XCEngine::UI { + +class UIDrawData; + +struct UIInputEvent; +struct UIPoint; +struct UIRect; +struct UISize; + +} // namespace XCEngine::UI + +namespace XCEngine::UI::Editor { + +class UIEditorWorkspaceController; + +struct UIEditorShellInteractionFrame; +struct UIEditorShellInteractionState; + +namespace Widgets { +struct UIEditorDockHostDropPreviewState; +} + +} // namespace XCEngine::UI::Editor + +namespace XCEngine::UI::Editor::Rendering::Host { + +class UiTextureHost; +class ViewportRenderHost; + +} // namespace XCEngine::UI::Editor::Rendering::Host + +namespace XCEngine::UI::Editor::App { + +class EditorContext; + +enum class EditorWindowContentCursorKind : std::uint8_t { + Arrow = 0, + ResizeEW, + ResizeNS, +}; + +class EditorWindowWorkspaceBinding { +public: + virtual ~EditorWindowWorkspaceBinding() = default; + + virtual const UIEditorWorkspaceController* TryGetWorkspaceController() const = 0; + virtual void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) = 0; +}; + +class EditorWindowDockHostBinding { +public: + virtual ~EditorWindowDockHostBinding() = default; + + virtual void SetExternalDockHostDropPreview( + const Widgets::UIEditorDockHostDropPreviewState& preview) = 0; + virtual void ClearExternalDockHostDropPreview() = 0; + virtual bool TryResolveDockTabDragHotspot( + std::string_view nodeId, + std::string_view panelId, + const ::XCEngine::UI::UIPoint& point, + ::XCEngine::UI::UIPoint& outHotspot) const = 0; + virtual UIEditorDockHostTabDropTarget ResolveDockTabDropTarget( + const ::XCEngine::UI::UIPoint& point) const = 0; +}; + +class EditorWindowInputFeedbackBinding { +public: + virtual ~EditorWindowInputFeedbackBinding() = default; + + virtual bool HasHostedContentCapture() const = 0; + virtual bool HasShellInteractiveCapture() const = 0; + virtual bool HasInteractiveCapture() const = 0; + virtual EditorWindowContentCursorKind GetHostedContentCursorKind() const = 0; + virtual EditorWindowContentCursorKind GetDockCursorKind() const = 0; +}; + +class EditorWindowTitleBarBinding { +public: + virtual ~EditorWindowTitleBarBinding() = default; + + virtual bool ShouldUseDetachedTitleBarTabStrip() const = 0; + virtual std::string ResolveTabStripTitleText(std::string_view fallbackTitle) const = 0; + virtual std::string ResolveDetachedWindowTitleText( + std::string_view fallbackWindowTitle) const = 0; +}; + +struct EditorWindowContentInitializationContext { + const std::filesystem::path& repoRoot; + EditorContext& editorContext; + Rendering::Host::UiTextureHost& textureHost; + UIEditorTextMeasurer& textMeasurer; + Rendering::Host::ViewportRenderHost& viewportRenderer; +}; + +struct EditorWindowContentFrameContext { + EditorContext& editorContext; + const ::XCEngine::UI::UIRect& bounds; + const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents; + std::string_view captureStatusText; + bool primary = false; + bool globalTabDragActive = false; + bool useDetachedTitleBarTabStrip = false; +}; + +class EditorWindowContentController { +public: + virtual ~EditorWindowContentController() = default; + + virtual EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() { + return nullptr; + } + virtual const EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() const { + return nullptr; + } + virtual EditorWindowDockHostBinding* TryGetDockHostBinding() { + return nullptr; + } + virtual const EditorWindowDockHostBinding* TryGetDockHostBinding() const { + return nullptr; + } + virtual const EditorWindowInputFeedbackBinding* TryGetInputFeedbackBinding() const { + return nullptr; + } + virtual const EditorWindowTitleBarBinding* TryGetTitleBarBinding() const { + return nullptr; + } + + virtual void Initialize(const EditorWindowContentInitializationContext&) {} + virtual void Shutdown() {} + virtual void ResetInteractionState() {} + virtual void SetViewportSurfacePresentationEnabled(bool) {} + + virtual EditorWindowFrameTransferRequests UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) = 0; + virtual void RenderRequestedViewports(const ::XCEngine::Rendering::RenderContext&) {} + + virtual const UIEditorShellInteractionFrame& GetShellFrame() const = 0; + virtual const UIEditorShellInteractionState& GetShellInteractionState() const = 0; + + virtual ::XCEngine::UI::UISize ResolveMinimumOuterSize() const = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp b/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp new file mode 100644 index 00000000..e901f869 --- /dev/null +++ b/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp @@ -0,0 +1,198 @@ +#include "Platform/Win32/Content/EditorWorkspaceWindowContentController.h" + +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +EditorWindowContentCursorKind ToContentCursorKind(ProjectPanel::CursorKind cursorKind) { + switch (cursorKind) { + case ProjectPanel::CursorKind::ResizeEW: + return EditorWindowContentCursorKind::ResizeEW; + case ProjectPanel::CursorKind::Arrow: + default: + return EditorWindowContentCursorKind::Arrow; + } +} + +EditorWindowContentCursorKind ToContentCursorKind( + Widgets::UIEditorDockHostCursorKind cursorKind) { + switch (cursorKind) { + case Widgets::UIEditorDockHostCursorKind::ResizeEW: + return EditorWindowContentCursorKind::ResizeEW; + case Widgets::UIEditorDockHostCursorKind::ResizeNS: + return EditorWindowContentCursorKind::ResizeNS; + case Widgets::UIEditorDockHostCursorKind::Arrow: + default: + return EditorWindowContentCursorKind::Arrow; + } +} + +} // namespace + +EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController( + UIEditorWorkspaceController workspaceController) + : m_workspaceController(std::move(workspaceController)) {} + +EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default; + +EditorWindowWorkspaceBinding* EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() { + return this; +} + +const EditorWindowWorkspaceBinding* +EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() const { + return this; +} + +EditorWindowDockHostBinding* EditorWorkspaceWindowContentController::TryGetDockHostBinding() { + return this; +} + +const EditorWindowDockHostBinding* +EditorWorkspaceWindowContentController::TryGetDockHostBinding() const { + return this; +} + +const EditorWindowInputFeedbackBinding* +EditorWorkspaceWindowContentController::TryGetInputFeedbackBinding() const { + return this; +} + +const EditorWindowTitleBarBinding* +EditorWorkspaceWindowContentController::TryGetTitleBarBinding() const { + return this; +} + +const UIEditorWorkspaceController* +EditorWorkspaceWindowContentController::TryGetWorkspaceController() const { + return &m_workspaceController; +} + +void EditorWorkspaceWindowContentController::ReplaceWorkspaceController( + UIEditorWorkspaceController workspaceController) { + m_workspaceController = std::move(workspaceController); +} + +void EditorWorkspaceWindowContentController::Initialize( + const EditorWindowContentInitializationContext& context) { + m_shellRuntime.Initialize(context.repoRoot, context.textureHost, context.textMeasurer); + m_shellRuntime.AttachViewportWindowRenderer(context.viewportRenderer); +} + +void EditorWorkspaceWindowContentController::Shutdown() { + m_shellRuntime.Shutdown(); +} + +void EditorWorkspaceWindowContentController::ResetInteractionState() { + m_shellRuntime.ResetInteractionState(); +} + +void EditorWorkspaceWindowContentController::SetViewportSurfacePresentationEnabled(bool enabled) { + m_shellRuntime.SetViewportSurfacePresentationEnabled(enabled); +} + +EditorWindowFrameTransferRequests EditorWorkspaceWindowContentController::UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) { + return m_frameOrchestrator.UpdateAndAppend( + context.editorContext, + m_workspaceController, + m_shellRuntime, + context.bounds, + context.inputEvents, + context.captureStatusText, + context.primary, + context.globalTabDragActive, + context.useDetachedTitleBarTabStrip, + drawData); +} + +void EditorWorkspaceWindowContentController::RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext) { + m_shellRuntime.RenderRequestedViewports(renderContext); +} + +const UIEditorShellInteractionFrame& +EditorWorkspaceWindowContentController::GetShellFrame() const { + return m_shellRuntime.GetShellFrame(); +} + +const UIEditorShellInteractionState& +EditorWorkspaceWindowContentController::GetShellInteractionState() const { + return m_shellRuntime.GetShellInteractionState(); +} + +void EditorWorkspaceWindowContentController::SetExternalDockHostDropPreview( + const Widgets::UIEditorDockHostDropPreviewState& preview) { + m_shellRuntime.SetExternalDockHostDropPreview(preview); +} + +void EditorWorkspaceWindowContentController::ClearExternalDockHostDropPreview() { + m_shellRuntime.ClearExternalDockHostDropPreview(); +} + +bool EditorWorkspaceWindowContentController::TryResolveDockTabDragHotspot( + std::string_view nodeId, + std::string_view panelId, + const ::XCEngine::UI::UIPoint& point, + ::XCEngine::UI::UIPoint& outHotspot) const { + return m_shellRuntime.TryResolveDockTabDragHotspot( + nodeId, + panelId, + point, + outHotspot); +} + +UIEditorDockHostTabDropTarget EditorWorkspaceWindowContentController::ResolveDockTabDropTarget( + const ::XCEngine::UI::UIPoint& point) const { + return m_shellRuntime.ResolveDockTabDropTarget(point); +} + +bool EditorWorkspaceWindowContentController::HasHostedContentCapture() const { + return m_shellRuntime.HasHostedContentCapture(); +} + +bool EditorWorkspaceWindowContentController::HasShellInteractiveCapture() const { + return m_shellRuntime.HasShellInteractiveCapture(); +} + +bool EditorWorkspaceWindowContentController::HasInteractiveCapture() const { + return m_shellRuntime.HasInteractiveCapture(); +} + +EditorWindowContentCursorKind +EditorWorkspaceWindowContentController::GetHostedContentCursorKind() const { + return ToContentCursorKind(m_shellRuntime.GetHostedContentCursorKind()); +} + +EditorWindowContentCursorKind EditorWorkspaceWindowContentController::GetDockCursorKind() const { + return ToContentCursorKind(m_shellRuntime.GetDockCursorKind()); +} + +::XCEngine::UI::UISize EditorWorkspaceWindowContentController::ResolveMinimumOuterSize() const { + return ResolveUIEditorDetachedWorkspaceMinimumOuterSize(m_workspaceController); +} + +bool EditorWorkspaceWindowContentController::ShouldUseDetachedTitleBarTabStrip() const { + return HasUIEditorSingleVisibleRootTab(m_workspaceController); +} + +std::string EditorWorkspaceWindowContentController::ResolveTabStripTitleText( + std::string_view fallbackTitle) const { + return ResolveUIEditorDetachedWorkspaceTitle(m_workspaceController, fallbackTitle); +} + +std::string EditorWorkspaceWindowContentController::ResolveDetachedWindowTitleText( + std::string_view fallbackWindowTitle) const { + return ResolveUIEditorDetachedWorkspaceTitle(m_workspaceController, fallbackWindowTitle); +} + +std::unique_ptr CreateEditorWorkspaceWindowContentController( + UIEditorWorkspaceController workspaceController) { + return std::make_unique( + std::move(workspaceController)); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.h b/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.h new file mode 100644 index 00000000..59465157 --- /dev/null +++ b/editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.h @@ -0,0 +1,79 @@ +#pragma once + +#include "Composition/EditorShellRuntime.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" +#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h" + +#include + +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWorkspaceWindowContentController final + : public EditorWindowContentController + , public EditorWindowWorkspaceBinding + , public EditorWindowDockHostBinding + , public EditorWindowInputFeedbackBinding + , public EditorWindowTitleBarBinding { +public: + explicit EditorWorkspaceWindowContentController(UIEditorWorkspaceController workspaceController); + ~EditorWorkspaceWindowContentController() override; + + EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() override; + const EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() const override; + EditorWindowDockHostBinding* TryGetDockHostBinding() override; + const EditorWindowDockHostBinding* TryGetDockHostBinding() const override; + const EditorWindowInputFeedbackBinding* TryGetInputFeedbackBinding() const override; + const EditorWindowTitleBarBinding* TryGetTitleBarBinding() const override; + const UIEditorWorkspaceController* TryGetWorkspaceController() const override; + void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) override; + + void Initialize(const EditorWindowContentInitializationContext& context) override; + void Shutdown() override; + void ResetInteractionState() override; + void SetViewportSurfacePresentationEnabled(bool enabled) override; + + EditorWindowFrameTransferRequests UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) override; + void RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext) override; + + const UIEditorShellInteractionFrame& GetShellFrame() const override; + const UIEditorShellInteractionState& GetShellInteractionState() const override; + + void SetExternalDockHostDropPreview( + const Widgets::UIEditorDockHostDropPreviewState& preview) override; + void ClearExternalDockHostDropPreview() override; + + bool TryResolveDockTabDragHotspot( + std::string_view nodeId, + std::string_view panelId, + const ::XCEngine::UI::UIPoint& point, + ::XCEngine::UI::UIPoint& outHotspot) const override; + UIEditorDockHostTabDropTarget ResolveDockTabDropTarget( + const ::XCEngine::UI::UIPoint& point) const override; + + bool HasHostedContentCapture() const override; + bool HasShellInteractiveCapture() const override; + bool HasInteractiveCapture() const override; + EditorWindowContentCursorKind GetHostedContentCursorKind() const override; + EditorWindowContentCursorKind GetDockCursorKind() const override; + + ::XCEngine::UI::UISize ResolveMinimumOuterSize() const override; + bool ShouldUseDetachedTitleBarTabStrip() const override; + std::string ResolveTabStripTitleText(std::string_view fallbackTitle) const override; + std::string ResolveDetachedWindowTitleText( + std::string_view fallbackWindowTitle) const override; + +private: + UIEditorWorkspaceController m_workspaceController = {}; + EditorShellRuntime m_shellRuntime = {}; + EditorWindowFrameOrchestrator m_frameOrchestrator = {}; +}; + +std::unique_ptr CreateEditorWorkspaceWindowContentController( + UIEditorWorkspaceController workspaceController); + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp b/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp new file mode 100644 index 00000000..e4104db5 --- /dev/null +++ b/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.cpp @@ -0,0 +1,46 @@ +#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" + +#include "Platform/Win32/Chrome/EditorWindowChromeController.h" +#include "Platform/Win32/Windowing/EditorWindow.h" + +namespace XCEngine::UI::Editor::App { + +EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveFrameInternal( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive, + bool requestSkipNextSteadyStateFrame) { + if (!window.IsRenderReady() || + window.GetHwnd() == nullptr || + window.GetLifecycleState() != EditorWindowLifecycleState::Running) { + return {}; + } + + EditorWindowFrameTransferRequests transferRequests = + window.RenderFrame(editorContext, globalTabDragActive); + if (const HWND hwnd = window.GetHwnd(); + hwnd != nullptr && IsWindow(hwnd)) { + ValidateRect(hwnd, nullptr); + } + if (requestSkipNextSteadyStateFrame) { + window.RequestSkipNextSteadyStateFrame(); + } + + return transferRequests; +} + +EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveFrame( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive) { + return DriveFrameInternal(window, editorContext, globalTabDragActive, false); +} + +EditorWindowFrameTransferRequests EditorWindowFrameDriver::DriveImmediateFrame( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive) { + return DriveFrameInternal(window, editorContext, globalTabDragActive, true); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.h b/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.h new file mode 100644 index 00000000..d005cb94 --- /dev/null +++ b/editor/app/Platform/Win32/Runtime/EditorWindowFrameDriver.h @@ -0,0 +1,29 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +namespace XCEngine::UI::Editor::App { + +class EditorContext; +class EditorWindow; + +class EditorWindowFrameDriver final { +public: + static EditorWindowFrameTransferRequests DriveFrame( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive); + static EditorWindowFrameTransferRequests DriveImmediateFrame( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive); + +private: + static EditorWindowFrameTransferRequests DriveFrameInternal( + EditorWindow& window, + EditorContext& editorContext, + bool globalTabDragActive, + bool requestSkipNextSteadyStateFrame); +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.cpp b/editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.cpp similarity index 55% rename from new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.cpp rename to editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.cpp index 9e9992b2..63c10bee 100644 --- a/new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.cpp +++ b/editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.cpp @@ -1,35 +1,28 @@ -#include "Windowing/Content/EditorWindowFrameOrchestrator.h" +#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h" #include "Composition/EditorContext.h" #include "Composition/EditorShellRuntime.h" #include "Composition/EditorShellVariant.h" -#include "Support/EnvironmentFlags.h" -#include "Windowing/Content/EditorWindowContentStyle.h" -#include "Windowing/Utility/EditorUtilityWindowRequestSink.h" -#include "Windowing/Workspace/WindowWorkspaceTransferQueue.h" +#include "Platform/Win32/Windowing/EditorWindowSupport.h" -#include "Windowing/Workspace/UIEditorDetachedWindowPolicy.h" -#include #include #include #include -#include namespace XCEngine::UI::Editor::App { -using namespace EditorWindowContentStyle; +using namespace EditorWindowSupport; using ::XCEngine::UI::UIDrawData; using ::XCEngine::UI::UIDrawList; using ::XCEngine::UI::UIInputEvent; using ::XCEngine::UI::UIInputEventType; using ::XCEngine::UI::UIPoint; -namespace WindowingDomain = ::XCEngine::UI::Editor::Windowing::Domain; namespace { bool IsVerboseRuntimeTraceEnabled() { - static const bool s_enabled = IsEnvironmentFlagEnabled("XCUIEDITOR_VERBOSE_TRACE"); + static const bool s_enabled = ResolveVerboseRuntimeTraceEnabled(); return s_enabled; } @@ -50,75 +43,10 @@ std::string DescribeInputEventType(const UIInputEvent& event) { } } -WindowingDomain::WindowCursorType ToWindowCursorType(ProjectPanel::CursorKind cursorType) { - switch (cursorType) { - case ProjectPanel::CursorKind::ResizeEW: - return WindowingDomain::WindowCursorType::ResizeEW; - case ProjectPanel::CursorKind::Arrow: - default: - return WindowingDomain::WindowCursorType::Arrow; - } -} - -WindowingDomain::WindowCursorType ToWindowCursorType( - Widgets::UIEditorDockHostCursorKind cursorType) { - switch (cursorType) { - case Widgets::UIEditorDockHostCursorKind::ResizeEW: - return WindowingDomain::WindowCursorType::ResizeEW; - case Widgets::UIEditorDockHostCursorKind::ResizeNS: - return WindowingDomain::WindowCursorType::ResizeNS; - case Widgets::UIEditorDockHostCursorKind::Arrow: - default: - return WindowingDomain::WindowCursorType::Arrow; - } -} - -WindowingDomain::WindowCaptureDemand BuildCaptureDemand( - const EditorShellRuntime& shellRuntime) { - return WindowingDomain::WindowCaptureDemand{ - .shellInteractive = shellRuntime.HasShellInteractiveCapture(), - .hostedContent = shellRuntime.HasHostedContentCapture(), - }; -} - -WindowingDomain::WindowCursorType ResolveContentCursorType( - const EditorShellRuntime& shellRuntime) { - const WindowingDomain::WindowCursorType hostedCursorType = - ToWindowCursorType(shellRuntime.GetHostedContentCursorType()); - if (hostedCursorType != WindowingDomain::WindowCursorType::Arrow) { - return hostedCursorType; - } - - return ToWindowCursorType(shellRuntime.GetDockCursorType()); -} - -void QueueWorkspaceTransferRequest( - WindowWorkspaceTransferQueue& workspaceTransferQueue, - WindowWorkspaceTransferRequest::Type type, - std::string_view sourceWindowId, - std::string sourceNodeId, - std::string panelId, - std::int32_t cursorScreenX, - std::int32_t cursorScreenY) { - WindowWorkspaceTransferRequest request = {}; - request.type = type; - request.sourceWindowId = std::string(sourceWindowId); - request.sourceNodeId = std::move(sourceNodeId); - request.panelId = std::move(panelId); - request.screenX = cursorScreenX; - request.screenY = cursorScreenY; - request.hasScreenPoint = true; - workspaceTransferQueue.QueueWorkspaceTransferRequest(request); -} - } // namespace -EditorWindowContentUpdateResult EditorWindowFrameOrchestrator::UpdateAndAppend( +EditorWindowFrameTransferRequests EditorWindowFrameOrchestrator::UpdateAndAppend( EditorContext& editorContext, - std::string_view sourceWindowId, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, UIEditorWorkspaceController& workspaceController, EditorShellRuntime& shellRuntime, const ::XCEngine::UI::UIRect& workspaceBounds, @@ -127,9 +55,6 @@ EditorWindowContentUpdateResult EditorWindowFrameOrchestrator::UpdateAndAppend( bool primary, bool globalTabDragActive, bool useDetachedTitleBarTabStrip, - std::int32_t cursorScreenX, - std::int32_t cursorScreenY, - bool hasCursorScreenPoint, UIDrawData& drawData) const { LogInputTrace( editorContext, @@ -137,15 +62,8 @@ EditorWindowContentUpdateResult EditorWindowFrameOrchestrator::UpdateAndAppend( shellRuntime.GetShellInteractionState(), frameEvents); - utilityRequestSink.ConfigureFrameSource( - sourceWindowId, - cursorScreenX, - cursorScreenY, - hasCursorScreenPoint); shellRuntime.Update( editorContext, - utilityWindowResultState, - utilityRequestSink, workspaceController, workspaceBounds, frameEvents, @@ -159,28 +77,27 @@ EditorWindowContentUpdateResult EditorWindowFrameOrchestrator::UpdateAndAppend( shellRuntime.GetShellInteractionState().workspaceInteractionState.dockHostInteractionState; LogFrameInteractionTrace(workspaceController, frameEvents, shellFrame); - EditorWindowContentUpdateResult updateResult = {}; - updateResult.contentOutput.captureDemand = BuildCaptureDemand(shellRuntime); - updateResult.contentOutput.cursorType = ResolveContentCursorType(shellRuntime); - updateResult.contentOutput.titleBarMode = - HasUIEditorSingleVisibleRootTab(workspaceController) - ? WindowingDomain::WindowTitleBarMode::DetachedTabStrip - : WindowingDomain::WindowTitleBarMode::SystemChrome; - AppendWorkspaceTransferRequests( - sourceWindowId, - globalTabDragActive, - dockHostInteractionState, - shellFrame, - cursorScreenX, - cursorScreenY, - hasCursorScreenPoint, - workspaceTransferQueue); + EditorWindowFrameTransferRequests transferRequests = + BuildShellTransferRequests(globalTabDragActive, dockHostInteractionState, shellFrame); + POINT screenPoint = {}; + if (const std::optional requestedKind = + editorContext.ConsumeOpenUtilityWindowRequest(); + requestedKind.has_value()) { + transferRequests.openUtilityWindow = EditorWindowOpenUtilityWindowRequest{ + .kind = *requestedKind, + .useCursorPlacement = GetCursorPos(&screenPoint) != FALSE, + }; + if (transferRequests.openUtilityWindow->useCursorPlacement) { + transferRequests.openUtilityWindow->screenPoint = screenPoint; + } + } + for (const WorkspaceTraceEntry& entry : shellRuntime.GetTraceEntries()) { - AppendUIEditorRuntimeTrace(entry.channel, entry.message); + LogRuntimeTrace(entry.channel, entry.message); } shellRuntime.Append(drawData); - return updateResult; + return transferRequests; } void EditorWindowFrameOrchestrator::AppendInvalidFrame( @@ -229,7 +146,7 @@ void EditorWindowFrameOrchestrator::LogInputTrace( return; } - AppendUIEditorRuntimeTrace( + LogRuntimeTrace( "input", DescribeInputEvents(frameEvents) + " | " + editorContext.DescribeWorkspaceState( @@ -261,51 +178,38 @@ void EditorWindowFrameOrchestrator::LogFrameInteractionTrace( << workspaceController.GetWorkspace().activePanelId << " message=" << shellFrame.result.workspaceResult.dockHostResult.layoutResult.message; - AppendUIEditorRuntimeTrace("frame", frameTrace.str()); + LogRuntimeTrace("frame", frameTrace.str()); } -void EditorWindowFrameOrchestrator::AppendWorkspaceTransferRequests( - std::string_view sourceWindowId, +EditorWindowFrameTransferRequests EditorWindowFrameOrchestrator::BuildShellTransferRequests( bool globalTabDragActive, const UIEditorDockHostInteractionState& dockHostInteractionState, - const UIEditorShellInteractionFrame& shellFrame, - std::int32_t cursorScreenX, - std::int32_t cursorScreenY, - bool hasCursorScreenPoint, - WindowWorkspaceTransferQueue& workspaceTransferQueue) const { + const UIEditorShellInteractionFrame& shellFrame) const { + EditorWindowFrameTransferRequests transferRequests = {}; + POINT screenPoint = {}; + const bool hasScreenPoint = GetCursorPos(&screenPoint) != FALSE; + if (!globalTabDragActive && !dockHostInteractionState.activeTabDragNodeId.empty() && !dockHostInteractionState.activeTabDragPanelId.empty() && - hasCursorScreenPoint) { - QueueWorkspaceTransferRequest( - workspaceTransferQueue, - WindowWorkspaceTransferRequest::Type::StartGlobalTabDrag, - sourceWindowId, + hasScreenPoint) { + transferRequests.beginGlobalTabDrag = EditorWindowPanelTransferRequest{ dockHostInteractionState.activeTabDragNodeId, dockHostInteractionState.activeTabDragPanelId, - cursorScreenX, - cursorScreenY); + screenPoint, + }; } - if (shellFrame.result.workspaceResult.dockHostResult.detachRequested && - hasCursorScreenPoint) { - QueueWorkspaceTransferRequest( - workspaceTransferQueue, - WindowWorkspaceTransferRequest::Type::DetachPanel, - sourceWindowId, + if (shellFrame.result.workspaceResult.dockHostResult.detachRequested && hasScreenPoint) { + transferRequests.detachPanel = EditorWindowPanelTransferRequest{ shellFrame.result.workspaceResult.dockHostResult.detachedNodeId, shellFrame.result.workspaceResult.dockHostResult.detachedPanelId, - cursorScreenX, - cursorScreenY); + screenPoint, + }; } + + return transferRequests; } } // namespace XCEngine::UI::Editor::App - - - - - - - diff --git a/new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.h b/editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h similarity index 72% rename from new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.h rename to editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h index a0ea10f7..eb080305 100644 --- a/new_editor/app/Windowing/Content/EditorWindowFrameOrchestrator.h +++ b/editor/app/Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h @@ -1,10 +1,9 @@ #pragma once -#include "Windowing/Application/EditorWindowContentUpdateResult.h" +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" #include -#include #include #include #include @@ -32,10 +31,7 @@ struct UIEditorShellInteractionState; namespace XCEngine::UI::Editor::App { class EditorContext; -struct EditorUtilityWindowResultState; class EditorShellRuntime; -class EditorUtilityWindowRequestSink; -class WindowWorkspaceTransferQueue; class EditorWindowFrameOrchestrator final { public: @@ -47,12 +43,8 @@ public: EditorWindowFrameOrchestrator(EditorWindowFrameOrchestrator&&) = delete; EditorWindowFrameOrchestrator& operator=(EditorWindowFrameOrchestrator&&) = delete; - EditorWindowContentUpdateResult UpdateAndAppend( + EditorWindowFrameTransferRequests UpdateAndAppend( EditorContext& editorContext, - std::string_view sourceWindowId, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, UIEditorWorkspaceController& workspaceController, EditorShellRuntime& shellRuntime, const ::XCEngine::UI::UIRect& workspaceBounds, @@ -61,9 +53,6 @@ public: bool primary, bool globalTabDragActive, bool useDetachedTitleBarTabStrip, - std::int32_t cursorScreenX, - std::int32_t cursorScreenY, - bool hasCursorScreenPoint, ::XCEngine::UI::UIDrawData& drawData) const; void AppendInvalidFrame( EditorContext& editorContext, @@ -81,18 +70,10 @@ private: const UIEditorWorkspaceController& workspaceController, const std::vector<::XCEngine::UI::UIInputEvent>& frameEvents, const UIEditorShellInteractionFrame& shellFrame) const; - void AppendWorkspaceTransferRequests( - std::string_view sourceWindowId, + EditorWindowFrameTransferRequests BuildShellTransferRequests( bool globalTabDragActive, const UIEditorDockHostInteractionState& dockHostInteractionState, - const UIEditorShellInteractionFrame& shellFrame, - std::int32_t cursorScreenX, - std::int32_t cursorScreenY, - bool hasCursorScreenPoint, - WindowWorkspaceTransferQueue& workspaceTransferQueue) const; + const UIEditorShellInteractionFrame& shellFrame) const; }; } // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp b/editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp similarity index 87% rename from new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp rename to editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp index 72e57ed2..8c8116b3 100644 --- a/new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp +++ b/editor/app/Platform/Win32/Runtime/EditorWindowInputController.cpp @@ -36,30 +36,65 @@ std::uint64_t GetInputEventTimestampNanoseconds() { } // namespace -bool EditorWindowInputController::AcquirePointerCapture(HWND hwnd) { - if (hwnd == nullptr || !IsWindow(hwnd)) { - return false; +bool EditorWindowInputController::IsTrackingMouseLeave() const { + return m_trackingMouseLeave; +} + +void EditorWindowInputController::SetTrackingMouseLeave(bool trackingMouseLeave) { + m_trackingMouseLeave = trackingMouseLeave; +} + +EditorWindowPointerCaptureOwner EditorWindowInputController::GetPointerCaptureOwner() const { + return m_pointerCaptureOwner; +} + +bool EditorWindowInputController::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const { + return m_pointerCaptureOwner == owner; +} + +bool EditorWindowInputController::HasPointerCaptureOwner() const { + return m_pointerCaptureOwner != EditorWindowPointerCaptureOwner::None; +} + +void EditorWindowInputController::AcquirePointerCapture( + HWND hwnd, + EditorWindowPointerCaptureOwner owner) { + if (owner == EditorWindowPointerCaptureOwner::None || + hwnd == nullptr || + !IsWindow(hwnd)) { + return; } + m_pointerCaptureOwner = owner; if (GetCapture() != hwnd) { SetCapture(hwnd); } - - return GetCapture() == hwnd; } -void EditorWindowInputController::ReleasePointerCapture(HWND hwnd) { +void EditorWindowInputController::ReleasePointerCapture( + HWND hwnd, + EditorWindowPointerCaptureOwner owner) { + if (m_pointerCaptureOwner != owner) { + return; + } + + m_pointerCaptureOwner = EditorWindowPointerCaptureOwner::None; if (hwnd != nullptr && GetCapture() == hwnd) { ReleaseCapture(); } } void EditorWindowInputController::ForceReleasePointerCapture(HWND hwnd) { + m_pointerCaptureOwner = EditorWindowPointerCaptureOwner::None; if (hwnd != nullptr && GetCapture() == hwnd) { ReleaseCapture(); } } +void EditorWindowInputController::ClearPointerCaptureOwner() { + m_pointerCaptureOwner = EditorWindowPointerCaptureOwner::None; +} + void EditorWindowInputController::QueuePointerEvent( UIInputEventType type, UIPointerButton button, @@ -198,11 +233,15 @@ void EditorWindowInputController::ClearPendingEvents() { } void EditorWindowInputController::ResetInteractionState() { + ForceReleasePointerCapture(nullptr); ClearPendingEvents(); + m_trackingMouseLeave = false; m_modifierTracker.Reset(); } void EditorWindowInputController::ResetWindowState() { + m_trackingMouseLeave = false; + m_pointerCaptureOwner = EditorWindowPointerCaptureOwner::None; m_pendingDoubleClickButtons = 0u; } diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.h b/editor/app/Platform/Win32/Runtime/EditorWindowInputController.h similarity index 78% rename from new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.h rename to editor/app/Platform/Win32/Runtime/EditorWindowInputController.h index f9b7430b..5f770201 100644 --- a/new_editor/app/Platform/Win32/Runtime/EditorWindowInputController.h +++ b/editor/app/Platform/Win32/Runtime/EditorWindowInputController.h @@ -26,9 +26,16 @@ public: EditorWindowInputController(EditorWindowInputController&&) = delete; EditorWindowInputController& operator=(EditorWindowInputController&&) = delete; - bool AcquirePointerCapture(HWND hwnd); - void ReleasePointerCapture(HWND hwnd); + bool IsTrackingMouseLeave() const; + void SetTrackingMouseLeave(bool trackingMouseLeave); + + EditorWindowPointerCaptureOwner GetPointerCaptureOwner() const; + bool OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const; + bool HasPointerCaptureOwner() const; + void AcquirePointerCapture(HWND hwnd, EditorWindowPointerCaptureOwner owner); + void ReleasePointerCapture(HWND hwnd, EditorWindowPointerCaptureOwner owner); void ForceReleasePointerCapture(HWND hwnd); + void ClearPointerCaptureOwner(); void QueuePointerEvent( ::XCEngine::UI::UIInputEventType type, @@ -65,6 +72,9 @@ private: Host::InputModifierTracker m_modifierTracker = {}; std::vector<::XCEngine::UI::UIInputEvent> m_pendingEvents = {}; std::uint8_t m_pendingDoubleClickButtons = 0u; + bool m_trackingMouseLeave = false; + EditorWindowPointerCaptureOwner m_pointerCaptureOwner = + EditorWindowPointerCaptureOwner::None; }; } // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp b/editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp new file mode 100644 index 00000000..e0daacb4 --- /dev/null +++ b/editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp @@ -0,0 +1,402 @@ +#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" + +#include "Bootstrap/EditorResources.h" +#include "Composition/EditorContext.h" +#include "Platform/Win32/Windowing/EditorWindowSupport.h" +#include "Support/EmbeddedPngLoader.h" + +#include + +#include +#include +#include +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +using App::LoadEmbeddedPngTexture; +using namespace EditorWindowSupport; + +namespace { + +constexpr float kFrameTimeSmoothingFactor = 0.12f; +constexpr float kFrameStatsDisplayRefreshIntervalSeconds = 0.25f; + +} + +EditorWindowRuntimeController::EditorWindowRuntimeController( + std::unique_ptr contentController) + : m_contentController(std::move(contentController)) {} + +EditorWindowRuntimeController::~EditorWindowRuntimeController() = default; + +bool EditorWindowRuntimeController::IsReady() const { + return m_ready; +} + +EditorWindowWorkspaceBinding* EditorWindowRuntimeController::TryGetWorkspaceBinding() { + return m_contentController != nullptr + ? m_contentController->TryGetWorkspaceBinding() + : nullptr; +} + +const EditorWindowWorkspaceBinding* EditorWindowRuntimeController::TryGetWorkspaceBinding() const { + return m_contentController != nullptr + ? m_contentController->TryGetWorkspaceBinding() + : nullptr; +} + +EditorWindowDockHostBinding* EditorWindowRuntimeController::TryGetDockHostBinding() { + return m_contentController != nullptr + ? m_contentController->TryGetDockHostBinding() + : nullptr; +} + +const EditorWindowDockHostBinding* EditorWindowRuntimeController::TryGetDockHostBinding() const { + return m_contentController != nullptr + ? m_contentController->TryGetDockHostBinding() + : nullptr; +} + +const EditorWindowInputFeedbackBinding* +EditorWindowRuntimeController::TryGetInputFeedbackBinding() const { + return m_contentController != nullptr + ? m_contentController->TryGetInputFeedbackBinding() + : nullptr; +} + +const EditorWindowTitleBarBinding* EditorWindowRuntimeController::TryGetTitleBarBinding() const { + return m_contentController != nullptr + ? m_contentController->TryGetTitleBarBinding() + : nullptr; +} + +const UIEditorShellInteractionFrame& EditorWindowRuntimeController::GetShellFrame() const { + assert(m_contentController != nullptr); + return m_contentController->GetShellFrame(); +} + +const UIEditorShellInteractionState& EditorWindowRuntimeController::GetShellInteractionState() + const { + assert(m_contentController != nullptr); + return m_contentController->GetShellInteractionState(); +} + +::XCEngine::UI::UISize EditorWindowRuntimeController::ResolveMinimumOuterSize() const { + assert(m_contentController != nullptr); + return m_contentController->ResolveMinimumOuterSize(); +} + +void EditorWindowRuntimeController::SetDpiScale(float dpiScale) { + m_dpiScale = dpiScale > 0.0f ? dpiScale : 1.0f; + m_textSystem.SetDpiScale(m_dpiScale); + m_uiRenderer.SetDpiScale(m_dpiScale); +} + +::XCEngine::UI::Editor::UIEditorTextMeasurer& EditorWindowRuntimeController::GetTextMeasurer() { + return m_textSystem; +} + +const ::XCEngine::UI::Editor::UIEditorTextMeasurer& +EditorWindowRuntimeController::GetTextMeasurer() const { + return m_textSystem; +} + +const ::XCEngine::UI::UITextureHandle& EditorWindowRuntimeController::GetTitleBarLogoIcon() const { + return m_titleBarLogoIcon; +} + +bool EditorWindowRuntimeController::Initialize( + HWND hwnd, + const std::filesystem::path& repoRoot, + EditorContext& editorContext, + const std::filesystem::path& captureRoot, + bool autoCaptureOnStartup) { + if (hwnd == nullptr) { + LogRuntimeTrace("app", "window initialize skipped: hwnd is null"); + return false; + } + + RECT clientRect = {}; + GetClientRect(hwnd, &clientRect); + const int clientWidth = (std::max)(clientRect.right - clientRect.left, 1L); + const int clientHeight = (std::max)(clientRect.bottom - clientRect.top, 1L); + if (!m_windowRenderer.Initialize(hwnd, clientWidth, clientHeight)) { + LogRuntimeTrace("app", "d3d12 window renderer initialization failed"); + return false; + } + + if (!m_textureHost.Initialize(m_windowRenderer)) { + LogRuntimeTrace("app", "d3d12 ui texture host initialization failed"); + m_windowRenderer.Shutdown(); + return false; + } + + if (!m_textSystem.Initialize()) { + LogRuntimeTrace("app", "d3d12 ui text system initialization failed"); + m_textureHost.Shutdown(); + m_windowRenderer.Shutdown(); + return false; + } + m_textSystem.SetDpiScale(m_dpiScale); + + if (!m_uiRenderer.Initialize(m_windowRenderer, m_textureHost, m_textSystem)) { + LogRuntimeTrace("app", "d3d12 ui renderer initialization failed"); + m_textSystem.Shutdown(); + m_textureHost.Shutdown(); + m_windowRenderer.Shutdown(); + return false; + } + m_uiRenderer.SetDpiScale(m_dpiScale); + + const Host::D3D12WindowRenderLoopAttachResult attachResult = + m_windowRenderLoop.Attach(m_uiRenderer, m_windowRenderer); + if (!attachResult.warning.empty()) { + LogRuntimeTrace("app", attachResult.warning); + } + + editorContext.AttachTextMeasurer(m_textSystem); + assert(m_contentController != nullptr); + m_contentController->Initialize(EditorWindowContentInitializationContext{ + .repoRoot = repoRoot, + .editorContext = editorContext, + .textureHost = m_textureHost, + .textMeasurer = m_textSystem, + .viewportRenderer = m_windowRenderer, + }); + m_contentController->SetViewportSurfacePresentationEnabled( + attachResult.hasViewportSurfacePresentation); + + std::string titleBarLogoError = {}; + if (!LoadEmbeddedPngTexture( + m_textureHost, + IDR_PNG_LOGO_ICON, + m_titleBarLogoIcon, + titleBarLogoError)) { + LogRuntimeTrace("icons", "titlebar logo_icon.png: " + titleBarLogoError); + } + + if (const EditorWindowWorkspaceBinding* workspaceBinding = TryGetWorkspaceBinding(); + workspaceBinding != nullptr) { + const UIEditorWorkspaceController* workspaceController = + workspaceBinding->TryGetWorkspaceController(); + assert(workspaceController != nullptr); + LogRuntimeTrace( + "app", + "shell runtime initialized: " + + editorContext.DescribeWorkspaceState( + *workspaceController, + m_contentController->GetShellInteractionState())); + } else { + LogRuntimeTrace("app", "window content initialized: non-workspace content"); + } + + ResetFrameTiming(); + m_ready = true; + + m_screenshotController.Initialize(captureRoot); + if (autoCaptureOnStartup) { + m_screenshotController.RequestCapture("startup"); + editorContext.SetStatus("Capture", "Startup capture requested."); + } + + return true; +} + +void EditorWindowRuntimeController::Shutdown() { + m_ready = false; + ResetFrameTiming(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=WaitForGpuIdle"); + m_windowRenderer.WaitForGpuIdle(); + LogRuntimeTrace( + "window-close", + "EditorWindowRuntimeController::Shutdown stage=ScreenshotController"); + m_screenshotController.Shutdown(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=WindowContent"); + if (m_contentController != nullptr) { + m_contentController->Shutdown(); + } + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=RenderLoopDetach"); + m_windowRenderLoop.Detach(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=UiRenderer"); + m_uiRenderer.Shutdown(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=TextSystem"); + m_textSystem.Shutdown(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=TitleBarLogo"); + m_textureHost.ReleaseTexture(m_titleBarLogoIcon); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=TextureHost"); + m_textureHost.Shutdown(); + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=WindowRenderer"); + m_windowRenderer.Shutdown(); + m_dpiScale = 1.0f; + LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown end"); +} + +void EditorWindowRuntimeController::ResetInteractionState() { + if (m_contentController != nullptr) { + m_contentController->ResetInteractionState(); + } + ResetFrameTiming(); +} + +bool EditorWindowRuntimeController::ApplyResize(UINT width, UINT height) { + if (!m_ready || width == 0u || height == 0u) { + return false; + } + + const Host::D3D12WindowRenderLoopResizeResult resizeResult = + m_windowRenderLoop.ApplyResize(width, height); + if (m_contentController != nullptr) { + m_contentController->SetViewportSurfacePresentationEnabled( + resizeResult.hasViewportSurfacePresentation); + } + + if (!resizeResult.windowRendererWarning.empty()) { + LogRuntimeTrace("present", resizeResult.windowRendererWarning); + } + + return resizeResult.hasViewportSurfacePresentation; +} + +Host::D3D12WindowRenderLoopFrameContext EditorWindowRuntimeController::BeginFrame() { + UpdateFrameTiming(); + return m_windowRenderLoop.BeginFrame(); +} + +Host::D3D12WindowRenderLoopPresentResult EditorWindowRuntimeController::Present( + const ::XCEngine::UI::UIDrawData& drawData) { + std::filesystem::path capturePath = {}; + const bool captureRequested = m_screenshotController.TryBeginCapture(capturePath); + + Host::D3D12WindowRenderLoopPresentResult result = + m_windowRenderLoop.Present( + drawData, + captureRequested ? &capturePath : nullptr); + + if (captureRequested) { + const bool captureSucceeded = result.framePresented && result.captureSucceeded; + if (captureSucceeded) { + m_screenshotController.CompleteCaptureSuccess(capturePath); + LogRuntimeTrace("capture", "native d3d12 capture succeeded: " + capturePath.string()); + } else { + std::string captureError = result.captureError; + if (captureError.empty()) { + captureError = !result.warning.empty() + ? result.warning + : "Screenshot capture did not complete."; + } + m_screenshotController.CompleteCaptureFailure(std::move(captureError)); + LogRuntimeTrace( + "capture", + "native d3d12 capture failed: " + m_screenshotController.GetLastCaptureError()); + } + } + + return result; +} + +EditorWindowFrameTransferRequests EditorWindowRuntimeController::UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData) { + assert(m_contentController != nullptr); + return m_contentController->UpdateAndAppend(context, drawData); +} + +void EditorWindowRuntimeController::RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext) { + if (m_contentController != nullptr) { + m_contentController->RenderRequestedViewports(renderContext); + } +} + +void EditorWindowRuntimeController::RequestManualScreenshot(std::string reason) { + m_screenshotController.RequestCapture(std::move(reason)); +} + +std::string EditorWindowRuntimeController::BuildCaptureStatusText() const { + if (m_screenshotController.HasPendingCapture()) { + return "Shot pending..."; + } + + if (!m_screenshotController.GetLastCaptureError().empty()) { + return TruncateText(m_screenshotController.GetLastCaptureError(), 38u); + } + + if (!m_screenshotController.GetLastCaptureSummary().empty()) { + return TruncateText(m_screenshotController.GetLastCaptureSummary(), 38u); + } + + return {}; +} + +std::string EditorWindowRuntimeController::BuildFrameRateText() const { + return m_frameRateText; +} + +void EditorWindowRuntimeController::ResetFrameTiming() { + m_lastFrameTime = {}; + m_hasLastFrameTime = false; + m_smoothedDeltaTimeSeconds = 0.0f; + m_frameStatsDisplayAccumulatorSeconds = 0.0f; + m_displayFps = 0.0f; + m_displayFrameTimeMs = 0.0f; + m_frameRateText.clear(); +} + +void EditorWindowRuntimeController::UpdateFrameTiming() { + const auto now = std::chrono::steady_clock::now(); + if (!m_hasLastFrameTime) { + m_lastFrameTime = now; + m_hasLastFrameTime = true; + return; + } + + const float deltaTime = std::chrono::duration(now - m_lastFrameTime).count(); + m_lastFrameTime = now; + if (deltaTime <= 0.0f) { + return; + } + + if (m_smoothedDeltaTimeSeconds <= 0.0f) { + m_smoothedDeltaTimeSeconds = deltaTime; + } else { + m_smoothedDeltaTimeSeconds += + (deltaTime - m_smoothedDeltaTimeSeconds) * kFrameTimeSmoothingFactor; + } + + m_displayFrameTimeMs = m_smoothedDeltaTimeSeconds * 1000.0f; + m_displayFps = m_smoothedDeltaTimeSeconds > 0.0f + ? 1.0f / m_smoothedDeltaTimeSeconds + : 0.0f; + + m_frameStatsDisplayAccumulatorSeconds += deltaTime; + if (m_frameRateText.empty() || + m_frameStatsDisplayAccumulatorSeconds >= kFrameStatsDisplayRefreshIntervalSeconds) { + RefreshDisplayedFrameStats(); + m_frameStatsDisplayAccumulatorSeconds = 0.0f; + } +} + +void EditorWindowRuntimeController::RefreshDisplayedFrameStats() { + if (m_displayFps <= 0.0f || m_displayFrameTimeMs <= 0.0f) { + m_frameRateText.clear(); + return; + } + + const int roundedFps = (std::max)(0, static_cast(std::lround(m_displayFps))); + const int roundedFrameTimeMs = + (std::max)(0, static_cast(std::lround(m_displayFrameTimeMs))); + + char buffer[48] = {}; + std::snprintf( + buffer, + sizeof(buffer), + "FPS %3d | %2d ms", + roundedFps, + roundedFrameTimeMs); + m_frameRateText = buffer; +} + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h b/editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h similarity index 51% rename from new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h rename to editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h index 06814ef3..881ca11e 100644 --- a/new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h +++ b/editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h @@ -1,20 +1,24 @@ -#pragma once +#pragma once #ifndef NOMINMAX #define NOMINMAX #endif -#include "Platform/Win32/Rendering/D3D12WindowRenderHost.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" #include "Platform/Win32/Runtime/EditorWindowScreenshotController.h" -#include "Windowing/Content/EditorWindowContentRuntime.h" -#include + +#include +#include +#include +#include +#include #include #include +#include #include -#include #include #include @@ -25,8 +29,7 @@ class EditorContext; class EditorWindowRuntimeController final { public: explicit EditorWindowRuntimeController( - EditorWindowContentSpec contentSpec, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType); + std::unique_ptr contentController); ~EditorWindowRuntimeController(); EditorWindowRuntimeController(const EditorWindowRuntimeController&) = delete; @@ -36,25 +39,12 @@ public: bool IsReady() const; - const UIEditorWorkspaceController& GetWorkspaceController() const; - void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController); - void UpdateUtilityWindowSession(EditorUtilityWindowSession session); - void SetExternalDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview); - void ClearExternalDockHostDropPreview(); - bool TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const ::XCEngine::UI::UIPoint& point, - ::XCEngine::UI::UIPoint& outHotspot) const; - UIEditorDockHostTabDropTarget ResolveDockTabDropTarget( - const ::XCEngine::UI::UIPoint& point) const; - EditorWindowContentPresentationSummary BuildPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const; - ::XCEngine::UI::Editor::Windowing::Domain::WindowCaptureDemand GetCurrentCaptureDemand() - const; - ::XCEngine::UI::Editor::Windowing::Domain::WindowCursorType GetCurrentCursorType() const; + EditorWindowWorkspaceBinding* TryGetWorkspaceBinding(); + const EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() const; + EditorWindowDockHostBinding* TryGetDockHostBinding(); + const EditorWindowDockHostBinding* TryGetDockHostBinding() const; + const EditorWindowInputFeedbackBinding* TryGetInputFeedbackBinding() const; + const EditorWindowTitleBarBinding* TryGetTitleBarBinding() const; const UIEditorShellInteractionFrame& GetShellFrame() const; const UIEditorShellInteractionState& GetShellInteractionState() const; @@ -75,29 +65,41 @@ public: void ResetInteractionState(); bool ApplyResize(UINT width, UINT height); - EditorWindowContentUpdateResult RenderFrame( - const EditorWindowContentFrameContext* contentContext, - ::XCEngine::UI::UIDrawData& drawData, - const std::function& finalizeFrame); + Host::D3D12WindowRenderLoopFrameContext BeginFrame(); + Host::D3D12WindowRenderLoopPresentResult Present( + const ::XCEngine::UI::UIDrawData& drawData); + EditorWindowFrameTransferRequests UpdateAndAppend( + const EditorWindowContentFrameContext& context, + ::XCEngine::UI::UIDrawData& drawData); + void RenderRequestedViewports( + const ::XCEngine::Rendering::RenderContext& renderContext); void RequestManualScreenshot(std::string reason); std::string BuildCaptureStatusText() const; std::string BuildFrameRateText() const; private: - EditorWindowContentUpdateResult UpdateAndAppend( - const EditorWindowContentFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData); + void ResetFrameTiming(); + void UpdateFrameTiming(); + void RefreshDisplayedFrameStats(); - D3D12WindowRenderHost m_renderHost = {}; + Host::D3D12WindowRenderer m_windowRenderer = {}; + Host::D3D12UiTextureHost m_textureHost = {}; + Host::D3D12UiTextSystem m_textSystem = {}; + Host::D3D12UiRenderer m_uiRenderer = {}; + Host::D3D12WindowRenderLoop m_windowRenderLoop = {}; EditorWindowScreenshotController m_screenshotController = {}; ::XCEngine::UI::UITextureHandle m_titleBarLogoIcon = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType m_windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; - ::XCEngine::UI::Editor::Windowing::Domain::WindowContentOutput m_latestContentOutput = {}; - EditorWindowContentRuntime m_contentRuntime; + std::unique_ptr m_contentController = {}; + std::chrono::steady_clock::time_point m_lastFrameTime = {}; + bool m_hasLastFrameTime = false; + float m_smoothedDeltaTimeSeconds = 0.0f; + float m_frameStatsDisplayAccumulatorSeconds = 0.0f; + float m_displayFps = 0.0f; + float m_displayFrameTimeMs = 0.0f; + float m_dpiScale = 1.0f; + std::string m_frameRateText = {}; + bool m_ready = false; }; } // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp b/editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp similarity index 100% rename from new_editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp rename to editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.h b/editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.h similarity index 100% rename from new_editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.h rename to editor/app/Platform/Win32/Runtime/EditorWindowScreenshotController.h diff --git a/new_editor/app/Platform/Win32/Runtime/InputModifierTracker.h b/editor/app/Platform/Win32/Runtime/InputModifierTracker.h similarity index 100% rename from new_editor/app/Platform/Win32/Runtime/InputModifierTracker.h rename to editor/app/Platform/Win32/Runtime/InputModifierTracker.h diff --git a/new_editor/app/Platform/Win32/System/Win32SystemInteractionHost.cpp b/editor/app/Platform/Win32/System/Win32SystemInteractionHost.cpp similarity index 100% rename from new_editor/app/Platform/Win32/System/Win32SystemInteractionHost.cpp rename to editor/app/Platform/Win32/System/Win32SystemInteractionHost.cpp diff --git a/new_editor/app/Platform/Win32/System/Win32SystemInteractionHost.h b/editor/app/Platform/Win32/System/Win32SystemInteractionHost.h similarity index 100% rename from new_editor/app/Platform/Win32/System/Win32SystemInteractionHost.h rename to editor/app/Platform/Win32/System/Win32SystemInteractionHost.h diff --git a/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp b/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp new file mode 100644 index 00000000..a271b019 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp @@ -0,0 +1,46 @@ +#include "Platform/Win32/Windowing/EditorFloatingWindowPlacement.h" + +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +constexpr LONG kFloatingWindowTopOffset = 24; + +} + +RECT BuildEditorFloatingWindowRect( + const POINT& screenPoint, + LONG preferredWidth, + LONG preferredHeight, + LONG fallbackWidth, + LONG fallbackHeight) { + const LONG resolvedWidth = preferredWidth > 0 ? preferredWidth : fallbackWidth; + const LONG resolvedHeight = preferredHeight > 0 ? preferredHeight : fallbackHeight; + const LONG left = screenPoint.x - resolvedWidth / 2; + const LONG top = screenPoint.y - kFloatingWindowTopOffset; + RECT rect = { + left, + top, + left + resolvedWidth, + top + resolvedHeight + }; + + const HMONITOR monitor = MonitorFromPoint(screenPoint, MONITOR_DEFAULTTONEAREST); + MONITORINFO monitorInfo = {}; + monitorInfo.cbSize = sizeof(monitorInfo); + if (monitor != nullptr && GetMonitorInfoW(monitor, &monitorInfo)) { + const RECT& workArea = monitorInfo.rcWork; + const LONG width = rect.right - rect.left; + const LONG height = rect.bottom - rect.top; + rect.left = (std::max)(workArea.left, (std::min)(rect.left, workArea.right - width)); + rect.top = (std::max)(workArea.top, (std::min)(rect.top, workArea.bottom - height)); + rect.right = rect.left + width; + rect.bottom = rect.top + height; + } + + return rect; +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.h b/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.h new file mode 100644 index 00000000..ae113c72 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include + +namespace XCEngine::UI::Editor::App { + +RECT BuildEditorFloatingWindowRect( + const POINT& screenPoint, + LONG preferredWidth = 0, + LONG preferredHeight = 0, + LONG fallbackWidth = 960, + LONG fallbackHeight = 720); + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.cpp b/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.cpp new file mode 100644 index 00000000..5c9beac1 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.cpp @@ -0,0 +1,150 @@ +#include "Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h" + +#include "UtilityWindows/EditorUtilityWindowRegistry.h" +#include "Platform/Win32/Windowing/EditorFloatingWindowPlacement.h" +#include "Platform/Win32/Content/EditorUtilityWindowContentController.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" + +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +bool IsLiveWindow(const EditorWindow* window) { + return window != nullptr && + window->GetHwnd() != nullptr && + window->GetLifecycleState() == EditorWindowLifecycleState::Running; +} + +LONG ResolveOuterDimension(float value, LONG fallback) { + return value > 0.0f + ? static_cast(std::lround(value)) + : fallback; +} + +} + +EditorUtilityWindowCoordinator::EditorUtilityWindowCoordinator( + EditorWindowHostRuntime& hostRuntime) + : m_hostRuntime(hostRuntime) {} + +EditorUtilityWindowCoordinator::~EditorUtilityWindowCoordinator() = default; + +void EditorUtilityWindowCoordinator::BindLifecycleCoordinator( + EditorWindowLifecycleCoordinator& lifecycleCoordinator) { + m_lifecycleCoordinator = &lifecycleCoordinator; +} + +void EditorUtilityWindowCoordinator::HandleWindowFrameTransferRequests( + EditorWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests) { + if (transferRequests.openUtilityWindow.has_value() && + transferRequests.openUtilityWindow->IsValid()) { + TryProcessOpenUtilityWindowRequest(sourceWindow, *transferRequests.openUtilityWindow); + } +} + +bool EditorUtilityWindowCoordinator::TryProcessOpenUtilityWindowRequest( + EditorWindow& sourceWindow, + const EditorWindowOpenUtilityWindowRequest& request) { + if (!IsLiveWindow(&sourceWindow)) { + LogRuntimeTrace( + "utility", + "open utility window request rejected: source window is not running"); + return false; + } + + const EditorUtilityWindowDescriptor* descriptor = + ResolveEditorUtilityWindowDescriptor(request.kind); + if (descriptor == nullptr) { + LogRuntimeTrace("utility", "open utility window request rejected: unknown kind"); + return false; + } + + if (EditorWindow* existingWindow = m_hostRuntime.FindWindow(descriptor->windowId); + existingWindow != nullptr && existingWindow->IsDestroyed() && + m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->ReapDestroyedWindows(); + } + + if (EditorWindow* existingWindow = m_hostRuntime.FindWindow(descriptor->windowId); + IsLiveWindow(existingWindow)) { + FocusWindow(*existingWindow); + LogRuntimeTrace( + "utility", + "reused utility window '" + std::string(descriptor->windowId) + "'"); + return true; + } + + if (EditorWindow* existingWindow = m_hostRuntime.FindWindow(descriptor->windowId); + existingWindow != nullptr) { + LogRuntimeTrace( + "utility", + "open utility window request rejected: existing utility window is not reusable"); + return false; + } + + std::unique_ptr contentController = + CreateEditorUtilityWindowContentController(*descriptor); + if (contentController == nullptr) { + LogRuntimeTrace( + "utility", + "open utility window request rejected: content factory returned null"); + return false; + } + + EditorWindowHostRuntime::CreateParams createParams = {}; + createParams.windowId = std::string(descriptor->windowId); + createParams.title = descriptor->title; + createParams.primary = false; + createParams.initialWidth = ResolveOuterDimension( + descriptor->preferredOuterSize.width, + createParams.initialWidth); + createParams.initialHeight = ResolveOuterDimension( + descriptor->preferredOuterSize.height, + createParams.initialHeight); + if (request.useCursorPlacement) { + const RECT rect = BuildEditorFloatingWindowRect( + request.screenPoint, + createParams.initialWidth, + createParams.initialHeight); + createParams.initialX = rect.left; + createParams.initialY = rect.top; + createParams.initialWidth = rect.right - rect.left; + createParams.initialHeight = rect.bottom - rect.top; + } + + EditorWindow* utilityWindow = + m_hostRuntime.CreateEditorWindow(std::move(contentController), createParams); + if (utilityWindow == nullptr) { + LogRuntimeTrace("utility", "failed to create utility window"); + return false; + } + + FocusWindow(*utilityWindow); + LogRuntimeTrace( + "utility", + "opened utility window '" + std::string(descriptor->windowId) + "'"); + return true; +} + +void EditorUtilityWindowCoordinator::FocusWindow(EditorWindow& window) const { + if (!IsLiveWindow(&window)) { + return; + } + + ShowWindow(window.GetHwnd(), SW_RESTORE); + SetForegroundWindow(window.GetHwnd()); +} + +void EditorUtilityWindowCoordinator::LogRuntimeTrace( + std::string_view channel, + std::string_view message) const { + m_hostRuntime.LogRuntimeTrace(channel, message); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h b/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h new file mode 100644 index 00000000..1b2ebe5e --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWindow; +class EditorWindowHostRuntime; +class EditorWindowLifecycleCoordinator; + +class EditorUtilityWindowCoordinator final { +public: + explicit EditorUtilityWindowCoordinator(EditorWindowHostRuntime& hostRuntime); + ~EditorUtilityWindowCoordinator(); + + void BindLifecycleCoordinator(EditorWindowLifecycleCoordinator& lifecycleCoordinator); + void HandleWindowFrameTransferRequests( + EditorWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests); + +private: + bool TryProcessOpenUtilityWindowRequest( + EditorWindow& sourceWindow, + const EditorWindowOpenUtilityWindowRequest& request); + void FocusWindow(EditorWindow& window) const; + void LogRuntimeTrace(std::string_view channel, std::string_view message) const; + + EditorWindowHostRuntime& m_hostRuntime; + EditorWindowLifecycleCoordinator* m_lifecycleCoordinator = nullptr; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindow.cpp b/editor/app/Platform/Win32/Windowing/EditorWindow.cpp new file mode 100644 index 00000000..1f67497d --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindow.cpp @@ -0,0 +1,900 @@ +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Bootstrap/EditorResources.h" +#include "Platform/Win32/Chrome/EditorWindowChromeController.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" +#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" +#include "Platform/Win32/Windowing/EditorWindowSession.h" +#include "Platform/Win32/Windowing/EditorWindowSupport.h" +#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h" +#include "Platform/Win32/Runtime/EditorWindowInputController.h" +#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" +#include "Composition/EditorContext.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace XCEngine::UI::Editor::App::EditorWindowSupport { + +UINT QuerySystemDpi() { + HDC screenDc = GetDC(nullptr); + if (screenDc == nullptr) { + return kDefaultDpi; + } + + const int dpiX = GetDeviceCaps(screenDc, LOGPIXELSX); + ReleaseDC(nullptr, screenDc); + return dpiX > 0 ? static_cast(dpiX) : kDefaultDpi; +} + +UINT QueryWindowDpi(HWND hwnd) { + if (hwnd != nullptr) { + const HMODULE user32 = GetModuleHandleW(L"user32.dll"); + if (user32 != nullptr) { + using GetDpiForWindowFn = UINT(WINAPI*)(HWND); + const auto getDpiForWindow = + reinterpret_cast(GetProcAddress(user32, "GetDpiForWindow")); + if (getDpiForWindow != nullptr) { + const UINT dpi = getDpiForWindow(hwnd); + if (dpi != 0u) { + return dpi; + } + } + } + } + + return QuerySystemDpi(); +} + +bool ResolveVerboseRuntimeTraceEnabled() { + wchar_t buffer[8] = {}; + const DWORD length = GetEnvironmentVariableW( + L"XCUIEDITOR_VERBOSE_TRACE", + buffer, + static_cast(std::size(buffer))); + return length > 0u && buffer[0] != L'0'; +} + +void LogRuntimeTrace(std::string_view channel, std::string_view message) { + AppendUIEditorRuntimeTrace(channel, message); +} + +} // namespace XCEngine::UI::Editor::App::EditorWindowSupport + +namespace XCEngine::UI::Editor::App { + +using namespace EditorWindowSupport; +using ::XCEngine::UI::UIPoint; + +EditorWindow::EditorWindow( + std::string windowId, + std::wstring title, + bool primary, + std::unique_ptr contentController) + : m_session(std::make_unique( + std::move(windowId), + std::move(title), + primary)) + , m_chromeController(std::make_unique()) + , m_frameOrchestrator(std::make_unique()) + , m_inputController(std::make_unique()) + , m_runtime(std::make_unique( + std::move(contentController))) {} + +EditorWindow::~EditorWindow() = default; + +std::string_view EditorWindow::GetWindowId() const { + return m_session->GetWindowId(); +} + +HWND EditorWindow::GetHwnd() const { + return m_session->GetHwnd(); +} + +bool EditorWindow::HasHwnd() const { + return m_session->HasHwnd(); +} + +EditorWindowLifecycleState EditorWindow::GetLifecycleState() const { + return m_session->GetLifecycleState(); +} + +bool EditorWindow::IsPrimary() const { + return m_session->IsPrimary(); +} + +bool EditorWindow::IsClosing() const { + return m_session->IsClosing(); +} + +bool EditorWindow::IsDestroyed() const { + return m_session->IsDestroyed(); +} + +bool EditorWindow::IsRenderReady() const { + return m_runtime->IsReady(); +} + +const std::wstring& EditorWindow::GetTitle() const { + return m_session->GetTitle(); +} + +std::string_view EditorWindow::GetCachedTitleText() const { + return m_session->GetCachedTitleText(); +} + +const UIEditorWorkspaceController* EditorWindow::TryGetWorkspaceController() const { + const EditorWindowWorkspaceBinding* workspaceBinding = m_runtime->TryGetWorkspaceBinding(); + return workspaceBinding != nullptr + ? workspaceBinding->TryGetWorkspaceController() + : nullptr; +} + +const UIEditorWorkspaceController& EditorWindow::GetWorkspaceController() const { + const UIEditorWorkspaceController* workspaceController = TryGetWorkspaceController(); + assert(workspaceController != nullptr); + return *workspaceController; +} + +void EditorWindow::AttachHwnd(HWND hwnd) { + m_session->AttachHwnd(hwnd); +} + +void EditorWindow::MarkInitializing() { + m_session->MarkInitializing(); +} + +void EditorWindow::MarkRunning() { + m_session->MarkRunning(); +} + +void EditorWindow::MarkDestroyed() { + m_session->MarkDestroyed(); + m_inputController->ResetWindowState(); +} + +void EditorWindow::MarkClosing() { + m_session->MarkClosing(); +} + +void EditorWindow::SetPrimary(bool primary) { + m_session->SetPrimary(primary); +} + +void EditorWindow::SetTitle(std::wstring title) { + m_session->SetTitle(std::move(title)); +} + +void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) { + EditorWindowWorkspaceBinding* workspaceBinding = m_runtime->TryGetWorkspaceBinding(); + assert(workspaceBinding != nullptr); + workspaceBinding->ReplaceWorkspaceController(std::move(workspaceController)); +} + +void EditorWindow::InvalidateHostWindow() const { + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr && IsWindow(hwnd)) { + InvalidateRect(hwnd, nullptr, FALSE); + } +} + +bool EditorWindow::Initialize( + const std::filesystem::path& repoRoot, + EditorContext& editorContext, + const std::filesystem::path& captureRoot, + bool autoCaptureOnStartup) { + if (m_session->GetHwnd() == nullptr) { + LogRuntimeTrace("app", "window initialize skipped: hwnd is null"); + return false; + } + + Host::RefreshBorderlessWindowDwmDecorations(m_session->GetHwnd()); + m_chromeController->Reset(); + m_chromeController->SetWindowDpi(QueryWindowDpi(m_session->GetHwnd())); + m_runtime->SetDpiScale(GetDpiScale()); + + std::ostringstream dpiTrace = {}; + dpiTrace << "initial dpi=" << m_chromeController->GetWindowDpi() + << " scale=" << GetDpiScale(); + LogRuntimeTrace("window", dpiTrace.str()); + + MarkInitializing(); + const bool initialized = m_runtime->Initialize( + m_session->GetHwnd(), + repoRoot, + editorContext, + captureRoot, + autoCaptureOnStartup); + if (initialized) { + MarkRunning(); + } else { + m_session->MarkNativeAttached(); + } + return initialized; +} + +void EditorWindow::Shutdown() { + std::ostringstream trace = {}; + trace << "EditorWindow::Shutdown begin windowId='" << GetWindowId() + << "' hwnd=0x" << std::hex << std::uppercase + << reinterpret_cast(GetHwnd()) + << std::dec + << " primary=" << (IsPrimary() ? 1 : 0) + << " lifecycle=" << GetEditorWindowLifecycleStateName(GetLifecycleState()) + << " runtimeReady=" << (m_runtime->IsReady() ? 1 : 0); + LogRuntimeTrace("window-close", trace.str()); + ForceReleasePointerCapture(); + + if (m_runtime->IsReady()) { + m_runtime->Shutdown(); + } + m_inputController->ClearPendingEvents(); + m_chromeController->Reset(); + LogRuntimeTrace( + "window-close", + "EditorWindow::Shutdown end windowId='" + std::string(GetWindowId()) + "'"); +} + +void EditorWindow::ResetInteractionState() { + ForceReleasePointerCapture(); + + m_inputController->ResetInteractionState(); + m_runtime->ResetInteractionState(); + m_chromeController->ResetChromeState(); + m_chromeController->EndBorderlessResize(); + m_chromeController->EndBorderlessWindowDragRestore(); + m_chromeController->EndInteractiveResize(); + m_chromeController->SetHoveredBorderlessResizeEdge( + Host::BorderlessWindowResizeEdge::None); + m_chromeController->ClearPredictedClientPixelSize(); +} + +bool EditorWindow::ApplyWindowResize(UINT width, UINT height) { + if (!m_runtime->IsReady() || width == 0u || height == 0u) { + return false; + } + return m_runtime->ApplyResize(width, height); +} + +bool EditorWindow::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const { + outWidth = 0u; + outHeight = 0u; + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { + return false; + } + + RECT clientRect = {}; + if (!GetClientRect(hwnd, &clientRect)) { + return false; + } + + const LONG width = clientRect.right - clientRect.left; + const LONG height = clientRect.bottom - clientRect.top; + if (width <= 0 || height <= 0) { + return false; + } + + outWidth = static_cast(width); + outHeight = static_cast(height); + return true; +} + +bool EditorWindow::ResolveRenderClientPixelSize(UINT& outWidth, UINT& outHeight) const { + if (m_chromeController->TryGetPredictedClientPixelSize(outWidth, outHeight)) { + return true; + } + + return QueryCurrentClientPixelSize(outWidth, outHeight); +} + +float EditorWindow::GetDpiScale() const { + return m_chromeController->GetDpiScale(kBaseDpiScale); +} + +float EditorWindow::PixelsToDips(float pixels) const { + const float dpiScale = GetDpiScale(); + return dpiScale > 0.0f ? pixels / dpiScale : pixels; +} + +UIPoint EditorWindow::ConvertClientPixelsToDips(LONG x, LONG y) const { + return UIPoint( + PixelsToDips(static_cast(x)), + PixelsToDips(static_cast(y))); +} + +UIPoint EditorWindow::ConvertScreenPixelsToClientDips(const POINT& screenPoint) const { + POINT clientPoint = screenPoint; + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + ScreenToClient(hwnd, &clientPoint); + } + + const float dpiScale = m_chromeController->GetDpiScale(kBaseDpiScale); + return UIPoint( + dpiScale > 0.0f + ? static_cast(clientPoint.x) / dpiScale + : static_cast(clientPoint.x), + dpiScale > 0.0f + ? static_cast(clientPoint.y) / dpiScale + : static_cast(clientPoint.y)); +} + +bool EditorWindow::TryResolveDockTabDragHotspot( + std::string_view nodeId, + std::string_view panelId, + const POINT& screenPoint, + POINT& outHotspot) const { + const EditorWindowDockHostBinding* dockHostBinding = m_runtime->TryGetDockHostBinding(); + if (dockHostBinding == nullptr) { + outHotspot = {}; + return false; + } + + const UIPoint clientPointDips = ConvertScreenPixelsToClientDips(screenPoint); + UIPoint hotspotDips = {}; + if (!dockHostBinding->TryResolveDockTabDragHotspot( + nodeId, + panelId, + clientPointDips, + hotspotDips)) { + outHotspot = {}; + return false; + } + + const float dpiScale = GetDpiScale(); + outHotspot.x = static_cast(std::lround(hotspotDips.x * dpiScale)); + outHotspot.y = static_cast(std::lround(hotspotDips.y * dpiScale)); + return true; +} + +bool EditorWindow::TryResolveDockTabDropTarget( + const POINT& screenPoint, + UIEditorDockHostTabDropTarget& outTarget) const { + const EditorWindowDockHostBinding* dockHostBinding = m_runtime->TryGetDockHostBinding(); + if (dockHostBinding == nullptr) { + outTarget = {}; + return false; + } + + outTarget = dockHostBinding->ResolveDockTabDropTarget( + ConvertScreenPixelsToClientDips(screenPoint)); + return outTarget.valid; +} + +bool EditorWindow::OnResize(UINT width, UINT height) { + const bool matchedPresentedPrediction = + m_chromeController->ConsumePresentedPredictedClientPixelSizeMatch(width, height); + if (!matchedPresentedPrediction) { + m_chromeController->ClearPredictedClientPixelSize(); + } + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + Host::RefreshBorderlessWindowDwmDecorations(hwnd); + } + + if (matchedPresentedPrediction) { + return false; + } + + ApplyWindowResize(width, height); + return true; +} + +void EditorWindow::OnEnterSizeMove() { + m_chromeController->BeginInteractiveResize(); +} + +bool EditorWindow::OnExitSizeMove() { + m_chromeController->EndInteractiveResize(); + m_chromeController->ClearPredictedClientPixelSize(); + UINT width = 0u; + UINT height = 0u; + if (QueryCurrentClientPixelSize(width, height)) { + ApplyWindowResize(width, height); + return true; + } + return false; +} + +void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) { + m_chromeController->SetWindowDpi(dpi == 0u ? kDefaultDpi : dpi); + m_runtime->SetDpiScale(GetDpiScale()); + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + const LONG windowWidth = suggestedRect.right - suggestedRect.left; + const LONG windowHeight = suggestedRect.bottom - suggestedRect.top; + SetWindowPos( + hwnd, + nullptr, + suggestedRect.left, + suggestedRect.top, + windowWidth, + windowHeight, + SWP_NOZORDER | SWP_NOACTIVATE); + UINT clientWidth = 0u; + UINT clientHeight = 0u; + if (QueryCurrentClientPixelSize(clientWidth, clientHeight)) { + ApplyWindowResize(clientWidth, clientHeight); + } + Host::RefreshBorderlessWindowDwmDecorations(hwnd); + } + + std::ostringstream trace = {}; + trace << "dpi changed to " << m_chromeController->GetWindowDpi() + << " scale=" << GetDpiScale(); + LogRuntimeTrace("window", trace.str()); +} + +bool EditorWindow::IsVerboseRuntimeTraceEnabled() { + static const bool s_enabled = ResolveVerboseRuntimeTraceEnabled(); + return s_enabled; +} + +} // namespace XCEngine::UI::Editor::App + +namespace XCEngine::UI::Editor::App { + +using namespace EditorWindowSupport; +using ::XCEngine::UI::UIDrawData; +using ::XCEngine::UI::UIDrawList; +using ::XCEngine::UI::UIInputEvent; +using ::XCEngine::UI::UIInputModifiers; +using ::XCEngine::UI::UIPointerButton; +using ::XCEngine::UI::UIRect; + +namespace { + +std::uint8_t ButtonMask(UIPointerButton button) { + switch (button) { + case UIPointerButton::Left: return 1u << 0u; + case UIPointerButton::Right: return 1u << 1u; + case UIPointerButton::Middle: return 1u << 2u; + case UIPointerButton::X1: return 1u << 3u; + case UIPointerButton::X2: return 1u << 4u; + case UIPointerButton::None: + default: + return 0u; + } +} + +std::uint8_t ButtonMaskFromModifiers(const UIInputModifiers& modifiers) { + std::uint8_t mask = 0u; + if (modifiers.leftMouse) { + mask |= ButtonMask(UIPointerButton::Left); + } + if (modifiers.rightMouse) { + mask |= ButtonMask(UIPointerButton::Right); + } + if (modifiers.middleMouse) { + mask |= ButtonMask(UIPointerButton::Middle); + } + if (modifiers.x1Mouse) { + mask |= ButtonMask(UIPointerButton::X1); + } + if (modifiers.x2Mouse) { + mask |= ButtonMask(UIPointerButton::X2); + } + return mask; +} + +std::uint8_t ResolveExpectedShellCaptureButtons( + const UIEditorShellInteractionState& shellState) { + std::uint8_t expectedButtons = 0u; + const auto& dockHostState = + shellState.workspaceInteractionState.dockHostInteractionState; + if (dockHostState.splitterDragState.active || + !dockHostState.activeTabDragNodeId.empty()) { + expectedButtons |= ButtonMask(UIPointerButton::Left); + } + + for (const auto& panelState : + shellState.workspaceInteractionState.composeState.panelStates) { + const auto& inputBridgeState = panelState.viewportShellState.inputBridgeState; + if (inputBridgeState.captured) { + expectedButtons |= ButtonMask(inputBridgeState.captureButton); + } + } + + return expectedButtons; +} + +} // namespace + +EditorWindowFrameTransferRequests EditorWindow::RenderFrame( + EditorContext& editorContext, + bool globalTabDragActive) { + if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) { + return {}; + } + + UINT pixelWidth = 0u; + UINT pixelHeight = 0u; + if (!ResolveRenderClientPixelSize(pixelWidth, pixelHeight)) { + return {}; + } + + const float width = PixelsToDips(static_cast(pixelWidth)); + const float height = PixelsToDips(static_cast(pixelHeight)); + const UIRect workspaceBounds = ResolveWorkspaceBounds(width, height); + + UIDrawData drawData = {}; + UIDrawList& backgroundDrawList = drawData.EmplaceDrawList("XCEditorWindow.Surface"); + backgroundDrawList.AddFilledRect( + UIRect(0.0f, 0.0f, width, height), + kShellSurfaceColor); + + EditorWindowFrameTransferRequests transferRequests = {}; + if (editorContext.IsValid()) { + transferRequests = + RenderRuntimeFrame(editorContext, globalTabDragActive, workspaceBounds, drawData); + } else { + UIDrawList& invalidDrawList = drawData.EmplaceDrawList("XCEditorWindow.Invalid"); + m_frameOrchestrator->AppendInvalidFrame(editorContext, invalidDrawList); + } + + UIDrawList& windowChromeDrawList = drawData.EmplaceDrawList("XCEditorWindow.Chrome"); + m_chromeController->AppendChrome(*this, windowChromeDrawList, width); + + const Host::D3D12WindowRenderLoopPresentResult presentResult = m_runtime->Present(drawData); + if (!presentResult.warning.empty()) { + LogRuntimeTrace("present", presentResult.warning); + } + return transferRequests; +} + +EditorWindowFrameTransferRequests EditorWindow::OnPaintMessage( + EditorContext& editorContext, + bool globalTabDragActive) { + if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) { + return {}; + } + + PAINTSTRUCT paintStruct = {}; + BeginPaint(m_session->GetHwnd(), &paintStruct); + const EditorWindowFrameTransferRequests transferRequests = + EditorWindowFrameDriver::DriveImmediateFrame( + *this, + editorContext, + globalTabDragActive); + EndPaint(m_session->GetHwnd(), &paintStruct); + return transferRequests; +} + +void EditorWindow::QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests) { + m_session->QueueCompletedImmediateFrame(std::move(transferRequests)); +} + +bool EditorWindow::HasQueuedCompletedImmediateFrame() const { + return m_session->HasQueuedCompletedImmediateFrame(); +} + +EditorWindowFrameTransferRequests +EditorWindow::ConsumeQueuedCompletedImmediateFrameTransferRequests() { + return m_session->ConsumeQueuedCompletedImmediateFrameTransferRequests(); +} + +void EditorWindow::RequestSkipNextSteadyStateFrame() { + m_chromeController->RequestSkipNextSteadyStateFrame(); +} + +bool EditorWindow::ConsumeSkipNextSteadyStateFrame() { + return m_chromeController->ConsumeSkipNextSteadyStateFrame(); +} + +UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const { + if (m_chromeController->ShouldUseDetachedTitleBarTabStrip(*this)) { + return UIRect(0.0f, 0.0f, clientWidthDips, clientHeightDips); + } + + const float titleBarHeight = (std::min)(kBorderlessTitleBarHeightDips, clientHeightDips); + return UIRect( + 0.0f, + titleBarHeight, + clientWidthDips, + (std::max)(0.0f, clientHeightDips - titleBarHeight)); +} + +EditorWindowFrameTransferRequests EditorWindow::RenderRuntimeFrame( + EditorContext& editorContext, + bool globalTabDragActive, + const UIRect& workspaceBounds, + UIDrawData& drawData) { + SyncShellCapturedPointerButtonsFromSystemState(); + std::vector frameEvents = m_inputController->TakePendingEvents(); + const bool useDetachedTitleBarTabStrip = + m_chromeController->ShouldUseDetachedTitleBarTabStrip(*this); + editorContext.AttachTextMeasurer(m_runtime->GetTextMeasurer()); + const Host::D3D12WindowRenderLoopFrameContext frameContext = m_runtime->BeginFrame(); + if (!frameContext.warning.empty()) { + LogRuntimeTrace("viewport", frameContext.warning); + } + + const EditorWindowFrameTransferRequests transferRequests = + m_runtime->UpdateAndAppend( + EditorWindowContentFrameContext{ + .editorContext = editorContext, + .bounds = workspaceBounds, + .inputEvents = frameEvents, + .captureStatusText = m_runtime->BuildCaptureStatusText(), + .primary = m_session->IsPrimary(), + .globalTabDragActive = globalTabDragActive, + .useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip, + }, + drawData); + if (frameContext.canRenderViewports) { + m_runtime->RenderRequestedViewports(frameContext.renderContext); + } + + ApplyShellRuntimePointerCapture(); + ApplyCurrentCursor(); + return transferRequests; +} + +void EditorWindow::SyncShellCapturedPointerButtonsFromSystemState() { + m_inputController->SyncInputModifiersFromSystemState(); + + const std::uint8_t expectedButtons = ResolveExpectedShellCaptureButtons( + m_runtime->GetShellInteractionState()); + if (expectedButtons == 0u || + m_inputController->HasPendingPointerStateReconciliationEvent()) { + return; + } + + const UIInputModifiers modifiers = m_inputController->GetCurrentModifiers(); + if ((ButtonMaskFromModifiers(modifiers) & expectedButtons) == expectedButtons) { + return; + } + + QueueSyntheticPointerStateSyncEvent(modifiers); +} + +void EditorWindow::ApplyShellRuntimePointerCapture() { + const EditorWindowInputFeedbackBinding* inputFeedbackBinding = + m_runtime->TryGetInputFeedbackBinding(); + if (inputFeedbackBinding != nullptr && + inputFeedbackBinding->HasShellInteractiveCapture()) { + AcquirePointerCapture(EditorWindowPointerCaptureOwner::Shell); + return; + } + + if (inputFeedbackBinding != nullptr && + inputFeedbackBinding->HasHostedContentCapture()) { + AcquirePointerCapture(EditorWindowPointerCaptureOwner::HostedContent); + return; + } + + if (OwnsPointerCapture(EditorWindowPointerCaptureOwner::Shell)) { + ReleasePointerCapture(EditorWindowPointerCaptureOwner::Shell); + } + + if (OwnsPointerCapture(EditorWindowPointerCaptureOwner::HostedContent)) { + ReleasePointerCapture(EditorWindowPointerCaptureOwner::HostedContent); + } +} + +} // namespace XCEngine::UI::Editor::App + +namespace XCEngine::UI::Editor::App { + +using ::XCEngine::UI::UIInputEventType; +using ::XCEngine::UI::UIPointerButton; + +namespace { + +bool IsScreenPointOverWindow(HWND hwnd, const POINT& screenPoint) { + if (hwnd == nullptr || !IsWindow(hwnd)) { + return false; + } + + const HWND hitWindow = WindowFromPoint(screenPoint); + if (hitWindow == nullptr || GetAncestor(hitWindow, GA_ROOT) != hwnd) { + return false; + } + + RECT windowRect = {}; + if (!GetWindowRect(hwnd, &windowRect)) { + return false; + } + + return screenPoint.x >= windowRect.left && screenPoint.x < windowRect.right && + screenPoint.y >= windowRect.top && screenPoint.y < windowRect.bottom; +} +} // namespace + +bool EditorWindow::ApplyCurrentCursor() const { + if (!HasInteractiveCaptureState() && !IsPointerInsideClientArea()) { + return false; + } + + const HCURSOR cursor = LoadCursorW(nullptr, ResolveCurrentCursorResource()); + if (cursor == nullptr) { + return false; + } + + SetCursor(cursor); + return true; +} + + +bool EditorWindow::HasInteractiveCaptureState() const { + const EditorWindowInputFeedbackBinding* inputFeedbackBinding = + m_runtime->TryGetInputFeedbackBinding(); + return (inputFeedbackBinding != nullptr && inputFeedbackBinding->HasInteractiveCapture()) || + m_chromeController->IsBorderlessWindowDragRestoreArmed() || + m_chromeController->IsBorderlessResizeActive() || + m_inputController->HasPointerCaptureOwner(); +} + +bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const { + return m_inputController->OwnsPointerCapture(owner); +} + +void EditorWindow::AcquirePointerCapture(EditorWindowPointerCaptureOwner owner) { + m_inputController->AcquirePointerCapture(m_session->GetHwnd(), owner); +} + +void EditorWindow::ReleasePointerCapture(EditorWindowPointerCaptureOwner owner) { + m_inputController->ReleasePointerCapture(m_session->GetHwnd(), owner); +} + +void EditorWindow::ForceReleasePointerCapture() { + m_inputController->ForceReleasePointerCapture(m_session->GetHwnd()); +} + +void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || + !IsWindow(hwnd) || + GetCapture() == hwnd) { + return; + } + + const ::XCEngine::UI::UIPoint clientPoint = ConvertClientPixelsToDips( + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam)); + if (!ShouldStartImmediateUIEditorShellPointerCapture( + m_runtime->GetShellFrame(), + clientPoint)) { + return; + } + + AcquirePointerCapture(EditorWindowPointerCaptureOwner::Shell); +} + +void EditorWindow::QueuePointerEvent( + UIInputEventType type, + UIPointerButton button, + WPARAM wParam, + LPARAM lParam, + bool doubleClick) { + m_inputController->QueuePointerEvent( + type, + button, + ConvertClientPixelsToDips(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)), + wParam, + doubleClick); +} + +void EditorWindow::QueueSyntheticPointerStateSyncEvent( + const ::XCEngine::UI::UIInputModifiers& modifiers) { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { + return; + } + + POINT screenPoint = {}; + if (!GetCursorPos(&screenPoint)) { + return; + } + if (!ScreenToClient(hwnd, &screenPoint)) { + return; + } + + m_inputController->QueueSyntheticPointerStateSyncEvent( + ConvertClientPixelsToDips(screenPoint.x, screenPoint.y), + modifiers); +} + +void EditorWindow::QueuePointerLeaveEvent() { + ::XCEngine::UI::UIPoint position = {}; + if (const HWND hwnd = m_session->GetHwnd(); + hwnd != nullptr) { + POINT clientPoint = {}; + GetCursorPos(&clientPoint); + ScreenToClient(hwnd, &clientPoint); + position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y); + } + m_inputController->QueuePointerLeaveEvent(position); +} + +void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) { + if (m_session->GetHwnd() == nullptr) { + return; + } + + POINT screenPoint = { + GET_X_LPARAM(lParam), + GET_Y_LPARAM(lParam) + }; + ScreenToClient(m_session->GetHwnd(), &screenPoint); + + m_inputController->QueuePointerWheelEvent( + ConvertClientPixelsToDips(screenPoint.x, screenPoint.y), + wheelDelta, + wParam); +} + +bool EditorWindow::IsPointerInsideClientArea() const { + const HWND hwnd = m_session->GetHwnd(); + if (hwnd == nullptr || !IsWindow(hwnd)) { + return false; + } + + POINT screenPoint = {}; + if (!GetCursorPos(&screenPoint)) { + return false; + } + + if (!IsScreenPointOverWindow(hwnd, screenPoint)) { + return false; + } + + const LPARAM pointParam = MAKELPARAM( + static_cast(screenPoint.x), + static_cast(screenPoint.y)); + return SendMessageW(hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT; +} + +LPCWSTR EditorWindow::ResolveCurrentCursorResource() const { + const EditorWindowInputFeedbackBinding* inputFeedbackBinding = + m_runtime->TryGetInputFeedbackBinding(); + const Host::BorderlessWindowResizeEdge borderlessResizeEdge = + m_chromeController->IsBorderlessResizeActive() + ? m_chromeController->GetBorderlessResizeEdge() + : m_chromeController->GetHoveredBorderlessResizeEdge(); + if (borderlessResizeEdge != Host::BorderlessWindowResizeEdge::None) { + return Host::ResolveBorderlessWindowResizeCursor(borderlessResizeEdge); + } + + const EditorWindowContentCursorKind hostedContentCursorKind = + inputFeedbackBinding != nullptr + ? inputFeedbackBinding->GetHostedContentCursorKind() + : EditorWindowContentCursorKind::Arrow; + switch (hostedContentCursorKind) { + case EditorWindowContentCursorKind::ResizeEW: + return IDC_SIZEWE; + case EditorWindowContentCursorKind::ResizeNS: + return IDC_SIZENS; + case EditorWindowContentCursorKind::Arrow: + default: + break; + } + + const EditorWindowContentCursorKind dockCursorKind = + inputFeedbackBinding != nullptr + ? inputFeedbackBinding->GetDockCursorKind() + : EditorWindowContentCursorKind::Arrow; + switch (dockCursorKind) { + case EditorWindowContentCursorKind::ResizeEW: + return IDC_SIZEWE; + case EditorWindowContentCursorKind::ResizeNS: + return IDC_SIZENS; + case EditorWindowContentCursorKind::Arrow: + default: + return IDC_ARROW; + } +} + +} // namespace XCEngine::UI::Editor::App + + diff --git a/editor/app/Platform/Win32/Windowing/EditorWindow.h b/editor/app/Platform/Win32/Windowing/EditorWindow.h new file mode 100644 index 00000000..84cbf521 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindow.h @@ -0,0 +1,192 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" +#include "Platform/Win32/Windowing/EditorWindowSession.h" + +#include + +#include +#include +#include +#include +#include +#include + +namespace XCEngine::UI { + +class UIDrawData; +class UIDrawList; + +struct UIPoint; +struct UIRect; +struct UIInputEvent; +struct UIInputModifiers; + +enum class UIPointerButton : std::uint8_t; +enum class UIInputEventType : std::uint8_t; + +} // namespace XCEngine::UI + +namespace XCEngine::UI::Editor { + +struct UIEditorDockHostTabDropTarget; +class UIEditorWorkspaceController; + +struct UIEditorDockHostInteractionState; +struct UIEditorShellInteractionFrame; +struct UIEditorShellInteractionState; +struct UIEditorShellInteractionResult; + +namespace Widgets { +struct UIEditorDockHostDropPreviewState; +} + +} // namespace XCEngine::UI::Editor + +namespace XCEngine::UI::Editor::App { + +class EditorContext; +class EditorWindowContentController; +class EditorWindowChromeController; +class EditorWindowFrameDriver; +class EditorWindowFrameOrchestrator; +class EditorWindowHostRuntime; +class EditorWindowInputController; +class EditorWindowLifecycleCoordinator; +class EditorWindowMessageDispatcher; +class EditorWindowRuntimeController; +class EditorWindowWorkspaceCoordinator; +class EditorWindowSession; + +class EditorWindow { +public: + EditorWindow( + std::string windowId, + std::wstring title, + bool primary, + std::unique_ptr contentController); + ~EditorWindow(); + + EditorWindow(const EditorWindow&) = delete; + EditorWindow& operator=(const EditorWindow&) = delete; + EditorWindow(EditorWindow&&) = delete; + EditorWindow& operator=(EditorWindow&&) = delete; + + std::string_view GetWindowId() const; + HWND GetHwnd() const; + bool HasHwnd() const; + EditorWindowLifecycleState GetLifecycleState() const; + bool IsPrimary() const; + bool IsClosing() const; + bool IsDestroyed() const; + const std::wstring& GetTitle() const; + std::string_view GetCachedTitleText() const; + const UIEditorWorkspaceController* TryGetWorkspaceController() const; + const UIEditorWorkspaceController& GetWorkspaceController() const; + ::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const; + +private: + friend class EditorWindowChromeController; + friend class EditorWindowFrameDriver; + friend class EditorWindowHostRuntime; + friend class EditorWindowMessageDispatcher; + friend class EditorWindowLifecycleCoordinator; + friend class EditorWindowWorkspaceCoordinator; + + bool IsRenderReady() const; + bool TryResolveDockTabDragHotspot( + std::string_view nodeId, + std::string_view panelId, + const POINT& screenPoint, + POINT& outHotspot) const; + bool TryResolveDockTabDropTarget( + const POINT& screenPoint, + UIEditorDockHostTabDropTarget& outTarget) const; + void InvalidateHostWindow() const; + + void AttachHwnd(HWND hwnd); + void MarkInitializing(); + void MarkRunning(); + void MarkDestroyed(); + void MarkClosing(); + void SetPrimary(bool primary); + void SetTitle(std::wstring title); + void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController); + + bool Initialize( + const std::filesystem::path& repoRoot, + EditorContext& editorContext, + const std::filesystem::path& captureRoot, + bool autoCaptureOnStartup); + void Shutdown(); + void ResetInteractionState(); + + EditorWindowFrameTransferRequests RenderFrame( + EditorContext& editorContext, + bool globalTabDragActive); + EditorWindowFrameTransferRequests OnPaintMessage( + EditorContext& editorContext, + bool globalTabDragActive); + void QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests); + bool HasQueuedCompletedImmediateFrame() const; + EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests(); + void RequestSkipNextSteadyStateFrame(); + bool ConsumeSkipNextSteadyStateFrame(); + bool OnResize(UINT width, UINT height); + void OnEnterSizeMove(); + bool OnExitSizeMove(); + void OnDpiChanged(UINT dpi, const RECT& suggestedRect); + + bool ApplyCurrentCursor() const; + bool HasInteractiveCaptureState() const; + bool OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const; + void AcquirePointerCapture(EditorWindowPointerCaptureOwner owner); + void ReleasePointerCapture(EditorWindowPointerCaptureOwner owner); + void ForceReleasePointerCapture(); + void TryStartImmediateShellPointerCapture(LPARAM lParam); + + void QueuePointerEvent( + ::XCEngine::UI::UIInputEventType type, + ::XCEngine::UI::UIPointerButton button, + WPARAM wParam, + LPARAM lParam, + bool doubleClick = false); + void QueueSyntheticPointerStateSyncEvent( + const ::XCEngine::UI::UIInputModifiers& modifiers); + void QueuePointerLeaveEvent(); + void QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam); + void SyncShellCapturedPointerButtonsFromSystemState(); + + bool ApplyWindowResize(UINT width, UINT height); + bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const; + bool ResolveRenderClientPixelSize(UINT& outWidth, UINT& outHeight) const; + ::XCEngine::UI::UIRect ResolveWorkspaceBounds( + float clientWidthDips, + float clientHeightDips) const; + EditorWindowFrameTransferRequests RenderRuntimeFrame( + EditorContext& editorContext, + bool globalTabDragActive, + const ::XCEngine::UI::UIRect& workspaceBounds, + ::XCEngine::UI::UIDrawData& drawData); + bool IsPointerInsideClientArea() const; + LPCWSTR ResolveCurrentCursorResource() const; + float GetDpiScale() const; + float PixelsToDips(float pixels) const; + ::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const; + void ApplyShellRuntimePointerCapture(); + static bool IsVerboseRuntimeTraceEnabled(); + + std::unique_ptr m_session = {}; + std::unique_ptr m_chromeController = {}; + std::unique_ptr m_frameOrchestrator = {}; + std::unique_ptr m_inputController = {}; + std::unique_ptr m_runtime = {}; +}; + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp new file mode 100644 index 00000000..f2e3b382 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.cpp @@ -0,0 +1,286 @@ +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" + +#include "Bootstrap/EditorResources.h" +#include "Composition/EditorContext.h" +#include "Platform/Win32/Chrome/EditorWindowChromeController.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" +#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" +#include "Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h" +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" +#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h" + +#include + +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +std::string DescribeHwnd(HWND hwnd) { + std::ostringstream stream = {}; + stream << "0x" << std::hex << std::uppercase + << reinterpret_cast(hwnd); + return stream.str(); +} + +std::string DescribeHostWindows( + const std::vector>& windows) { + std::ostringstream stream = {}; + stream << "count=" << windows.size() << " ["; + bool first = true; + for (const std::unique_ptr& window : windows) { + if (!first) { + stream << ", "; + } + first = false; + if (window == nullptr) { + stream << ""; + continue; + } + + stream << window->GetWindowId() + << "{hwnd=" << DescribeHwnd(window->GetHwnd()) + << ",primary=" << (window->IsPrimary() ? '1' : '0') + << ",state=" << GetEditorWindowLifecycleStateName(window->GetLifecycleState()) + << '}'; + } + stream << ']'; + return stream.str(); +} + +} // namespace + +EditorWindowHostRuntime::EditorWindowHostRuntime( + EditorWindowHostConfig hostConfig, + std::filesystem::path repoRoot, + EditorContext& editorContext) + : m_hostConfig(hostConfig), + m_repoRoot(std::move(repoRoot)), + m_editorContext(editorContext) {} + +EditorWindowHostRuntime::~EditorWindowHostRuntime() = default; + +EditorWindow* EditorWindowHostRuntime::CreateEditorWindow( + std::unique_ptr contentController, + const CreateParams& params) { + auto windowPtr = std::make_unique( + params.windowId, + params.title.empty() ? std::wstring(L"XCEngine Editor") : params.title, + params.primary, + std::move(contentController)); + EditorWindow* const rawWindow = windowPtr.get(); + m_windows.push_back(std::move(windowPtr)); + + const auto eraseRawWindow = [this, rawWindow]() { + const auto it = std::find_if( + m_windows.begin(), + m_windows.end(), + [rawWindow](const std::unique_ptr& candidate) { + return candidate.get() == rawWindow; + }); + if (it != m_windows.end()) { + m_windows.erase(it); + } + }; + + m_pendingCreateWindow = rawWindow; + const HWND hwnd = CreateWindowExW( + WS_EX_APPWINDOW, + m_hostConfig.windowClassName, + rawWindow->GetTitle().c_str(), + m_hostConfig.windowStyle, + params.initialX, + params.initialY, + params.initialWidth, + params.initialHeight, + nullptr, + nullptr, + m_hostConfig.hInstance, + m_hostConfig.windowUserData); + m_pendingCreateWindow = nullptr; + if (hwnd == nullptr) { + eraseRawWindow(); + return nullptr; + } + + if (!rawWindow->HasHwnd()) { + rawWindow->AttachHwnd(hwnd); + } + + auto failWindowInitialization = [&](std::string_view message) { + LogRuntimeTrace("window", std::string(message)); + m_lifecycleCoordinator->AbortUnregisteredWindow(*rawWindow); + return static_cast(nullptr); + }; + + const HICON bigIcon = static_cast( + LoadImageW( + m_hostConfig.hInstance, + MAKEINTRESOURCEW(IDI_APP_ICON), + IMAGE_ICON, + 0, + 0, + LR_DEFAULTSIZE)); + const HICON smallIcon = static_cast( + LoadImageW( + m_hostConfig.hInstance, + MAKEINTRESOURCEW(IDI_APP_ICON_SMALL), + IMAGE_ICON, + GetSystemMetrics(SM_CXSMICON), + GetSystemMetrics(SM_CYSMICON), + LR_DEFAULTCOLOR)); + if (bigIcon != nullptr) { + SendMessageW(hwnd, WM_SETICON, ICON_BIG, reinterpret_cast(bigIcon)); + } + if (smallIcon != nullptr) { + SendMessageW(hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); + } + + if (!rawWindow->Initialize( + m_repoRoot, + m_editorContext, + m_editorContext.GetShellAsset().captureRootPath, + params.autoCaptureOnStartup)) { + return failWindowInitialization("managed window initialization failed"); + } + + ShowWindow(hwnd, params.showCommand); + UpdateWindow(hwnd); + return rawWindow; +} + +void EditorWindowHostRuntime::BindLifecycleCoordinator( + EditorWindowLifecycleCoordinator& lifecycleCoordinator) { + m_lifecycleCoordinator = &lifecycleCoordinator; +} + +void EditorWindowHostRuntime::HandlePendingNativeWindowCreated(HWND hwnd) { + if (m_pendingCreateWindow != nullptr && + m_pendingCreateWindow->GetLifecycleState() == + EditorWindowLifecycleState::PendingNativeCreate && + !m_pendingCreateWindow->HasHwnd()) { + m_pendingCreateWindow->AttachHwnd(hwnd); + } +} + +bool EditorWindowHostRuntime::HasWindows() const { + return !m_windows.empty(); +} + +void EditorWindowHostRuntime::RenderAllWindows( + bool globalTabDragActive, + EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorUtilityWindowCoordinator& utilityCoordinator) { + struct WindowFrameTransferBatch { + EditorWindow* sourceWindow = nullptr; + EditorWindowFrameTransferRequests requests = {}; + }; + + std::vector transferBatches = {}; + transferBatches.reserve(m_windows.size()); + + for (const std::unique_ptr& window : m_windows) { + if (window == nullptr || + window->GetHwnd() == nullptr || + window->GetLifecycleState() != EditorWindowLifecycleState::Running) { + continue; + } + + if (window->ConsumeSkipNextSteadyStateFrame()) { + workspaceCoordinator.RefreshWindowPresentation(*window); + continue; + } + + EditorWindowFrameTransferRequests transferRequests = + EditorWindowFrameDriver::DriveFrame( + *window, + m_editorContext, + globalTabDragActive); + workspaceCoordinator.RefreshWindowPresentation(*window); + if (!transferRequests.HasPendingRequests()) { + continue; + } + + transferBatches.push_back(WindowFrameTransferBatch{ + window.get(), + std::move(transferRequests), + }); + } + + for (WindowFrameTransferBatch& batch : transferBatches) { + if (batch.sourceWindow == nullptr || + batch.sourceWindow->GetHwnd() == nullptr || + batch.sourceWindow->GetLifecycleState() != EditorWindowLifecycleState::Running) { + continue; + } + + workspaceCoordinator.HandleWindowFrameTransferRequests( + *batch.sourceWindow, + batch.requests); + utilityCoordinator.HandleWindowFrameTransferRequests( + *batch.sourceWindow, + batch.requests); + } +} + +EditorWindow* EditorWindowHostRuntime::FindWindow(HWND hwnd) { + if (hwnd == nullptr) { + return nullptr; + } + + for (const std::unique_ptr& window : m_windows) { + if (window != nullptr && window->GetHwnd() == hwnd) { + return window.get(); + } + } + + return nullptr; +} + +const EditorWindow* EditorWindowHostRuntime::FindWindow(HWND hwnd) const { + return const_cast(this)->FindWindow(hwnd); +} + +EditorWindow* EditorWindowHostRuntime::FindWindow(std::string_view windowId) { + if (windowId.empty()) { + return nullptr; + } + + for (const std::unique_ptr& window : m_windows) { + if (window != nullptr && window->GetWindowId() == windowId) { + return window.get(); + } + } + + return nullptr; +} + +const EditorWindow* EditorWindowHostRuntime::FindWindow(std::string_view windowId) const { + return const_cast(this)->FindWindow(windowId); +} + +EditorWindow* EditorWindowHostRuntime::FindPrimaryWindow() { + for (const std::unique_ptr& window : m_windows) { + if (window != nullptr && window->IsPrimary()) { + return window.get(); + } + } + + return nullptr; +} + +const EditorWindow* EditorWindowHostRuntime::FindPrimaryWindow() const { + return const_cast(this)->FindPrimaryWindow(); +} + +void EditorWindowHostRuntime::LogRuntimeTrace( + std::string_view channel, + std::string_view message) const { + AppendUIEditorRuntimeTrace(channel, message); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h new file mode 100644 index 00000000..a7ded4f2 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowHostRuntime.h @@ -0,0 +1,87 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowManager.h" + +#include + +#include +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorContext; +class EditorWindow; +class EditorWindowContentController; +class EditorWindowLifecycleCoordinator; +class EditorUtilityWindowCoordinator; +class EditorWindowWorkspaceCoordinator; + +class EditorWindowHostRuntime final { +public: + using CreateParams = EditorWindowManager::CreateParams; + + EditorWindowHostRuntime( + EditorWindowHostConfig hostConfig, + std::filesystem::path repoRoot, + EditorContext& editorContext); + ~EditorWindowHostRuntime(); + + EditorWindow* CreateEditorWindow( + std::unique_ptr contentController, + const CreateParams& params); + void BindLifecycleCoordinator(EditorWindowLifecycleCoordinator& lifecycleCoordinator); + void HandlePendingNativeWindowCreated(HWND hwnd); + + EditorWindow* FindWindow(HWND hwnd); + const EditorWindow* FindWindow(HWND hwnd) const; + EditorWindow* FindWindow(std::string_view windowId); + const EditorWindow* FindWindow(std::string_view windowId) const; + EditorWindow* FindPrimaryWindow(); + const EditorWindow* FindPrimaryWindow() const; + + bool HasWindows() const; + void RenderAllWindows( + bool globalTabDragActive, + EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorUtilityWindowCoordinator& utilityCoordinator); + + EditorContext& GetEditorContext() { + return m_editorContext; + } + + const EditorContext& GetEditorContext() const { + return m_editorContext; + } + + const EditorWindowHostConfig& GetHostConfig() const { + return m_hostConfig; + } + + const std::filesystem::path& GetRepoRoot() const { + return m_repoRoot; + } + + std::vector>& GetWindows() { + return m_windows; + } + + const std::vector>& GetWindows() const { + return m_windows; + } + + void LogRuntimeTrace(std::string_view channel, std::string_view message) const; + +private: + friend class EditorWindowLifecycleCoordinator; + + EditorWindowHostConfig m_hostConfig = {}; + std::filesystem::path m_repoRoot = {}; + EditorContext& m_editorContext; + std::vector> m_windows = {}; + EditorWindow* m_pendingCreateWindow = nullptr; + EditorWindowLifecycleCoordinator* m_lifecycleCoordinator = nullptr; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.cpp new file mode 100644 index 00000000..55fa32f5 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.cpp @@ -0,0 +1,248 @@ +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" + +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h" + +#include +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +std::string DescribeHwnd(HWND hwnd) { + std::ostringstream stream = {}; + stream << "0x" << std::hex << std::uppercase + << reinterpret_cast(hwnd); + return stream.str(); +} + +std::string DescribeHostWindows( + const std::vector>& windows) { + std::ostringstream stream = {}; + stream << "count=" << windows.size() << " ["; + bool first = true; + for (const std::unique_ptr& window : windows) { + if (!first) { + stream << ", "; + } + first = false; + if (window == nullptr) { + stream << ""; + continue; + } + + stream << window->GetWindowId() + << "{hwnd=" << DescribeHwnd(window->GetHwnd()) + << ",primary=" << (window->IsPrimary() ? '1' : '0') + << ",state=" << GetEditorWindowLifecycleStateName(window->GetLifecycleState()) + << '}'; + } + stream << ']'; + return stream.str(); +} + +} // namespace + +EditorWindowLifecycleCoordinator::EditorWindowLifecycleCoordinator( + EditorWindowHostRuntime& hostRuntime, + EditorWindowWorkspaceCoordinator& workspaceCoordinator) + : m_hostRuntime(hostRuntime), + m_workspaceCoordinator(workspaceCoordinator) {} + +EditorWindowLifecycleCoordinator::~EditorWindowLifecycleCoordinator() = default; + +void EditorWindowLifecycleCoordinator::PostCloseRequest(EditorWindow& window) { + if (window.IsDestroyed()) { + return; + } + + const HWND hwnd = window.GetHwnd(); + if (!window.IsClosing()) { + window.MarkClosing(); + } + + if (hwnd == nullptr || !IsWindow(hwnd)) { + ShutdownRuntimeIfNeeded(window); + window.MarkDestroyed(); + return; + } + + LogRuntimeTrace( + "window-close", + "PostCloseRequest windowId='" + std::string(window.GetWindowId()) + + "' hwnd=" + DescribeHwnd(hwnd) + + " primary=" + (window.IsPrimary() ? "1" : "0") + + " host=" + DescribeHostWindows(m_hostRuntime.GetWindows())); + PostMessageW(hwnd, WM_CLOSE, 0, 0); +} + +void EditorWindowLifecycleCoordinator::ExecuteCloseRequest(EditorWindow& window) { + if (window.IsDestroyed()) { + return; + } + + const HWND hwnd = window.GetHwnd(); + LogRuntimeTrace( + "window-close", + "ExecuteCloseRequest begin windowId='" + std::string(window.GetWindowId()) + + "' hwnd=" + DescribeHwnd(hwnd) + + " primary=" + (window.IsPrimary() ? "1" : "0") + + " lifecycleBefore=" + + std::string(GetEditorWindowLifecycleStateName(window.GetLifecycleState())) + + " workspace=" + m_workspaceCoordinator.DescribeWindowSet() + + " host=" + DescribeHostWindows(m_hostRuntime.GetWindows())); + + if (!window.IsClosing()) { + window.MarkClosing(); + } + + ShutdownRuntimeIfNeeded(window); + + if (hwnd != nullptr && IsWindow(hwnd)) { + DestroyWindow(hwnd); + } else { + window.MarkDestroyed(); + } + + LogRuntimeTrace( + "window-close", + "ExecuteCloseRequest end windowId='" + std::string(window.GetWindowId()) + + "' host=" + DescribeHostWindows(m_hostRuntime.GetWindows())); +} + +void EditorWindowLifecycleCoordinator::HandleNativeWindowDestroyed(EditorWindow& window) { + if (window.IsDestroyed()) { + return; + } + + const bool destroyedPrimary = + m_workspaceCoordinator.IsPrimaryWindowId(window.GetWindowId()); + LogRuntimeTrace( + "window-close", + "HandleNativeWindowDestroyed begin windowId='" + std::string(window.GetWindowId()) + + "' hwnd=" + DescribeHwnd(window.GetHwnd()) + + " destroyedPrimary=" + (destroyedPrimary ? "1" : "0") + + " localPrimary=" + (window.IsPrimary() ? "1" : "0") + + " workspaceBefore=" + m_workspaceCoordinator.DescribeWindowSet() + + " hostBefore=" + DescribeHostWindows(m_hostRuntime.GetWindows())); + + if (m_workspaceCoordinator.OwnsActiveGlobalTabDrag(window.GetWindowId())) { + m_workspaceCoordinator.EndGlobalTabDragSession(); + } + + ShutdownRuntimeIfNeeded(window); + m_workspaceCoordinator.RemoveWindowProjection(window.GetWindowId(), destroyedPrimary); + window.MarkDestroyed(); + + if (destroyedPrimary) { + std::vector closeTargets = {}; + closeTargets.reserve(m_hostRuntime.GetWindows().size()); + for (const std::unique_ptr& otherWindow : m_hostRuntime.GetWindows()) { + if (otherWindow == nullptr || + otherWindow.get() == &window || + otherWindow->GetHwnd() == nullptr || + otherWindow->IsClosing()) { + continue; + } + closeTargets.push_back(otherWindow.get()); + } + + for (EditorWindow* closeTarget : closeTargets) { + if (closeTarget != nullptr) { + PostCloseRequest(*closeTarget); + } + } + } + + LogRuntimeTrace( + "window-close", + "HandleNativeWindowDestroyed end windowId='" + std::string(window.GetWindowId()) + + "' workspaceAfter=" + m_workspaceCoordinator.DescribeWindowSet() + + " hostAfter=" + DescribeHostWindows(m_hostRuntime.GetWindows())); +} + +void EditorWindowLifecycleCoordinator::AbortUnregisteredWindow(EditorWindow& window) { + const HWND hwnd = window.GetHwnd(); + LogRuntimeTrace( + "window-close", + "AbortUnregisteredWindow begin windowId='" + std::string(window.GetWindowId()) + + "' hwnd=" + DescribeHwnd(hwnd) + + " hostBefore=" + DescribeHostWindows(m_hostRuntime.GetWindows())); + + if (!window.IsClosing()) { + window.MarkClosing(); + } + + ShutdownRuntimeIfNeeded(window); + if (hwnd != nullptr && IsWindow(hwnd)) { + DestroyWindow(hwnd); + } else { + window.MarkDestroyed(); + } + ReapDestroyedWindows(); + + LogRuntimeTrace( + "window-close", + "AbortUnregisteredWindow end windowId='" + std::string(window.GetWindowId()) + + "' hostAfter=" + DescribeHostWindows(m_hostRuntime.GetWindows())); +} + +void EditorWindowLifecycleCoordinator::ShutdownAllWindows() { + std::vector closeTargets = {}; + closeTargets.reserve(m_hostRuntime.GetWindows().size()); + for (const std::unique_ptr& window : m_hostRuntime.GetWindows()) { + if (window != nullptr) { + closeTargets.push_back(window.get()); + } + } + + for (EditorWindow* closeTarget : closeTargets) { + if (closeTarget != nullptr) { + ExecuteCloseRequest(*closeTarget); + } + } + + ReapDestroyedWindows(); +} + +void EditorWindowLifecycleCoordinator::ReapDestroyedWindows() { + auto& windows = m_hostRuntime.GetWindows(); + for (auto it = windows.begin(); it != windows.end();) { + EditorWindow* const window = it->get(); + if (window == nullptr || !window->IsDestroyed()) { + ++it; + continue; + } + + if (m_hostRuntime.m_pendingCreateWindow == window) { + m_hostRuntime.m_pendingCreateWindow = nullptr; + } + + LogRuntimeTrace( + "window-close", + "ReapDestroyedWindows erase windowId='" + std::string(window->GetWindowId()) + + "' hostBefore=" + DescribeHostWindows(windows)); + it = windows.erase(it); + LogRuntimeTrace( + "window-close", + "ReapDestroyedWindows erase end hostAfter=" + DescribeHostWindows(windows)); + } +} + +void EditorWindowLifecycleCoordinator::ShutdownRuntimeIfNeeded(EditorWindow& window) { + if (window.IsRenderReady()) { + window.Shutdown(); + } +} + +void EditorWindowLifecycleCoordinator::LogRuntimeTrace( + std::string_view channel, + std::string_view message) const { + m_hostRuntime.LogRuntimeTrace(channel, message); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h b/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h new file mode 100644 index 00000000..64c7c5ba --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h @@ -0,0 +1,33 @@ +#pragma once + +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWindow; +class EditorWindowHostRuntime; +class EditorWindowWorkspaceCoordinator; + +class EditorWindowLifecycleCoordinator final { +public: + EditorWindowLifecycleCoordinator( + EditorWindowHostRuntime& hostRuntime, + EditorWindowWorkspaceCoordinator& workspaceCoordinator); + ~EditorWindowLifecycleCoordinator(); + + void PostCloseRequest(EditorWindow& window); + void ExecuteCloseRequest(EditorWindow& window); + void HandleNativeWindowDestroyed(EditorWindow& window); + void AbortUnregisteredWindow(EditorWindow& window); + void ShutdownAllWindows(); + void ReapDestroyedWindows(); + +private: + void ShutdownRuntimeIfNeeded(EditorWindow& window); + void LogRuntimeTrace(std::string_view channel, std::string_view message) const; + + EditorWindowHostRuntime& m_hostRuntime; + EditorWindowWorkspaceCoordinator& m_workspaceCoordinator; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowManager.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowManager.cpp new file mode 100644 index 00000000..83add784 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowManager.cpp @@ -0,0 +1,124 @@ +#include "Platform/Win32/Windowing/EditorWindowManager.h" + +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Content/EditorWindowContentController.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" +#include "Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h" +#include "Platform/Win32/Windowing/EditorWindowMessageDispatcher.h" +#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h" + +#include + +namespace XCEngine::UI::Editor::App { + +EditorWindowManager::EditorWindowManager( + EditorWindowHostConfig hostConfig, + std::filesystem::path repoRoot, + EditorContext& editorContext) + : m_hostRuntime(std::make_unique( + hostConfig, + std::move(repoRoot), + editorContext)) { + m_workspaceCoordinator = + std::make_unique(*m_hostRuntime); + m_utilityCoordinator = + std::make_unique(*m_hostRuntime); + m_lifecycleCoordinator = std::make_unique( + *m_hostRuntime, + *m_workspaceCoordinator); + m_hostRuntime->BindLifecycleCoordinator(*m_lifecycleCoordinator); + m_workspaceCoordinator->BindLifecycleCoordinator(*m_lifecycleCoordinator); + m_utilityCoordinator->BindLifecycleCoordinator(*m_lifecycleCoordinator); +} + +EditorWindowManager::~EditorWindowManager() = default; + +EditorWindow* EditorWindowManager::CreateEditorWindow( + std::unique_ptr contentController, + const CreateParams& params) { + EditorWindow* const window = + m_hostRuntime->CreateEditorWindow(std::move(contentController), params); + if (window != nullptr) { + m_workspaceCoordinator->RegisterExistingWindow(*window); + } + return window; +} + +void EditorWindowManager::HandlePendingNativeWindowCreated(HWND hwnd) { + m_hostRuntime->HandlePendingNativeWindowCreated(hwnd); +} + +void EditorWindowManager::Shutdown() { + m_workspaceCoordinator->EndGlobalTabDragSession(); + m_lifecycleCoordinator->ShutdownAllWindows(); +} + +bool EditorWindowManager::TryDispatchWindowMessage( + HWND hwnd, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + if (m_hostRuntime == nullptr || m_workspaceCoordinator == nullptr) { + return false; + } + + EditorWindow* const window = m_hostRuntime->FindWindow(hwnd); + if (window == nullptr) { + return false; + } + + return EditorWindowMessageDispatcher::TryDispatch( + hwnd, + *m_hostRuntime, + *m_lifecycleCoordinator, + *m_utilityCoordinator, + *m_workspaceCoordinator, + *window, + message, + wParam, + lParam, + outResult); +} + +EditorWindow* EditorWindowManager::FindWindow(HWND hwnd) { + return m_hostRuntime->FindWindow(hwnd); +} + +const EditorWindow* EditorWindowManager::FindWindow(HWND hwnd) const { + return m_hostRuntime->FindWindow(hwnd); +} + +EditorWindow* EditorWindowManager::FindWindow(std::string_view windowId) { + return m_hostRuntime->FindWindow(windowId); +} + +const EditorWindow* EditorWindowManager::FindWindow(std::string_view windowId) const { + return m_hostRuntime->FindWindow(windowId); +} + +EditorWindow* EditorWindowManager::FindPrimaryWindow() { + return m_hostRuntime->FindPrimaryWindow(); +} + +const EditorWindow* EditorWindowManager::FindPrimaryWindow() const { + return m_hostRuntime->FindPrimaryWindow(); +} + +bool EditorWindowManager::HasWindows() const { + return m_hostRuntime->HasWindows(); +} + +void EditorWindowManager::DestroyClosedWindows() { + m_lifecycleCoordinator->ReapDestroyedWindows(); +} + +void EditorWindowManager::RenderAllWindows() { + m_hostRuntime->RenderAllWindows( + m_workspaceCoordinator->IsGlobalTabDragActive(), + *m_workspaceCoordinator, + *m_utilityCoordinator); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowManager.h b/editor/app/Platform/Win32/Windowing/EditorWindowManager.h new file mode 100644 index 00000000..eca85c52 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowManager.h @@ -0,0 +1,101 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include + +#include +#include +#include +#include +#include + +namespace XCEngine::UI::Editor { + +class UIEditorWindowWorkspaceController; +class UIEditorWorkspaceController; + +struct UIEditorWindowWorkspaceSet; +struct UIEditorWindowWorkspaceState; + +} // namespace XCEngine::UI::Editor + +namespace XCEngine::UI::Editor::App { + +class EditorContext; +class EditorWindow; +class EditorWindowContentController; +class EditorWindowHostRuntime; +class EditorWindowLifecycleCoordinator; +class EditorUtilityWindowCoordinator; +class EditorWindowWorkspaceCoordinator; +struct EditorWindowPanelTransferRequest; +struct EditorWindowFrameTransferRequests; + +struct EditorWindowHostConfig { + HINSTANCE hInstance = nullptr; + const wchar_t* windowClassName = L""; + DWORD windowStyle = 0; + const wchar_t* primaryWindowTitle = L""; + void* windowUserData = nullptr; +}; + +class EditorWindowManager final { +public: + struct CreateParams { + std::string windowId = {}; + std::wstring title = {}; + int initialX = CW_USEDEFAULT; + int initialY = CW_USEDEFAULT; + int initialWidth = 1540; + int initialHeight = 940; + int showCommand = SW_SHOW; + bool primary = false; + bool autoCaptureOnStartup = false; + }; + + EditorWindowManager( + EditorWindowHostConfig hostConfig, + std::filesystem::path repoRoot, + EditorContext& editorContext); + ~EditorWindowManager(); + + EditorWindowManager(const EditorWindowManager&) = delete; + EditorWindowManager& operator=(const EditorWindowManager&) = delete; + EditorWindowManager(EditorWindowManager&&) = delete; + EditorWindowManager& operator=(EditorWindowManager&&) = delete; + + EditorWindow* CreateEditorWindow( + std::unique_ptr contentController, + const CreateParams& params); + void HandlePendingNativeWindowCreated(HWND hwnd); + void Shutdown(); + bool TryDispatchWindowMessage( + HWND hwnd, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); + + EditorWindow* FindWindow(HWND hwnd); + const EditorWindow* FindWindow(HWND hwnd) const; + EditorWindow* FindWindow(std::string_view windowId); + const EditorWindow* FindWindow(std::string_view windowId) const; + EditorWindow* FindPrimaryWindow(); + const EditorWindow* FindPrimaryWindow() const; + + bool HasWindows() const; + void DestroyClosedWindows(); + void RenderAllWindows(); + +private: + std::unique_ptr m_hostRuntime = {}; + std::unique_ptr m_lifecycleCoordinator = {}; + std::unique_ptr m_utilityCoordinator = {}; + std::unique_ptr m_workspaceCoordinator = {}; +}; + +} // namespace XCEngine::UI::Editor::App + diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp new file mode 100644 index 00000000..2e40e78b --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp @@ -0,0 +1,585 @@ +#include "Platform/Win32/Windowing/EditorWindowMessageDispatcher.h" + +#include "Platform/Win32/Chrome/BorderlessWindowChrome.h" +#include "Platform/Win32/Chrome/EditorWindowChromeController.h" +#include "Platform/Win32/Runtime/EditorWindowInputController.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h" +#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" +#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" +#include "Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h" +#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h" + +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +constexpr UINT kMessageNcUaDrawCaption = 0x00AEu; +constexpr UINT kMessageNcUaDrawFrame = 0x00AFu; + +std::string DescribeHwnd(HWND hwnd) { + std::ostringstream stream = {}; + stream << "0x" << std::hex << std::uppercase + << reinterpret_cast(hwnd); + return stream.str(); +} + +std::string DescribeHostWindows(const EditorWindowHostRuntime& hostRuntime) { + std::ostringstream stream = {}; + const auto& windows = hostRuntime.GetWindows(); + stream << "count=" << windows.size() << " ["; + bool first = true; + for (const std::unique_ptr& window : windows) { + if (!first) { + stream << ", "; + } + first = false; + if (window == nullptr) { + stream << ""; + continue; + } + + stream << window->GetWindowId() + << "{hwnd=" << DescribeHwnd(window->GetHwnd()) + << ",primary=" << (window->IsPrimary() ? '1' : '0') + << ",state=" << GetEditorWindowLifecycleStateName(window->GetLifecycleState()) + << '}'; + } + stream << ']'; + return stream.str(); +} + +} // namespace + +struct EditorWindowMessageDispatcher::DispatchContext { + HWND hwnd = nullptr; + EditorWindowHostRuntime& hostRuntime; + EditorWindowLifecycleCoordinator& lifecycleCoordinator; + EditorUtilityWindowCoordinator& utilityCoordinator; + EditorWindowWorkspaceCoordinator& workspaceCoordinator; + EditorWindow& window; +}; + +void EditorWindowMessageDispatcher::DispatchWindowFrameTransferRequests( + const DispatchContext& context, + const EditorWindowFrameTransferRequests& transferRequests) { + context.workspaceCoordinator.HandleWindowFrameTransferRequests( + context.window, + transferRequests); + context.utilityCoordinator.HandleWindowFrameTransferRequests( + context.window, + transferRequests); +} + +void EditorWindowMessageDispatcher::FinalizeImmediateFrame( + const DispatchContext& context, + const EditorWindowFrameTransferRequests& transferRequests) { + context.workspaceCoordinator.RefreshWindowPresentation(context.window); + if (!transferRequests.HasPendingRequests()) { + return; + } + + DispatchWindowFrameTransferRequests(context, transferRequests); +} + +void EditorWindowMessageDispatcher::FlushQueuedCompletedImmediateFrame( + const DispatchContext& context) { + if (!context.window.HasQueuedCompletedImmediateFrame()) { + return; + } + + FinalizeImmediateFrame( + context, + context.window.ConsumeQueuedCompletedImmediateFrameTransferRequests()); +} + +void EditorWindowMessageDispatcher::RenderAndHandleWindowFrame(const DispatchContext& context) { + FinalizeImmediateFrame( + context, + EditorWindowFrameDriver::DriveImmediateFrame( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive())); +} + +bool EditorWindowMessageDispatcher::EnsureTrackingMouseLeave(const DispatchContext& context) { + if (context.window.m_inputController->IsTrackingMouseLeave()) { + return true; + } + + TRACKMOUSEEVENT trackMouseEvent = {}; + trackMouseEvent.cbSize = sizeof(trackMouseEvent); + trackMouseEvent.dwFlags = TME_LEAVE; + trackMouseEvent.hwndTrack = context.hwnd; + if (!TrackMouseEvent(&trackMouseEvent)) { + return false; + } + + context.window.m_inputController->SetTrackingMouseLeave(true); + return true; +} + +bool EditorWindowMessageDispatcher::TryHandleChromeHoverConsumption( + const DispatchContext& context, + LPARAM lParam, + LRESULT& outResult) { + EditorWindowInputController& inputController = *context.window.m_inputController; + EditorWindowChromeController& chromeController = *context.window.m_chromeController; + const EditorWindowInputFeedbackBinding* inputFeedbackBinding = + context.window.m_runtime->TryGetInputFeedbackBinding(); + + if (!CanConsumeEditorWindowChromeHover( + inputController.GetPointerCaptureOwner(), + inputFeedbackBinding != nullptr && + inputFeedbackBinding->HasShellInteractiveCapture(), + inputFeedbackBinding != nullptr && + inputFeedbackBinding->HasHostedContentCapture())) { + return false; + } + + const bool resizeHoverChanged = chromeController.UpdateResizeHover(context.window, lParam); + if (chromeController.UpdateChromeHover(context.window, lParam)) { + context.window.InvalidateHostWindow(); + } + if (resizeHoverChanged) { + context.window.InvalidateHostWindow(); + } + + EnsureTrackingMouseLeave(context); + if (chromeController.GetHoveredBorderlessResizeEdge() != + Host::BorderlessWindowResizeEdge::None) { + outResult = 0; + return true; + } + + const Host::BorderlessWindowChromeHitTarget chromeHitTarget = + chromeController.HitTestChrome(context.window, lParam); + if (chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MinimizeButton || + chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton || + chromeHitTarget == Host::BorderlessWindowChromeHitTarget::CloseButton) { + outResult = 0; + return true; + } + + return false; +} + +bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + EditorWindowInputController& inputController = *context.window.m_inputController; + EditorWindowChromeController& chromeController = *context.window.m_chromeController; + + switch (message) { + case WM_MOUSEMOVE: + if (CanRouteEditorWindowGlobalTabDragPointerMessages( + inputController.GetPointerCaptureOwner(), + context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && + context.workspaceCoordinator.HandleGlobalTabDragPointerMove(context.hwnd)) { + outResult = 0; + return true; + } + if (CanRouteEditorWindowBorderlessResizePointerMessages( + inputController.GetPointerCaptureOwner()) && + chromeController.HandleResizePointerMove( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive())) { + outResult = 0; + return true; + } + if (CanRouteEditorWindowBorderlessChromePointerMessages( + inputController.GetPointerCaptureOwner()) && + chromeController.HandleChromeDragRestorePointerMove( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive())) { + outResult = 0; + return true; + } + if (TryHandleChromeHoverConsumption(context, lParam, outResult)) { + return true; + } + + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerMove, + ::XCEngine::UI::UIPointerButton::None, + wParam, + lParam); + outResult = 0; + return true; + case WM_MOUSELEAVE: + inputController.SetTrackingMouseLeave(false); + chromeController.ClearResizeState(context.window); + chromeController.ClearChromeDragRestoreState(context.window); + chromeController.ClearChromeState(context.window); + context.window.QueuePointerLeaveEvent(); + outResult = 0; + return true; + case WM_LBUTTONDOWN: + if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) { + context.workspaceCoordinator.EndGlobalTabDragSession(); + } + if (chromeController.HandleResizeButtonDown(context.window, lParam)) { + outResult = 0; + return true; + } + if (chromeController.HandleChromeButtonDown(context.window, lParam)) { + outResult = 0; + return true; + } + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Left, + wParam, + lParam, + true); + outResult = 0; + return true; + case WM_RBUTTONDOWN: + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Right, + wParam, + lParam, + true); + outResult = 0; + return true; + case WM_MBUTTONDOWN: + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Middle, + wParam, + lParam, + true); + outResult = 0; + return true; + case WM_LBUTTONUP: + if (CanRouteEditorWindowGlobalTabDragPointerMessages( + inputController.GetPointerCaptureOwner(), + context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) && + context.workspaceCoordinator.HandleGlobalTabDragPointerButtonUp(context.hwnd)) { + outResult = 0; + return true; + } + if (CanRouteEditorWindowBorderlessResizePointerMessages( + inputController.GetPointerCaptureOwner()) && + chromeController.HandleResizeButtonUp(context.window)) { + outResult = 0; + return true; + } + if (CanRouteEditorWindowBorderlessChromePointerMessages( + inputController.GetPointerCaptureOwner()) && + chromeController.HandleChromeButtonUp( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive(), + lParam)) { + outResult = 0; + return true; + } + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonUp, + ::XCEngine::UI::UIPointerButton::Left, + wParam, + lParam); + outResult = 0; + return true; + case WM_RBUTTONUP: + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonUp, + ::XCEngine::UI::UIPointerButton::Right, + wParam, + lParam); + outResult = 0; + return true; + case WM_MBUTTONUP: + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonUp, + ::XCEngine::UI::UIPointerButton::Middle, + wParam, + lParam); + outResult = 0; + return true; + case WM_LBUTTONDBLCLK: + if (chromeController.HandleChromeDoubleClick( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive(), + lParam)) { + outResult = 0; + return true; + } + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Left, + wParam, + lParam); + outResult = 0; + return true; + case WM_RBUTTONDBLCLK: + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Right, + wParam, + lParam); + outResult = 0; + return true; + case WM_MBUTTONDBLCLK: + SetFocus(context.hwnd); + context.window.TryStartImmediateShellPointerCapture(lParam); + context.window.QueuePointerEvent( + ::XCEngine::UI::UIInputEventType::PointerButtonDown, + ::XCEngine::UI::UIPointerButton::Middle, + wParam, + lParam); + outResult = 0; + return true; + case WM_MOUSEWHEEL: + context.window.QueuePointerWheelEvent(GET_WHEEL_DELTA_WPARAM(wParam), wParam, lParam); + outResult = 0; + return true; + default: + return false; + } +} + +bool EditorWindowMessageDispatcher::TryDispatchWindowInputMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + EditorWindowInputController& inputController = *context.window.m_inputController; + EditorWindowChromeController& chromeController = *context.window.m_chromeController; + + if (TryDispatchWindowPointerMessage(context, message, wParam, lParam, outResult)) { + return true; + } + + switch (message) { + case WM_SETFOCUS: + inputController.SyncInputModifiersFromSystemState(); + inputController.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusGained); + outResult = 0; + return true; + case WM_KILLFOCUS: + inputController.ResetInputModifiers(); + inputController.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost); + outResult = 0; + return true; + case WM_CAPTURECHANGED: + if (reinterpret_cast(lParam) != context.hwnd) { + inputController.ClearPointerCaptureOwner(); + } + if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId()) && + reinterpret_cast(lParam) != context.hwnd) { + context.workspaceCoordinator.EndGlobalTabDragSession(); + outResult = 0; + return true; + } + if (reinterpret_cast(lParam) != context.hwnd && + context.window.HasInteractiveCaptureState()) { + inputController.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost); + chromeController.ForceClearResizeState(context.window); + chromeController.ClearChromeDragRestoreState(context.window); + chromeController.ClearChromeState(context.window); + outResult = 0; + return true; + } + if (reinterpret_cast(lParam) != context.hwnd) { + chromeController.ForceClearResizeState(context.window); + chromeController.ClearChromeDragRestoreState(context.window); + chromeController.ClearChromeState(context.window); + } + return false; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (wParam == VK_F12) { + context.window.m_runtime->RequestManualScreenshot("manual_f12"); + } + inputController.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyDown, wParam, lParam); + outResult = 0; + return true; + case WM_KEYUP: + case WM_SYSKEYUP: + inputController.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyUp, wParam, lParam); + outResult = 0; + return true; + case WM_CHAR: + inputController.QueueCharacterEvent(wParam); + outResult = 0; + return true; + default: + return false; + } +} + +bool EditorWindowMessageDispatcher::TryDispatchWindowLifecycleMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + switch (message) { + case WM_DPICHANGED: + if (lParam == 0) { + return false; + } + context.window.OnDpiChanged( + static_cast(LOWORD(wParam)), + *reinterpret_cast(lParam)); + RenderAndHandleWindowFrame(context); + outResult = 0; + return true; + case WM_ENTERSIZEMOVE: + context.window.OnEnterSizeMove(); + outResult = 0; + return true; + case WM_EXITSIZEMOVE: + if (context.window.OnExitSizeMove()) { + RenderAndHandleWindowFrame(context); + } + outResult = 0; + return true; + case WM_SIZE: + if (wParam != SIZE_MINIMIZED) { + const bool requiresImmediateFrame = context.window.OnResize( + static_cast(LOWORD(lParam)), + static_cast(HIWORD(lParam))); + if (requiresImmediateFrame) { + RenderAndHandleWindowFrame(context); + } + } + outResult = 0; + return true; + case WM_CLOSE: + context.lifecycleCoordinator.ExecuteCloseRequest(context.window); + outResult = 0; + return true; + case WM_PAINT: + FinalizeImmediateFrame( + context, + context.window.OnPaintMessage( + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive())); + outResult = 0; + return true; + case WM_ERASEBKGND: + outResult = 1; + return true; + case WM_DESTROY: + context.lifecycleCoordinator.HandleNativeWindowDestroyed(context.window); + outResult = 0; + return true; + default: + return false; + } +} + +bool EditorWindowMessageDispatcher::TryDispatchWindowChromeMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + EditorWindowChromeController& chromeController = *context.window.m_chromeController; + + switch (message) { + case WM_GETMINMAXINFO: + if (chromeController.HandleGetMinMaxInfo(context.window, lParam)) { + outResult = 0; + return true; + } + return false; + case WM_NCCALCSIZE: + outResult = chromeController.HandleNcCalcSize(context.window, wParam, lParam); + return true; + case WM_NCACTIVATE: + outResult = TRUE; + return true; + case WM_NCHITTEST: + outResult = HTCLIENT; + return true; + case WM_NCPAINT: + case kMessageNcUaDrawCaption: + case kMessageNcUaDrawFrame: + outResult = 0; + return true; + case WM_SYSCOMMAND: + if (chromeController.HandleSystemCommand( + context.window, + context.hostRuntime.GetEditorContext(), + context.workspaceCoordinator.IsGlobalTabDragActive(), + wParam)) { + outResult = 0; + return true; + } + return false; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT && context.window.ApplyCurrentCursor()) { + outResult = TRUE; + return true; + } + return false; + default: + return false; + } +} + +bool EditorWindowMessageDispatcher::TryDispatch( + HWND hwnd, + EditorWindowHostRuntime& hostRuntime, + EditorWindowLifecycleCoordinator& lifecycleCoordinator, + EditorUtilityWindowCoordinator& utilityCoordinator, + EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorWindow& window, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult) { + const DispatchContext context = { + .hwnd = hwnd, + .hostRuntime = hostRuntime, + .lifecycleCoordinator = lifecycleCoordinator, + .utilityCoordinator = utilityCoordinator, + .workspaceCoordinator = workspaceCoordinator, + .window = window, + }; + + bool handled = false; + if (TryDispatchWindowChromeMessage(context, message, wParam, lParam, outResult)) { + handled = true; + } else if (TryDispatchWindowLifecycleMessage(context, message, wParam, lParam, outResult)) { + handled = true; + } else if (TryDispatchWindowInputMessage(context, message, wParam, lParam, outResult)) { + handled = true; + } + + if (handled) { + FlushQueuedCompletedImmediateFrame(context); + } + + return handled; +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h new file mode 100644 index 00000000..d506a727 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.h @@ -0,0 +1,79 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include + +namespace XCEngine::UI::Editor::App { +class EditorWindow; +} + +namespace XCEngine::UI::Editor::App { + +class EditorWindowHostRuntime; +class EditorWindowLifecycleCoordinator; +class EditorUtilityWindowCoordinator; +class EditorWindowWorkspaceCoordinator; + +class EditorWindowMessageDispatcher final { +public: + static bool TryDispatch( + HWND hwnd, + EditorWindowHostRuntime& hostRuntime, + EditorWindowLifecycleCoordinator& lifecycleCoordinator, + EditorUtilityWindowCoordinator& utilityCoordinator, + EditorWindowWorkspaceCoordinator& workspaceCoordinator, + EditorWindow& window, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); + +private: + struct DispatchContext; + + static void FinalizeImmediateFrame( + const DispatchContext& context, + const EditorWindowFrameTransferRequests& transferRequests); + static void FlushQueuedCompletedImmediateFrame(const DispatchContext& context); + static void RenderAndHandleWindowFrame(const DispatchContext& context); + static void DispatchWindowFrameTransferRequests( + const DispatchContext& context, + const EditorWindowFrameTransferRequests& transferRequests); + static bool EnsureTrackingMouseLeave(const DispatchContext& context); + static bool TryHandleChromeHoverConsumption( + const DispatchContext& context, + LPARAM lParam, + LRESULT& outResult); + static bool TryDispatchWindowPointerMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); + static bool TryDispatchWindowInputMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); + static bool TryDispatchWindowLifecycleMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); + static bool TryDispatchWindowChromeMessage( + const DispatchContext& context, + UINT message, + WPARAM wParam, + LPARAM lParam, + LRESULT& outResult); +}; + +} // namespace XCEngine::UI::Editor::App + diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowPointerCapture.h b/editor/app/Platform/Win32/Windowing/EditorWindowPointerCapture.h similarity index 100% rename from new_editor/app/Platform/Win32/Windowing/EditorWindowPointerCapture.h rename to editor/app/Platform/Win32/Windowing/EditorWindowPointerCapture.h diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp new file mode 100644 index 00000000..2e5045ad --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp @@ -0,0 +1,126 @@ +#include "Platform/Win32/Windowing/EditorWindowSession.h" + +#include "Platform/Win32/Windowing/EditorWindowSupport.h" + +#include + +namespace XCEngine::UI::Editor::App { + +using namespace EditorWindowSupport; + +EditorWindowSession::EditorWindowSession( + std::string windowId, + std::wstring title, + bool primary) { + m_state.window.windowId = std::move(windowId); + m_state.window.title = std::move(title); + m_state.window.primary = primary; + UpdateCachedTitleText(); +} + +std::string_view EditorWindowSession::GetWindowId() const { + return m_state.window.windowId; +} + +HWND EditorWindowSession::GetHwnd() const { + return m_state.window.hwnd; +} + +bool EditorWindowSession::HasHwnd() const { + return m_state.window.hwnd != nullptr; +} + +EditorWindowLifecycleState EditorWindowSession::GetLifecycleState() const { + return m_state.window.lifecycle; +} + +bool EditorWindowSession::IsPrimary() const { + return m_state.window.primary; +} + +bool EditorWindowSession::IsClosing() const { + return m_state.window.lifecycle == EditorWindowLifecycleState::Closing; +} + +bool EditorWindowSession::IsDestroyed() const { + return m_state.window.lifecycle == EditorWindowLifecycleState::Destroyed; +} + +const std::wstring& EditorWindowSession::GetTitle() const { + return m_state.window.title; +} + +std::string_view EditorWindowSession::GetCachedTitleText() const { + return m_state.window.titleText; +} + +void EditorWindowSession::AttachHwnd(HWND hwnd) { + m_state.window.hwnd = hwnd; + m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; +} + +void EditorWindowSession::MarkNativeAttached() { + m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; +} + +void EditorWindowSession::MarkInitializing() { + m_state.window.lifecycle = EditorWindowLifecycleState::Initializing; +} + +void EditorWindowSession::MarkRunning() { + m_state.window.lifecycle = EditorWindowLifecycleState::Running; +} + +void EditorWindowSession::MarkDestroyed() { + m_state.window.hwnd = nullptr; + m_state.window.lifecycle = EditorWindowLifecycleState::Destroyed; +} + +void EditorWindowSession::MarkClosing() { + m_state.window.lifecycle = EditorWindowLifecycleState::Closing; +} + +void EditorWindowSession::SetPrimary(bool primary) { + m_state.window.primary = primary; +} + +void EditorWindowSession::SetTitle(std::wstring title) { + m_state.window.title = std::move(title); + UpdateCachedTitleText(); +} + +void EditorWindowSession::QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests) { + m_hasQueuedCompletedImmediateFrame = true; + if (transferRequests.beginGlobalTabDrag.has_value()) { + m_queuedImmediateFrameTransferRequests.beginGlobalTabDrag = + std::move(transferRequests.beginGlobalTabDrag); + } + if (transferRequests.detachPanel.has_value()) { + m_queuedImmediateFrameTransferRequests.detachPanel = + std::move(transferRequests.detachPanel); + } + if (transferRequests.openUtilityWindow.has_value()) { + m_queuedImmediateFrameTransferRequests.openUtilityWindow = + std::move(transferRequests.openUtilityWindow); + } +} + +bool EditorWindowSession::HasQueuedCompletedImmediateFrame() const { + return m_hasQueuedCompletedImmediateFrame; +} + +EditorWindowFrameTransferRequests +EditorWindowSession::ConsumeQueuedCompletedImmediateFrameTransferRequests() { + m_hasQueuedCompletedImmediateFrame = false; + EditorWindowFrameTransferRequests transferRequests = + std::move(m_queuedImmediateFrameTransferRequests); + m_queuedImmediateFrameTransferRequests = {}; + return transferRequests; +} + +void EditorWindowSession::UpdateCachedTitleText() { + m_state.window.titleText = WideToUtf8(m_state.window.title); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowSession.h b/editor/app/Platform/Win32/Windowing/EditorWindowSession.h new file mode 100644 index 00000000..c2027c0b --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowSession.h @@ -0,0 +1,47 @@ +#pragma once + +#include "Platform/Win32/Windowing/EditorWindowState.h" +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWindowSession final { +public: + EditorWindowSession(std::string windowId, std::wstring title, bool primary); + + std::string_view GetWindowId() const; + HWND GetHwnd() const; + bool HasHwnd() const; + EditorWindowLifecycleState GetLifecycleState() const; + bool IsPrimary() const; + bool IsClosing() const; + bool IsDestroyed() const; + const std::wstring& GetTitle() const; + std::string_view GetCachedTitleText() const; + + void AttachHwnd(HWND hwnd); + void MarkNativeAttached(); + void MarkInitializing(); + void MarkRunning(); + void MarkDestroyed(); + void MarkClosing(); + void SetPrimary(bool primary); + void SetTitle(std::wstring title); + + void QueueCompletedImmediateFrame( + EditorWindowFrameTransferRequests transferRequests); + bool HasQueuedCompletedImmediateFrame() const; + EditorWindowFrameTransferRequests ConsumeQueuedCompletedImmediateFrameTransferRequests(); + +private: + void UpdateCachedTitleText(); + + EditorWindowState m_state = {}; + EditorWindowFrameTransferRequests m_queuedImmediateFrameTransferRequests = {}; + bool m_hasQueuedCompletedImmediateFrame = false; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowState.h b/editor/app/Platform/Win32/Windowing/EditorWindowState.h similarity index 51% rename from new_editor/app/Platform/Win32/Windowing/EditorWindowState.h rename to editor/app/Platform/Win32/Windowing/EditorWindowState.h index 3a258d89..5b17b15c 100644 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowState.h +++ b/editor/app/Platform/Win32/Windowing/EditorWindowState.h @@ -6,11 +6,6 @@ #include -#include "Platform/Win32/Chrome/BorderlessWindowChrome.h" -#include "Platform/Win32/Chrome/HostRuntimeState.h" -#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" -#include - #include #include #include @@ -49,45 +44,14 @@ inline std::string_view GetEditorWindowLifecycleStateName( struct EditorWindowWindowState { HWND hwnd = nullptr; std::string windowId = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; std::wstring title = {}; std::string titleText = {}; - UINT dpi = 96u; bool primary = false; EditorWindowLifecycleState lifecycle = EditorWindowLifecycleState::PendingNativeCreate; }; -struct EditorWindowFrameState { - struct PredictedClientPixelSizeState { - bool active = false; - UINT width = 0u; - UINT height = 0u; - bool presented = false; - }; - - PredictedClientPixelSizeState predictedClientPixelSize = {}; -}; - -struct EditorWindowInputState { - bool trackingMouseLeave = false; - EditorWindowPointerCaptureOwner pointerCaptureOwner = - EditorWindowPointerCaptureOwner::None; -}; - -struct EditorWindowChromeWindowState { - bool interactiveResizeActive = false; - Host::BorderlessWindowResizeState borderlessResize = {}; - Host::BorderlessWindowPlacementState borderlessWindowPlacement = {}; - Host::BorderlessWindowDragRestoreState borderlessWindowDragRestore = {}; - Host::BorderlessWindowChromeState chrome = {}; -}; - struct EditorWindowState { EditorWindowWindowState window = {}; - EditorWindowFrameState frame = {}; - EditorWindowInputState input = {}; - EditorWindowChromeWindowState chrome = {}; }; } // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Content/EditorWindowContentStyle.h b/editor/app/Platform/Win32/Windowing/EditorWindowSupport.h similarity index 52% rename from new_editor/app/Windowing/Content/EditorWindowContentStyle.h rename to editor/app/Platform/Win32/Windowing/EditorWindowSupport.h index 21f72dbb..563a753e 100644 --- a/new_editor/app/Windowing/Content/EditorWindowContentStyle.h +++ b/editor/app/Platform/Win32/Windowing/EditorWindowSupport.h @@ -1,8 +1,20 @@ #pragma once +#include "Support/EnvironmentFlags.h" +#include "Support/StringEncoding.h" +#include "Support/TextFormat.h" + #include -namespace XCEngine::UI::Editor::App::EditorWindowContentStyle { +#include + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include + +namespace XCEngine::UI::Editor::App::EditorWindowSupport { inline constexpr unsigned int kDefaultDpi = 96u; inline constexpr float kBaseDpiScale = 96.0f; @@ -14,4 +26,12 @@ inline const ::XCEngine::UI::UIColor kShellBorderColor(0.15f, 0.15f, 0.15f, 1.0f inline const ::XCEngine::UI::UIColor kShellTextColor(0.92f, 0.92f, 0.92f, 1.0f); inline const ::XCEngine::UI::UIColor kShellMutedTextColor(0.70f, 0.70f, 0.70f, 1.0f); -} // namespace XCEngine::UI::Editor::App::EditorWindowContentStyle +UINT QuerySystemDpi(); +UINT QueryWindowDpi(HWND hwnd); +bool ResolveVerboseRuntimeTraceEnabled(); +void LogRuntimeTrace(std::string_view channel, std::string_view message); + +using App::TruncateText; +using App::WideToUtf8; + +} // namespace XCEngine::UI::Editor::App::EditorWindowSupport diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowTransferRequests.h b/editor/app/Platform/Win32/Windowing/EditorWindowTransferRequests.h new file mode 100644 index 00000000..363cad23 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowTransferRequests.h @@ -0,0 +1,48 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include "UtilityWindows/EditorUtilityWindowKind.h" + +#include + +#include +#include + +namespace XCEngine::UI::Editor::App { + +struct EditorWindowPanelTransferRequest { + std::string nodeId = {}; + std::string panelId = {}; + POINT screenPoint = {}; + + bool IsValid() const { + return !nodeId.empty() && !panelId.empty(); + } +}; + +struct EditorWindowOpenUtilityWindowRequest { + EditorUtilityWindowKind kind = EditorUtilityWindowKind::None; + POINT screenPoint = {}; + bool useCursorPlacement = false; + + bool IsValid() const { + return kind != EditorUtilityWindowKind::None; + } +}; + +struct EditorWindowFrameTransferRequests { + std::optional beginGlobalTabDrag = {}; + std::optional detachPanel = {}; + std::optional openUtilityWindow = {}; + + bool HasPendingRequests() const { + return beginGlobalTabDrag.has_value() || + detachPanel.has_value() || + openUtilityWindow.has_value(); + } +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp b/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp new file mode 100644 index 00000000..e924b001 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp @@ -0,0 +1,843 @@ +#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h" + +#include "Composition/EditorContext.h" +#include "Platform/Win32/Windowing/EditorWindow.h" +#include "Platform/Win32/Windowing/EditorFloatingWindowPlacement.h" +#include "Platform/Win32/Content/EditorWorkspaceWindowContentController.h" +#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" +#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h" +#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +struct ExistingWindowSnapshot { + EditorWindow* window = nullptr; + UIEditorWorkspaceController workspaceController = {}; + std::wstring title = {}; + bool primary = false; +}; + +using ::XCEngine::UI::UIPoint; + +constexpr LONG kFallbackDragHotspotX = 40; +constexpr LONG kFallbackDragHotspotY = 12; + +POINT BuildFallbackGlobalTabDragHotspot() { + POINT hotspot = {}; + hotspot.x = kFallbackDragHotspotX; + hotspot.y = kFallbackDragHotspotY; + return hotspot; +} + +bool CanStartGlobalTabDragFromWindow( + const EditorWindow& sourceWindow, + std::string_view sourceNodeId, + std::string_view panelId) { + UIEditorWorkspaceModel workspace = + sourceWindow.GetWorkspaceController().GetWorkspace(); + UIEditorWorkspaceSession session = + sourceWindow.GetWorkspaceController().GetSession(); + UIEditorWorkspaceExtractedPanel extractedPanel = {}; + return TryExtractUIEditorWorkspaceVisiblePanel( + workspace, + session, + sourceNodeId, + panelId, + extractedPanel); +} + +bool IsLiveInteractiveWindow(const EditorWindow* window) { + return window != nullptr && + window->GetHwnd() != nullptr && + window->GetLifecycleState() == EditorWindowLifecycleState::Running; +} + +std::string DescribeWindowSetState(const UIEditorWindowWorkspaceSet& windowSet) { + std::ostringstream stream = {}; + stream << "primary='" << windowSet.primaryWindowId + << "' active='" << windowSet.activeWindowId + << "' count=" << windowSet.windows.size() + << " windows=["; + bool first = true; + for (const UIEditorWindowWorkspaceState& state : windowSet.windows) { + if (!first) { + stream << ','; + } + first = false; + stream << state.windowId; + } + stream << ']'; + return stream.str(); +} + +UIEditorWindowWorkspaceSet BuildLiveWindowWorkspaceSet( + const EditorWindowHostRuntime& hostRuntime, + std::string_view excludedWindowId = {}, + bool includeClosingWindows = false) { + UIEditorWindowWorkspaceSet windowSet = {}; + + for (const std::unique_ptr& window : hostRuntime.GetWindows()) { + if (window == nullptr || + window->GetHwnd() == nullptr || + window->GetWindowId() == excludedWindowId || + (!includeClosingWindows && + window->GetLifecycleState() != EditorWindowLifecycleState::Running)) { + continue; + } + + UIEditorWindowWorkspaceState state = {}; + state.windowId = std::string(window->GetWindowId()); + const UIEditorWorkspaceController* const workspaceController = + window->TryGetWorkspaceController(); + if (workspaceController == nullptr) { + continue; + } + state.workspace = workspaceController->GetWorkspace(); + state.session = workspaceController->GetSession(); + if (window->IsPrimary()) { + windowSet.primaryWindowId = state.windowId; + } + windowSet.windows.push_back(std::move(state)); + } + + if (windowSet.activeWindowId.empty()) { + if (!windowSet.primaryWindowId.empty() && + FindUIEditorWindowWorkspaceState(windowSet, windowSet.primaryWindowId) != nullptr) { + windowSet.activeWindowId = windowSet.primaryWindowId; + } else if (!windowSet.windows.empty()) { + windowSet.activeWindowId = windowSet.windows.front().windowId; + } + } + + return windowSet; +} + +} // namespace + +EditorWindowWorkspaceCoordinator::EditorWindowWorkspaceCoordinator( + EditorWindowHostRuntime& hostRuntime) + : m_hostRuntime(hostRuntime), + m_workspaceStore(hostRuntime.GetEditorContext().GetShellAsset().panelRegistry) {} + +EditorWindowWorkspaceCoordinator::~EditorWindowWorkspaceCoordinator() = default; + +void EditorWindowWorkspaceCoordinator::BindLifecycleCoordinator( + EditorWindowLifecycleCoordinator& lifecycleCoordinator) { + m_lifecycleCoordinator = &lifecycleCoordinator; +} + +void EditorWindowWorkspaceCoordinator::RegisterExistingWindow(EditorWindow& window) { + RefreshWindowTitle(window); +} + +void EditorWindowWorkspaceCoordinator::RefreshWindowPresentation(EditorWindow& window) const { + RefreshWindowTitle(window); +} + +bool EditorWindowWorkspaceCoordinator::IsPrimaryWindowId(std::string_view windowId) const { + if (const EditorWindow* window = m_hostRuntime.FindWindow(windowId); window != nullptr) { + return window->IsPrimary(); + } + + return false; +} + +std::string EditorWindowWorkspaceCoordinator::DescribeWindowSet() const { + return DescribeWindowSetState(BuildLiveWindowWorkspaceSet(m_hostRuntime, {}, true)); +} + +void EditorWindowWorkspaceCoordinator::RemoveWindowProjection( + std::string_view windowId, + bool primary) { + LogRuntimeTrace( + "window-close", + "workspace remove begin windowId='" + std::string(windowId) + + "' primaryArg=" + (primary ? "1" : "0") + + " stateBefore=" + DescribeWindowSet()); + + const UIEditorWindowWorkspaceSet stateAfter = + primary + ? UIEditorWindowWorkspaceSet{} + : BuildLiveWindowWorkspaceSet(m_hostRuntime, windowId, true); + LogRuntimeTrace( + "window-close", + "workspace remove end windowId='" + std::string(windowId) + + "' stateAfter=" + DescribeWindowSetState(stateAfter)); +} + +UIEditorWindowWorkspaceController +EditorWindowWorkspaceCoordinator::BuildWorkspaceMutationController() const { + return UIEditorWindowWorkspaceController( + m_workspaceStore.GetPanelRegistry(), + BuildLiveWindowWorkspaceSet(m_hostRuntime)); +} + +UIEditorWorkspaceController EditorWindowWorkspaceCoordinator::BuildWorkspaceControllerForWindow( + const UIEditorWindowWorkspaceState& windowState) const { + return UIEditorWorkspaceController( + m_workspaceStore.GetPanelRegistry(), + windowState.workspace, + windowState.session); +} + +std::wstring EditorWindowWorkspaceCoordinator::BuildWindowTitle( + const UIEditorWorkspaceController& workspaceController) const { + const std::string titleText = + ResolveUIEditorDetachedWorkspaceTitle(workspaceController); + if (!titleText.empty()) { + const std::string decoratedTitle = titleText + " - XCEngine Editor"; + return std::wstring(decoratedTitle.begin(), decoratedTitle.end()); + } + + return std::wstring(L"XCEngine Editor"); +} + +void EditorWindowWorkspaceCoordinator::RefreshWindowTitle(EditorWindow& window) const { + if (window.IsPrimary()) { + return; + } + + if (window.TryGetWorkspaceController() == nullptr) { + return; + } + + const std::wstring title = BuildWindowTitle(window.GetWorkspaceController()); + if (title == window.GetTitle()) { + return; + } + + window.SetTitle(title); + if (window.GetHwnd() != nullptr) { + SetWindowTextW(window.GetHwnd(), window.GetTitle().c_str()); + } +} + +bool EditorWindowWorkspaceCoordinator::SynchronizeWindowsFromWindowSet( + const UIEditorWindowWorkspaceSet& windowSet, + std::string_view preferredNewWindowId, + const POINT& preferredScreenPoint, + LONG preferredWidth, + LONG preferredHeight) { + const auto restoreWindowSnapshot = [](const ExistingWindowSnapshot& snapshot) { + if (snapshot.window == nullptr) { + return; + } + + snapshot.window->ReplaceWorkspaceController(snapshot.workspaceController); + snapshot.window->SetPrimary(snapshot.primary); + snapshot.window->SetTitle(snapshot.title); + snapshot.window->ResetInteractionState(); + if (snapshot.window->GetHwnd() != nullptr) { + SetWindowTextW(snapshot.window->GetHwnd(), snapshot.window->GetTitle().c_str()); + } + }; + + const auto destroyAndEraseWindowById = [this](std::string_view windowId) { + EditorWindow* const window = m_hostRuntime.FindWindow(windowId); + if (window == nullptr || m_lifecycleCoordinator == nullptr) { + return false; + } + + m_lifecycleCoordinator->AbortUnregisteredWindow(*window); + return true; + }; + + std::vector windowIdsInSet = {}; + windowIdsInSet.reserve(windowSet.windows.size()); + std::vector existingWindowSnapshots = {}; + existingWindowSnapshots.reserve(windowSet.windows.size()); + std::vector createdWindowIds = {}; + + for (const UIEditorWindowWorkspaceState& entry : windowSet.windows) { + windowIdsInSet.push_back(entry.windowId); + const bool isPrimaryWindow = entry.windowId == windowSet.primaryWindowId; + EditorWindow* existingWindow = m_hostRuntime.FindWindow(entry.windowId); + if (existingWindow != nullptr && + existingWindow->IsDestroyed() && + m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->ReapDestroyedWindows(); + existingWindow = m_hostRuntime.FindWindow(entry.windowId); + } + + if (existingWindow != nullptr) { + if (existingWindow->GetLifecycleState() != EditorWindowLifecycleState::Running) { + LogRuntimeTrace( + "window", + "workspace synchronization rejected: window '" + entry.windowId + + "' is in lifecycle state '" + + std::string( + GetEditorWindowLifecycleStateName( + existingWindow->GetLifecycleState())) + + "'"); + return false; + } + + existingWindowSnapshots.push_back(ExistingWindowSnapshot{ + existingWindow, + existingWindow->GetWorkspaceController(), + existingWindow->GetTitle(), + existingWindow->IsPrimary(), + }); + existingWindow->SetPrimary(isPrimaryWindow); + existingWindow->ReplaceWorkspaceController(BuildWorkspaceControllerForWindow(entry)); + existingWindow->ResetInteractionState(); + existingWindow->SetTitle( + isPrimaryWindow + ? std::wstring( + m_hostRuntime.GetHostConfig().primaryWindowTitle != nullptr && + m_hostRuntime.GetHostConfig().primaryWindowTitle[0] != L'\0' + ? m_hostRuntime.GetHostConfig().primaryWindowTitle + : L"XCEngine Editor") + : BuildWindowTitle(existingWindow->GetWorkspaceController())); + if (existingWindow->GetHwnd() != nullptr) { + SetWindowTextW(existingWindow->GetHwnd(), existingWindow->GetTitle().c_str()); + } + continue; + } + + EditorWindowHostRuntime::CreateParams createParams = {}; + createParams.windowId = entry.windowId; + createParams.primary = isPrimaryWindow; + createParams.title = + createParams.primary + ? std::wstring( + m_hostRuntime.GetHostConfig().primaryWindowTitle != nullptr && + m_hostRuntime.GetHostConfig().primaryWindowTitle[0] != L'\0' + ? m_hostRuntime.GetHostConfig().primaryWindowTitle + : L"XCEngine Editor") + : BuildWindowTitle(BuildWorkspaceControllerForWindow(entry)); + if (entry.windowId == preferredNewWindowId) { + const RECT detachedRect = BuildEditorFloatingWindowRect( + preferredScreenPoint, + preferredWidth, + preferredHeight); + createParams.initialX = detachedRect.left; + createParams.initialY = detachedRect.top; + createParams.initialWidth = detachedRect.right - detachedRect.left; + createParams.initialHeight = detachedRect.bottom - detachedRect.top; + } + + if (m_hostRuntime.CreateEditorWindow( + CreateEditorWorkspaceWindowContentController( + BuildWorkspaceControllerForWindow(entry)), + createParams) == nullptr) { + for (const ExistingWindowSnapshot& snapshot : existingWindowSnapshots) { + restoreWindowSnapshot(snapshot); + } + for (auto it = createdWindowIds.rbegin(); it != createdWindowIds.rend(); ++it) { + destroyAndEraseWindowById(*it); + } + return false; + } + createdWindowIds.push_back(entry.windowId); + } + + for (const std::unique_ptr& window : m_hostRuntime.GetWindows()) { + if (window == nullptr || + window->GetHwnd() == nullptr || + window->IsPrimary() || + window->GetLifecycleState() != EditorWindowLifecycleState::Running) { + continue; + } + + const bool existsInWindowSet = + std::find( + windowIdsInSet.begin(), + windowIdsInSet.end(), + window->GetWindowId()) != windowIdsInSet.end(); + if (!existsInWindowSet) { + if (m_lifecycleCoordinator != nullptr) { + m_lifecycleCoordinator->PostCloseRequest(*window); + } + } + } + + return true; +} + +bool EditorWindowWorkspaceCoordinator::CommitWindowWorkspaceMutation( + const UIEditorWindowWorkspaceController& windowWorkspaceController, + std::string_view preferredNewWindowId, + const POINT& preferredScreenPoint, + LONG preferredWidth, + LONG preferredHeight) { + const UIEditorWindowWorkspaceSet nextWindowSet = windowWorkspaceController.GetWindowSet(); + std::string error = {}; + if (!m_workspaceStore.ValidateWindowSet(nextWindowSet, error)) { + LogRuntimeTrace("window", "workspace mutation validation failed: " + error); + return false; + } + + if (!SynchronizeWindowsFromWindowSet( + nextWindowSet, + preferredNewWindowId, + preferredScreenPoint, + preferredWidth, + preferredHeight)) { + return false; + } + + return true; +} + +bool EditorWindowWorkspaceCoordinator::IsGlobalTabDragActive() const { + return m_globalTabDragSession.active; +} + +bool EditorWindowWorkspaceCoordinator::OwnsActiveGlobalTabDrag( + std::string_view windowId) const { + return m_globalTabDragSession.active && + m_globalTabDragSession.panelWindowId == windowId; +} + +void EditorWindowWorkspaceCoordinator::BeginGlobalTabDragSession( + std::string_view panelWindowId, + std::string_view sourceNodeId, + std::string_view panelId, + const POINT& screenPoint, + const POINT& dragHotspot) { + m_globalTabDragSession.active = true; + m_globalTabDragSession.panelWindowId = std::string(panelWindowId); + m_globalTabDragSession.sourceNodeId = std::string(sourceNodeId); + m_globalTabDragSession.panelId = std::string(panelId); + m_globalTabDragSession.screenPoint = screenPoint; + m_globalTabDragSession.dragHotspot = dragHotspot; +} + +bool EditorWindowWorkspaceCoordinator::TryResolveGlobalTabDragHotspot( + const EditorWindow& sourceWindow, + std::string_view nodeId, + std::string_view panelId, + const POINT& screenPoint, + POINT& outDragHotspot) const { + return sourceWindow.TryResolveDockTabDragHotspot( + nodeId, + panelId, + screenPoint, + outDragHotspot); +} + +void EditorWindowWorkspaceCoordinator::UpdateGlobalTabDragOwnerWindowPosition() { + if (!m_globalTabDragSession.active) { + return; + } + + EditorWindow* ownerWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.panelWindowId); + if (!IsLiveInteractiveWindow(ownerWindow)) { + return; + } + + RECT windowRect = {}; + if (!GetWindowRect(ownerWindow->GetHwnd(), &windowRect)) { + return; + } + + const LONG targetLeft = + m_globalTabDragSession.screenPoint.x - m_globalTabDragSession.dragHotspot.x; + const LONG targetTop = + m_globalTabDragSession.screenPoint.y - m_globalTabDragSession.dragHotspot.y; + if (windowRect.left == targetLeft && windowRect.top == targetTop) { + return; + } + + SetWindowPos( + ownerWindow->GetHwnd(), + nullptr, + targetLeft, + targetTop, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); +} + +void EditorWindowWorkspaceCoordinator::ClearGlobalTabDragDropPreview() { + if (m_globalTabDragSession.previewWindowId.empty()) { + return; + } + + if (EditorWindow* previewWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.previewWindowId); + IsLiveInteractiveWindow(previewWindow)) { + if (EditorWindowDockHostBinding* dockHostBinding = + previewWindow->m_runtime->TryGetDockHostBinding(); + dockHostBinding != nullptr) { + dockHostBinding->ClearExternalDockHostDropPreview(); + previewWindow->InvalidateHostWindow(); + } + } + m_globalTabDragSession.previewWindowId.clear(); +} + +void EditorWindowWorkspaceCoordinator::UpdateGlobalTabDragDropPreview() { + if (!m_globalTabDragSession.active) { + return; + } + + EditorWindow* targetWindow = FindTopmostWindowAtScreenPoint( + m_globalTabDragSession.screenPoint, + m_globalTabDragSession.panelWindowId); + if (!IsLiveInteractiveWindow(targetWindow)) { + ClearGlobalTabDragDropPreview(); + return; + } + + UIEditorDockHostTabDropTarget dropTarget = {}; + if (!targetWindow->TryResolveDockTabDropTarget( + m_globalTabDragSession.screenPoint, + dropTarget)) { + ClearGlobalTabDragDropPreview(); + return; + } + + if (!m_globalTabDragSession.previewWindowId.empty() && + m_globalTabDragSession.previewWindowId != targetWindow->GetWindowId()) { + ClearGlobalTabDragDropPreview(); + } + + Widgets::UIEditorDockHostDropPreviewState preview = {}; + preview.visible = true; + preview.sourceNodeId = m_globalTabDragSession.sourceNodeId; + preview.sourcePanelId = m_globalTabDragSession.panelId; + preview.targetNodeId = dropTarget.nodeId; + preview.placement = dropTarget.placement; + preview.insertionIndex = dropTarget.insertionIndex; + if (EditorWindowDockHostBinding* dockHostBinding = + targetWindow->m_runtime->TryGetDockHostBinding(); + dockHostBinding != nullptr) { + dockHostBinding->SetExternalDockHostDropPreview(preview); + targetWindow->InvalidateHostWindow(); + } + m_globalTabDragSession.previewWindowId = std::string(targetWindow->GetWindowId()); +} + +void EditorWindowWorkspaceCoordinator::EndGlobalTabDragSession() { + if (!m_globalTabDragSession.active) { + return; + } + + ClearGlobalTabDragDropPreview(); + + if (EditorWindow* ownerWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.panelWindowId); + ownerWindow != nullptr) { + ownerWindow->ReleasePointerCapture(EditorWindowPointerCaptureOwner::GlobalTabDrag); + if (IsLiveInteractiveWindow(ownerWindow)) { + ownerWindow->ResetInteractionState(); + } + } + + m_globalTabDragSession = {}; +} + +bool EditorWindowWorkspaceCoordinator::HandleGlobalTabDragPointerMove(HWND hwnd) { + if (!m_globalTabDragSession.active) { + return false; + } + + const EditorWindow* ownerWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.panelWindowId); + if (!IsLiveInteractiveWindow(ownerWindow)) { + EndGlobalTabDragSession(); + return false; + } + if (ownerWindow->GetHwnd() != hwnd) { + return false; + } + + POINT screenPoint = {}; + if (GetCursorPos(&screenPoint)) { + m_globalTabDragSession.screenPoint = screenPoint; + UpdateGlobalTabDragOwnerWindowPosition(); + UpdateGlobalTabDragDropPreview(); + } + return true; +} + +bool EditorWindowWorkspaceCoordinator::HandleGlobalTabDragPointerButtonUp(HWND hwnd) { + if (!m_globalTabDragSession.active) { + return false; + } + + const EditorWindow* ownerWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.panelWindowId); + if (!IsLiveInteractiveWindow(ownerWindow)) { + EndGlobalTabDragSession(); + return false; + } + if (ownerWindow->GetHwnd() != hwnd) { + return false; + } + + POINT screenPoint = m_globalTabDragSession.screenPoint; + GetCursorPos(&screenPoint); + + const std::string panelWindowId = m_globalTabDragSession.panelWindowId; + const std::string sourceNodeId = m_globalTabDragSession.sourceNodeId; + const std::string panelId = m_globalTabDragSession.panelId; + EndGlobalTabDragSession(); + + EditorWindow* targetWindow = FindTopmostWindowAtScreenPoint(screenPoint, panelWindowId); + if (!IsLiveInteractiveWindow(targetWindow)) { + return true; + } + + UIEditorDockHostTabDropTarget dropTarget = {}; + if (!targetWindow->TryResolveDockTabDropTarget(screenPoint, dropTarget)) { + return true; + } + + UIEditorWindowWorkspaceController windowWorkspaceController = + BuildWorkspaceMutationController(); + const UIEditorWindowWorkspaceOperationResult result = + dropTarget.placement == UIEditorWorkspaceDockPlacement::Center + ? windowWorkspaceController.MovePanelToStack( + panelWindowId, + sourceNodeId, + panelId, + targetWindow->GetWindowId(), + dropTarget.nodeId, + dropTarget.insertionIndex) + : windowWorkspaceController.DockPanelRelative( + panelWindowId, + sourceNodeId, + panelId, + targetWindow->GetWindowId(), + dropTarget.nodeId, + dropTarget.placement); + if (result.status != UIEditorWindowWorkspaceOperationStatus::Changed) { + LogRuntimeTrace("drag", "cross-window drop rejected: " + result.message); + return true; + } + + if (!CommitWindowWorkspaceMutation( + windowWorkspaceController, + {}, + screenPoint)) { + LogRuntimeTrace("drag", "failed to synchronize windows after cross-window drop"); + return true; + } + + if (EditorWindow* updatedTargetWindow = m_hostRuntime.FindWindow(targetWindow->GetWindowId()); + IsLiveInteractiveWindow(updatedTargetWindow)) { + SetForegroundWindow(updatedTargetWindow->GetHwnd()); + } + LogRuntimeTrace( + "drag", + "committed cross-window drop panel '" + panelId + + "' into window '" + std::string(targetWindow->GetWindowId()) + "'"); + return true; +} + +bool EditorWindowWorkspaceCoordinator::TryStartGlobalTabDrag( + EditorWindow& sourceWindow, + const EditorWindowPanelTransferRequest& request) { + if (!IsLiveInteractiveWindow(&sourceWindow)) { + LogRuntimeTrace("drag", "failed to start global tab drag: source window is closing"); + return false; + } + + POINT dragHotspot = BuildFallbackGlobalTabDragHotspot(); + TryResolveGlobalTabDragHotspot( + sourceWindow, + request.nodeId, + request.panelId, + request.screenPoint, + dragHotspot); + + const auto tryStartDetachedPanelGlobalDrag = + [this, &request, &dragHotspot]( + UIEditorWindowWorkspaceController& windowWorkspaceController, + const UIEditorWindowWorkspaceOperationResult& result) { + if (!CommitWindowWorkspaceMutation( + windowWorkspaceController, + result.targetWindowId, + request.screenPoint)) { + LogRuntimeTrace("drag", "failed to synchronize detached drag window state"); + return false; + } + + EditorWindow* detachedWindow = m_hostRuntime.FindWindow(result.targetWindowId); + if (!IsLiveInteractiveWindow(detachedWindow)) { + LogRuntimeTrace("drag", "detached drag window was not created."); + return false; + } + + BeginGlobalTabDragSession( + detachedWindow->GetWindowId(), + detachedWindow->GetWorkspaceController().GetWorkspace().root.nodeId, + request.panelId, + request.screenPoint, + dragHotspot); + UpdateGlobalTabDragOwnerWindowPosition(); + detachedWindow->AcquirePointerCapture( + EditorWindowPointerCaptureOwner::GlobalTabDrag); + SetForegroundWindow(detachedWindow->GetHwnd()); + LogRuntimeTrace( + "drag", + "started global tab drag by detaching panel '" + request.panelId + + "' into window '" + std::string(detachedWindow->GetWindowId()) + "'"); + return true; + }; + + UIEditorWindowWorkspaceController windowWorkspaceController = + BuildWorkspaceMutationController(); + const UIEditorWindowWorkspaceOperationResult result = + windowWorkspaceController.DetachPanelToNewWindow( + sourceWindow.GetWindowId(), + request.nodeId, + request.panelId); + if (result.status == UIEditorWindowWorkspaceOperationStatus::Changed) { + return tryStartDetachedPanelGlobalDrag(windowWorkspaceController, result); + } + + if (sourceWindow.IsPrimary()) { + LogRuntimeTrace( + "drag", + "failed to start global tab drag from primary window: " + result.message); + return false; + } + + sourceWindow.ResetInteractionState(); + if (result.status != UIEditorWindowWorkspaceOperationStatus::NoOp) { + LogRuntimeTrace( + "drag", + "failed to start global tab drag from detached window: " + result.message); + return false; + } + if (!CanStartGlobalTabDragFromWindow(sourceWindow, request.nodeId, request.panelId)) { + LogRuntimeTrace( + "drag", + "failed to start global tab drag from detached window: invalid source panel request"); + return false; + } + + BeginGlobalTabDragSession( + sourceWindow.GetWindowId(), + request.nodeId, + request.panelId, + request.screenPoint, + dragHotspot); + UpdateGlobalTabDragOwnerWindowPosition(); + sourceWindow.AcquirePointerCapture(EditorWindowPointerCaptureOwner::GlobalTabDrag); + LogRuntimeTrace( + "drag", + "started global tab drag from detached window '" + + std::string(sourceWindow.GetWindowId()) + + "' panel '" + request.panelId + "'"); + return true; +} + +bool EditorWindowWorkspaceCoordinator::TryProcessDetachRequest( + EditorWindow& sourceWindow, + const EditorWindowPanelTransferRequest& request) { + if (!IsLiveInteractiveWindow(&sourceWindow)) { + LogRuntimeTrace("detach", "detach request rejected: source window is closing"); + return false; + } + + const std::string sourceWindowId(sourceWindow.GetWindowId()); + UIEditorWindowWorkspaceController windowWorkspaceController = + BuildWorkspaceMutationController(); + const UIEditorWindowWorkspaceOperationResult result = + windowWorkspaceController.DetachPanelToNewWindow( + sourceWindowId, + request.nodeId, + request.panelId); + if (result.status != UIEditorWindowWorkspaceOperationStatus::Changed) { + LogRuntimeTrace("detach", "detach request rejected: " + result.message); + return false; + } + + if (!CommitWindowWorkspaceMutation( + windowWorkspaceController, + result.targetWindowId, + request.screenPoint)) { + LogRuntimeTrace("detach", "failed to synchronize detached window state"); + return false; + } + + if (EditorWindow* detachedWindow = m_hostRuntime.FindWindow(result.targetWindowId); + IsLiveInteractiveWindow(detachedWindow)) { + SetForegroundWindow(detachedWindow->GetHwnd()); + } + + LogRuntimeTrace( + "detach", + "detached panel '" + request.panelId + "' from window '" + sourceWindowId + + "' to window '" + result.targetWindowId + "'"); + return true; +} + +void EditorWindowWorkspaceCoordinator::HandleWindowFrameTransferRequests( + EditorWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests) { + if (!m_globalTabDragSession.active && + transferRequests.beginGlobalTabDrag.has_value() && + transferRequests.beginGlobalTabDrag->IsValid()) { + TryStartGlobalTabDrag(sourceWindow, *transferRequests.beginGlobalTabDrag); + } + + if (!m_globalTabDragSession.active && + transferRequests.detachPanel.has_value() && + transferRequests.detachPanel->IsValid()) { + TryProcessDetachRequest(sourceWindow, *transferRequests.detachPanel); + } +} + +EditorWindow* EditorWindowWorkspaceCoordinator::FindTopmostWindowAtScreenPoint( + const POINT& screenPoint, + std::string_view excludedWindowId) { + if (const HWND hitWindow = WindowFromPoint(screenPoint); hitWindow != nullptr) { + const HWND rootWindow = GetAncestor(hitWindow, GA_ROOT); + if (EditorWindow* window = m_hostRuntime.FindWindow(rootWindow); + IsLiveInteractiveWindow(window) && + window->GetWindowId() != excludedWindowId) { + return window; + } + } + + for (auto it = m_hostRuntime.GetWindows().rbegin(); it != m_hostRuntime.GetWindows().rend(); ++it) { + EditorWindow* const window = it->get(); + if (window == nullptr || + !IsLiveInteractiveWindow(window) || + window->GetWindowId() == excludedWindowId) { + continue; + } + + RECT windowRect = {}; + if (GetWindowRect(window->GetHwnd(), &windowRect) && + screenPoint.x >= windowRect.left && + screenPoint.x < windowRect.right && + screenPoint.y >= windowRect.top && + screenPoint.y < windowRect.bottom) { + return window; + } + } + + return nullptr; +} + +const EditorWindow* EditorWindowWorkspaceCoordinator::FindTopmostWindowAtScreenPoint( + const POINT& screenPoint, + std::string_view excludedWindowId) const { + return const_cast(this)->FindTopmostWindowAtScreenPoint( + screenPoint, + excludedWindowId); +} + +void EditorWindowWorkspaceCoordinator::LogRuntimeTrace( + std::string_view channel, + std::string_view message) const { + m_hostRuntime.LogRuntimeTrace(channel, message); +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h b/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h new file mode 100644 index 00000000..d61ffc78 --- /dev/null +++ b/editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h @@ -0,0 +1,108 @@ +#pragma once + +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#include "Composition/EditorWindowWorkspaceStore.h" +#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h" + +#include + +#include + +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorWindow; +class EditorWindowHostRuntime; +class EditorWindowLifecycleCoordinator; + +class EditorWindowWorkspaceCoordinator final { +public: + explicit EditorWindowWorkspaceCoordinator(EditorWindowHostRuntime& hostRuntime); + ~EditorWindowWorkspaceCoordinator(); + + void BindLifecycleCoordinator(EditorWindowLifecycleCoordinator& lifecycleCoordinator); + void RegisterExistingWindow(EditorWindow& window); + void RefreshWindowPresentation(EditorWindow& window) const; + bool IsPrimaryWindowId(std::string_view windowId) const; + std::string DescribeWindowSet() const; + void RemoveWindowProjection(std::string_view windowId, bool primary); + + bool IsGlobalTabDragActive() const; + bool OwnsActiveGlobalTabDrag(std::string_view windowId) const; + void EndGlobalTabDragSession(); + bool HandleGlobalTabDragPointerMove(HWND hwnd); + bool HandleGlobalTabDragPointerButtonUp(HWND hwnd); + void HandleWindowFrameTransferRequests( + EditorWindow& sourceWindow, + const EditorWindowFrameTransferRequests& transferRequests); + +private: + struct GlobalTabDragSession { + bool active = false; + std::string panelWindowId = {}; + std::string sourceNodeId = {}; + std::string panelId = {}; + std::string previewWindowId = {}; + POINT screenPoint = {}; + POINT dragHotspot = {}; + }; + + UIEditorWindowWorkspaceController BuildWorkspaceMutationController() const; + bool SynchronizeWindowsFromWindowSet( + const UIEditorWindowWorkspaceSet& windowSet, + std::string_view preferredNewWindowId, + const POINT& preferredScreenPoint, + LONG preferredWidth = 0, + LONG preferredHeight = 0); + bool CommitWindowWorkspaceMutation( + const UIEditorWindowWorkspaceController& windowWorkspaceController, + std::string_view preferredNewWindowId, + const POINT& preferredScreenPoint, + LONG preferredWidth = 0, + LONG preferredHeight = 0); + UIEditorWorkspaceController BuildWorkspaceControllerForWindow( + const UIEditorWindowWorkspaceState& windowState) const; + std::wstring BuildWindowTitle( + const UIEditorWorkspaceController& workspaceController) const; + void RefreshWindowTitle(EditorWindow& window) const; + void BeginGlobalTabDragSession( + std::string_view panelWindowId, + std::string_view sourceNodeId, + std::string_view panelId, + const POINT& screenPoint, + const POINT& dragHotspot); + bool TryResolveGlobalTabDragHotspot( + const EditorWindow& sourceWindow, + std::string_view nodeId, + std::string_view panelId, + const POINT& screenPoint, + POINT& outDragHotspot) const; + void ClearGlobalTabDragDropPreview(); + void UpdateGlobalTabDragDropPreview(); + void UpdateGlobalTabDragOwnerWindowPosition(); + EditorWindow* FindTopmostWindowAtScreenPoint( + const POINT& screenPoint, + std::string_view excludedWindowId = {}); + const EditorWindow* FindTopmostWindowAtScreenPoint( + const POINT& screenPoint, + std::string_view excludedWindowId = {}) const; + bool TryStartGlobalTabDrag( + EditorWindow& sourceWindow, + const EditorWindowPanelTransferRequest& request); + bool TryProcessDetachRequest( + EditorWindow& sourceWindow, + const EditorWindowPanelTransferRequest& request); + void LogRuntimeTrace(std::string_view channel, std::string_view message) const; + + EditorWindowHostRuntime& m_hostRuntime; + EditorWindowLifecycleCoordinator* m_lifecycleCoordinator = nullptr; + EditorWindowWorkspaceStore m_workspaceStore; + GlobalTabDragSession m_globalTabDragSession = {}; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Project/EditorProjectRuntime.cpp b/editor/app/Project/EditorProjectRuntime.cpp similarity index 100% rename from new_editor/app/Project/EditorProjectRuntime.cpp rename to editor/app/Project/EditorProjectRuntime.cpp diff --git a/new_editor/app/Project/EditorProjectRuntime.h b/editor/app/Project/EditorProjectRuntime.h similarity index 100% rename from new_editor/app/Project/EditorProjectRuntime.h rename to editor/app/Project/EditorProjectRuntime.h diff --git a/new_editor/app/Rendering/Assets/BuiltInIcons.cpp b/editor/app/Rendering/Assets/BuiltInIcons.cpp similarity index 100% rename from new_editor/app/Rendering/Assets/BuiltInIcons.cpp rename to editor/app/Rendering/Assets/BuiltInIcons.cpp diff --git a/new_editor/app/Rendering/Assets/BuiltInIcons.h b/editor/app/Rendering/Assets/BuiltInIcons.h similarity index 100% rename from new_editor/app/Rendering/Assets/BuiltInIcons.h rename to editor/app/Rendering/Assets/BuiltInIcons.h diff --git a/new_editor/app/Rendering/D3D12/D3D12HostDevice.cpp b/editor/app/Rendering/D3D12/D3D12HostDevice.cpp similarity index 70% rename from new_editor/app/Rendering/D3D12/D3D12HostDevice.cpp rename to editor/app/Rendering/D3D12/D3D12HostDevice.cpp index d23595dd..90a262ab 100644 --- a/new_editor/app/Rendering/D3D12/D3D12HostDevice.cpp +++ b/editor/app/Rendering/D3D12/D3D12HostDevice.cpp @@ -3,7 +3,6 @@ #include #include -#include namespace XCEngine::UI::Editor::Host { @@ -19,28 +18,6 @@ using ::XCEngine::RHI::RHIDeviceDesc; using ::XCEngine::RHI::RHIFactory; using ::XCEngine::RHI::RHIType; -namespace { - -constexpr DWORD kFrameWaitTimeoutMs = 1u; -constexpr DWORD kTrackedFrameRetirementTimeoutMs = 50u; -constexpr DWORD kGpuIdleWaitTimeoutMs = 2000u; - -std::string BuildFenceWaitError( - std::string_view scope, - std::uint64_t fenceValue, - DWORD timeoutMs, - DWORD waitResult) { - std::ostringstream stream = {}; - stream << scope - << " fence wait failed value=" << fenceValue - << " timeoutMs=" << timeoutMs - << " waitResult=0x" << std::hex << std::uppercase - << static_cast(waitResult); - return stream.str(); -} - -} // namespace - bool D3D12HostDevice::Initialize() { Shutdown(); @@ -184,9 +161,7 @@ using ::XCEngine::RHI::D3D12CommandList; using ::XCEngine::RHI::RHICommandList; bool D3D12HostDevice::BeginFrame(std::uint32_t frameIndex) { - if (!WaitForFrame(frameIndex)) { - return false; - } + WaitForFrame(frameIndex); RHICommandList* commandList = GetCommandList(frameIndex); D3D12CommandList* d3d12CommandList = GetD3D12CommandList(frameIndex); @@ -233,95 +208,36 @@ bool D3D12HostDevice::SignalFrameCompletion(std::uint32_t frameIndex) { return SUCCEEDED(hr); } -bool D3D12HostDevice::WaitForFrame(std::uint32_t frameIndex) { +void D3D12HostDevice::WaitForFrame(std::uint32_t frameIndex) { if (m_frameCompletionFence == nullptr || m_frameCompletionEvent == nullptr || frameIndex >= m_frameFenceValues.size()) { - m_lastError.clear(); - return true; + return; } const std::uint64_t fenceValue = m_frameFenceValues[frameIndex]; if (fenceValue == 0u || m_frameCompletionFence->GetCompletedValue() >= fenceValue) { - m_lastError.clear(); - return true; + return; } const HRESULT hr = m_frameCompletionFence->SetEventOnCompletion( fenceValue, m_frameCompletionEvent); - if (FAILED(hr)) { - std::ostringstream error = {}; - error << "BeginFrame failed to arm frame completion wait. hr=0x" - << std::hex << std::uppercase - << static_cast(hr); - m_lastError = error.str(); - AppendUIEditorRuntimeTrace("present", m_lastError); - return false; + if (SUCCEEDED(hr)) { + WaitForSingleObject(m_frameCompletionEvent, INFINITE); } - - const DWORD waitResult = WaitForSingleObject(m_frameCompletionEvent, kFrameWaitTimeoutMs); - if (waitResult == WAIT_OBJECT_0) { - m_lastError.clear(); - return true; - } - - m_lastError = BuildFenceWaitError( - "BeginFrame", - fenceValue, - kFrameWaitTimeoutMs, - waitResult); - AppendUIEditorRuntimeTrace("present", m_lastError); - return false; } -bool D3D12HostDevice::WaitForTrackedFrameRetirement() { +void D3D12HostDevice::WaitForTrackedFrameRetirement() { for (std::uint32_t frameIndex = 0u; frameIndex < m_frameFenceValues.size(); ++frameIndex) { - if (m_frameCompletionFence == nullptr || - m_frameCompletionEvent == nullptr) { - m_lastError.clear(); - return true; - } - - const std::uint64_t fenceValue = m_frameFenceValues[frameIndex]; - if (fenceValue == 0u || - m_frameCompletionFence->GetCompletedValue() >= fenceValue) { - continue; - } - - const HRESULT hr = m_frameCompletionFence->SetEventOnCompletion( - fenceValue, - m_frameCompletionEvent); - if (FAILED(hr)) { - std::ostringstream error = {}; - error << "WaitForTrackedFrameRetirement failed to arm fence wait. hr=0x" - << std::hex << std::uppercase - << static_cast(hr); - m_lastError = error.str(); - AppendUIEditorRuntimeTrace("present", m_lastError); - return false; - } - - const DWORD waitResult = - WaitForSingleObject(m_frameCompletionEvent, kTrackedFrameRetirementTimeoutMs); - if (waitResult != WAIT_OBJECT_0) { - m_lastError = BuildFenceWaitError( - "WaitForTrackedFrameRetirement", - fenceValue, - kTrackedFrameRetirementTimeoutMs, - waitResult); - AppendUIEditorRuntimeTrace("present", m_lastError); - return false; - } + WaitForFrame(frameIndex); } - m_lastError.clear(); - return true; } -bool D3D12HostDevice::WaitForGpuIdle() { +void D3D12HostDevice::WaitForGpuIdle() { { std::ostringstream stream = {}; stream << "D3D12HostDevice::WaitForGpuIdle begin queue=" @@ -341,8 +257,7 @@ bool D3D12HostDevice::WaitForGpuIdle() { AppendUIEditorRuntimeTrace( "window-close", "D3D12HostDevice::WaitForGpuIdle end via queue fallback"); - m_lastError.clear(); - return true; + return; } ++m_lastSubmittedFrameValue; @@ -355,42 +270,21 @@ bool D3D12HostDevice::WaitForGpuIdle() { stream << "D3D12HostDevice::WaitForGpuIdle signal failed hr=0x" << std::hex << std::uppercase << static_cast(signalHr); - m_lastError = stream.str(); - AppendUIEditorRuntimeTrace("window-close", m_lastError); - return false; + AppendUIEditorRuntimeTrace("window-close", stream.str()); + return; } if (m_frameCompletionFence->GetCompletedValue() >= fenceValue) { - m_lastError.clear(); - return true; + return; } const HRESULT waitHr = m_frameCompletionFence->SetEventOnCompletion( fenceValue, m_frameCompletionEvent); - if (FAILED(waitHr)) { - std::ostringstream error = {}; - error << "WaitForGpuIdle failed to arm fence wait. hr=0x" - << std::hex << std::uppercase - << static_cast(waitHr); - m_lastError = error.str(); - AppendUIEditorRuntimeTrace("window-close", m_lastError); - return false; - } - - const DWORD waitResult = WaitForSingleObject(m_frameCompletionEvent, kGpuIdleWaitTimeoutMs); - if (waitResult != WAIT_OBJECT_0) { - m_lastError = BuildFenceWaitError( - "WaitForGpuIdle", - fenceValue, - kGpuIdleWaitTimeoutMs, - waitResult); - AppendUIEditorRuntimeTrace("window-close", m_lastError); - return false; + if (SUCCEEDED(waitHr)) { + WaitForSingleObject(m_frameCompletionEvent, INFINITE); } AppendUIEditorRuntimeTrace("window-close", "D3D12HostDevice::WaitForGpuIdle end"); - m_lastError.clear(); - return true; } void D3D12HostDevice::ResetFrameTracking() { diff --git a/new_editor/app/Rendering/D3D12/D3D12HostDevice.h b/editor/app/Rendering/D3D12/D3D12HostDevice.h similarity index 94% rename from new_editor/app/Rendering/D3D12/D3D12HostDevice.h rename to editor/app/Rendering/D3D12/D3D12HostDevice.h index cbf2d04a..8458cc47 100644 --- a/new_editor/app/Rendering/D3D12/D3D12HostDevice.h +++ b/editor/app/Rendering/D3D12/D3D12HostDevice.h @@ -32,9 +32,9 @@ public: bool BeginFrame(std::uint32_t frameIndex); bool SubmitFrame(std::uint32_t frameIndex); bool SignalFrameCompletion(std::uint32_t frameIndex); - bool WaitForFrame(std::uint32_t frameIndex); - bool WaitForTrackedFrameRetirement(); - bool WaitForGpuIdle(); + void WaitForFrame(std::uint32_t frameIndex); + void WaitForTrackedFrameRetirement(); + void WaitForGpuIdle(); void ResetFrameTracking(); ID3D12Device* GetDevice() const; diff --git a/new_editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.cpp b/editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.cpp rename to editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.h b/editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.h rename to editor/app/Rendering/D3D12/D3D12ShaderResourceDescriptorAllocator.h diff --git a/new_editor/app/Rendering/D3D12/D3D12UiRenderer.cpp b/editor/app/Rendering/D3D12/D3D12UiRenderer.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiRenderer.cpp rename to editor/app/Rendering/D3D12/D3D12UiRenderer.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12UiRenderer.h b/editor/app/Rendering/D3D12/D3D12UiRenderer.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiRenderer.h rename to editor/app/Rendering/D3D12/D3D12UiRenderer.h diff --git a/new_editor/app/Rendering/D3D12/D3D12UiTextSystem.cpp b/editor/app/Rendering/D3D12/D3D12UiTextSystem.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiTextSystem.cpp rename to editor/app/Rendering/D3D12/D3D12UiTextSystem.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12UiTextSystem.h b/editor/app/Rendering/D3D12/D3D12UiTextSystem.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiTextSystem.h rename to editor/app/Rendering/D3D12/D3D12UiTextSystem.h diff --git a/new_editor/app/Rendering/D3D12/D3D12UiTextureHost.cpp b/editor/app/Rendering/D3D12/D3D12UiTextureHost.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiTextureHost.cpp rename to editor/app/Rendering/D3D12/D3D12UiTextureHost.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12UiTextureHost.h b/editor/app/Rendering/D3D12/D3D12UiTextureHost.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12UiTextureHost.h rename to editor/app/Rendering/D3D12/D3D12UiTextureHost.h diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowCapture.cpp b/editor/app/Rendering/D3D12/D3D12WindowCapture.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowCapture.cpp rename to editor/app/Rendering/D3D12/D3D12WindowCapture.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowCapture.h b/editor/app/Rendering/D3D12/D3D12WindowCapture.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowCapture.h rename to editor/app/Rendering/D3D12/D3D12WindowCapture.h diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowRenderLoop.cpp b/editor/app/Rendering/D3D12/D3D12WindowRenderLoop.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowRenderLoop.cpp rename to editor/app/Rendering/D3D12/D3D12WindowRenderLoop.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowRenderLoop.h b/editor/app/Rendering/D3D12/D3D12WindowRenderLoop.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowRenderLoop.h rename to editor/app/Rendering/D3D12/D3D12WindowRenderLoop.h diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowRenderer.cpp b/editor/app/Rendering/D3D12/D3D12WindowRenderer.cpp similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowRenderer.cpp rename to editor/app/Rendering/D3D12/D3D12WindowRenderer.cpp diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowRenderer.h b/editor/app/Rendering/D3D12/D3D12WindowRenderer.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowRenderer.h rename to editor/app/Rendering/D3D12/D3D12WindowRenderer.h diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp b/editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp similarity index 99% rename from new_editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp rename to editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp index b79ea959..efe7eebd 100644 --- a/new_editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp +++ b/editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.cpp @@ -350,10 +350,7 @@ bool D3D12WindowSwapChainPresenter::Resize(int width, int height) { } const auto waitBegin = std::chrono::steady_clock::now(); - if (!m_hostDevice->WaitForTrackedFrameRetirement()) { - m_lastError = m_hostDevice->GetLastError(); - return false; - } + m_hostDevice->WaitForTrackedFrameRetirement(); const auto waitEnd = std::chrono::steady_clock::now(); ReleaseBackBufferCommandReferences(); ReleaseBackBufferViews(); diff --git a/new_editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.h b/editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.h similarity index 100% rename from new_editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.h rename to editor/app/Rendering/D3D12/D3D12WindowSwapChainPresenter.h diff --git a/new_editor/app/Rendering/Host/HostFwd.h b/editor/app/Rendering/Host/HostFwd.h similarity index 100% rename from new_editor/app/Rendering/Host/HostFwd.h rename to editor/app/Rendering/Host/HostFwd.h diff --git a/new_editor/app/Rendering/Host/UiTextureHost.h b/editor/app/Rendering/Host/UiTextureHost.h similarity index 100% rename from new_editor/app/Rendering/Host/UiTextureHost.h rename to editor/app/Rendering/Host/UiTextureHost.h diff --git a/new_editor/app/Rendering/Host/ViewportRenderHost.h b/editor/app/Rendering/Host/ViewportRenderHost.h similarity index 100% rename from new_editor/app/Rendering/Host/ViewportRenderHost.h rename to editor/app/Rendering/Host/ViewportRenderHost.h diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp b/editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp rename to editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.cpp diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.h b/editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.h similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.h rename to editor/app/Rendering/Viewport/Passes/SceneViewportGridPass.h diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp b/editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp rename to editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.cpp diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.h b/editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.h similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.h rename to editor/app/Rendering/Viewport/Passes/SceneViewportSelectedHelpersPass.h diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp b/editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp rename to editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.cpp diff --git a/new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.h b/editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.h similarity index 100% rename from new_editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.h rename to editor/app/Rendering/Viewport/Passes/SceneViewportSelectionOutlinePass.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportPassSpecs.h b/editor/app/Rendering/Viewport/SceneViewportPassSpecs.h similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportPassSpecs.h rename to editor/app/Rendering/Viewport/SceneViewportPassSpecs.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.cpp b/editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.cpp rename to editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.cpp diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.h b/editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.h similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.h rename to editor/app/Rendering/Viewport/SceneViewportRenderPassBundle.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderPlan.h b/editor/app/Rendering/Viewport/SceneViewportRenderPlan.h similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderPlan.h rename to editor/app/Rendering/Viewport/SceneViewportRenderPlan.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderRequest.h b/editor/app/Rendering/Viewport/SceneViewportRenderRequest.h similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderRequest.h rename to editor/app/Rendering/Viewport/SceneViewportRenderRequest.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderService.cpp b/editor/app/Rendering/Viewport/SceneViewportRenderService.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderService.cpp rename to editor/app/Rendering/Viewport/SceneViewportRenderService.cpp diff --git a/new_editor/app/Rendering/Viewport/SceneViewportRenderService.h b/editor/app/Rendering/Viewport/SceneViewportRenderService.h similarity index 100% rename from new_editor/app/Rendering/Viewport/SceneViewportRenderService.h rename to editor/app/Rendering/Viewport/SceneViewportRenderService.h diff --git a/new_editor/app/Rendering/Viewport/SceneViewportResourcePaths.h b/editor/app/Rendering/Viewport/SceneViewportResourcePaths.h similarity index 98% rename from new_editor/app/Rendering/Viewport/SceneViewportResourcePaths.h rename to editor/app/Rendering/Viewport/SceneViewportResourcePaths.h index 3661159a..a12124d3 100644 --- a/new_editor/app/Rendering/Viewport/SceneViewportResourcePaths.h +++ b/editor/app/Rendering/Viewport/SceneViewportResourcePaths.h @@ -29,7 +29,7 @@ inline ::XCEngine::Containers::String BuildSceneViewportResourcePath( const std::filesystem::path& relativePath) { return NormalizeSceneViewportResourcePath( GetSceneViewportResourceRepoRootPath() / - "new_editor" / + "editor" / "resources" / relativePath); } diff --git a/new_editor/app/Rendering/Viewport/ViewportContentRenderer.h b/editor/app/Rendering/Viewport/ViewportContentRenderer.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportContentRenderer.h rename to editor/app/Rendering/Viewport/ViewportContentRenderer.h diff --git a/new_editor/app/Rendering/Viewport/ViewportHostService.cpp b/editor/app/Rendering/Viewport/ViewportHostService.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportHostService.cpp rename to editor/app/Rendering/Viewport/ViewportHostService.cpp diff --git a/new_editor/app/Rendering/Viewport/ViewportHostService.h b/editor/app/Rendering/Viewport/ViewportHostService.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportHostService.h rename to editor/app/Rendering/Viewport/ViewportHostService.h diff --git a/new_editor/app/Rendering/Viewport/ViewportObjectIdPicker.h b/editor/app/Rendering/Viewport/ViewportObjectIdPicker.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportObjectIdPicker.h rename to editor/app/Rendering/Viewport/ViewportObjectIdPicker.h diff --git a/new_editor/app/Rendering/Viewport/ViewportObjectPickerService.h b/editor/app/Rendering/Viewport/ViewportObjectPickerService.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportObjectPickerService.h rename to editor/app/Rendering/Viewport/ViewportObjectPickerService.h diff --git a/new_editor/app/Rendering/Viewport/ViewportRenderTargetUtils.cpp b/editor/app/Rendering/Viewport/ViewportRenderTargetUtils.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportRenderTargetUtils.cpp rename to editor/app/Rendering/Viewport/ViewportRenderTargetUtils.cpp diff --git a/new_editor/app/Rendering/Viewport/ViewportRenderTargetUtils.h b/editor/app/Rendering/Viewport/ViewportRenderTargetUtils.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportRenderTargetUtils.h rename to editor/app/Rendering/Viewport/ViewportRenderTargetUtils.h diff --git a/new_editor/app/Rendering/Viewport/ViewportRenderTargets.cpp b/editor/app/Rendering/Viewport/ViewportRenderTargets.cpp similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportRenderTargets.cpp rename to editor/app/Rendering/Viewport/ViewportRenderTargets.cpp diff --git a/new_editor/app/Rendering/Viewport/ViewportRenderTargets.h b/editor/app/Rendering/Viewport/ViewportRenderTargets.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportRenderTargets.h rename to editor/app/Rendering/Viewport/ViewportRenderTargets.h diff --git a/new_editor/app/Rendering/Viewport/ViewportTypes.h b/editor/app/Rendering/Viewport/ViewportTypes.h similarity index 100% rename from new_editor/app/Rendering/Viewport/ViewportTypes.h rename to editor/app/Rendering/Viewport/ViewportTypes.h diff --git a/new_editor/app/Scene/EditorSceneBridge.cpp b/editor/app/Scene/EditorSceneBridge.cpp similarity index 100% rename from new_editor/app/Scene/EditorSceneBridge.cpp rename to editor/app/Scene/EditorSceneBridge.cpp diff --git a/new_editor/app/Scene/EditorSceneBridge.h b/editor/app/Scene/EditorSceneBridge.h similarity index 100% rename from new_editor/app/Scene/EditorSceneBridge.h rename to editor/app/Scene/EditorSceneBridge.h diff --git a/new_editor/app/Scene/EditorSceneRuntime.cpp b/editor/app/Scene/EditorSceneRuntime.cpp similarity index 98% rename from new_editor/app/Scene/EditorSceneRuntime.cpp rename to editor/app/Scene/EditorSceneRuntime.cpp index 803d7ba8..3ebc3ca3 100644 --- a/new_editor/app/Scene/EditorSceneRuntime.cpp +++ b/editor/app/Scene/EditorSceneRuntime.cpp @@ -1,4 +1,4 @@ -#include "Scene/EditorSceneRuntime.h" +#include "Scene/EditorSceneRuntime.h" #include #include @@ -501,17 +501,17 @@ bool EditorSceneRuntime::MoveGameObjectToRoot(std::string_view itemId) { bool EditorSceneRuntime::AddComponentToSelectedGameObject( std::string_view componentTypeName) { - return AddComponentToGameObject(GetSelectedItemId(), componentTypeName); -} - -bool EditorSceneRuntime::AddComponentToGameObject( - std::string_view itemId, - std::string_view componentTypeName) { - if (itemId.empty() || componentTypeName.empty()) { + if (componentTypeName.empty()) { return false; } - GameObject* gameObject = FindGameObject(itemId); + const std::optional selectedId = GetSelectedGameObjectId(); + Scene* scene = GetActiveScene(); + if (!selectedId.has_value() || scene == nullptr) { + return false; + } + + GameObject* gameObject = scene->FindByID(selectedId.value()); if (gameObject == nullptr) { return false; } @@ -1071,4 +1071,3 @@ void EditorSceneRuntime::ClearInvalidToolInteractionState() { } } // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Scene/EditorSceneRuntime.h b/editor/app/Scene/EditorSceneRuntime.h similarity index 98% rename from new_editor/app/Scene/EditorSceneRuntime.h rename to editor/app/Scene/EditorSceneRuntime.h index 535ba7d2..c72fd5be 100644 --- a/new_editor/app/Scene/EditorSceneRuntime.h +++ b/editor/app/Scene/EditorSceneRuntime.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "Scene/EditorSceneBridge.h" #include "Scene/SceneViewportCameraController.h" @@ -101,9 +101,6 @@ public: std::string_view targetItemId); bool MoveGameObjectToRoot(std::string_view itemId); bool AddComponentToSelectedGameObject(std::string_view componentTypeName); - bool AddComponentToGameObject( - std::string_view itemId, - std::string_view componentTypeName); bool CanRemoveSelectedComponent(std::string_view componentId) const; bool RemoveSelectedComponent(std::string_view componentId); bool SetSelectedTransformLocalPosition( @@ -189,4 +186,3 @@ private: }; } // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Scene/SceneToolState.h b/editor/app/Scene/SceneToolState.h similarity index 100% rename from new_editor/app/Scene/SceneToolState.h rename to editor/app/Scene/SceneToolState.h diff --git a/new_editor/app/Scene/SceneViewportCameraController.h b/editor/app/Scene/SceneViewportCameraController.h similarity index 100% rename from new_editor/app/Scene/SceneViewportCameraController.h rename to editor/app/Scene/SceneViewportCameraController.h diff --git a/editor/app/State/EditorColorPickerToolState.cpp b/editor/app/State/EditorColorPickerToolState.cpp new file mode 100644 index 00000000..3f093623 --- /dev/null +++ b/editor/app/State/EditorColorPickerToolState.cpp @@ -0,0 +1,59 @@ +#include "State/EditorColorPickerToolState.h" + +#include + +namespace XCEngine::UI::Editor::App { + +namespace { + +bool AreColorsEqual( + const ::XCEngine::UI::UIColor& lhs, + const ::XCEngine::UI::UIColor& rhs) { + return lhs.r == rhs.r && + lhs.g == rhs.g && + lhs.b == rhs.b && + lhs.a == rhs.a; +} + +} // namespace + +void ResetEditorColorPickerToolState(EditorColorPickerToolState& state) { + state = {}; +} + +void OpenEditorColorPickerToolForInspectorField( + EditorColorPickerToolState& state, + std::string_view subjectKey, + std::string_view fieldId, + const ::XCEngine::UI::UIColor& color, + bool showAlpha) { + state.active = true; + state.showAlpha = showAlpha; + state.color = color; + state.inspectorTarget.subjectKey = std::string(subjectKey); + state.inspectorTarget.fieldId = std::string(fieldId); + ++state.revision; +} + +bool UpdateEditorColorPickerToolColor( + EditorColorPickerToolState& state, + const ::XCEngine::UI::UIColor& color) { + if (!state.active || AreColorsEqual(state.color, color)) { + return false; + } + + state.color = color; + ++state.revision; + return true; +} + +bool IsEditorColorPickerToolTarget( + const EditorColorPickerToolState& state, + std::string_view subjectKey, + std::string_view fieldId) { + return state.active && + state.inspectorTarget.subjectKey == subjectKey && + state.inspectorTarget.fieldId == fieldId; +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/State/EditorColorPickerToolState.h b/editor/app/State/EditorColorPickerToolState.h new file mode 100644 index 00000000..b9160786 --- /dev/null +++ b/editor/app/State/EditorColorPickerToolState.h @@ -0,0 +1,39 @@ +#pragma once + +#include + +#include +#include +#include + +namespace XCEngine::UI::Editor::App { + +struct EditorColorPickerInspectorTarget { + std::string subjectKey = {}; + std::string fieldId = {}; +}; + +struct EditorColorPickerToolState { + bool active = false; + bool showAlpha = true; + ::XCEngine::UI::UIColor color = {}; + EditorColorPickerInspectorTarget inspectorTarget = {}; + std::uint64_t revision = 0u; +}; + +void ResetEditorColorPickerToolState(EditorColorPickerToolState& state); +void OpenEditorColorPickerToolForInspectorField( + EditorColorPickerToolState& state, + std::string_view subjectKey, + std::string_view fieldId, + const ::XCEngine::UI::UIColor& color, + bool showAlpha); +bool UpdateEditorColorPickerToolColor( + EditorColorPickerToolState& state, + const ::XCEngine::UI::UIColor& color); +bool IsEditorColorPickerToolTarget( + const EditorColorPickerToolState& state, + std::string_view subjectKey, + std::string_view fieldId); + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/State/EditorCommandFocusService.h b/editor/app/State/EditorCommandFocusService.h similarity index 100% rename from new_editor/app/State/EditorCommandFocusService.h rename to editor/app/State/EditorCommandFocusService.h diff --git a/new_editor/app/State/EditorSelectionService.h b/editor/app/State/EditorSelectionService.h similarity index 100% rename from new_editor/app/State/EditorSelectionService.h rename to editor/app/State/EditorSelectionService.h diff --git a/new_editor/app/State/EditorSelectionStamp.h b/editor/app/State/EditorSelectionStamp.h similarity index 100% rename from new_editor/app/State/EditorSelectionStamp.h rename to editor/app/State/EditorSelectionStamp.h diff --git a/new_editor/app/State/EditorSession.cpp b/editor/app/State/EditorSession.cpp similarity index 100% rename from new_editor/app/State/EditorSession.cpp rename to editor/app/State/EditorSession.cpp diff --git a/new_editor/app/State/EditorSession.h b/editor/app/State/EditorSession.h similarity index 100% rename from new_editor/app/State/EditorSession.h rename to editor/app/State/EditorSession.h diff --git a/editor/app/State/EditorUtilityWindowRequestState.cpp b/editor/app/State/EditorUtilityWindowRequestState.cpp new file mode 100644 index 00000000..23dc9d7b --- /dev/null +++ b/editor/app/State/EditorUtilityWindowRequestState.cpp @@ -0,0 +1,26 @@ +#include "State/EditorUtilityWindowRequestState.h" + +namespace XCEngine::UI::Editor::App { + +void ResetEditorUtilityWindowRequestState(EditorUtilityWindowRequestState& state) { + state = {}; +} + +void RequestEditorUtilityWindow( + EditorUtilityWindowRequestState& state, + EditorUtilityWindowKind kind) { + if (kind == EditorUtilityWindowKind::None) { + return; + } + + state.pendingKind = kind; +} + +std::optional ConsumeEditorUtilityWindowRequest( + EditorUtilityWindowRequestState& state) { + const std::optional requestedKind = state.pendingKind; + state.pendingKind.reset(); + return requestedKind; +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/State/EditorUtilityWindowRequestState.h b/editor/app/State/EditorUtilityWindowRequestState.h new file mode 100644 index 00000000..b2059dcf --- /dev/null +++ b/editor/app/State/EditorUtilityWindowRequestState.h @@ -0,0 +1,20 @@ +#pragma once + +#include "UtilityWindows/EditorUtilityWindowKind.h" + +#include + +namespace XCEngine::UI::Editor::App { + +struct EditorUtilityWindowRequestState { + std::optional pendingKind = {}; +}; + +void ResetEditorUtilityWindowRequestState(EditorUtilityWindowRequestState& state); +void RequestEditorUtilityWindow( + EditorUtilityWindowRequestState& state, + EditorUtilityWindowKind kind); +std::optional ConsumeEditorUtilityWindowRequest( + EditorUtilityWindowRequestState& state); + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Support/EmbeddedPngLoader.cpp b/editor/app/Support/EmbeddedPngLoader.cpp similarity index 100% rename from new_editor/app/Support/EmbeddedPngLoader.cpp rename to editor/app/Support/EmbeddedPngLoader.cpp diff --git a/new_editor/app/Support/EmbeddedPngLoader.h b/editor/app/Support/EmbeddedPngLoader.h similarity index 100% rename from new_editor/app/Support/EmbeddedPngLoader.h rename to editor/app/Support/EmbeddedPngLoader.h diff --git a/new_editor/app/Support/EnvironmentFlags.h b/editor/app/Support/EnvironmentFlags.h similarity index 100% rename from new_editor/app/Support/EnvironmentFlags.h rename to editor/app/Support/EnvironmentFlags.h diff --git a/new_editor/app/Support/ExecutablePath.h b/editor/app/Support/ExecutablePath.h similarity index 100% rename from new_editor/app/Support/ExecutablePath.h rename to editor/app/Support/ExecutablePath.h diff --git a/new_editor/app/Support/StringEncoding.h b/editor/app/Support/StringEncoding.h similarity index 100% rename from new_editor/app/Support/StringEncoding.h rename to editor/app/Support/StringEncoding.h diff --git a/new_editor/app/Support/TextFormat.h b/editor/app/Support/TextFormat.h similarity index 100% rename from new_editor/app/Support/TextFormat.h rename to editor/app/Support/TextFormat.h diff --git a/new_editor/app/System/SystemInteractionService.h b/editor/app/System/SystemInteractionService.h similarity index 100% rename from new_editor/app/System/SystemInteractionService.h rename to editor/app/System/SystemInteractionService.h diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowType.h b/editor/app/UtilityWindows/EditorUtilityWindowKind.h similarity index 76% rename from new_editor/app/Windowing/Utility/EditorUtilityWindowType.h rename to editor/app/UtilityWindows/EditorUtilityWindowKind.h index 860624d9..cb8e3542 100644 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowType.h +++ b/editor/app/UtilityWindows/EditorUtilityWindowKind.h @@ -4,7 +4,7 @@ namespace XCEngine::UI::Editor::App { -enum class EditorUtilityWindowType : std::uint8_t { +enum class EditorUtilityWindowKind : std::uint8_t { None = 0, ColorPicker, AddComponent, diff --git a/editor/app/UtilityWindows/EditorUtilityWindowPanel.h b/editor/app/UtilityWindows/EditorUtilityWindowPanel.h new file mode 100644 index 00000000..5042f7d6 --- /dev/null +++ b/editor/app/UtilityWindows/EditorUtilityWindowPanel.h @@ -0,0 +1,34 @@ +#pragma once + +#include + +#include +#include + +namespace XCEngine::UI::Editor::App { + +class EditorContext; + +struct EditorUtilityWindowHostContext { + bool mounted = false; + ::XCEngine::UI::UIRect bounds = {}; + bool allowInteraction = false; + bool focused = false; + bool focusGained = false; + bool focusLost = false; +}; + +class EditorUtilityWindowPanel { +public: + virtual ~EditorUtilityWindowPanel() = default; + + virtual std::string_view GetDrawListId() const = 0; + virtual void ResetInteractionState() = 0; + virtual void Update( + EditorContext& context, + const EditorUtilityWindowHostContext& hostContext, + const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) = 0; + virtual void Append(::XCEngine::UI::UIDrawList& drawList) const = 0; +}; + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp b/editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp new file mode 100644 index 00000000..b317167e --- /dev/null +++ b/editor/app/UtilityWindows/EditorUtilityWindowRegistry.cpp @@ -0,0 +1,56 @@ +#include "UtilityWindows/EditorUtilityWindowRegistry.h" + +#include "Features/ColorPicker/ColorPickerPanel.h" +#include "Features/Inspector/AddComponentPanel.h" + +namespace XCEngine::UI::Editor::App { + +namespace { + +using ::XCEngine::UI::UISize; + +constexpr EditorUtilityWindowDescriptor kColorPickerUtilityWindowDescriptor = { + .kind = EditorUtilityWindowKind::ColorPicker, + .windowId = "utility.color-picker", + .title = L"Color Picker", + .preferredOuterSize = UISize(352.0f, 500.0f), + .minimumOuterSize = UISize(320.0f, 460.0f), +}; + +constexpr EditorUtilityWindowDescriptor kAddComponentUtilityWindowDescriptor = { + .kind = EditorUtilityWindowKind::AddComponent, + .windowId = "utility.add-component", + .title = L"Add Component", + .preferredOuterSize = UISize(352.0f, 500.0f), + .minimumOuterSize = UISize(320.0f, 460.0f), +}; + +} // namespace + +const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( + EditorUtilityWindowKind kind) { + switch (kind) { + case EditorUtilityWindowKind::ColorPicker: + return &kColorPickerUtilityWindowDescriptor; + case EditorUtilityWindowKind::AddComponent: + return &kAddComponentUtilityWindowDescriptor; + case EditorUtilityWindowKind::None: + default: + return nullptr; + } +} + +std::unique_ptr CreateEditorUtilityWindowPanel( + EditorUtilityWindowKind kind) { + switch (kind) { + case EditorUtilityWindowKind::ColorPicker: + return std::make_unique(); + case EditorUtilityWindowKind::AddComponent: + return std::make_unique(); + case EditorUtilityWindowKind::None: + default: + return nullptr; + } +} + +} // namespace XCEngine::UI::Editor::App diff --git a/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h b/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h new file mode 100644 index 00000000..50a8c776 --- /dev/null +++ b/editor/app/UtilityWindows/EditorUtilityWindowRegistry.h @@ -0,0 +1,27 @@ +#pragma once + +#include "UtilityWindows/EditorUtilityWindowKind.h" +#include "UtilityWindows/EditorUtilityWindowPanel.h" + +#include + +#include +#include + +namespace XCEngine::UI::Editor::App { + +struct EditorUtilityWindowDescriptor { + EditorUtilityWindowKind kind = EditorUtilityWindowKind::None; + std::string_view windowId = {}; + const wchar_t* title = L""; + ::XCEngine::UI::UISize preferredOuterSize = {}; + ::XCEngine::UI::UISize minimumOuterSize = {}; +}; + +const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( + EditorUtilityWindowKind kind); + +std::unique_ptr CreateEditorUtilityWindowPanel( + EditorUtilityWindowKind kind); + +} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/main.cpp b/editor/app/main.cpp similarity index 100% rename from new_editor/app/main.cpp rename to editor/app/main.cpp diff --git a/new_editor/include/XCEditor/Collections/UIEditorDragDropInteraction.h b/editor/include/XCEditor/Collections/UIEditorDragDropInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorDragDropInteraction.h rename to editor/include/XCEditor/Collections/UIEditorDragDropInteraction.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorFilterableTreeHost.h b/editor/include/XCEditor/Collections/UIEditorFilterableTreeHost.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorFilterableTreeHost.h rename to editor/include/XCEditor/Collections/UIEditorFilterableTreeHost.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorGridDragDrop.h b/editor/include/XCEditor/Collections/UIEditorGridDragDrop.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorGridDragDrop.h rename to editor/include/XCEditor/Collections/UIEditorGridDragDrop.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorInlineRenameSession.h b/editor/include/XCEditor/Collections/UIEditorInlineRenameSession.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorInlineRenameSession.h rename to editor/include/XCEditor/Collections/UIEditorInlineRenameSession.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorListView.h b/editor/include/XCEditor/Collections/UIEditorListView.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorListView.h rename to editor/include/XCEditor/Collections/UIEditorListView.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorListViewInteraction.h b/editor/include/XCEditor/Collections/UIEditorListViewInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorListViewInteraction.h rename to editor/include/XCEditor/Collections/UIEditorListViewInteraction.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorScrollView.h b/editor/include/XCEditor/Collections/UIEditorScrollView.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorScrollView.h rename to editor/include/XCEditor/Collections/UIEditorScrollView.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorScrollViewInteraction.h b/editor/include/XCEditor/Collections/UIEditorScrollViewInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorScrollViewInteraction.h rename to editor/include/XCEditor/Collections/UIEditorScrollViewInteraction.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorTabStrip.h b/editor/include/XCEditor/Collections/UIEditorTabStrip.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorTabStrip.h rename to editor/include/XCEditor/Collections/UIEditorTabStrip.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorTabStripInteraction.h b/editor/include/XCEditor/Collections/UIEditorTabStripInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorTabStripInteraction.h rename to editor/include/XCEditor/Collections/UIEditorTabStripInteraction.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorTreeDragDrop.h b/editor/include/XCEditor/Collections/UIEditorTreeDragDrop.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorTreeDragDrop.h rename to editor/include/XCEditor/Collections/UIEditorTreeDragDrop.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorTreeView.h b/editor/include/XCEditor/Collections/UIEditorTreeView.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorTreeView.h rename to editor/include/XCEditor/Collections/UIEditorTreeView.h diff --git a/new_editor/include/XCEditor/Collections/UIEditorTreeViewInteraction.h b/editor/include/XCEditor/Collections/UIEditorTreeViewInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Collections/UIEditorTreeViewInteraction.h rename to editor/include/XCEditor/Collections/UIEditorTreeViewInteraction.h diff --git a/new_editor/include/XCEditor/Docking/UIEditorDockHost.h b/editor/include/XCEditor/Docking/UIEditorDockHost.h similarity index 100% rename from new_editor/include/XCEditor/Docking/UIEditorDockHost.h rename to editor/include/XCEditor/Docking/UIEditorDockHost.h diff --git a/new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h b/editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h rename to editor/include/XCEditor/Docking/UIEditorDockHostInteraction.h diff --git a/new_editor/include/XCEditor/Docking/UIEditorDockHostTransfer.h b/editor/include/XCEditor/Docking/UIEditorDockHostTransfer.h similarity index 100% rename from new_editor/include/XCEditor/Docking/UIEditorDockHostTransfer.h rename to editor/include/XCEditor/Docking/UIEditorDockHostTransfer.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorAssetField.h b/editor/include/XCEditor/Fields/UIEditorAssetField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorAssetField.h rename to editor/include/XCEditor/Fields/UIEditorAssetField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorAssetFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorAssetFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorAssetFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorAssetFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorBoolField.h b/editor/include/XCEditor/Fields/UIEditorBoolField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorBoolField.h rename to editor/include/XCEditor/Fields/UIEditorBoolField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorBoolFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorBoolFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorBoolFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorBoolFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorColorField.h b/editor/include/XCEditor/Fields/UIEditorColorField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorColorField.h rename to editor/include/XCEditor/Fields/UIEditorColorField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorColorFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorColorFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorColorFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorColorFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorEditableFieldCore.h b/editor/include/XCEditor/Fields/UIEditorEditableFieldCore.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorEditableFieldCore.h rename to editor/include/XCEditor/Fields/UIEditorEditableFieldCore.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorEnumField.h b/editor/include/XCEditor/Fields/UIEditorEnumField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorEnumField.h rename to editor/include/XCEditor/Fields/UIEditorEnumField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorEnumFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorEnumFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorEnumFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorEnumFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorFieldStyle.h b/editor/include/XCEditor/Fields/UIEditorFieldStyle.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorFieldStyle.h rename to editor/include/XCEditor/Fields/UIEditorFieldStyle.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorNumberField.h b/editor/include/XCEditor/Fields/UIEditorNumberField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorNumberField.h rename to editor/include/XCEditor/Fields/UIEditorNumberField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorNumberFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorNumberFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorNumberFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorNumberFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorObjectField.h b/editor/include/XCEditor/Fields/UIEditorObjectField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorObjectField.h rename to editor/include/XCEditor/Fields/UIEditorObjectField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorObjectFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorObjectFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorObjectFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorObjectFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorPropertyGrid.h b/editor/include/XCEditor/Fields/UIEditorPropertyGrid.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorPropertyGrid.h rename to editor/include/XCEditor/Fields/UIEditorPropertyGrid.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorPropertyGridInteraction.h b/editor/include/XCEditor/Fields/UIEditorPropertyGridInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorPropertyGridInteraction.h rename to editor/include/XCEditor/Fields/UIEditorPropertyGridInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorTextField.h b/editor/include/XCEditor/Fields/UIEditorTextField.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorTextField.h rename to editor/include/XCEditor/Fields/UIEditorTextField.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorTextFieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorTextFieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorTextFieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorTextFieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector2Field.h b/editor/include/XCEditor/Fields/UIEditorVector2Field.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector2Field.h rename to editor/include/XCEditor/Fields/UIEditorVector2Field.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector2FieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorVector2FieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector2FieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorVector2FieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector3Field.h b/editor/include/XCEditor/Fields/UIEditorVector3Field.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector3Field.h rename to editor/include/XCEditor/Fields/UIEditorVector3Field.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector3FieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorVector3FieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector3FieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorVector3FieldInteraction.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector4Field.h b/editor/include/XCEditor/Fields/UIEditorVector4Field.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector4Field.h rename to editor/include/XCEditor/Fields/UIEditorVector4Field.h diff --git a/new_editor/include/XCEditor/Fields/UIEditorVector4FieldInteraction.h b/editor/include/XCEditor/Fields/UIEditorVector4FieldInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Fields/UIEditorVector4FieldInteraction.h rename to editor/include/XCEditor/Fields/UIEditorVector4FieldInteraction.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorCommandDispatcher.h b/editor/include/XCEditor/Foundation/UIEditorCommandDispatcher.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorCommandDispatcher.h rename to editor/include/XCEditor/Foundation/UIEditorCommandDispatcher.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorCommandRegistry.h b/editor/include/XCEditor/Foundation/UIEditorCommandRegistry.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorCommandRegistry.h rename to editor/include/XCEditor/Foundation/UIEditorCommandRegistry.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorPanelInputFilter.h b/editor/include/XCEditor/Foundation/UIEditorPanelInputFilter.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorPanelInputFilter.h rename to editor/include/XCEditor/Foundation/UIEditorPanelInputFilter.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorRuntimeTrace.h b/editor/include/XCEditor/Foundation/UIEditorRuntimeTrace.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorRuntimeTrace.h rename to editor/include/XCEditor/Foundation/UIEditorRuntimeTrace.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorShortcutManager.h b/editor/include/XCEditor/Foundation/UIEditorShortcutManager.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorShortcutManager.h rename to editor/include/XCEditor/Foundation/UIEditorShortcutManager.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorTextLayout.h b/editor/include/XCEditor/Foundation/UIEditorTextLayout.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorTextLayout.h rename to editor/include/XCEditor/Foundation/UIEditorTextLayout.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorTextMeasurement.h b/editor/include/XCEditor/Foundation/UIEditorTextMeasurement.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorTextMeasurement.h rename to editor/include/XCEditor/Foundation/UIEditorTextMeasurement.h diff --git a/new_editor/include/XCEditor/Foundation/UIEditorTheme.h b/editor/include/XCEditor/Foundation/UIEditorTheme.h similarity index 100% rename from new_editor/include/XCEditor/Foundation/UIEditorTheme.h rename to editor/include/XCEditor/Foundation/UIEditorTheme.h diff --git a/new_editor/include/XCEditor/Menu/UIEditorMenuBar.h b/editor/include/XCEditor/Menu/UIEditorMenuBar.h similarity index 100% rename from new_editor/include/XCEditor/Menu/UIEditorMenuBar.h rename to editor/include/XCEditor/Menu/UIEditorMenuBar.h diff --git a/new_editor/include/XCEditor/Menu/UIEditorMenuModel.h b/editor/include/XCEditor/Menu/UIEditorMenuModel.h similarity index 100% rename from new_editor/include/XCEditor/Menu/UIEditorMenuModel.h rename to editor/include/XCEditor/Menu/UIEditorMenuModel.h diff --git a/new_editor/include/XCEditor/Menu/UIEditorMenuPopup.h b/editor/include/XCEditor/Menu/UIEditorMenuPopup.h similarity index 100% rename from new_editor/include/XCEditor/Menu/UIEditorMenuPopup.h rename to editor/include/XCEditor/Menu/UIEditorMenuPopup.h diff --git a/new_editor/include/XCEditor/Menu/UIEditorMenuSession.h b/editor/include/XCEditor/Menu/UIEditorMenuSession.h similarity index 100% rename from new_editor/include/XCEditor/Menu/UIEditorMenuSession.h rename to editor/include/XCEditor/Menu/UIEditorMenuSession.h diff --git a/new_editor/include/XCEditor/Panels/UIEditorHostedPanelDispatch.h b/editor/include/XCEditor/Panels/UIEditorHostedPanelDispatch.h similarity index 100% rename from new_editor/include/XCEditor/Panels/UIEditorHostedPanelDispatch.h rename to editor/include/XCEditor/Panels/UIEditorHostedPanelDispatch.h diff --git a/new_editor/include/XCEditor/Panels/UIEditorPanelContentHost.h b/editor/include/XCEditor/Panels/UIEditorPanelContentHost.h similarity index 100% rename from new_editor/include/XCEditor/Panels/UIEditorPanelContentHost.h rename to editor/include/XCEditor/Panels/UIEditorPanelContentHost.h diff --git a/new_editor/include/XCEditor/Panels/UIEditorPanelFrame.h b/editor/include/XCEditor/Panels/UIEditorPanelFrame.h similarity index 100% rename from new_editor/include/XCEditor/Panels/UIEditorPanelFrame.h rename to editor/include/XCEditor/Panels/UIEditorPanelFrame.h diff --git a/new_editor/include/XCEditor/Panels/UIEditorPanelHostLifecycle.h b/editor/include/XCEditor/Panels/UIEditorPanelHostLifecycle.h similarity index 100% rename from new_editor/include/XCEditor/Panels/UIEditorPanelHostLifecycle.h rename to editor/include/XCEditor/Panels/UIEditorPanelHostLifecycle.h diff --git a/new_editor/include/XCEditor/Panels/UIEditorPanelRegistry.h b/editor/include/XCEditor/Panels/UIEditorPanelRegistry.h similarity index 100% rename from new_editor/include/XCEditor/Panels/UIEditorPanelRegistry.h rename to editor/include/XCEditor/Panels/UIEditorPanelRegistry.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorShellAsset.h b/editor/include/XCEditor/Shell/UIEditorShellAsset.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorShellAsset.h rename to editor/include/XCEditor/Shell/UIEditorShellAsset.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorShellCapturePolicy.h b/editor/include/XCEditor/Shell/UIEditorShellCapturePolicy.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorShellCapturePolicy.h rename to editor/include/XCEditor/Shell/UIEditorShellCapturePolicy.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorShellCompose.h b/editor/include/XCEditor/Shell/UIEditorShellCompose.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorShellCompose.h rename to editor/include/XCEditor/Shell/UIEditorShellCompose.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorShellInteraction.h b/editor/include/XCEditor/Shell/UIEditorShellInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorShellInteraction.h rename to editor/include/XCEditor/Shell/UIEditorShellInteraction.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorStatusBar.h b/editor/include/XCEditor/Shell/UIEditorStatusBar.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorStatusBar.h rename to editor/include/XCEditor/Shell/UIEditorStatusBar.h diff --git a/new_editor/include/XCEditor/Shell/UIEditorStructuredShell.h b/editor/include/XCEditor/Shell/UIEditorStructuredShell.h similarity index 100% rename from new_editor/include/XCEditor/Shell/UIEditorStructuredShell.h rename to editor/include/XCEditor/Shell/UIEditorStructuredShell.h diff --git a/new_editor/include/XCEditor/Viewport/UIEditorViewportInputBridge.h b/editor/include/XCEditor/Viewport/UIEditorViewportInputBridge.h similarity index 100% rename from new_editor/include/XCEditor/Viewport/UIEditorViewportInputBridge.h rename to editor/include/XCEditor/Viewport/UIEditorViewportInputBridge.h diff --git a/new_editor/include/XCEditor/Viewport/UIEditorViewportShell.h b/editor/include/XCEditor/Viewport/UIEditorViewportShell.h similarity index 100% rename from new_editor/include/XCEditor/Viewport/UIEditorViewportShell.h rename to editor/include/XCEditor/Viewport/UIEditorViewportShell.h diff --git a/new_editor/include/XCEditor/Viewport/UIEditorViewportSlot.h b/editor/include/XCEditor/Viewport/UIEditorViewportSlot.h similarity index 100% rename from new_editor/include/XCEditor/Viewport/UIEditorViewportSlot.h rename to editor/include/XCEditor/Viewport/UIEditorViewportSlot.h diff --git a/new_editor/include/XCEditor/Widgets/UIEditorCollectionPrimitives.h b/editor/include/XCEditor/Widgets/UIEditorCollectionPrimitives.h similarity index 100% rename from new_editor/include/XCEditor/Widgets/UIEditorCollectionPrimitives.h rename to editor/include/XCEditor/Widgets/UIEditorCollectionPrimitives.h diff --git a/new_editor/include/XCEditor/Widgets/UIEditorColorUtils.h b/editor/include/XCEditor/Widgets/UIEditorColorUtils.h similarity index 100% rename from new_editor/include/XCEditor/Widgets/UIEditorColorUtils.h rename to editor/include/XCEditor/Widgets/UIEditorColorUtils.h diff --git a/new_editor/include/XCEditor/Widgets/UIEditorFieldRowLayout.h b/editor/include/XCEditor/Widgets/UIEditorFieldRowLayout.h similarity index 100% rename from new_editor/include/XCEditor/Widgets/UIEditorFieldRowLayout.h rename to editor/include/XCEditor/Widgets/UIEditorFieldRowLayout.h diff --git a/new_editor/include/XCEditor/Widgets/UIEditorTextLayout.h b/editor/include/XCEditor/Widgets/UIEditorTextLayout.h similarity index 100% rename from new_editor/include/XCEditor/Widgets/UIEditorTextLayout.h rename to editor/include/XCEditor/Widgets/UIEditorTextLayout.h diff --git a/new_editor/app/Windowing/Workspace/UIEditorDetachedWindowPolicy.h b/editor/include/XCEditor/Workspace/UIEditorDetachedWindowPolicy.h similarity index 100% rename from new_editor/app/Windowing/Workspace/UIEditorDetachedWindowPolicy.h rename to editor/include/XCEditor/Workspace/UIEditorDetachedWindowPolicy.h diff --git a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.h b/editor/include/XCEditor/Workspace/UIEditorWindowWorkspaceController.h similarity index 97% rename from new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.h rename to editor/include/XCEditor/Workspace/UIEditorWindowWorkspaceController.h index 70135ad6..70ae3014 100644 --- a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.h +++ b/editor/include/XCEditor/Workspace/UIEditorWindowWorkspaceController.h @@ -1,6 +1,6 @@ #pragma once -#include "UIEditorWindowWorkspaceModel.h" +#include #include #include diff --git a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceModel.h b/editor/include/XCEditor/Workspace/UIEditorWindowWorkspaceModel.h similarity index 100% rename from new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceModel.h rename to editor/include/XCEditor/Workspace/UIEditorWindowWorkspaceModel.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceCompose.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceController.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInputOwner.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceInputOwner.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInputOwner.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceInputOwner.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceInteraction.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceLayoutPersistence.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceLayoutPersistence.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceLayoutPersistence.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceLayoutPersistence.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceModel.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceModel.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceModel.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceModel.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceMutation.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceMutation.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceMutation.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceMutation.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceQueries.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceQueries.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceQueries.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceQueries.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceSession.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceSession.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceSession.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceSession.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceSplitterDragCorrection.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceSplitterDragCorrection.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceSplitterDragCorrection.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceSplitterDragCorrection.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceTransfer.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceTransfer.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceTransfer.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceTransfer.h diff --git a/new_editor/include/XCEditor/Workspace/UIEditorWorkspaceValidation.h b/editor/include/XCEditor/Workspace/UIEditorWorkspaceValidation.h similarity index 100% rename from new_editor/include/XCEditor/Workspace/UIEditorWorkspaceValidation.h rename to editor/include/XCEditor/Workspace/UIEditorWorkspaceValidation.h diff --git a/new_editor/resources/Icons/camera_gizmo.png b/editor/resources/Icons/camera_gizmo.png similarity index 100% rename from new_editor/resources/Icons/camera_gizmo.png rename to editor/resources/Icons/camera_gizmo.png diff --git a/new_editor/resources/Icons/directional_light_gizmo.png b/editor/resources/Icons/directional_light_gizmo.png similarity index 100% rename from new_editor/resources/Icons/directional_light_gizmo.png rename to editor/resources/Icons/directional_light_gizmo.png diff --git a/new_editor/resources/Icons/folder_icon.png b/editor/resources/Icons/folder_icon.png similarity index 100% rename from new_editor/resources/Icons/folder_icon.png rename to editor/resources/Icons/folder_icon.png diff --git a/new_editor/resources/Icons/gameobject_icon.png b/editor/resources/Icons/gameobject_icon.png similarity index 100% rename from new_editor/resources/Icons/gameobject_icon.png rename to editor/resources/Icons/gameobject_icon.png diff --git a/new_editor/resources/Icons/logo.ico b/editor/resources/Icons/logo.ico similarity index 100% rename from new_editor/resources/Icons/logo.ico rename to editor/resources/Icons/logo.ico diff --git a/new_editor/resources/Icons/logo.png b/editor/resources/Icons/logo.png similarity index 100% rename from new_editor/resources/Icons/logo.png rename to editor/resources/Icons/logo.png diff --git a/new_editor/resources/Icons/logo_icon.ico b/editor/resources/Icons/logo_icon.ico similarity index 100% rename from new_editor/resources/Icons/logo_icon.ico rename to editor/resources/Icons/logo_icon.ico diff --git a/new_editor/resources/Icons/logo_icon.png b/editor/resources/Icons/logo_icon.png similarity index 100% rename from new_editor/resources/Icons/logo_icon.png rename to editor/resources/Icons/logo_icon.png diff --git a/new_editor/resources/Icons/move_tool.png b/editor/resources/Icons/move_tool.png similarity index 100% rename from new_editor/resources/Icons/move_tool.png rename to editor/resources/Icons/move_tool.png diff --git a/new_editor/resources/Icons/move_tool_on.png b/editor/resources/Icons/move_tool_on.png similarity index 100% rename from new_editor/resources/Icons/move_tool_on.png rename to editor/resources/Icons/move_tool_on.png diff --git a/new_editor/resources/Icons/pause_button.png b/editor/resources/Icons/pause_button.png similarity index 100% rename from new_editor/resources/Icons/pause_button.png rename to editor/resources/Icons/pause_button.png diff --git a/new_editor/resources/Icons/play_button.png b/editor/resources/Icons/play_button.png similarity index 100% rename from new_editor/resources/Icons/play_button.png rename to editor/resources/Icons/play_button.png diff --git a/new_editor/resources/Icons/point_light_gizmo.png b/editor/resources/Icons/point_light_gizmo.png similarity index 100% rename from new_editor/resources/Icons/point_light_gizmo.png rename to editor/resources/Icons/point_light_gizmo.png diff --git a/new_editor/resources/Icons/rotate_tool.png b/editor/resources/Icons/rotate_tool.png similarity index 100% rename from new_editor/resources/Icons/rotate_tool.png rename to editor/resources/Icons/rotate_tool.png diff --git a/new_editor/resources/Icons/rotate_tool_on.png b/editor/resources/Icons/rotate_tool_on.png similarity index 100% rename from new_editor/resources/Icons/rotate_tool_on.png rename to editor/resources/Icons/rotate_tool_on.png diff --git a/new_editor/resources/Icons/scale_tool.png b/editor/resources/Icons/scale_tool.png similarity index 100% rename from new_editor/resources/Icons/scale_tool.png rename to editor/resources/Icons/scale_tool.png diff --git a/new_editor/resources/Icons/scale_tool_on.png b/editor/resources/Icons/scale_tool_on.png similarity index 100% rename from new_editor/resources/Icons/scale_tool_on.png rename to editor/resources/Icons/scale_tool_on.png diff --git a/new_editor/resources/Icons/scene_icon.png b/editor/resources/Icons/scene_icon.png similarity index 100% rename from new_editor/resources/Icons/scene_icon.png rename to editor/resources/Icons/scene_icon.png diff --git a/new_editor/resources/Icons/spot_light_gizmo.png b/editor/resources/Icons/spot_light_gizmo.png similarity index 100% rename from new_editor/resources/Icons/spot_light_gizmo.png rename to editor/resources/Icons/spot_light_gizmo.png diff --git a/new_editor/resources/Icons/step_button.png b/editor/resources/Icons/step_button.png similarity index 100% rename from new_editor/resources/Icons/step_button.png rename to editor/resources/Icons/step_button.png diff --git a/new_editor/resources/Icons/transform_tool.png b/editor/resources/Icons/transform_tool.png similarity index 100% rename from new_editor/resources/Icons/transform_tool.png rename to editor/resources/Icons/transform_tool.png diff --git a/new_editor/resources/Icons/transform_tool_on.png b/editor/resources/Icons/transform_tool_on.png similarity index 100% rename from new_editor/resources/Icons/transform_tool_on.png rename to editor/resources/Icons/transform_tool_on.png diff --git a/new_editor/resources/Icons/view_move_tool.png b/editor/resources/Icons/view_move_tool.png similarity index 100% rename from new_editor/resources/Icons/view_move_tool.png rename to editor/resources/Icons/view_move_tool.png diff --git a/new_editor/resources/Icons/view_move_tool_on.png b/editor/resources/Icons/view_move_tool_on.png similarity index 100% rename from new_editor/resources/Icons/view_move_tool_on.png rename to editor/resources/Icons/view_move_tool_on.png diff --git a/new_editor/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader b/editor/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader similarity index 100% rename from new_editor/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader rename to editor/resources/shaders/scene-viewport/infinite-grid/infinite-grid.shader diff --git a/new_editor/resources/shaders/scene-viewport/selection-mask/selection-mask.shader b/editor/resources/shaders/scene-viewport/selection-mask/selection-mask.shader similarity index 100% rename from new_editor/resources/shaders/scene-viewport/selection-mask/selection-mask.shader rename to editor/resources/shaders/scene-viewport/selection-mask/selection-mask.shader diff --git a/new_editor/resources/shaders/scene-viewport/selection-outline/selection-outline.shader b/editor/resources/shaders/scene-viewport/selection-outline/selection-outline.shader similarity index 100% rename from new_editor/resources/shaders/scene-viewport/selection-outline/selection-outline.shader rename to editor/resources/shaders/scene-viewport/selection-outline/selection-outline.shader diff --git a/new_editor/src/Collections/UIEditorFilterableTreeHost.cpp b/editor/src/Collections/UIEditorFilterableTreeHost.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorFilterableTreeHost.cpp rename to editor/src/Collections/UIEditorFilterableTreeHost.cpp diff --git a/new_editor/src/Collections/UIEditorInlineRenameSession.cpp b/editor/src/Collections/UIEditorInlineRenameSession.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorInlineRenameSession.cpp rename to editor/src/Collections/UIEditorInlineRenameSession.cpp diff --git a/new_editor/src/Collections/UIEditorListView.cpp b/editor/src/Collections/UIEditorListView.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorListView.cpp rename to editor/src/Collections/UIEditorListView.cpp diff --git a/new_editor/src/Collections/UIEditorListViewInteraction.cpp b/editor/src/Collections/UIEditorListViewInteraction.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorListViewInteraction.cpp rename to editor/src/Collections/UIEditorListViewInteraction.cpp diff --git a/new_editor/src/Collections/UIEditorScrollView.cpp b/editor/src/Collections/UIEditorScrollView.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorScrollView.cpp rename to editor/src/Collections/UIEditorScrollView.cpp diff --git a/new_editor/src/Collections/UIEditorScrollViewInteraction.cpp b/editor/src/Collections/UIEditorScrollViewInteraction.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorScrollViewInteraction.cpp rename to editor/src/Collections/UIEditorScrollViewInteraction.cpp diff --git a/new_editor/src/Collections/UIEditorTabStrip.cpp b/editor/src/Collections/UIEditorTabStrip.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorTabStrip.cpp rename to editor/src/Collections/UIEditorTabStrip.cpp diff --git a/new_editor/src/Collections/UIEditorTabStripInteraction.cpp b/editor/src/Collections/UIEditorTabStripInteraction.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorTabStripInteraction.cpp rename to editor/src/Collections/UIEditorTabStripInteraction.cpp diff --git a/new_editor/src/Collections/UIEditorTreeView.cpp b/editor/src/Collections/UIEditorTreeView.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorTreeView.cpp rename to editor/src/Collections/UIEditorTreeView.cpp diff --git a/new_editor/src/Collections/UIEditorTreeViewInteraction.cpp b/editor/src/Collections/UIEditorTreeViewInteraction.cpp similarity index 100% rename from new_editor/src/Collections/UIEditorTreeViewInteraction.cpp rename to editor/src/Collections/UIEditorTreeViewInteraction.cpp diff --git a/new_editor/src/Docking/DockHostHitTest.cpp b/editor/src/Docking/DockHostHitTest.cpp similarity index 100% rename from new_editor/src/Docking/DockHostHitTest.cpp rename to editor/src/Docking/DockHostHitTest.cpp diff --git a/new_editor/src/Docking/DockHostInteractionHelpers.cpp b/editor/src/Docking/DockHostInteractionHelpers.cpp similarity index 100% rename from new_editor/src/Docking/DockHostInteractionHelpers.cpp rename to editor/src/Docking/DockHostInteractionHelpers.cpp diff --git a/new_editor/src/Docking/DockHostInteractionInternal.h b/editor/src/Docking/DockHostInteractionInternal.h similarity index 100% rename from new_editor/src/Docking/DockHostInteractionInternal.h rename to editor/src/Docking/DockHostInteractionInternal.h diff --git a/new_editor/src/Docking/DockHostMeasure.cpp b/editor/src/Docking/DockHostMeasure.cpp similarity index 100% rename from new_editor/src/Docking/DockHostMeasure.cpp rename to editor/src/Docking/DockHostMeasure.cpp diff --git a/new_editor/src/Docking/DockHostMeasureInternal.h b/editor/src/Docking/DockHostMeasureInternal.h similarity index 100% rename from new_editor/src/Docking/DockHostMeasureInternal.h rename to editor/src/Docking/DockHostMeasureInternal.h diff --git a/new_editor/src/Docking/DockHostRendering.cpp b/editor/src/Docking/DockHostRendering.cpp similarity index 100% rename from new_editor/src/Docking/DockHostRendering.cpp rename to editor/src/Docking/DockHostRendering.cpp diff --git a/new_editor/src/Docking/UIEditorDockHost.cpp b/editor/src/Docking/UIEditorDockHost.cpp similarity index 100% rename from new_editor/src/Docking/UIEditorDockHost.cpp rename to editor/src/Docking/UIEditorDockHost.cpp diff --git a/new_editor/src/Docking/UIEditorDockHostInteraction.cpp b/editor/src/Docking/UIEditorDockHostInteraction.cpp similarity index 100% rename from new_editor/src/Docking/UIEditorDockHostInteraction.cpp rename to editor/src/Docking/UIEditorDockHostInteraction.cpp diff --git a/new_editor/src/Docking/UIEditorDockHostTransfer.cpp b/editor/src/Docking/UIEditorDockHostTransfer.cpp similarity index 100% rename from new_editor/src/Docking/UIEditorDockHostTransfer.cpp rename to editor/src/Docking/UIEditorDockHostTransfer.cpp diff --git a/new_editor/src/Fields/ColorFieldInternal.h b/editor/src/Fields/ColorFieldInternal.h similarity index 100% rename from new_editor/src/Fields/ColorFieldInternal.h rename to editor/src/Fields/ColorFieldInternal.h diff --git a/new_editor/src/Fields/ColorFieldRendering.cpp b/editor/src/Fields/ColorFieldRendering.cpp similarity index 100% rename from new_editor/src/Fields/ColorFieldRendering.cpp rename to editor/src/Fields/ColorFieldRendering.cpp diff --git a/new_editor/src/Fields/PropertyGridInteractionInternal.h b/editor/src/Fields/PropertyGridInteractionInternal.h similarity index 100% rename from new_editor/src/Fields/PropertyGridInteractionInternal.h rename to editor/src/Fields/PropertyGridInteractionInternal.h diff --git a/new_editor/src/Fields/PropertyGridInternal.h b/editor/src/Fields/PropertyGridInternal.h similarity index 100% rename from new_editor/src/Fields/PropertyGridInternal.h rename to editor/src/Fields/PropertyGridInternal.h diff --git a/new_editor/src/Fields/UIEditorAssetField.cpp b/editor/src/Fields/UIEditorAssetField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorAssetField.cpp rename to editor/src/Fields/UIEditorAssetField.cpp diff --git a/new_editor/src/Fields/UIEditorAssetFieldInteraction.cpp b/editor/src/Fields/UIEditorAssetFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorAssetFieldInteraction.cpp rename to editor/src/Fields/UIEditorAssetFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorBoolField.cpp b/editor/src/Fields/UIEditorBoolField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorBoolField.cpp rename to editor/src/Fields/UIEditorBoolField.cpp diff --git a/new_editor/src/Fields/UIEditorBoolFieldInteraction.cpp b/editor/src/Fields/UIEditorBoolFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorBoolFieldInteraction.cpp rename to editor/src/Fields/UIEditorBoolFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorColorField.cpp b/editor/src/Fields/UIEditorColorField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorColorField.cpp rename to editor/src/Fields/UIEditorColorField.cpp diff --git a/new_editor/src/Fields/UIEditorColorFieldInteraction.cpp b/editor/src/Fields/UIEditorColorFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorColorFieldInteraction.cpp rename to editor/src/Fields/UIEditorColorFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorEditableFieldCore.cpp b/editor/src/Fields/UIEditorEditableFieldCore.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorEditableFieldCore.cpp rename to editor/src/Fields/UIEditorEditableFieldCore.cpp diff --git a/new_editor/src/Fields/UIEditorEnumField.cpp b/editor/src/Fields/UIEditorEnumField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorEnumField.cpp rename to editor/src/Fields/UIEditorEnumField.cpp diff --git a/new_editor/src/Fields/UIEditorEnumFieldInteraction.cpp b/editor/src/Fields/UIEditorEnumFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorEnumFieldInteraction.cpp rename to editor/src/Fields/UIEditorEnumFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorFieldStyle.cpp b/editor/src/Fields/UIEditorFieldStyle.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorFieldStyle.cpp rename to editor/src/Fields/UIEditorFieldStyle.cpp diff --git a/new_editor/src/Fields/UIEditorNumberField.cpp b/editor/src/Fields/UIEditorNumberField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorNumberField.cpp rename to editor/src/Fields/UIEditorNumberField.cpp diff --git a/new_editor/src/Fields/UIEditorNumberFieldInteraction.cpp b/editor/src/Fields/UIEditorNumberFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorNumberFieldInteraction.cpp rename to editor/src/Fields/UIEditorNumberFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorObjectField.cpp b/editor/src/Fields/UIEditorObjectField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorObjectField.cpp rename to editor/src/Fields/UIEditorObjectField.cpp diff --git a/new_editor/src/Fields/UIEditorObjectFieldInteraction.cpp b/editor/src/Fields/UIEditorObjectFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorObjectFieldInteraction.cpp rename to editor/src/Fields/UIEditorObjectFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorPropertyGrid.cpp b/editor/src/Fields/UIEditorPropertyGrid.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorPropertyGrid.cpp rename to editor/src/Fields/UIEditorPropertyGrid.cpp diff --git a/new_editor/src/Fields/UIEditorPropertyGridInteraction.cpp b/editor/src/Fields/UIEditorPropertyGridInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorPropertyGridInteraction.cpp rename to editor/src/Fields/UIEditorPropertyGridInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorTextField.cpp b/editor/src/Fields/UIEditorTextField.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorTextField.cpp rename to editor/src/Fields/UIEditorTextField.cpp diff --git a/new_editor/src/Fields/UIEditorTextFieldInteraction.cpp b/editor/src/Fields/UIEditorTextFieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorTextFieldInteraction.cpp rename to editor/src/Fields/UIEditorTextFieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorVector2Field.cpp b/editor/src/Fields/UIEditorVector2Field.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector2Field.cpp rename to editor/src/Fields/UIEditorVector2Field.cpp diff --git a/new_editor/src/Fields/UIEditorVector2FieldInteraction.cpp b/editor/src/Fields/UIEditorVector2FieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector2FieldInteraction.cpp rename to editor/src/Fields/UIEditorVector2FieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorVector3Field.cpp b/editor/src/Fields/UIEditorVector3Field.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector3Field.cpp rename to editor/src/Fields/UIEditorVector3Field.cpp diff --git a/new_editor/src/Fields/UIEditorVector3FieldInteraction.cpp b/editor/src/Fields/UIEditorVector3FieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector3FieldInteraction.cpp rename to editor/src/Fields/UIEditorVector3FieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorVector4Field.cpp b/editor/src/Fields/UIEditorVector4Field.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector4Field.cpp rename to editor/src/Fields/UIEditorVector4Field.cpp diff --git a/new_editor/src/Fields/UIEditorVector4FieldInteraction.cpp b/editor/src/Fields/UIEditorVector4FieldInteraction.cpp similarity index 100% rename from new_editor/src/Fields/UIEditorVector4FieldInteraction.cpp rename to editor/src/Fields/UIEditorVector4FieldInteraction.cpp diff --git a/new_editor/src/Fields/UIEditorVectorFieldInteractionShared.h b/editor/src/Fields/UIEditorVectorFieldInteractionShared.h similarity index 100% rename from new_editor/src/Fields/UIEditorVectorFieldInteractionShared.h rename to editor/src/Fields/UIEditorVectorFieldInteractionShared.h diff --git a/new_editor/src/Fields/UIEditorVectorFieldShared.h b/editor/src/Fields/UIEditorVectorFieldShared.h similarity index 100% rename from new_editor/src/Fields/UIEditorVectorFieldShared.h rename to editor/src/Fields/UIEditorVectorFieldShared.h diff --git a/new_editor/src/Foundation/UIEditorCommandDispatcher.cpp b/editor/src/Foundation/UIEditorCommandDispatcher.cpp similarity index 100% rename from new_editor/src/Foundation/UIEditorCommandDispatcher.cpp rename to editor/src/Foundation/UIEditorCommandDispatcher.cpp diff --git a/new_editor/src/Foundation/UIEditorCommandRegistry.cpp b/editor/src/Foundation/UIEditorCommandRegistry.cpp similarity index 100% rename from new_editor/src/Foundation/UIEditorCommandRegistry.cpp rename to editor/src/Foundation/UIEditorCommandRegistry.cpp diff --git a/new_editor/src/Foundation/UIEditorRuntimeTrace.cpp b/editor/src/Foundation/UIEditorRuntimeTrace.cpp similarity index 100% rename from new_editor/src/Foundation/UIEditorRuntimeTrace.cpp rename to editor/src/Foundation/UIEditorRuntimeTrace.cpp diff --git a/new_editor/src/Foundation/UIEditorShortcutManager.cpp b/editor/src/Foundation/UIEditorShortcutManager.cpp similarity index 100% rename from new_editor/src/Foundation/UIEditorShortcutManager.cpp rename to editor/src/Foundation/UIEditorShortcutManager.cpp diff --git a/new_editor/src/Foundation/UIEditorTheme.cpp b/editor/src/Foundation/UIEditorTheme.cpp similarity index 100% rename from new_editor/src/Foundation/UIEditorTheme.cpp rename to editor/src/Foundation/UIEditorTheme.cpp diff --git a/new_editor/src/Menu/UIEditorMenuBar.cpp b/editor/src/Menu/UIEditorMenuBar.cpp similarity index 100% rename from new_editor/src/Menu/UIEditorMenuBar.cpp rename to editor/src/Menu/UIEditorMenuBar.cpp diff --git a/new_editor/src/Menu/UIEditorMenuModel.cpp b/editor/src/Menu/UIEditorMenuModel.cpp similarity index 100% rename from new_editor/src/Menu/UIEditorMenuModel.cpp rename to editor/src/Menu/UIEditorMenuModel.cpp diff --git a/new_editor/src/Menu/UIEditorMenuPopup.cpp b/editor/src/Menu/UIEditorMenuPopup.cpp similarity index 100% rename from new_editor/src/Menu/UIEditorMenuPopup.cpp rename to editor/src/Menu/UIEditorMenuPopup.cpp diff --git a/new_editor/src/Menu/UIEditorMenuSession.cpp b/editor/src/Menu/UIEditorMenuSession.cpp similarity index 100% rename from new_editor/src/Menu/UIEditorMenuSession.cpp rename to editor/src/Menu/UIEditorMenuSession.cpp diff --git a/new_editor/src/Panels/UIEditorHostedPanelDispatch.cpp b/editor/src/Panels/UIEditorHostedPanelDispatch.cpp similarity index 100% rename from new_editor/src/Panels/UIEditorHostedPanelDispatch.cpp rename to editor/src/Panels/UIEditorHostedPanelDispatch.cpp diff --git a/new_editor/src/Panels/UIEditorPanelContentHost.cpp b/editor/src/Panels/UIEditorPanelContentHost.cpp similarity index 100% rename from new_editor/src/Panels/UIEditorPanelContentHost.cpp rename to editor/src/Panels/UIEditorPanelContentHost.cpp diff --git a/new_editor/src/Panels/UIEditorPanelFrame.cpp b/editor/src/Panels/UIEditorPanelFrame.cpp similarity index 100% rename from new_editor/src/Panels/UIEditorPanelFrame.cpp rename to editor/src/Panels/UIEditorPanelFrame.cpp diff --git a/new_editor/src/Panels/UIEditorPanelHostLifecycle.cpp b/editor/src/Panels/UIEditorPanelHostLifecycle.cpp similarity index 100% rename from new_editor/src/Panels/UIEditorPanelHostLifecycle.cpp rename to editor/src/Panels/UIEditorPanelHostLifecycle.cpp diff --git a/new_editor/src/Panels/UIEditorPanelRegistry.cpp b/editor/src/Panels/UIEditorPanelRegistry.cpp similarity index 100% rename from new_editor/src/Panels/UIEditorPanelRegistry.cpp rename to editor/src/Panels/UIEditorPanelRegistry.cpp diff --git a/new_editor/src/Shell/ShellInteractionInternal.h b/editor/src/Shell/ShellInteractionInternal.h similarity index 100% rename from new_editor/src/Shell/ShellInteractionInternal.h rename to editor/src/Shell/ShellInteractionInternal.h diff --git a/new_editor/src/Shell/UIEditorShellAsset.cpp b/editor/src/Shell/UIEditorShellAsset.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorShellAsset.cpp rename to editor/src/Shell/UIEditorShellAsset.cpp diff --git a/new_editor/src/Shell/UIEditorShellCapturePolicy.cpp b/editor/src/Shell/UIEditorShellCapturePolicy.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorShellCapturePolicy.cpp rename to editor/src/Shell/UIEditorShellCapturePolicy.cpp diff --git a/new_editor/src/Shell/UIEditorShellCompose.cpp b/editor/src/Shell/UIEditorShellCompose.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorShellCompose.cpp rename to editor/src/Shell/UIEditorShellCompose.cpp diff --git a/new_editor/src/Shell/UIEditorShellInteraction.cpp b/editor/src/Shell/UIEditorShellInteraction.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorShellInteraction.cpp rename to editor/src/Shell/UIEditorShellInteraction.cpp diff --git a/new_editor/src/Shell/UIEditorStatusBar.cpp b/editor/src/Shell/UIEditorStatusBar.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorStatusBar.cpp rename to editor/src/Shell/UIEditorStatusBar.cpp diff --git a/new_editor/src/Shell/UIEditorStructuredShell.cpp b/editor/src/Shell/UIEditorStructuredShell.cpp similarity index 100% rename from new_editor/src/Shell/UIEditorStructuredShell.cpp rename to editor/src/Shell/UIEditorStructuredShell.cpp diff --git a/new_editor/src/Viewport/UIEditorViewportInputBridge.cpp b/editor/src/Viewport/UIEditorViewportInputBridge.cpp similarity index 100% rename from new_editor/src/Viewport/UIEditorViewportInputBridge.cpp rename to editor/src/Viewport/UIEditorViewportInputBridge.cpp diff --git a/new_editor/src/Viewport/UIEditorViewportShell.cpp b/editor/src/Viewport/UIEditorViewportShell.cpp similarity index 100% rename from new_editor/src/Viewport/UIEditorViewportShell.cpp rename to editor/src/Viewport/UIEditorViewportShell.cpp diff --git a/new_editor/src/Viewport/UIEditorViewportSlot.cpp b/editor/src/Viewport/UIEditorViewportSlot.cpp similarity index 100% rename from new_editor/src/Viewport/UIEditorViewportSlot.cpp rename to editor/src/Viewport/UIEditorViewportSlot.cpp diff --git a/new_editor/src/Widgets/UIEditorCollectionPrimitives.cpp b/editor/src/Widgets/UIEditorCollectionPrimitives.cpp similarity index 100% rename from new_editor/src/Widgets/UIEditorCollectionPrimitives.cpp rename to editor/src/Widgets/UIEditorCollectionPrimitives.cpp diff --git a/new_editor/src/Widgets/UIEditorColorUtils.cpp b/editor/src/Widgets/UIEditorColorUtils.cpp similarity index 100% rename from new_editor/src/Widgets/UIEditorColorUtils.cpp rename to editor/src/Widgets/UIEditorColorUtils.cpp diff --git a/new_editor/src/Widgets/UIEditorFieldRowLayout.cpp b/editor/src/Widgets/UIEditorFieldRowLayout.cpp similarity index 100% rename from new_editor/src/Widgets/UIEditorFieldRowLayout.cpp rename to editor/src/Widgets/UIEditorFieldRowLayout.cpp diff --git a/new_editor/src/Workspace/SplitterDragCorrection/Chain.cpp b/editor/src/Workspace/SplitterDragCorrection/Chain.cpp similarity index 100% rename from new_editor/src/Workspace/SplitterDragCorrection/Chain.cpp rename to editor/src/Workspace/SplitterDragCorrection/Chain.cpp diff --git a/new_editor/src/Workspace/SplitterDragCorrection/Correction.cpp b/editor/src/Workspace/SplitterDragCorrection/Correction.cpp similarity index 100% rename from new_editor/src/Workspace/SplitterDragCorrection/Correction.cpp rename to editor/src/Workspace/SplitterDragCorrection/Correction.cpp diff --git a/new_editor/src/Workspace/SplitterDragCorrection/Internal.h b/editor/src/Workspace/SplitterDragCorrection/Internal.h similarity index 100% rename from new_editor/src/Workspace/SplitterDragCorrection/Internal.h rename to editor/src/Workspace/SplitterDragCorrection/Internal.h diff --git a/new_editor/app/Windowing/Workspace/UIEditorDetachedWindowPolicy.cpp b/editor/src/Workspace/UIEditorDetachedWindowPolicy.cpp similarity index 97% rename from new_editor/app/Windowing/Workspace/UIEditorDetachedWindowPolicy.cpp rename to editor/src/Workspace/UIEditorDetachedWindowPolicy.cpp index 615353e3..12006a98 100644 --- a/new_editor/app/Windowing/Workspace/UIEditorDetachedWindowPolicy.cpp +++ b/editor/src/Workspace/UIEditorDetachedWindowPolicy.cpp @@ -1,4 +1,4 @@ -#include "UIEditorDetachedWindowPolicy.h" +#include namespace XCEngine::UI::Editor { diff --git a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.cpp b/editor/src/Workspace/UIEditorWindowWorkspaceController.cpp similarity index 99% rename from new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.cpp rename to editor/src/Workspace/UIEditorWindowWorkspaceController.cpp index 18dbdd7f..5c6b2395 100644 --- a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceController.cpp +++ b/editor/src/Workspace/UIEditorWindowWorkspaceController.cpp @@ -1,4 +1,4 @@ -#include "UIEditorWindowWorkspaceController.h" +#include #include #include diff --git a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceModel.cpp b/editor/src/Workspace/UIEditorWindowWorkspaceModel.cpp similarity index 98% rename from new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceModel.cpp rename to editor/src/Workspace/UIEditorWindowWorkspaceModel.cpp index f5e3cca4..69802730 100644 --- a/new_editor/app/Windowing/Workspace/UIEditorWindowWorkspaceModel.cpp +++ b/editor/src/Workspace/UIEditorWindowWorkspaceModel.cpp @@ -1,4 +1,4 @@ -#include "UIEditorWindowWorkspaceModel.h" +#include #include #include diff --git a/new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp b/editor/src/Workspace/UIEditorWorkspaceCompose.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceCompose.cpp rename to editor/src/Workspace/UIEditorWorkspaceCompose.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceController.cpp b/editor/src/Workspace/UIEditorWorkspaceController.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceController.cpp rename to editor/src/Workspace/UIEditorWorkspaceController.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp b/editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp rename to editor/src/Workspace/UIEditorWorkspaceInputOwner.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp b/editor/src/Workspace/UIEditorWorkspaceInteraction.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceInteraction.cpp rename to editor/src/Workspace/UIEditorWorkspaceInteraction.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp b/editor/src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp rename to editor/src/Workspace/UIEditorWorkspaceLayoutPersistence.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceModel.cpp b/editor/src/Workspace/UIEditorWorkspaceModel.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceModel.cpp rename to editor/src/Workspace/UIEditorWorkspaceModel.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceSession.cpp b/editor/src/Workspace/UIEditorWorkspaceSession.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceSession.cpp rename to editor/src/Workspace/UIEditorWorkspaceSession.cpp diff --git a/new_editor/src/Workspace/UIEditorWorkspaceTransfer.cpp b/editor/src/Workspace/UIEditorWorkspaceTransfer.cpp similarity index 100% rename from new_editor/src/Workspace/UIEditorWorkspaceTransfer.cpp rename to editor/src/Workspace/UIEditorWorkspaceTransfer.cpp diff --git a/new_editor/src/Workspace/WorkspaceControllerInternal.h b/editor/src/Workspace/WorkspaceControllerInternal.h similarity index 100% rename from new_editor/src/Workspace/WorkspaceControllerInternal.h rename to editor/src/Workspace/WorkspaceControllerInternal.h diff --git a/new_editor/src/Workspace/WorkspaceModelInternal.h b/editor/src/Workspace/WorkspaceModelInternal.h similarity index 100% rename from new_editor/src/Workspace/WorkspaceModelInternal.h rename to editor/src/Workspace/WorkspaceModelInternal.h diff --git a/new_editor/app/Composition/EditorUtilityWindowPanelComposition.cpp b/new_editor/app/Composition/EditorUtilityWindowPanelComposition.cpp deleted file mode 100644 index 3566281a..00000000 --- a/new_editor/app/Composition/EditorUtilityWindowPanelComposition.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "Composition/EditorUtilityWindowPanelComposition.h" - -#include "Features/ColorPicker/ColorPickerPanel.h" -#include "Features/Inspector/AddComponentPanel.h" - -namespace XCEngine::UI::Editor::App { - -std::unique_ptr EditorUtilityWindowPanelComposition::CreatePanel( - EditorUtilityWindowType type) const { - switch (type) { - case EditorUtilityWindowType::ColorPicker: - return std::make_unique(); - case EditorUtilityWindowType::AddComponent: - return std::make_unique(); - case EditorUtilityWindowType::None: - default: - return nullptr; - } -} - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Composition/EditorUtilityWindowPanelComposition.h b/new_editor/app/Composition/EditorUtilityWindowPanelComposition.h deleted file mode 100644 index f94b0d08..00000000 --- a/new_editor/app/Composition/EditorUtilityWindowPanelComposition.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowPanelProvider.h" - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowPanelComposition final : public EditorUtilityWindowPanelProvider { -public: - std::unique_ptr CreatePanel( - EditorUtilityWindowType type) const override; -}; - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Composition/EditorWindowApplicationComposition.cpp b/new_editor/app/Composition/EditorWindowApplicationComposition.cpp deleted file mode 100644 index 507ffa11..00000000 --- a/new_editor/app/Composition/EditorWindowApplicationComposition.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "Composition/EditorWindowApplicationComposition.h" - -#include "Composition/EditorUtilityWindowPanelComposition.h" -#include "Composition/EditorContext.h" -#include "Windowing/Application/EditorWindowApplicationRuntime.h" - -#include - -namespace XCEngine::UI::Editor::App { - -EditorWindowApplicationComposition::EditorWindowApplicationComposition( - std::wstring primaryWindowTitle, - EditorWindowHostAdapters hostAdapters, - EditorContext& editorContext, - std::unique_ptr utilityPanelProvider) { - if (utilityPanelProvider == nullptr) { - utilityPanelProvider = CreateEditorUtilityWindowPanelProvider(); - } - m_runtime = std::make_unique( - std::move(primaryWindowTitle), - hostAdapters, - editorContext, - std::move(utilityPanelProvider)); -} - -EditorWindowApplicationComposition::~EditorWindowApplicationComposition() = default; - -EditorWindowApplicationRuntime& EditorWindowApplicationComposition::GetRuntime() { - return *m_runtime; -} - -const EditorWindowApplicationRuntime& EditorWindowApplicationComposition::GetRuntime() const { - return *m_runtime; -} - -std::unique_ptr -CreateEditorUtilityWindowPanelProvider() { - return std::make_unique(); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Composition/EditorWindowApplicationComposition.h b/new_editor/app/Composition/EditorWindowApplicationComposition.h deleted file mode 100644 index 3ebe5e9a..00000000 --- a/new_editor/app/Composition/EditorWindowApplicationComposition.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "Windowing/Host/EditorWindowHostAdapters.h" -#include "Windowing/Utility/EditorUtilityWindowPanelProvider.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowApplicationRuntime; -class EditorContext; - -class EditorWindowApplicationComposition final { -public: - explicit EditorWindowApplicationComposition( - std::wstring primaryWindowTitle, - EditorWindowHostAdapters hostAdapters, - EditorContext& editorContext, - std::unique_ptr utilityPanelProvider = {}); - ~EditorWindowApplicationComposition(); - - EditorWindowApplicationComposition(const EditorWindowApplicationComposition&) = delete; - EditorWindowApplicationComposition& operator=( - const EditorWindowApplicationComposition&) = delete; - EditorWindowApplicationComposition(EditorWindowApplicationComposition&&) = delete; - EditorWindowApplicationComposition& operator=( - EditorWindowApplicationComposition&&) = delete; - - EditorWindowApplicationRuntime& GetRuntime(); - const EditorWindowApplicationRuntime& GetRuntime() const; - -private: - std::unique_ptr m_runtime = {}; -}; - -std::unique_ptr -CreateEditorUtilityWindowPanelProvider(); - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageAdapter.h b/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageAdapter.h deleted file mode 100644 index d0feab7f..00000000 --- a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageAdapter.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Platform/Win32/Adapter/Win32WindowMessageSink.h" -#include "Platform/Win32/Adapter/Win32WindowMessageTranslator.h" - -#include - -namespace XCEngine::UI::Editor::App { - -class Win32WindowMessageAdapter final { -public: - static bool TryDispatch( - UINT message, - WPARAM wParam, - LPARAM lParam, - Win32WindowMessageSink& sink, - LRESULT& outResult) { - const Win32WindowMessageEvent event = TranslateWin32WindowMessage(message, wParam, lParam); - return sink.TryDispatchTranslatedMessage(event, outResult); - } -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageSink.h b/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageSink.h deleted file mode 100644 index b4839160..00000000 --- a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageSink.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -namespace XCEngine::UI::Editor::App { - -struct Win32WindowMessageEvent; - -class Win32WindowMessageSink { -public: - virtual ~Win32WindowMessageSink() = default; - - virtual bool TryDispatchTranslatedMessage( - const Win32WindowMessageEvent& event, - LRESULT& outResult) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageTranslator.h b/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageTranslator.h deleted file mode 100644 index bc168ed1..00000000 --- a/new_editor/app/Platform/Win32/Adapter/Win32WindowMessageTranslator.h +++ /dev/null @@ -1,201 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -enum class Win32WindowMessageType { - Unknown, - PointerMove, - PointerLeave, - PointerButtonDown, - PointerButtonUp, - PointerButtonDoubleClick, - PointerWheel, - FocusGained, - FocusLost, - CaptureChanged, - KeyDown, - KeyUp, - Character, - DpiChanged, - EnterSizeMove, - ExitSizeMove, - Resize, - Close, - Paint, - EraseBackground, - Destroy, - GetMinMaxInfo, - NcCalcSize, - NcActivate, - NcHitTest, - NcPaint, - SystemCommand, - SetCursor, -}; - -struct Win32WindowMessageEvent { - Win32WindowMessageType type = Win32WindowMessageType::Unknown; - UINT message = 0; - WPARAM wParam = 0; - LPARAM lParam = 0; - ::XCEngine::UI::UIPointerButton pointerButton = ::XCEngine::UI::UIPointerButton::None; - short wheelDelta = 0; - UINT dpi = 0; - const RECT* suggestedRect = nullptr; - UINT clientWidth = 0; - UINT clientHeight = 0; - bool minimized = false; - HWND captureOwner = nullptr; - bool clientCursor = false; -}; - -constexpr UINT kWin32MessageNcUaDrawCaption = 0x00AEu; -constexpr UINT kWin32MessageNcUaDrawFrame = 0x00AFu; - -inline Win32WindowMessageEvent TranslateWin32WindowMessage( - UINT message, - WPARAM wParam, - LPARAM lParam) { - Win32WindowMessageEvent event = {}; - event.message = message; - event.wParam = wParam; - event.lParam = lParam; - - switch (message) { - case WM_MOUSEMOVE: - event.type = Win32WindowMessageType::PointerMove; - break; - case WM_MOUSELEAVE: - event.type = Win32WindowMessageType::PointerLeave; - break; - case WM_LBUTTONDOWN: - event.type = Win32WindowMessageType::PointerButtonDown; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Left; - break; - case WM_RBUTTONDOWN: - event.type = Win32WindowMessageType::PointerButtonDown; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Right; - break; - case WM_MBUTTONDOWN: - event.type = Win32WindowMessageType::PointerButtonDown; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Middle; - break; - case WM_LBUTTONUP: - event.type = Win32WindowMessageType::PointerButtonUp; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Left; - break; - case WM_RBUTTONUP: - event.type = Win32WindowMessageType::PointerButtonUp; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Right; - break; - case WM_MBUTTONUP: - event.type = Win32WindowMessageType::PointerButtonUp; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Middle; - break; - case WM_LBUTTONDBLCLK: - event.type = Win32WindowMessageType::PointerButtonDoubleClick; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Left; - break; - case WM_RBUTTONDBLCLK: - event.type = Win32WindowMessageType::PointerButtonDoubleClick; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Right; - break; - case WM_MBUTTONDBLCLK: - event.type = Win32WindowMessageType::PointerButtonDoubleClick; - event.pointerButton = ::XCEngine::UI::UIPointerButton::Middle; - break; - case WM_MOUSEWHEEL: - event.type = Win32WindowMessageType::PointerWheel; - event.wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam); - break; - case WM_SETFOCUS: - event.type = Win32WindowMessageType::FocusGained; - break; - case WM_KILLFOCUS: - event.type = Win32WindowMessageType::FocusLost; - break; - case WM_CAPTURECHANGED: - event.type = Win32WindowMessageType::CaptureChanged; - event.captureOwner = reinterpret_cast(lParam); - break; - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - event.type = Win32WindowMessageType::KeyDown; - break; - case WM_KEYUP: - case WM_SYSKEYUP: - event.type = Win32WindowMessageType::KeyUp; - break; - case WM_CHAR: - event.type = Win32WindowMessageType::Character; - break; - case WM_DPICHANGED: - event.type = Win32WindowMessageType::DpiChanged; - event.dpi = static_cast(LOWORD(wParam)); - event.suggestedRect = lParam != 0 ? reinterpret_cast(lParam) : nullptr; - break; - case WM_ENTERSIZEMOVE: - event.type = Win32WindowMessageType::EnterSizeMove; - break; - case WM_EXITSIZEMOVE: - event.type = Win32WindowMessageType::ExitSizeMove; - break; - case WM_SIZE: - event.type = Win32WindowMessageType::Resize; - event.clientWidth = static_cast(LOWORD(lParam)); - event.clientHeight = static_cast(HIWORD(lParam)); - event.minimized = wParam == SIZE_MINIMIZED; - break; - case WM_CLOSE: - event.type = Win32WindowMessageType::Close; - break; - case WM_PAINT: - event.type = Win32WindowMessageType::Paint; - break; - case WM_ERASEBKGND: - event.type = Win32WindowMessageType::EraseBackground; - break; - case WM_DESTROY: - event.type = Win32WindowMessageType::Destroy; - break; - case WM_GETMINMAXINFO: - event.type = Win32WindowMessageType::GetMinMaxInfo; - break; - case WM_NCCALCSIZE: - event.type = Win32WindowMessageType::NcCalcSize; - break; - case WM_NCACTIVATE: - event.type = Win32WindowMessageType::NcActivate; - break; - case WM_NCHITTEST: - event.type = Win32WindowMessageType::NcHitTest; - break; - case WM_NCPAINT: - case kWin32MessageNcUaDrawCaption: - case kWin32MessageNcUaDrawFrame: - event.type = Win32WindowMessageType::NcPaint; - break; - case WM_SYSCOMMAND: - event.type = Win32WindowMessageType::SystemCommand; - break; - case WM_SETCURSOR: - event.type = Win32WindowMessageType::SetCursor; - event.clientCursor = LOWORD(lParam) == HTCLIENT; - break; - default: - break; - } - - return event; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.cpp b/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.cpp deleted file mode 100644 index ef01f978..00000000 --- a/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.cpp +++ /dev/null @@ -1,360 +0,0 @@ -#include "Platform/Win32/Backend/Win32NativeWindowBackend.h" - -#include "Bootstrap/EditorResources.h" - -namespace XCEngine::UI::Editor::App { - -HWND Win32NativeWindowBackend::CreateNativeWindow( - const Win32NativeWindowCreateDesc& desc) const { - return CreateWindowExW( - desc.exStyle, - desc.className, - desc.title.data(), - desc.style, - desc.x, - desc.y, - desc.width, - desc.height, - nullptr, - nullptr, - desc.hInstance, - desc.userData); -} - -bool Win32NativeWindowBackend::IsNativeWindow(HWND hwnd) const { - return hwnd != nullptr && IsWindow(hwnd) != FALSE; -} - -void Win32NativeWindowBackend::DestroyNativeWindow(HWND hwnd) const { - if (!IsNativeWindow(hwnd)) { - return; - } - - DestroyWindow(hwnd); -} - -void Win32NativeWindowBackend::ApplyEditorIcons(HWND hwnd, HINSTANCE hInstance) const { - if (hwnd == nullptr || hInstance == nullptr) { - return; - } - - const HICON bigIcon = static_cast( - LoadImageW( - hInstance, - MAKEINTRESOURCEW(IDI_APP_ICON), - IMAGE_ICON, - 0, - 0, - LR_DEFAULTSIZE)); - const HICON smallIcon = static_cast( - LoadImageW( - hInstance, - MAKEINTRESOURCEW(IDI_APP_ICON_SMALL), - IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_DEFAULTCOLOR)); - if (bigIcon != nullptr) { - SendMessageW(hwnd, WM_SETICON, ICON_BIG, reinterpret_cast(bigIcon)); - } - if (smallIcon != nullptr) { - SendMessageW(hwnd, WM_SETICON, ICON_SMALL, reinterpret_cast(smallIcon)); - } -} - -void Win32NativeWindowBackend::ShowAndUpdate(HWND hwnd, int showCommand) const { - if (hwnd == nullptr) { - return; - } - - ShowWindow(hwnd, showCommand); - UpdateWindow(hwnd); -} - -void Win32NativeWindowBackend::RestoreWindow(HWND hwnd) const { - if (hwnd == nullptr) { - return; - } - - ShowWindow(hwnd, SW_RESTORE); -} - -void Win32NativeWindowBackend::FocusWindow(HWND hwnd) const { - if (hwnd == nullptr) { - return; - } - - SetForegroundWindow(hwnd); -} - -void Win32NativeWindowBackend::MoveWindowTo(HWND hwnd, int x, int y) const { - if (hwnd == nullptr) { - return; - } - - SetWindowPos( - hwnd, - nullptr, - x, - y, - 0, - 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); -} - -void Win32NativeWindowBackend::ResizeWindowTo(HWND hwnd, int width, int height) const { - if (hwnd == nullptr || width <= 0 || height <= 0) { - return; - } - - SetWindowPos( - hwnd, - nullptr, - 0, - 0, - width, - height, - SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); -} - -void Win32NativeWindowBackend::SetWindowBounds( - HWND hwnd, - int x, - int y, - int width, - int height, - Win32WindowBoundsMode mode) const { - if (hwnd == nullptr || width <= 0 || height <= 0) { - return; - } - - UINT flags = SWP_NOZORDER | SWP_NOACTIVATE; - if (mode == Win32WindowBoundsMode::InteractiveResizeNoRedraw) { - flags |= SWP_NOCOPYBITS | SWP_NOREDRAW; - } - - SetWindowPos( - hwnd, - nullptr, - x, - y, - width, - height, - flags); - - if (mode == Win32WindowBoundsMode::InteractiveResizeNoRedraw) { - ValidateRect(hwnd, nullptr); - } -} - -void Win32NativeWindowBackend::SetWindowTitle(HWND hwnd, std::wstring_view title) const { - if (hwnd == nullptr) { - return; - } - - SetWindowTextW(hwnd, title.data()); -} - -void Win32NativeWindowBackend::MinimizeWindow(HWND hwnd) const { - if (hwnd == nullptr) { - return; - } - - ShowWindow(hwnd, SW_MINIMIZE); -} - -void Win32NativeWindowBackend::RequestCloseWindow(HWND hwnd) const { - if (hwnd == nullptr) { - return; - } - - PostMessageW(hwnd, WM_CLOSE, 0, 0); -} - -void Win32NativeWindowBackend::BeginCaptionDrag(HWND hwnd) const { - if (hwnd == nullptr) { - return; - } - - SendMessageW(hwnd, WM_NCLBUTTONDOWN, HTCAPTION, 0); -} - -void Win32NativeWindowBackend::InvalidateWindow(HWND hwnd) const { - if (!IsNativeWindow(hwnd)) { - return; - } - - InvalidateRect(hwnd, nullptr, FALSE); -} - -UINT Win32NativeWindowBackend::QuerySystemDpi() const { - constexpr UINT kDefaultDpi = 96u; - HDC screenDc = GetDC(nullptr); - if (screenDc == nullptr) { - return kDefaultDpi; - } - - const int dpiX = GetDeviceCaps(screenDc, LOGPIXELSX); - ReleaseDC(nullptr, screenDc); - return dpiX > 0 ? static_cast(dpiX) : kDefaultDpi; -} - -UINT Win32NativeWindowBackend::QueryWindowDpi(HWND hwnd) const { - if (hwnd != nullptr) { - const HMODULE user32 = GetModuleHandleW(L"user32.dll"); - if (user32 != nullptr) { - using GetDpiForWindowFn = UINT(WINAPI*)(HWND); - const auto getDpiForWindow = - reinterpret_cast(GetProcAddress(user32, "GetDpiForWindow")); - if (getDpiForWindow != nullptr) { - const UINT dpi = getDpiForWindow(hwnd); - if (dpi != 0u) { - return dpi; - } - } - } - } - - return QuerySystemDpi(); -} - -bool Win32NativeWindowBackend::TryGetClientRect(HWND hwnd, RECT& outRect) const { - outRect = {}; - return IsNativeWindow(hwnd) && GetClientRect(hwnd, &outRect) != FALSE; -} - -bool Win32NativeWindowBackend::TryGetWindowRect(HWND hwnd, RECT& outRect) const { - outRect = {}; - return IsNativeWindow(hwnd) && GetWindowRect(hwnd, &outRect) != FALSE; -} - -bool Win32NativeWindowBackend::TryGetCursorScreenPoint(POINT& outPoint) const { - outPoint = {}; - return GetCursorPos(&outPoint) != FALSE; -} - -bool Win32NativeWindowBackend::TryGetCursorScreenPoint( - EditorWindowScreenPoint& outPoint) const { - POINT point = {}; - if (!TryGetCursorScreenPoint(point)) { - outPoint = {}; - return false; - } - - outPoint = EditorWindowScreenPoint{point.x, point.y}; - return true; -} - -bool Win32NativeWindowBackend::TryConvertScreenToClient(HWND hwnd, POINT& inOutPoint) const { - return IsNativeWindow(hwnd) && ScreenToClient(hwnd, &inOutPoint) != FALSE; -} - -bool Win32NativeWindowBackend::TrackMouseLeave(HWND hwnd) const { - if (!IsNativeWindow(hwnd)) { - return false; - } - - TRACKMOUSEEVENT trackMouseEvent = {}; - trackMouseEvent.cbSize = sizeof(trackMouseEvent); - trackMouseEvent.dwFlags = TME_LEAVE; - trackMouseEvent.hwndTrack = hwnd; - return ::TrackMouseEvent(&trackMouseEvent) != FALSE; -} - -bool Win32NativeWindowBackend::ApplyCursorResource(LPCWSTR cursorResource) const { - const HCURSOR cursor = LoadCursorW(nullptr, cursorResource); - if (cursor == nullptr) { - return false; - } - - SetCursor(cursor); - return true; -} - -bool Win32NativeWindowBackend::IsWindowUnderScreenPoint( - HWND hwnd, - const POINT& screenPoint) const { - if (!IsNativeWindow(hwnd)) { - return false; - } - - const HWND hitWindow = WindowFromPoint(screenPoint); - if (hitWindow == nullptr || GetAncestor(hitWindow, GA_ROOT) != hwnd) { - return false; - } - - RECT windowRect = {}; - if (!TryGetWindowRect(hwnd, windowRect)) { - return false; - } - - return screenPoint.x >= windowRect.left && screenPoint.x < windowRect.right && - screenPoint.y >= windowRect.top && screenPoint.y < windowRect.bottom; -} - -bool Win32NativeWindowBackend::TryGetNearestMonitorWorkArea( - EditorWindowScreenPoint screenPoint, - EditorWindowRect& outRect) const { - const POINT point{screenPoint.x, screenPoint.y}; - const HMONITOR monitor = MonitorFromPoint(point, MONITOR_DEFAULTTONEAREST); - MONITORINFO monitorInfo = {}; - monitorInfo.cbSize = sizeof(monitorInfo); - if (monitor == nullptr || GetMonitorInfoW(monitor, &monitorInfo) == FALSE) { - outRect = {}; - return false; - } - - const RECT& workArea = monitorInfo.rcWork; - outRect = EditorWindowRect{workArea.left, workArea.top, workArea.right, workArea.bottom}; - return true; -} - -bool Win32NativeWindowBackend::IsCurrentCaptureWindow(HWND hwnd) const { - return IsNativeWindow(hwnd) && GetCapture() == hwnd; -} - -bool Win32NativeWindowBackend::IsClientHitAtScreenPoint( - HWND hwnd, - const POINT& screenPoint) const { - if (!IsWindowUnderScreenPoint(hwnd, screenPoint)) { - return false; - } - - const LPARAM pointParam = - MAKELPARAM(static_cast(screenPoint.x), static_cast(screenPoint.y)); - return SendMessageW(hwnd, WM_NCHITTEST, 0, pointParam) == HTCLIENT; -} - -bool Win32NativeWindowBackend::IsWindowMinimized(HWND hwnd) const { - return IsNativeWindow(hwnd) && IsIconic(hwnd) != FALSE; -} - -POINT Win32NativeWindowBackend::QueryPointerDragThreshold() const { - return POINT{ - (std::max)(GetSystemMetrics(SM_CXDRAG), 1), - (std::max)(GetSystemMetrics(SM_CYDRAG), 1), - }; -} - -bool Win32NativeWindowBackend::TryGetMonitorWorkArea(HWND hwnd, RECT& outRect) const { - outRect = {}; - if (!IsNativeWindow(hwnd)) { - return false; - } - - const HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - if (monitor == nullptr) { - return false; - } - - MONITORINFO monitorInfo = {}; - monitorInfo.cbSize = sizeof(monitorInfo); - if (!GetMonitorInfoW(monitor, &monitorInfo)) { - return false; - } - - outRect = monitorInfo.rcWork; - return true; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.h b/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.h deleted file mode 100644 index 3832cc76..00000000 --- a/new_editor/app/Platform/Win32/Backend/Win32NativeWindowBackend.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Windowing/Application/EditorWindowGeometry.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -enum class Win32WindowBoundsMode : std::uint8_t { - Default = 0, - InteractiveResizeNoRedraw, -}; - -struct Win32NativeWindowCreateDesc { - HINSTANCE hInstance = nullptr; - const wchar_t* className = L""; - DWORD exStyle = WS_EX_APPWINDOW; - DWORD style = 0; - std::wstring_view title = {}; - int x = CW_USEDEFAULT; - int y = CW_USEDEFAULT; - int width = 1540; - int height = 940; - void* userData = nullptr; -}; - -class Win32NativeWindowBackend final { -public: - HWND CreateNativeWindow(const Win32NativeWindowCreateDesc& desc) const; - void DestroyNativeWindow(HWND hwnd) const; - bool IsNativeWindow(HWND hwnd) const; - void ApplyEditorIcons(HWND hwnd, HINSTANCE hInstance) const; - void ShowAndUpdate(HWND hwnd, int showCommand) const; - void RestoreWindow(HWND hwnd) const; - void FocusWindow(HWND hwnd) const; - void MoveWindowTo(HWND hwnd, int x, int y) const; - void ResizeWindowTo(HWND hwnd, int width, int height) const; - void SetWindowBounds( - HWND hwnd, - int x, - int y, - int width, - int height, - Win32WindowBoundsMode mode = Win32WindowBoundsMode::Default) const; - void SetWindowTitle(HWND hwnd, std::wstring_view title) const; - void MinimizeWindow(HWND hwnd) const; - void RequestCloseWindow(HWND hwnd) const; - void BeginCaptionDrag(HWND hwnd) const; - void InvalidateWindow(HWND hwnd) const; - UINT QuerySystemDpi() const; - UINT QueryWindowDpi(HWND hwnd) const; - bool TryGetClientRect(HWND hwnd, RECT& outRect) const; - bool TryGetWindowRect(HWND hwnd, RECT& outRect) const; - bool TryGetCursorScreenPoint(POINT& outPoint) const; - bool TryGetCursorScreenPoint(EditorWindowScreenPoint& outPoint) const; - bool TryConvertScreenToClient(HWND hwnd, POINT& inOutPoint) const; - bool TrackMouseLeave(HWND hwnd) const; - bool ApplyCursorResource(LPCWSTR cursorResource) const; - bool IsWindowUnderScreenPoint(HWND hwnd, const POINT& screenPoint) const; - bool TryGetNearestMonitorWorkArea( - EditorWindowScreenPoint screenPoint, - EditorWindowRect& outRect) const; - bool IsCurrentCaptureWindow(HWND hwnd) const; - bool IsClientHitAtScreenPoint(HWND hwnd, const POINT& screenPoint) const; - bool IsWindowMinimized(HWND hwnd) const; - POINT QueryPointerDragThreshold() const; - bool TryGetMonitorWorkArea(HWND hwnd, RECT& outRect) const; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeProjection.h b/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeProjection.h deleted file mode 100644 index 131d1636..00000000 --- a/new_editor/app/Platform/Win32/Chrome/EditorWindowChromeProjection.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorWindowChromeProjection { - bool useDetachedTitleBarTabStrip = false; - float detachedTabStripLeadingWidth = 0.0f; - std::string titleText = {}; - std::string frameRateText = {}; - float frameRateTextWidth = 0.0f; - ::XCEngine::UI::UITextureHandle titleBarLogoIcon = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.cpp b/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.cpp deleted file mode 100644 index ba956437..00000000 --- a/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" - -#include "Platform/Win32/Backend/Win32NativeWindowBackend.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Support/StringEncoding.h" - -namespace XCEngine::UI::Editor::App { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -Win32WindowCommandProjector::Win32WindowCommandProjector( - Win32NativeWindowBackend& nativeWindowBackend, - const EditorWindowRegistryRuntime& windowRegistryRuntime) - : m_nativeWindowBackend(nativeWindowBackend) - , m_windowRegistryRuntime(windowRegistryRuntime) { -} - -void Win32WindowCommandProjector::ProjectCommand( - HWND hwnd, - const Domain::WindowCommand& command) const { - switch (command.type) { - case Domain::WindowCommand::Type::ShowWindow: - m_nativeWindowBackend.RestoreWindow(hwnd); - return; - case Domain::WindowCommand::Type::FocusWindow: - m_nativeWindowBackend.FocusWindow(hwnd); - return; - case Domain::WindowCommand::Type::MoveWindow: - m_nativeWindowBackend.MoveWindowTo(hwnd, command.x, command.y); - return; - case Domain::WindowCommand::Type::ResizeWindow: - m_nativeWindowBackend.ResizeWindowTo(hwnd, command.width, command.height); - return; - case Domain::WindowCommand::Type::SetWindowTitle: - m_nativeWindowBackend.SetWindowTitle(hwnd, Utf8ToWide(command.payload)); - return; - case Domain::WindowCommand::Type::SetWindowBounds: - m_nativeWindowBackend.SetWindowBounds( - hwnd, - command.x, - command.y, - command.width, - command.height, - command.boundsMode == Domain::WindowCommand::BoundsMode::InteractiveResizeNoRedraw - ? Win32WindowBoundsMode::InteractiveResizeNoRedraw - : Win32WindowBoundsMode::Default); - return; - case Domain::WindowCommand::Type::DestroyNativeWindow: - m_nativeWindowBackend.DestroyNativeWindow(hwnd); - return; - case Domain::WindowCommand::Type::MinimizeWindow: - m_nativeWindowBackend.MinimizeWindow(hwnd); - return; - case Domain::WindowCommand::Type::CloseWindow: - m_nativeWindowBackend.RequestCloseWindow(hwnd); - return; - case Domain::WindowCommand::Type::BeginCaptionDrag: - m_nativeWindowBackend.BeginCaptionDrag(hwnd); - return; - case Domain::WindowCommand::Type::None: - default: - return; - } -} - -void Win32WindowCommandProjector::ProjectCommands( - HWND hwnd, - std::span commands) const { - for (const Domain::WindowCommand& command : commands) { - ProjectCommand(hwnd, command); - } -} - -void Win32WindowCommandProjector::ProjectCommands( - std::string_view windowId, - std::span commands) const { - const EditorWindow* const window = m_windowRegistryRuntime.FindWindow(windowId); - if (window == nullptr || window->GetHwnd() == nullptr) { - return; - } - - ProjectCommands(window->GetHwnd(), commands); -} -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.h b/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.h deleted file mode 100644 index 5ffc95c1..00000000 --- a/new_editor/app/Platform/Win32/Projection/Win32WindowCommandProjector.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Windowing/Application/EditorWindowCommandSink.h" - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class Win32NativeWindowBackend; -class EditorWindowRegistryRuntime; - -class Win32WindowCommandProjector final : public EditorWindowCommandSink { -public: - Win32WindowCommandProjector( - Win32NativeWindowBackend& nativeWindowBackend, - const EditorWindowRegistryRuntime& windowRegistryRuntime); - - void ProjectCommand( - HWND hwnd, - const ::XCEngine::UI::Editor::Windowing::Domain::WindowCommand& command) const; - void ProjectCommands( - HWND hwnd, - std::span commands) const; - void ProjectCommands( - std::string_view windowId, - std::span commands) const override; - -private: - Win32NativeWindowBackend& m_nativeWindowBackend; - const EditorWindowRegistryRuntime& m_windowRegistryRuntime; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.cpp b/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.cpp deleted file mode 100644 index 06d37c5b..00000000 --- a/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "Platform/Win32/Rendering/D3D12WindowRenderHost.h" - -#include "Platform/Win32/Windowing/EditorWindowSupport.h" - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -using namespace EditorWindowSupport; - -namespace { - -constexpr float kFrameTimeSmoothingFactor = 0.12f; -constexpr float kFrameStatsDisplayRefreshIntervalSeconds = 0.25f; - -} // namespace - -D3D12WindowRenderHost::~D3D12WindowRenderHost() = default; - -bool D3D12WindowRenderHost::IsReady() const { - return m_ready; -} - -bool D3D12WindowRenderHost::HasViewportSurfacePresentation() const { - return m_hasViewportSurfacePresentation; -} - -void D3D12WindowRenderHost::SetDpiScale(float dpiScale) { - m_dpiScale = dpiScale > 0.0f ? dpiScale : 1.0f; - m_textSystem.SetDpiScale(m_dpiScale); - m_uiRenderer.SetDpiScale(m_dpiScale); -} - -::XCEngine::UI::Editor::UIEditorTextMeasurer& D3D12WindowRenderHost::GetTextMeasurer() { - return m_textSystem; -} - -const ::XCEngine::UI::Editor::UIEditorTextMeasurer& -D3D12WindowRenderHost::GetTextMeasurer() const { - return m_textSystem; -} - -Host::D3D12UiTextureHost& D3D12WindowRenderHost::GetTextureHost() { - return m_textureHost; -} - -const Host::D3D12UiTextureHost& D3D12WindowRenderHost::GetTextureHost() const { - return m_textureHost; -} - -Host::D3D12WindowRenderer& D3D12WindowRenderHost::GetWindowRenderer() { - return m_windowRenderer; -} - -const Host::D3D12WindowRenderer& D3D12WindowRenderHost::GetWindowRenderer() const { - return m_windowRenderer; -} - -bool D3D12WindowRenderHost::Initialize(HWND hwnd) { - if (hwnd == nullptr) { - LogRuntimeTrace("app", "window initialize skipped: hwnd is null"); - return false; - } - - RECT clientRect = {}; - GetClientRect(hwnd, &clientRect); - const int clientWidth = (std::max)(clientRect.right - clientRect.left, 1L); - const int clientHeight = (std::max)(clientRect.bottom - clientRect.top, 1L); - if (!m_windowRenderer.Initialize(hwnd, clientWidth, clientHeight)) { - LogRuntimeTrace("app", "d3d12 window renderer initialization failed"); - return false; - } - - if (!m_textureHost.Initialize(m_windowRenderer)) { - LogRuntimeTrace("app", "d3d12 ui texture host initialization failed"); - m_windowRenderer.Shutdown(); - return false; - } - - if (!m_textSystem.Initialize()) { - LogRuntimeTrace("app", "d3d12 ui text system initialization failed"); - m_textureHost.Shutdown(); - m_windowRenderer.Shutdown(); - return false; - } - m_textSystem.SetDpiScale(m_dpiScale); - - if (!m_uiRenderer.Initialize(m_windowRenderer, m_textureHost, m_textSystem)) { - LogRuntimeTrace("app", "d3d12 ui renderer initialization failed"); - m_textSystem.Shutdown(); - m_textureHost.Shutdown(); - m_windowRenderer.Shutdown(); - return false; - } - m_uiRenderer.SetDpiScale(m_dpiScale); - - const Host::D3D12WindowRenderLoopAttachResult attachResult = - m_windowRenderLoop.Attach(m_uiRenderer, m_windowRenderer); - if (!attachResult.warning.empty()) { - LogRuntimeTrace("app", attachResult.warning); - } - - m_hasViewportSurfacePresentation = attachResult.hasViewportSurfacePresentation; - ResetFrameTiming(); - m_ready = true; - return true; -} - -void D3D12WindowRenderHost::WaitForGpuIdle() { - m_windowRenderer.WaitForGpuIdle(); -} - -void D3D12WindowRenderHost::Shutdown() { - m_ready = false; - ResetFrameTiming(); - m_hasViewportSurfacePresentation = false; - m_windowRenderLoop.Detach(); - m_uiRenderer.Shutdown(); - m_textSystem.Shutdown(); - m_textureHost.Shutdown(); - m_windowRenderer.Shutdown(); - m_dpiScale = 1.0f; -} - -void D3D12WindowRenderHost::ResetFrameTiming() { - m_lastFrameTime = {}; - m_hasLastFrameTime = false; - m_smoothedDeltaTimeSeconds = 0.0f; - m_frameStatsDisplayAccumulatorSeconds = 0.0f; - m_displayFps = 0.0f; - m_displayFrameTimeMs = 0.0f; - m_frameRateText.clear(); -} - -bool D3D12WindowRenderHost::ApplyResize(UINT width, UINT height) { - if (!m_ready || width == 0u || height == 0u) { - return false; - } - - const Host::D3D12WindowRenderLoopResizeResult resizeResult = - m_windowRenderLoop.ApplyResize(width, height); - m_hasViewportSurfacePresentation = resizeResult.hasViewportSurfacePresentation; - - if (!resizeResult.windowRendererWarning.empty()) { - LogRuntimeTrace("present", resizeResult.windowRendererWarning); - } - - return resizeResult.hasViewportSurfacePresentation; -} - -Host::D3D12WindowRenderLoopFrameContext D3D12WindowRenderHost::BeginFrame() { - UpdateFrameTiming(); - return m_windowRenderLoop.BeginFrame(); -} - -Host::D3D12WindowRenderLoopPresentResult D3D12WindowRenderHost::Present( - const ::XCEngine::UI::UIDrawData& drawData, - const std::filesystem::path* capturePath) { - return m_windowRenderLoop.Present(drawData, capturePath); -} - -const std::string& D3D12WindowRenderHost::BuildFrameRateText() const { - return m_frameRateText; -} - -void D3D12WindowRenderHost::UpdateFrameTiming() { - const auto now = std::chrono::steady_clock::now(); - if (!m_hasLastFrameTime) { - m_lastFrameTime = now; - m_hasLastFrameTime = true; - return; - } - - const float deltaTime = std::chrono::duration(now - m_lastFrameTime).count(); - m_lastFrameTime = now; - if (deltaTime <= 0.0f) { - return; - } - - if (m_smoothedDeltaTimeSeconds <= 0.0f) { - m_smoothedDeltaTimeSeconds = deltaTime; - } else { - m_smoothedDeltaTimeSeconds += - (deltaTime - m_smoothedDeltaTimeSeconds) * kFrameTimeSmoothingFactor; - } - - m_displayFrameTimeMs = m_smoothedDeltaTimeSeconds * 1000.0f; - m_displayFps = m_smoothedDeltaTimeSeconds > 0.0f - ? 1.0f / m_smoothedDeltaTimeSeconds - : 0.0f; - - m_frameStatsDisplayAccumulatorSeconds += deltaTime; - if (m_frameRateText.empty() || - m_frameStatsDisplayAccumulatorSeconds >= kFrameStatsDisplayRefreshIntervalSeconds) { - RefreshDisplayedFrameStats(); - m_frameStatsDisplayAccumulatorSeconds = 0.0f; - } -} - -void D3D12WindowRenderHost::RefreshDisplayedFrameStats() { - if (m_displayFps <= 0.0f || m_displayFrameTimeMs <= 0.0f) { - m_frameRateText.clear(); - return; - } - - const int roundedFps = (std::max)(0, static_cast(std::lround(m_displayFps))); - const int roundedFrameTimeMs = - (std::max)(0, static_cast(std::lround(m_displayFrameTimeMs))); - - char buffer[48] = {}; - std::snprintf( - buffer, - sizeof(buffer), - "FPS %3d | %2d ms", - roundedFps, - roundedFrameTimeMs); - m_frameRateText = buffer; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.h b/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.h deleted file mode 100644 index c221723e..00000000 --- a/new_editor/app/Platform/Win32/Rendering/D3D12WindowRenderHost.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace XCEngine::UI { - -class UIDrawData; - -} // namespace XCEngine::UI - -namespace XCEngine::UI::Editor::App { - -class D3D12WindowRenderHost final { -public: - D3D12WindowRenderHost() = default; - ~D3D12WindowRenderHost(); - - D3D12WindowRenderHost(const D3D12WindowRenderHost&) = delete; - D3D12WindowRenderHost& operator=(const D3D12WindowRenderHost&) = delete; - D3D12WindowRenderHost(D3D12WindowRenderHost&&) = delete; - D3D12WindowRenderHost& operator=(D3D12WindowRenderHost&&) = delete; - - bool IsReady() const; - bool HasViewportSurfacePresentation() const; - - void SetDpiScale(float dpiScale); - ::XCEngine::UI::Editor::UIEditorTextMeasurer& GetTextMeasurer(); - const ::XCEngine::UI::Editor::UIEditorTextMeasurer& GetTextMeasurer() const; - Host::D3D12UiTextureHost& GetTextureHost(); - const Host::D3D12UiTextureHost& GetTextureHost() const; - Host::D3D12WindowRenderer& GetWindowRenderer(); - const Host::D3D12WindowRenderer& GetWindowRenderer() const; - - bool Initialize(HWND hwnd); - void WaitForGpuIdle(); - void Shutdown(); - void ResetFrameTiming(); - bool ApplyResize(UINT width, UINT height); - - Host::D3D12WindowRenderLoopFrameContext BeginFrame(); - Host::D3D12WindowRenderLoopPresentResult Present( - const ::XCEngine::UI::UIDrawData& drawData, - const std::filesystem::path* capturePath = nullptr); - - const std::string& BuildFrameRateText() const; - -private: - void UpdateFrameTiming(); - void RefreshDisplayedFrameStats(); - - Host::D3D12WindowRenderer m_windowRenderer = {}; - Host::D3D12UiTextureHost m_textureHost = {}; - Host::D3D12UiTextSystem m_textSystem = {}; - Host::D3D12UiRenderer m_uiRenderer = {}; - Host::D3D12WindowRenderLoop m_windowRenderLoop = {}; - std::chrono::steady_clock::time_point m_lastFrameTime = {}; - bool m_hasLastFrameTime = false; - float m_smoothedDeltaTimeSeconds = 0.0f; - float m_frameStatsDisplayAccumulatorSeconds = 0.0f; - float m_displayFps = 0.0f; - float m_displayFrameTimeMs = 0.0f; - float m_dpiScale = 1.0f; - std::string m_frameRateText = {}; - bool m_ready = false; - bool m_hasViewportSurfacePresentation = false; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp b/new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp deleted file mode 100644 index fdc5bb58..00000000 --- a/new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp +++ /dev/null @@ -1,297 +0,0 @@ -#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" - -#include "Bootstrap/EditorResources.h" -#include "Composition/EditorContext.h" -#include "Platform/Win32/Windowing/EditorWindowSupport.h" -#include "Support/EmbeddedPngLoader.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -using App::LoadEmbeddedPngTexture; -using namespace EditorWindowSupport; - -EditorWindowRuntimeController::EditorWindowRuntimeController( - EditorWindowContentSpec contentSpec, - Windowing::Domain::WindowType windowType) - : m_windowType(windowType) - , m_contentRuntime(std::move(contentSpec)) {} - -EditorWindowRuntimeController::~EditorWindowRuntimeController() = default; - -bool EditorWindowRuntimeController::IsReady() const { - return m_renderHost.IsReady(); -} - -const UIEditorWorkspaceController& EditorWindowRuntimeController::GetWorkspaceController() const { - return m_contentRuntime.GetWorkspaceController(); -} - -void EditorWindowRuntimeController::ReplaceWorkspaceController( - UIEditorWorkspaceController workspaceController) { - m_contentRuntime.ReplaceWorkspaceController(std::move(workspaceController)); -} - -void EditorWindowRuntimeController::UpdateUtilityWindowSession( - EditorUtilityWindowSession session) { - m_contentRuntime.UpdateUtilityWindowSession(std::move(session)); -} - -void EditorWindowRuntimeController::SetExternalDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview) { - m_contentRuntime.SetExternalDockHostDropPreview(preview); -} - -void EditorWindowRuntimeController::ClearExternalDockHostDropPreview() { - m_contentRuntime.ClearExternalDockHostDropPreview(); -} - -bool EditorWindowRuntimeController::TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const ::XCEngine::UI::UIPoint& point, - ::XCEngine::UI::UIPoint& outHotspot) const { - return m_contentRuntime.TryResolveDockTabDragHotspot( - nodeId, - panelId, - point, - outHotspot); -} - -UIEditorDockHostTabDropTarget EditorWindowRuntimeController::ResolveDockTabDropTarget( - const ::XCEngine::UI::UIPoint& point) const { - return m_contentRuntime.ResolveDockTabDropTarget(point); -} - -EditorWindowContentPresentationSummary EditorWindowRuntimeController::BuildPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const { - return m_contentRuntime.BuildPresentationSummary(fallbackTabTitle, fallbackWindowTitle); -} - -Windowing::Domain::WindowCaptureDemand EditorWindowRuntimeController::GetCurrentCaptureDemand() - const { - return m_latestContentOutput.captureDemand.value_or(Windowing::Domain::WindowCaptureDemand{}); -} - -Windowing::Domain::WindowCursorType EditorWindowRuntimeController::GetCurrentCursorType() const { - return m_latestContentOutput.cursorType.value_or(Windowing::Domain::WindowCursorType::Arrow); -} - -const UIEditorShellInteractionFrame& EditorWindowRuntimeController::GetShellFrame() const { - return m_contentRuntime.GetShellFrame(); -} - -const UIEditorShellInteractionState& EditorWindowRuntimeController::GetShellInteractionState() - const { - return m_contentRuntime.GetShellInteractionState(); -} - -::XCEngine::UI::UISize EditorWindowRuntimeController::ResolveMinimumOuterSize() const { - return m_contentRuntime.ResolveMinimumOuterSize(); -} - -void EditorWindowRuntimeController::SetDpiScale(float dpiScale) { - m_renderHost.SetDpiScale(dpiScale); -} - -::XCEngine::UI::Editor::UIEditorTextMeasurer& EditorWindowRuntimeController::GetTextMeasurer() { - return m_renderHost.GetTextMeasurer(); -} - -const ::XCEngine::UI::Editor::UIEditorTextMeasurer& -EditorWindowRuntimeController::GetTextMeasurer() const { - return m_renderHost.GetTextMeasurer(); -} - -const ::XCEngine::UI::UITextureHandle& EditorWindowRuntimeController::GetTitleBarLogoIcon() const { - return m_titleBarLogoIcon; -} - -bool EditorWindowRuntimeController::Initialize( - HWND hwnd, - const std::filesystem::path& repoRoot, - EditorContext& editorContext, - const std::filesystem::path& captureRoot, - bool autoCaptureOnStartup) { - if (!m_renderHost.Initialize(hwnd)) { - return false; - } - - editorContext.AttachTextMeasurer(m_renderHost.GetTextMeasurer()); - m_contentRuntime.Initialize(EditorWindowContentInitializationContext{ - .repoRoot = repoRoot, - .editorContext = editorContext, - .textureHost = m_renderHost.GetTextureHost(), - .textMeasurer = m_renderHost.GetTextMeasurer(), - .viewportRenderer = m_renderHost.GetWindowRenderer(), - }); - m_contentRuntime.SetViewportSurfacePresentationEnabled( - m_renderHost.HasViewportSurfacePresentation()); - - std::string titleBarLogoError = {}; - if (!LoadEmbeddedPngTexture( - m_renderHost.GetTextureHost(), - IDR_PNG_LOGO_ICON, - m_titleBarLogoIcon, - titleBarLogoError)) { - LogRuntimeTrace("icons", "titlebar logo_icon.png: " + titleBarLogoError); - } - - const bool workspaceWindow = - m_windowType == Windowing::Domain::WindowType::PrimaryWorkspace || - m_windowType == Windowing::Domain::WindowType::DetachedWorkspace; - if (workspaceWindow) { - LogRuntimeTrace( - "app", - "shell runtime initialized: " + - editorContext.DescribeWorkspaceState( - GetWorkspaceController(), - m_contentRuntime.GetShellInteractionState())); - } else { - LogRuntimeTrace("app", "window content initialized: non-workspace content"); - } - - m_screenshotController.Initialize(captureRoot); - if (autoCaptureOnStartup) { - m_screenshotController.RequestCapture("startup"); - editorContext.SetStatus("Capture", "Startup capture requested."); - } - - return true; -} - -void EditorWindowRuntimeController::Shutdown() { - LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=WaitForGpuIdle"); - m_renderHost.WaitForGpuIdle(); - LogRuntimeTrace( - "window-close", - "EditorWindowRuntimeController::Shutdown stage=ScreenshotController"); - m_screenshotController.Shutdown(); - LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=WindowContent"); - m_contentRuntime.Shutdown(); - m_latestContentOutput = {}; - LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=TitleBarLogo"); - m_renderHost.GetTextureHost().ReleaseTexture(m_titleBarLogoIcon); - LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown stage=RenderHost"); - m_renderHost.Shutdown(); - LogRuntimeTrace("window-close", "EditorWindowRuntimeController::Shutdown end"); -} - -void EditorWindowRuntimeController::ResetInteractionState() { - m_contentRuntime.ResetInteractionState(); - m_latestContentOutput = {}; - m_renderHost.ResetFrameTiming(); -} - -bool EditorWindowRuntimeController::ApplyResize(UINT width, UINT height) { - if (!m_renderHost.IsReady() || width == 0u || height == 0u) { - return false; - } - - const bool hasViewportSurfacePresentation = m_renderHost.ApplyResize(width, height); - m_contentRuntime.SetViewportSurfacePresentationEnabled( - hasViewportSurfacePresentation); - - return hasViewportSurfacePresentation; -} - -EditorWindowContentUpdateResult EditorWindowRuntimeController::RenderFrame( - const EditorWindowContentFrameContext* contentContext, - ::XCEngine::UI::UIDrawData& drawData, - const std::function& finalizeFrame) { - if (contentContext != nullptr) { - contentContext->editorContext.AttachTextMeasurer(m_renderHost.GetTextMeasurer()); - } - - const Host::D3D12WindowRenderLoopFrameContext frameContext = m_renderHost.BeginFrame(); - if (!frameContext.warning.empty()) { - LogRuntimeTrace("viewport", frameContext.warning); - } - - EditorWindowContentUpdateResult updateResult = {}; - if (contentContext != nullptr) { - updateResult = UpdateAndAppend(*contentContext, drawData); - m_latestContentOutput = updateResult.contentOutput; - if (frameContext.canRenderViewports) { - m_contentRuntime.RenderRequestedViewports(frameContext.renderContext); - } - } else { - m_latestContentOutput = {}; - } - - if (finalizeFrame) { - finalizeFrame(drawData); - } - - if (!frameContext.canRenderViewports) { - return updateResult; - } - - std::filesystem::path capturePath = {}; - const bool captureRequested = m_screenshotController.TryBeginCapture(capturePath); - Host::D3D12WindowRenderLoopPresentResult presentResult = - m_renderHost.Present(drawData, captureRequested ? &capturePath : nullptr); - - if (captureRequested) { - const bool captureSucceeded = presentResult.framePresented && - presentResult.captureSucceeded; - if (captureSucceeded) { - m_screenshotController.CompleteCaptureSuccess(capturePath); - LogRuntimeTrace("capture", "native d3d12 capture succeeded: " + capturePath.string()); - } else { - std::string captureError = presentResult.captureError; - if (captureError.empty()) { - captureError = !presentResult.warning.empty() - ? presentResult.warning - : "Screenshot capture did not complete."; - } - m_screenshotController.CompleteCaptureFailure(std::move(captureError)); - LogRuntimeTrace( - "capture", - "native d3d12 capture failed: " + m_screenshotController.GetLastCaptureError()); - } - } - - if (!presentResult.warning.empty()) { - LogRuntimeTrace("present", presentResult.warning); - } - - return updateResult; -} - -EditorWindowContentUpdateResult EditorWindowRuntimeController::UpdateAndAppend( - const EditorWindowContentFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData) { - return m_contentRuntime.UpdateAndAppend(context, drawData); -} - -void EditorWindowRuntimeController::RequestManualScreenshot(std::string reason) { - m_screenshotController.RequestCapture(std::move(reason)); -} - -std::string EditorWindowRuntimeController::BuildCaptureStatusText() const { - if (m_screenshotController.HasPendingCapture()) { - return "Shot pending..."; - } - - if (!m_screenshotController.GetLastCaptureError().empty()) { - return TruncateText(m_screenshotController.GetLastCaptureError(), 38u); - } - - if (!m_screenshotController.GetLastCaptureSummary().empty()) { - return TruncateText(m_screenshotController.GetLastCaptureSummary(), 38u); - } - - return {}; -} - -std::string EditorWindowRuntimeController::BuildFrameRateText() const { - return m_renderHost.BuildFrameRateText(); -} - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp deleted file mode 100644 index 25344da1..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp +++ /dev/null @@ -1,1270 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Bootstrap/EditorResources.h" -#include "Platform/Win32/Backend/Win32NativeWindowBackend.h" -#include "Platform/Win32/Chrome/EditorWindowChromeController.h" -#include "Platform/Win32/Chrome/EditorWindowChromeProjection.h" -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" -#include "Platform/Win32/Windowing/EditorWindowSession.h" -#include "Platform/Win32/Windowing/EditorWindowSupport.h" -#include "Windowing/Content/EditorWindowFrameOrchestrator.h" -#include "Platform/Win32/Runtime/EditorWindowInputController.h" -#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h" -#include "Composition/EditorContext.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App::EditorWindowSupport { - -bool ResolveVerboseRuntimeTraceEnabled() { - wchar_t buffer[8] = {}; - const DWORD length = GetEnvironmentVariableW( - L"XCUIEDITOR_VERBOSE_TRACE", - buffer, - static_cast(std::size(buffer))); - return length > 0u && buffer[0] != L'0'; -} - -void LogRuntimeTrace(std::string_view channel, std::string_view message) { - AppendUIEditorRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App::EditorWindowSupport - -namespace XCEngine::UI::Editor::App { - -using namespace EditorWindowSupport; -using ::XCEngine::UI::UIPoint; - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -Domain::WindowCommand BuildSetWindowBoundsCommand(const RECT& rect) { - return Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::SetWindowBounds, - .x = rect.left, - .y = rect.top, - .width = rect.right - rect.left, - .height = rect.bottom - rect.top, - }; -} - -} // namespace - -EditorWindow::EditorWindow( - std::string windowId, - Domain::WindowType windowType, - std::wstring title, - bool primary, - EditorWindowContentSpec contentSpec, - Win32NativeWindowBackend& nativeWindowBackend, - Win32WindowCommandProjector& windowCommandProjector) - : m_session(std::make_unique( - std::move(windowId), - windowType, - std::move(title), - primary)) - , m_nativeWindowBackend(nativeWindowBackend) - , m_windowCommandProjector(windowCommandProjector) - , m_chromeController( - std::make_unique( - nativeWindowBackend, - windowCommandProjector)) - , m_frameOrchestrator(std::make_unique()) - , m_inputController(std::make_unique()) - , m_runtime(std::make_unique( - std::move(contentSpec), - windowType)) {} - -EditorWindow::~EditorWindow() = default; - -std::string_view EditorWindow::GetWindowId() const { - return m_session->GetWindowId(); -} - -HWND EditorWindow::GetHwnd() const { - return m_session->GetHwnd(); -} - -bool EditorWindow::HasHwnd() const { - return m_session->HasHwnd(); -} - -EditorWindowLifecycleState EditorWindow::GetLifecycleState() const { - return m_session->GetLifecycleState(); -} - -bool EditorWindow::IsPrimary() const { - return m_session->IsPrimary(); -} - -bool EditorWindow::IsClosing() const { - return m_session->IsClosing(); -} - -bool EditorWindow::IsDestroyed() const { - return m_session->IsDestroyed(); -} - -Domain::WindowType EditorWindow::GetWindowType() const { - return m_session->GetWindowType(); -} - -bool EditorWindow::IsWorkspaceWindow() const { - return GetWindowType() == Domain::WindowType::PrimaryWorkspace || - GetWindowType() == Domain::WindowType::DetachedWorkspace; -} - -bool EditorWindow::IsRenderReady() const { - return m_runtime->IsReady(); -} - -const std::wstring& EditorWindow::GetTitle() const { - return m_session->GetTitle(); -} - -std::string_view EditorWindow::GetCachedTitleText() const { - return m_session->GetCachedTitleText(); -} - -const UIEditorWorkspaceController& EditorWindow::GetWorkspaceController() const { - assert(IsWorkspaceWindow()); - return m_runtime->GetWorkspaceController(); -} - -EditorWindowContentPresentationSummary EditorWindow::BuildContentPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const { - return m_runtime->BuildPresentationSummary(fallbackTabTitle, fallbackWindowTitle); -} - -void EditorWindow::BindFrameRequestSource(EditorWindowFrameRequestSource& frameRequestSource) { - m_frameRequestSource = &frameRequestSource; -} - -void EditorWindow::AttachHwnd(HWND hwnd) { - m_session->AttachHwnd(hwnd); -} - -void EditorWindow::MarkInitializing() { - m_session->MarkInitializing(); -} - -void EditorWindow::MarkRunning() { - m_session->MarkRunning(); -} - -void EditorWindow::MarkDestroyed() { - m_session->MarkDestroyed(); - m_session->ResetInputWindowState(); - m_inputController->ResetWindowState(); -} - -void EditorWindow::MarkClosing() { - m_session->MarkClosing(); -} - -void EditorWindow::SetPrimary(bool primary) { - m_session->SetPrimary(primary); -} - -void EditorWindow::SetTitle(std::wstring title) { - m_session->SetTitle(std::move(title)); -} - -void EditorWindow::SetWindowDpi(UINT dpi) { - m_session->SetWindowDpi(dpi); -} - -UINT EditorWindow::GetWindowDpi() const { - return m_session->GetWindowDpi(); -} - -void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) { - assert(IsWorkspaceWindow()); - m_runtime->ReplaceWorkspaceController(std::move(workspaceController)); -} - -void EditorWindow::UpdateUtilityWindowSession(EditorUtilityWindowSession session) { - assert(GetWindowType() == Domain::WindowType::Utility); - m_runtime->UpdateUtilityWindowSession(std::move(session)); -} - -void EditorWindow::InvalidateHostWindow() const { - m_nativeWindowBackend.InvalidateWindow(m_session->GetHwnd()); -} - -bool EditorWindow::Initialize( - const std::filesystem::path& repoRoot, - EditorContext& editorContext, - const std::filesystem::path& captureRoot, - bool autoCaptureOnStartup) { - if (m_session->GetHwnd() == nullptr) { - LogRuntimeTrace("app", "window initialize skipped: hwnd is null"); - return false; - } - - Host::RefreshBorderlessWindowDwmDecorations(m_session->GetHwnd()); - ResetChromeWindowState(); - SetWindowDpi(m_nativeWindowBackend.QueryWindowDpi(m_session->GetHwnd())); - m_runtime->SetDpiScale(GetDpiScale()); - - std::ostringstream dpiTrace = {}; - dpiTrace << "initial dpi=" << GetWindowDpi() - << " scale=" << GetDpiScale(); - LogRuntimeTrace("window", dpiTrace.str()); - - MarkInitializing(); - const bool initialized = m_runtime->Initialize( - m_session->GetHwnd(), - repoRoot, - editorContext, - captureRoot, - autoCaptureOnStartup); - if (initialized) { - MarkRunning(); - } else { - m_session->MarkNativeAttached(); - } - return initialized; -} - -void EditorWindow::Shutdown() { - std::ostringstream trace = {}; - trace << "EditorWindow::Shutdown begin windowId='" << GetWindowId() - << "' hwnd=0x" << std::hex << std::uppercase - << reinterpret_cast(GetHwnd()) - << std::dec - << " primary=" << (IsPrimary() ? 1 : 0) - << " lifecycle=" << GetEditorWindowLifecycleStateName(GetLifecycleState()) - << " runtimeReady=" << (m_runtime->IsReady() ? 1 : 0); - LogRuntimeTrace("window-close", trace.str()); - ForceReleasePointerCapture(); - - if (m_runtime->IsReady()) { - m_runtime->Shutdown(); - } - m_inputController->ClearPendingEvents(); - ResetChromeWindowState(); - LogRuntimeTrace( - "window-close", - "EditorWindow::Shutdown end windowId='" + std::string(GetWindowId()) + "'"); -} - -void EditorWindow::ResetInteractionState() { - ForceReleasePointerCapture(); - m_session->ResetInputWindowState(); - - m_inputController->ResetInteractionState(); - m_runtime->ResetInteractionState(); - ResetChromeState(); - EndBorderlessResize(); - EndBorderlessWindowDragRestore(); - EndInteractiveResize(); - SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge::None); - ClearPredictedClientPixelSize(); -} - -bool EditorWindow::ApplyWindowResize(UINT width, UINT height) { - if (!m_runtime->IsReady() || width == 0u || height == 0u) { - return false; - } - return m_runtime->ApplyResize(width, height); -} - -bool EditorWindow::QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const { - outWidth = 0u; - outHeight = 0u; - const HWND hwnd = m_session->GetHwnd(); - if (hwnd == nullptr) { - return false; - } - - RECT clientRect = {}; - if (!m_nativeWindowBackend.TryGetClientRect(hwnd, clientRect)) { - return false; - } - - const LONG width = clientRect.right - clientRect.left; - const LONG height = clientRect.bottom - clientRect.top; - if (width <= 0 || height <= 0) { - return false; - } - - outWidth = static_cast(width); - outHeight = static_cast(height); - return true; -} - -bool EditorWindow::ResolveRenderClientPixelSize(UINT& outWidth, UINT& outHeight) const { - if (TryGetPredictedClientPixelSize(outWidth, outHeight)) { - return true; - } - - return QueryCurrentClientPixelSize(outWidth, outHeight); -} - -float EditorWindow::GetDpiScale() const { - return m_session->GetDpiScale(kBaseDpiScale); -} - -float EditorWindow::PixelsToDips(float pixels) const { - const float dpiScale = GetDpiScale(); - return dpiScale > 0.0f ? pixels / dpiScale : pixels; -} - -UIPoint EditorWindow::ConvertClientPixelsToDips(LONG x, LONG y) const { - return UIPoint( - PixelsToDips(static_cast(x)), - PixelsToDips(static_cast(y))); -} - -UIPoint EditorWindow::ConvertScreenPixelsToClientDips(const POINT& screenPoint) const { - POINT clientPoint = screenPoint; - if (const HWND hwnd = m_session->GetHwnd(); - hwnd != nullptr) { - m_nativeWindowBackend.TryConvertScreenToClient(hwnd, clientPoint); - } - - const float dpiScale = GetDpiScale(); - return UIPoint( - dpiScale > 0.0f - ? static_cast(clientPoint.x) / dpiScale - : static_cast(clientPoint.x), - dpiScale > 0.0f - ? static_cast(clientPoint.y) / dpiScale - : static_cast(clientPoint.y)); -} - -bool EditorWindow::TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const POINT& screenPoint, - POINT& outHotspot) const { - if (!IsWorkspaceWindow()) { - outHotspot = {}; - return false; - } - - const UIPoint clientPointDips = ConvertScreenPixelsToClientDips(screenPoint); - UIPoint hotspotDips = {}; - if (!m_runtime->TryResolveDockTabDragHotspot( - nodeId, - panelId, - clientPointDips, - hotspotDips)) { - outHotspot = {}; - return false; - } - - const float dpiScale = GetDpiScale(); - outHotspot.x = static_cast(std::lround(hotspotDips.x * dpiScale)); - outHotspot.y = static_cast(std::lround(hotspotDips.y * dpiScale)); - return true; -} - -bool EditorWindow::TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outHotspot) const { - POINT win32Hotspot = {}; - if (!TryResolveDockTabDragHotspot( - nodeId, - panelId, - POINT{screenPoint.x, screenPoint.y}, - win32Hotspot)) { - outHotspot = {}; - return false; - } - - outHotspot = EditorWindowScreenPoint{win32Hotspot.x, win32Hotspot.y}; - return true; -} - -bool EditorWindow::TryResolveDockTabDropTarget( - const POINT& screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const { - if (!IsWorkspaceWindow()) { - outTarget = {}; - return false; - } - - outTarget = m_runtime->ResolveDockTabDropTarget( - ConvertScreenPixelsToClientDips(screenPoint)); - return outTarget.valid; -} - -bool EditorWindow::TryResolveDockTabDropTarget( - EditorWindowScreenPoint screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const { - return TryResolveDockTabDropTarget( - POINT{screenPoint.x, screenPoint.y}, - outTarget); -} - -bool EditorWindow::SetDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview) { - if (!IsWorkspaceWindow()) { - return false; - } - - m_runtime->SetExternalDockHostDropPreview(preview); - InvalidateHostWindow(); - return true; -} - -bool EditorWindow::ClearDockHostDropPreview() { - if (!IsWorkspaceWindow()) { - return false; - } - - m_runtime->ClearExternalDockHostDropPreview(); - InvalidateHostWindow(); - return true; -} - -::XCEngine::UI::UISize EditorWindow::ResolveMinimumOuterSize() const { - return m_runtime->ResolveMinimumOuterSize(); -} - -EditorWindowChromeProjection EditorWindow::BuildChromeProjection() const { - EditorWindowChromeProjection projection = {}; - projection.titleBarLogoIcon = m_runtime->GetTitleBarLogoIcon(); - - const std::string_view cachedTitleText = GetCachedTitleText(); - const std::string_view fallbackWindowTitle = - cachedTitleText.empty() - ? std::string_view("XCEngine Editor") - : cachedTitleText; - - const EditorWindowContentPresentationSummary contentPresentation = - BuildContentPresentationSummary("Panel", fallbackWindowTitle); - projection.useDetachedTitleBarTabStrip = - !IsPrimary() && - IsWorkspaceWindow() && - contentPresentation.useDetachedTitleBarTabStrip; - - if (projection.useDetachedTitleBarTabStrip) { - const Widgets::UIEditorTabStripMetrics& metrics = ResolveUIEditorTabStripMetrics(); - Widgets::UIEditorTabStripItem item = {}; - item.title = contentPresentation.tabStripTitleText; - const float measuredLabelWidth = Widgets::ResolveUIEditorTabStripMeasuredLabelWidth( - item, - metrics, - &m_runtime->GetTextMeasurer()); - projection.detachedTabStripLeadingWidth = ::XCEngine::UI::Layout::MeasureUITabStripHeaderWidth( - measuredLabelWidth, - metrics.layoutMetrics); - } - - projection.titleText = !IsPrimary() && IsWorkspaceWindow() - ? contentPresentation.detachedWindowTitleText - : std::string(fallbackWindowTitle); - - if (IsPrimary()) { - projection.frameRateText = m_runtime->BuildFrameRateText(); - if (!projection.frameRateText.empty()) { - projection.frameRateTextWidth = m_runtime->GetTextMeasurer().MeasureTextWidth( - UIEditorTextMeasureRequest{ - projection.frameRateText, - kBorderlessTitleBarFontSize, - }); - } - } - - return projection; -} - -void EditorWindow::ResetChromeWindowState() { - m_session->ResetChromeWindowState(); -} - -void EditorWindow::BeginInteractiveResize() { - m_session->BeginInteractiveResize(); -} - -void EditorWindow::EndInteractiveResize() { - m_session->EndInteractiveResize(); -} - -bool EditorWindow::IsInteractiveResize() const { - return m_session->IsInteractiveResize(); -} - -void EditorWindow::BeginBorderlessResize( - Host::BorderlessWindowResizeEdge edge, - const POINT& initialScreenPoint, - const RECT& initialWindowRect) { - m_session->BeginBorderlessResize(edge, initialScreenPoint, initialWindowRect); -} - -void EditorWindow::EndBorderlessResize() { - m_session->EndBorderlessResize(); -} - -bool EditorWindow::IsBorderlessResizeActive() const { - return m_session->IsBorderlessResizeActive(); -} - -Host::BorderlessWindowResizeEdge EditorWindow::GetBorderlessResizeEdge() const { - return m_session->GetBorderlessResizeEdge(); -} - -const POINT& EditorWindow::GetBorderlessResizeInitialScreenPoint() const { - return m_session->GetBorderlessResizeInitialScreenPoint(); -} - -const RECT& EditorWindow::GetBorderlessResizeInitialWindowRect() const { - return m_session->GetBorderlessResizeInitialWindowRect(); -} - -void EditorWindow::SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge edge) { - m_session->SetHoveredBorderlessResizeEdge(edge); -} - -Host::BorderlessWindowResizeEdge EditorWindow::GetHoveredBorderlessResizeEdge() const { - return m_session->GetHoveredBorderlessResizeEdge(); -} - -void EditorWindow::SetBorderlessWindowMaximized(bool maximized) { - m_session->SetBorderlessWindowMaximized(maximized); -} - -bool EditorWindow::IsBorderlessWindowMaximized() const { - return m_session->IsBorderlessWindowMaximized(); -} - -void EditorWindow::SetBorderlessWindowRestoreRect(const RECT& rect) { - m_session->SetBorderlessWindowRestoreRect(rect); -} - -bool EditorWindow::TryGetBorderlessWindowRestoreRect(RECT& outRect) const { - return m_session->TryGetBorderlessWindowRestoreRect(outRect); -} - -void EditorWindow::BeginBorderlessWindowDragRestore(const POINT& initialScreenPoint) { - m_session->BeginBorderlessWindowDragRestore(initialScreenPoint); -} - -void EditorWindow::EndBorderlessWindowDragRestore() { - m_session->EndBorderlessWindowDragRestore(); -} - -bool EditorWindow::IsBorderlessWindowDragRestoreArmed() const { - return m_session->IsBorderlessWindowDragRestoreArmed(); -} - -const POINT& EditorWindow::GetBorderlessWindowDragRestoreInitialScreenPoint() const { - return m_session->GetBorderlessWindowDragRestoreInitialScreenPoint(); -} - -Host::BorderlessWindowChromeHitTarget EditorWindow::GetHoveredChromeTarget() const { - return m_session->GetHoveredChromeTarget(); -} - -void EditorWindow::SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget target) { - m_session->SetHoveredChromeTarget(target); -} - -Host::BorderlessWindowChromeHitTarget EditorWindow::GetPressedChromeTarget() const { - return m_session->GetPressedChromeTarget(); -} - -void EditorWindow::SetPressedChromeTarget(Host::BorderlessWindowChromeHitTarget target) { - m_session->SetPressedChromeTarget(target); -} - -void EditorWindow::ResetChromeState() { - m_session->ResetChromeState(); -} - -bool EditorWindow::IsChromeStateClear() const { - return m_session->IsChromeStateClear(); -} - -const Host::BorderlessWindowChromeState& EditorWindow::GetChromeState() const { - return m_session->GetChromeState(); -} - -bool EditorWindow::OnResize(UINT width, UINT height) { - const bool matchedPresentedPrediction = - ConsumePresentedPredictedClientPixelSizeMatch(width, height); - if (!matchedPresentedPrediction) { - ClearPredictedClientPixelSize(); - } - if (const HWND hwnd = m_session->GetHwnd(); - hwnd != nullptr) { - Host::RefreshBorderlessWindowDwmDecorations(hwnd); - } - - if (matchedPresentedPrediction) { - return false; - } - - ApplyWindowResize(width, height); - return true; -} - -void EditorWindow::OnEnterSizeMove() { - BeginInteractiveResize(); -} - -bool EditorWindow::OnExitSizeMove() { - EndInteractiveResize(); - ClearPredictedClientPixelSize(); - UINT width = 0u; - UINT height = 0u; - if (QueryCurrentClientPixelSize(width, height)) { - ApplyWindowResize(width, height); - return true; - } - return false; -} - -void EditorWindow::OnDpiChanged(UINT dpi, const RECT& suggestedRect) { - SetWindowDpi(dpi == 0u ? kDefaultDpi : dpi); - m_runtime->SetDpiScale(GetDpiScale()); - if (const HWND hwnd = m_session->GetHwnd(); - hwnd != nullptr) { - m_windowCommandProjector.ProjectCommand(hwnd, BuildSetWindowBoundsCommand(suggestedRect)); - UINT clientWidth = 0u; - UINT clientHeight = 0u; - if (QueryCurrentClientPixelSize(clientWidth, clientHeight)) { - ApplyWindowResize(clientWidth, clientHeight); - } - Host::RefreshBorderlessWindowDwmDecorations(hwnd); - } - - std::ostringstream trace = {}; - trace << "dpi changed to " << GetWindowDpi() - << " scale=" << GetDpiScale(); - LogRuntimeTrace("window", trace.str()); -} - -bool EditorWindow::IsVerboseRuntimeTraceEnabled() { - static const bool s_enabled = ResolveVerboseRuntimeTraceEnabled(); - return s_enabled; -} - -} // namespace XCEngine::UI::Editor::App - -namespace XCEngine::UI::Editor::App { - -using namespace EditorWindowSupport; -using ::XCEngine::UI::UIDrawData; -using ::XCEngine::UI::UIDrawList; -using ::XCEngine::UI::UIInputEvent; -using ::XCEngine::UI::UIInputModifiers; -using ::XCEngine::UI::UIPointerButton; -using ::XCEngine::UI::UIRect; - -namespace { - -std::uint8_t ButtonMask(UIPointerButton button) { - switch (button) { - case UIPointerButton::Left: return 1u << 0u; - case UIPointerButton::Right: return 1u << 1u; - case UIPointerButton::Middle: return 1u << 2u; - case UIPointerButton::X1: return 1u << 3u; - case UIPointerButton::X2: return 1u << 4u; - case UIPointerButton::None: - default: - return 0u; - } -} - -std::uint8_t ButtonMaskFromModifiers(const UIInputModifiers& modifiers) { - std::uint8_t mask = 0u; - if (modifiers.leftMouse) { - mask |= ButtonMask(UIPointerButton::Left); - } - if (modifiers.rightMouse) { - mask |= ButtonMask(UIPointerButton::Right); - } - if (modifiers.middleMouse) { - mask |= ButtonMask(UIPointerButton::Middle); - } - if (modifiers.x1Mouse) { - mask |= ButtonMask(UIPointerButton::X1); - } - if (modifiers.x2Mouse) { - mask |= ButtonMask(UIPointerButton::X2); - } - return mask; -} - -std::uint8_t ResolveExpectedShellCaptureButtons( - const UIEditorShellInteractionState& shellState) { - std::uint8_t expectedButtons = 0u; - const auto& dockHostState = - shellState.workspaceInteractionState.dockHostInteractionState; - if (dockHostState.splitterDragState.active || - !dockHostState.activeTabDragNodeId.empty()) { - expectedButtons |= ButtonMask(UIPointerButton::Left); - } - - for (const auto& panelState : - shellState.workspaceInteractionState.composeState.panelStates) { - const auto& inputBridgeState = panelState.viewportShellState.inputBridgeState; - if (inputBridgeState.captured) { - expectedButtons |= ButtonMask(inputBridgeState.captureButton); - } - } - - return expectedButtons; -} - -} // namespace - -EditorWindowContentUpdateResult EditorWindow::RenderFrame( - EditorContext& editorContext, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow, - bool globalTabDragActive) { - if (!m_runtime->IsReady() || m_session->GetHwnd() == nullptr) { - return {}; - } - - UINT pixelWidth = 0u; - UINT pixelHeight = 0u; - if (!ResolveRenderClientPixelSize(pixelWidth, pixelHeight)) { - return {}; - } - - const float width = PixelsToDips(static_cast(pixelWidth)); - const float height = PixelsToDips(static_cast(pixelHeight)); - const UIRect workspaceBounds = ResolveWorkspaceBounds(width, height); - - UIDrawData drawData = {}; - UIDrawList& backgroundDrawList = drawData.EmplaceDrawList("XCEditorWindow.Surface"); - backgroundDrawList.AddFilledRect( - UIRect(0.0f, 0.0f, width, height), - kShellSurfaceColor); - - EditorWindowContentUpdateResult updateResult = {}; - if (editorContext.IsValid()) { - updateResult = - RenderRuntimeFrame( - editorContext, - utilityWindowResultState, - utilityRequestSink, - workspaceTransferQueue, - utilityWindowFrameWorkflow, - globalTabDragActive, - width, - workspaceBounds, - drawData); - } else { - UIDrawList& invalidDrawList = drawData.EmplaceDrawList("XCEditorWindow.Invalid"); - m_frameOrchestrator->AppendInvalidFrame(editorContext, invalidDrawList); - m_runtime->RenderFrame( - nullptr, - drawData, - [this, width](UIDrawData& frameDrawData) { - UIDrawList& windowChromeDrawList = - frameDrawData.EmplaceDrawList("XCEditorWindow.Chrome"); - m_chromeController->AppendChrome(*this, windowChromeDrawList, width); - }); - return {}; - } - return updateResult; -} - -void EditorWindow::RequestInteractionFrame() { - if (m_frameRequestSource == nullptr) { - return; - } - - m_frameRequestSource->RequestImmediateFrame( - GetWindowId(), - Windowing::Domain::FramePriority::High, - Windowing::Domain::FrameReason::InteractionContinuation); -} - -void EditorWindow::SetPredictedClientPixelSize(UINT width, UINT height) { - m_session->SetPredictedClientPixelSize(width, height); -} - -void EditorWindow::ClearPredictedClientPixelSize() { - m_session->ClearPredictedClientPixelSize(); -} - -bool EditorWindow::TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const { - return m_session->TryGetPredictedClientPixelSize(outWidth, outHeight); -} - -void EditorWindow::MarkPredictedClientPixelSizePresented() { - m_session->MarkPredictedClientPixelSizePresented(); -} - -bool EditorWindow::ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height) { - return m_session->ConsumePresentedPredictedClientPixelSizeMatch(width, height); -} - -UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const { - if (BuildChromeProjection().useDetachedTitleBarTabStrip) { - return UIRect(0.0f, 0.0f, clientWidthDips, clientHeightDips); - } - - const float titleBarHeight = (std::min)(kBorderlessTitleBarHeightDips, clientHeightDips); - return UIRect( - 0.0f, - titleBarHeight, - clientWidthDips, - (std::max)(0.0f, clientHeightDips - titleBarHeight)); -} - -EditorWindowContentUpdateResult EditorWindow::RenderRuntimeFrame( - EditorContext& editorContext, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow, - bool globalTabDragActive, - float windowWidth, - const UIRect& workspaceBounds, - UIDrawData& drawData) { - SyncShellCapturedPointerButtonsFromSystemState(); - std::vector frameEvents = m_inputController->TakePendingEvents(); - const EditorWindowChromeProjection chromeProjection = BuildChromeProjection(); - POINT cursorScreenPoint = {}; - const bool hasCursorScreenPoint = - m_nativeWindowBackend.TryGetCursorScreenPoint(cursorScreenPoint); - const EditorWindowContentFrameContext frameContext{ - .editorContext = editorContext, - .utilityWindowResultState = utilityWindowResultState, - .utilityWindowFrameWorkflow = utilityWindowFrameWorkflow, - .utilityRequestSink = utilityRequestSink, - .workspaceTransferQueue = workspaceTransferQueue, - .sourceWindowId = GetWindowId(), - .bounds = workspaceBounds, - .inputEvents = frameEvents, - .captureStatusText = m_runtime->BuildCaptureStatusText(), - .primary = m_session->IsPrimary(), - .globalTabDragActive = globalTabDragActive, - .useDetachedTitleBarTabStrip = chromeProjection.useDetachedTitleBarTabStrip, - .cursorScreenX = cursorScreenPoint.x, - .cursorScreenY = cursorScreenPoint.y, - .hasCursorScreenPoint = hasCursorScreenPoint, - }; - - return m_runtime->RenderFrame( - &frameContext, - drawData, - [this, windowWidth](UIDrawData& frameDrawData) { - UIDrawList& windowChromeDrawList = - frameDrawData.EmplaceDrawList("XCEditorWindow.Chrome"); - m_chromeController->AppendChrome( - *this, - windowChromeDrawList, - windowWidth); - ApplyShellRuntimePointerCapture(); - ApplyCurrentCursor(); - }); -} - -void EditorWindow::SyncShellCapturedPointerButtonsFromSystemState() { - m_inputController->SyncInputModifiersFromSystemState(); - - const std::uint8_t expectedButtons = ResolveExpectedShellCaptureButtons( - m_runtime->GetShellInteractionState()); - if (expectedButtons == 0u || - m_inputController->HasPendingPointerStateReconciliationEvent()) { - return; - } - - const UIInputModifiers modifiers = m_inputController->GetCurrentModifiers(); - if ((ButtonMaskFromModifiers(modifiers) & expectedButtons) == expectedButtons) { - return; - } - - QueueSyntheticPointerStateSyncEvent(modifiers); -} - -void EditorWindow::ApplyShellRuntimePointerCapture() { - const Domain::WindowCaptureDemand captureDemand = m_runtime->GetCurrentCaptureDemand(); - if (captureDemand.shellInteractive) { - AcquirePointerCapture(EditorWindowPointerCaptureOwner::Shell); - return; - } - - if (captureDemand.hostedContent) { - AcquirePointerCapture(EditorWindowPointerCaptureOwner::HostedContent); - return; - } - - if (OwnsPointerCapture(EditorWindowPointerCaptureOwner::Shell)) { - ReleasePointerCapture(EditorWindowPointerCaptureOwner::Shell); - } - - if (OwnsPointerCapture(EditorWindowPointerCaptureOwner::HostedContent)) { - ReleasePointerCapture(EditorWindowPointerCaptureOwner::HostedContent); - } -} - -} // namespace XCEngine::UI::Editor::App - -namespace XCEngine::UI::Editor::App { - -using ::XCEngine::UI::UIInputEventType; -using ::XCEngine::UI::UIPointerButton; - -bool EditorWindow::ApplyCurrentCursor() const { - if (!HasInteractiveCaptureState() && !IsPointerInsideClientArea()) { - return false; - } - - return m_nativeWindowBackend.ApplyCursorResource(ResolveCurrentCursorResource()); -} - - -bool EditorWindow::HasInteractiveCaptureState() const { - return m_runtime->GetCurrentCaptureDemand().HasAny() || - IsBorderlessWindowDragRestoreArmed() || - IsBorderlessResizeActive() || - m_session->HasPointerCaptureOwner(); -} - -void EditorWindow::SetTrackingMouseLeave(bool trackingMouseLeave) { - m_session->SetTrackingMouseLeave(trackingMouseLeave); -} - -EditorWindowPointerCaptureOwner EditorWindow::GetPointerCaptureOwner() const { - return m_session->GetPointerCaptureOwner(); -} - -bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const { - return m_session->OwnsPointerCapture(owner); -} - -void EditorWindow::AcquirePointerCapture(EditorWindowPointerCaptureOwner owner) { - if (owner == EditorWindowPointerCaptureOwner::None) { - return; - } - - if (!m_inputController->AcquirePointerCapture(m_session->GetHwnd())) { - return; - } - - m_session->SetPointerCaptureOwner(owner); -} - -void EditorWindow::ReleasePointerCapture(EditorWindowPointerCaptureOwner owner) { - if (!m_session->OwnsPointerCapture(owner)) { - return; - } - - m_session->ClearPointerCaptureOwner(); - m_inputController->ReleasePointerCapture(m_session->GetHwnd()); -} - -void EditorWindow::ForceReleasePointerCapture() { - m_session->ClearPointerCaptureOwner(); - m_inputController->ForceReleasePointerCapture(m_session->GetHwnd()); -} - -void EditorWindow::ClearPointerCaptureOwner() { - m_session->ClearPointerCaptureOwner(); -} - -void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) { - const HWND hwnd = m_session->GetHwnd(); - if (hwnd == nullptr || - m_nativeWindowBackend.IsCurrentCaptureWindow(hwnd)) { - return; - } - - const ::XCEngine::UI::UIPoint clientPoint = ConvertClientPixelsToDips( - GET_X_LPARAM(lParam), - GET_Y_LPARAM(lParam)); - if (!ShouldStartImmediateUIEditorShellPointerCapture( - m_runtime->GetShellFrame(), - clientPoint)) { - return; - } - - AcquirePointerCapture(EditorWindowPointerCaptureOwner::Shell); -} - -bool EditorWindow::TryHandleChromeHoverConsumption(LPARAM lParam, LRESULT& outResult) { - const Domain::WindowCaptureDemand captureDemand = m_runtime->GetCurrentCaptureDemand(); - if (!CanConsumeEditorWindowChromeHover( - GetPointerCaptureOwner(), - captureDemand.shellInteractive, - captureDemand.hostedContent)) { - return false; - } - - const bool resizeHoverChanged = - m_chromeController->UpdateResizeHover(*this, lParam); - if (m_chromeController->UpdateChromeHover(*this, lParam)) { - InvalidateHostWindow(); - } - if (resizeHoverChanged) { - InvalidateHostWindow(); - } - - if (const HWND hwnd = m_session->GetHwnd(); - hwnd != nullptr) { - if (m_nativeWindowBackend.TrackMouseLeave(hwnd)) { - SetTrackingMouseLeave(true); - } - } - - if (GetHoveredBorderlessResizeEdge() != Host::BorderlessWindowResizeEdge::None) { - outResult = 0; - return true; - } - - const Host::BorderlessWindowChromeHitTarget chromeHitTarget = - m_chromeController->HitTestChrome(*this, lParam); - if (chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MinimizeButton || - chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton || - chromeHitTarget == Host::BorderlessWindowChromeHitTarget::CloseButton) { - outResult = 0; - return true; - } - - return false; -} - -bool EditorWindow::HandleResizePointerMove( - EditorContext& editorContext, - bool globalTabDragActive) { - return m_chromeController->HandleResizePointerMove( - *this, - editorContext, - globalTabDragActive); -} - -bool EditorWindow::HandleChromeDragRestorePointerMove( - EditorContext& editorContext, - bool globalTabDragActive) { - return m_chromeController->HandleChromeDragRestorePointerMove( - *this, - editorContext, - globalTabDragActive); -} - -bool EditorWindow::HandleResizeButtonDown(LPARAM lParam) { - return m_chromeController->HandleResizeButtonDown(*this, lParam); -} - -bool EditorWindow::HandleChromeButtonDown(LPARAM lParam) { - return m_chromeController->HandleChromeButtonDown(*this, lParam); -} - -bool EditorWindow::HandleResizeButtonUp() { - return m_chromeController->HandleResizeButtonUp(*this); -} - -bool EditorWindow::HandleChromeButtonUp( - EditorContext& editorContext, - bool globalTabDragActive, - LPARAM lParam) { - return m_chromeController->HandleChromeButtonUp( - *this, - editorContext, - globalTabDragActive, - lParam); -} - -bool EditorWindow::HandleChromeDoubleClick( - EditorContext& editorContext, - bool globalTabDragActive, - LPARAM lParam) { - return m_chromeController->HandleChromeDoubleClick( - *this, - editorContext, - globalTabDragActive, - lParam); -} - -void EditorWindow::ClearChromeInteractionState() { - m_chromeController->ClearResizeState(*this); - m_chromeController->ClearChromeDragRestoreState(*this); - m_chromeController->ClearChromeState(*this); -} - -void EditorWindow::ForceClearChromeInteractionState() { - m_chromeController->ForceClearResizeState(*this); - m_chromeController->ClearChromeDragRestoreState(*this); - m_chromeController->ClearChromeState(*this); -} - -bool EditorWindow::HandleGetMinMaxInfo(LPARAM lParam) const { - return m_chromeController->HandleGetMinMaxInfo(*this, lParam); -} - -LRESULT EditorWindow::HandleNcCalcSize(WPARAM wParam, LPARAM lParam) const { - return m_chromeController->HandleNcCalcSize(*this, wParam, lParam); -} - -bool EditorWindow::HandleSystemCommand( - EditorContext& editorContext, - bool globalTabDragActive, - WPARAM wParam) { - return m_chromeController->HandleSystemCommand( - *this, - editorContext, - globalTabDragActive, - wParam); -} - -void EditorWindow::RequestManualScreenshot(std::string_view reason) { - m_runtime->RequestManualScreenshot(std::string(reason)); -} - -void EditorWindow::SyncInputModifiersFromSystemState() { - m_inputController->SyncInputModifiersFromSystemState(); -} - -void EditorWindow::ResetInputModifiers() { - m_inputController->ResetInputModifiers(); -} - -void EditorWindow::QueueWindowFocusEvent(UIInputEventType type) { - m_inputController->QueueWindowFocusEvent(type); -} - -void EditorWindow::QueueKeyEvent(UIInputEventType type, WPARAM wParam, LPARAM lParam) { - m_inputController->QueueKeyEvent(type, wParam, lParam); -} - -void EditorWindow::QueueCharacterEvent(WPARAM wParam) { - m_inputController->QueueCharacterEvent(wParam); -} - -void EditorWindow::QueuePointerEvent( - UIInputEventType type, - UIPointerButton button, - WPARAM wParam, - LPARAM lParam, - bool doubleClick) { - m_inputController->QueuePointerEvent( - type, - button, - ConvertClientPixelsToDips(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)), - wParam, - doubleClick); -} - -void EditorWindow::QueueSyntheticPointerStateSyncEvent( - const ::XCEngine::UI::UIInputModifiers& modifiers) { - const HWND hwnd = m_session->GetHwnd(); - if (hwnd == nullptr) { - return; - } - - POINT screenPoint = {}; - if (!m_nativeWindowBackend.TryGetCursorScreenPoint(screenPoint)) { - return; - } - if (!m_nativeWindowBackend.TryConvertScreenToClient(hwnd, screenPoint)) { - return; - } - - m_inputController->QueueSyntheticPointerStateSyncEvent( - ConvertClientPixelsToDips(screenPoint.x, screenPoint.y), - modifiers); -} - -void EditorWindow::QueuePointerLeaveEvent() { - ::XCEngine::UI::UIPoint position = {}; - if (const HWND hwnd = m_session->GetHwnd(); - hwnd != nullptr) { - POINT clientPoint = {}; - if (m_nativeWindowBackend.TryGetCursorScreenPoint(clientPoint) && - m_nativeWindowBackend.TryConvertScreenToClient(hwnd, clientPoint)) { - position = ConvertClientPixelsToDips(clientPoint.x, clientPoint.y); - } - } - m_inputController->QueuePointerLeaveEvent(position); -} - -void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam) { - const HWND hwnd = m_session->GetHwnd(); - if (hwnd == nullptr) { - return; - } - - POINT screenPoint = { - GET_X_LPARAM(lParam), - GET_Y_LPARAM(lParam) - }; - if (!m_nativeWindowBackend.TryConvertScreenToClient(hwnd, screenPoint)) { - return; - } - - m_inputController->QueuePointerWheelEvent( - ConvertClientPixelsToDips(screenPoint.x, screenPoint.y), - wheelDelta, - wParam); -} - -bool EditorWindow::IsPointerInsideClientArea() const { - const HWND hwnd = m_session->GetHwnd(); - if (hwnd == nullptr) { - return false; - } - - POINT screenPoint = {}; - if (!m_nativeWindowBackend.TryGetCursorScreenPoint(screenPoint)) { - return false; - } - - return m_nativeWindowBackend.IsClientHitAtScreenPoint(hwnd, screenPoint); -} - -LPCWSTR EditorWindow::ResolveCurrentCursorResource() const { - const Host::BorderlessWindowResizeEdge borderlessResizeEdge = - IsBorderlessResizeActive() - ? GetBorderlessResizeEdge() - : GetHoveredBorderlessResizeEdge(); - if (borderlessResizeEdge != Host::BorderlessWindowResizeEdge::None) { - return Host::ResolveBorderlessWindowResizeCursor(borderlessResizeEdge); - } - - switch (m_runtime->GetCurrentCursorType()) { - case Domain::WindowCursorType::ResizeEW: - return IDC_SIZEWE; - case Domain::WindowCursorType::ResizeNS: - return IDC_SIZENS; - case Domain::WindowCursorType::Arrow: - default: - return IDC_ARROW; - } -} - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - - - - - diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindow.h b/new_editor/app/Platform/Win32/Windowing/EditorWindow.h deleted file mode 100644 index fe9e590d..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindow.h +++ /dev/null @@ -1,308 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Platform/Win32/Chrome/EditorWindowChromeProjection.h" -#include "Windowing/Application/EditorWindowContentUpdateResult.h" -#include "Windowing/Application/EditorWindowFrameRequestSource.h" -#include "Windowing/Content/EditorWindowContentRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" -#include "Platform/Win32/Windowing/EditorWindowSession.h" -#include "Windowing/Application/EditorWindowGeometry.h" - -#include - -#include -#include -#include -#include -#include -#include - -namespace XCEngine::UI { - -class UIDrawData; -class UIDrawList; - -struct UIPoint; -struct UIRect; -struct UISize; -struct UIInputEvent; -struct UIInputModifiers; - -enum class UIPointerButton : std::uint8_t; -enum class UIInputEventType : std::uint8_t; - -} // namespace XCEngine::UI - -namespace XCEngine::UI::Editor { - -struct UIEditorDockHostTabDropTarget; -class UIEditorWorkspaceController; - -struct UIEditorDockHostInteractionState; -struct UIEditorShellInteractionFrame; -struct UIEditorShellInteractionState; -struct UIEditorShellInteractionResult; - -namespace Widgets { -struct UIEditorDockHostDropPreviewState; -} - -} // namespace XCEngine::UI::Editor - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindowChromeController; -class EditorWindowFrameOrchestrator; -class EditorWindowInputController; -class EditorWindowRuntimeController; -class EditorWindowWorkspaceInteractionRuntime; -class EditorUtilityWindowRequestSink; -class EditorUtilityWindowFrameWorkflow; -class WindowWorkspaceTransferQueue; -class EditorWindowSession; -class EditorWindowPlatformRuntime; -class Win32NativeWindowBackend; -class Win32WindowCommandProjector; - -class EditorWindow final { -public: - EditorWindow( - std::string windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - std::wstring title, - bool primary, - EditorWindowContentSpec contentSpec, - Win32NativeWindowBackend& nativeWindowBackend, - Win32WindowCommandProjector& windowCommandProjector); - ~EditorWindow(); - - EditorWindow(const EditorWindow&) = delete; - EditorWindow& operator=(const EditorWindow&) = delete; - EditorWindow(EditorWindow&&) = delete; - EditorWindow& operator=(EditorWindow&&) = delete; - - std::string_view GetWindowId() const; - HWND GetHwnd() const; - bool HasHwnd() const; - EditorWindowLifecycleState GetLifecycleState() const; - bool IsPrimary() const; - bool IsClosing() const; - bool IsDestroyed() const; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType GetWindowType() const; - bool IsWorkspaceWindow() const; - const std::wstring& GetTitle() const; - std::string_view GetCachedTitleText() const; - const UIEditorWorkspaceController& GetWorkspaceController() const; - EditorWindowContentPresentationSummary BuildContentPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const; - void UpdateUtilityWindowSession(EditorUtilityWindowSession session); - void AttachHwnd(HWND hwnd); - bool Initialize( - const std::filesystem::path& repoRoot, - EditorContext& editorContext, - const std::filesystem::path& captureRoot, - bool autoCaptureOnStartup); - ::XCEngine::UI::UIPoint ConvertScreenPixelsToClientDips(const POINT& screenPoint) const; - void BindFrameRequestSource(EditorWindowFrameRequestSource& frameRequestSource); - bool IsRenderReady() const; - EditorWindowContentUpdateResult RenderFrame( - EditorContext& editorContext, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow, - bool globalTabDragActive); - - void SetPrimary(bool primary); - void SetTitle(std::wstring title); - void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController); - void ResetInteractionState(); - bool TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const POINT& screenPoint, - POINT& outHotspot) const; - bool TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outHotspot) const; - bool TryResolveDockTabDropTarget( - const POINT& screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const; - bool TryResolveDockTabDropTarget( - EditorWindowScreenPoint screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const; - bool SetDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview); - bool ClearDockHostDropPreview(); - - bool OnResize(UINT width, UINT height); - void OnEnterSizeMove(); - bool OnExitSizeMove(); - void OnDpiChanged(UINT dpi, const RECT& suggestedRect); - bool ApplyCurrentCursor() const; - bool HasInteractiveCaptureState() const; - void SetTrackingMouseLeave(bool trackingMouseLeave); - EditorWindowPointerCaptureOwner GetPointerCaptureOwner() const; - void ClearPointerCaptureOwner(); - void TryStartImmediateShellPointerCapture(LPARAM lParam); - bool TryHandleChromeHoverConsumption(LPARAM lParam, LRESULT& outResult); - bool HandleResizePointerMove( - EditorContext& editorContext, - bool globalTabDragActive); - bool HandleChromeDragRestorePointerMove( - EditorContext& editorContext, - bool globalTabDragActive); - bool HandleResizeButtonDown(LPARAM lParam); - bool HandleChromeButtonDown(LPARAM lParam); - bool HandleResizeButtonUp(); - bool HandleChromeButtonUp( - EditorContext& editorContext, - bool globalTabDragActive, - LPARAM lParam); - bool HandleChromeDoubleClick( - EditorContext& editorContext, - bool globalTabDragActive, - LPARAM lParam); - void ClearChromeInteractionState(); - void ForceClearChromeInteractionState(); - bool HandleGetMinMaxInfo(LPARAM lParam) const; - LRESULT HandleNcCalcSize(WPARAM wParam, LPARAM lParam) const; - bool HandleSystemCommand( - EditorContext& editorContext, - bool globalTabDragActive, - WPARAM wParam); - void RequestManualScreenshot(std::string_view reason); - void SyncInputModifiersFromSystemState(); - void ResetInputModifiers(); - void QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType type); - void QueueKeyEvent( - ::XCEngine::UI::UIInputEventType type, - WPARAM wParam, - LPARAM lParam); - void QueueCharacterEvent(WPARAM wParam); - void QueuePointerEvent( - ::XCEngine::UI::UIInputEventType type, - ::XCEngine::UI::UIPointerButton button, - WPARAM wParam, - LPARAM lParam, - bool doubleClick = false); - void QueuePointerLeaveEvent(); - void QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam); - void MarkDestroyed(); - void MarkClosing(); - void Shutdown(); - - void InvalidateHostWindow() const; - UINT GetWindowDpi() const; - void SetPredictedClientPixelSize(UINT width, UINT height); - void ClearPredictedClientPixelSize(); - void MarkPredictedClientPixelSizePresented(); - void AcquirePointerCapture(EditorWindowPointerCaptureOwner owner); - void ReleasePointerCapture(EditorWindowPointerCaptureOwner owner); - void ForceReleasePointerCapture(); - bool ApplyWindowResize(UINT width, UINT height); - ::XCEngine::UI::UISize ResolveMinimumOuterSize() const; - void RequestInteractionFrame(); - float GetDpiScale() const; - float PixelsToDips(float pixels) const; - ::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const; - EditorWindowChromeProjection BuildChromeProjection() const; - void ResetChromeWindowState(); - void BeginInteractiveResize(); - void EndInteractiveResize(); - bool IsInteractiveResize() const; - void BeginBorderlessResize( - Host::BorderlessWindowResizeEdge edge, - const POINT& initialScreenPoint, - const RECT& initialWindowRect); - void EndBorderlessResize(); - bool IsBorderlessResizeActive() const; - Host::BorderlessWindowResizeEdge GetBorderlessResizeEdge() const; - const POINT& GetBorderlessResizeInitialScreenPoint() const; - const RECT& GetBorderlessResizeInitialWindowRect() const; - void SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge edge); - Host::BorderlessWindowResizeEdge GetHoveredBorderlessResizeEdge() const; - void SetBorderlessWindowMaximized(bool maximized); - bool IsBorderlessWindowMaximized() const; - void SetBorderlessWindowRestoreRect(const RECT& rect); - bool TryGetBorderlessWindowRestoreRect(RECT& outRect) const; - void BeginBorderlessWindowDragRestore(const POINT& initialScreenPoint); - void EndBorderlessWindowDragRestore(); - bool IsBorderlessWindowDragRestoreArmed() const; - const POINT& GetBorderlessWindowDragRestoreInitialScreenPoint() const; - Host::BorderlessWindowChromeHitTarget GetHoveredChromeTarget() const; - void SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget target); - Host::BorderlessWindowChromeHitTarget GetPressedChromeTarget() const; - void SetPressedChromeTarget(Host::BorderlessWindowChromeHitTarget target); - void ResetChromeState(); - bool IsChromeStateClear() const; - const Host::BorderlessWindowChromeState& GetChromeState() const; - -private: - friend class EditorWindowPlatformRuntime; - - void MarkInitializing(); - void MarkRunning(); - void SetWindowDpi(UINT dpi); - - bool TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const; - bool ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height); - - bool OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const; - void QueueSyntheticPointerStateSyncEvent( - const ::XCEngine::UI::UIInputModifiers& modifiers); - void SyncShellCapturedPointerButtonsFromSystemState(); - - bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const; - bool ResolveRenderClientPixelSize(UINT& outWidth, UINT& outHeight) const; - ::XCEngine::UI::UIRect ResolveWorkspaceBounds( - float clientWidthDips, - float clientHeightDips) const; - EditorWindowContentUpdateResult RenderRuntimeFrame( - EditorContext& editorContext, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow, - bool globalTabDragActive, - float windowWidth, - const ::XCEngine::UI::UIRect& workspaceBounds, - ::XCEngine::UI::UIDrawData& drawData); - bool IsPointerInsideClientArea() const; - LPCWSTR ResolveCurrentCursorResource() const; - void ApplyShellRuntimePointerCapture(); - static bool IsVerboseRuntimeTraceEnabled(); - - std::unique_ptr m_session = {}; - Win32NativeWindowBackend& m_nativeWindowBackend; - Win32WindowCommandProjector& m_windowCommandProjector; - std::unique_ptr m_chromeController = {}; - std::unique_ptr m_frameOrchestrator = {}; - std::unique_ptr m_inputController = {}; - std::unique_ptr m_runtime = {}; - EditorWindowFrameRequestSource* m_frameRequestSource = nullptr; -}; - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - - - - - diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowCreateParams.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowCreateParams.h deleted file mode 100644 index f9b067c4..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowCreateParams.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorWindowCreateParams { - std::string windowId = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; - std::wstring title = {}; - int initialX = CW_USEDEFAULT; - int initialY = CW_USEDEFAULT; - int initialWidth = 1540; - int initialHeight = 940; - int showCommand = SW_SHOW; - bool primary = false; - bool autoCaptureOnStartup = false; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpMode.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpMode.h deleted file mode 100644 index 256fac4f..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpMode.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -namespace XCEngine::UI::Editor::App { - -enum class EditorWindowFramePumpMode { - AfterMessage, - SteadyTick, -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.cpp deleted file mode 100644 index e9498834..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h" - -#include "Composition/EditorContext.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" -#include "Windowing/Application/EditorWindowPostFrameRuntime.h" -#include "Windowing/Utility/EditorUtilityWindowRequestSink.h" -#include "Windowing/Workspace/WindowWorkspaceTransferQueue.h" - -namespace XCEngine::UI::Editor::App { - -namespace { - -bool IsLiveInteractiveWindow(const EditorWindow* window) { - return window != nullptr && - window->GetHwnd() != nullptr && - window->GetLifecycleState() == EditorWindowLifecycleState::Running; -} - -EditorWindowContentUpdateResult DriveScheduledWindowFrame( - EditorWindow& window, - EditorContext& editorContext, - EditorUtilityWindowResultState& utilityWindowResultState, - EditorUtilityWindowRequestSink& utilityRequestSink, - WindowWorkspaceTransferQueue& workspaceTransferQueue, - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow, - bool globalTabDragActive) { - EditorWindowContentUpdateResult updateResult = - window.RenderFrame( - editorContext, - utilityWindowResultState, - utilityRequestSink, - workspaceTransferQueue, - utilityWindowFrameWorkflow, - globalTabDragActive); - if (const HWND hwnd = window.GetHwnd(); - hwnd != nullptr && IsWindow(hwnd)) { - ValidateRect(hwnd, nullptr); - } - - return updateResult; -} -} // namespace - -EditorWindowFramePumpRuntime::EditorWindowFramePumpRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorContext& editorContext, - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowPostFrameRuntime& postFrameRuntime) - : m_windowRegistryRuntime(windowRegistryRuntime) - , m_editorContext(editorContext) - , m_applicationStateRuntime(applicationStateRuntime) - , m_postFrameRuntime(postFrameRuntime) { -} - -void EditorWindowFramePumpRuntime::PumpFrames(EditorWindowFramePumpMode mode) { - switch (mode) { - case EditorWindowFramePumpMode::AfterMessage: - FlushScheduledFrames(); - return; - case EditorWindowFramePumpMode::SteadyTick: - QueueSteadyFrames(); - FlushScheduledFrames(); - return; - } -} - -void EditorWindowFramePumpRuntime::FlushScheduledFrames() { - std::vector<::XCEngine::UI::Editor::Windowing::Application::FrameRequest> - scheduledFrameRequests = - m_applicationStateRuntime.ConsumeScheduledFrameRequests(); - if (scheduledFrameRequests.empty()) { - return; - } - - const bool globalTabDragActive = m_postFrameRuntime.IsGlobalTabDragActive(); - for (const ::XCEngine::UI::Editor::Windowing::Application::FrameRequest& request : - scheduledFrameRequests) { - if (request.windowId.empty()) { - continue; - } - - EditorWindow* const window = - m_windowRegistryRuntime.FindWindow(request.windowId.value); - if (!IsLiveInteractiveWindow(window)) { - continue; - } - - EditorUtilityWindowRequestSink utilityRequestSink = {}; - WindowWorkspaceTransferQueue workspaceTransferQueue = {}; - EditorWindowContentUpdateResult updateResult = - DriveScheduledWindowFrame( - *window, - m_editorContext, - m_postFrameRuntime.GetUtilityWindowResultState(), - utilityRequestSink, - workspaceTransferQueue, - m_postFrameRuntime.GetUtilityWindowFrameWorkflow(), - globalTabDragActive); - m_postFrameRuntime.HandleRenderedWindow( - request, - window->GetWindowId(), - window->GetWindowType(), - window->IsPrimary(), - window->IsWorkspaceWindow() ? &window->GetWorkspaceController() : nullptr, - updateResult); - m_postFrameRuntime.HandleUtilityWindowRequests(utilityRequestSink); - m_postFrameRuntime.HandleWorkspaceTransferRequests(workspaceTransferQueue); - } - - m_postFrameRuntime.FlushPendingPostFrameWork(); -} - -void EditorWindowFramePumpRuntime::QueueSteadyFrames() { - for (const std::unique_ptr& window : - m_windowRegistryRuntime.GetWindows()) { - if (window != nullptr) { - m_applicationStateRuntime.RequestSteadyFrame(window->GetWindowId()); - } - } -} - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h deleted file mode 100644 index 604fd5e4..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "Platform/Win32/Windowing/EditorWindowFramePumpMode.h" - -namespace XCEngine::UI::Editor::App { - -class EditorWindowApplicationStateRuntime; -class EditorContext; -class EditorWindowPostFrameRuntime; -class EditorWindowRegistryRuntime; - -class EditorWindowFramePumpRuntime final { -public: - EditorWindowFramePumpRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorContext& editorContext, - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowPostFrameRuntime& postFrameRuntime); - - void PumpFrames(EditorWindowFramePumpMode mode); - -private: - void FlushScheduledFrames(); - void QueueSteadyFrames(); - - EditorWindowRegistryRuntime& m_windowRegistryRuntime; - EditorContext& m_editorContext; - EditorWindowApplicationStateRuntime& m_applicationStateRuntime; - EditorWindowPostFrameRuntime& m_postFrameRuntime; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.cpp deleted file mode 100644 index fd1585db..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h" - -#include "Platform/Win32/Adapter/Win32WindowMessageTranslator.h" -#include "Platform/Win32/Chrome/BorderlessWindowChrome.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" - -namespace XCEngine::UI::Editor::App { - -bool EditorWindowInputMessageExecutor::TryExecutePointerEvent( - HWND hwnd, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - switch (event.type) { - case Win32WindowMessageType::PointerMove: - if (CanRouteEditorWindowGlobalTabDragPointerMessages( - window.GetPointerCaptureOwner(), - workspaceInteractionRuntime.OwnsActiveGlobalTabDrag(window.GetWindowId())) && - workspaceInteractionRuntime.HandleGlobalTabDragPointerMove(window.GetWindowId())) { - outResult = 0; - return true; - } - if (CanRouteEditorWindowBorderlessResizePointerMessages( - window.GetPointerCaptureOwner()) && - window.HandleResizePointerMove( - editorContext, - workspaceInteractionRuntime.IsGlobalTabDragActive())) { - outResult = 0; - return true; - } - if (CanRouteEditorWindowBorderlessChromePointerMessages( - window.GetPointerCaptureOwner()) && - window.HandleChromeDragRestorePointerMove( - editorContext, - workspaceInteractionRuntime.IsGlobalTabDragActive())) { - outResult = 0; - return true; - } - if (window.TryHandleChromeHoverConsumption(event.lParam, outResult)) { - return true; - } - - window.QueuePointerEvent( - ::XCEngine::UI::UIInputEventType::PointerMove, - ::XCEngine::UI::UIPointerButton::None, - event.wParam, - event.lParam); - outResult = 0; - return true; - case Win32WindowMessageType::PointerLeave: - window.SetTrackingMouseLeave(false); - window.ClearChromeInteractionState(); - window.QueuePointerLeaveEvent(); - outResult = 0; - return true; - case Win32WindowMessageType::PointerButtonDown: - if (event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - workspaceInteractionRuntime.OwnsActiveGlobalTabDrag(window.GetWindowId())) { - workspaceInteractionRuntime.EndGlobalTabDragSession(); - } - if (event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - window.HandleResizeButtonDown(event.lParam)) { - outResult = 0; - return true; - } - if (event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - window.HandleChromeButtonDown(event.lParam)) { - outResult = 0; - return true; - } - SetFocus(hwnd); - window.TryStartImmediateShellPointerCapture(event.lParam); - window.QueuePointerEvent( - ::XCEngine::UI::UIInputEventType::PointerButtonDown, - event.pointerButton, - event.wParam, - event.lParam); - outResult = 0; - return true; - case Win32WindowMessageType::PointerButtonUp: - if (CanRouteEditorWindowGlobalTabDragPointerMessages( - window.GetPointerCaptureOwner(), - workspaceInteractionRuntime.OwnsActiveGlobalTabDrag(window.GetWindowId())) && - event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - workspaceInteractionRuntime.HandleGlobalTabDragPointerButtonUp(window.GetWindowId())) { - outResult = 0; - return true; - } - if (CanRouteEditorWindowBorderlessResizePointerMessages( - window.GetPointerCaptureOwner()) && - event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - window.HandleResizeButtonUp()) { - outResult = 0; - return true; - } - if (CanRouteEditorWindowBorderlessChromePointerMessages( - window.GetPointerCaptureOwner()) && - event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - window.HandleChromeButtonUp( - editorContext, - workspaceInteractionRuntime.IsGlobalTabDragActive(), - event.lParam)) { - outResult = 0; - return true; - } - window.QueuePointerEvent( - ::XCEngine::UI::UIInputEventType::PointerButtonUp, - event.pointerButton, - event.wParam, - event.lParam); - outResult = 0; - return true; - case Win32WindowMessageType::PointerButtonDoubleClick: - if (event.pointerButton == ::XCEngine::UI::UIPointerButton::Left && - window.HandleChromeDoubleClick( - editorContext, - workspaceInteractionRuntime.IsGlobalTabDragActive(), - event.lParam)) { - outResult = 0; - return true; - } - SetFocus(hwnd); - window.TryStartImmediateShellPointerCapture(event.lParam); - window.QueuePointerEvent( - ::XCEngine::UI::UIInputEventType::PointerButtonDown, - event.pointerButton, - event.wParam, - event.lParam, - true); - outResult = 0; - return true; - case Win32WindowMessageType::PointerWheel: - window.QueuePointerWheelEvent( - event.wheelDelta, - event.wParam, - event.lParam); - outResult = 0; - return true; - default: - return false; - } -} - -bool EditorWindowInputMessageExecutor::TryExecute( - HWND hwnd, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - if (TryExecutePointerEvent( - hwnd, - editorContext, - workspaceInteractionRuntime, - window, - event, - outResult)) { - return true; - } - - switch (event.type) { - case Win32WindowMessageType::FocusGained: - window.SyncInputModifiersFromSystemState(); - window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusGained); - outResult = 0; - return true; - case Win32WindowMessageType::FocusLost: - window.ResetInputModifiers(); - window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost); - outResult = 0; - return true; - case Win32WindowMessageType::CaptureChanged: - if (event.captureOwner != hwnd) { - window.ClearPointerCaptureOwner(); - } - if (workspaceInteractionRuntime.OwnsActiveGlobalTabDrag(window.GetWindowId()) && - event.captureOwner != hwnd) { - workspaceInteractionRuntime.EndGlobalTabDragSession(); - outResult = 0; - return true; - } - if (event.captureOwner != hwnd && - window.HasInteractiveCaptureState()) { - window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost); - window.ForceClearChromeInteractionState(); - outResult = 0; - return true; - } - if (event.captureOwner != hwnd) { - window.ForceClearChromeInteractionState(); - } - return false; - case Win32WindowMessageType::KeyDown: - if (event.wParam == VK_F12) { - window.RequestManualScreenshot("manual_f12"); - } - window.QueueKeyEvent( - ::XCEngine::UI::UIInputEventType::KeyDown, - event.wParam, - event.lParam); - outResult = 0; - return true; - case Win32WindowMessageType::KeyUp: - window.QueueKeyEvent( - ::XCEngine::UI::UIInputEventType::KeyUp, - event.wParam, - event.lParam); - outResult = 0; - return true; - case Win32WindowMessageType::Character: - window.QueueCharacterEvent(event.wParam); - outResult = 0; - return true; - default: - return false; - } -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h deleted file mode 100644 index 61268a9e..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindow; -class EditorWindowWorkspaceInteractionRuntime; -struct Win32WindowMessageEvent; - -class EditorWindowInputMessageExecutor final { -public: - static bool TryExecute( - HWND hwnd, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult); - -private: - static bool TryExecutePointerEvent( - HWND hwnd, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult); -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.cpp deleted file mode 100644 index 8e48366f..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h" - -#include "Platform/Win32/Adapter/Win32WindowMessageTranslator.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h" -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = XCEngine::UI::Editor::Windowing::Domain; - -bool TryBuildDomainWindowEvent( - const Win32WindowMessageEvent& event, - Domain::WindowEvent& outEvent) { - outEvent = {}; - - switch (event.type) { - case Win32WindowMessageType::FocusGained: - outEvent.type = Domain::WindowEvent::Type::FocusGained; - return true; - case Win32WindowMessageType::FocusLost: - outEvent.type = Domain::WindowEvent::Type::FocusLost; - return true; - case Win32WindowMessageType::DpiChanged: - if (event.suggestedRect == nullptr) { - return false; - } - outEvent.type = Domain::WindowEvent::Type::DpiChanged; - outEvent.frameReason = Domain::FrameReason::DpiChange; - outEvent.dpiScale = - event.dpi != 0u ? static_cast(event.dpi) / 96.0f : 1.0f; - return true; - case Win32WindowMessageType::EnterSizeMove: - outEvent.type = Domain::WindowEvent::Type::InteractiveResizeStarted; - return true; - case Win32WindowMessageType::ExitSizeMove: - outEvent.type = Domain::WindowEvent::Type::InteractiveResizeEnded; - outEvent.frameReason = Domain::FrameReason::InteractionContinuation; - return true; - case Win32WindowMessageType::Resize: - if (event.minimized) { - return false; - } - outEvent.type = Domain::WindowEvent::Type::ClientResized; - outEvent.frameReason = Domain::FrameReason::Resize; - outEvent.width = event.clientWidth; - outEvent.height = event.clientHeight; - return true; - case Win32WindowMessageType::Close: - outEvent.type = Domain::WindowEvent::Type::CloseRequested; - return true; - case Win32WindowMessageType::Paint: - outEvent.type = Domain::WindowEvent::Type::PaintRequested; - outEvent.frameReason = Domain::FrameReason::PaintValidation; - return true; - case Win32WindowMessageType::Destroy: - outEvent.type = Domain::WindowEvent::Type::NativeDestroyed; - return true; - default: - return false; - } -} - -Domain::FramePriority ResolveFramePriority(const Win32WindowMessageEvent& event) { - switch (event.type) { - case Win32WindowMessageType::FocusGained: - case Win32WindowMessageType::FocusLost: - return Domain::FramePriority::None; - case Win32WindowMessageType::DpiChanged: - return Domain::FramePriority::Critical; - case Win32WindowMessageType::Resize: - case Win32WindowMessageType::Paint: - case Win32WindowMessageType::ExitSizeMove: - return Domain::FramePriority::High; - default: - return Domain::FramePriority::None; - } -} - -bool ExecuteNativeMessageSideEffect( - HWND hwnd, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - switch (event.type) { - case Win32WindowMessageType::DpiChanged: - if (event.suggestedRect == nullptr) { - return false; - } - window.OnDpiChanged(event.dpi, *event.suggestedRect); - outResult = 0; - return true; - case Win32WindowMessageType::EnterSizeMove: - window.OnEnterSizeMove(); - outResult = 0; - return true; - case Win32WindowMessageType::ExitSizeMove: - window.OnExitSizeMove(); - outResult = 0; - return true; - case Win32WindowMessageType::Resize: - if (!event.minimized) { - window.OnResize(event.clientWidth, event.clientHeight); - } - outResult = 0; - return true; - case Win32WindowMessageType::Paint: { - PAINTSTRUCT paintStruct = {}; - BeginPaint(hwnd, &paintStruct); - EndPaint(hwnd, &paintStruct); - outResult = 0; - return true; - } - case Win32WindowMessageType::EraseBackground: - outResult = 1; - return true; - default: - return false; - } -} - -} // namespace - -EditorWindowLifecycleEventRuntime::EditorWindowLifecycleEventRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowLifecycleFinalizationRuntime& lifecycleFinalizationRuntime) - : m_applicationStateRuntime(applicationStateRuntime) - , m_lifecycleFinalizationRuntime(lifecycleFinalizationRuntime) { -} - -bool EditorWindowLifecycleEventRuntime::TryDispatchLifecycleEvent( - HWND hwnd, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - ApplyLifecycleEvent(window, event); - switch (event.type) { - case Win32WindowMessageType::FocusGained: - case Win32WindowMessageType::FocusLost: - return false; - case Win32WindowMessageType::Close: - m_lifecycleFinalizationRuntime.ExecuteCloseRequest(window); - outResult = 0; - return true; - case Win32WindowMessageType::Destroy: - m_lifecycleFinalizationRuntime.HandleNativeWindowDestroyed(window); - outResult = 0; - return true; - case Win32WindowMessageType::DpiChanged: - case Win32WindowMessageType::EnterSizeMove: - case Win32WindowMessageType::ExitSizeMove: - case Win32WindowMessageType::Resize: - case Win32WindowMessageType::Paint: - case Win32WindowMessageType::EraseBackground: - return ExecuteNativeMessageSideEffect( - hwnd, - window, - event, - outResult); - default: - return false; - } -} - -void EditorWindowLifecycleEventRuntime::ApplyLifecycleEvent( - const EditorWindow& window, - const Win32WindowMessageEvent& event) { - Domain::WindowEvent domainEvent = {}; - if (!TryBuildDomainWindowEvent(event, domainEvent)) { - return; - } - - m_applicationStateRuntime.ApplyWindowEvent( - window.GetWindowId(), - window.GetWindowType(), - domainEvent); - const Domain::FramePriority priority = ResolveFramePriority(event); - if (priority == Domain::FramePriority::None || - domainEvent.frameReason == Domain::FrameReason::Unknown) { - return; - } - - m_applicationStateRuntime.RequestImmediateFrame( - window.GetWindowId(), - priority, - domainEvent.frameReason); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h deleted file mode 100644 index 21b1559a..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowApplicationStateRuntime; -class EditorWindow; -class EditorWindowLifecycleFinalizationRuntime; -struct Win32WindowMessageEvent; - -class EditorWindowLifecycleEventRuntime final { -public: - explicit EditorWindowLifecycleEventRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowLifecycleFinalizationRuntime& lifecycleFinalizationRuntime); - - bool TryDispatchLifecycleEvent( - HWND hwnd, - EditorWindow& window, - const Win32WindowMessageEvent& event, - LRESULT& outResult); - -private: - void ApplyLifecycleEvent( - const EditorWindow& window, - const Win32WindowMessageEvent& event); - - EditorWindowApplicationStateRuntime& m_applicationStateRuntime; - EditorWindowLifecycleFinalizationRuntime& m_lifecycleFinalizationRuntime; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.cpp deleted file mode 100644 index 7b0cdbb6..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.cpp +++ /dev/null @@ -1,238 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h" - -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h" - -#include - -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -std::string DescribeHwnd(HWND hwnd) { - std::ostringstream stream = {}; - stream << "0x" << std::hex << std::uppercase - << reinterpret_cast(hwnd); - return stream.str(); -} - -Domain::WindowCommand BuildCloseWindowCommand() { - return Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::CloseWindow, - }; -} - -Domain::WindowCommand BuildDestroyNativeWindowCommand() { - return Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::DestroyNativeWindow, - }; -} - -} // namespace - -EditorWindowLifecycleFinalizationRuntime::EditorWindowLifecycleFinalizationRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowWorkspaceProjectionRuntime& workspaceProjectionRuntime, - Win32WindowCommandProjector& windowCommandProjector) - : m_windowRegistryRuntime(windowRegistryRuntime) - , m_workspaceInteractionRuntime(workspaceInteractionRuntime) - , m_workspaceProjectionRuntime(workspaceProjectionRuntime) - , m_windowCommandProjector(windowCommandProjector) { -} - -void EditorWindowLifecycleFinalizationRuntime::PostCloseRequest( - std::string_view windowId) { - EditorWindow* const window = m_windowRegistryRuntime.FindWindow(windowId); - if (window != nullptr) { - PostCloseRequest(*window); - } -} - -void EditorWindowLifecycleFinalizationRuntime::PostCloseRequest( - EditorWindow& window) { - if (window.IsDestroyed()) { - return; - } - - const HWND hwnd = window.GetHwnd(); - if (!window.IsClosing()) { - window.MarkClosing(); - } - - if (hwnd == nullptr || !IsWindow(hwnd)) { - window.MarkDestroyed(); - return; - } - - LogRuntimeTrace( - "window-close", - "PostCloseRequest windowId='" + std::string(window.GetWindowId()) + - "' hwnd=" + DescribeHwnd(hwnd) + - " primary=" + (window.IsPrimary() ? "1" : "0") + - " registry=" + m_windowRegistryRuntime.DescribeWindowSet()); - m_windowCommandProjector.ProjectCommand(hwnd, BuildCloseWindowCommand()); -} - -void EditorWindowLifecycleFinalizationRuntime::ExecuteCloseRequest( - EditorWindow& window) { - if (window.IsDestroyed()) { - return; - } - - const HWND hwnd = window.GetHwnd(); - LogRuntimeTrace( - "window-close", - "ExecuteCloseRequest begin windowId='" + std::string(window.GetWindowId()) + - "' hwnd=" + DescribeHwnd(hwnd) + - " primary=" + (window.IsPrimary() ? "1" : "0") + - " lifecycleBefore=" + - std::string(GetEditorWindowLifecycleStateName(window.GetLifecycleState())) + - " workspace=" + m_workspaceProjectionRuntime.DescribeWindowSet() + - " registry=" + m_windowRegistryRuntime.DescribeWindowSet()); - - if (!window.IsClosing()) { - window.MarkClosing(); - } - - if (hwnd != nullptr && IsWindow(hwnd)) { - m_windowCommandProjector.ProjectCommand(hwnd, BuildDestroyNativeWindowCommand()); - } else { - window.MarkDestroyed(); - } - - LogRuntimeTrace( - "window-close", - "ExecuteCloseRequest end windowId='" + std::string(window.GetWindowId()) + - "' registry=" + m_windowRegistryRuntime.DescribeWindowSet()); -} - -void EditorWindowLifecycleFinalizationRuntime::HandleNativeWindowDestroyed( - EditorWindow& window) { - if (window.IsDestroyed()) { - return; - } - - const bool destroyedPrimary = - m_workspaceProjectionRuntime.IsPrimaryWindowId(window.GetWindowId()); - LogRuntimeTrace( - "window-close", - "HandleNativeWindowDestroyed begin windowId='" + std::string(window.GetWindowId()) + - "' hwnd=" + DescribeHwnd(window.GetHwnd()) + - " destroyedPrimary=" + (destroyedPrimary ? "1" : "0") + - " localPrimary=" + (window.IsPrimary() ? "1" : "0") + - " workspaceBefore=" + m_workspaceProjectionRuntime.DescribeWindowSet() + - " registryBefore=" + m_windowRegistryRuntime.DescribeWindowSet()); - - if (m_workspaceInteractionRuntime.OwnsActiveGlobalTabDrag(window.GetWindowId())) { - m_workspaceInteractionRuntime.EndGlobalTabDragSession(); - } - - m_workspaceProjectionRuntime.RemoveWindowProjection(window.GetWindowId(), destroyedPrimary); - window.MarkDestroyed(); - - if (destroyedPrimary) { - std::vector closeTargets = - m_windowRegistryRuntime.CollectSiblingCloseTargetsForPrimaryDestroyed(window); - - for (EditorWindow* closeTarget : closeTargets) { - if (closeTarget != nullptr) { - PostCloseRequest(*closeTarget); - } - } - } - - LogRuntimeTrace( - "window-close", - "HandleNativeWindowDestroyed end windowId='" + std::string(window.GetWindowId()) + - "' workspaceAfter=" + m_workspaceProjectionRuntime.DescribeWindowSet() + - " registryAfter=" + m_windowRegistryRuntime.DescribeWindowSet()); -} - -void EditorWindowLifecycleFinalizationRuntime::AbortUnregisteredWindow( - std::string_view windowId) { - EditorWindow* const window = m_windowRegistryRuntime.FindWindow(windowId); - if (window != nullptr) { - AbortUnregisteredWindow(*window); - } -} - -void EditorWindowLifecycleFinalizationRuntime::AbortUnregisteredWindow( - EditorWindow& window) { - const HWND hwnd = window.GetHwnd(); - const std::string windowId(window.GetWindowId()); - LogRuntimeTrace( - "window-close", - "AbortUnregisteredWindow begin windowId='" + windowId + - "' hwnd=" + DescribeHwnd(hwnd) + - " registryBefore=" + m_windowRegistryRuntime.DescribeWindowSet()); - - if (!window.IsClosing()) { - window.MarkClosing(); - } - - if (hwnd != nullptr && IsWindow(hwnd)) { - m_windowCommandProjector.ProjectCommand(hwnd, BuildDestroyNativeWindowCommand()); - } else { - window.MarkDestroyed(); - } - ReapDestroyedWindows(); - - LogRuntimeTrace( - "window-close", - "AbortUnregisteredWindow end windowId='" + windowId + - " registryAfter=" + m_windowRegistryRuntime.DescribeWindowSet()); -} - -void EditorWindowLifecycleFinalizationRuntime::ShutdownAllWindows() { - std::vector closeTargets = - m_windowRegistryRuntime.CollectAllWindowCloseTargets(); - - for (EditorWindow* closeTarget : closeTargets) { - if (closeTarget != nullptr) { - ExecuteCloseRequest(*closeTarget); - } - } - - ReapDestroyedWindows(); -} - -void EditorWindowLifecycleFinalizationRuntime::ReapDestroyedWindows() { - for (const std::unique_ptr& window : - m_windowRegistryRuntime.GetWindows()) { - if (window == nullptr || !window->IsDestroyed()) { - continue; - } - - LogRuntimeTrace( - "window-close", - "ReapDestroyedWindows shutdown windowId='" + std::string(window->GetWindowId()) + "'"); - ShutdownRuntimeIfNeeded(*window); - } - m_windowRegistryRuntime.ReapDestroyedWindows(); -} - -void EditorWindowLifecycleFinalizationRuntime::ShutdownRuntimeIfNeeded( - EditorWindow& window) { - if (window.IsRenderReady()) { - window.Shutdown(); - } -} - -void EditorWindowLifecycleFinalizationRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - m_windowRegistryRuntime.LogRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h deleted file mode 100644 index 68078235..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Windowing/Ports/EditorWindowLifecyclePort.h" - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindow; -class EditorWindowRegistryRuntime; -class EditorWindowWorkspaceInteractionRuntime; -class EditorWindowWorkspaceProjectionRuntime; -class Win32WindowCommandProjector; - -class EditorWindowLifecycleFinalizationRuntime final : public EditorWindowLifecyclePort { -public: - EditorWindowLifecycleFinalizationRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowWorkspaceProjectionRuntime& workspaceProjectionRuntime, - Win32WindowCommandProjector& windowCommandProjector); - - void PostCloseRequest(std::string_view windowId) override; - void PostCloseRequest(EditorWindow& window); - void ExecuteCloseRequest(EditorWindow& window); - void HandleNativeWindowDestroyed(EditorWindow& window); - void AbortUnregisteredWindow(std::string_view windowId) override; - void AbortUnregisteredWindow(EditorWindow& window); - void ShutdownAllWindows(); - void ReapDestroyedWindows() override; - -private: - void ShutdownRuntimeIfNeeded(EditorWindow& window); - void LogRuntimeTrace(std::string_view channel, std::string_view message) const; - - EditorWindowRegistryRuntime& m_windowRegistryRuntime; - EditorWindowWorkspaceInteractionRuntime& m_workspaceInteractionRuntime; - EditorWindowWorkspaceProjectionRuntime& m_workspaceProjectionRuntime; - Win32WindowCommandProjector& m_windowCommandProjector; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.cpp deleted file mode 100644 index 91078a12..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.cpp +++ /dev/null @@ -1,243 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h" - -#include "Platform/Win32/Adapter/Win32WindowMessageAdapter.h" -#include "Platform/Win32/Adapter/Win32WindowMessageSink.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowInputMessageExecutor.h" - -namespace XCEngine::UI::Editor::App { - -namespace { - -struct DispatchContext { - HWND hwnd = nullptr; - EditorContext& editorContext; - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime; - EditorWindowLifecycleEventRuntime& lifecycleEventRuntime; - EditorWindow& window; -}; - -struct EditorWindowChromeMessageAction { - enum class Type { - None, - GetMinMaxInfo, - NcCalcSize, - NcActivate, - NcHitTest, - NcPaint, - SystemCommand, - SetCursor, - }; - - Type type = Type::None; - WPARAM wParam = 0; - LPARAM lParam = 0; - bool clientCursor = false; -}; - -bool TryMapEditorWindowChromeMessageAction( - const Win32WindowMessageEvent& event, - EditorWindowChromeMessageAction& outAction) { - outAction = {}; - outAction.wParam = event.wParam; - outAction.lParam = event.lParam; - outAction.clientCursor = event.clientCursor; - - switch (event.type) { - case Win32WindowMessageType::GetMinMaxInfo: - outAction.type = EditorWindowChromeMessageAction::Type::GetMinMaxInfo; - return true; - case Win32WindowMessageType::NcCalcSize: - outAction.type = EditorWindowChromeMessageAction::Type::NcCalcSize; - return true; - case Win32WindowMessageType::NcActivate: - outAction.type = EditorWindowChromeMessageAction::Type::NcActivate; - return true; - case Win32WindowMessageType::NcHitTest: - outAction.type = EditorWindowChromeMessageAction::Type::NcHitTest; - return true; - case Win32WindowMessageType::NcPaint: - outAction.type = EditorWindowChromeMessageAction::Type::NcPaint; - return true; - case Win32WindowMessageType::SystemCommand: - outAction.type = EditorWindowChromeMessageAction::Type::SystemCommand; - return true; - case Win32WindowMessageType::SetCursor: - outAction.type = EditorWindowChromeMessageAction::Type::SetCursor; - return true; - default: - return false; - } -} - -bool TryDispatchInputEvent( - const DispatchContext& context, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - return EditorWindowInputMessageExecutor::TryExecute( - context.hwnd, - context.editorContext, - context.workspaceInteractionRuntime, - context.window, - event, - outResult); -} - -bool TryDispatchLifecycleEvent( - const DispatchContext& context, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - return context.lifecycleEventRuntime.TryDispatchLifecycleEvent( - context.hwnd, - context.window, - event, - outResult); -} - -bool TryDispatchChromeEvent( - const DispatchContext& context, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - EditorWindowChromeMessageAction action = {}; - if (!TryMapEditorWindowChromeMessageAction(event, action)) { - return false; - } - - switch (action.type) { - case EditorWindowChromeMessageAction::Type::GetMinMaxInfo: - if (context.window.HandleGetMinMaxInfo(action.lParam)) { - outResult = 0; - return true; - } - return false; - case EditorWindowChromeMessageAction::Type::NcCalcSize: - outResult = context.window.HandleNcCalcSize(action.wParam, action.lParam); - return true; - case EditorWindowChromeMessageAction::Type::NcActivate: - outResult = TRUE; - return true; - case EditorWindowChromeMessageAction::Type::NcHitTest: - outResult = HTCLIENT; - return true; - case EditorWindowChromeMessageAction::Type::NcPaint: - outResult = 0; - return true; - case EditorWindowChromeMessageAction::Type::SystemCommand: - if (context.window.HandleSystemCommand( - context.editorContext, - context.workspaceInteractionRuntime.IsGlobalTabDragActive(), - action.wParam)) { - outResult = 0; - return true; - } - return false; - case EditorWindowChromeMessageAction::Type::SetCursor: - if (action.clientCursor && context.window.ApplyCurrentCursor()) { - outResult = TRUE; - return true; - } - return false; - case EditorWindowChromeMessageAction::Type::None: - default: - return false; - } -} - -bool TryDispatchTranslatedMessage( - const DispatchContext& context, - const Win32WindowMessageEvent& event, - LRESULT& outResult) { - if (TryDispatchChromeEvent(context, event, outResult)) { - return true; - } - if (TryDispatchLifecycleEvent(context, event, outResult)) { - return true; - } - if (TryDispatchInputEvent(context, event, outResult)) { - return true; - } - - return false; -} - -class EditorWindowDispatchSink final : public Win32WindowMessageSink { -public: - EditorWindowDispatchSink( - HWND hwnd, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowLifecycleEventRuntime& lifecycleEventRuntime, - EditorWindow& window) - : m_hwnd(hwnd) - , m_editorContext(editorContext) - , m_workspaceInteractionRuntime(workspaceInteractionRuntime) - , m_lifecycleEventRuntime(lifecycleEventRuntime) - , m_window(window) { - } - - bool TryDispatchTranslatedMessage( - const Win32WindowMessageEvent& event, - LRESULT& outResult) override { - const DispatchContext context = { - .hwnd = m_hwnd, - .editorContext = m_editorContext, - .workspaceInteractionRuntime = m_workspaceInteractionRuntime, - .lifecycleEventRuntime = m_lifecycleEventRuntime, - .window = m_window, - }; - return ::XCEngine::UI::Editor::App::TryDispatchTranslatedMessage( - context, - event, - outResult); - } - -private: - HWND m_hwnd = nullptr; - EditorContext& m_editorContext; - EditorWindowWorkspaceInteractionRuntime& m_workspaceInteractionRuntime; - EditorWindowLifecycleEventRuntime& m_lifecycleEventRuntime; - EditorWindow& m_window; -}; - -} // namespace - -EditorWindowMessagePumpRuntime::EditorWindowMessagePumpRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowLifecycleEventRuntime& lifecycleEventRuntime) - : m_windowRegistryRuntime(windowRegistryRuntime) - , m_editorContext(editorContext) - , m_workspaceInteractionRuntime(workspaceInteractionRuntime) - , m_lifecycleEventRuntime(lifecycleEventRuntime) { -} - -bool EditorWindowMessagePumpRuntime::TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult) { - EditorWindow* const window = m_windowRegistryRuntime.FindWindow(hwnd); - if (window == nullptr) { - return false; - } - - EditorWindowDispatchSink sink( - hwnd, - m_editorContext, - m_workspaceInteractionRuntime, - m_lifecycleEventRuntime, - *window); - return Win32WindowMessageAdapter::TryDispatch( - message, - wParam, - lParam, - sink, - outResult); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h deleted file mode 100644 index 1a24c831..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindowLifecycleEventRuntime; -class EditorWindowRegistryRuntime; -class EditorWindowWorkspaceInteractionRuntime; - -class EditorWindowMessagePumpRuntime final { -public: - EditorWindowMessagePumpRuntime( - EditorWindowRegistryRuntime& windowRegistryRuntime, - EditorContext& editorContext, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowLifecycleEventRuntime& lifecycleEventRuntime); - - bool TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult); - -private: - EditorWindowRegistryRuntime& m_windowRegistryRuntime; - EditorContext& m_editorContext; - EditorWindowWorkspaceInteractionRuntime& m_workspaceInteractionRuntime; - EditorWindowLifecycleEventRuntime& m_lifecycleEventRuntime; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.cpp deleted file mode 100644 index 71dd7282..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowPlatformRuntime.h" - -#include "Composition/EditorContext.h" -#include "Platform/Win32/Backend/Win32NativeWindowBackend.h" -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" -#include "Windowing/Utility/EditorUtilityWindowPanelProvider.h" - -namespace XCEngine::UI::Editor::App { - -namespace { - -EditorWindowCreateParams BuildCreateParamsFromHostRequest( - const EditorWindowHostCreateRequest& request) { - EditorWindowCreateParams params = {}; - params.windowId = request.windowId; - params.windowType = request.windowType; - params.title = request.title; - if (!request.useDefaultInitialPosition) { - params.initialX = request.initialX; - params.initialY = request.initialY; - } - params.initialWidth = request.initialWidth; - params.initialHeight = request.initialHeight; - params.primary = request.primary; - params.autoCaptureOnStartup = request.autoCaptureOnStartup; - return params; -} - -} // namespace -EditorWindowPlatformRuntime::EditorWindowPlatformRuntime( - EditorWindowHostConfig hostConfig, - std::filesystem::path repoRoot, - EditorContext& editorContext) - : m_hostConfig(hostConfig) - , m_repoRoot(std::move(repoRoot)) - , m_editorContext(editorContext) - , m_nativeWindowBackend(std::make_unique()) - , m_windowRegistryRuntime(std::make_unique()) - , m_windowCommandProjector( - std::make_unique( - *m_nativeWindowBackend, - *m_windowRegistryRuntime)) { -} - -EditorWindowPlatformRuntime::~EditorWindowPlatformRuntime() = default; - -EditorWindow* EditorWindowPlatformRuntime::CreateEditorWindow( - EditorWindowContentSpec contentSpec, - const CreateParams& params) { - auto windowPtr = std::make_unique( - params.windowId, - params.windowType, - params.title.empty() ? std::wstring(L"XCEngine Editor") : params.title, - params.primary, - std::move(contentSpec), - *m_nativeWindowBackend, - *m_windowCommandProjector); - EditorWindow* const rawWindow = m_windowRegistryRuntime->RegisterWindow(std::move(windowPtr)); - if (rawWindow == nullptr) { - return nullptr; - } - - m_pendingCreateWindow = rawWindow; - const HWND hwnd = m_nativeWindowBackend->CreateNativeWindow(Win32NativeWindowCreateDesc{ - .hInstance = m_hostConfig.hInstance, - .className = m_hostConfig.windowClassName, - .style = m_hostConfig.windowStyle, - .title = rawWindow->GetTitle(), - .x = params.initialX, - .y = params.initialY, - .width = params.initialWidth, - .height = params.initialHeight, - .userData = m_hostConfig.windowUserData, - }); - m_pendingCreateWindow = nullptr; - if (hwnd == nullptr) { - m_windowRegistryRuntime->UnregisterWindow(rawWindow); - return nullptr; - } - - if (!rawWindow->HasHwnd()) { - rawWindow->AttachHwnd(hwnd); - } - - const auto failWindowInitialization = [this, rawWindow]() { - m_windowRegistryRuntime->LogRuntimeTrace( - "window", - "managed window initialization failed"); - if (m_lifecycleFinalizationRuntime != nullptr) { - m_lifecycleFinalizationRuntime->AbortUnregisteredWindow(*rawWindow); - } else { - m_windowRegistryRuntime->UnregisterWindow(rawWindow); - } - return static_cast(nullptr); - }; - - m_nativeWindowBackend->ApplyEditorIcons(hwnd, m_hostConfig.hInstance); - - if (!rawWindow->Initialize( - m_repoRoot, - m_editorContext, - m_editorContext.GetShellAsset().captureRootPath, - params.autoCaptureOnStartup)) { - return failWindowInitialization(); - } - - m_nativeWindowBackend->ShowAndUpdate(hwnd, params.showCommand); - if (m_applicationStateRuntime != nullptr) { - rawWindow->BindFrameRequestSource(*m_applicationStateRuntime); - m_applicationStateRuntime->RegisterNativeAttached( - rawWindow->GetWindowId(), - rawWindow->GetWindowType(), - rawWindow->IsPrimary(), - rawWindow->IsWorkspaceWindow() ? &rawWindow->GetWorkspaceController() : nullptr); - } - return rawWindow; -} - - -EditorWindowHostCreateResult EditorWindowPlatformRuntime::CreateWorkspaceWindow( - EditorWorkspaceWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) { - EditorWindow* const window = CreateEditorWindow( - EditorWindowContentSpec(std::move(contentSpec)), - BuildCreateParamsFromHostRequest(request)); - return EditorWindowHostCreateResult{ - .success = window != nullptr, - .windowId = request.windowId, - }; -} - -EditorWindowHostCreateResult EditorWindowPlatformRuntime::CreateUtilityWindow( - EditorUtilityWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) { - EditorWindow* const window = CreateEditorWindow( - EditorWindowContentSpec(std::move(contentSpec)), - BuildCreateParamsFromHostRequest(request)); - return EditorWindowHostCreateResult{ - .success = window != nullptr, - .windowId = request.windowId, - }; -} - -bool EditorWindowPlatformRuntime::TryGetCursorScreenPoint( - EditorWindowScreenPoint& outPoint) const { - return m_nativeWindowBackend->TryGetCursorScreenPoint(outPoint); -} - -bool EditorWindowPlatformRuntime::TryGetWindowRect( - std::string_view windowId, - EditorWindowRect& outRect) const { - const EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - outRect = {}; - return false; - } - - RECT rect = {}; - if (!m_nativeWindowBackend->TryGetWindowRect(window->GetHwnd(), rect)) { - outRect = {}; - return false; - } - - outRect = EditorWindowRect{rect.left, rect.top, rect.right, rect.bottom}; - return true; -} - -bool EditorWindowPlatformRuntime::IsWindowUnderScreenPoint( - std::string_view windowId, - EditorWindowScreenPoint screenPoint) const { - const EditorWindow* const window = FindWindow(windowId); - return window != nullptr && - m_nativeWindowBackend->IsWindowUnderScreenPoint( - window->GetHwnd(), - POINT{screenPoint.x, screenPoint.y}); -} - -bool EditorWindowPlatformRuntime::TryGetNearestMonitorWorkArea( - EditorWindowScreenPoint screenPoint, - EditorWindowRect& outRect) const { - return m_nativeWindowBackend->TryGetNearestMonitorWorkArea(screenPoint, outRect); -} - -void EditorWindowPlatformRuntime::BindApplicationStateRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime) { - m_applicationStateRuntime = &applicationStateRuntime; -} - -void EditorWindowPlatformRuntime::BindLifecycleFinalizationRuntime( - EditorWindowLifecycleFinalizationRuntime& lifecycleFinalizationRuntime) { - m_lifecycleFinalizationRuntime = &lifecycleFinalizationRuntime; -} - -void EditorWindowPlatformRuntime::HandlePendingNativeWindowCreated(HWND hwnd) { - if (m_pendingCreateWindow != nullptr && - m_pendingCreateWindow->GetLifecycleState() == - EditorWindowLifecycleState::PendingNativeCreate && - !m_pendingCreateWindow->HasHwnd()) { - m_pendingCreateWindow->AttachHwnd(hwnd); - } -} - -EditorWindow* EditorWindowPlatformRuntime::FindWindow(HWND hwnd) { - return m_windowRegistryRuntime->FindWindow(hwnd); -} - -const EditorWindow* EditorWindowPlatformRuntime::FindWindow(HWND hwnd) const { - return m_windowRegistryRuntime->FindWindow(hwnd); -} - -EditorWindow* EditorWindowPlatformRuntime::FindWindow(std::string_view windowId) { - return m_windowRegistryRuntime->FindWindow(windowId); -} - -const EditorWindow* EditorWindowPlatformRuntime::FindWindow(std::string_view windowId) const { - return m_windowRegistryRuntime->FindWindow(windowId); -} - -EditorWindow* EditorWindowPlatformRuntime::FindPrimaryWindow() { - return m_windowRegistryRuntime->FindPrimaryWindow(); -} - -const EditorWindow* EditorWindowPlatformRuntime::FindPrimaryWindow() const { - return m_windowRegistryRuntime->FindPrimaryWindow(); -} - -bool EditorWindowPlatformRuntime::HasWindows() const { - return m_windowRegistryRuntime->HasWindows(); -} - -EditorWindowHostAdapters -EditorWindowPlatformRuntime::CreateWindowHostAdapters() { - return EditorWindowHostAdapters{ - .windowDirectory = *m_windowRegistryRuntime, - .utilitySessionHost = *m_windowRegistryRuntime, - .traceSink = *m_windowRegistryRuntime, - .workspaceContentPort = *m_windowRegistryRuntime, - .workspaceHostPort = *m_windowRegistryRuntime, - .hostCreationPort = *this, - .nativeQueryPort = *this, - .windowCommandSink = *m_windowCommandProjector, - }; -} - -EditorWindowRegistryRuntime& EditorWindowPlatformRuntime::GetWindowRegistryRuntime() { - return *m_windowRegistryRuntime; -} - -const EditorWindowRegistryRuntime& EditorWindowPlatformRuntime::GetWindowRegistryRuntime() const { - return *m_windowRegistryRuntime; -} - -Win32NativeWindowBackend& EditorWindowPlatformRuntime::GetNativeWindowBackend() { - return *m_nativeWindowBackend; -} - -const Win32NativeWindowBackend& EditorWindowPlatformRuntime::GetNativeWindowBackend() const { - return *m_nativeWindowBackend; -} - -Win32WindowCommandProjector& EditorWindowPlatformRuntime::GetWindowCommandProjector() { - return *m_windowCommandProjector; -} - -const Win32WindowCommandProjector& -EditorWindowPlatformRuntime::GetWindowCommandProjector() const { - return *m_windowCommandProjector; -} - -const EditorWindowHostConfig& EditorWindowPlatformRuntime::GetHostConfig() const { - return m_hostConfig; -} - -} // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.h deleted file mode 100644 index f6597e8f..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowPlatformRuntime.h +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Platform/Win32/Windowing/EditorWindowCreateParams.h" -#include "Platform/Win32/Windowing/EditorWindowFramePumpMode.h" -#include "Windowing/Content/EditorWindowContentRuntime.h" -#include "Windowing/Host/EditorWindowHostAdapters.h" -#include "Windowing/Ports/EditorWindowHostCreationPort.h" -#include "Windowing/Ports/EditorWindowNativeQueryPort.h" - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -} // namespace XCEngine::UI::Editor::Windowing::Application - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindow; -class EditorWindowApplicationStateRuntime; -class EditorWindowLifecycleFinalizationRuntime; -class EditorWindowRegistryRuntime; -class Win32NativeWindowBackend; -class Win32WindowCommandProjector; - -struct EditorWindowHostConfig { - HINSTANCE hInstance = nullptr; - const wchar_t* windowClassName = L""; - DWORD windowStyle = 0; - const wchar_t* primaryWindowTitle = L""; - void* windowUserData = nullptr; -}; - -class EditorWindowPlatformRuntime final - : public EditorWindowHostCreationPort - , public EditorWindowNativeQueryPort { -public: - using CreateParams = EditorWindowCreateParams; - - EditorWindowPlatformRuntime( - EditorWindowHostConfig hostConfig, - std::filesystem::path repoRoot, - EditorContext& editorContext); - ~EditorWindowPlatformRuntime(); - - EditorWindowPlatformRuntime(const EditorWindowPlatformRuntime&) = delete; - EditorWindowPlatformRuntime& operator=(const EditorWindowPlatformRuntime&) = delete; - EditorWindowPlatformRuntime(EditorWindowPlatformRuntime&&) = delete; - EditorWindowPlatformRuntime& operator=(EditorWindowPlatformRuntime&&) = delete; - - EditorWindow* CreateEditorWindow( - EditorWindowContentSpec contentSpec, - const CreateParams& params); - EditorWindowHostCreateResult CreateWorkspaceWindow( - EditorWorkspaceWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) override; - EditorWindowHostCreateResult CreateUtilityWindow( - EditorUtilityWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) override; - bool TryGetCursorScreenPoint(EditorWindowScreenPoint& outPoint) const override; - bool TryGetWindowRect(std::string_view windowId, EditorWindowRect& outRect) const override; - bool IsWindowUnderScreenPoint( - std::string_view windowId, - EditorWindowScreenPoint screenPoint) const override; - bool TryGetNearestMonitorWorkArea( - EditorWindowScreenPoint screenPoint, - EditorWindowRect& outRect) const override; - void BindApplicationStateRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime); - void BindLifecycleFinalizationRuntime( - EditorWindowLifecycleFinalizationRuntime& lifecycleFinalizationRuntime); - void HandlePendingNativeWindowCreated(HWND hwnd); - - EditorWindow* FindWindow(HWND hwnd); - const EditorWindow* FindWindow(HWND hwnd) const; - EditorWindow* FindWindow(std::string_view windowId); - const EditorWindow* FindWindow(std::string_view windowId) const; - EditorWindow* FindPrimaryWindow(); - const EditorWindow* FindPrimaryWindow() const; - - bool HasWindows() const; - EditorWindowHostAdapters CreateWindowHostAdapters(); - - EditorWindowRegistryRuntime& GetWindowRegistryRuntime(); - const EditorWindowRegistryRuntime& GetWindowRegistryRuntime() const; - Win32NativeWindowBackend& GetNativeWindowBackend(); - const Win32NativeWindowBackend& GetNativeWindowBackend() const; - Win32WindowCommandProjector& GetWindowCommandProjector(); - const Win32WindowCommandProjector& GetWindowCommandProjector() const; - const EditorWindowHostConfig& GetHostConfig() const; - -private: - EditorWindowHostConfig m_hostConfig = {}; - std::filesystem::path m_repoRoot = {}; - EditorContext& m_editorContext; - std::unique_ptr m_nativeWindowBackend = {}; - std::unique_ptr m_windowRegistryRuntime = {}; - std::unique_ptr m_windowCommandProjector = {}; - EditorWindow* m_pendingCreateWindow = nullptr; - EditorWindowApplicationStateRuntime* m_applicationStateRuntime = nullptr; - EditorWindowLifecycleFinalizationRuntime* m_lifecycleFinalizationRuntime = nullptr; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.cpp deleted file mode 100644 index 9e38121f..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.cpp +++ /dev/null @@ -1,330 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" - -#include "Platform/Win32/Windowing/EditorWindow.h" - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -std::string DescribeHwnd(HWND hwnd) { - std::ostringstream stream = {}; - stream << "0x" << std::hex << std::uppercase - << reinterpret_cast(hwnd); - return stream.str(); -} - -std::string DescribeWindows(const std::vector>& windows) { - std::ostringstream stream = {}; - stream << "count=" << windows.size() << " ["; - bool first = true; - for (const std::unique_ptr& window : windows) { - if (!first) { - stream << ", "; - } - first = false; - if (window == nullptr) { - stream << ""; - continue; - } - - stream << window->GetWindowId() - << "{hwnd=" << DescribeHwnd(window->GetHwnd()) - << ",primary=" << (window->IsPrimary() ? '1' : '0') - << ",state=" << GetEditorWindowLifecycleStateName(window->GetLifecycleState()) - << '}'; - } - stream << ']'; - return stream.str(); -} - -} // namespace - -EditorWindow* EditorWindowRegistryRuntime::RegisterWindow( - std::unique_ptr window) { - if (window == nullptr) { - return nullptr; - } - - EditorWindow* const rawWindow = window.get(); - m_windows.push_back(std::move(window)); - return rawWindow; -} - -bool EditorWindowRegistryRuntime::UnregisterWindow(EditorWindow* window) { - if (window == nullptr) { - return false; - } - - const auto it = std::find_if( - m_windows.begin(), - m_windows.end(), - [window](const std::unique_ptr& candidate) { - return candidate.get() == window; - }); - if (it == m_windows.end()) { - return false; - } - - m_windows.erase(it); - return true; -} - -EditorWindow* EditorWindowRegistryRuntime::FindWindow(HWND hwnd) { - if (hwnd == nullptr) { - return nullptr; - } - - for (const std::unique_ptr& window : m_windows) { - if (window != nullptr && window->GetHwnd() == hwnd) { - return window.get(); - } - } - - return nullptr; -} - -const EditorWindow* EditorWindowRegistryRuntime::FindWindow(HWND hwnd) const { - return const_cast(this)->FindWindow(hwnd); -} - -EditorWindow* EditorWindowRegistryRuntime::FindWindow(std::string_view windowId) { - if (windowId.empty()) { - return nullptr; - } - - for (const std::unique_ptr& window : m_windows) { - if (window != nullptr && window->GetWindowId() == windowId) { - return window.get(); - } - } - - return nullptr; -} - -const EditorWindow* EditorWindowRegistryRuntime::FindWindow(std::string_view windowId) const { - return const_cast(this)->FindWindow(windowId); -} - -bool EditorWindowRegistryRuntime::TryGetWindowSnapshot( - std::string_view windowId, - EditorWindowSnapshot& outSnapshot) const { - const EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - outSnapshot = {}; - return false; - } - - outSnapshot = EditorWindowSnapshot{ - .windowId = std::string(window->GetWindowId()), - .windowType = window->GetWindowType(), - .primary = window->IsPrimary(), - .hasNativeWindow = window->GetHwnd() != nullptr, - .running = window->GetLifecycleState() == EditorWindowLifecycleState::Running, - .closing = window->IsClosing(), - .destroyed = window->IsDestroyed(), - }; - return true; -} - -bool EditorWindowRegistryRuntime::UpdateUtilityWindowSession( - std::string_view windowId, - EditorUtilityWindowSession session) { - EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - return false; - } - - window->UpdateUtilityWindowSession(std::move(session)); - return true; -} - -bool EditorWindowRegistryRuntime::TryGetWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController& outWorkspaceController) const { - const EditorWindow* const window = FindWindow(windowId); - if (window == nullptr || !window->IsWorkspaceWindow()) { - outWorkspaceController = {}; - return false; - } - - outWorkspaceController = window->GetWorkspaceController(); - return true; -} - -bool EditorWindowRegistryRuntime::TryApplyWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, - bool primary) { - EditorWindow* const window = FindWindow(windowId); - if (window == nullptr || !window->IsWorkspaceWindow()) { - return false; - } - - window->SetPrimary(primary); - window->ReplaceWorkspaceController(std::move(workspaceController)); - return true; -} - -bool EditorWindowRegistryRuntime::ResetWorkspaceInteractionState(std::string_view windowId) { - EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - return false; - } - - window->ResetInteractionState(); - return true; -} - -bool EditorWindowRegistryRuntime::TryResolveDockTabDragHotspot( - std::string_view windowId, - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outDragHotspot) const { - const EditorWindow* const window = FindWindow(windowId); - return window != nullptr && window->TryResolveDockTabDragHotspot( - nodeId, - panelId, - screenPoint, - outDragHotspot); -} - -bool EditorWindowRegistryRuntime::TryResolveDockTabDropTarget( - std::string_view windowId, - EditorWindowScreenPoint screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const { - const EditorWindow* const window = FindWindow(windowId); - return window != nullptr && window->TryResolveDockTabDropTarget(screenPoint, outTarget); -} - -bool EditorWindowRegistryRuntime::SetDockHostDropPreview( - std::string_view windowId, - const Widgets::UIEditorDockHostDropPreviewState& preview) { - EditorWindow* const window = FindWindow(windowId); - return window != nullptr && window->SetDockHostDropPreview(preview); -} - -bool EditorWindowRegistryRuntime::ClearDockHostDropPreview(std::string_view windowId) { - EditorWindow* const window = FindWindow(windowId); - return window != nullptr && window->ClearDockHostDropPreview(); -} - -bool EditorWindowRegistryRuntime::AcquireGlobalTabDragPointerCapture(std::string_view windowId) { - EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - return false; - } - - window->AcquirePointerCapture(EditorWindowPointerCaptureOwner::GlobalTabDrag); - return true; -} - -bool EditorWindowRegistryRuntime::ReleaseGlobalTabDragPointerCapture(std::string_view windowId) { - EditorWindow* const window = FindWindow(windowId); - if (window == nullptr) { - return false; - } - - window->ReleasePointerCapture(EditorWindowPointerCaptureOwner::GlobalTabDrag); - return true; -} - -EditorWindow* EditorWindowRegistryRuntime::FindPrimaryWindow() { - for (const std::unique_ptr& window : m_windows) { - if (window != nullptr && window->IsPrimary()) { - return window.get(); - } - } - - return nullptr; -} - -const EditorWindow* EditorWindowRegistryRuntime::FindPrimaryWindow() const { - return const_cast(this)->FindPrimaryWindow(); -} - -bool EditorWindowRegistryRuntime::HasWindows() const { - return !m_windows.empty(); -} - -std::string EditorWindowRegistryRuntime::DescribeWindowSet() const { - return DescribeWindows(m_windows); -} - -std::vector -EditorWindowRegistryRuntime::CollectAllWindowCloseTargets() { - std::vector closeTargets = {}; - closeTargets.reserve(m_windows.size()); - for (const std::unique_ptr& window : m_windows) { - if (window != nullptr) { - closeTargets.push_back(window.get()); - } - } - return closeTargets; -} - -std::vector -EditorWindowRegistryRuntime::CollectSiblingCloseTargetsForPrimaryDestroyed( - const EditorWindow& destroyedWindow) { - std::vector closeTargets = {}; - closeTargets.reserve(m_windows.size()); - for (const std::unique_ptr& otherWindow : m_windows) { - if (otherWindow == nullptr || - otherWindow->GetHwnd() == nullptr || - otherWindow->IsClosing()) { - continue; - } - if (otherWindow.get() == &destroyedWindow) { - continue; - } - closeTargets.push_back(otherWindow.get()); - } - return closeTargets; -} - -void EditorWindowRegistryRuntime::ReapDestroyedWindows() { - for (auto it = m_windows.begin(); it != m_windows.end();) { - EditorWindow* const window = it->get(); - if (window == nullptr || !window->IsDestroyed()) { - ++it; - continue; - } - - LogRuntimeTrace( - "window-close", - "ReapDestroyedWindows erase windowId='" + std::string(window->GetWindowId()) + - "' registryBefore=" + DescribeWindows(m_windows)); - it = m_windows.erase(it); - LogRuntimeTrace( - "window-close", - "ReapDestroyedWindows erase end registryAfter=" + DescribeWindows(m_windows)); - } -} - -void EditorWindowRegistryRuntime::ForEachWindowSnapshot( - const std::function& visitor) const { - for (const std::unique_ptr& window : m_windows) { - if (window == nullptr) { - continue; - } - - EditorWindowSnapshot snapshot = {}; - if (TryGetWindowSnapshot(window->GetWindowId(), snapshot) && !visitor(snapshot)) { - break; - } - } -} - -void EditorWindowRegistryRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - AppendUIEditorRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.h deleted file mode 100644 index 6c4f6ba8..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowRegistryRuntime.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Windowing/Host/EditorWindowDirectory.h" -#include "Windowing/Host/EditorWindowTraceSink.h" -#include "Windowing/Host/EditorWindowUtilitySessionHost.h" -#include "Windowing/Ports/EditorWindowWorkspaceContentPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceHostPort.h" - -#include - -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindow; -class EditorWindowRegistryRuntime final - : public EditorWindowDirectory - , public EditorWindowUtilitySessionHost - , public EditorWindowTraceSink - , public EditorWindowWorkspaceContentPort - , public EditorWindowWorkspaceHostPort { -public: - EditorWindowRegistryRuntime() = default; - ~EditorWindowRegistryRuntime() = default; - - EditorWindow* RegisterWindow(std::unique_ptr window); - bool UnregisterWindow(EditorWindow* window); - - EditorWindow* FindWindow(HWND hwnd); - const EditorWindow* FindWindow(HWND hwnd) const; - EditorWindow* FindWindow(std::string_view windowId); - const EditorWindow* FindWindow(std::string_view windowId) const; - bool TryGetWindowSnapshot( - std::string_view windowId, - EditorWindowSnapshot& outSnapshot) const override; - bool UpdateUtilityWindowSession( - std::string_view windowId, - EditorUtilityWindowSession session) override; - bool TryGetWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController& outWorkspaceController) const override; - bool TryApplyWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, - bool primary) override; - bool ResetWorkspaceInteractionState(std::string_view windowId) override; - bool TryResolveDockTabDragHotspot( - std::string_view windowId, - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outDragHotspot) const override; - bool TryResolveDockTabDropTarget( - std::string_view windowId, - EditorWindowScreenPoint screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const override; - bool SetDockHostDropPreview( - std::string_view windowId, - const Widgets::UIEditorDockHostDropPreviewState& preview) override; - bool ClearDockHostDropPreview(std::string_view windowId) override; - bool AcquireGlobalTabDragPointerCapture(std::string_view windowId) override; - bool ReleaseGlobalTabDragPointerCapture(std::string_view windowId) override; - EditorWindow* FindPrimaryWindow(); - const EditorWindow* FindPrimaryWindow() const; - - bool HasWindows() const; - std::string DescribeWindowSet() const; - std::vector CollectAllWindowCloseTargets(); - std::vector CollectSiblingCloseTargetsForPrimaryDestroyed( - const EditorWindow& destroyedWindow); - void ReapDestroyedWindows(); - - std::vector>& GetWindows() { return m_windows; } - const std::vector>& GetWindows() const { return m_windows; } - - void ForEachWindowSnapshot( - const std::function& visitor) const override; - - void LogRuntimeTrace(std::string_view channel, std::string_view message) const override; - -private: - std::vector> m_windows = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp deleted file mode 100644 index 3cd4fbe0..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.cpp +++ /dev/null @@ -1,331 +0,0 @@ -#include "Platform/Win32/Windowing/EditorWindowSession.h" - -#include "Platform/Win32/Windowing/EditorWindowSupport.h" - -#include - -namespace XCEngine::UI::Editor::App { - -using namespace EditorWindowSupport; - -EditorWindowSession::EditorWindowSession( - std::string windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - std::wstring title, - bool primary) { - m_state.window.windowId = std::move(windowId); - m_state.window.windowType = windowType; - m_state.window.title = std::move(title); - m_state.window.primary = primary; - UpdateCachedTitleText(); -} - -std::string_view EditorWindowSession::GetWindowId() const { - return m_state.window.windowId; -} - -::XCEngine::UI::Editor::Windowing::Domain::WindowType EditorWindowSession::GetWindowType() const { - return m_state.window.windowType; -} - -HWND EditorWindowSession::GetHwnd() const { - return m_state.window.hwnd; -} - -bool EditorWindowSession::HasHwnd() const { - return m_state.window.hwnd != nullptr; -} - -EditorWindowLifecycleState EditorWindowSession::GetLifecycleState() const { - return m_state.window.lifecycle; -} - -bool EditorWindowSession::IsPrimary() const { - return m_state.window.primary; -} - -bool EditorWindowSession::IsClosing() const { - return m_state.window.lifecycle == EditorWindowLifecycleState::Closing; -} - -bool EditorWindowSession::IsDestroyed() const { - return m_state.window.lifecycle == EditorWindowLifecycleState::Destroyed; -} - -const std::wstring& EditorWindowSession::GetTitle() const { - return m_state.window.title; -} - -std::string_view EditorWindowSession::GetCachedTitleText() const { - return m_state.window.titleText; -} - -void EditorWindowSession::AttachHwnd(HWND hwnd) { - m_state.window.hwnd = hwnd; - m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; -} - -void EditorWindowSession::MarkNativeAttached() { - m_state.window.lifecycle = EditorWindowLifecycleState::NativeAttached; -} - -void EditorWindowSession::MarkInitializing() { - m_state.window.lifecycle = EditorWindowLifecycleState::Initializing; -} - -void EditorWindowSession::MarkRunning() { - m_state.window.lifecycle = EditorWindowLifecycleState::Running; -} - -void EditorWindowSession::MarkDestroyed() { - m_state.window.hwnd = nullptr; - m_state.window.lifecycle = EditorWindowLifecycleState::Destroyed; - m_state.frame = {}; - m_state.input = {}; - m_state.chrome = {}; -} - -void EditorWindowSession::MarkClosing() { - m_state.window.lifecycle = EditorWindowLifecycleState::Closing; -} - -void EditorWindowSession::SetPrimary(bool primary) { - m_state.window.primary = primary; -} - -void EditorWindowSession::SetTitle(std::wstring title) { - m_state.window.title = std::move(title); - UpdateCachedTitleText(); -} - -void EditorWindowSession::SetWindowDpi(UINT dpi) { - m_state.window.dpi = dpi == 0u ? 96u : dpi; -} - -UINT EditorWindowSession::GetWindowDpi() const { - return m_state.window.dpi; -} - -float EditorWindowSession::GetDpiScale(float baseDpiScale) const { - return baseDpiScale > 0.0f - ? static_cast(m_state.window.dpi) / baseDpiScale - : 1.0f; -} - -bool EditorWindowSession::IsTrackingMouseLeave() const { - return m_state.input.trackingMouseLeave; -} - -void EditorWindowSession::SetTrackingMouseLeave(bool trackingMouseLeave) { - m_state.input.trackingMouseLeave = trackingMouseLeave; -} - -EditorWindowPointerCaptureOwner EditorWindowSession::GetPointerCaptureOwner() const { - return m_state.input.pointerCaptureOwner; -} - -bool EditorWindowSession::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const { - return m_state.input.pointerCaptureOwner == owner; -} - -bool EditorWindowSession::HasPointerCaptureOwner() const { - return m_state.input.pointerCaptureOwner != EditorWindowPointerCaptureOwner::None; -} - -void EditorWindowSession::SetPointerCaptureOwner(EditorWindowPointerCaptureOwner owner) { - m_state.input.pointerCaptureOwner = owner; -} - -void EditorWindowSession::ClearPointerCaptureOwner() { - m_state.input.pointerCaptureOwner = EditorWindowPointerCaptureOwner::None; -} - -void EditorWindowSession::ResetInputWindowState() { - m_state.input = {}; -} - -void EditorWindowSession::ResetChromeWindowState() { - m_state.chrome = {}; -} - -void EditorWindowSession::BeginInteractiveResize() { - m_state.chrome.interactiveResizeActive = true; -} - -void EditorWindowSession::EndInteractiveResize() { - m_state.chrome.interactiveResizeActive = false; -} - -bool EditorWindowSession::IsInteractiveResize() const { - return m_state.chrome.interactiveResizeActive; -} - -void EditorWindowSession::BeginBorderlessResize( - Host::BorderlessWindowResizeEdge edge, - const POINT& initialScreenPoint, - const RECT& initialWindowRect) { - m_state.chrome.borderlessResize.active = edge != Host::BorderlessWindowResizeEdge::None; - m_state.chrome.borderlessResize.edge = edge; - m_state.chrome.borderlessResize.initialScreenPoint = initialScreenPoint; - m_state.chrome.borderlessResize.initialWindowRect = initialWindowRect; - m_state.chrome.borderlessResize.hoveredEdge = edge; - m_state.chrome.interactiveResizeActive = m_state.chrome.borderlessResize.active; -} - -void EditorWindowSession::EndBorderlessResize() { - m_state.chrome.borderlessResize.active = false; - m_state.chrome.borderlessResize.edge = Host::BorderlessWindowResizeEdge::None; - m_state.chrome.interactiveResizeActive = false; -} - -bool EditorWindowSession::IsBorderlessResizeActive() const { - return m_state.chrome.borderlessResize.active; -} - -Host::BorderlessWindowResizeEdge EditorWindowSession::GetBorderlessResizeEdge() const { - return m_state.chrome.borderlessResize.edge; -} - -const POINT& EditorWindowSession::GetBorderlessResizeInitialScreenPoint() const { - return m_state.chrome.borderlessResize.initialScreenPoint; -} - -const RECT& EditorWindowSession::GetBorderlessResizeInitialWindowRect() const { - return m_state.chrome.borderlessResize.initialWindowRect; -} - -void EditorWindowSession::SetHoveredBorderlessResizeEdge( - Host::BorderlessWindowResizeEdge edge) { - m_state.chrome.borderlessResize.hoveredEdge = edge; -} - -Host::BorderlessWindowResizeEdge EditorWindowSession::GetHoveredBorderlessResizeEdge() const { - return m_state.chrome.borderlessResize.hoveredEdge; -} - -void EditorWindowSession::SetBorderlessWindowMaximized(bool maximized) { - m_state.chrome.borderlessWindowPlacement.maximized = maximized; -} - -bool EditorWindowSession::IsBorderlessWindowMaximized() const { - return m_state.chrome.borderlessWindowPlacement.maximized; -} - -void EditorWindowSession::SetBorderlessWindowRestoreRect(const RECT& rect) { - m_state.chrome.borderlessWindowPlacement.restoreRect = rect; - m_state.chrome.borderlessWindowPlacement.hasRestoreRect = true; -} - -bool EditorWindowSession::TryGetBorderlessWindowRestoreRect(RECT& outRect) const { - outRect = {}; - if (!m_state.chrome.borderlessWindowPlacement.hasRestoreRect) { - return false; - } - - outRect = m_state.chrome.borderlessWindowPlacement.restoreRect; - return true; -} - -void EditorWindowSession::BeginBorderlessWindowDragRestore(const POINT& initialScreenPoint) { - m_state.chrome.borderlessWindowDragRestore.armed = true; - m_state.chrome.borderlessWindowDragRestore.initialScreenPoint = initialScreenPoint; -} - -void EditorWindowSession::EndBorderlessWindowDragRestore() { - m_state.chrome.borderlessWindowDragRestore = {}; -} - -bool EditorWindowSession::IsBorderlessWindowDragRestoreArmed() const { - return m_state.chrome.borderlessWindowDragRestore.armed; -} - -const POINT& EditorWindowSession::GetBorderlessWindowDragRestoreInitialScreenPoint() const { - return m_state.chrome.borderlessWindowDragRestore.initialScreenPoint; -} - -Host::BorderlessWindowChromeHitTarget EditorWindowSession::GetHoveredChromeTarget() const { - return m_state.chrome.chrome.hoveredTarget; -} - -void EditorWindowSession::SetHoveredChromeTarget( - Host::BorderlessWindowChromeHitTarget target) { - m_state.chrome.chrome.hoveredTarget = target; -} - -Host::BorderlessWindowChromeHitTarget EditorWindowSession::GetPressedChromeTarget() const { - return m_state.chrome.chrome.pressedTarget; -} - -void EditorWindowSession::SetPressedChromeTarget( - Host::BorderlessWindowChromeHitTarget target) { - m_state.chrome.chrome.pressedTarget = target; -} - -void EditorWindowSession::ResetChromeState() { - m_state.chrome.chrome = {}; -} - -bool EditorWindowSession::IsChromeStateClear() const { - return m_state.chrome.chrome.hoveredTarget == Host::BorderlessWindowChromeHitTarget::None && - m_state.chrome.chrome.pressedTarget == Host::BorderlessWindowChromeHitTarget::None; -} - -const Host::BorderlessWindowChromeState& EditorWindowSession::GetChromeState() const { - return m_state.chrome.chrome; -} - -void EditorWindowSession::SetPredictedClientPixelSize(UINT width, UINT height) { - if (width == 0u || height == 0u) { - m_state.frame.predictedClientPixelSize = {}; - return; - } - - m_state.frame.predictedClientPixelSize.active = true; - m_state.frame.predictedClientPixelSize.width = width; - m_state.frame.predictedClientPixelSize.height = height; - m_state.frame.predictedClientPixelSize.presented = false; -} - -void EditorWindowSession::ClearPredictedClientPixelSize() { - m_state.frame.predictedClientPixelSize = {}; -} - -bool EditorWindowSession::TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const { - outWidth = 0u; - outHeight = 0u; - if (!m_state.frame.predictedClientPixelSize.active || - m_state.frame.predictedClientPixelSize.width == 0u || - m_state.frame.predictedClientPixelSize.height == 0u) { - return false; - } - - outWidth = m_state.frame.predictedClientPixelSize.width; - outHeight = m_state.frame.predictedClientPixelSize.height; - return true; -} - -void EditorWindowSession::MarkPredictedClientPixelSizePresented() { - if (!m_state.frame.predictedClientPixelSize.active) { - return; - } - - m_state.frame.predictedClientPixelSize.presented = true; -} - -bool EditorWindowSession::ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height) { - if (!m_state.frame.predictedClientPixelSize.active || - !m_state.frame.predictedClientPixelSize.presented || - m_state.frame.predictedClientPixelSize.width != width || - m_state.frame.predictedClientPixelSize.height != height) { - return false; - } - - m_state.frame.predictedClientPixelSize = {}; - return true; -} - -void EditorWindowSession::UpdateCachedTitleText() { - m_state.window.titleText = WideToUtf8(m_state.window.title); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h deleted file mode 100644 index 74bb372e..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowSession.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include "Platform/Win32/Windowing/EditorWindowState.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowSession final { -public: - EditorWindowSession( - std::string windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - std::wstring title, - bool primary); - - std::string_view GetWindowId() const; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType GetWindowType() const; - HWND GetHwnd() const; - bool HasHwnd() const; - EditorWindowLifecycleState GetLifecycleState() const; - bool IsPrimary() const; - bool IsClosing() const; - bool IsDestroyed() const; - const std::wstring& GetTitle() const; - std::string_view GetCachedTitleText() const; - - void AttachHwnd(HWND hwnd); - void MarkNativeAttached(); - void MarkInitializing(); - void MarkRunning(); - void MarkDestroyed(); - void MarkClosing(); - void SetPrimary(bool primary); - void SetTitle(std::wstring title); - void SetWindowDpi(UINT dpi); - UINT GetWindowDpi() const; - float GetDpiScale(float baseDpiScale) const; - bool IsTrackingMouseLeave() const; - void SetTrackingMouseLeave(bool trackingMouseLeave); - EditorWindowPointerCaptureOwner GetPointerCaptureOwner() const; - bool OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const; - bool HasPointerCaptureOwner() const; - void SetPointerCaptureOwner(EditorWindowPointerCaptureOwner owner); - void ClearPointerCaptureOwner(); - void ResetInputWindowState(); - void ResetChromeWindowState(); - void BeginInteractiveResize(); - void EndInteractiveResize(); - bool IsInteractiveResize() const; - void BeginBorderlessResize( - Host::BorderlessWindowResizeEdge edge, - const POINT& initialScreenPoint, - const RECT& initialWindowRect); - void EndBorderlessResize(); - bool IsBorderlessResizeActive() const; - Host::BorderlessWindowResizeEdge GetBorderlessResizeEdge() const; - const POINT& GetBorderlessResizeInitialScreenPoint() const; - const RECT& GetBorderlessResizeInitialWindowRect() const; - void SetHoveredBorderlessResizeEdge(Host::BorderlessWindowResizeEdge edge); - Host::BorderlessWindowResizeEdge GetHoveredBorderlessResizeEdge() const; - void SetBorderlessWindowMaximized(bool maximized); - bool IsBorderlessWindowMaximized() const; - void SetBorderlessWindowRestoreRect(const RECT& rect); - bool TryGetBorderlessWindowRestoreRect(RECT& outRect) const; - void BeginBorderlessWindowDragRestore(const POINT& initialScreenPoint); - void EndBorderlessWindowDragRestore(); - bool IsBorderlessWindowDragRestoreArmed() const; - const POINT& GetBorderlessWindowDragRestoreInitialScreenPoint() const; - Host::BorderlessWindowChromeHitTarget GetHoveredChromeTarget() const; - void SetHoveredChromeTarget(Host::BorderlessWindowChromeHitTarget target); - Host::BorderlessWindowChromeHitTarget GetPressedChromeTarget() const; - void SetPressedChromeTarget(Host::BorderlessWindowChromeHitTarget target); - void ResetChromeState(); - bool IsChromeStateClear() const; - const Host::BorderlessWindowChromeState& GetChromeState() const; - - void SetPredictedClientPixelSize(UINT width, UINT height); - void ClearPredictedClientPixelSize(); - bool TryGetPredictedClientPixelSize(UINT& outWidth, UINT& outHeight) const; - void MarkPredictedClientPixelSizePresented(); - bool ConsumePresentedPredictedClientPixelSizeMatch(UINT width, UINT height); - -private: - void UpdateCachedTitleText(); - - EditorWindowState m_state = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/EditorWindowSupport.h b/new_editor/app/Platform/Win32/Windowing/EditorWindowSupport.h deleted file mode 100644 index b2fbc0e3..00000000 --- a/new_editor/app/Platform/Win32/Windowing/EditorWindowSupport.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "Support/EnvironmentFlags.h" -#include "Support/StringEncoding.h" -#include "Support/TextFormat.h" -#include "Windowing/Content/EditorWindowContentStyle.h" - -#include - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include - -namespace XCEngine::UI::Editor::App::EditorWindowSupport { - -using EditorWindowContentStyle::kBaseDpiScale; -using EditorWindowContentStyle::kBorderlessTitleBarFontSize; -using EditorWindowContentStyle::kBorderlessTitleBarHeightDips; -using EditorWindowContentStyle::kDefaultDpi; -using EditorWindowContentStyle::kShellBorderColor; -using EditorWindowContentStyle::kShellMutedTextColor; -using EditorWindowContentStyle::kShellSurfaceColor; -using EditorWindowContentStyle::kShellTextColor; - -UINT QuerySystemDpi(); -UINT QueryWindowDpi(HWND hwnd); -bool ResolveVerboseRuntimeTraceEnabled(); -void LogRuntimeTrace(std::string_view channel, std::string_view message); - -using App::TruncateText; -using App::WideToUtf8; - -} // namespace XCEngine::UI::Editor::App::EditorWindowSupport diff --git a/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.cpp b/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.cpp deleted file mode 100644 index f5a4f03c..00000000 --- a/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.cpp +++ /dev/null @@ -1,117 +0,0 @@ -#include "Platform/Win32/Windowing/Win32WindowApplicationRuntime.h" - -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowPlatformRuntime.h" -#include "Platform/Win32/Windowing/Win32WindowRuntimeGraph.h" -#include "Windowing/Application/EditorWindowApplicationRuntime.h" - -#include - -namespace XCEngine::UI::Editor::App { - -Win32WindowApplicationRuntime::Win32WindowApplicationRuntime( - std::unique_ptr platformRuntime, - EditorWindowApplicationRuntime& applicationRuntime, - EditorContext& editorContext) - : m_platformRuntime(std::move(platformRuntime)) { - if (m_platformRuntime == nullptr) { - return; - } - - m_nativeRuntimeGraph = std::make_unique( - *m_platformRuntime, - applicationRuntime, - editorContext); -} - -Win32WindowApplicationRuntime::~Win32WindowApplicationRuntime() = default; - -EditorWindow* Win32WindowApplicationRuntime::CreateEditorWindow( - EditorWindowContentSpec contentSpec, - const CreateParams& params) { - if (m_platformRuntime == nullptr) { - return nullptr; - } - - EditorWindow* const window = - m_platformRuntime->CreateEditorWindow(std::move(contentSpec), params); - if (window != nullptr) { - PumpFrames(EditorWindowFramePumpMode::AfterMessage); - } - return window; -} - -bool Win32WindowApplicationRuntime::CreateWindowHost( - EditorWindowContentSpec contentSpec, - const CreateParams& params) { - return CreateEditorWindow(std::move(contentSpec), params) != nullptr; -} - -bool Win32WindowApplicationRuntime::RequestClosePrimaryWindow() { - if (m_platformRuntime == nullptr || m_nativeRuntimeGraph == nullptr) { - return false; - } - - EditorWindow* const primaryWindow = m_platformRuntime->FindPrimaryWindow(); - if (primaryWindow == nullptr || primaryWindow->GetHwnd() == nullptr) { - return false; - } - - return m_nativeRuntimeGraph->PostCloseRequest(*primaryWindow); -} - -void Win32WindowApplicationRuntime::HandlePendingNativeWindowCreated(HWND hwnd) { - if (m_platformRuntime == nullptr) { - return; - } - m_platformRuntime->HandlePendingNativeWindowCreated(hwnd); -} - -void Win32WindowApplicationRuntime::Shutdown() { - if (m_nativeRuntimeGraph == nullptr) { - return; - } - m_nativeRuntimeGraph->Shutdown(); -} - -bool Win32WindowApplicationRuntime::TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult) { - if (m_nativeRuntimeGraph == nullptr) { - return false; - } - return m_nativeRuntimeGraph->TryDispatchWindowMessage( - hwnd, - message, - wParam, - lParam, - outResult); -} - -bool Win32WindowApplicationRuntime::HasWindows() const { - return m_platformRuntime != nullptr && m_platformRuntime->HasWindows(); -} - -void Win32WindowApplicationRuntime::DestroyClosedWindows() { - if (m_nativeRuntimeGraph == nullptr) { - return; - } - m_nativeRuntimeGraph->DestroyClosedWindows(); -} - -void Win32WindowApplicationRuntime::PumpFrames(EditorWindowFramePumpMode mode) { - if (m_nativeRuntimeGraph == nullptr) { - return; - } - m_nativeRuntimeGraph->PumpFrames(mode); -} - -} // namespace XCEngine::UI::Editor::App - - - - - diff --git a/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.h b/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.h deleted file mode 100644 index ddae22b6..00000000 --- a/new_editor/app/Platform/Win32/Windowing/Win32WindowApplicationRuntime.h +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Platform/Win32/Windowing/EditorWindowCreateParams.h" -#include "Platform/Win32/Windowing/EditorWindowFramePumpMode.h" -#include "Windowing/Content/EditorWindowContentRuntime.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindow; -class EditorWindowApplicationRuntime; -class EditorWindowPlatformRuntime; -class Win32WindowRuntimeGraph; - -class Win32WindowApplicationRuntime final { -public: - using CreateParams = EditorWindowCreateParams; - - Win32WindowApplicationRuntime( - std::unique_ptr platformRuntime, - EditorWindowApplicationRuntime& applicationRuntime, - EditorContext& editorContext); - ~Win32WindowApplicationRuntime(); - - Win32WindowApplicationRuntime(const Win32WindowApplicationRuntime&) = delete; - Win32WindowApplicationRuntime& operator=(const Win32WindowApplicationRuntime&) = delete; - Win32WindowApplicationRuntime(Win32WindowApplicationRuntime&&) = delete; - Win32WindowApplicationRuntime& operator=(Win32WindowApplicationRuntime&&) = delete; - - bool CreateWindowHost( - EditorWindowContentSpec contentSpec, - const CreateParams& params); - bool RequestClosePrimaryWindow(); - void HandlePendingNativeWindowCreated(HWND hwnd); - void Shutdown(); - bool TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult); - - bool HasWindows() const; - void DestroyClosedWindows(); - void PumpFrames(EditorWindowFramePumpMode mode); - -private: - EditorWindow* CreateEditorWindow( - EditorWindowContentSpec contentSpec, - const CreateParams& params); - - std::unique_ptr m_platformRuntime = {}; - std::unique_ptr m_nativeRuntimeGraph = {}; -}; - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.cpp b/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.cpp deleted file mode 100644 index 10e0c2d2..00000000 --- a/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "Platform/Win32/Windowing/Win32WindowRuntimeGraph.h" - -#include "Platform/Win32/Projection/Win32WindowCommandProjector.h" -#include "Platform/Win32/Windowing/EditorWindow.h" -#include "Platform/Win32/Windowing/EditorWindowFramePumpRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowLifecycleEventRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowLifecycleFinalizationRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowMessagePumpRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowPlatformRuntime.h" -#include "Platform/Win32/Windowing/EditorWindowRegistryRuntime.h" -#include "Windowing/Application/EditorWindowApplicationRuntime.h" - -namespace XCEngine::UI::Editor::App { - -Win32WindowRuntimeGraph::Win32WindowRuntimeGraph( - EditorWindowPlatformRuntime& platformRuntime, - EditorWindowApplicationRuntime& applicationRuntime, - EditorContext& editorContext) { - EditorWindowRegistryRuntime& windowRegistryRuntime = - platformRuntime.GetWindowRegistryRuntime(); - Win32WindowCommandProjector& windowCommandProjector = - platformRuntime.GetWindowCommandProjector(); - - m_lifecycleFinalizationRuntime = - std::make_unique( - windowRegistryRuntime, - applicationRuntime.GetWorkspaceInteractionRuntime(), - applicationRuntime.GetWorkspaceProjectionRuntime(), - windowCommandProjector); - m_lifecycleEventRuntime = std::make_unique( - applicationRuntime.GetApplicationStateRuntime(), - *m_lifecycleFinalizationRuntime); - m_messagePumpRuntime = std::make_unique( - windowRegistryRuntime, - editorContext, - applicationRuntime.GetWorkspaceInteractionRuntime(), - *m_lifecycleEventRuntime); - m_framePumpRuntime = std::make_unique( - windowRegistryRuntime, - editorContext, - applicationRuntime.GetApplicationStateRuntime(), - applicationRuntime.GetPostFrameRuntime()); - platformRuntime.BindApplicationStateRuntime( - applicationRuntime.GetApplicationStateRuntime()); - platformRuntime.BindLifecycleFinalizationRuntime(*m_lifecycleFinalizationRuntime); - applicationRuntime.GetLifecycleRelay().Attach(*m_lifecycleFinalizationRuntime); -} - -Win32WindowRuntimeGraph::~Win32WindowRuntimeGraph() = default; - -void Win32WindowRuntimeGraph::Shutdown() { - if (m_lifecycleFinalizationRuntime == nullptr) { - return; - } - m_lifecycleFinalizationRuntime->ShutdownAllWindows(); -} - -bool Win32WindowRuntimeGraph::PostCloseRequest(EditorWindow& window) { - if (m_lifecycleFinalizationRuntime == nullptr || window.IsDestroyed()) { - return false; - } - - m_lifecycleFinalizationRuntime->PostCloseRequest(window); - return true; -} - -bool Win32WindowRuntimeGraph::TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult) { - if (m_messagePumpRuntime == nullptr) { - return false; - } - return m_messagePumpRuntime->TryDispatchWindowMessage( - hwnd, - message, - wParam, - lParam, - outResult); -} - -void Win32WindowRuntimeGraph::DestroyClosedWindows() { - if (m_lifecycleFinalizationRuntime == nullptr) { - return; - } - m_lifecycleFinalizationRuntime->ReapDestroyedWindows(); -} - -void Win32WindowRuntimeGraph::PumpFrames(EditorWindowFramePumpMode mode) { - if (m_framePumpRuntime == nullptr) { - return; - } - m_framePumpRuntime->PumpFrames(mode); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.h b/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.h deleted file mode 100644 index 08cb3bc8..00000000 --- a/new_editor/app/Platform/Win32/Windowing/Win32WindowRuntimeGraph.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#include "Platform/Win32/Windowing/EditorWindowFramePumpMode.h" - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindow; -class EditorWindowApplicationRuntime; -class EditorWindowFramePumpRuntime; -class EditorWindowLifecycleEventRuntime; -class EditorWindowLifecycleFinalizationRuntime; -class EditorWindowMessagePumpRuntime; -class EditorWindowPlatformRuntime; - -class Win32WindowRuntimeGraph final { -public: - Win32WindowRuntimeGraph( - EditorWindowPlatformRuntime& platformRuntime, - EditorWindowApplicationRuntime& applicationRuntime, - EditorContext& editorContext); - ~Win32WindowRuntimeGraph(); - - Win32WindowRuntimeGraph(const Win32WindowRuntimeGraph&) = delete; - Win32WindowRuntimeGraph& operator=(const Win32WindowRuntimeGraph&) = delete; - Win32WindowRuntimeGraph(Win32WindowRuntimeGraph&&) = delete; - Win32WindowRuntimeGraph& operator=(Win32WindowRuntimeGraph&&) = delete; - - void Shutdown(); - bool PostCloseRequest(EditorWindow& window); - bool TryDispatchWindowMessage( - HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam, - LRESULT& outResult); - void DestroyClosedWindows(); - void PumpFrames(EditorWindowFramePumpMode mode); - -private: - std::unique_ptr m_lifecycleFinalizationRuntime = {}; - std::unique_ptr m_lifecycleEventRuntime = {}; - std::unique_ptr m_messagePumpRuntime = {}; - std::unique_ptr m_framePumpRuntime = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.cpp b/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.cpp deleted file mode 100644 index bf6474c6..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "Windowing/Application/EditorWindowApplicationRuntime.h" - - -#include "Composition/EditorContext.h" -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" -#include "Windowing/Application/EditorWindowCommandSink.h" -#include "Windowing/Application/EditorWindowPostFrameRuntime.h" -#include "Windowing/Ports/EditorWindowHostCreationPort.h" -#include "Windowing/Ports/EditorWindowNativeQueryPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceContentPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceHostPort.h" -#include "Windowing/Utility/EditorUtilityWindowPanelProvider.h" -#include "Windowing/Utility/EditorWindowUtilityRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h" - -namespace XCEngine::UI::Editor::App { - -EditorWindowApplicationRuntime::EditorWindowApplicationRuntime( - std::wstring primaryWindowTitle, - EditorWindowHostAdapters hostAdapters, - EditorContext& editorContext, - std::unique_ptr utilityPanelProvider) - : m_workspaceProjectionRuntime(std::make_unique( - std::move(primaryWindowTitle), - m_topologyService, - hostAdapters.windowCommandSink)) - , m_workspaceMutationRuntime(std::make_unique( - hostAdapters.windowDirectory, - hostAdapters.traceSink, - hostAdapters.workspaceContentPort, - hostAdapters.hostCreationPort, - m_lifecycleRelay, - editorContext, - *m_workspaceProjectionRuntime, - m_topologyService, - hostAdapters.windowCommandSink)) - , m_workspaceInteractionRuntime(std::make_unique( - hostAdapters.windowDirectory, - hostAdapters.traceSink, - hostAdapters.workspaceContentPort, - hostAdapters.workspaceHostPort, - m_topologyService, - hostAdapters.nativeQueryPort, - hostAdapters.windowCommandSink, - *m_workspaceMutationRuntime)) - , m_utilityPanelProvider(std::move(utilityPanelProvider)) - , m_utilityRuntime(std::make_unique( - hostAdapters.windowDirectory, - hostAdapters.utilitySessionHost, - hostAdapters.traceSink, - hostAdapters.hostCreationPort, - hostAdapters.nativeQueryPort, - m_lifecycleRelay, - m_topologyService, - hostAdapters.windowCommandSink, - *m_utilityPanelProvider)) - , m_applicationStateRuntime(std::make_unique( - m_frameScheduler, - m_sessionStore, - m_topologyService, - *m_workspaceInteractionRuntime)) - , m_postFrameRuntime(std::make_unique( - *m_applicationStateRuntime, - *m_workspaceProjectionRuntime, - *m_workspaceInteractionRuntime, - *m_utilityRuntime, - hostAdapters.windowCommandSink, - editorContext.GetSceneRuntime())) { -} - -EditorWindowApplicationRuntime::~EditorWindowApplicationRuntime() = default; - -EditorWindowApplicationStateRuntime& -EditorWindowApplicationRuntime::GetApplicationStateRuntime() { - return *m_applicationStateRuntime; -} - -EditorWindowLifecycleRelay& EditorWindowApplicationRuntime::GetLifecycleRelay() { - return m_lifecycleRelay; -} - -EditorWindowPostFrameRuntime& EditorWindowApplicationRuntime::GetPostFrameRuntime() { - return *m_postFrameRuntime; -} - -EditorWindowUtilityRuntime& EditorWindowApplicationRuntime::GetUtilityRuntime() { - return *m_utilityRuntime; -} - -EditorWindowWorkspaceInteractionRuntime& -EditorWindowApplicationRuntime::GetWorkspaceInteractionRuntime() { - return *m_workspaceInteractionRuntime; -} - -EditorWindowWorkspaceMutationRuntime& -EditorWindowApplicationRuntime::GetWorkspaceMutationRuntime() { - return *m_workspaceMutationRuntime; -} - -EditorWindowWorkspaceProjectionRuntime& -EditorWindowApplicationRuntime::GetWorkspaceProjectionRuntime() { - return *m_workspaceProjectionRuntime; -} - -} // namespace XCEngine::UI::Editor::App - - - - - diff --git a/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.h b/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.h deleted file mode 100644 index 841722b3..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowApplicationRuntime.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowLifecycleRelay.h" -#include "Windowing/Application/FrameScheduler.h" -#include "Windowing/Application/WindowTopologyService.h" -#include "Windowing/Application/WindowSession.h" -#include "Windowing/Host/EditorWindowHostAdapters.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorUtilityWindowPanelProvider; -class EditorWindowApplicationStateRuntime; -class EditorWindowCommandSink; -class EditorWindowHostCreationPort; -class EditorWindowNativeQueryPort; -class EditorWindowPostFrameRuntime; -class EditorWindowUtilityRuntime; -class EditorWindowWorkspaceInteractionRuntime; -class EditorWindowWorkspaceMutationRuntime; -class EditorWindowWorkspaceProjectionRuntime; - -class EditorWindowApplicationRuntime final { -public: - EditorWindowApplicationRuntime( - std::wstring primaryWindowTitle, - EditorWindowHostAdapters hostAdapters, - EditorContext& editorContext, - std::unique_ptr utilityPanelProvider); - ~EditorWindowApplicationRuntime(); - - EditorWindowApplicationRuntime(const EditorWindowApplicationRuntime&) = delete; - EditorWindowApplicationRuntime& operator=(const EditorWindowApplicationRuntime&) = delete; - EditorWindowApplicationRuntime(EditorWindowApplicationRuntime&&) = delete; - EditorWindowApplicationRuntime& operator=(EditorWindowApplicationRuntime&&) = delete; - - EditorWindowApplicationStateRuntime& GetApplicationStateRuntime(); - EditorWindowLifecycleRelay& GetLifecycleRelay(); - EditorWindowPostFrameRuntime& GetPostFrameRuntime(); - EditorWindowUtilityRuntime& GetUtilityRuntime(); - EditorWindowWorkspaceInteractionRuntime& GetWorkspaceInteractionRuntime(); - EditorWindowWorkspaceMutationRuntime& GetWorkspaceMutationRuntime(); - EditorWindowWorkspaceProjectionRuntime& GetWorkspaceProjectionRuntime(); - -private: - ::XCEngine::UI::Editor::Windowing::Application::FrameScheduler m_frameScheduler = {}; - ::XCEngine::UI::Editor::Windowing::Application::WindowSessionStore m_sessionStore = {}; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService m_topologyService = {}; - EditorWindowLifecycleRelay m_lifecycleRelay = {}; - std::unique_ptr m_workspaceProjectionRuntime = {}; - std::unique_ptr m_workspaceMutationRuntime = {}; - std::unique_ptr m_workspaceInteractionRuntime = {}; - std::unique_ptr m_utilityPanelProvider = {}; - std::unique_ptr m_utilityRuntime = {}; - std::unique_ptr m_applicationStateRuntime = {}; - std::unique_ptr m_postFrameRuntime = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.cpp b/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.cpp deleted file mode 100644 index edf38ba5..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" - -#include "Windowing/Utility/EditorUtilityWindowCatalog.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" - -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = XCEngine::UI::Editor::Windowing::Domain; -namespace WindowingApp = XCEngine::UI::Editor::Windowing::Application; - -Domain::WindowId ResolveDomainWindowId(std::string_view windowId) { - return Domain::WindowId(std::string(windowId)); -} - -WindowingApp::WindowSession& EnsureDomainWindowSession( - WindowingApp::WindowSessionStore& store, - std::string_view windowId, - Domain::WindowType windowType) { - return store.EnsureSession( - ResolveDomainWindowId(windowId), - windowType); -} - -std::string ResolveUtilityWindowTypeToken( - std::string_view windowId, - Domain::WindowType windowType) { - if (windowType != Domain::WindowType::Utility) { - return {}; - } - - EditorUtilityWindowType utilityWindowType = EditorUtilityWindowType::None; - if (!TryResolveEditorUtilityWindowTypeFromWindowId(windowId, utilityWindowType)) { - return {}; - } - - return std::string(ResolveEditorUtilityWindowTypeToken(utilityWindowType)); -} - -void SyncTopologyProjection( - WindowingApp::WindowTopologyService& topologyService, - std::string_view windowId, - Domain::WindowType windowType, - bool primary) { - Domain::WindowProjectionSnapshot projection = {}; - projection.windowId = ResolveDomainWindowId(windowId); - projection.windowType = windowType; - projection.primary = primary; - projection.utilityWindowType = ResolveUtilityWindowTypeToken(windowId, windowType); - topologyService.UpdateProjection(projection); -} - -void SyncTopologyWorkspaceSnapshot( - WindowingApp::WindowTopologyService& topologyService, - std::string_view windowId, - const UIEditorWorkspaceController* workspaceController) { - if (workspaceController == nullptr) { - return; - } - - topologyService.UpdateWorkspaceSnapshot( - ResolveDomainWindowId(windowId), - workspaceController->GetWorkspace(), - workspaceController->GetSession()); -} - -Domain::FrameDispatchMode ResolveFrameDispatchMode( - Domain::FramePriority priority, - Domain::FrameReason reason) { - return priority == Domain::FramePriority::Normal && - reason == Domain::FrameReason::SteadyTick - ? Domain::FrameDispatchMode::Steady - : Domain::FrameDispatchMode::Immediate; -} - -} // namespace - -EditorWindowApplicationStateRuntime::EditorWindowApplicationStateRuntime( - WindowingApp::FrameScheduler& frameScheduler, - WindowingApp::WindowSessionStore& sessionStore, - WindowingApp::WindowTopologyService& topologyService, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime) - : m_frameScheduler(frameScheduler) - , m_sessionStore(sessionStore) - , m_topologyService(topologyService) - , m_workspaceInteractionRuntime(workspaceInteractionRuntime) { -} - -void EditorWindowApplicationStateRuntime::ApplyWindowEvent( - std::string_view windowIdValue, - Domain::WindowType windowType, - const Domain::WindowEvent& event) { - EnsureDomainWindowSession( - m_sessionStore, - windowIdValue, - windowType).ApplyEvent(event); - - const Domain::WindowId windowId = ResolveDomainWindowId(windowIdValue); - switch (event.type) { - case Domain::WindowEvent::Type::FocusGained: - m_topologyService.SetActiveWindow(windowId); - break; - case Domain::WindowEvent::Type::FocusLost: - m_topologyService.ClearActiveWindow(windowId); - break; - default: - break; - } - - if (event.type == Domain::WindowEvent::Type::NativeDestroyed) { - m_sessionStore.RemoveSession(windowId); - m_frameScheduler.RemoveWindow(windowId); - m_workspaceInteractionRuntime.RemoveWindow(windowIdValue); - m_topologyService.RemoveWindow(windowId); - } -} - -void EditorWindowApplicationStateRuntime::RegisterNativeAttached( - std::string_view windowId, - Domain::WindowType windowType, - bool primary, - const UIEditorWorkspaceController* workspaceController) { - Domain::WindowEvent nativeAttachedEvent = {}; - nativeAttachedEvent.type = Domain::WindowEvent::Type::NativeAttached; - ApplyWindowEvent(windowId, windowType, nativeAttachedEvent); - SyncWindowTopology(windowId, windowType, primary, workspaceController); -} - -void EditorWindowApplicationStateRuntime::SyncWindowTopology( - std::string_view windowId, - Domain::WindowType windowType, - bool primary, - const UIEditorWorkspaceController* workspaceController) { - SyncTopologyProjection(m_topologyService, windowId, windowType, primary); - SyncTopologyWorkspaceSnapshot(m_topologyService, windowId, workspaceController); -} - -void EditorWindowApplicationStateRuntime::RequestSteadyFrame( - std::string_view windowId) { - m_frameScheduler.RequestFrame( - ResolveDomainWindowId(windowId), - Domain::FramePriority::Normal, - Domain::FrameReason::SteadyTick, - Domain::FrameDispatchMode::Steady); -} - -void EditorWindowApplicationStateRuntime::RequestImmediateFrame( - std::string_view windowId, - Domain::FramePriority priority, - Domain::FrameReason reason) { - if (windowId.empty()) { - return; - } - - m_frameScheduler.RequestFrame( - ResolveDomainWindowId(windowId), - priority, - reason, - ResolveFrameDispatchMode(priority, reason)); -} - -WindowingApp::WindowSessionResult EditorWindowApplicationStateRuntime::ApplyContentOutput( - std::string_view windowId, - Domain::WindowType windowType, - const Domain::WindowContentOutput& output) { - WindowingApp::WindowSessionResult result = - EnsureDomainWindowSession( - m_sessionStore, - windowId, - windowType).ApplyContentOutput(output); - WindowingApp::WindowSessionResult filteredResult = result; - filteredResult.intents.clear(); - - for (const Domain::WindowIntent& intent : result.intents) { - if (intent.type == Domain::WindowIntent::Type::RequestFrame && - intent.framePriority != Domain::FramePriority::None && - intent.frameReason != Domain::FrameReason::Unknown) { - RequestImmediateFrame( - windowId, - intent.framePriority, - intent.frameReason); - continue; - } - - filteredResult.intents.push_back(intent); - } - - return filteredResult; -} -std::vector -EditorWindowApplicationStateRuntime::ConsumeScheduledFrameRequests() { - return m_frameScheduler.ConsumeAll(); -} - -void EditorWindowApplicationStateRuntime::NotifyFrameExecuted( - const WindowingApp::FrameRequest& request) { - m_frameScheduler.NotifyFrameExecuted(request); -} - -} // namespace XCEngine::UI::Editor::App - - - - - diff --git a/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.h b/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.h deleted file mode 100644 index de843dcc..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowApplicationStateRuntime.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowFrameRequestSource.h" -#include "Windowing/Application/FrameScheduler.h" -#include "Windowing/Application/WindowSession.h" -#include "Windowing/Application/WindowTopologyService.h" - -#include -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowWorkspaceInteractionRuntime; - -class EditorWindowApplicationStateRuntime final - : public EditorWindowFrameRequestSource { -public: - EditorWindowApplicationStateRuntime( - ::XCEngine::UI::Editor::Windowing::Application::FrameScheduler& frameScheduler, - ::XCEngine::UI::Editor::Windowing::Application::WindowSessionStore& sessionStore, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime); - - void RegisterNativeAttached( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController* workspaceController); - void ApplyWindowEvent( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - const ::XCEngine::UI::Editor::Windowing::Domain::WindowEvent& event); - void RequestSteadyFrame(std::string_view windowId); - void RequestImmediateFrame( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::FramePriority priority, - ::XCEngine::UI::Editor::Windowing::Domain::FrameReason reason) override; - ::XCEngine::UI::Editor::Windowing::Application::WindowSessionResult ApplyContentOutput( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - const ::XCEngine::UI::Editor::Windowing::Domain::WindowContentOutput& output); - std::vector<::XCEngine::UI::Editor::Windowing::Application::FrameRequest> - ConsumeScheduledFrameRequests(); - void NotifyFrameExecuted( - const ::XCEngine::UI::Editor::Windowing::Application::FrameRequest& request); - -private: - void SyncWindowTopology( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController* workspaceController); - - ::XCEngine::UI::Editor::Windowing::Application::FrameScheduler& m_frameScheduler; - ::XCEngine::UI::Editor::Windowing::Application::WindowSessionStore& m_sessionStore; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& m_topologyService; - EditorWindowWorkspaceInteractionRuntime& m_workspaceInteractionRuntime; -}; - -} // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Windowing/Application/EditorWindowCommandSink.h b/new_editor/app/Windowing/Application/EditorWindowCommandSink.h deleted file mode 100644 index bc57f024..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowCommandSink.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowCommandSink { -public: - virtual ~EditorWindowCommandSink() = default; - - virtual void ProjectCommands( - std::string_view windowId, - std::span commands) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowContentSpec.h b/new_editor/app/Windowing/Application/EditorWindowContentSpec.h deleted file mode 100644 index 5a4de62b..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowContentSpec.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowPanel.h" -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -#include -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorWorkspaceWindowContentSpec { - UIEditorWorkspaceController workspaceController = {}; -}; - -struct EditorUtilityWindowContentSpec { - EditorUtilityWindowSession session = {}; - std::unique_ptr panel = {}; - ::XCEngine::UI::UISize minimumOuterSize = {}; -}; - -using EditorWindowContentSpec = - std::variant; - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Windowing/Application/EditorWindowContentUpdateResult.h b/new_editor/app/Windowing/Application/EditorWindowContentUpdateResult.h deleted file mode 100644 index eaab21a1..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowContentUpdateResult.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorWindowContentUpdateResult { - ::XCEngine::UI::Editor::Windowing::Domain::WindowContentOutput contentOutput = {}; - std::vector<::XCEngine::UI::Editor::Windowing::Domain::WindowCommand> commands = {}; - - bool HasContentOutput() const { - return contentOutput.cursorType.has_value() || - contentOutput.captureDemand.has_value() || - contentOutput.titleBarMode.has_value() || - !contentOutput.statusText.empty() || - !contentOutput.intents.empty() || - !commands.empty(); - } - - bool HasPostRenderWork() const { - return HasContentOutput(); - } -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowFrameRequestSource.h b/new_editor/app/Windowing/Application/EditorWindowFrameRequestSource.h deleted file mode 100644 index 88f1ba74..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowFrameRequestSource.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowFrameRequestSource { -public: - virtual ~EditorWindowFrameRequestSource() = default; - - virtual void RequestImmediateFrame( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::FramePriority priority, - ::XCEngine::UI::Editor::Windowing::Domain::FrameReason reason) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowGeometry.cpp b/new_editor/app/Windowing/Application/EditorWindowGeometry.cpp deleted file mode 100644 index ebf28c46..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowGeometry.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "Windowing/Application/EditorWindowGeometry.h" - -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -constexpr int kFloatingWindowTopOffset = 24; - -} // namespace - -int EditorWindowRect::Width() const { - return right - left; -} - -int EditorWindowRect::Height() const { - return bottom - top; -} - -bool EditorWindowRect::Contains(EditorWindowScreenPoint point) const { - return point.x >= left && point.x < right && point.y >= top && point.y < bottom; -} - -EditorWindowRect BuildEditorFloatingWindowRect( - EditorWindowScreenPoint screenPoint, - int preferredWidth, - int preferredHeight, - int fallbackWidth, - int fallbackHeight, - const EditorWindowRect* workArea) { - const int resolvedWidth = preferredWidth > 0 ? preferredWidth : fallbackWidth; - const int resolvedHeight = preferredHeight > 0 ? preferredHeight : fallbackHeight; - EditorWindowRect rect{ - screenPoint.x - resolvedWidth / 2, - screenPoint.y - kFloatingWindowTopOffset, - screenPoint.x - resolvedWidth / 2 + resolvedWidth, - screenPoint.y - kFloatingWindowTopOffset + resolvedHeight, - }; - - if (workArea != nullptr) { - const int width = rect.Width(); - const int height = rect.Height(); - rect.left = (std::max)(workArea->left, (std::min)(rect.left, workArea->right - width)); - rect.top = (std::max)(workArea->top, (std::min)(rect.top, workArea->bottom - height)); - rect.right = rect.left + width; - rect.bottom = rect.top + height; - } - - return rect; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowGeometry.h b/new_editor/app/Windowing/Application/EditorWindowGeometry.h deleted file mode 100644 index 60779b6f..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowGeometry.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -namespace XCEngine::UI::Editor::App { - -struct EditorWindowScreenPoint { - int x = 0; - int y = 0; -}; - -struct EditorWindowRect { - int left = 0; - int top = 0; - int right = 0; - int bottom = 0; - - int Width() const; - int Height() const; - bool Contains(EditorWindowScreenPoint point) const; -}; - -EditorWindowRect BuildEditorFloatingWindowRect( - EditorWindowScreenPoint screenPoint, - int preferredWidth = 0, - int preferredHeight = 0, - int fallbackWidth = 960, - int fallbackHeight = 720, - const EditorWindowRect* workArea = nullptr); - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.cpp b/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.cpp deleted file mode 100644 index 1366cee2..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "Windowing/Application/EditorWindowLifecycleRelay.h" - -namespace XCEngine::UI::Editor::App { - -void EditorWindowLifecycleRelay::Attach(EditorWindowLifecyclePort& target) { - m_target = ⌖ -} - -void EditorWindowLifecycleRelay::Detach(const EditorWindowLifecyclePort& target) { - if (m_target == &target) { - m_target = nullptr; - } -} - -void EditorWindowLifecycleRelay::PostCloseRequest(std::string_view windowId) { - if (m_target != nullptr) { - m_target->PostCloseRequest(windowId); - } -} - -void EditorWindowLifecycleRelay::AbortUnregisteredWindow(std::string_view windowId) { - if (m_target != nullptr) { - m_target->AbortUnregisteredWindow(windowId); - } -} - -void EditorWindowLifecycleRelay::ReapDestroyedWindows() { - if (m_target != nullptr) { - m_target->ReapDestroyedWindows(); - } -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.h b/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.h deleted file mode 100644 index b286d9b7..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowLifecycleRelay.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "Windowing/Ports/EditorWindowLifecyclePort.h" - -namespace XCEngine::UI::Editor::App { - -class EditorWindowLifecycleRelay final : public EditorWindowLifecyclePort { -public: - void Attach(EditorWindowLifecyclePort& target); - void Detach(const EditorWindowLifecyclePort& target); - - void PostCloseRequest(std::string_view windowId) override; - void AbortUnregisteredWindow(std::string_view windowId) override; - void ReapDestroyedWindows() override; - -private: - EditorWindowLifecyclePort* m_target = nullptr; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.cpp b/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.cpp deleted file mode 100644 index c3f0e47f..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include "Windowing/Application/EditorWindowPostFrameRuntime.h" - -#include "Windowing/Application/EditorWindowContentUpdateResult.h" -#include "Scene/EditorSceneRuntime.h" -#include "Windowing/Application/EditorWindowApplicationStateRuntime.h" -#include "Windowing/Utility/EditorWindowUtilityRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" -#include "Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h" -#include "Windowing/Application/EditorWindowCommandSink.h" -#include "Windowing/Utility/EditorUtilityWindowRequestSink.h" -#include "Windowing/Utility/WindowUtilityRequest.h" -#include "Windowing/Workspace/WindowWorkspaceTransferQueue.h" - -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -} // namespace - -EditorWindowPostFrameRuntime::EditorWindowPostFrameRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowWorkspaceProjectionRuntime& workspaceProjectionRuntime, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowUtilityRuntime& utilityRuntime, - EditorWindowCommandSink& windowCommandSink, - EditorSceneRuntime& sceneRuntime) - : m_applicationStateRuntime(applicationStateRuntime) - , m_workspaceProjectionRuntime(workspaceProjectionRuntime) - , m_workspaceInteractionRuntime(workspaceInteractionRuntime) - , m_utilityRuntime(utilityRuntime) - , m_windowCommandSink(windowCommandSink) - , m_utilityWindowSceneFeatureWorkflow(sceneRuntime) - , m_utilityWindowFrameWorkflow(m_utilityWindowSceneFeatureWorkflow) { - ResetEditorUtilityWindowResultState(m_utilityWindowResultState); -} - -bool EditorWindowPostFrameRuntime::IsGlobalTabDragActive() const { - return m_workspaceInteractionRuntime.IsGlobalTabDragActive(); -} - -EditorUtilityWindowResultState& EditorWindowPostFrameRuntime::GetUtilityWindowResultState() { - return m_utilityWindowResultState; -} - -EditorUtilityWindowFrameWorkflow& -EditorWindowPostFrameRuntime::GetUtilityWindowFrameWorkflow() { - return m_utilityWindowFrameWorkflow; -} - -void EditorWindowPostFrameRuntime::HandleRenderedWindow( - const ::XCEngine::UI::Editor::Windowing::Application::FrameRequest& request, - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController* workspaceController, - const EditorWindowContentUpdateResult& updateResult) { - m_applicationStateRuntime.NotifyFrameExecuted(request); - if (workspaceController != nullptr) { - m_workspaceProjectionRuntime.RefreshWorkspaceWindowPresentation( - windowId, - windowType, - primary, - *workspaceController); - } - if (!updateResult.HasContentOutput()) { - return; - } - - const std::size_t commandOffset = m_pendingCommands.size(); - m_pendingCommands.insert( - m_pendingCommands.end(), - updateResult.commands.begin(), - updateResult.commands.end()); - m_pendingContentOutputs.push_back(updateResult.contentOutput); - m_pendingContentOutputBatches.push_back(PendingContentOutputBatch{ - .sourceWindowId = std::string(windowId), - .sourceWindowType = windowType, - .contentOutputIndex = m_pendingContentOutputs.size() - 1, - .commandOffset = commandOffset, - .commandCount = updateResult.commands.size(), - }); -} - -void EditorWindowPostFrameRuntime::HandleUtilityWindowRequests( - EditorUtilityWindowRequestSink& utilityRequestSink) { - std::vector requests = - utilityRequestSink.ConsumePendingRequests(); - for (EditorUtilityWindowOpenRequest& request : requests) { - if (!request.IsValid()) { - continue; - } - - WindowUtilityRequest utilityRequest = {}; - utilityRequest.sourceWindowId = std::move(request.sourceWindowId); - utilityRequest.session = std::move(request.session); - utilityRequest.screenX = request.screenX; - utilityRequest.screenY = request.screenY; - utilityRequest.hasScreenPoint = request.hasScreenPoint; - m_utilityRuntime.QueueUtilityWindowRequest(utilityRequest); - } -} - -void EditorWindowPostFrameRuntime::HandleWorkspaceTransferRequests( - WindowWorkspaceTransferQueue& workspaceTransferQueue) { - std::vector requests = - workspaceTransferQueue.ConsumePendingWorkspaceTransferRequests(); - for (const WindowWorkspaceTransferRequest& request : requests) { - m_workspaceInteractionRuntime.QueueWorkspaceTransferRequest(request); - } -} - -void EditorWindowPostFrameRuntime::FlushPendingPostFrameWork() { - for (const PendingContentOutputBatch& batch : m_pendingContentOutputBatches) { - if (batch.sourceWindowId.empty() || - batch.contentOutputIndex >= m_pendingContentOutputs.size()) { - continue; - } - - m_applicationStateRuntime.ApplyContentOutput( - batch.sourceWindowId, - batch.sourceWindowType, - m_pendingContentOutputs[batch.contentOutputIndex]); - if (batch.commandOffset + batch.commandCount <= m_pendingCommands.size() && - batch.commandCount > 0u) { - m_windowCommandSink.ProjectCommands( - batch.sourceWindowId, - std::span( - m_pendingCommands.data() + batch.commandOffset, - batch.commandCount)); - } - } - - m_pendingContentOutputBatches.clear(); - m_pendingContentOutputs.clear(); - m_pendingCommands.clear(); - m_workspaceInteractionRuntime.FlushPendingWorkspaceTransferRequests(); - m_utilityRuntime.FlushPendingUtilityWindowRequests(); -} - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - - - - - diff --git a/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.h b/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.h deleted file mode 100644 index d048bef5..00000000 --- a/new_editor/app/Windowing/Application/EditorWindowPostFrameRuntime.h +++ /dev/null @@ -1,88 +0,0 @@ -#pragma once - -#include "Windowing/Application/FrameScheduler.h" -#include "Windowing/Utility/EditorUtilityWindowFrameWorkflow.h" -#include "Windowing/Utility/EditorUtilityWindowResultState.h" - -#include -#include -#include -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindow; -class EditorWindowApplicationStateRuntime; -class EditorWindowUtilityRuntime; -class EditorWindowWorkspaceInteractionRuntime; -class EditorWindowWorkspaceProjectionRuntime; -class EditorWindowCommandSink; -class EditorUtilityWindowRequestSink; -class WindowWorkspaceTransferQueue; -struct EditorWindowContentUpdateResult; - -class EditorWindowPostFrameRuntime final { -public: - EditorWindowPostFrameRuntime( - EditorWindowApplicationStateRuntime& applicationStateRuntime, - EditorWindowWorkspaceProjectionRuntime& workspaceProjectionRuntime, - EditorWindowWorkspaceInteractionRuntime& workspaceInteractionRuntime, - EditorWindowUtilityRuntime& utilityRuntime, - EditorWindowCommandSink& windowCommandSink, - EditorSceneRuntime& sceneRuntime); - - bool IsGlobalTabDragActive() const; - EditorUtilityWindowResultState& GetUtilityWindowResultState(); - EditorUtilityWindowFrameWorkflow& GetUtilityWindowFrameWorkflow(); - void HandleRenderedWindow( - const ::XCEngine::UI::Editor::Windowing::Application::FrameRequest& request, - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController* workspaceController, - const EditorWindowContentUpdateResult& updateResult); - void HandleUtilityWindowRequests(EditorUtilityWindowRequestSink& utilityRequestSink); - void HandleWorkspaceTransferRequests(WindowWorkspaceTransferQueue& workspaceTransferQueue); - void FlushPendingPostFrameWork(); - -private: - struct PendingContentOutputBatch { - std::string sourceWindowId = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType sourceWindowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; - std::size_t contentOutputIndex = 0; - std::size_t commandOffset = 0; - std::size_t commandCount = 0; - }; - - EditorWindowApplicationStateRuntime& m_applicationStateRuntime; - EditorWindowWorkspaceProjectionRuntime& m_workspaceProjectionRuntime; - EditorWindowWorkspaceInteractionRuntime& m_workspaceInteractionRuntime; - EditorWindowUtilityRuntime& m_utilityRuntime; - EditorWindowCommandSink& m_windowCommandSink; - EditorUtilityWindowResultState m_utilityWindowResultState = {}; - EditorUtilityWindowSceneFeatureWorkflow m_utilityWindowSceneFeatureWorkflow; - EditorUtilityWindowFrameWorkflow m_utilityWindowFrameWorkflow; - std::vector m_pendingContentOutputBatches = {}; - std::vector<::XCEngine::UI::Editor::Windowing::Domain::WindowContentOutput> - m_pendingContentOutputs = {}; - std::vector<::XCEngine::UI::Editor::Windowing::Domain::WindowCommand> - m_pendingCommands = {}; -}; - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - - diff --git a/new_editor/app/Windowing/Application/FrameScheduler.cpp b/new_editor/app/Windowing/Application/FrameScheduler.cpp deleted file mode 100644 index 5ca34a10..00000000 --- a/new_editor/app/Windowing/Application/FrameScheduler.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include "Windowing/Application/FrameScheduler.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -void FrameScheduler::RequestFrame( - Domain::WindowId windowId, - Domain::FramePriority priority, - Domain::FrameReason reason, - Domain::FrameDispatchMode dispatchMode) { - if (windowId.value.empty() || - priority == Domain::FramePriority::None || - reason == Domain::FrameReason::Unknown) { - return; - } - - PendingWindowFrame& pendingWindow = EnsurePendingWindow(std::move(windowId)); - if (dispatchMode == Domain::FrameDispatchMode::Steady && - !pendingWindow.hasPendingRequest && - pendingWindow.suppressNextSteadyFrame) { - pendingWindow.suppressNextSteadyFrame = false; - return; - } - - const std::uint32_t reasonMask = BuildReasonMask(reason); - if (!pendingWindow.hasPendingRequest) { - pendingWindow.request = FrameRequest{ - .windowId = pendingWindow.windowId, - .dispatchMode = dispatchMode, - .priority = priority, - .reason = reason, - .reasonMask = reasonMask, - }; - pendingWindow.hasPendingRequest = true; - return; - } - - FrameRequest& request = pendingWindow.request; - const Domain::FramePriority previousPriority = request.priority; - const Domain::FrameDispatchMode previousDispatchMode = request.dispatchMode; - const Domain::FrameReason previousReason = request.reason; - if (dispatchMode > request.dispatchMode) { - request.dispatchMode = dispatchMode; - } - if (priority > request.priority) { - request.priority = priority; - } - - request.reasonMask |= reasonMask; - - if (priority > previousPriority || - (priority == request.priority && - (dispatchMode > previousDispatchMode || - GetFrameReasonRank(reason) > GetFrameReasonRank(previousReason)))) { - request.reason = reason; - } else { - request.reason = ResolvePrimaryReason(request.reasonMask); - } -} - -bool FrameScheduler::HasPendingFrame() const { - return std::any_of( - m_pendingWindows.begin(), - m_pendingWindows.end(), - [](const PendingWindowFrame& pendingWindow) { - return pendingWindow.hasPendingRequest; - }); -} - -std::vector FrameScheduler::ConsumeAll() { - std::vector requests = {}; - requests.reserve(m_pendingWindows.size()); - for (PendingWindowFrame& pendingWindow : m_pendingWindows) { - if (!pendingWindow.hasPendingRequest) { - continue; - } - - requests.push_back(pendingWindow.request); - pendingWindow.request = {}; - pendingWindow.request.windowId = pendingWindow.windowId; - pendingWindow.hasPendingRequest = false; - } - - std::stable_sort( - requests.begin(), - requests.end(), - [](const FrameRequest& lhs, const FrameRequest& rhs) { - if (lhs.dispatchMode != rhs.dispatchMode) { - return lhs.dispatchMode > rhs.dispatchMode; - } - return lhs.priority > rhs.priority; - }); - return requests; -} - -void FrameScheduler::NotifyFrameExecuted(const FrameRequest& request) { - PendingWindowFrame* const pendingWindow = FindPendingWindow(request.windowId); - if (pendingWindow == nullptr) { - return; - } - - if (request.dispatchMode == Domain::FrameDispatchMode::Immediate) { - pendingWindow->suppressNextSteadyFrame = true; - } -} - -void FrameScheduler::RemoveWindow(const Domain::WindowId& windowId) { - const auto it = std::remove_if( - m_pendingWindows.begin(), - m_pendingWindows.end(), - [&windowId](const PendingWindowFrame& pendingWindow) { - return pendingWindow.windowId == windowId; - }); - m_pendingWindows.erase(it, m_pendingWindows.end()); -} - -std::uint32_t FrameScheduler::BuildReasonMask(Domain::FrameReason reason) { - const std::uint32_t reasonOrdinal = static_cast(reason); - if (reasonOrdinal >= 32u) { - return 0u; - } - return 1u << reasonOrdinal; -} - -int FrameScheduler::GetFrameReasonRank(Domain::FrameReason reason) { - switch (reason) { - case Domain::FrameReason::DpiChange: - return 6; - case Domain::FrameReason::Resize: - return 5; - case Domain::FrameReason::InteractionContinuation: - return 4; - case Domain::FrameReason::ContentInvalidation: - return 3; - case Domain::FrameReason::PaintValidation: - return 2; - case Domain::FrameReason::SteadyTick: - return 1; - case Domain::FrameReason::Unknown: - default: - return 0; - } -} - -Domain::FrameReason FrameScheduler::ResolvePrimaryReason(std::uint32_t reasonMask) { - constexpr Domain::FrameReason kPriorityOrder[] = { - Domain::FrameReason::DpiChange, - Domain::FrameReason::Resize, - Domain::FrameReason::InteractionContinuation, - Domain::FrameReason::ContentInvalidation, - Domain::FrameReason::PaintValidation, - Domain::FrameReason::SteadyTick, - }; - - for (const Domain::FrameReason reason : kPriorityOrder) { - if ((reasonMask & BuildReasonMask(reason)) != 0u) { - return reason; - } - } - - return Domain::FrameReason::Unknown; -} - -FrameScheduler::PendingWindowFrame& FrameScheduler::EnsurePendingWindow( - Domain::WindowId windowId) { - if (PendingWindowFrame* const pendingWindow = FindPendingWindow(windowId)) { - return *pendingWindow; - } - - m_pendingWindows.push_back(PendingWindowFrame{ - .windowId = std::move(windowId), - }); - m_pendingWindows.back().request.windowId = m_pendingWindows.back().windowId; - return m_pendingWindows.back(); -} - -FrameScheduler::PendingWindowFrame* FrameScheduler::FindPendingWindow( - const Domain::WindowId& windowId) { - const auto it = std::find_if( - m_pendingWindows.begin(), - m_pendingWindows.end(), - [&windowId](const PendingWindowFrame& pendingWindow) { - return pendingWindow.windowId == windowId; - }); - return it != m_pendingWindows.end() ? &(*it) : nullptr; -} - -} // namespace XCEngine::UI::Editor::Windowing::Application diff --git a/new_editor/app/Windowing/Application/FrameScheduler.h b/new_editor/app/Windowing/Application/FrameScheduler.h deleted file mode 100644 index 7e991a24..00000000 --- a/new_editor/app/Windowing/Application/FrameScheduler.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -namespace Domain = XCEngine::UI::Editor::Windowing::Domain; - -struct FrameRequest { - Domain::WindowId windowId = {}; - Domain::FrameDispatchMode dispatchMode = Domain::FrameDispatchMode::Steady; - Domain::FramePriority priority = Domain::FramePriority::Normal; - Domain::FrameReason reason = Domain::FrameReason::Unknown; - std::uint32_t reasonMask = 0u; -}; - -class FrameScheduler final { -public: - void RequestFrame( - Domain::WindowId windowId, - Domain::FramePriority priority, - Domain::FrameReason reason, - Domain::FrameDispatchMode dispatchMode); - - bool HasPendingFrame() const; - std::vector ConsumeAll(); - void NotifyFrameExecuted(const FrameRequest& request); - void RemoveWindow(const Domain::WindowId& windowId); - -private: - struct PendingWindowFrame { - Domain::WindowId windowId = {}; - FrameRequest request = {}; - bool hasPendingRequest = false; - bool suppressNextSteadyFrame = false; - }; - - static std::uint32_t BuildReasonMask(Domain::FrameReason reason); - static int GetFrameReasonRank(Domain::FrameReason reason); - static Domain::FrameReason ResolvePrimaryReason(std::uint32_t reasonMask); - - PendingWindowFrame& EnsurePendingWindow(Domain::WindowId windowId); - PendingWindowFrame* FindPendingWindow(const Domain::WindowId& windowId); - - std::vector m_pendingWindows = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Application diff --git a/new_editor/app/Windowing/Application/WindowSession.cpp b/new_editor/app/Windowing/Application/WindowSession.cpp deleted file mode 100644 index 977509f9..00000000 --- a/new_editor/app/Windowing/Application/WindowSession.cpp +++ /dev/null @@ -1,154 +0,0 @@ -#include "Windowing/Application/WindowSession.h" - -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -namespace { - -bool ApplyWindowEventToState(Domain::WindowState& state, const Domain::WindowEvent& event) { - switch (event.type) { - case Domain::WindowEvent::Type::NativeAttached: - if (state.lifecycle == Domain::WindowLifecycleState::NativeAttached) { - return false; - } - state.lifecycle = Domain::WindowLifecycleState::NativeAttached; - return true; - case Domain::WindowEvent::Type::CloseRequested: - if (state.lifecycle == Domain::WindowLifecycleState::Closing) { - return false; - } - state.lifecycle = Domain::WindowLifecycleState::Closing; - return true; - case Domain::WindowEvent::Type::NativeDestroyed: - if (state.lifecycle == Domain::WindowLifecycleState::Destroyed) { - return false; - } - state.lifecycle = Domain::WindowLifecycleState::Destroyed; - return true; - case Domain::WindowEvent::Type::FocusGained: - if (state.presentation.focused) { - return false; - } - state.presentation.focused = true; - return true; - case Domain::WindowEvent::Type::FocusLost: - if (!state.presentation.focused) { - return false; - } - state.presentation.focused = false; - return true; - case Domain::WindowEvent::Type::ClientResized: - state.size.clientPixelWidth = event.width; - state.size.clientPixelHeight = event.height; - state.frame.needsFrame = true; - state.frame.priority = Domain::FramePriority::High; - ++state.frame.resizeEpoch; - return true; - case Domain::WindowEvent::Type::DpiChanged: - state.presentation.dpiScale = event.dpiScale; - state.frame.needsFrame = true; - state.frame.priority = Domain::FramePriority::Critical; - return true; - case Domain::WindowEvent::Type::InteractiveResizeStarted: - if (state.chrome.interactiveResize) { - return false; - } - state.chrome.interactiveResize = true; - return true; - case Domain::WindowEvent::Type::InteractiveResizeEnded: - if (!state.chrome.interactiveResize) { - return false; - } - state.chrome.interactiveResize = false; - return true; - case Domain::WindowEvent::Type::PaintRequested: - state.frame.needsFrame = true; - state.frame.priority = Domain::FramePriority::High; - return true; - case Domain::WindowEvent::Type::Unknown: - case Domain::WindowEvent::Type::FramePresented: - default: - return false; - } -} - -} // namespace - -WindowSession::WindowSession(Domain::WindowId windowId, Domain::WindowType windowType) { - m_state.identity.windowId = std::move(windowId); - m_state.identity.windowType = windowType; -} - -const Domain::WindowState& WindowSession::Snapshot() const { - return m_state; -} - -WindowSessionResult WindowSession::ApplyEvent(const Domain::WindowEvent& event) { - WindowSessionResult result = {}; - result.stateChanged = ApplyWindowEventToState(m_state, event); - return result; -} - -WindowSessionResult WindowSession::ApplyContentOutput(const Domain::WindowContentOutput& output) { - WindowSessionResult result = {}; - result.intents = output.intents; - result.stateChanged = !output.intents.empty(); - - if (output.cursorType.has_value() && m_state.content.cursorType != *output.cursorType) { - m_state.content.cursorType = *output.cursorType; - result.stateChanged = true; - } - - if (output.captureDemand.has_value() && - (m_state.content.captureDemand.shellInteractive != - output.captureDemand->shellInteractive || - m_state.content.captureDemand.hostedContent != - output.captureDemand->hostedContent)) { - m_state.content.captureDemand = *output.captureDemand; - result.stateChanged = true; - } - - if (output.titleBarMode.has_value() && - m_state.content.titleBarMode != *output.titleBarMode) { - m_state.content.titleBarMode = *output.titleBarMode; - result.stateChanged = true; - } - - if (m_state.content.statusText != output.statusText) { - m_state.content.statusText = output.statusText; - result.stateChanged = true; - } - - return result; -} - -WindowSession& WindowSessionStore::EnsureSession( - Domain::WindowId windowId, - Domain::WindowType windowType) { - const std::string key = windowId.value; - auto [it, inserted] = m_sessions.emplace( - key, - WindowSession(Domain::WindowId(key), windowType)); - if (inserted) { - return it->second; - } - - return it->second; -} - -WindowSession* WindowSessionStore::FindSession(const Domain::WindowId& windowId) { - const auto it = m_sessions.find(windowId.value); - return it != m_sessions.end() ? &it->second : nullptr; -} - -const WindowSession* WindowSessionStore::FindSession( - const Domain::WindowId& windowId) const { - return const_cast(this)->FindSession(windowId); -} - -void WindowSessionStore::RemoveSession(const Domain::WindowId& windowId) { - m_sessions.erase(windowId.value); -} - -} // namespace XCEngine::UI::Editor::Windowing::Application diff --git a/new_editor/app/Windowing/Application/WindowSession.h b/new_editor/app/Windowing/Application/WindowSession.h deleted file mode 100644 index fa15fe7c..00000000 --- a/new_editor/app/Windowing/Application/WindowSession.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -namespace Domain = XCEngine::UI::Editor::Windowing::Domain; - -struct WindowSessionResult { - bool stateChanged = false; - std::vector intents = {}; -}; - -class WindowSession final { -public: - WindowSession(Domain::WindowId windowId, Domain::WindowType windowType); - - const Domain::WindowState& Snapshot() const; - - WindowSessionResult ApplyEvent(const Domain::WindowEvent& event); - WindowSessionResult ApplyContentOutput(const Domain::WindowContentOutput& output); - -private: - Domain::WindowState m_state = {}; -}; - -class WindowSessionStore final { -public: - WindowSession& EnsureSession(Domain::WindowId windowId, Domain::WindowType windowType); - WindowSession* FindSession(const Domain::WindowId& windowId); - const WindowSession* FindSession(const Domain::WindowId& windowId) const; - void RemoveSession(const Domain::WindowId& windowId); - -private: - std::unordered_map m_sessions = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Application diff --git a/new_editor/app/Windowing/Application/WindowTopologyService.h b/new_editor/app/Windowing/Application/WindowTopologyService.h deleted file mode 100644 index 404afac1..00000000 --- a/new_editor/app/Windowing/Application/WindowTopologyService.h +++ /dev/null @@ -1,478 +0,0 @@ -#pragma once - -#include "Windowing/Application/WindowTopologyState.h" - -#include "Windowing/Workspace/UIEditorWindowWorkspaceModel.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { - -namespace Domain = XCEngine::UI::Editor::Windowing::Domain; - -class WindowTopologyService final { -public: - const Domain::WindowTopologyState& Snapshot() const { - return m_state; - } - - bool IsPrimaryWindowId(std::string_view windowId) const { - if (windowId.empty()) { - return false; - } - - if (WindowIdEquals(m_state.primaryWindowId, windowId)) { - return true; - } - - const auto it = std::find_if( - m_state.windowProjections.begin(), - m_state.windowProjections.end(), - [windowId](const Domain::WindowProjectionSnapshot& projection) { - return projection.primary && WindowIdEquals(projection.windowId, windowId); - }); - return it != m_state.windowProjections.end(); - } - - void UpdateProjection(const Domain::WindowProjectionSnapshot& projection) { - auto it = std::find_if( - m_state.windowProjections.begin(), - m_state.windowProjections.end(), - [&projection](const Domain::WindowProjectionSnapshot& current) { - return current.windowId == projection.windowId; - }); - if (it == m_state.windowProjections.end()) { - m_state.windowProjections.push_back(projection); - } else { - *it = projection; - } - - UpsertWindowId(m_state.orderedWindowIds, projection.windowId); - RemoveWindowId(m_state.workspaceWindowIds, projection.windowId); - RemoveWindowId(m_state.utilityWindowIds, projection.windowId); - - switch (projection.windowType) { - case Domain::WindowType::PrimaryWorkspace: - case Domain::WindowType::DetachedWorkspace: - UpsertWindowId(m_state.workspaceWindowIds, projection.windowId); - break; - case Domain::WindowType::Utility: - UpsertWindowId(m_state.utilityWindowIds, projection.windowId); - break; - case Domain::WindowType::Unknown: - default: - break; - } - - if (projection.primary) { - m_state.primaryWindowId = projection.windowId; - } else if (m_state.primaryWindowId == projection.windowId) { - m_state.primaryWindowId = {}; - } - } - - void SetActiveWindow(const Domain::WindowId& windowId) { - if (windowId.value.empty()) { - return; - } - - m_state.activeWindowId = windowId; - } - - void ClearActiveWindow(const Domain::WindowId& windowId) { - if (m_state.activeWindowId == windowId) { - m_state.activeWindowId = {}; - } - } - - void UpdateWorkspaceSnapshot( - const Domain::WindowId& windowId, - const ::XCEngine::UI::Editor::UIEditorWorkspaceModel& workspace, - const ::XCEngine::UI::Editor::UIEditorWorkspaceSession& session) { - if (windowId.value.empty()) { - return; - } - - Domain::WorkspaceStateSnapshot* snapshot = FindMutableWorkspaceStateSnapshot(windowId); - if (snapshot == nullptr) { - m_state.workspaceStateSnapshots.push_back( - Domain::WorkspaceStateSnapshot{ - .windowId = windowId, - .workspace = workspace, - .session = session, - .valid = true, - }); - return; - } - - snapshot->workspace = workspace; - snapshot->session = session; - snapshot->valid = true; - } - - void ClearWorkspaceSnapshot(const Domain::WindowId& windowId) { - std::erase_if( - m_state.workspaceStateSnapshots, - [&windowId](const Domain::WorkspaceStateSnapshot& current) { - return current.windowId == windowId; - }); - } - - bool TryGetWorkspaceState( - const Domain::WindowId& windowId, - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceState& outState) const { - outState = {}; - if (windowId.value.empty() || !ShouldExposeWorkspaceSnapshot(windowId)) { - return false; - } - - const Domain::WorkspaceStateSnapshot* const snapshot = - FindWorkspaceStateSnapshot(windowId); - if (snapshot == nullptr || !snapshot->valid) { - return false; - } - - outState.windowId = windowId.value; - outState.workspace = snapshot->workspace; - outState.session = snapshot->session; - return true; - } - - bool TryBuildWorkspaceSet( - std::string_view excludedWindowId, - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet& outWindowSet, - std::string& outError) const { - outWindowSet = {}; - outError.clear(); - - const std::vector orderedWindowIds = - BuildOrderedWorkspaceWindowIds(); - for (const Domain::WindowId& windowId : orderedWindowIds) { - if (windowId.value.empty() || WindowIdEquals(windowId, excludedWindowId)) { - continue; - } - - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceState state = {}; - if (!TryBuildWorkspaceState(windowId, state, outError)) { - outWindowSet = {}; - return false; - } - - outWindowSet.windows.push_back(std::move(state)); - } - - if (!m_state.primaryWindowId.value.empty() && - !WindowIdEquals(m_state.primaryWindowId, excludedWindowId) && - ::XCEngine::UI::Editor::FindUIEditorWindowWorkspaceState( - outWindowSet, - m_state.primaryWindowId.value) != nullptr) { - outWindowSet.primaryWindowId = m_state.primaryWindowId.value; - } - - if (!m_state.activeWindowId.value.empty() && - !WindowIdEquals(m_state.activeWindowId, excludedWindowId) && - ::XCEngine::UI::Editor::FindUIEditorWindowWorkspaceState( - outWindowSet, - m_state.activeWindowId.value) != nullptr) { - outWindowSet.activeWindowId = m_state.activeWindowId.value; - } - - if (outWindowSet.activeWindowId.empty()) { - if (!outWindowSet.primaryWindowId.empty()) { - outWindowSet.activeWindowId = outWindowSet.primaryWindowId; - } else if (!outWindowSet.windows.empty()) { - outWindowSet.activeWindowId = outWindowSet.windows.front().windowId; - } - } - - return true; - } - - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet BuildWorkspaceSet() const { - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet windowSet = {}; - std::string error = {}; - if (!TryBuildWorkspaceSet({}, windowSet, error)) { - windowSet = {}; - } - return windowSet; - } - - void ReplaceWorkspaceWindowSet( - const ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet& windowSet) { - std::vector nextWorkspaceWindowIds = {}; - nextWorkspaceWindowIds.reserve(windowSet.windows.size()); - - for (const ::XCEngine::UI::Editor::UIEditorWindowWorkspaceState& windowState : - windowSet.windows) { - if (windowState.windowId.empty()) { - continue; - } - - const Domain::WindowId windowId(windowState.windowId); - nextWorkspaceWindowIds.push_back(windowId); - UpdateWorkspaceSnapshot(windowId, windowState.workspace, windowState.session); - UpdateProjection(Domain::WindowProjectionSnapshot{ - .windowId = windowId, - .windowType = - windowState.windowId == windowSet.primaryWindowId - ? Domain::WindowType::PrimaryWorkspace - : Domain::WindowType::DetachedWorkspace, - .primary = windowState.windowId == windowSet.primaryWindowId, - }); - } - - std::erase_if( - m_state.workspaceStateSnapshots, - [&nextWorkspaceWindowIds](const Domain::WorkspaceStateSnapshot& snapshot) { - return std::find( - nextWorkspaceWindowIds.begin(), - nextWorkspaceWindowIds.end(), - snapshot.windowId) == nextWorkspaceWindowIds.end(); - }); - std::erase_if( - m_state.windowProjections, - [&nextWorkspaceWindowIds](const Domain::WindowProjectionSnapshot& projection) { - return IsWorkspaceWindowType(projection.windowType) && - std::find( - nextWorkspaceWindowIds.begin(), - nextWorkspaceWindowIds.end(), - projection.windowId) == nextWorkspaceWindowIds.end(); - }); - - for (const Domain::WindowId& previousWorkspaceWindowId : m_state.workspaceWindowIds) { - RemoveWindowId(m_state.orderedWindowIds, previousWorkspaceWindowId); - } - - m_state.workspaceWindowIds = {}; - m_state.workspaceWindowIds.reserve(nextWorkspaceWindowIds.size()); - for (const Domain::WindowId& windowId : nextWorkspaceWindowIds) { - UpsertWindowId(m_state.workspaceWindowIds, windowId); - UpsertWindowId(m_state.orderedWindowIds, windowId); - } - - m_state.primaryWindowId = Domain::WindowId(windowSet.primaryWindowId); - if (!ShouldPreserveActiveWindow(windowSet)) { - if (!m_state.primaryWindowId.value.empty()) { - m_state.activeWindowId = m_state.primaryWindowId; - } else if (!nextWorkspaceWindowIds.empty()) { - m_state.activeWindowId = nextWorkspaceWindowIds.front(); - } else { - m_state.activeWindowId = {}; - } - } - } - - void RemoveWindow(const Domain::WindowId& windowId) { - auto matchWindowId = [&windowId](const auto& current) { - return current.windowId == windowId; - }; - - std::erase_if(m_state.windowProjections, matchWindowId); - std::erase_if(m_state.workspaceStateSnapshots, matchWindowId); - RemoveWindowId(m_state.orderedWindowIds, windowId); - RemoveWindowId(m_state.workspaceWindowIds, windowId); - RemoveWindowId(m_state.utilityWindowIds, windowId); - if (m_state.primaryWindowId == windowId) { - m_state.primaryWindowId = {}; - } - if (m_state.activeWindowId == windowId) { - m_state.activeWindowId = {}; - } - } - -private: - static bool IsWorkspaceWindowType(Domain::WindowType windowType) { - return windowType == Domain::WindowType::PrimaryWorkspace || - windowType == Domain::WindowType::DetachedWorkspace; - } - - static bool WindowIdEquals(const Domain::WindowId& windowId, std::string_view value) { - return windowId.value == value; - } - - bool ContainsWindowId( - const std::vector& windowIds, - std::string_view windowId) const { - return std::find_if( - windowIds.begin(), - windowIds.end(), - [windowId](const Domain::WindowId& current) { - return WindowIdEquals(current, windowId); - }) != windowIds.end(); - } - - std::vector BuildOrderedWorkspaceWindowIds() const { - std::vector orderedWindowIds = {}; - orderedWindowIds.reserve(m_state.workspaceWindowIds.size()); - - const auto appendIfWorkspaceWindow = [this, &orderedWindowIds]( - const Domain::WindowId& windowId) { - if (windowId.value.empty() || - !ContainsWindowId(m_state.workspaceWindowIds, windowId.value) || - ContainsWindowId(orderedWindowIds, windowId.value)) { - return; - } - - const Domain::WindowProjectionSnapshot* const projection = FindProjection(windowId); - if (projection == nullptr || !IsWorkspaceWindowType(projection->windowType)) { - return; - } - - orderedWindowIds.push_back(windowId); - }; - - for (const Domain::WindowId& windowId : m_state.orderedWindowIds) { - appendIfWorkspaceWindow(windowId); - } - for (const Domain::WindowId& windowId : m_state.workspaceWindowIds) { - appendIfWorkspaceWindow(windowId); - } - - return orderedWindowIds; - } - - bool TryBuildWorkspaceState( - const Domain::WindowId& windowId, - ::XCEngine::UI::Editor::UIEditorWindowWorkspaceState& outState, - std::string& outError) const { - outState = {}; - outError.clear(); - - const Domain::WorkspaceStateSnapshot* const workspaceState = - FindWorkspaceStateSnapshot(windowId); - if (workspaceState == nullptr || !workspaceState->valid) { - outError = "missing workspace snapshot for window '" + windowId.value + "'"; - return false; - } - - outState.windowId = windowId.value; - outState.workspace = workspaceState->workspace; - outState.session = workspaceState->session; - return true; - } - - static const Domain::WorkspaceStateSnapshot* FindWorkspaceStateSnapshot( - const std::vector& snapshots, - const Domain::WindowId& windowId) { - const auto it = std::find_if( - snapshots.begin(), - snapshots.end(), - [&windowId](const Domain::WorkspaceStateSnapshot& current) { - return current.windowId == windowId; - }); - return it != snapshots.end() ? &(*it) : nullptr; - } - - static Domain::WorkspaceStateSnapshot* FindMutableWorkspaceStateSnapshot( - std::vector& snapshots, - const Domain::WindowId& windowId) { - const auto it = std::find_if( - snapshots.begin(), - snapshots.end(), - [&windowId](const Domain::WorkspaceStateSnapshot& current) { - return current.windowId == windowId; - }); - return it != snapshots.end() ? &(*it) : nullptr; - } - - static std::string ResolveWindowSetWindowId( - const ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet& windowSet, - const Domain::WindowId& windowId) { - if (windowId.value.empty()) { - return {}; - } - - return ::XCEngine::UI::Editor::FindUIEditorWindowWorkspaceState( - windowSet, - windowId.value) != nullptr - ? windowId.value - : std::string{}; - } - - static void UpsertWindowId(std::vector& windowIds, const Domain::WindowId& windowId) { - if (windowId.value.empty()) { - return; - } - - const auto it = std::find(windowIds.begin(), windowIds.end(), windowId); - if (it == windowIds.end()) { - windowIds.push_back(windowId); - } - } - - static void RemoveWindowId(std::vector& windowIds, const Domain::WindowId& windowId) { - std::erase(windowIds, windowId); - } - - const Domain::WindowProjectionSnapshot* FindProjection(const Domain::WindowId& windowId) const { - const auto it = std::find_if( - m_state.windowProjections.begin(), - m_state.windowProjections.end(), - [&windowId](const Domain::WindowProjectionSnapshot& current) { - return current.windowId == windowId; - }); - return it != m_state.windowProjections.end() ? &(*it) : nullptr; - } - - const Domain::WorkspaceStateSnapshot* FindWorkspaceStateSnapshot( - const Domain::WindowId& windowId) const { - return FindWorkspaceStateSnapshot(m_state.workspaceStateSnapshots, windowId); - } - - Domain::WorkspaceStateSnapshot* FindMutableWorkspaceStateSnapshot( - const Domain::WindowId& windowId) { - return FindMutableWorkspaceStateSnapshot(m_state.workspaceStateSnapshots, windowId); - } - - bool ShouldExposeWorkspaceSnapshot(const Domain::WindowId& windowId) const { - const Domain::WindowProjectionSnapshot* const projection = FindProjection(windowId); - return projection == nullptr || IsWorkspaceWindowType(projection->windowType); - } - - std::string ResolvePrimaryWindowId( - const ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet& windowSet) const { - if (const std::string primaryWindowId = - ResolveWindowSetWindowId(windowSet, m_state.primaryWindowId); - !primaryWindowId.empty()) { - return primaryWindowId; - } - - for (const Domain::WindowProjectionSnapshot& projection : m_state.windowProjections) { - if (!projection.primary) { - continue; - } - - if (const std::string primaryWindowId = - ResolveWindowSetWindowId(windowSet, projection.windowId); - !primaryWindowId.empty()) { - return primaryWindowId; - } - } - - return !windowSet.windows.empty() ? windowSet.windows.front().windowId : std::string{}; - } - - bool ShouldPreserveActiveWindow( - const ::XCEngine::UI::Editor::UIEditorWindowWorkspaceSet& windowSet) const { - if (m_state.activeWindowId.value.empty()) { - return false; - } - - const Domain::WindowProjectionSnapshot* const activeProjection = - FindProjection(m_state.activeWindowId); - if (activeProjection == nullptr) { - return false; - } - - if (!IsWorkspaceWindowType(activeProjection->windowType)) { - return true; - } - - return !ResolveWindowSetWindowId(windowSet, m_state.activeWindowId).empty(); - } - - Domain::WindowTopologyState m_state = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Application diff --git a/new_editor/app/Windowing/Application/WindowTopologyState.h b/new_editor/app/Windowing/Application/WindowTopologyState.h deleted file mode 100644 index 8133d8e2..00000000 --- a/new_editor/app/Windowing/Application/WindowTopologyState.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -#include "Windowing/Workspace/UIEditorWindowWorkspaceModel.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowProjectionSnapshot { - WindowId windowId = {}; - WindowType windowType = WindowType::Unknown; - bool primary = false; - std::string utilityWindowType = {}; -}; - -struct WorkspaceStateSnapshot { - WindowId windowId = {}; - ::XCEngine::UI::Editor::UIEditorWorkspaceModel workspace = {}; - ::XCEngine::UI::Editor::UIEditorWorkspaceSession session = {}; - bool valid = false; -}; - -struct WindowTopologyState { - WindowId primaryWindowId = {}; - WindowId activeWindowId = {}; - std::vector orderedWindowIds = {}; - std::vector workspaceWindowIds = {}; - std::vector utilityWindowIds = {}; - std::vector windowProjections = {}; - std::vector workspaceStateSnapshots = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/app/Windowing/Content/EditorWindowContentRuntime.cpp b/new_editor/app/Windowing/Content/EditorWindowContentRuntime.cpp deleted file mode 100644 index 0addb2d1..00000000 --- a/new_editor/app/Windowing/Content/EditorWindowContentRuntime.cpp +++ /dev/null @@ -1,364 +0,0 @@ -#include "Windowing/Content/EditorWindowContentRuntime.h" - -#include "Composition/EditorContext.h" -#include "Composition/EditorShellRuntime.h" -#include -#include "Windowing/Workspace/UIEditorDetachedWindowPolicy.h" - -#include - -#include "Windowing/Content/EditorWindowFrameOrchestrator.h" -#include "Windowing/Utility/EditorUtilityWindowPanel.h" -#include "Windowing/Utility/EditorUtilityWindowFrameWorkflow.h" - -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -using ::XCEngine::UI::UIInputEvent; -using ::XCEngine::UI::UIInputEventType; - -struct EditorWindowContentRuntime::WorkspaceContentState { - UIEditorWorkspaceController workspaceController = {}; - EditorShellRuntime shellRuntime = {}; - EditorWindowFrameOrchestrator frameOrchestrator = {}; -}; - -struct EditorWindowContentRuntime::UtilityContentState { - EditorUtilityWindowSession session = {}; - std::unique_ptr panel = {}; - ::XCEngine::UI::UISize minimumOuterSize = {}; - UIEditorShellInteractionState shellInteractionState = {}; - UIEditorShellInteractionFrame shellFrame = {}; - bool windowFocused = true; -}; - -EditorWindowContentRuntime::EditorWindowContentRuntime(EditorWindowContentSpec contentSpec) - : m_contentState(std::visit( - [](auto&& spec) -> ContentStateStorage { - using SpecType = std::decay_t; - if constexpr (std::is_same_v) { - auto workspaceState = std::make_unique(); - workspaceState->workspaceController = std::move(spec.workspaceController); - return ContentStateStorage( - std::in_place_type>, - std::move(workspaceState)); - } else { - auto utilityState = std::make_unique(); - utilityState->session = std::move(spec.session); - utilityState->panel = std::move(spec.panel); - utilityState->minimumOuterSize = spec.minimumOuterSize; - return ContentStateStorage( - std::in_place_type>, - std::move(utilityState)); - } - }, - std::move(contentSpec))) { -} - -EditorWindowContentRuntime::~EditorWindowContentRuntime() = default; - -bool EditorWindowContentRuntime::IsWorkspaceContent() const { - return std::holds_alternative>(m_contentState); -} - -const UIEditorWorkspaceController& EditorWindowContentRuntime::GetWorkspaceController() const { - const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - assert(workspaceState != nullptr); - return workspaceState->workspaceController; -} - -void EditorWindowContentRuntime::ReplaceWorkspaceController( - UIEditorWorkspaceController workspaceController) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->workspaceController = std::move(workspaceController); - } -} - -void EditorWindowContentRuntime::UpdateUtilityWindowSession( - EditorUtilityWindowSession session) { - if (!session.IsValid()) { - return; - } - - if (UtilityContentState* utilityState = GetUtilityContentState(); - utilityState != nullptr) { - utilityState->session = std::move(session); - if (utilityState->panel != nullptr) { - utilityState->panel->ResetInteractionState(); - } - } -} - -void EditorWindowContentRuntime::SetExternalDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.SetExternalDockHostDropPreview(preview); - } -} - -void EditorWindowContentRuntime::ClearExternalDockHostDropPreview() { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.ClearExternalDockHostDropPreview(); - } -} - -bool EditorWindowContentRuntime::TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const ::XCEngine::UI::UIPoint& point, - ::XCEngine::UI::UIPoint& outHotspot) const { - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return workspaceState->shellRuntime.TryResolveDockTabDragHotspot( - nodeId, - panelId, - point, - outHotspot); - } - - return false; -} - -UIEditorDockHostTabDropTarget EditorWindowContentRuntime::ResolveDockTabDropTarget( - const ::XCEngine::UI::UIPoint& point) const { - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return workspaceState->shellRuntime.ResolveDockTabDropTarget(point); - } - - return {}; -} - -EditorWindowContentPresentationSummary EditorWindowContentRuntime::BuildPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const { - EditorWindowContentPresentationSummary summary = {}; - summary.tabStripTitleText = std::string(fallbackTabTitle); - summary.detachedWindowTitleText = std::string(fallbackWindowTitle); - - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - summary.useDetachedTitleBarTabStrip = - HasUIEditorSingleVisibleRootTab(workspaceState->workspaceController); - summary.tabStripTitleText = ResolveUIEditorDetachedWorkspaceTitle( - workspaceState->workspaceController, - fallbackTabTitle); - summary.detachedWindowTitleText = ResolveUIEditorDetachedWorkspaceTitle( - workspaceState->workspaceController, - fallbackWindowTitle); - } - - return summary; -} - -void EditorWindowContentRuntime::Initialize( - const EditorWindowContentInitializationContext& context) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.Initialize( - context.repoRoot, - context.textureHost, - context.textMeasurer); - workspaceState->shellRuntime.AttachViewportWindowRenderer(context.viewportRenderer); - } -} - -void EditorWindowContentRuntime::Shutdown() { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.Shutdown(); - return; - } - - if (UtilityContentState* utilityState = GetUtilityContentState(); - utilityState != nullptr) { - if (utilityState->panel != nullptr) { - utilityState->panel->ResetInteractionState(); - } - utilityState->shellInteractionState = {}; - utilityState->shellFrame = {}; - utilityState->windowFocused = false; - } -} - -void EditorWindowContentRuntime::ResetInteractionState() { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.ResetInteractionState(); - return; - } - - if (UtilityContentState* utilityState = GetUtilityContentState(); - utilityState != nullptr && utilityState->panel != nullptr) { - utilityState->panel->ResetInteractionState(); - } -} - -void EditorWindowContentRuntime::SetViewportSurfacePresentationEnabled(bool enabled) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.SetViewportSurfacePresentationEnabled(enabled); - } -} - -EditorWindowContentUpdateResult EditorWindowContentRuntime::UpdateAndAppend( - const EditorWindowContentFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return workspaceState->frameOrchestrator.UpdateAndAppend( - context.editorContext, - context.sourceWindowId, - context.utilityWindowResultState, - context.utilityRequestSink, - context.workspaceTransferQueue, - workspaceState->workspaceController, - workspaceState->shellRuntime, - context.bounds, - context.inputEvents, - context.captureStatusText, - context.primary, - context.globalTabDragActive, - context.useDetachedTitleBarTabStrip, - context.cursorScreenX, - context.cursorScreenY, - context.hasCursorScreenPoint, - drawData); - } - - UtilityContentState* utilityState = GetUtilityContentState(); - assert(utilityState != nullptr); - - bool focusGained = false; - bool focusLost = false; - for (const UIInputEvent& event : context.inputEvents) { - if (event.type == UIInputEventType::FocusGained) { - utilityState->windowFocused = true; - focusGained = true; - } else if (event.type == UIInputEventType::FocusLost) { - utilityState->windowFocused = false; - focusLost = true; - } - } - - utilityState->shellInteractionState.focused = utilityState->windowFocused; - utilityState->shellFrame.focused = utilityState->windowFocused; - - if (utilityState->panel == nullptr) { - return {}; - } - - return context.utilityWindowFrameWorkflow.UpdateAndAppend( - *utilityState->panel, - EditorUtilityWindowFrameContext{ - .resultState = context.utilityWindowResultState, - .hostContext = EditorUtilityWindowHostContext{ - .mounted = true, - .bounds = context.bounds, - .allowInteraction = true, - .focused = utilityState->windowFocused, - .focusGained = focusGained, - .focusLost = focusLost, - }, - .session = utilityState->session, - .inputEvents = context.inputEvents, - }, - drawData); -} - -void EditorWindowContentRuntime::RenderRequestedViewports( - const ::XCEngine::Rendering::RenderContext& renderContext) { - if (WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - workspaceState->shellRuntime.RenderRequestedViewports(renderContext); - } -} - -const UIEditorShellInteractionFrame& EditorWindowContentRuntime::GetShellFrame() const { - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return workspaceState->shellRuntime.GetShellFrame(); - } - - const UtilityContentState* utilityState = GetUtilityContentState(); - assert(utilityState != nullptr); - return utilityState->shellFrame; -} - -const UIEditorShellInteractionState& EditorWindowContentRuntime::GetShellInteractionState() const { - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return workspaceState->shellRuntime.GetShellInteractionState(); - } - - const UtilityContentState* utilityState = GetUtilityContentState(); - assert(utilityState != nullptr); - return utilityState->shellInteractionState; -} - -::XCEngine::UI::UISize EditorWindowContentRuntime::ResolveMinimumOuterSize() const { - if (const WorkspaceContentState* workspaceState = GetWorkspaceContentState(); - workspaceState != nullptr) { - return ResolveUIEditorDetachedWorkspaceMinimumOuterSize( - workspaceState->workspaceController); - } - - const UtilityContentState* utilityState = GetUtilityContentState(); - assert(utilityState != nullptr); - return utilityState->minimumOuterSize; -} - -EditorWindowContentRuntime::WorkspaceContentState* -EditorWindowContentRuntime::GetWorkspaceContentState() { - const auto state = std::get_if>(&m_contentState); - return state != nullptr ? state->get() : nullptr; -} - -const EditorWindowContentRuntime::WorkspaceContentState* -EditorWindowContentRuntime::GetWorkspaceContentState() const { - const auto state = std::get_if>(&m_contentState); - return state != nullptr ? state->get() : nullptr; -} - -EditorWindowContentRuntime::UtilityContentState* -EditorWindowContentRuntime::GetUtilityContentState() { - const auto state = std::get_if>(&m_contentState); - return state != nullptr ? state->get() : nullptr; -} - -const EditorWindowContentRuntime::UtilityContentState* -EditorWindowContentRuntime::GetUtilityContentState() const { - const auto state = std::get_if>(&m_contentState); - return state != nullptr ? state->get() : nullptr; -} - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - - - - - - - - - - - - - diff --git a/new_editor/app/Windowing/Content/EditorWindowContentRuntime.h b/new_editor/app/Windowing/Content/EditorWindowContentRuntime.h deleted file mode 100644 index 497bc965..00000000 --- a/new_editor/app/Windowing/Content/EditorWindowContentRuntime.h +++ /dev/null @@ -1,164 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowContentUpdateResult.h" -#include "Windowing/Application/EditorWindowContentSpec.h" -#include "Windowing/Utility/EditorUtilityWindowPanel.h" -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace XCEngine::Rendering { - -struct RenderContext; - -} // namespace XCEngine::Rendering - -namespace XCEngine::UI { - -class UIDrawData; - -struct UIInputEvent; -struct UIPoint; -struct UIRect; -struct UISize; - -} // namespace XCEngine::UI - -namespace XCEngine::UI::Editor { - -struct UIEditorShellInteractionFrame; -struct UIEditorShellInteractionState; - -namespace Widgets { -struct UIEditorDockHostDropPreviewState; -} - -} // namespace XCEngine::UI::Editor - -namespace XCEngine::UI::Editor::Rendering::Host { - -class UiTextureHost; -class ViewportRenderHost; - -} // namespace XCEngine::UI::Editor::Rendering::Host - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -struct EditorUtilityWindowResultState; -class EditorUtilityWindowRequestSink; -class EditorUtilityWindowFrameWorkflow; -class WindowWorkspaceTransferQueue; - -struct EditorWindowContentInitializationContext { - const std::filesystem::path& repoRoot; - EditorContext& editorContext; - Rendering::Host::UiTextureHost& textureHost; - UIEditorTextMeasurer& textMeasurer; - Rendering::Host::ViewportRenderHost& viewportRenderer; -}; - -struct EditorWindowContentFrameContext { - EditorContext& editorContext; - EditorUtilityWindowResultState& utilityWindowResultState; - EditorUtilityWindowFrameWorkflow& utilityWindowFrameWorkflow; - EditorUtilityWindowRequestSink& utilityRequestSink; - WindowWorkspaceTransferQueue& workspaceTransferQueue; - std::string_view sourceWindowId; - const ::XCEngine::UI::UIRect& bounds; - const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents; - std::string_view captureStatusText; - bool primary = false; - bool globalTabDragActive = false; - bool useDetachedTitleBarTabStrip = false; - std::int32_t cursorScreenX = 0; - std::int32_t cursorScreenY = 0; - bool hasCursorScreenPoint = false; -}; - -struct EditorWindowContentPresentationSummary { - bool useDetachedTitleBarTabStrip = false; - std::string tabStripTitleText = {}; - std::string detachedWindowTitleText = {}; -}; -class EditorWindowContentRuntime final { -public: - explicit EditorWindowContentRuntime(EditorWindowContentSpec contentSpec); - ~EditorWindowContentRuntime(); - - EditorWindowContentRuntime(const EditorWindowContentRuntime&) = delete; - EditorWindowContentRuntime& operator=(const EditorWindowContentRuntime&) = delete; - EditorWindowContentRuntime(EditorWindowContentRuntime&&) = delete; - EditorWindowContentRuntime& operator=(EditorWindowContentRuntime&&) = delete; - - bool IsWorkspaceContent() const; - - const UIEditorWorkspaceController& GetWorkspaceController() const; - void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController); - void UpdateUtilityWindowSession(EditorUtilityWindowSession session); - - void SetExternalDockHostDropPreview( - const Widgets::UIEditorDockHostDropPreviewState& preview); - void ClearExternalDockHostDropPreview(); - bool TryResolveDockTabDragHotspot( - std::string_view nodeId, - std::string_view panelId, - const ::XCEngine::UI::UIPoint& point, - ::XCEngine::UI::UIPoint& outHotspot) const; - UIEditorDockHostTabDropTarget ResolveDockTabDropTarget( - const ::XCEngine::UI::UIPoint& point) const; - - EditorWindowContentPresentationSummary BuildPresentationSummary( - std::string_view fallbackTabTitle, - std::string_view fallbackWindowTitle) const; - - void Initialize(const EditorWindowContentInitializationContext& context); - void Shutdown(); - void ResetInteractionState(); - void SetViewportSurfacePresentationEnabled(bool enabled); - - EditorWindowContentUpdateResult UpdateAndAppend( - const EditorWindowContentFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData); - void RenderRequestedViewports(const ::XCEngine::Rendering::RenderContext& renderContext); - - const UIEditorShellInteractionFrame& GetShellFrame() const; - const UIEditorShellInteractionState& GetShellInteractionState() const; - ::XCEngine::UI::UISize ResolveMinimumOuterSize() const; - -private: - struct WorkspaceContentState; - struct UtilityContentState; - - WorkspaceContentState* GetWorkspaceContentState(); - const WorkspaceContentState* GetWorkspaceContentState() const; - UtilityContentState* GetUtilityContentState(); - const UtilityContentState* GetUtilityContentState() const; - - using ContentStateStorage = std::variant< - std::unique_ptr, - std::unique_ptr>; - - ContentStateStorage m_contentState; -}; - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - diff --git a/new_editor/app/Windowing/Host/EditorWindowDirectory.h b/new_editor/app/Windowing/Host/EditorWindowDirectory.h deleted file mode 100644 index e57f8a52..00000000 --- a/new_editor/app/Windowing/Host/EditorWindowDirectory.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorWindowSnapshot { - std::string windowId = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; - bool primary = false; - bool hasNativeWindow = false; - bool running = false; - bool closing = false; - bool destroyed = false; -}; - -class EditorWindowDirectory { -public: - virtual ~EditorWindowDirectory() = default; - - virtual bool TryGetWindowSnapshot( - std::string_view windowId, - EditorWindowSnapshot& outSnapshot) const = 0; - virtual void ForEachWindowSnapshot( - const std::function& visitor) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Host/EditorWindowHostAdapters.h b/new_editor/app/Windowing/Host/EditorWindowHostAdapters.h deleted file mode 100644 index 9d6fa83d..00000000 --- a/new_editor/app/Windowing/Host/EditorWindowHostAdapters.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "Windowing/Host/EditorWindowDirectory.h" -#include "Windowing/Host/EditorWindowTraceSink.h" -#include "Windowing/Host/EditorWindowUtilitySessionHost.h" -#include "Windowing/Ports/EditorWindowHostCreationPort.h" -#include "Windowing/Ports/EditorWindowNativeQueryPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceContentPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceHostPort.h" - -namespace XCEngine::UI::Editor::App { - -class EditorWindowCommandSink; - -struct EditorWindowHostAdapters { - EditorWindowDirectory& windowDirectory; - EditorWindowUtilitySessionHost& utilitySessionHost; - EditorWindowTraceSink& traceSink; - EditorWindowWorkspaceContentPort& workspaceContentPort; - EditorWindowWorkspaceHostPort& workspaceHostPort; - EditorWindowHostCreationPort& hostCreationPort; - EditorWindowNativeQueryPort& nativeQueryPort; - EditorWindowCommandSink& windowCommandSink; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Host/EditorWindowTraceSink.h b/new_editor/app/Windowing/Host/EditorWindowTraceSink.h deleted file mode 100644 index 20764cdc..00000000 --- a/new_editor/app/Windowing/Host/EditorWindowTraceSink.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowTraceSink { -public: - virtual ~EditorWindowTraceSink() = default; - - virtual void LogRuntimeTrace(std::string_view channel, std::string_view message) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Host/EditorWindowUtilitySessionHost.h b/new_editor/app/Windowing/Host/EditorWindowUtilitySessionHost.h deleted file mode 100644 index a0c0c318..00000000 --- a/new_editor/app/Windowing/Host/EditorWindowUtilitySessionHost.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowUtilitySessionHost { -public: - virtual ~EditorWindowUtilitySessionHost() = default; - - virtual bool UpdateUtilityWindowSession( - std::string_view windowId, - EditorUtilityWindowSession session) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Ports/EditorWindowHostCreationPort.h b/new_editor/app/Windowing/Ports/EditorWindowHostCreationPort.h deleted file mode 100644 index bde0e546..00000000 --- a/new_editor/app/Windowing/Ports/EditorWindowHostCreationPort.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowContentSpec.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowPanel; - -struct EditorWindowHostCreateRequest { - std::string windowId = {}; - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Unknown; - std::wstring title = {}; - int initialX = 0; - int initialY = 0; - int initialWidth = 1540; - int initialHeight = 940; - bool useDefaultInitialPosition = true; - bool primary = false; - bool autoCaptureOnStartup = false; -}; - -struct EditorWindowHostCreateResult { - bool success = false; - std::string windowId = {}; -}; - -class EditorWindowHostCreationPort { -public: - virtual ~EditorWindowHostCreationPort() = default; - - virtual EditorWindowHostCreateResult CreateWorkspaceWindow( - EditorWorkspaceWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) = 0; - virtual EditorWindowHostCreateResult CreateUtilityWindow( - EditorUtilityWindowContentSpec contentSpec, - const EditorWindowHostCreateRequest& request) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Ports/EditorWindowLifecyclePort.h b/new_editor/app/Windowing/Ports/EditorWindowLifecyclePort.h deleted file mode 100644 index 5af6d2e6..00000000 --- a/new_editor/app/Windowing/Ports/EditorWindowLifecyclePort.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowLifecyclePort { -public: - virtual ~EditorWindowLifecyclePort() = default; - - virtual void PostCloseRequest(std::string_view windowId) = 0; - virtual void AbortUnregisteredWindow(std::string_view windowId) = 0; - virtual void ReapDestroyedWindows() = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Ports/EditorWindowNativeQueryPort.h b/new_editor/app/Windowing/Ports/EditorWindowNativeQueryPort.h deleted file mode 100644 index a8b44791..00000000 --- a/new_editor/app/Windowing/Ports/EditorWindowNativeQueryPort.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowGeometry.h" - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowNativeQueryPort { -public: - virtual ~EditorWindowNativeQueryPort() = default; - - virtual bool TryGetCursorScreenPoint(EditorWindowScreenPoint& outPoint) const = 0; - virtual bool TryGetWindowRect(std::string_view windowId, EditorWindowRect& outRect) const = 0; - virtual bool IsWindowUnderScreenPoint( - std::string_view windowId, - EditorWindowScreenPoint screenPoint) const = 0; - virtual bool TryGetNearestMonitorWorkArea( - EditorWindowScreenPoint screenPoint, - EditorWindowRect& outRect) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Ports/EditorWindowWorkspaceContentPort.h b/new_editor/app/Windowing/Ports/EditorWindowWorkspaceContentPort.h deleted file mode 100644 index 4960f6af..00000000 --- a/new_editor/app/Windowing/Ports/EditorWindowWorkspaceContentPort.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowWorkspaceContentPort { -public: - virtual ~EditorWindowWorkspaceContentPort() = default; - - virtual bool TryGetWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController& outWorkspaceController) const = 0; - virtual bool TryApplyWorkspaceController( - std::string_view windowId, - UIEditorWorkspaceController workspaceController, - bool primary) = 0; - virtual bool ResetWorkspaceInteractionState(std::string_view windowId) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Ports/EditorWindowWorkspaceHostPort.h b/new_editor/app/Windowing/Ports/EditorWindowWorkspaceHostPort.h deleted file mode 100644 index 8208f9c1..00000000 --- a/new_editor/app/Windowing/Ports/EditorWindowWorkspaceHostPort.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowGeometry.h" - -#include -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorWindowWorkspaceHostPort { -public: - virtual ~EditorWindowWorkspaceHostPort() = default; - - virtual bool TryResolveDockTabDragHotspot( - std::string_view windowId, - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outDragHotspot) const = 0; - virtual bool TryResolveDockTabDropTarget( - std::string_view windowId, - EditorWindowScreenPoint screenPoint, - UIEditorDockHostTabDropTarget& outTarget) const = 0; - virtual bool SetDockHostDropPreview( - std::string_view windowId, - const Widgets::UIEditorDockHostDropPreviewState& preview) = 0; - virtual bool ClearDockHostDropPreview(std::string_view windowId) = 0; - virtual bool AcquireGlobalTabDragPointerCapture(std::string_view windowId) = 0; - virtual bool ReleaseGlobalTabDragPointerCapture(std::string_view windowId) = 0; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.cpp b/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.cpp deleted file mode 100644 index b7f70443..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include "Windowing/Utility/EditorUtilityWindowCatalog.h" - -namespace XCEngine::UI::Editor::App { - -namespace { - -using ::XCEngine::UI::UISize; - -constexpr EditorUtilityWindowDescriptor kColorPickerUtilityWindowDescriptor = { - .type = EditorUtilityWindowType::ColorPicker, - .windowId = "utility.color-picker", - .title = L"Color Picker", - .preferredOuterSize = UISize(352.0f, 500.0f), - .minimumOuterSize = UISize(320.0f, 460.0f), -}; - -constexpr EditorUtilityWindowDescriptor kAddComponentUtilityWindowDescriptor = { - .type = EditorUtilityWindowType::AddComponent, - .windowId = "utility.add-component", - .title = L"Add Component", - .preferredOuterSize = UISize(352.0f, 500.0f), - .minimumOuterSize = UISize(320.0f, 460.0f), -}; - -} // namespace - -const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( - EditorUtilityWindowType type) { - switch (type) { - case EditorUtilityWindowType::ColorPicker: - return &kColorPickerUtilityWindowDescriptor; - case EditorUtilityWindowType::AddComponent: - return &kAddComponentUtilityWindowDescriptor; - case EditorUtilityWindowType::None: - default: - return nullptr; - } -} - -std::string_view ResolveEditorUtilityWindowTypeToken(EditorUtilityWindowType type) { - switch (type) { - case EditorUtilityWindowType::ColorPicker: - return "color-picker"; - case EditorUtilityWindowType::AddComponent: - return "add-component"; - case EditorUtilityWindowType::None: - default: - return {}; - } -} - -bool TryParseEditorUtilityWindowTypeToken( - std::string_view token, - EditorUtilityWindowType& outType) { - if (token == "color-picker") { - outType = EditorUtilityWindowType::ColorPicker; - return true; - } - - if (token == "add-component") { - outType = EditorUtilityWindowType::AddComponent; - return true; - } - - outType = EditorUtilityWindowType::None; - return false; -} - -bool TryResolveEditorUtilityWindowTypeFromWindowId( - std::string_view windowId, - EditorUtilityWindowType& outType) { - if (windowId == kColorPickerUtilityWindowDescriptor.windowId) { - outType = EditorUtilityWindowType::ColorPicker; - return true; - } - - if (windowId == kAddComponentUtilityWindowDescriptor.windowId) { - outType = EditorUtilityWindowType::AddComponent; - return true; - } - - outType = EditorUtilityWindowType::None; - return false; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.h deleted file mode 100644 index 97906af8..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowCatalog.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowType.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorUtilityWindowDescriptor { - EditorUtilityWindowType type = EditorUtilityWindowType::None; - std::string_view windowId = {}; - const wchar_t* title = L""; - ::XCEngine::UI::UISize preferredOuterSize = {}; - ::XCEngine::UI::UISize minimumOuterSize = {}; -}; - -const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor( - EditorUtilityWindowType type); -std::string_view ResolveEditorUtilityWindowTypeToken(EditorUtilityWindowType type); -bool TryParseEditorUtilityWindowTypeToken( - std::string_view token, - EditorUtilityWindowType& outType); -bool TryResolveEditorUtilityWindowTypeFromWindowId( - std::string_view windowId, - EditorUtilityWindowType& outType); - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowFeatureCommands.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowFeatureCommands.h deleted file mode 100644 index 4399b7c4..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowFeatureCommands.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include -#include - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowAddComponentQueryPort { -public: - virtual ~EditorUtilityWindowAddComponentQueryPort() = default; - - virtual const ::XCEngine::Components::GameObject* FindTargetGameObject( - std::string_view targetItemId) const = 0; -}; - -class EditorUtilityWindowAddComponentCommandPort { -public: - virtual ~EditorUtilityWindowAddComponentCommandPort() = default; - - virtual bool TryAddComponent( - std::string_view targetItemId, - std::string_view componentTypeName) = 0; -}; - -class EditorUtilityWindowColorPickerCommandPort { -public: - virtual ~EditorUtilityWindowColorPickerCommandPort() = default; - - virtual bool TryApplyColorPickerValue( - std::string_view targetSubjectKey, - std::string_view targetFieldId, - const ::XCEngine::UI::UIColor& color) = 0; -}; -} // namespace XCEngine::UI::Editor::App - - - diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.cpp b/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.cpp deleted file mode 100644 index 9cbdd02a..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include "Windowing/Utility/EditorUtilityWindowFrameWorkflow.h" - -#include "Scene/EditorSceneRuntime.h" -#include "Windowing/Utility/EditorUtilityWindowResultState.h" - -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -EditorWindowContentUpdateResult ApplyUtilityPanelOutput( - EditorUtilityWindowResultServices services, - const EditorUtilityWindowPanelOutput& panelOutput) { - EditorWindowContentUpdateResult updateResult = {}; - if (panelOutput.closeRequested || panelOutput.cancelRequested) { - updateResult.commands.push_back(Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::CloseWindow, - }); - } - - if (!panelOutput.result.has_value()) { - return updateResult; - } - - switch (panelOutput.result->type) { - case EditorUtilityWindowPanelResult::Type::AddComponent: - if (services.addComponentCommands != nullptr && - services.addComponentCommands->TryAddComponent( - panelOutput.result->targetItemId, - panelOutput.result->componentTypeName)) { - updateResult.contentOutput.statusText = "Add component completed."; - } else { - updateResult.contentOutput.statusText = "Add component failed."; - } - break; - case EditorUtilityWindowPanelResult::Type::ColorPickerValueChanged: - if (services.colorPickerCommands != nullptr && - services.colorPickerCommands->TryApplyColorPickerValue( - panelOutput.result->targetSubjectKey, - panelOutput.result->targetFieldId, - panelOutput.result->color)) { - updateResult.contentOutput.statusText = "Color updated."; - } else if (services.resultState != nullptr) { - SetEditorUtilityWindowColorPickerResult( - *services.resultState, - panelOutput.result->targetSubjectKey, - panelOutput.result->targetFieldId, - panelOutput.result->color, - panelOutput.result->showAlpha); - } - break; - } - - return updateResult; -} - -} // namespace - -EditorUtilityWindowSceneFeatureWorkflow::EditorUtilityWindowSceneFeatureWorkflow( - EditorSceneRuntime& sceneRuntime) - : m_sceneRuntime(sceneRuntime) { -} - -const ::XCEngine::Components::GameObject* -EditorUtilityWindowSceneFeatureWorkflow::FindTargetGameObject( - std::string_view targetItemId) const { - return m_sceneRuntime.FindGameObject(targetItemId); -} - -bool EditorUtilityWindowSceneFeatureWorkflow::TryAddComponent( - std::string_view targetItemId, - std::string_view componentTypeName) { - return m_sceneRuntime.AddComponentToGameObject(targetItemId, componentTypeName); -} - -EditorUtilityWindowFrameWorkflow::EditorUtilityWindowFrameWorkflow( - EditorUtilityWindowSceneFeatureWorkflow& sceneFeatureWorkflow) - : m_sceneFeatureWorkflow(sceneFeatureWorkflow) { -} - - -EditorWindowContentUpdateResult EditorUtilityWindowFrameWorkflow::UpdateAndAppend( - EditorUtilityWindowPanel& panel, - const EditorUtilityWindowFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData) const { - const EditorUtilityWindowPanelOutput panelOutput = panel.Update( - EditorUtilityWindowPanelServices{ - .addComponentQueries = &m_sceneFeatureWorkflow, - }, - context.hostContext, - context.session, - context.inputEvents); - - ::XCEngine::UI::UIDrawList& drawList = - drawData.EmplaceDrawList(std::string(panel.GetDrawListId())); - panel.Append(drawList); - - return ApplyUtilityPanelOutput( - EditorUtilityWindowResultServices{ - .addComponentCommands = &m_sceneFeatureWorkflow, - .resultState = &context.resultState, - .colorPickerCommands = context.colorPickerCommands, - }, - panelOutput); -} - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.h deleted file mode 100644 index 17e233ca..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowFrameWorkflow.h +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowContentUpdateResult.h" -#include "Windowing/Utility/EditorUtilityWindowFeatureCommands.h" -#include "Windowing/Utility/EditorUtilityWindowPanel.h" - -namespace XCEngine::UI { -class UIDrawData; -struct UIInputEvent; -} // namespace XCEngine::UI - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowColorPickerCommandPort; -class EditorSceneRuntime; -struct EditorUtilityWindowResultState; - -class EditorUtilityWindowSceneFeatureWorkflow final - : public EditorUtilityWindowAddComponentQueryPort, - public EditorUtilityWindowAddComponentCommandPort { -public: - explicit EditorUtilityWindowSceneFeatureWorkflow(EditorSceneRuntime& sceneRuntime); - - const ::XCEngine::Components::GameObject* FindTargetGameObject( - std::string_view targetItemId) const override; - bool TryAddComponent( - std::string_view targetItemId, - std::string_view componentTypeName) override; - -private: - EditorSceneRuntime& m_sceneRuntime; -}; - -struct EditorUtilityWindowFrameContext { - EditorUtilityWindowResultState& resultState; - EditorUtilityWindowColorPickerCommandPort* colorPickerCommands = nullptr; - EditorUtilityWindowHostContext hostContext = {}; - const EditorUtilityWindowSession& session; - const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents; -}; - -class EditorUtilityWindowFrameWorkflow final { -public: - explicit EditorUtilityWindowFrameWorkflow( - EditorUtilityWindowSceneFeatureWorkflow& sceneFeatureWorkflow); - EditorWindowContentUpdateResult UpdateAndAppend( - EditorUtilityWindowPanel& panel, - const EditorUtilityWindowFrameContext& context, - ::XCEngine::UI::UIDrawData& drawData) const; - -private: - EditorUtilityWindowSceneFeatureWorkflow& m_sceneFeatureWorkflow; -}; - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowPanel.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowPanel.h deleted file mode 100644 index 30c2ab13..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowPanel.h +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -#include - -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowAddComponentCommandPort; -class EditorUtilityWindowAddComponentQueryPort; -class EditorUtilityWindowColorPickerCommandPort; -struct EditorUtilityWindowResultState; - -struct EditorUtilityWindowHostContext { - bool mounted = false; - ::XCEngine::UI::UIRect bounds = {}; - bool allowInteraction = false; - bool focused = false; - bool focusGained = false; - bool focusLost = false; -}; - -struct EditorUtilityWindowPanelServices { - EditorUtilityWindowAddComponentQueryPort* addComponentQueries = nullptr; -}; - -struct EditorUtilityWindowResultServices { - EditorUtilityWindowAddComponentCommandPort* addComponentCommands = nullptr; - EditorUtilityWindowResultState* resultState = nullptr; - EditorUtilityWindowColorPickerCommandPort* colorPickerCommands = nullptr; -}; -struct EditorUtilityWindowPanelResult { - enum class Type : std::uint8_t { - AddComponent, - ColorPickerValueChanged, - }; - - Type type = Type::AddComponent; - std::string targetItemId = {}; - std::string componentTypeName = {}; - std::string targetSubjectKey = {}; - std::string targetFieldId = {}; - ::XCEngine::UI::UIColor color = {}; - bool showAlpha = true; -}; - -struct EditorUtilityWindowPanelOutput { - bool closeRequested = false; - bool cancelRequested = false; - std::optional result = {}; -}; -class EditorUtilityWindowPanel { -public: - virtual ~EditorUtilityWindowPanel() = default; - - virtual std::string_view GetDrawListId() const = 0; - virtual void ResetInteractionState() = 0; - virtual EditorUtilityWindowPanelOutput Update( - EditorUtilityWindowPanelServices services, - const EditorUtilityWindowHostContext& hostContext, - const EditorUtilityWindowSession& session, - const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) = 0; - virtual void Append(::XCEngine::UI::UIDrawList& drawList) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App - - - - - - - - - - diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowPanelProvider.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowPanelProvider.h deleted file mode 100644 index 620768d0..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowPanelProvider.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowType.h" - -#include - -namespace XCEngine::UI::Editor::App { - -class EditorUtilityWindowPanel; - -class EditorUtilityWindowPanelProvider { -public: - virtual ~EditorUtilityWindowPanelProvider() = default; - - virtual std::unique_ptr CreatePanel( - EditorUtilityWindowType type) const = 0; -}; - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.cpp b/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.cpp deleted file mode 100644 index b6521024..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "Windowing/Utility/EditorUtilityWindowRequestSink.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -void EditorUtilityWindowRequestSink::ConfigureFrameSource( - std::string_view sourceWindowId, - std::int32_t screenX, - std::int32_t screenY, - bool hasScreenPoint) { - m_sourceWindowId = std::string(sourceWindowId); - m_screenX = screenX; - m_screenY = screenY; - m_hasScreenPoint = hasScreenPoint; -} - -void EditorUtilityWindowRequestSink::Request(EditorUtilityWindowSession session) { - if (!session.IsValid() || m_sourceWindowId.empty()) { - return; - } - - session.sourceWindowId = m_sourceWindowId; - - EditorUtilityWindowOpenRequest request = {}; - request.sourceWindowId = m_sourceWindowId; - request.session = std::move(session); - request.screenX = m_screenX; - request.screenY = m_screenY; - request.hasScreenPoint = m_hasScreenPoint; - - const auto it = std::find_if( - pendingRequests.begin(), - pendingRequests.end(), - [&request](const EditorUtilityWindowOpenRequest& current) { - return current.sourceWindowId == request.sourceWindowId && - current.session.type == request.session.type; - }); - if (it == pendingRequests.end()) { - pendingRequests.push_back(std::move(request)); - } else { - *it = std::move(request); - } -} - -std::vector -EditorUtilityWindowRequestSink::ConsumePendingRequests() { - std::vector requests = std::move(pendingRequests); - pendingRequests = {}; - return requests; -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.h deleted file mode 100644 index 3affd86c..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowRequestSink.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowSession.h" -#include "Windowing/Utility/EditorUtilityWindowType.h" - -#include -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorUtilityWindowOpenRequest { - std::string sourceWindowId = {}; - EditorUtilityWindowSession session = {}; - std::int32_t screenX = 0; - std::int32_t screenY = 0; - bool hasScreenPoint = false; - - bool IsValid() const { - return !sourceWindowId.empty() && session.IsValid(); - } -}; - -class EditorUtilityWindowRequestSink final { -public: - void ConfigureFrameSource( - std::string_view sourceWindowId, - std::int32_t screenX, - std::int32_t screenY, - bool hasScreenPoint); - void Request(EditorUtilityWindowSession session); - std::vector ConsumePendingRequests(); - -private: - std::string m_sourceWindowId = {}; - std::int32_t m_screenX = 0; - std::int32_t m_screenY = 0; - bool m_hasScreenPoint = false; - std::vector pendingRequests = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowResultState.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowResultState.h deleted file mode 100644 index 626012fc..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowResultState.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorUtilityWindowColorPickerResult { - bool active = false; - bool showAlpha = true; - ::XCEngine::UI::UIColor color = {}; - std::string targetSubjectKey = {}; - std::string targetFieldId = {}; -}; - -struct EditorUtilityWindowResultState { - EditorUtilityWindowColorPickerResult colorPickerResult = {}; -}; - -inline void ResetEditorUtilityWindowResultState(EditorUtilityWindowResultState& state) { - state = {}; -} - -inline void SetEditorUtilityWindowColorPickerResult( - EditorUtilityWindowResultState& state, - std::string_view subjectKey, - std::string_view fieldId, - const ::XCEngine::UI::UIColor& color, - bool showAlpha) { - state.colorPickerResult.active = true; - state.colorPickerResult.showAlpha = showAlpha; - state.colorPickerResult.color = color; - state.colorPickerResult.targetSubjectKey = std::string(subjectKey); - state.colorPickerResult.targetFieldId = std::string(fieldId); -} - -inline void ClearEditorUtilityWindowColorPickerResult( - EditorUtilityWindowResultState& state) { - state.colorPickerResult = {}; -} - -inline bool IsEditorUtilityWindowColorPickerResultTarget( - const EditorUtilityWindowResultState& state, - std::string_view subjectKey, - std::string_view fieldId) { - return state.colorPickerResult.active && - state.colorPickerResult.targetSubjectKey == subjectKey && - state.colorPickerResult.targetFieldId == fieldId; -} - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.cpp b/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.cpp deleted file mode 100644 index 87b0f777..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -namespace XCEngine::UI::Editor::App { - -const EditorUtilityWindowColorPickerPayload* TryGetColorPickerPayload( - const EditorUtilityWindowSession& session) { - if (session.type != EditorUtilityWindowType::ColorPicker) { - return nullptr; - } - return std::get_if(&session.payload); -} - -const EditorUtilityWindowAddComponentPayload* TryGetAddComponentPayload( - const EditorUtilityWindowSession& session) { - if (session.type != EditorUtilityWindowType::AddComponent) { - return nullptr; - } - return std::get_if(&session.payload); -} - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.h b/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.h deleted file mode 100644 index c88d3260..00000000 --- a/new_editor/app/Windowing/Utility/EditorUtilityWindowSession.h +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowType.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct EditorUtilityWindowColorPickerPayload { - std::string targetSubjectKey = {}; - std::string targetFieldId = {}; - ::XCEngine::UI::UIColor initialColor = {}; - bool showAlpha = true; - - bool IsValid() const { - return !targetSubjectKey.empty() && !targetFieldId.empty(); - } -}; - -struct EditorUtilityWindowAddComponentPayload { - std::string targetItemId = {}; - std::string targetDisplayName = {}; - - bool IsValid() const { - return !targetItemId.empty(); - } -}; - -using EditorUtilityWindowPayload = std::variant< - std::monostate, - EditorUtilityWindowColorPickerPayload, - EditorUtilityWindowAddComponentPayload>; - -struct EditorUtilityWindowSession { - EditorUtilityWindowType type = EditorUtilityWindowType::None; - std::string sourceWindowId = {}; - EditorUtilityWindowPayload payload = {}; - - bool IsValid() const { - switch (type) { - case EditorUtilityWindowType::ColorPicker: { - const auto* colorPicker = std::get_if(&payload); - return colorPicker != nullptr && colorPicker->IsValid(); - } - case EditorUtilityWindowType::AddComponent: { - const auto* addComponent = std::get_if(&payload); - return addComponent != nullptr && addComponent->IsValid(); - } - case EditorUtilityWindowType::None: - default: - return false; - } - } -}; - -const EditorUtilityWindowColorPickerPayload* TryGetColorPickerPayload( - const EditorUtilityWindowSession& session); -const EditorUtilityWindowAddComponentPayload* TryGetAddComponentPayload( - const EditorUtilityWindowSession& session); - -} // namespace XCEngine::UI::Editor::App \ No newline at end of file diff --git a/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.cpp b/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.cpp deleted file mode 100644 index 3a5b57a5..00000000 --- a/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.cpp +++ /dev/null @@ -1,285 +0,0 @@ -#include "Windowing/Utility/EditorWindowUtilityRuntime.h" - -#include "Windowing/Utility/EditorUtilityWindowCatalog.h" -#include "Windowing/Utility/EditorUtilityWindowPanelProvider.h" -#include "Windowing/Application/EditorWindowGeometry.h" -#include "Windowing/Application/WindowTopologyService.h" -#include "Windowing/Application/EditorWindowContentSpec.h" -#include "Windowing/Host/EditorWindowDirectory.h" -#include "Windowing/Host/EditorWindowTraceSink.h" -#include "Windowing/Host/EditorWindowUtilitySessionHost.h" -#include "Windowing/Ports/EditorWindowLifecyclePort.h" -#include "Windowing/Ports/EditorWindowHostCreationPort.h" -#include "Windowing/Ports/EditorWindowNativeQueryPort.h" -#include "Windowing/Application/EditorWindowCommandSink.h" - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -bool IsLiveWindow(const EditorWindowSnapshot& snapshot) { - return snapshot.hasNativeWindow && snapshot.running && !snapshot.destroyed; -} - -EditorWindowScreenPoint BuildScreenPoint(const WindowUtilityRequest& request) { - return EditorWindowScreenPoint{request.screenX, request.screenY}; -} - -int ResolveOuterDimension(float value, int fallback) { - return value > 0.0f - ? static_cast(std::lround(value)) - : fallback; -} - -std::array BuildRestoreAndFocusCommands() { - return { - Domain::WindowCommand{.type = Domain::WindowCommand::Type::ShowWindow}, - Domain::WindowCommand{.type = Domain::WindowCommand::Type::FocusWindow}, - }; -} - - -Domain::WindowProjectionSnapshot BuildUtilityWindowProjection( - std::string_view windowId, - const EditorUtilityWindowDescriptor& descriptor) { - return Domain::WindowProjectionSnapshot{ - .windowId = Domain::WindowId(std::string(windowId)), - .windowType = Domain::WindowType::Utility, - .primary = false, - .utilityWindowType = std::string(ResolveEditorUtilityWindowTypeToken(descriptor.type)), - }; -} - -} - -EditorWindowUtilityRuntime::EditorWindowUtilityRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowUtilitySessionHost& utilitySessionHost, - EditorWindowTraceSink& traceSink, - EditorWindowHostCreationPort& hostCreationPort, - EditorWindowNativeQueryPort& nativeQueryPort, - EditorWindowLifecyclePort& lifecyclePort, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink, - const EditorUtilityWindowPanelProvider& panelProvider) - : m_windowDirectory(windowDirectory) - , m_utilitySessionHost(utilitySessionHost) - , m_traceSink(traceSink) - , m_hostCreationPort(hostCreationPort) - , m_nativeQueryPort(nativeQueryPort) - , m_topologyService(topologyService) - , m_windowCommandSink(windowCommandSink) - , m_panelProvider(panelProvider) - , m_lifecyclePort(lifecyclePort) {} - -EditorWindowUtilityRuntime::~EditorWindowUtilityRuntime() = default; - -void EditorWindowUtilityRuntime::QueueUtilityWindowRequest( - const WindowUtilityRequest& request) { - if (!request.IsValid()) { - return; - } - - const auto it = std::find_if( - m_pendingUtilityRequests.begin(), - m_pendingUtilityRequests.end(), - [&request](const WindowUtilityRequest& current) { - return current.sourceWindowId == request.sourceWindowId && - current.session.type == request.session.type; - }); - if (it == m_pendingUtilityRequests.end()) { - m_pendingUtilityRequests.push_back(request); - } else { - *it = request; - } -} - -void EditorWindowUtilityRuntime::RemoveWindow(std::string_view windowId) { - if (windowId.empty()) { - return; - } - - std::erase_if( - m_pendingUtilityRequests, - [windowId](const WindowUtilityRequest& current) { - return current.sourceWindowId == windowId; - }); -} - -void EditorWindowUtilityRuntime::FlushPendingUtilityWindowRequests() { - std::vector requests = std::move(m_pendingUtilityRequests); - m_pendingUtilityRequests.clear(); - for (const WindowUtilityRequest& request : requests) { - EditorWindowSnapshot sourceSnapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot( - request.sourceWindowId, - sourceSnapshot) || - !IsLiveWindow(sourceSnapshot)) { - LogRuntimeTrace( - "utility", - "topology utility request dropped: source window is not running"); - continue; - } - - if (!request.IsValid()) { - LogRuntimeTrace( - "utility", - "topology utility request dropped: invalid utility request payload"); - continue; - } - - TryProcessOpenUtilityWindowRequest(request.sourceWindowId, request); - } -} - -bool EditorWindowUtilityRuntime::TryProcessOpenUtilityWindowRequest( - std::string_view sourceWindowId, - const WindowUtilityRequest& request) { - EditorWindowSnapshot sourceSnapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(sourceWindowId, sourceSnapshot) || - !IsLiveWindow(sourceSnapshot)) { - LogRuntimeTrace( - "utility", - "open utility window request rejected: source window is not running"); - return false; - } - - if (request.session.type == EditorUtilityWindowType::None) { - LogRuntimeTrace("utility", "open utility window request rejected: invalid type"); - return false; - } - - const EditorUtilityWindowDescriptor* descriptor = - ResolveEditorUtilityWindowDescriptor(request.session.type); - if (descriptor == nullptr) { - LogRuntimeTrace("utility", "open utility window request rejected: unknown type"); - return false; - } - - EditorWindowSnapshot existingSnapshot = {}; - if (m_windowDirectory.TryGetWindowSnapshot(descriptor->windowId, existingSnapshot) && - existingSnapshot.destroyed) { - m_lifecyclePort.ReapDestroyedWindows(); - } - - existingSnapshot = {}; - if (m_windowDirectory.TryGetWindowSnapshot(descriptor->windowId, existingSnapshot) && - IsLiveWindow(existingSnapshot)) { - m_utilitySessionHost.UpdateUtilityWindowSession( - descriptor->windowId, - request.session); - m_topologyService.UpdateProjection( - BuildUtilityWindowProjection(descriptor->windowId, *descriptor)); - FocusWindow(descriptor->windowId); - LogRuntimeTrace( - "utility", - "reused utility window '" + std::string(descriptor->windowId) + "'"); - return true; - } - - existingSnapshot = {}; - if (m_windowDirectory.TryGetWindowSnapshot(descriptor->windowId, existingSnapshot)) { - LogRuntimeTrace( - "utility", - "open utility window request rejected: existing utility window is not reusable"); - return false; - } - - std::unique_ptr panel = - m_panelProvider.CreatePanel(descriptor->type); - if (panel == nullptr) { - LogRuntimeTrace( - "utility", - "open utility window request rejected: panel factory returned null"); - return false; - } - - EditorWindowHostCreateRequest createRequest = {}; - createRequest.windowId = std::string(descriptor->windowId); - createRequest.windowType = - ::XCEngine::UI::Editor::Windowing::Domain::WindowType::Utility; - createRequest.title = descriptor->title; - createRequest.primary = false; - createRequest.useDefaultInitialPosition = true; - createRequest.initialWidth = ResolveOuterDimension( - descriptor->preferredOuterSize.width, - createRequest.initialWidth); - createRequest.initialHeight = ResolveOuterDimension( - descriptor->preferredOuterSize.height, - createRequest.initialHeight); - if (request.hasScreenPoint) { - const EditorWindowScreenPoint screenPoint = BuildScreenPoint(request); - EditorWindowRect workArea = {}; - const bool hasWorkArea = - m_nativeQueryPort.TryGetNearestMonitorWorkArea(screenPoint, workArea); - const EditorWindowRect rect = BuildEditorFloatingWindowRect( - screenPoint, - createRequest.initialWidth, - createRequest.initialHeight, - 960, - 720, - hasWorkArea ? &workArea : nullptr); - createRequest.initialX = rect.left; - createRequest.initialY = rect.top; - createRequest.initialWidth = rect.Width(); - createRequest.initialHeight = rect.Height(); - createRequest.useDefaultInitialPosition = false; - } - - const EditorWindowHostCreateResult createResult = - m_hostCreationPort.CreateUtilityWindow( - EditorUtilityWindowContentSpec{ - .session = request.session, - .panel = std::move(panel), - .minimumOuterSize = descriptor->minimumOuterSize, - }, - createRequest); - if (!createResult.success) { - LogRuntimeTrace("utility", "failed to create utility window"); - return false; - } - - EditorWindowSnapshot createdSnapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(createResult.windowId, createdSnapshot) || - !IsLiveWindow(createdSnapshot)) { - LogRuntimeTrace("utility", "created utility window is not available in registry"); - return false; - } - - m_topologyService.UpdateProjection(BuildUtilityWindowProjection(createResult.windowId, *descriptor)); - FocusWindow(createResult.windowId); - LogRuntimeTrace( - "utility", - "opened utility window '" + std::string(descriptor->windowId) + "'"); - return true; -} - -void EditorWindowUtilityRuntime::FocusWindow(std::string_view windowId) const { - EditorWindowSnapshot snapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(windowId, snapshot) || - !IsLiveWindow(snapshot)) { - return; - } - - const std::array commands = BuildRestoreAndFocusCommands(); - m_windowCommandSink.ProjectCommands(windowId, commands); -} - -void EditorWindowUtilityRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - m_traceSink.LogRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App - - - - - diff --git a/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.h b/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.h deleted file mode 100644 index f3963992..00000000 --- a/new_editor/app/Windowing/Utility/EditorWindowUtilityRuntime.h +++ /dev/null @@ -1,61 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowGeometry.h" -#include "Windowing/Utility/WindowUtilityRequest.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { -class WindowTopologyService; -} - -namespace XCEngine::UI::Editor::App { - -class EditorWindowLifecyclePort; -class EditorWindowHostCreationPort; -class EditorWindowNativeQueryPort; -class EditorUtilityWindowPanelProvider; -class EditorWindowDirectory; -class EditorWindowTraceSink; -class EditorWindowUtilitySessionHost; -class EditorWindowCommandSink; - -class EditorWindowUtilityRuntime final { -public: - EditorWindowUtilityRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowUtilitySessionHost& utilitySessionHost, - EditorWindowTraceSink& traceSink, - EditorWindowHostCreationPort& hostCreationPort, - EditorWindowNativeQueryPort& nativeQueryPort, - EditorWindowLifecyclePort& lifecyclePort, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink, - const EditorUtilityWindowPanelProvider& panelProvider); - ~EditorWindowUtilityRuntime(); - - void QueueUtilityWindowRequest(const WindowUtilityRequest& request); - void RemoveWindow(std::string_view windowId); - void FlushPendingUtilityWindowRequests(); - -private: - bool TryProcessOpenUtilityWindowRequest( - std::string_view sourceWindowId, - const WindowUtilityRequest& request); - void FocusWindow(std::string_view windowId) const; - void LogRuntimeTrace(std::string_view channel, std::string_view message) const; - - EditorWindowDirectory& m_windowDirectory; - EditorWindowUtilitySessionHost& m_utilitySessionHost; - EditorWindowTraceSink& m_traceSink; - EditorWindowHostCreationPort& m_hostCreationPort; - EditorWindowNativeQueryPort& m_nativeQueryPort; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& m_topologyService; - EditorWindowCommandSink& m_windowCommandSink; - const EditorUtilityWindowPanelProvider& m_panelProvider; - EditorWindowLifecyclePort& m_lifecyclePort; - std::vector m_pendingUtilityRequests = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Utility/WindowUtilityRequest.h b/new_editor/app/Windowing/Utility/WindowUtilityRequest.h deleted file mode 100644 index 740e5da1..00000000 --- a/new_editor/app/Windowing/Utility/WindowUtilityRequest.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "Windowing/Utility/EditorUtilityWindowSession.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct WindowUtilityRequest { - std::string sourceWindowId = {}; - EditorUtilityWindowSession session = {}; - std::int32_t screenX = 0; - std::int32_t screenY = 0; - bool hasScreenPoint = false; - - bool IsValid() const { - return !sourceWindowId.empty() && session.IsValid(); - } -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.cpp b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.cpp deleted file mode 100644 index f31159f7..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.cpp +++ /dev/null @@ -1,593 +0,0 @@ -#include "Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h" - -#include "Windowing/Ports/EditorWindowNativeQueryPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceHostPort.h" -#include "Windowing/Application/EditorWindowCommandSink.h" -#include "Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h" -#include "Windowing/Host/EditorWindowDirectory.h" -#include "Windowing/Host/EditorWindowTraceSink.h" -#include "Windowing/Ports/EditorWindowWorkspaceContentPort.h" -#include "Windowing/Application/WindowTopologyService.h" - -#include -#include "UIEditorWindowWorkspaceController.h" -#include -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -using ::XCEngine::UI::UIPoint; - -constexpr int kFallbackDragHotspotX = 40; -constexpr int kFallbackDragHotspotY = 12; - -EditorWindowScreenPoint BuildFallbackGlobalTabDragHotspot() { - return EditorWindowScreenPoint{kFallbackDragHotspotX, kFallbackDragHotspotY}; -} - -bool CanStartGlobalTabDragFromWindow( - const UIEditorWorkspaceController& workspaceController, - std::string_view sourceNodeId, - std::string_view panelId) { - UIEditorWorkspaceModel workspace = workspaceController.GetWorkspace(); - UIEditorWorkspaceSession session = workspaceController.GetSession(); - UIEditorWorkspaceExtractedPanel extractedPanel = {}; - return TryExtractUIEditorWorkspaceVisiblePanel( - workspace, - session, - sourceNodeId, - panelId, - extractedPanel); -} - -bool IsLiveInteractiveWindowSnapshot(const EditorWindowSnapshot& snapshot) { - return snapshot.hasNativeWindow && snapshot.running && !snapshot.closing && !snapshot.destroyed; -} - -EditorWindowScreenPoint BuildScreenPoint(const WindowWorkspaceTransferRequest& request) { - return EditorWindowScreenPoint{request.screenX, request.screenY}; -} - -std::array BuildMoveWindowCommands(int x, int y) { - return { - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::MoveWindow, - .x = x, - .y = y, - }, - }; -} - -} // namespace - -EditorWindowWorkspaceInteractionRuntime::EditorWindowWorkspaceInteractionRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowTraceSink& traceSink, - EditorWindowWorkspaceContentPort& workspaceContentPort, - EditorWindowWorkspaceHostPort& workspaceHostPort, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowNativeQueryPort& nativeQueryPort, - EditorWindowCommandSink& windowCommandSink, - EditorWindowWorkspaceMutationRuntime& mutationRuntime) - : m_windowDirectory(windowDirectory) - , m_traceSink(traceSink) - , m_workspaceContentPort(workspaceContentPort) - , m_workspaceHostPort(workspaceHostPort) - , m_topologyService(topologyService) - , m_nativeQueryPort(nativeQueryPort) - , m_windowCommandSink(windowCommandSink) - , m_mutationRuntime(mutationRuntime) { -} - -EditorWindowWorkspaceInteractionRuntime::~EditorWindowWorkspaceInteractionRuntime() = default; - -bool EditorWindowWorkspaceInteractionRuntime::IsGlobalTabDragActive() const { - return m_globalTabDragState.active; -} - -bool EditorWindowWorkspaceInteractionRuntime::OwnsActiveGlobalTabDrag( - std::string_view windowId) const { - return m_globalTabDragState.active && m_globalTabDragState.ownerWindowId == windowId; -} - -bool EditorWindowWorkspaceInteractionRuntime::IsLiveInteractiveWindow( - std::string_view windowId) const { - EditorWindowSnapshot snapshot = {}; - return m_windowDirectory.TryGetWindowSnapshot(windowId, snapshot) && - IsLiveInteractiveWindowSnapshot(snapshot); -} - -void EditorWindowWorkspaceInteractionRuntime::BeginGlobalTabDragSession( - std::string_view ownerWindowId, - std::string_view originWindowId, - std::string_view sourceNodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint dragHotspot) { - if (ownerWindowId.empty() || sourceNodeId.empty() || panelId.empty()) { - m_globalTabDragState = {}; - return; - } - - m_globalTabDragState = GlobalTabDragSessionState{ - .active = true, - .ownerWindowId = std::string(ownerWindowId), - .originWindowId = std::string(originWindowId), - .sourceNodeId = std::string(sourceNodeId), - .panelId = std::string(panelId), - }; - - m_globalTabDragInteractionState.screenPoint = screenPoint; - m_globalTabDragInteractionState.dragHotspot = dragHotspot; -} - -bool EditorWindowWorkspaceInteractionRuntime::TryResolveGlobalTabDragHotspot( - std::string_view sourceWindowId, - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outDragHotspot) const { - return m_workspaceHostPort.TryResolveDockTabDragHotspot( - sourceWindowId, - nodeId, - panelId, - screenPoint, - outDragHotspot); -} - -void EditorWindowWorkspaceInteractionRuntime::UpdateGlobalTabDragOwnerWindowPosition() { - if (!IsGlobalTabDragActive()) { - return; - } - - const std::string& ownerWindowId = m_globalTabDragState.ownerWindowId; - if (!IsLiveInteractiveWindow(ownerWindowId)) { - return; - } - - EditorWindowRect windowRect = {}; - if (!m_nativeQueryPort.TryGetWindowRect(ownerWindowId, windowRect)) { - return; - } - - const int targetLeft = - m_globalTabDragInteractionState.screenPoint.x - - m_globalTabDragInteractionState.dragHotspot.x; - const int targetTop = - m_globalTabDragInteractionState.screenPoint.y - - m_globalTabDragInteractionState.dragHotspot.y; - if (windowRect.left == targetLeft && windowRect.top == targetTop) { - return; - } - - const std::array commands = - BuildMoveWindowCommands(targetLeft, targetTop); - m_windowCommandSink.ProjectCommands(ownerWindowId, commands); -} - -void EditorWindowWorkspaceInteractionRuntime::ClearGlobalTabDragDropPreview() { - if (m_globalTabDragInteractionState.previewWindowId.empty()) { - return; - } - - m_workspaceHostPort.ClearDockHostDropPreview( - m_globalTabDragInteractionState.previewWindowId); - m_globalTabDragInteractionState.previewWindowId.clear(); -} - -void EditorWindowWorkspaceInteractionRuntime::UpdateGlobalTabDragDropPreview() { - if (!IsGlobalTabDragActive()) { - return; - } - - const std::string targetWindowId = FindTopmostWindowIdAtScreenPoint( - m_globalTabDragInteractionState.screenPoint, - m_globalTabDragState.ownerWindowId); - if (targetWindowId.empty()) { - ClearGlobalTabDragDropPreview(); - return; - } - - UIEditorDockHostTabDropTarget dropTarget = {}; - if (!m_workspaceHostPort.TryResolveDockTabDropTarget( - targetWindowId, - m_globalTabDragInteractionState.screenPoint, - dropTarget)) { - ClearGlobalTabDragDropPreview(); - return; - } - - if (!m_globalTabDragInteractionState.previewWindowId.empty() && - m_globalTabDragInteractionState.previewWindowId != targetWindowId) { - ClearGlobalTabDragDropPreview(); - } - - Widgets::UIEditorDockHostDropPreviewState preview = {}; - preview.visible = true; - preview.sourceNodeId = m_globalTabDragState.sourceNodeId; - preview.sourcePanelId = m_globalTabDragState.panelId; - preview.targetNodeId = dropTarget.nodeId; - preview.placement = dropTarget.placement; - preview.insertionIndex = dropTarget.insertionIndex; - if (m_workspaceHostPort.SetDockHostDropPreview(targetWindowId, preview)) { - m_globalTabDragInteractionState.previewWindowId = targetWindowId; - } -} - -void EditorWindowWorkspaceInteractionRuntime::EndGlobalTabDragSession() { - if (!IsGlobalTabDragActive()) { - return; - } - - const std::string ownerWindowId = m_globalTabDragState.ownerWindowId; - ClearGlobalTabDragDropPreview(); - - m_workspaceHostPort.ReleaseGlobalTabDragPointerCapture(ownerWindowId); - if (IsLiveInteractiveWindow(ownerWindowId)) { - m_workspaceContentPort.ResetWorkspaceInteractionState(ownerWindowId); - } - - m_globalTabDragState = {}; - m_globalTabDragInteractionState = {}; -} - -bool EditorWindowWorkspaceInteractionRuntime::HandleGlobalTabDragPointerMove( - std::string_view ownerWindowId) { - if (!IsGlobalTabDragActive()) { - return false; - } - - const GlobalTabDragSessionState& dragState = m_globalTabDragState; - if (!IsLiveInteractiveWindow(dragState.ownerWindowId)) { - EndGlobalTabDragSession(); - return false; - } - if (dragState.ownerWindowId != ownerWindowId) { - return false; - } - - EditorWindowScreenPoint screenPoint = {}; - if (m_nativeQueryPort.TryGetCursorScreenPoint(screenPoint)) { - m_globalTabDragInteractionState.screenPoint = screenPoint; - UpdateGlobalTabDragOwnerWindowPosition(); - UpdateGlobalTabDragDropPreview(); - } - return true; -} - -bool EditorWindowWorkspaceInteractionRuntime::HandleGlobalTabDragPointerButtonUp( - std::string_view ownerWindowId) { - if (!IsGlobalTabDragActive()) { - return false; - } - - const GlobalTabDragSessionState dragState = m_globalTabDragState; - if (!IsLiveInteractiveWindow(dragState.ownerWindowId)) { - EndGlobalTabDragSession(); - return false; - } - if (dragState.ownerWindowId != ownerWindowId) { - return false; - } - - EditorWindowScreenPoint screenPoint = m_globalTabDragInteractionState.screenPoint; - m_nativeQueryPort.TryGetCursorScreenPoint(screenPoint); - - const std::string panelWindowId = dragState.ownerWindowId; - const std::string sourceNodeId = dragState.sourceNodeId; - const std::string panelId = dragState.panelId; - EndGlobalTabDragSession(); - - const std::string targetWindowId = FindTopmostWindowIdAtScreenPoint(screenPoint, panelWindowId); - if (targetWindowId.empty()) { - return true; - } - - UIEditorDockHostTabDropTarget dropTarget = {}; - if (!m_workspaceHostPort.TryResolveDockTabDropTarget( - targetWindowId, - screenPoint, - dropTarget)) { - return true; - } - - UIEditorWindowWorkspaceController windowWorkspaceController = - m_mutationRuntime.BuildWorkspaceMutationController(); - const UIEditorWindowWorkspaceOperationResult result = - dropTarget.placement == UIEditorWorkspaceDockPlacement::Center - ? windowWorkspaceController.MovePanelToStack( - panelWindowId, - sourceNodeId, - panelId, - targetWindowId, - dropTarget.nodeId, - dropTarget.insertionIndex) - : windowWorkspaceController.DockPanelRelative( - panelWindowId, - sourceNodeId, - panelId, - targetWindowId, - dropTarget.nodeId, - dropTarget.placement); - if (result.status != UIEditorWindowWorkspaceOperationStatus::Changed) { - LogRuntimeTrace("drag", "cross-window drop rejected: " + result.message); - return true; - } - - if (!m_mutationRuntime.CommitWindowWorkspaceMutation( - windowWorkspaceController, - {}, - screenPoint)) { - LogRuntimeTrace("drag", "failed to synchronize windows after cross-window drop"); - return true; - } - - m_mutationRuntime.FocusWindow(targetWindowId); - LogRuntimeTrace( - "drag", - "committed cross-window drop panel '" + panelId + - "' into window '" + targetWindowId + "'"); - return true; -} - -bool EditorWindowWorkspaceInteractionRuntime::TryStartGlobalTabDrag( - std::string_view sourceWindowId, - const WindowWorkspaceTransferRequest& request) { - EditorWindowSnapshot sourceSnapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(sourceWindowId, sourceSnapshot) || - !IsLiveInteractiveWindowSnapshot(sourceSnapshot)) { - LogRuntimeTrace("drag", "failed to start global tab drag: source window is closing"); - return false; - } - - UIEditorWorkspaceController sourceWorkspaceController = {}; - if (!m_workspaceContentPort.TryGetWorkspaceController( - sourceWindowId, - sourceWorkspaceController)) { - LogRuntimeTrace("drag", "failed to start global tab drag: source workspace unavailable"); - return false; - } - - const EditorWindowScreenPoint screenPoint = BuildScreenPoint(request); - EditorWindowScreenPoint dragHotspot = BuildFallbackGlobalTabDragHotspot(); - TryResolveGlobalTabDragHotspot( - sourceWindowId, - request.sourceNodeId, - request.panelId, - screenPoint, - dragHotspot); - - const auto tryStartDetachedPanelGlobalDrag = - [this, &request, &dragHotspot]( - UIEditorWindowWorkspaceController& windowWorkspaceController, - const UIEditorWindowWorkspaceOperationResult& result) { - const EditorWindowScreenPoint screenPoint = BuildScreenPoint(request); - if (!m_mutationRuntime.CommitWindowWorkspaceMutation( - windowWorkspaceController, - result.targetWindowId, - screenPoint)) { - LogRuntimeTrace("drag", "failed to synchronize detached drag window state"); - return false; - } - - EditorWindowSnapshot detachedSnapshot = {}; - UIEditorWorkspaceController detachedWorkspaceController = {}; - if (!m_windowDirectory.TryGetWindowSnapshot( - result.targetWindowId, - detachedSnapshot) || - !IsLiveInteractiveWindowSnapshot(detachedSnapshot) || - !m_workspaceContentPort.TryGetWorkspaceController( - result.targetWindowId, - detachedWorkspaceController)) { - LogRuntimeTrace("drag", "detached drag window was not created."); - return false; - } - - BeginGlobalTabDragSession( - result.targetWindowId, - result.sourceWindowId, - detachedWorkspaceController.GetWorkspace().root.nodeId, - request.panelId, - screenPoint, - dragHotspot); - UpdateGlobalTabDragOwnerWindowPosition(); - m_workspaceHostPort.AcquireGlobalTabDragPointerCapture(result.targetWindowId); - m_mutationRuntime.FocusWindow(result.targetWindowId); - LogRuntimeTrace( - "drag", - "started global tab drag by detaching panel '" + request.panelId + - "' into window '" + result.targetWindowId + "'"); - return true; - }; - - UIEditorWindowWorkspaceController windowWorkspaceController = - m_mutationRuntime.BuildWorkspaceMutationController(); - const UIEditorWindowWorkspaceOperationResult result = - windowWorkspaceController.DetachPanelToNewWindow( - sourceWindowId, - request.sourceNodeId, - request.panelId); - if (result.status == UIEditorWindowWorkspaceOperationStatus::Changed) { - return tryStartDetachedPanelGlobalDrag(windowWorkspaceController, result); - } - - if (sourceSnapshot.primary) { - LogRuntimeTrace( - "drag", - "failed to start global tab drag from primary window: " + result.message); - return false; - } - - m_workspaceContentPort.ResetWorkspaceInteractionState(sourceWindowId); - if (result.status != UIEditorWindowWorkspaceOperationStatus::NoOp) { - LogRuntimeTrace( - "drag", - "failed to start global tab drag from detached window: " + result.message); - return false; - } - if (!CanStartGlobalTabDragFromWindow( - sourceWorkspaceController, - request.sourceNodeId, - request.panelId)) { - LogRuntimeTrace( - "drag", - "failed to start global tab drag from detached window: invalid source panel request"); - return false; - } - - BeginGlobalTabDragSession( - sourceWindowId, - sourceWindowId, - request.sourceNodeId, - request.panelId, - screenPoint, - dragHotspot); - UpdateGlobalTabDragOwnerWindowPosition(); - m_workspaceHostPort.AcquireGlobalTabDragPointerCapture(sourceWindowId); - LogRuntimeTrace( - "drag", - "started global tab drag from detached window '" + - std::string(sourceWindowId) + - "' panel '" + request.panelId + "'"); - return true; -} - -bool EditorWindowWorkspaceInteractionRuntime::TryProcessDetachRequest( - std::string_view sourceWindowId, - const WindowWorkspaceTransferRequest& request) { - if (!IsLiveInteractiveWindow(sourceWindowId)) { - LogRuntimeTrace("detach", "detach request rejected: source window is closing"); - return false; - } - - const EditorWindowScreenPoint screenPoint = BuildScreenPoint(request); - UIEditorWindowWorkspaceController windowWorkspaceController = - m_mutationRuntime.BuildWorkspaceMutationController(); - const UIEditorWindowWorkspaceOperationResult result = - windowWorkspaceController.DetachPanelToNewWindow( - sourceWindowId, - request.sourceNodeId, - request.panelId); - if (result.status != UIEditorWindowWorkspaceOperationStatus::Changed) { - LogRuntimeTrace("detach", "detach request rejected: " + result.message); - return false; - } - - if (!m_mutationRuntime.CommitWindowWorkspaceMutation( - windowWorkspaceController, - result.targetWindowId, - screenPoint)) { - LogRuntimeTrace("detach", "failed to synchronize detached window state"); - return false; - } - - m_mutationRuntime.FocusWindow(result.targetWindowId); - - LogRuntimeTrace( - "detach", - "detached panel '" + request.panelId + "' from window '" + std::string(sourceWindowId) + - "' to window '" + result.targetWindowId + "'"); - return true; -} - -void EditorWindowWorkspaceInteractionRuntime::HandlePendingWorkspaceTransferRequests( - const std::vector& requests) { - for (const WindowWorkspaceTransferRequest& transferRequest : requests) { - if (!IsLiveInteractiveWindow(transferRequest.sourceWindowId)) { - LogRuntimeTrace( - "workspace", - "workspace transfer request dropped: source window is not running"); - continue; - } - - switch (transferRequest.type) { - case WindowWorkspaceTransferRequest::Type::StartGlobalTabDrag: - if (!IsGlobalTabDragActive() && transferRequest.IsValid()) { - TryStartGlobalTabDrag(transferRequest.sourceWindowId, transferRequest); - } - break; - case WindowWorkspaceTransferRequest::Type::DetachPanel: - if (!IsGlobalTabDragActive() && transferRequest.IsValid()) { - TryProcessDetachRequest(transferRequest.sourceWindowId, transferRequest); - } - break; - default: - break; - } - } -} - -void EditorWindowWorkspaceInteractionRuntime::QueueWorkspaceTransferRequest( - const WindowWorkspaceTransferRequest& request) { - m_workspaceTransferQueue.QueueWorkspaceTransferRequest(request); -} - -void EditorWindowWorkspaceInteractionRuntime::RemoveWindow(std::string_view windowId) { - m_workspaceTransferQueue.RemoveWindow(windowId); -} - -void EditorWindowWorkspaceInteractionRuntime::FlushPendingWorkspaceTransferRequests() { - HandlePendingWorkspaceTransferRequests( - m_workspaceTransferQueue.ConsumePendingWorkspaceTransferRequests()); -} - -std::string EditorWindowWorkspaceInteractionRuntime::FindTopmostWindowIdAtScreenPoint( - EditorWindowScreenPoint screenPoint, - std::string_view excludedWindowId) { - std::vector windows = {}; - m_windowDirectory.ForEachWindowSnapshot( - [&windows](const EditorWindowSnapshot& snapshot) { - windows.push_back(snapshot); - return true; - }); - - for (auto it = windows.rbegin(); it != windows.rend(); ++it) { - const EditorWindowSnapshot& snapshot = *it; - if (!IsLiveInteractiveWindowSnapshot(snapshot) || snapshot.windowId == excludedWindowId) { - continue; - } - - if (m_nativeQueryPort.IsWindowUnderScreenPoint(snapshot.windowId, screenPoint)) { - return snapshot.windowId; - } - } - - for (auto it = windows.rbegin(); it != windows.rend(); ++it) { - const EditorWindowSnapshot& snapshot = *it; - if (!IsLiveInteractiveWindowSnapshot(snapshot) || snapshot.windowId == excludedWindowId) { - continue; - } - - EditorWindowRect windowRect = {}; - if (m_nativeQueryPort.TryGetWindowRect(snapshot.windowId, windowRect) && - windowRect.Contains(screenPoint)) { - return snapshot.windowId; - } - } - - return {}; -} - -std::string EditorWindowWorkspaceInteractionRuntime::FindTopmostWindowIdAtScreenPoint( - EditorWindowScreenPoint screenPoint, - std::string_view excludedWindowId) const { - return const_cast(this)->FindTopmostWindowIdAtScreenPoint( - screenPoint, - excludedWindowId); -} - -void EditorWindowWorkspaceInteractionRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - m_traceSink.LogRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h deleted file mode 100644 index 3b88af98..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceInteractionRuntime.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -#include "Windowing/Application/EditorWindowGeometry.h" -#include "Windowing/Workspace/WindowWorkspaceTransferQueue.h" - -#include - -#include -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { -class WindowTopologyService; -} - -namespace XCEngine::UI::Editor::App { - -class EditorWindow; -class EditorWindowDirectory; -class EditorWindowTraceSink; -class EditorWindowWorkspaceContentPort; -class EditorWindowWorkspaceHostPort; -class EditorWindowWorkspaceMutationRuntime; -class EditorWindowNativeQueryPort; -class EditorWindowCommandSink; - -class EditorWindowWorkspaceInteractionRuntime final { -public: - EditorWindowWorkspaceInteractionRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowTraceSink& traceSink, - EditorWindowWorkspaceContentPort& workspaceContentPort, - EditorWindowWorkspaceHostPort& workspaceHostPort, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowNativeQueryPort& nativeQueryPort, - EditorWindowCommandSink& windowCommandSink, - EditorWindowWorkspaceMutationRuntime& mutationRuntime); - ~EditorWindowWorkspaceInteractionRuntime(); - - bool IsGlobalTabDragActive() const; - bool OwnsActiveGlobalTabDrag(std::string_view windowId) const; - void EndGlobalTabDragSession(); - bool HandleGlobalTabDragPointerMove(std::string_view ownerWindowId); - bool HandleGlobalTabDragPointerButtonUp(std::string_view ownerWindowId); - void HandlePendingWorkspaceTransferRequests( - const std::vector& requests); - void QueueWorkspaceTransferRequest(const WindowWorkspaceTransferRequest& request); - void RemoveWindow(std::string_view windowId); - void FlushPendingWorkspaceTransferRequests(); - -private: - struct GlobalTabDragInteractionState { - std::string previewWindowId = {}; - EditorWindowScreenPoint screenPoint = {}; - EditorWindowScreenPoint dragHotspot = {}; - }; - - struct GlobalTabDragSessionState { - bool active = false; - std::string ownerWindowId = {}; - std::string originWindowId = {}; - std::string sourceNodeId = {}; - std::string panelId = {}; - }; - - void BeginGlobalTabDragSession( - std::string_view ownerWindowId, - std::string_view originWindowId, - std::string_view sourceNodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint dragHotspot); - bool TryResolveGlobalTabDragHotspot( - std::string_view sourceWindowId, - std::string_view nodeId, - std::string_view panelId, - EditorWindowScreenPoint screenPoint, - EditorWindowScreenPoint& outDragHotspot) const; - void ClearGlobalTabDragDropPreview(); - void UpdateGlobalTabDragDropPreview(); - void UpdateGlobalTabDragOwnerWindowPosition(); - std::string FindTopmostWindowIdAtScreenPoint( - EditorWindowScreenPoint screenPoint, - std::string_view excludedWindowId = {}); - std::string FindTopmostWindowIdAtScreenPoint( - EditorWindowScreenPoint screenPoint, - std::string_view excludedWindowId = {}) const; - bool TryStartGlobalTabDrag( - std::string_view sourceWindowId, - const WindowWorkspaceTransferRequest& request); - bool TryProcessDetachRequest( - std::string_view sourceWindowId, - const WindowWorkspaceTransferRequest& request); - bool IsLiveInteractiveWindow(std::string_view windowId) const; - void LogRuntimeTrace(std::string_view channel, std::string_view message) const; - - EditorWindowDirectory& m_windowDirectory; - EditorWindowTraceSink& m_traceSink; - EditorWindowWorkspaceContentPort& m_workspaceContentPort; - EditorWindowWorkspaceHostPort& m_workspaceHostPort; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& m_topologyService; - EditorWindowNativeQueryPort& m_nativeQueryPort; - EditorWindowCommandSink& m_windowCommandSink; - EditorWindowWorkspaceMutationRuntime& m_mutationRuntime; - GlobalTabDragSessionState m_globalTabDragState = {}; - GlobalTabDragInteractionState m_globalTabDragInteractionState = {}; - WindowWorkspaceTransferQueue m_workspaceTransferQueue = {}; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.cpp b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.cpp deleted file mode 100644 index 533c4fe4..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#include "Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h" - -#include "Composition/EditorContext.h" -#include "Windowing/Application/EditorWindowContentSpec.h" -#include "Windowing/Application/EditorWindowCommandSink.h" -#include "Windowing/Application/EditorWindowGeometry.h" -#include "Windowing/Host/EditorWindowDirectory.h" -#include "Windowing/Host/EditorWindowTraceSink.h" -#include "Windowing/Ports/EditorWindowLifecyclePort.h" -#include "Windowing/Ports/EditorWindowHostCreationPort.h" -#include "Windowing/Ports/EditorWindowWorkspaceContentPort.h" -#include "Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h" - -#include "Windowing/Application/WindowTopologyService.h" - -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -struct ExistingWindowSnapshot { - std::string windowId = {}; - UIEditorWorkspaceController workspaceController = {}; - bool primary = false; -}; - -std::array BuildFocusWindowCommands() { - return { - Domain::WindowCommand{.type = Domain::WindowCommand::Type::FocusWindow}, - }; -} - -} // namespace - -EditorWindowWorkspaceMutationRuntime::EditorWindowWorkspaceMutationRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowTraceSink& traceSink, - EditorWindowWorkspaceContentPort& workspaceContentPort, - EditorWindowHostCreationPort& hostCreationPort, - EditorWindowLifecyclePort& lifecyclePort, - EditorContext& editorContext, - EditorWindowWorkspaceProjectionRuntime& projectionRuntime, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink) - : m_windowDirectory(windowDirectory) - , m_traceSink(traceSink) - , m_workspaceContentPort(workspaceContentPort) - , m_hostCreationPort(hostCreationPort) - , m_projectionRuntime(projectionRuntime) - , m_topologyService(topologyService) - , m_windowCommandSink(windowCommandSink) - , m_lifecyclePort(lifecyclePort) - , m_workspaceStore(editorContext.GetShellAsset().panelRegistry) { -} - -EditorWindowWorkspaceMutationRuntime::~EditorWindowWorkspaceMutationRuntime() = default; - -UIEditorWindowWorkspaceController -EditorWindowWorkspaceMutationRuntime::BuildWorkspaceMutationController() const { - UIEditorWindowWorkspaceSet windowSet = {}; - std::string error = {}; - if (!m_topologyService.TryBuildWorkspaceSet({}, windowSet, error)) { - LogRuntimeTrace( - "workspace", - "workspace mutation controller topology snapshot unavailable: " + error); - } - - return UIEditorWindowWorkspaceController( - m_workspaceStore.GetPanelRegistry(), - windowSet); -} - -UIEditorWorkspaceController -EditorWindowWorkspaceMutationRuntime::BuildWorkspaceControllerForWindow( - const UIEditorWindowWorkspaceState& windowState) const { - return UIEditorWorkspaceController( - m_workspaceStore.GetPanelRegistry(), - windowState.workspace, - windowState.session); -} - -void EditorWindowWorkspaceMutationRuntime::FocusWindow(std::string_view windowId) const { - EditorWindowSnapshot snapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(windowId, snapshot) || - !snapshot.hasNativeWindow || - !snapshot.running || - snapshot.destroyed) { - return; - } - - const std::array commands = BuildFocusWindowCommands(); - m_windowCommandSink.ProjectCommands(windowId, commands); -} - -bool EditorWindowWorkspaceMutationRuntime::SynchronizeWindowsFromWindowSet( - const UIEditorWindowWorkspaceSet& windowSet, - std::string_view preferredNewWindowId, - EditorWindowScreenPoint preferredScreenPoint, - int preferredWidth, - int preferredHeight) { - const auto restoreWindowSnapshot = [this](const ExistingWindowSnapshot& snapshot) { - if (snapshot.windowId.empty()) { - return; - } - - m_workspaceContentPort.TryApplyWorkspaceController( - snapshot.windowId, - snapshot.workspaceController, - snapshot.primary); - m_workspaceContentPort.ResetWorkspaceInteractionState(snapshot.windowId); - EditorWindowSnapshot registrySnapshot = {}; - if (m_windowDirectory.TryGetWindowSnapshot(snapshot.windowId, registrySnapshot)) { - m_projectionRuntime.RefreshWorkspaceWindowPresentation( - snapshot.windowId, - registrySnapshot.windowType, - snapshot.primary, - snapshot.workspaceController); - } - }; - - const auto destroyAndEraseWindowById = [this](std::string_view windowId) { - EditorWindowSnapshot snapshot = {}; - if (!m_windowDirectory.TryGetWindowSnapshot(windowId, snapshot)) { - return false; - } - - m_lifecyclePort.AbortUnregisteredWindow(snapshot.windowId); - return true; - }; - - std::vector windowIdsInSet = {}; - windowIdsInSet.reserve(windowSet.windows.size()); - std::vector existingWindowSnapshots = {}; - existingWindowSnapshots.reserve(windowSet.windows.size()); - std::vector createdWindowIds = {}; - - for (const UIEditorWindowWorkspaceState& entry : windowSet.windows) { - windowIdsInSet.push_back(entry.windowId); - const bool isPrimaryWindow = entry.windowId == windowSet.primaryWindowId; - EditorWindowSnapshot existingSnapshot = {}; - bool existingWindowFound = - m_windowDirectory.TryGetWindowSnapshot(entry.windowId, existingSnapshot); - if (existingWindowFound && existingSnapshot.destroyed) { - m_lifecyclePort.ReapDestroyedWindows(); - existingWindowFound = - m_windowDirectory.TryGetWindowSnapshot(entry.windowId, existingSnapshot); - } - - if (existingWindowFound) { - if (!existingSnapshot.running) { - LogRuntimeTrace( - "window", - "workspace synchronization rejected: window '" + entry.windowId + - "' is not running"); - return false; - } - - UIEditorWorkspaceController previousWorkspaceController = {}; - m_workspaceContentPort.TryGetWorkspaceController( - entry.windowId, - previousWorkspaceController); - existingWindowSnapshots.push_back(ExistingWindowSnapshot{ - entry.windowId, - previousWorkspaceController, - existingSnapshot.primary, - }); - UIEditorWorkspaceController workspaceController = BuildWorkspaceControllerForWindow(entry); - m_workspaceContentPort.TryApplyWorkspaceController( - entry.windowId, - workspaceController, - isPrimaryWindow); - m_workspaceContentPort.ResetWorkspaceInteractionState(entry.windowId); - if (m_windowDirectory.TryGetWindowSnapshot(entry.windowId, existingSnapshot)) { - m_projectionRuntime.RefreshWorkspaceWindowPresentation( - entry.windowId, - existingSnapshot.windowType, - isPrimaryWindow, - workspaceController); - } - continue; - } - - EditorWindowHostCreateRequest createRequest = {}; - createRequest.windowId = entry.windowId; - createRequest.windowType = - isPrimaryWindow - ? Domain::WindowType::PrimaryWorkspace - : Domain::WindowType::DetachedWorkspace; - createRequest.primary = isPrimaryWindow; - createRequest.useDefaultInitialPosition = true; - createRequest.title = - createRequest.primary - ? m_projectionRuntime.ResolvePrimaryWindowTitle() - : m_projectionRuntime.BuildWindowTitleFromWorkspaceController( - BuildWorkspaceControllerForWindow(entry)); - if (entry.windowId == preferredNewWindowId) { - const EditorWindowRect detachedRect = BuildEditorFloatingWindowRect( - preferredScreenPoint, - preferredWidth, - preferredHeight); - createRequest.initialX = detachedRect.left; - createRequest.initialY = detachedRect.top; - createRequest.initialWidth = detachedRect.right - detachedRect.left; - createRequest.initialHeight = detachedRect.bottom - detachedRect.top; - createRequest.useDefaultInitialPosition = false; - } - - const EditorWindowHostCreateResult createResult = - m_hostCreationPort.CreateWorkspaceWindow( - EditorWorkspaceWindowContentSpec{ - .workspaceController = BuildWorkspaceControllerForWindow(entry), - }, - createRequest); - if (!createResult.success) { - for (const ExistingWindowSnapshot& snapshot : existingWindowSnapshots) { - restoreWindowSnapshot(snapshot); - } - for (auto it = createdWindowIds.rbegin(); it != createdWindowIds.rend(); ++it) { - destroyAndEraseWindowById(*it); - } - return false; - } - - createdWindowIds.push_back(createResult.windowId); - } - - m_windowDirectory.ForEachWindowSnapshot( - [this, &windowIdsInSet](const EditorWindowSnapshot& window) { - if (!window.hasNativeWindow || window.primary || !window.running) { - return true; - } - - const bool existsInWindowSet = - std::find( - windowIdsInSet.begin(), - windowIdsInSet.end(), - window.windowId) != windowIdsInSet.end(); - if (!existsInWindowSet) { - m_lifecyclePort.PostCloseRequest(window.windowId); - } - return true; - }); - - return true; -} - -bool EditorWindowWorkspaceMutationRuntime::CommitWindowWorkspaceMutation( - const UIEditorWindowWorkspaceController& windowWorkspaceController, - std::string_view preferredNewWindowId, - EditorWindowScreenPoint preferredScreenPoint, - int preferredWidth, - int preferredHeight) { - const UIEditorWindowWorkspaceSet nextWindowSet = windowWorkspaceController.GetWindowSet(); - std::string error = {}; - if (!m_workspaceStore.ValidateWindowSet(nextWindowSet, error)) { - LogRuntimeTrace("window", "workspace mutation validation failed: " + error); - return false; - } - - if (!SynchronizeWindowsFromWindowSet( - nextWindowSet, - preferredNewWindowId, - preferredScreenPoint, - preferredWidth, - preferredHeight)) { - return false; - } - - m_topologyService.ReplaceWorkspaceWindowSet(nextWindowSet); - return true; -} - -void EditorWindowWorkspaceMutationRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - m_traceSink.LogRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App - diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h deleted file mode 100644 index 2840cf1c..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceMutationRuntime.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "Composition/EditorWindowWorkspaceStore.h" -#include "Windowing/Application/EditorWindowGeometry.h" -#include "Windowing/Workspace/UIEditorWindowWorkspaceController.h" - -#include - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { -class WindowTopologyService; -} - -namespace XCEngine::UI::Editor::App { - -class EditorContext; -class EditorWindowLifecyclePort; -class EditorWindowHostCreationPort; -class EditorWindowDirectory; -class EditorWindowTraceSink; -class EditorWindowWorkspaceContentPort; -class EditorWindowWorkspaceProjectionRuntime; -class EditorWindowCommandSink; - -class EditorWindowWorkspaceMutationRuntime final { -public: - EditorWindowWorkspaceMutationRuntime( - EditorWindowDirectory& windowDirectory, - EditorWindowTraceSink& traceSink, - EditorWindowWorkspaceContentPort& workspaceContentPort, - EditorWindowHostCreationPort& hostCreationPort, - EditorWindowLifecyclePort& lifecyclePort, - EditorContext& editorContext, - EditorWindowWorkspaceProjectionRuntime& projectionRuntime, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink); - ~EditorWindowWorkspaceMutationRuntime(); - - UIEditorWindowWorkspaceController BuildWorkspaceMutationController() const; - bool CommitWindowWorkspaceMutation( - const UIEditorWindowWorkspaceController& windowWorkspaceController, - std::string_view preferredNewWindowId, - EditorWindowScreenPoint preferredScreenPoint, - int preferredWidth = 0, - int preferredHeight = 0); - void FocusWindow(std::string_view windowId) const; - -private: - bool SynchronizeWindowsFromWindowSet( - const UIEditorWindowWorkspaceSet& windowSet, - std::string_view preferredNewWindowId, - EditorWindowScreenPoint preferredScreenPoint, - int preferredWidth, - int preferredHeight); - UIEditorWorkspaceController BuildWorkspaceControllerForWindow( - const UIEditorWindowWorkspaceState& windowState) const; - void LogRuntimeTrace(std::string_view channel, std::string_view message) const; - - EditorWindowDirectory& m_windowDirectory; - EditorWindowTraceSink& m_traceSink; - EditorWindowWorkspaceContentPort& m_workspaceContentPort; - EditorWindowHostCreationPort& m_hostCreationPort; - EditorWindowWorkspaceProjectionRuntime& m_projectionRuntime; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& m_topologyService; - EditorWindowCommandSink& m_windowCommandSink; - EditorWindowLifecyclePort& m_lifecyclePort; - EditorWindowWorkspaceStore m_workspaceStore; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.cpp b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.cpp deleted file mode 100644 index 011eb5b0..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#include "Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h" - -#include "Support/StringEncoding.h" -#include "Windowing/Application/EditorWindowCommandSink.h" -#include "Windowing/Application/WindowTopologyService.h" - -#include -#include -#include "UIEditorDetachedWindowPolicy.h" - -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -namespace { - -namespace Domain = ::XCEngine::UI::Editor::Windowing::Domain; - -std::string DescribeWindowSetState(const UIEditorWindowWorkspaceSet& windowSet) { - std::ostringstream stream = {}; - stream << "primary='" << windowSet.primaryWindowId - << "' active='" << windowSet.activeWindowId - << "' count=" << windowSet.windows.size() - << " windows=["; - bool first = true; - for (const UIEditorWindowWorkspaceState& state : windowSet.windows) { - if (!first) { - stream << ','; - } - first = false; - stream << state.windowId; - } - stream << ']'; - return stream.str(); -} - -std::array BuildSetWindowTitleCommands(std::wstring_view title) { - return { - Domain::WindowCommand{ - .type = Domain::WindowCommand::Type::SetWindowTitle, - .payload = WideToUtf8(title), - }, - }; -} - -} // namespace - -EditorWindowWorkspaceProjectionRuntime::EditorWindowWorkspaceProjectionRuntime( - std::wstring primaryWindowTitle, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink) - : m_primaryWindowTitle(!primaryWindowTitle.empty() ? std::move(primaryWindowTitle) : L"XCEngine Editor") - , m_topologyService(topologyService) - , m_windowCommandSink(windowCommandSink) { -} - -void EditorWindowWorkspaceProjectionRuntime::RefreshWorkspaceWindowPresentation( - std::string_view windowId, - Domain::WindowType windowType, - bool primary, - const UIEditorWorkspaceController& workspaceController) { - const std::wstring title = primary - ? ResolvePrimaryWindowTitle() - : BuildWindowTitleFromWorkspaceController(workspaceController); - const std::array commands = - BuildSetWindowTitleCommands(title); - m_windowCommandSink.ProjectCommands(windowId, commands); - SyncWorkspaceWindowTopology(windowId, windowType, primary, workspaceController); -} - -bool EditorWindowWorkspaceProjectionRuntime::IsPrimaryWindowId(std::string_view windowId) const { - return m_topologyService.IsPrimaryWindowId(windowId); -} - -std::string EditorWindowWorkspaceProjectionRuntime::DescribeWindowSet() const { - UIEditorWindowWorkspaceSet windowSet = {}; - std::string error = {}; - if (!m_topologyService.TryBuildWorkspaceSet({}, windowSet, error)) { - return DescribeWindowSetState(windowSet) + " topologyUnavailable='" + error + "'"; - } - - return DescribeWindowSetState(windowSet); -} - -void EditorWindowWorkspaceProjectionRuntime::RemoveWindowProjection( - std::string_view windowId, - bool primary) { - LogRuntimeTrace( - "window-close", - "workspace remove begin windowId='" + std::string(windowId) + - "' primaryArg=" + (primary ? "1" : "0") + - " stateBefore=" + DescribeWindowSet()); - - UIEditorWindowWorkspaceSet stateAfter = {}; - std::string error = {}; - if (!primary && - !m_topologyService.TryBuildWorkspaceSet(windowId, stateAfter, error)) { - LogRuntimeTrace( - "window-close", - "workspace remove topology snapshot unavailable windowId='" + - std::string(windowId) + "' error='" + error + "'"); - } - LogRuntimeTrace( - "window-close", - "workspace remove end windowId='" + std::string(windowId) + - "' stateAfter=" + DescribeWindowSetState(stateAfter)); -} - -std::wstring EditorWindowWorkspaceProjectionRuntime::ResolvePrimaryWindowTitle() const { - return m_primaryWindowTitle; -} - -std::wstring EditorWindowWorkspaceProjectionRuntime::BuildWindowTitleFromWorkspaceController( - const UIEditorWorkspaceController& workspaceController) const { - const std::string titleText = - ResolveUIEditorDetachedWorkspaceTitle(workspaceController, "XCEngine Editor"); - if (!titleText.empty()) { - return std::wstring(titleText.begin(), titleText.end()); - } - - return std::wstring(L"XCEngine Editor"); -} - -void EditorWindowWorkspaceProjectionRuntime::SyncWorkspaceWindowTopology( - std::string_view windowId, - Domain::WindowType windowType, - bool primary, - const UIEditorWorkspaceController& workspaceController) { - Domain::WindowProjectionSnapshot projection = {}; - projection.windowId = Domain::WindowId(std::string(windowId)); - projection.windowType = windowType; - projection.primary = primary; - m_topologyService.UpdateProjection(projection); - m_topologyService.UpdateWorkspaceSnapshot( - projection.windowId, - workspaceController.GetWorkspace(), - workspaceController.GetSession()); -} - -void EditorWindowWorkspaceProjectionRuntime::LogRuntimeTrace( - std::string_view channel, - std::string_view message) const { - AppendUIEditorRuntimeTrace(channel, message); -} - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h b/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h deleted file mode 100644 index 90d7ac25..00000000 --- a/new_editor/app/Windowing/Workspace/EditorWindowWorkspaceProjectionRuntime.h +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "Windowing/Workspace/UIEditorWindowWorkspaceController.h" - -#include -#include - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Application { -class WindowTopologyService; -} - -namespace XCEngine::UI::Editor::App { - -class EditorWindowCommandSink; - -class EditorWindowWorkspaceProjectionRuntime final { -public: - EditorWindowWorkspaceProjectionRuntime( - std::wstring primaryWindowTitle, - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& topologyService, - EditorWindowCommandSink& windowCommandSink); - - void RefreshWorkspaceWindowPresentation( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController& workspaceController); - bool IsPrimaryWindowId(std::string_view windowId) const; - std::string DescribeWindowSet() const; - void RemoveWindowProjection(std::string_view windowId, bool primary); - std::wstring ResolvePrimaryWindowTitle() const; - std::wstring BuildWindowTitleFromWorkspaceController( - const ::XCEngine::UI::Editor::UIEditorWorkspaceController& workspaceController) const; - void SyncWorkspaceWindowTopology( - std::string_view windowId, - ::XCEngine::UI::Editor::Windowing::Domain::WindowType windowType, - bool primary, - const ::XCEngine::UI::Editor::UIEditorWorkspaceController& workspaceController); - -private: - void LogRuntimeTrace(std::string_view channel, std::string_view message) const; - - std::wstring m_primaryWindowTitle = {}; - ::XCEngine::UI::Editor::Windowing::Application::WindowTopologyService& m_topologyService; - EditorWindowCommandSink& m_windowCommandSink; -}; - -} // namespace XCEngine::UI::Editor::App diff --git a/new_editor/app/Windowing/Workspace/WindowWorkspaceTransferQueue.h b/new_editor/app/Windowing/Workspace/WindowWorkspaceTransferQueue.h deleted file mode 100644 index 6c1bdf3b..00000000 --- a/new_editor/app/Windowing/Workspace/WindowWorkspaceTransferQueue.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace XCEngine::UI::Editor::App { - -struct WindowWorkspaceTransferRequest { - enum class Type : std::uint8_t { - None = 0, - StartGlobalTabDrag, - DetachPanel, - }; - - Type type = Type::None; - std::string sourceWindowId = {}; - std::string sourceNodeId = {}; - std::string panelId = {}; - std::int32_t screenX = 0; - std::int32_t screenY = 0; - bool hasScreenPoint = false; - - bool IsValid() const { - return type != Type::None && - !sourceWindowId.empty() && - !sourceNodeId.empty() && - !panelId.empty() && - hasScreenPoint; - } -}; - -class WindowWorkspaceTransferQueue final { -public: - - void QueueWorkspaceTransferRequest(const WindowWorkspaceTransferRequest& request) { - if (!request.IsValid()) { - return; - } - - const auto it = std::find_if( - m_pendingWorkspaceTransferRequests.begin(), - m_pendingWorkspaceTransferRequests.end(), - [&request](const WindowWorkspaceTransferRequest& current) { - return current.type == request.type && - current.sourceWindowId == request.sourceWindowId && - current.sourceNodeId == request.sourceNodeId && - current.panelId == request.panelId; - }); - if (it == m_pendingWorkspaceTransferRequests.end()) { - m_pendingWorkspaceTransferRequests.push_back(request); - } else { - *it = request; - } - } - - std::vector ConsumePendingWorkspaceTransferRequests() { - std::vector requests = - std::move(m_pendingWorkspaceTransferRequests); - m_pendingWorkspaceTransferRequests.clear(); - return requests; - } - - void RemoveWindow(std::string_view windowId) { - if (windowId.empty()) { - return; - } - - std::erase_if( - m_pendingWorkspaceTransferRequests, - [windowId](const WindowWorkspaceTransferRequest& current) { - return current.sourceWindowId == windowId; - }); - } - -private: - std::vector m_pendingWorkspaceTransferRequests = {}; -}; - -} // namespace XCEngine::UI::Editor::App - - diff --git a/new_editor/include/XCEditor/Windowing/FrameDispatchMode.h b/new_editor/include/XCEditor/Windowing/FrameDispatchMode.h deleted file mode 100644 index 749654c2..00000000 --- a/new_editor/include/XCEditor/Windowing/FrameDispatchMode.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class FrameDispatchMode : std::uint8_t { - Steady = 0, - Immediate, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/FramePriority.h b/new_editor/include/XCEditor/Windowing/FramePriority.h deleted file mode 100644 index b897ba93..00000000 --- a/new_editor/include/XCEditor/Windowing/FramePriority.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class FramePriority : std::uint8_t { - None = 0, - Normal, - High, - Critical, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/FrameReason.h b/new_editor/include/XCEditor/Windowing/FrameReason.h deleted file mode 100644 index 8c054fee..00000000 --- a/new_editor/include/XCEditor/Windowing/FrameReason.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class FrameReason : std::uint8_t { - Unknown = 0, - SteadyTick, - PaintValidation, - Resize, - DpiChange, - InteractionContinuation, - ContentInvalidation, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowCaptureDemand.h b/new_editor/include/XCEditor/Windowing/WindowCaptureDemand.h deleted file mode 100644 index 9e74a740..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowCaptureDemand.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowCaptureDemand { - bool shellInteractive = false; - bool hostedContent = false; - - bool HasAny() const { - return shellInteractive || hostedContent; - } -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowCommand.h b/new_editor/include/XCEditor/Windowing/WindowCommand.h deleted file mode 100644 index 51fde4f4..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowCommand.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowCommand { - enum class Type : std::uint8_t { - None = 0, - DestroyNativeWindow, - ShowWindow, - FocusWindow, - ResizeWindow, - MoveWindow, - SetWindowTitle, - SetWindowBounds, - MinimizeWindow, - CloseWindow, - BeginCaptionDrag, - }; - - enum class BoundsMode : std::uint8_t { - Default = 0, - InteractiveResizeNoRedraw, - }; - - Type type = Type::None; - BoundsMode boundsMode = BoundsMode::Default; - std::string payload = {}; - std::int32_t x = 0; - std::int32_t y = 0; - std::int32_t width = 0; - std::int32_t height = 0; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowContentOutput.h b/new_editor/include/XCEditor/Windowing/WindowContentOutput.h deleted file mode 100644 index 1ea826d0..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowContentOutput.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "WindowCaptureDemand.h" -#include "WindowCursorType.h" -#include "WindowTitleBarMode.h" -#include "WindowIntent.h" - -#include -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowContentOutput { - std::optional cursorType = {}; - std::optional captureDemand = {}; - std::optional titleBarMode = {}; - std::string statusText = {}; - std::vector intents = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowCursorType.h b/new_editor/include/XCEditor/Windowing/WindowCursorType.h deleted file mode 100644 index df8f917d..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowCursorType.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class WindowCursorType : std::uint8_t { - Default = 0, - Arrow, - IBeam, - Crosshair, - Hand, - ResizeEW, - ResizeNS, - ResizeNWSE, - ResizeNESW, - NotAllowed, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowEvent.h b/new_editor/include/XCEditor/Windowing/WindowEvent.h deleted file mode 100644 index eef30672..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowEvent.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "FrameReason.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowEvent { - enum class Type : std::uint8_t { - Unknown = 0, - NativeAttached, - NativeDestroyed, - CloseRequested, - FocusGained, - FocusLost, - ClientResized, - DpiChanged, - InteractiveResizeStarted, - InteractiveResizeEnded, - PaintRequested, - FramePresented, - }; - - Type type = Type::Unknown; - FrameReason frameReason = FrameReason::Unknown; - std::uint32_t width = 0u; - std::uint32_t height = 0u; - float dpiScale = 1.0f; - std::string payload = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowId.h b/new_editor/include/XCEditor/Windowing/WindowId.h deleted file mode 100644 index a3cfa607..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowId.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowId { - std::string value = {}; - - WindowId() = default; - explicit WindowId(std::string windowId) - : value(std::move(windowId)) {} - - bool empty() const { - return value.empty(); - } - - auto operator<=>(const WindowId&) const = default; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain - -template <> -struct std::hash { - std::size_t operator()(const XCEngine::UI::Editor::Windowing::Domain::WindowId& value) const noexcept { - return std::hash{}(value.value); - } -}; diff --git a/new_editor/include/XCEditor/Windowing/WindowIntent.h b/new_editor/include/XCEditor/Windowing/WindowIntent.h deleted file mode 100644 index 3a855a59..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowIntent.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "FramePriority.h" -#include "FrameReason.h" - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -struct WindowIntent { - enum class Type : std::uint8_t { - None = 0, - RequestFrame, - }; - - Type type = Type::None; - FramePriority framePriority = FramePriority::Normal; - FrameReason frameReason = FrameReason::Unknown; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowState.h b/new_editor/include/XCEditor/Windowing/WindowState.h deleted file mode 100644 index b8920ff4..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowState.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once - -#include "FramePriority.h" -#include "WindowCaptureDemand.h" -#include "WindowCursorType.h" -#include "WindowId.h" -#include "WindowType.h" -#include "WindowTitleBarMode.h" - -#include -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class WindowLifecycleState : std::uint8_t { - PendingCreate = 0, - NativeAttached, - Initializing, - Running, - Closing, - Destroyed, -}; - -struct WindowIdentityState { - WindowId windowId = {}; - WindowType windowType = WindowType::Unknown; -}; - -struct WindowPresentationState { - std::wstring title = {}; - float dpiScale = 1.0f; - bool focused = false; - bool visible = false; - bool minimized = false; -}; - -struct WindowSizeState { - std::uint32_t clientPixelWidth = 0u; - std::uint32_t clientPixelHeight = 0u; - std::uint32_t predictedClientPixelWidth = 0u; - std::uint32_t predictedClientPixelHeight = 0u; -}; - -struct WindowChromeState { - bool interactiveResize = false; -}; - -struct WindowFrameState { - bool needsFrame = false; - FramePriority priority = FramePriority::Normal; - std::uint64_t frameSerial = 0u; - std::uint64_t resizeEpoch = 0u; -}; - -struct WindowContentState { - WindowCursorType cursorType = WindowCursorType::Arrow; - WindowCaptureDemand captureDemand = {}; - WindowTitleBarMode titleBarMode = WindowTitleBarMode::SystemChrome; - std::string statusText = {}; -}; - -struct WindowState { - WindowIdentityState identity = {}; - WindowLifecycleState lifecycle = WindowLifecycleState::PendingCreate; - WindowPresentationState presentation = {}; - WindowSizeState size = {}; - WindowChromeState chrome = {}; - WindowFrameState frame = {}; - WindowContentState content = {}; -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowTitleBarMode.h b/new_editor/include/XCEditor/Windowing/WindowTitleBarMode.h deleted file mode 100644 index 46ef922e..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowTitleBarMode.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class WindowTitleBarMode : std::uint8_t { - SystemChrome = 0, - DetachedTabStrip, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain diff --git a/new_editor/include/XCEditor/Windowing/WindowType.h b/new_editor/include/XCEditor/Windowing/WindowType.h deleted file mode 100644 index 0a47a924..00000000 --- a/new_editor/include/XCEditor/Windowing/WindowType.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -namespace XCEngine::UI::Editor::Windowing::Domain { - -enum class WindowType : std::uint8_t { - Unknown = 0, - PrimaryWorkspace, - DetachedWorkspace, - Utility, -}; - -} // namespace XCEngine::UI::Editor::Windowing::Domain