Refactor editor rendering contracts

This commit is contained in:
2026-04-28 02:57:49 +08:00
parent 3bc0cfcf08
commit b1ae6c462d
47 changed files with 798 additions and 377 deletions

View File

@@ -6,7 +6,9 @@
#include "EditorUtilityWindowRegistry.h"
#include "EditorWorkspacePanelRegistry.h"
#include "EditorWindowManager.h"
#include "Assets/EditorIconServiceFactory.h"
#include "Diagnostics/Win32CrashTrace.h"
#include "Viewport/EditorViewportRuntimeServicesFactory.h"
#include "System/Win32SystemInteractionHost.h"
#include "Resources/Win32EditorResourceService.h"
#include "Windowing/EditorWindow.h"
@@ -153,7 +155,9 @@ bool Application::Initialize(HINSTANCE hInstance, int nCmdShow) {
std::make_unique<Host::D3D12EditorWindowRenderRuntimeFactory>();
App::EditorWorkspaceShellRuntimeFactory workspaceShellRuntimeFactory = []() {
return App::CreateEditorWorkspaceShellRuntime(
App::CreateEditorWorkspacePanelRuntimeSet());
App::CreateEditorWorkspacePanelRuntimeSet(),
App::CreateEditorIconService(),
App::CreateEditorViewportRuntimeServices());
};
m_windowManager = std::make_unique<App::EditorWindowManager>(
*m_editorContext,

View File

@@ -14,3 +14,13 @@ IDR_PNG_LOGO_ICON PNG "../resources/Icons/logo_icon.png"
IDR_PNG_PLAY_BUTTON_ICON PNG "../resources/Icons/play_button.png"
IDR_PNG_PAUSE_BUTTON_ICON PNG "../resources/Icons/pause_button.png"
IDR_PNG_STEP_BUTTON_ICON PNG "../resources/Icons/step_button.png"
IDR_PNG_VIEW_MOVE_TOOL_ICON PNG "../resources/Icons/view_move_tool.png"
IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/view_move_tool_on.png"
IDR_PNG_MOVE_TOOL_ICON PNG "../resources/Icons/move_tool.png"
IDR_PNG_MOVE_TOOL_ACTIVE_ICON PNG "../resources/Icons/move_tool_on.png"
IDR_PNG_ROTATE_TOOL_ICON PNG "../resources/Icons/rotate_tool.png"
IDR_PNG_ROTATE_TOOL_ACTIVE_ICON PNG "../resources/Icons/rotate_tool_on.png"
IDR_PNG_SCALE_TOOL_ICON PNG "../resources/Icons/scale_tool.png"
IDR_PNG_SCALE_TOOL_ACTIVE_ICON PNG "../resources/Icons/scale_tool_on.png"
IDR_PNG_TRANSFORM_TOOL_ICON PNG "../resources/Icons/transform_tool.png"
IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON PNG "../resources/Icons/transform_tool_on.png"

View File

@@ -14,3 +14,13 @@
#define IDR_PNG_PLAY_BUTTON_ICON 210
#define IDR_PNG_PAUSE_BUTTON_ICON 211
#define IDR_PNG_STEP_BUTTON_ICON 212
#define IDR_PNG_VIEW_MOVE_TOOL_ICON 213
#define IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON 214
#define IDR_PNG_MOVE_TOOL_ICON 215
#define IDR_PNG_MOVE_TOOL_ACTIVE_ICON 216
#define IDR_PNG_ROTATE_TOOL_ICON 217
#define IDR_PNG_ROTATE_TOOL_ACTIVE_ICON 218
#define IDR_PNG_SCALE_TOOL_ICON 219
#define IDR_PNG_SCALE_TOOL_ACTIVE_ICON 220
#define IDR_PNG_TRANSFORM_TOOL_ICON 221
#define IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON 222

View File

@@ -6,7 +6,7 @@
#include <utility>
#include "Panels/EditorPanelIds.h"
#include <XCEngine/Input/InputTypes.h>
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
namespace XCEngine::UI::Editor::App {

View File

@@ -1,7 +1,7 @@
#include "EditorShellDrawComposer.h"
#include "WorkspacePanels/EditorWorkspacePanelRuntime.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
@@ -18,16 +18,16 @@ using ::XCEngine::UI::UIDrawList;
class BuiltInIconResolver final : public UIEditorShellIconResolver {
public:
explicit BuiltInIconResolver(const BuiltInIcons& icons)
: m_icons(icons) {}
explicit BuiltInIconResolver(const EditorIconService& iconService)
: m_iconService(iconService) {}
const ::XCEngine::UI::UITextureHandle* TryResolveIcon(
std::uint8_t iconKind) const override {
return &m_icons.Resolve(static_cast<BuiltInIconKind>(iconKind));
return &m_iconService.Resolve(static_cast<BuiltInIconKind>(iconKind));
}
private:
const BuiltInIcons& m_icons;
const EditorIconService& m_iconService;
};
UIEditorShellComposeModel BuildShellComposeModelFromFrame(
@@ -90,7 +90,7 @@ void EditorShellDrawComposer::Append(
const auto& palette = ResolveUIEditorShellInteractionPalette();
const UIEditorShellComposeModel shellComposeModel =
BuildShellComposeModelFromFrame(context.shellFrame);
const BuiltInIconResolver iconResolver(context.builtInIcons);
const BuiltInIconResolver iconResolver(context.iconService);
AppendDrawPacket(
drawData,

View File

@@ -11,13 +11,13 @@ struct UIEditorShellInteractionState;
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorIconService;
class EditorWorkspacePanelRuntimeSet;
struct EditorShellDrawComposerContext {
const UIEditorShellInteractionFrame& shellFrame;
const UIEditorShellInteractionState& shellInteractionState;
const BuiltInIcons& builtInIcons;
const EditorIconService& iconService;
const EditorWorkspacePanelRuntimeSet& workspacePanels;
};

View File

@@ -18,7 +18,7 @@ bool IsViewportPanel(std::string_view panelId) {
}
void ApplyViewportFrameToPresentation(
const ViewportFrame& viewportFrame,
const EditorViewportFrame& viewportFrame,
UIEditorWorkspacePanelPresentationModel& presentation) {
presentation.viewportShellModel.frame.texture = viewportFrame.texture;
presentation.viewportShellModel.frame.requestedSize = viewportFrame.requestedSize;
@@ -28,7 +28,7 @@ void ApplyViewportFrameToPresentation(
}
void ApplyViewportFrameToShellModel(
const ViewportFrame& viewportFrame,
const EditorViewportFrame& viewportFrame,
UIEditorViewportShellModel& shellModel) {
shellModel.frame.texture = viewportFrame.texture;
shellModel.frame.requestedSize = viewportFrame.requestedSize;
@@ -51,7 +51,7 @@ UIEditorWorkspacePanelPresentationModel* FindMutableWorkspacePresentation(
void ApplyViewportFramesToShellFrame(
UIEditorShellInteractionFrame& shellFrame,
ViewportHostService& viewportHostService) {
EditorViewportRuntimeServices& viewportRuntimeServices) {
auto applyToViewportFrames =
[&](std::vector<UIEditorWorkspaceViewportComposeFrame>& viewportFrames) {
for (UIEditorWorkspaceViewportComposeFrame& viewportComposeFrame : viewportFrames) {
@@ -59,8 +59,8 @@ void ApplyViewportFramesToShellFrame(
continue;
}
const ViewportFrame viewportFrame =
viewportHostService.RequestViewport(
const EditorViewportFrame viewportFrame =
viewportRuntimeServices.RequestViewport(
viewportComposeFrame.panelId,
viewportComposeFrame.viewportShellFrame.requestedViewportSize);
ApplyViewportFrameToShellModel(
@@ -128,7 +128,7 @@ void EditorShellInteractionEngine::Update(
const Widgets::UIEditorDockHostLayout preUpdateDockLayout =
context.shellFrame.workspaceInteractionFrame.dockHostFrame.layout;
context.viewportHostService.BeginFrame();
context.viewportRuntimeServices.BeginFrame();
const std::vector<UIInputEvent> shellEvents =
context.hostedContentCaptureActive
? FilterShellInputEventsForHostedContentCapture(context.inputEvents)
@@ -160,7 +160,7 @@ void EditorShellInteractionEngine::Update(
metrics);
}
ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportHostService);
ApplyViewportFramesToShellFrame(context.shellFrame, context.viewportRuntimeServices);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Viewport/ViewportHostService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
@@ -33,7 +33,7 @@ struct EditorShellInteractionEngineContext {
bool useDetachedTitleBarTabStrip = false;
float detachedTitleBarTabHeight = 0.0f;
float detachedWindowChromeHeight = 0.0f;
ViewportHostService& viewportHostService;
EditorViewportRuntimeServices& viewportRuntimeServices;
};
class EditorShellInteractionEngine final {

View File

@@ -4,40 +4,57 @@
#include <XCEditor/Shell/UIEditorShellCapturePolicy.h>
#include <XCEngine/Rendering/RenderContext.h>
#include <cassert>
#include <utility>
namespace XCEngine::UI::Editor::App {
EditorShellRuntime::EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels)
: m_workspacePanels(std::move(workspacePanels)) {}
EditorShellRuntime::EditorShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices)
: m_iconService(std::move(iconService))
, m_viewportRuntimeServices(std::move(viewportRuntimeServices))
, m_workspacePanels(std::move(workspacePanels)) {}
void EditorShellRuntime::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
Host::EditorHostResourceService& resourceService,
UIEditorTextMeasurer& textMeasurer) {
m_textureHost = &textureHost;
m_builtInIcons.Initialize(textureHost, resourceService);
assert(m_iconService != nullptr);
assert(m_viewportRuntimeServices != nullptr);
if (m_iconService == nullptr || m_viewportRuntimeServices == nullptr) {
return;
}
m_iconService->Initialize(textureHost, resourceService);
m_viewportRuntimeServices->Initialize(repoRoot);
m_workspacePanels.Initialize(
EditorWorkspacePanelInitializationContext{
.repoRoot = repoRoot,
.textureHost = textureHost,
.textMeasurer = textMeasurer,
.builtInIcons = m_builtInIcons,
.viewportHostService = m_viewportHostService,
.iconService = *m_iconService,
.sceneViewportRuntime = &m_viewportRuntimeServices->GetSceneViewportRuntime(),
});
}
void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) {
m_viewportHostService.AttachWindowRenderer(renderer);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->AttachWindowRenderer(renderer);
}
}
void EditorShellRuntime::DetachViewportWindowRenderer() {
m_viewportHostService.DetachWindowRenderer();
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->DetachWindowRenderer();
}
}
void EditorShellRuntime::SetViewportSurfacePresentationEnabled(bool enabled) {
m_viewportHostService.SetSurfacePresentationEnabled(enabled);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->SetSurfacePresentationEnabled(enabled);
}
}
void EditorShellRuntime::Shutdown() {
@@ -45,20 +62,14 @@ void EditorShellRuntime::Shutdown() {
m_shellInteractionState = {};
m_splitterDragCorrectionState = {};
m_traceEntries.clear();
if (m_textureHost != nullptr) {
m_workspacePanels.Shutdown(
EditorWorkspacePanelShutdownContext{
.textureHost = *m_textureHost,
.viewportHostService = m_viewportHostService,
});
m_workspacePanels = {};
m_builtInIcons.Shutdown();
m_textureHost = nullptr;
} else {
m_workspacePanels = {};
m_builtInIcons.Shutdown();
m_workspacePanels.Shutdown(EditorWorkspacePanelShutdownContext{});
m_workspacePanels = {};
if (m_iconService != nullptr) {
m_iconService->Shutdown();
}
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->Shutdown();
}
m_viewportHostService.Shutdown();
}
void EditorShellRuntime::ResetInteractionState() {
@@ -82,7 +93,8 @@ const std::vector<WorkspaceTraceEntry>& EditorShellRuntime::GetTraceEntries() co
}
const std::string& EditorShellRuntime::GetBuiltInIconError() const {
return m_builtInIcons.GetLastError();
static const std::string kEmptyError = {};
return m_iconService != nullptr ? m_iconService->GetLastError() : kEmptyError;
}
void EditorShellRuntime::SetExternalDockHostDropPreview(
@@ -144,8 +156,13 @@ bool EditorShellRuntime::HasInteractiveCapture() const {
}
std::unique_ptr<EditorWorkspaceShellRuntime> CreateEditorWorkspaceShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels) {
return std::make_unique<EditorShellRuntime>(std::move(workspacePanels));
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices) {
return std::make_unique<EditorShellRuntime>(
std::move(workspacePanels),
std::move(iconService),
std::move(viewportRuntimeServices));
}
} // namespace XCEngine::UI::Editor::App
@@ -154,15 +171,21 @@ namespace XCEngine::UI::Editor::App {
void EditorShellRuntime::RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) {
m_viewportHostService.RenderRequestedViewports(renderContext);
if (m_viewportRuntimeServices != nullptr) {
m_viewportRuntimeServices->RenderRequestedViewports(renderContext);
}
}
void EditorShellRuntime::Append(::XCEngine::UI::UIDrawData& drawData) const {
if (m_iconService == nullptr) {
return;
}
m_drawComposer.Append(
EditorShellDrawComposerContext{
.shellFrame = m_shellFrame,
.shellInteractionState = m_shellInteractionState,
.builtInIcons = m_builtInIcons,
.iconService = *m_iconService,
.workspacePanels = m_workspacePanels,
},
drawData);
@@ -182,6 +205,10 @@ void EditorShellRuntime::Update(
bool useDetachedTitleBarTabStrip,
float detachedTitleBarTabHeight,
float detachedWindowChromeHeight) {
if (m_viewportRuntimeServices == nullptr) {
return;
}
const auto buildDefinition = [&]() {
return m_sessionCoordinator.PrepareShellDefinition(
EditorShellSessionCoordinatorContext{
@@ -206,7 +233,7 @@ void EditorShellRuntime::Update(
.useDetachedTitleBarTabStrip = useDetachedTitleBarTabStrip,
.detachedTitleBarTabHeight = detachedTitleBarTabHeight,
.detachedWindowChromeHeight = detachedWindowChromeHeight,
.viewportHostService = m_viewportHostService,
.viewportRuntimeServices = *m_viewportRuntimeServices,
});
m_sessionCoordinator.FinalizeFrame(frameServices, workspaceController, m_shellFrame.result);

View File

@@ -4,10 +4,10 @@
#include "EditorShellHostedPanelCoordinator.h"
#include "EditorShellInteractionEngine.h"
#include "EditorShellSessionCoordinator.h"
#include "Assets/EditorIconService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include "Windowing/EditorWorkspaceShellRuntime.h"
#include "WorkspacePanels/EditorWorkspacePanelRuntime.h"
#include "Assets/BuiltInIcons.h"
#include "Viewport/ViewportHostService.h"
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
@@ -45,8 +45,10 @@ namespace XCEngine::UI::Editor::App {
class EditorShellRuntime final : public EditorWorkspaceShellRuntime {
public:
EditorShellRuntime() = default;
explicit EditorShellRuntime(EditorWorkspacePanelRuntimeSet workspacePanels);
EditorShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices);
void Initialize(
const std::filesystem::path& repoRoot,
@@ -95,9 +97,8 @@ public:
bool HasInteractiveCapture() const override;
private:
ViewportHostService m_viewportHostService = {};
BuiltInIcons m_builtInIcons = {};
Rendering::Host::UiTextureHost* m_textureHost = nullptr;
std::unique_ptr<EditorIconService> m_iconService = {};
std::unique_ptr<EditorViewportRuntimeServices> m_viewportRuntimeServices = {};
EditorWorkspacePanelRuntimeSet m_workspacePanels = {};
UIEditorShellInteractionState m_shellInteractionState = {};
UIEditorShellInteractionFrame m_shellFrame = {};
@@ -110,7 +111,9 @@ private:
};
std::unique_ptr<EditorWorkspaceShellRuntime> CreateEditorWorkspaceShellRuntime(
EditorWorkspacePanelRuntimeSet workspacePanels);
EditorWorkspacePanelRuntimeSet workspacePanels,
std::unique_ptr<EditorIconService> iconService,
std::unique_ptr<EditorViewportRuntimeServices> viewportRuntimeServices);
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,60 @@
#pragma once
#include "HostFwd.h"
#include <XCEngine/UI/Types.h>
#include <cstdint>
#include <filesystem>
#include <string>
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
enum class BuiltInIconKind : std::uint8_t {
Folder = 0,
GameObject,
Scene,
CameraGizmo,
DirectionalLightGizmo,
PointLightGizmo,
SpotLightGizmo,
PlayButton,
PauseButton,
StepButton,
ViewMoveTool,
ViewMoveToolActive,
MoveTool,
MoveToolActive,
RotateTool,
RotateToolActive,
ScaleTool,
ScaleToolActive,
TransformTool,
TransformToolActive
};
class EditorIconService {
public:
virtual ~EditorIconService() = default;
virtual void Initialize(
Rendering::Host::UiTextureHost& renderer,
Host::EditorHostResourceService& resourceService) = 0;
virtual void Shutdown() = 0;
virtual void BeginFrame() = 0;
[[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle& Resolve(
BuiltInIconKind kind) const = 0;
[[nodiscard]] virtual const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot) = 0;
[[nodiscard]] virtual const std::string& GetLastError() const = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,41 @@
#pragma once
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <XCEngine/UI/Types.h>
#include <cstdint>
namespace XCEngine::UI::Editor::App {
enum class ViewportObjectIdPickStatus : std::uint8_t {
Unavailable = 0,
Success,
ReadbackFailed
};
struct ViewportObjectIdPickResult {
ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable;
std::uint64_t frameSerial = 0u;
::XCEngine::Rendering::RenderObjectId renderObjectId =
::XCEngine::Rendering::kInvalidRenderObjectId;
std::uint64_t resolvedEntityId = 0u;
bool HasResolvedSample() const {
return status == ViewportObjectIdPickStatus::Success;
}
bool HasResolvedEntity() const {
return HasResolvedSample() && resolvedEntityId != 0u;
}
};
class IViewportObjectPickerService {
public:
virtual ~IViewportObjectPickerService() = default;
virtual ViewportObjectIdPickResult PickObject(
const ::XCEngine::UI::UISize& viewportSize,
const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,50 @@
#pragma once
#include "Scene/SceneViewportRenderRequest.h"
#include "Viewport/EditorViewportPicking.h"
#include "Viewport/EditorViewportTypes.h"
#include <filesystem>
#include <string_view>
namespace XCEngine::Rendering {
class RenderContext;
} // namespace XCEngine::Rendering
namespace XCEngine::UI::Editor::Rendering::Host {
class ViewportRenderHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class EditorSceneViewportRuntime {
public:
virtual ~EditorSceneViewportRuntime() = default;
virtual void SetRenderRequest(SceneViewportRenderRequest request) = 0;
[[nodiscard]] virtual const IViewportObjectPickerService& GetObjectPicker() const = 0;
};
class EditorViewportRuntimeServices {
public:
virtual ~EditorViewportRuntimeServices() = default;
virtual void Initialize(const std::filesystem::path& repoRoot) = 0;
virtual void Shutdown() = 0;
virtual void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) = 0;
virtual void DetachWindowRenderer() = 0;
virtual void SetSurfacePresentationEnabled(bool enabled) = 0;
virtual void BeginFrame() = 0;
[[nodiscard]] virtual EditorViewportFrame RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize) = 0;
virtual void RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext) = 0;
[[nodiscard]] virtual EditorSceneViewportRuntime& GetSceneViewportRuntime() = 0;
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,24 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <string>
namespace XCEngine::UI::Editor::App {
struct EditorViewportResourceRequirements {
bool requiresDepthSampling = false;
bool requiresObjectIdSurface = false;
bool requiresSelectionMaskSurface = false;
};
struct EditorViewportFrame {
::XCEngine::UI::UITextureHandle texture = {};
::XCEngine::UI::UISize requestedSize = {};
::XCEngine::UI::UISize renderSize = {};
bool hasTexture = false;
bool wasRequested = false;
std::string statusText = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,8 +1,10 @@
#pragma once
#include "Assets/EditorIconService.h"
#include "Commands/EditorEditCommandRoute.h"
#include "State/EditorSession.h"
#include "Panels/EditorPanelServices.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
#include <XCEditor/Panels/UIEditorHostedPanelDispatch.h>
@@ -25,17 +27,8 @@ struct UIInputEvent;
} // namespace XCEngine::UI
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class ViewportHostService;
enum class EditorWorkspacePanelCursorKind : std::uint8_t {
Arrow = 0,
ResizeEW
@@ -54,16 +47,12 @@ struct EditorWorkspacePanelFrameEvent {
struct EditorWorkspacePanelInitializationContext {
const std::filesystem::path& repoRoot;
Rendering::Host::UiTextureHost& textureHost;
UIEditorTextMeasurer& textMeasurer;
BuiltInIcons& builtInIcons;
ViewportHostService& viewportHostService;
EditorIconService& iconService;
EditorSceneViewportRuntime* sceneViewportRuntime = nullptr;
};
struct EditorWorkspacePanelShutdownContext {
Rendering::Host::UiTextureHost& textureHost;
ViewportHostService& viewportHostService;
};
struct EditorWorkspacePanelShutdownContext {};
struct EditorWorkspacePanelUpdateContext {
EditorPanelServices& services;

View File

@@ -7,8 +7,6 @@
#include "Project/ProjectPanel.h"
#include "Scene/SceneEditCommandRoute.h"
#include "Scene/SceneViewportFeature.h"
#include "Assets/BuiltInIcons.h"
#include "Viewport/ViewportHostService.h"
#include <XCEditor/Panels/UIEditorHostedPanelDispatch.h>
@@ -219,7 +217,7 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_panel.SetBuiltInIcons(&context.builtInIcons);
m_panel.SetIconService(&context.iconService);
m_panel.SetTextMeasurer(&context.textMeasurer);
m_panel.Initialize();
}
@@ -330,7 +328,7 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_panel.SetBuiltInIcons(&context.builtInIcons);
m_panel.SetIconService(&context.iconService);
m_panel.SetTextMeasurer(&context.textMeasurer);
}
@@ -406,15 +404,16 @@ public:
}
void Initialize(const EditorWorkspacePanelInitializationContext& context) override {
m_feature.Initialize(
context.repoRoot,
context.textureHost,
&context.builtInIcons,
context.viewportHostService);
if (context.sceneViewportRuntime != nullptr) {
m_feature.Initialize(
&context.iconService,
*context.sceneViewportRuntime);
}
}
void Shutdown(const EditorWorkspacePanelShutdownContext& context) override {
m_feature.Shutdown(context.textureHost, context.viewportHostService);
(void)context;
m_feature.Shutdown();
m_commandRoute.BindSceneRuntime(nullptr);
}

View File

@@ -1,5 +1,5 @@
#include "HierarchyPanel.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Foundation/UIEditorPanelInputFilter.h>
#include <XCEditor/Foundation/UIEditorTheme.h>
#include "EditorSceneRuntime.h"
@@ -15,13 +15,13 @@ using ::XCEngine::UI::UIColor;
inline constexpr float kDragThreshold = 4.0f;
inline constexpr UIColor kDragPreviewColor(0.92f, 0.92f, 0.92f, 0.42f);
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons);
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons);
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveGameObjectIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::GameObject)
: ::XCEngine::UI::UITextureHandle {};
@@ -80,7 +80,7 @@ void HierarchyPanel::SetCommandFocusService(
m_commandFocusService = commandFocusService;
}
void HierarchyPanel::SetBuiltInIcons(const BuiltInIcons* icons) {
void HierarchyPanel::SetIconService(const EditorIconService* icons) {
m_icons = icons;
RebuildItems();
}

View File

@@ -20,8 +20,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorCommandFocusService;
class EditorIconService;
class EditorSceneRuntime;
class HierarchyPanel final : public EditorEditCommandRoute {
@@ -44,7 +44,7 @@ public:
void Initialize();
void SetSceneRuntime(EditorSceneRuntime* sceneRuntime);
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SetBuiltInIcons(const BuiltInIcons* icons);
void SetIconService(const EditorIconService* icons);
void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer);
void ResetInteractionState();
void Update(
@@ -90,7 +90,7 @@ private:
const std::vector<Widgets::UIEditorTreeViewItem>& GetPresentedTreeItems() const;
const ::XCEngine::UI::Widgets::UIExpansionModel& GetPresentedExpansionModel() const;
const BuiltInIcons* m_icons = nullptr;
const EditorIconService* m_icons = nullptr;
EditorCommandFocusService* m_commandFocusService = nullptr;
EditorSceneRuntime* m_sceneRuntime = nullptr;
HierarchyModel m_model = {};

View File

@@ -1,5 +1,5 @@
#include "ProjectPanel.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include <XCEditor/Collections/UIEditorScrollView.h>
#include <XCEditor/Collections/UIEditorTreeView.h>
#include <XCEditor/Foundation/UIEditorTheme.h>
@@ -71,7 +71,7 @@ float MeasureTextWidth(
const UIEditorTextMeasurer* textMeasurer,
std::string_view text,
float fontSize);
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons);
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons);
float ClampNavigationWidth(float value, float totalWidth);
UIRect ComputeFittedTextureRect(
const UIRect& bounds,
@@ -129,7 +129,7 @@ float MeasureTextWidth(
return static_cast<float>(text.size()) * fontSize * 0.56f;
}
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveFolderIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::Folder)
: ::XCEngine::UI::UITextureHandle {};
@@ -425,7 +425,7 @@ void ProjectPanel::SetSystemInteractionHost(
m_systemInteractionHost = systemInteractionHost;
}
void ProjectPanel::SetBuiltInIcons(BuiltInIcons* icons) {
void ProjectPanel::SetIconService(EditorIconService* icons) {
m_icons = icons;
RebuildWindowTreeItems();
}

View File

@@ -29,8 +29,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorCommandFocusService;
class EditorIconService;
} // namespace XCEngine::UI::Editor::App
@@ -86,7 +86,7 @@ public:
void SetProjectRuntime(EditorProjectRuntime* projectRuntime);
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost);
void SetBuiltInIcons(BuiltInIcons* icons);
void SetIconService(EditorIconService* icons);
void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer);
void ResetInteractionState();
void Update(
@@ -254,7 +254,7 @@ private:
EditorProjectRuntime* m_projectRuntime = nullptr;
EditorCommandFocusService* m_commandFocusService = nullptr;
System::SystemInteractionService* m_systemInteractionHost = nullptr;
BuiltInIcons* m_icons = nullptr;
EditorIconService* m_icons = nullptr;
const ::XCEngine::UI::Editor::UIEditorTextMeasurer* m_textMeasurer = nullptr;
std::vector<Widgets::UIEditorTreeViewItem> m_windowTreeItems = {};
::XCEngine::UI::Widgets::UISelectionModel m_folderSelection = {};

View File

@@ -1,6 +1,6 @@
#include "Scene/SceneViewportController.h"
#include "Viewport/ViewportObjectPickerService.h"
#include "Viewport/EditorViewportPicking.h"
#include "EditorSceneRuntime.h"
#include "State/EditorCommandFocusService.h"
@@ -136,17 +136,15 @@ void ApplySceneViewportToggleButton(
} // namespace
void SceneViewportController::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons) {
m_toolOverlay.Initialize(repoRoot, renderer);
m_sceneOverlay.SetBuiltInIcons(builtInIcons);
void SceneViewportController::Initialize(const EditorIconService* iconService) {
m_toolOverlay.SetIconService(iconService);
m_sceneOverlay.SetIconService(iconService);
ResetInteractionState();
}
void SceneViewportController::Shutdown(Rendering::Host::UiTextureHost& renderer) {
m_toolOverlay.Shutdown(renderer);
void SceneViewportController::Shutdown() {
m_toolOverlay.SetIconService(nullptr);
m_sceneOverlay.SetIconService(nullptr);
ResetInteractionState();
}

View File

@@ -10,32 +10,18 @@
#include <XCEngine/UI/Types.h>
#include <chrono>
#include <filesystem>
namespace XCEngine::UI::Editor::App {
class EditorCommandFocusService;
class BuiltInIcons;
class EditorIconService;
class EditorSceneRuntime;
class IViewportObjectPickerService;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class SceneViewportController {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void Initialize(const EditorIconService* iconService);
void Shutdown();
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);

View File

@@ -1,33 +1,20 @@
#include "Scene/SceneViewportFeature.h"
#include "Panels/EditorPanelIds.h"
#include "UiTextureHost.h"
#include "Viewport/SceneViewportResourcePaths.h"
#include "Viewport/ViewportHostService.h"
#include "EditorSceneRuntime.h"
#include "State/EditorCommandFocusService.h"
namespace XCEngine::UI::Editor::App {
void SceneViewportFeature::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService) {
m_renderService.Initialize(BuildSceneViewportShaderPaths(repoRoot));
viewportHostService.SetContentRenderer(
kScenePanelId,
&m_renderService,
SceneViewportRenderService::GetViewportResourceRequirements());
m_controller.Initialize(repoRoot, textureHost, builtInIcons);
const EditorIconService* iconService,
EditorSceneViewportRuntime& sceneViewportRuntime) {
m_sceneViewportRuntime = &sceneViewportRuntime;
m_controller.Initialize(iconService);
}
void SceneViewportFeature::Shutdown(
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService) {
viewportHostService.SetContentRenderer(kScenePanelId, nullptr, {});
m_controller.Shutdown(textureHost);
m_renderService.Shutdown();
void SceneViewportFeature::Shutdown() {
m_controller.Shutdown();
m_sceneViewportRuntime = nullptr;
}
void SceneViewportFeature::ResetInteractionState() {
@@ -40,17 +27,23 @@ void SceneViewportFeature::SetCommandFocusService(
}
void SceneViewportFeature::SyncRenderRequest(EditorSceneRuntime& sceneRuntime) {
m_renderService.SetRenderRequest(
sceneRuntime.BuildSceneViewportRenderRequest());
if (m_sceneViewportRuntime != nullptr) {
m_sceneViewportRuntime->SetRenderRequest(
sceneRuntime.BuildSceneViewportRenderRequest());
}
}
void SceneViewportFeature::Update(
EditorSceneRuntime& sceneRuntime,
const UIEditorWorkspaceComposeState& composeState,
const UIEditorWorkspaceComposeFrame& composeFrame) {
if (m_sceneViewportRuntime == nullptr) {
return;
}
m_controller.Update(
sceneRuntime,
m_renderService,
m_sceneViewportRuntime->GetObjectPicker(),
composeState,
composeFrame);
SyncRenderRequest(sceneRuntime);

View File

@@ -1,42 +1,24 @@
#pragma once
#include "Assets/EditorIconService.h"
#include "Scene/SceneViewportController.h"
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/EditorViewportRuntimeServices.h"
#include <XCEditor/Workspace/UIEditorWorkspaceCompose.h>
#include <XCEngine/UI/DrawData.h>
#include <filesystem>
namespace XCEngine::UI::Editor::App {
class EditorCommandFocusService;
class BuiltInIcons;
class EditorSceneRuntime;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
class ViewportHostService;
class SceneViewportFeature {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService);
void Shutdown(
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService);
const EditorIconService* iconService,
EditorSceneViewportRuntime& sceneViewportRuntime);
void Shutdown();
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SyncRenderRequest(EditorSceneRuntime& sceneRuntime);
@@ -47,7 +29,7 @@ public:
void Append(::XCEngine::UI::UIDrawList& drawList) const;
private:
SceneViewportRenderService m_renderService = {};
EditorSceneViewportRuntime* m_sceneViewportRuntime = nullptr;
SceneViewportController m_controller = {};
};

View File

@@ -1,7 +1,7 @@
#include "Scene/SceneViewportSceneOverlay.h"
#include "Scene/SceneViewportTransformGizmoSupport.h"
#include "Assets/BuiltInIcons.h"
#include "Assets/EditorIconService.h"
#include "EditorSceneRuntime.h"
#include <XCEngine/Components/CameraComponent.h>
@@ -68,14 +68,14 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData(
return overlay;
}
::XCEngine::UI::UITextureHandle ResolveCameraIcon(const BuiltInIcons* icons) {
::XCEngine::UI::UITextureHandle ResolveCameraIcon(const EditorIconService* icons) {
return icons != nullptr
? icons->Resolve(BuiltInIconKind::CameraGizmo)
: ::XCEngine::UI::UITextureHandle();
}
::XCEngine::UI::UITextureHandle ResolveLightIcon(
const BuiltInIcons* icons,
const EditorIconService* icons,
const LightComponent& light) {
if (icons == nullptr) {
return {};
@@ -95,7 +95,7 @@ SceneViewportGizmoSupport::SceneViewportOverlayData BuildOverlayData(
} // namespace
void SceneViewportSceneOverlay::SetBuiltInIcons(const BuiltInIcons* icons) {
void SceneViewportSceneOverlay::SetIconService(const EditorIconService* icons) {
m_icons = icons;
if (m_icons == nullptr) {
ResetFrame();

View File

@@ -7,8 +7,8 @@
namespace XCEngine::UI::Editor::App {
class BuiltInIcons;
class EditorSceneRuntime;
class EditorIconService;
class SceneViewportSceneOverlay {
public:
@@ -21,7 +21,7 @@ public:
}
};
void SetBuiltInIcons(const BuiltInIcons* icons);
void SetIconService(const EditorIconService* icons);
void ResetFrame();
void Refresh(
EditorSceneRuntime& sceneRuntime,
@@ -42,7 +42,7 @@ public:
};
private:
const BuiltInIcons* m_icons = nullptr;
const EditorIconService* m_icons = nullptr;
Frame m_frame = {};
};

View File

@@ -1,7 +1,5 @@
#include "Scene/SceneViewportToolOverlay.h"
#include "UiTextureHost.h"
#include <XCEditor/Widgets/UIEditorTextLayout.h>
#include <algorithm>
@@ -39,16 +37,16 @@ constexpr float kToggleMinWidth = 60.0f;
struct ToolButtonSpec {
SceneToolMode mode = SceneToolMode::View;
const char* label = "";
const char* inactiveFile = "";
const char* activeFile = "";
BuiltInIconKind inactiveIcon = BuiltInIconKind::ViewMoveTool;
BuiltInIconKind activeIcon = BuiltInIconKind::ViewMoveToolActive;
};
constexpr std::array<ToolButtonSpec, 5> kToolButtonSpecs = {{
{ SceneToolMode::View, "View", "view_move_tool.png", "view_move_tool_on.png" },
{ SceneToolMode::Translate, "Move", "move_tool.png", "move_tool_on.png" },
{ SceneToolMode::Rotate, "Rotate", "rotate_tool.png", "rotate_tool_on.png" },
{ SceneToolMode::Scale, "Scale", "scale_tool.png", "scale_tool_on.png" },
{ SceneToolMode::Transform, "Transform", "transform_tool.png", "transform_tool_on.png" }
{ SceneToolMode::View, "View", BuiltInIconKind::ViewMoveTool, BuiltInIconKind::ViewMoveToolActive },
{ SceneToolMode::Translate, "Move", BuiltInIconKind::MoveTool, BuiltInIconKind::MoveToolActive },
{ SceneToolMode::Rotate, "Rotate", BuiltInIconKind::RotateTool, BuiltInIconKind::RotateToolActive },
{ SceneToolMode::Scale, "Scale", BuiltInIconKind::ScaleTool, BuiltInIconKind::ScaleToolActive },
{ SceneToolMode::Transform, "Transform", BuiltInIconKind::TransformTool, BuiltInIconKind::TransformToolActive }
}};
bool ContainsPoint(const UIRect& rect, const UIPoint& point) {
@@ -198,47 +196,10 @@ UIRect BuildToggleButtonRect(
return kToggleIdle;
}
} // namespace
bool SceneViewportToolOverlay::Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer) {
Shutdown(renderer);
const std::filesystem::path iconRoot =
(repoRoot / "editor" / "resources" / "Icons").lexically_normal();
bool loadedAnyTexture = false;
for (std::size_t index = 0; index < kToolButtonSpecs.size(); ++index) {
const ToolButtonSpec& path = kToolButtonSpecs[index];
ToolTextureSet& textureSet = m_toolTextures[index];
textureSet = {};
textureSet.mode = path.mode;
textureSet.label = path.label;
std::string error = {};
loadedAnyTexture =
renderer.LoadTextureFromFile(
iconRoot / path.inactiveFile,
textureSet.inactiveTexture,
error) || loadedAnyTexture;
error.clear();
loadedAnyTexture =
renderer.LoadTextureFromFile(
iconRoot / path.activeFile,
textureSet.activeTexture,
error) || loadedAnyTexture;
}
return loadedAnyTexture;
}
void SceneViewportToolOverlay::Shutdown(Rendering::Host::UiTextureHost& renderer) {
for (ToolTextureSet& textureSet : m_toolTextures) {
renderer.ReleaseTexture(textureSet.inactiveTexture);
renderer.ReleaseTexture(textureSet.activeTexture);
textureSet = {};
}
void SceneViewportToolOverlay::SetIconService(const EditorIconService* iconService) {
m_iconService = iconService;
ResetFrame();
}
@@ -305,7 +266,6 @@ void SceneViewportToolOverlay::BuildFrame(
for (std::size_t index = 0; index < m_frame.buttons.size(); ++index) {
const ToolButtonSpec& spec = kToolButtonSpecs[index];
const ToolTextureSet& textureSet = m_toolTextures[index];
SceneViewportToolOverlayButtonFrame& button = m_frame.buttons[index];
button = {};
button.mode = spec.mode;
@@ -314,9 +274,10 @@ void SceneViewportToolOverlay::BuildFrame(
button.active = spec.mode == activeMode;
button.hovered = index == hoveredIndex;
button.pressed = index == pressedIndex;
button.texture = spec.mode == activeMode
? textureSet.activeTexture
: textureSet.inactiveTexture;
if (m_iconService != nullptr) {
button.texture = m_iconService->Resolve(
spec.mode == activeMode ? spec.activeIcon : spec.inactiveIcon);
}
}
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "SceneToolState.h"
#include "HostFwd.h"
#include "Assets/EditorIconService.h"
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Types.h>
@@ -9,7 +9,6 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <string>
namespace XCEngine::UI::Editor::App {
@@ -57,10 +56,7 @@ struct SceneViewportToolOverlayFrame {
class SceneViewportToolOverlay {
public:
bool Initialize(
const std::filesystem::path& repoRoot,
Rendering::Host::UiTextureHost& renderer);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void SetIconService(const EditorIconService* iconService);
void ResetFrame();
void BuildFrame(
@@ -82,15 +78,8 @@ public:
const SceneViewportToolOverlayFrame& GetFrame() const;
private:
struct ToolTextureSet {
SceneToolMode mode = SceneToolMode::View;
const char* label = "";
::XCEngine::UI::UITextureHandle inactiveTexture = {};
::XCEngine::UI::UITextureHandle activeTexture = {};
};
std::array<ToolTextureSet, 5> m_toolTextures = {};
SceneViewportToolOverlayFrame m_frame = {};
const EditorIconService* m_iconService = nullptr;
};
void AppendSceneViewportToolOverlay(

View File

@@ -20,6 +20,16 @@ enum class EditorHostPngResourceKind : std::uint8_t {
PlayButtonIcon,
PauseButtonIcon,
StepButtonIcon,
ViewMoveToolIcon,
ViewMoveToolActiveIcon,
MoveToolIcon,
MoveToolActiveIcon,
RotateToolIcon,
RotateToolActiveIcon,
ScaleToolIcon,
ScaleToolActiveIcon,
TransformToolIcon,
TransformToolActiveIcon,
};
struct EditorHostResourceBytes {

View File

@@ -34,6 +34,26 @@ int ResolvePngResourceId(EditorHostPngResourceKind kind) {
return IDR_PNG_PAUSE_BUTTON_ICON;
case EditorHostPngResourceKind::StepButtonIcon:
return IDR_PNG_STEP_BUTTON_ICON;
case EditorHostPngResourceKind::ViewMoveToolIcon:
return IDR_PNG_VIEW_MOVE_TOOL_ICON;
case EditorHostPngResourceKind::ViewMoveToolActiveIcon:
return IDR_PNG_VIEW_MOVE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::MoveToolIcon:
return IDR_PNG_MOVE_TOOL_ICON;
case EditorHostPngResourceKind::MoveToolActiveIcon:
return IDR_PNG_MOVE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::RotateToolIcon:
return IDR_PNG_ROTATE_TOOL_ICON;
case EditorHostPngResourceKind::RotateToolActiveIcon:
return IDR_PNG_ROTATE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::ScaleToolIcon:
return IDR_PNG_SCALE_TOOL_ICON;
case EditorHostPngResourceKind::ScaleToolActiveIcon:
return IDR_PNG_SCALE_TOOL_ACTIVE_ICON;
case EditorHostPngResourceKind::TransformToolIcon:
return IDR_PNG_TRANSFORM_TOOL_ICON;
case EditorHostPngResourceKind::TransformToolActiveIcon:
return IDR_PNG_TRANSFORM_TOOL_ACTIVE_ICON;
default:
return 0;
}

View File

@@ -584,6 +584,76 @@ void BuiltInIcons::Initialize(
"step_button.png",
m_stepButtonIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ViewMoveToolIcon,
"view_move_tool.png",
m_viewMoveToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ViewMoveToolActiveIcon,
"view_move_tool_on.png",
m_viewMoveToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::MoveToolIcon,
"move_tool.png",
m_moveToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::MoveToolActiveIcon,
"move_tool_on.png",
m_moveToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::RotateToolIcon,
"rotate_tool.png",
m_rotateToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::RotateToolActiveIcon,
"rotate_tool_on.png",
m_rotateToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ScaleToolIcon,
"scale_tool.png",
m_scaleToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::ScaleToolActiveIcon,
"scale_tool_on.png",
m_scaleToolActiveIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::TransformToolIcon,
"transform_tool.png",
m_transformToolIcon,
errorStream);
LoadEmbeddedIconTexture(
renderer,
resourceService,
Host::EditorHostPngResourceKind::TransformToolActiveIcon,
"transform_tool_on.png",
m_transformToolActiveIcon,
errorStream);
m_frameIndex = 0;
m_previewLoadsThisFrame = 0;
@@ -605,6 +675,16 @@ void BuiltInIcons::Shutdown() {
m_renderer->ReleaseTexture(m_playButtonIcon);
m_renderer->ReleaseTexture(m_pauseButtonIcon);
m_renderer->ReleaseTexture(m_stepButtonIcon);
m_renderer->ReleaseTexture(m_viewMoveToolIcon);
m_renderer->ReleaseTexture(m_viewMoveToolActiveIcon);
m_renderer->ReleaseTexture(m_moveToolIcon);
m_renderer->ReleaseTexture(m_moveToolActiveIcon);
m_renderer->ReleaseTexture(m_rotateToolIcon);
m_renderer->ReleaseTexture(m_rotateToolActiveIcon);
m_renderer->ReleaseTexture(m_scaleToolIcon);
m_renderer->ReleaseTexture(m_scaleToolActiveIcon);
m_renderer->ReleaseTexture(m_transformToolIcon);
m_renderer->ReleaseTexture(m_transformToolActiveIcon);
}
m_renderer = nullptr;
@@ -944,6 +1024,26 @@ const ::XCEngine::UI::UITextureHandle& BuiltInIcons::Resolve(
return m_pauseButtonIcon;
case BuiltInIconKind::StepButton:
return m_stepButtonIcon;
case BuiltInIconKind::ViewMoveTool:
return m_viewMoveToolIcon;
case BuiltInIconKind::ViewMoveToolActive:
return m_viewMoveToolActiveIcon;
case BuiltInIconKind::MoveTool:
return m_moveToolIcon;
case BuiltInIconKind::MoveToolActive:
return m_moveToolActiveIcon;
case BuiltInIconKind::RotateTool:
return m_rotateToolIcon;
case BuiltInIconKind::RotateToolActive:
return m_rotateToolActiveIcon;
case BuiltInIconKind::ScaleTool:
return m_scaleToolIcon;
case BuiltInIconKind::ScaleToolActive:
return m_scaleToolActiveIcon;
case BuiltInIconKind::TransformTool:
return m_transformToolIcon;
case BuiltInIconKind::TransformToolActive:
return m_transformToolActiveIcon;
default:
return m_folderIcon;
}

View File

@@ -1,8 +1,6 @@
#pragma once
#include "HostFwd.h"
#include <XCEngine/UI/Types.h>
#include "Assets/EditorIconService.h"
#include <condition_variable>
#include <cstdint>
@@ -17,32 +15,19 @@
namespace XCEngine::UI::Editor::App {
enum class BuiltInIconKind : std::uint8_t {
Folder = 0,
GameObject,
Scene,
CameraGizmo,
DirectionalLightGizmo,
PointLightGizmo,
SpotLightGizmo,
PlayButton,
PauseButton,
StepButton
};
class BuiltInIcons {
class BuiltInIcons final : public EditorIconService {
public:
void Initialize(
Rendering::Host::UiTextureHost& renderer,
Host::EditorHostResourceService& resourceService);
void Shutdown();
void BeginFrame();
Host::EditorHostResourceService& resourceService) override;
void Shutdown() override;
void BeginFrame() override;
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const;
const ::XCEngine::UI::UITextureHandle& Resolve(BuiltInIconKind kind) const override;
const ::XCEngine::UI::UITextureHandle* ResolveAssetPreview(
const std::filesystem::path& assetPath,
const std::filesystem::path& projectRoot);
const std::string& GetLastError() const;
const std::filesystem::path& projectRoot) override;
const std::string& GetLastError() const override;
struct LoadedTexturePixels {
std::vector<std::uint8_t> rgbaPixels = {};
@@ -121,6 +106,16 @@ private:
::XCEngine::UI::UITextureHandle m_playButtonIcon = {};
::XCEngine::UI::UITextureHandle m_pauseButtonIcon = {};
::XCEngine::UI::UITextureHandle m_stepButtonIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolIcon = {};
::XCEngine::UI::UITextureHandle m_viewMoveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolIcon = {};
::XCEngine::UI::UITextureHandle m_moveToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolIcon = {};
::XCEngine::UI::UITextureHandle m_rotateToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolIcon = {};
::XCEngine::UI::UITextureHandle m_scaleToolActiveIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolIcon = {};
::XCEngine::UI::UITextureHandle m_transformToolActiveIcon = {};
std::unordered_map<std::string, CachedAssetPreview> m_assetPreviews = {};
std::vector<std::thread> m_previewWorkers = {};
std::deque<PreviewDecodeJob> m_previewDecodeQueue = {};

View File

@@ -0,0 +1,11 @@
#include "Assets/EditorIconServiceFactory.h"
#include "Assets/BuiltInIcons.h"
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorIconService> CreateEditorIconService() {
return std::make_unique<BuiltInIcons>();
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Assets/EditorIconService.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorIconService> CreateEditorIconService();
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#include "Viewport/EditorViewportRuntimeServicesFactory.h"
#include "Viewport/ViewportHostService.h"
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorViewportRuntimeServices> CreateEditorViewportRuntimeServices() {
return std::make_unique<ViewportHostService>();
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,11 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
std::unique_ptr<EditorViewportRuntimeServices> CreateEditorViewportRuntimeServices();
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,5 +1,7 @@
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/ViewportObjectIdPicker.h"
#include <XCEngine/Rendering/Picking/RenderObjectIdRegistry.h>
#include <XCEngine/Rendering/Execution/SceneRenderer.h>
#include <XCEngine/Scene/Scene.h>
@@ -41,9 +43,9 @@ SceneViewportRenderService::SceneViewportRenderService() = default;
SceneViewportRenderService::~SceneViewportRenderService() = default;
ViewportResourceRequirements
EditorViewportResourceRequirements
SceneViewportRenderService::GetViewportResourceRequirements() {
ViewportResourceRequirements requirements = {};
EditorViewportResourceRequirements requirements = {};
requirements.requiresDepthSampling = true;
requirements.requiresObjectIdSurface = true;
requirements.requiresSelectionMaskSurface = true;
@@ -79,6 +81,10 @@ void SceneViewportRenderService::SetRenderRequest(
m_renderRequest = std::move(request);
}
const IViewportObjectPickerService& SceneViewportRenderService::GetObjectPicker() const {
return *this;
}
ViewportRenderResult SceneViewportRenderService::Render(
ViewportRenderTargets& targets,
::XCEngine::RHI::RHIDevice& device,

View File

@@ -1,9 +1,8 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include "Viewport/ViewportContentRenderer.h"
#include "Viewport/ViewportObjectPickerService.h"
#include "Viewport/SceneViewportRenderPassBundle.h"
#include "Scene/SceneViewportRenderRequest.h"
#include <memory>
#include <string>
@@ -28,16 +27,18 @@ namespace XCEngine::UI::Editor::App {
class SceneViewportRenderService
: public IViewportContentRenderer
, public EditorSceneViewportRuntime
, public IViewportObjectPickerService {
public:
SceneViewportRenderService();
~SceneViewportRenderService();
static ViewportResourceRequirements GetViewportResourceRequirements();
static EditorViewportResourceRequirements GetViewportResourceRequirements();
void Initialize(const SceneViewportShaderPaths& shaderPaths);
void Shutdown();
void SetRenderRequest(SceneViewportRenderRequest request);
void SetRenderRequest(SceneViewportRenderRequest request) override;
const IViewportObjectPickerService& GetObjectPicker() const override;
ViewportRenderResult Render(
ViewportRenderTargets& targets,

View File

@@ -1,5 +1,7 @@
#include "ViewportHostService.h"
#include "Panels/EditorPanelIds.h"
#include "Viewport/SceneViewportResourcePaths.h"
#include "ViewportRenderHost.h"
#include <XCEngine/RHI/RHICommandList.h>
@@ -18,6 +20,14 @@ ViewportHostService::ViewportHostService() = default;
ViewportHostService::~ViewportHostService() = default;
void ViewportHostService::Initialize(const std::filesystem::path& repoRoot) {
m_sceneViewportRuntime.Initialize(BuildSceneViewportShaderPaths(repoRoot));
SetContentRenderer(
kScenePanelId,
&m_sceneViewportRuntime,
SceneViewportRenderService::GetViewportResourceRequirements());
}
void ViewportHostService::AttachWindowRenderer(
Rendering::Host::ViewportRenderHost& windowRenderer) {
if (m_windowRenderer == &windowRenderer) {
@@ -43,13 +53,15 @@ void ViewportHostService::SetSurfacePresentationEnabled(bool enabled) {
void ViewportHostService::SetContentRenderer(
std::string_view viewportId,
IViewportContentRenderer* renderer,
const ViewportResourceRequirements& requirements) {
const EditorViewportResourceRequirements& requirements) {
ViewportEntry& entry = GetOrCreateEntry(viewportId);
entry.renderer = renderer;
entry.requirements = requirements;
}
void ViewportHostService::Shutdown() {
SetContentRenderer(kScenePanelId, nullptr, {});
m_sceneViewportRuntime.Shutdown();
for (auto& [viewportId, entry] : m_entries) {
DestroyViewportEntry(entry);
}
@@ -155,7 +167,7 @@ void ViewportHostService::RetireViewportTargets(ViewportRenderTargets& targets)
std::swap(m_retiredTargetsBySlot[activeSlot].back(), targets);
}
ViewportFrame ViewportHostService::RequestViewport(
EditorViewportFrame ViewportHostService::RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize) {
ViewportEntry& entry = GetOrCreateEntry(viewportId);
@@ -302,10 +314,10 @@ void ViewportHostService::ClearViewport(
entry.renderTargets.objectIdFrameSerial = 0u;
}
ViewportFrame ViewportHostService::BuildFrame(
EditorViewportFrame ViewportHostService::BuildFrame(
const ViewportEntry& entry,
const ::XCEngine::UI::UISize& requestedSize) const {
ViewportFrame frame = {};
EditorViewportFrame frame = {};
frame.requestedSize = requestedSize;
frame.renderSize = ::XCEngine::UI::UISize(
static_cast<float>(entry.renderTargets.width),
@@ -322,4 +334,8 @@ ViewportFrame ViewportHostService::BuildFrame(
return frame;
}
EditorSceneViewportRuntime& ViewportHostService::GetSceneViewportRuntime() {
return m_sceneViewportRuntime;
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,8 @@
#pragma once
#include "Viewport/EditorViewportRuntimeServices.h"
#include "HostFwd.h"
#include "Viewport/SceneViewportRenderService.h"
#include "Viewport/ViewportContentRenderer.h"
#include "ViewportRenderTargets.h"
@@ -15,33 +17,35 @@
namespace XCEngine::UI::Editor::App {
class ViewportHostService {
class ViewportHostService final : public EditorViewportRuntimeServices {
public:
ViewportHostService();
~ViewportHostService();
void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer);
void DetachWindowRenderer();
void SetSurfacePresentationEnabled(bool enabled);
void Initialize(const std::filesystem::path& repoRoot) override;
void Shutdown() override;
void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer) override;
void DetachWindowRenderer() override;
void SetSurfacePresentationEnabled(bool enabled) override;
void SetContentRenderer(
std::string_view viewportId,
IViewportContentRenderer* renderer,
const ViewportResourceRequirements& requirements = {});
const EditorViewportResourceRequirements& requirements = {});
void Shutdown();
void BeginFrame();
void BeginFrame() override;
ViewportFrame RequestViewport(
EditorViewportFrame RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize);
const ::XCEngine::UI::UISize& requestedSize) override;
void RenderRequestedViewports(
const ::XCEngine::Rendering::RenderContext& renderContext);
const ::XCEngine::Rendering::RenderContext& renderContext) override;
EditorSceneViewportRuntime& GetSceneViewportRuntime() override;
private:
struct ViewportEntry {
IViewportContentRenderer* renderer = nullptr;
ViewportResourceRequirements requirements = {};
EditorViewportResourceRequirements requirements = {};
std::uint32_t requestedWidth = 0;
std::uint32_t requestedHeight = 0;
bool requestedThisFrame = false;
@@ -68,7 +72,7 @@ private:
float g,
float b,
float a);
ViewportFrame BuildFrame(
EditorViewportFrame BuildFrame(
const ViewportEntry& entry,
const ::XCEngine::UI::UISize& requestedSize) const;
@@ -78,6 +82,7 @@ private:
bool m_surfacePresentationEnabled = false;
std::unordered_map<std::string, ViewportEntry> m_entries = {};
std::vector<std::vector<ViewportRenderTargets>> m_retiredTargetsBySlot = {};
SceneViewportRenderService m_sceneViewportRuntime = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,10 +1,11 @@
#pragma once
#include "Viewport/EditorViewportPicking.h"
#include <XCEngine/RHI/RHICommandQueue.h>
#include <XCEngine/RHI/RHIEnums.h>
#include <XCEngine/RHI/RHITexture.h>
#include <XCEngine/Rendering/Picking/ObjectIdCodec.h>
#include <XCEngine/UI/Types.h>
#include <algorithm>
#include <array>
@@ -36,28 +37,6 @@ struct ViewportObjectIdReadbackRequest {
std::uint32_t pixelY = 0;
};
enum class ViewportObjectIdPickStatus : std::uint8_t {
Unavailable = 0,
Success,
ReadbackFailed
};
struct ViewportObjectIdPickResult {
ViewportObjectIdPickStatus status = ViewportObjectIdPickStatus::Unavailable;
std::uint64_t frameSerial = 0u;
::XCEngine::Rendering::RenderObjectId renderObjectId =
::XCEngine::Rendering::kInvalidRenderObjectId;
std::uint64_t resolvedEntityId = 0u;
bool HasResolvedSample() const {
return status == ViewportObjectIdPickStatus::Success;
}
bool HasResolvedEntity() const {
return HasResolvedSample() && resolvedEntityId != 0u;
}
};
inline bool CanPickViewportObjectId(const ViewportObjectIdPickContext& context) {
return context.commandQueue != nullptr &&
context.texture != nullptr &&

View File

@@ -1,16 +1,3 @@
#pragma once
#include "Viewport/ViewportObjectIdPicker.h"
namespace XCEngine::UI::Editor::App {
class IViewportObjectPickerService {
public:
virtual ~IViewportObjectPickerService() = default;
virtual ViewportObjectIdPickResult PickObject(
const ::XCEngine::UI::UISize& viewportSize,
const ::XCEngine::UI::UIPoint& viewportMousePosition) const = 0;
};
} // namespace XCEngine::UI::Editor::App
#include "Viewport/EditorViewportPicking.h"

View File

@@ -1,25 +1,11 @@
#pragma once
#include <XCEngine/UI/Types.h>
#include <string>
#include "Viewport/EditorViewportTypes.h"
namespace XCEngine::UI::Editor::App {
struct ViewportResourceRequirements {
bool requiresDepthSampling = false;
bool requiresObjectIdSurface = false;
bool requiresSelectionMaskSurface = false;
};
struct ViewportFrame {
::XCEngine::UI::UITextureHandle texture = {};
::XCEngine::UI::UISize requestedSize = {};
::XCEngine::UI::UISize renderSize = {};
bool hasTexture = false;
bool wasRequested = false;
std::string statusText = {};
};
using ViewportResourceRequirements = EditorViewportResourceRequirements;
using ViewportFrame = EditorViewportFrame;
} // namespace XCEngine::UI::Editor::App