Refactor new_editor window architecture and routing

This commit is contained in:
2026-04-23 14:11:33 +08:00
parent 5c0a878aa0
commit af5690395d
121 changed files with 1647 additions and 1592 deletions

View File

@@ -0,0 +1,168 @@
# NewEditor Content Capability Refactor Plan
Date: 2026-04-23
Status: Completed
## 1. Objective
Refactor the `new_editor/app/Platform/Win32` window-content boundary so that optional behaviors are expressed as explicit capabilities instead of being stuffed into one fat `EditorWindowContentController` interface.
This plan targets the most severe remaining architecture issue in Win32:
1. `EditorWindowContentController` currently mixes base rendering lifecycle, workspace mutation, dock-host interaction, capture/cursor feedback, and title-bar policy in one interface.
2. `EditorWindowRuntimeController` mirrors that bloated surface almost one-to-one, so every optional behavior is forwarded twice before it reaches real implementation.
3. Workspace content implements nearly the entire interface, while utility content implements only a thin subset and inherits a large set of meaningless default methods.
The goal is to stop capability sprawl at the root instead of continuing to delete wrappers one file at a time.
## 2. Confirmed Root Cause
The current layering drift is:
1. `EditorWindowContentController` acts as both:
- mandatory window-content contract
- optional capability registry
2. `EditorWindowRuntimeController` repeats those same optional operations as direct forwarding methods.
3. Callers such as:
- `EditorWindow`
- `EditorWindowMessageDispatcher`
- `EditorWindowWorkspaceCoordinator`
- `EditorWindowChromeController`
consume the mirrored runtime API instead of consuming small, explicit capability contracts.
That creates two kinds of redundancy:
1. interface redundancy:
optional methods live on a base type that many implementations do not meaningfully support
2. forwarding redundancy:
runtime methods exist only to forward a single optional call to content
## 3. Target End State
After the refactor:
1. `EditorWindowContentController` keeps only mandatory content lifecycle and frame responsibilities.
2. Optional behaviors become explicit capability interfaces:
- workspace binding
- dock-host interaction
- input/capture feedback
- title-bar presentation policy
3. `EditorWindowRuntimeController` exposes capability lookup, not one forwarding method per optional behavior.
4. Win32 callers use those capability interfaces directly and apply local fallback behavior when a capability is absent.
## 4. Capability Split
### 4.1 Mandatory base contract
Keep in `EditorWindowContentController` only behavior that every content implementation must provide:
1. initialize / shutdown / reset
2. viewport presentation enablement
3. frame update and viewport render
4. shell frame and shell interaction state
5. minimum outer size
### 4.2 Optional capability contracts
Introduce explicit optional interfaces:
1. `EditorWindowWorkspaceBinding`
- already exists
2. `EditorWindowDockHostBinding`
- external dock preview
- dock tab drag hotspot
- dock drop target resolution
3. `EditorWindowInputFeedbackBinding`
- hosted content capture
- shell capture
- generic interactive capture
- hosted content cursor
- dock cursor
4. `EditorWindowTitleBarBinding`
- detached title-bar tab strip policy
- detached tab title resolution
- detached window title resolution
## 5. Execution Phases
### Phase A. Introduce capability interfaces
1. Extend `EditorWindowContentController.h` with the new capability types.
2. Replace optional default methods on the base class with `TryGet...Binding()` queries.
### Phase B. Move workspace content onto explicit capabilities
1. Make `EditorWorkspaceWindowContentController` implement:
- `EditorWindowDockHostBinding`
- `EditorWindowInputFeedbackBinding`
- `EditorWindowTitleBarBinding`
2. Keep utility-window content minimal; it should not implement capabilities it does not need.
### Phase C. Shrink runtime surface
1. Delete mirrored forwarding methods from `EditorWindowRuntimeController` for:
- dock preview / hotspot / drop target
- capture feedback / cursor feedback
- title-bar policy helpers
2. Replace them with capability accessors.
### Phase D. Update Win32 callers
Update callers to query the capability they actually need:
1. `EditorWindow`
2. `EditorWindowMessageDispatcher`
3. `EditorWindowWorkspaceCoordinator`
4. `EditorWindowChromeController`
Each caller must own its fallback behavior instead of assuming every content type supports everything.
### Phase E. Validate
1. build `XCUIEditorApp`
2. confirm no stale content/runtime forwarding methods remain
3. confirm utility-window content still compiles without fake overrides
## 6. Concrete File Plan
### Files to update
1. `new_editor/app/Platform/Win32/Content/EditorWindowContentController.h`
2. `new_editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.h`
3. `new_editor/app/Platform/Win32/Content/EditorWorkspaceWindowContentController.cpp`
4. `new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.h`
5. `new_editor/app/Platform/Win32/Runtime/EditorWindowRuntimeController.cpp`
6. `new_editor/app/Platform/Win32/Windowing/EditorWindow.cpp`
7. `new_editor/app/Platform/Win32/Windowing/EditorWindowMessageDispatcher.cpp`
8. `new_editor/app/Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.cpp`
9. `new_editor/app/Platform/Win32/Chrome/EditorWindowChromeController.cpp`
## 7. Validation Criteria
The refactor is only considered correct if all of the following are true:
1. optional content behaviors are no longer declared as default no-op methods on the main base class
2. runtime no longer mirrors those same optional methods one-by-one
3. callers consume explicit capability types
4. the editor build still reaches at least the same link stage as before the refactor
## 8. Non-Goals
This plan does not include:
1. removing `EditorWindowManager`
2. splitting `EditorWindowWorkspaceCoordinator`
3. merging steady-state and immediate frame finalization flows
4. changing utility-window feature behavior
## 9. Completion Notes
Completed on: 2026-04-23
Validation result:
1. `EditorWindowContentController` no longer carries the old default no-op optional behavior surface.
2. `EditorWindowRuntimeController` no longer mirrors those optional behaviors as one-by-one forwarding methods.
3. Win32 callers now consume capability bindings instead of the old mirrored runtime helpers.
4. `XCUIEditorApp` builds successfully with:
`cmake --build D:\Xuanchi\Main\XCEngine\build\new_editor --config Debug --target XCUIEditorApp`

View File

@@ -150,12 +150,12 @@ set(XCUI_EDITOR_SHARED_SOURCES
)
set(XCUI_EDITOR_HOST_PLATFORM_SOURCES
app/Platform/Win32/BorderlessWindowChrome.cpp
app/Platform/Win32/BorderlessWindowFrame.cpp
app/Platform/Win32/Chrome/BorderlessWindowChrome.cpp
app/Platform/Win32/Chrome/BorderlessWindowFrame.cpp
)
set(XCUI_EDITOR_HOST_RENDERING_SOURCES
app/Platform/Win32/EditorWindowScreenshotController.cpp
app/Platform/Win32/Runtime/EditorWindowScreenshotController.cpp
app/Rendering/D3D12/D3D12HostDevice.cpp
app/Rendering/D3D12/D3D12WindowCapture.cpp
app/Rendering/D3D12/D3D12UiRenderer.cpp
@@ -217,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
@@ -239,25 +240,22 @@ if(XCENGINE_BUILD_XCUI_EDITOR_APP)
)
set(XCUI_EDITOR_APP_PLATFORM_SOURCES
app/Platform/Win32/EditorWindow.cpp
app/Platform/Win32/EditorAddComponentUtilityWindowContentController.cpp
app/Platform/Win32/EditorColorPickerUtilityWindowContentController.cpp
app/Platform/Win32/EditorFloatingWindowPlacement.cpp
app/Platform/Win32/EditorStandaloneUtilityWindowContentController.cpp
app/Platform/Win32/EditorWindowChromeController.cpp
app/Platform/Win32/EditorWindowFrameDriver.cpp
app/Platform/Win32/EditorWindowFrameOrchestrator.cpp
app/Platform/Win32/EditorWindowInputController.cpp
app/Platform/Win32/EditorWindowRuntimeController.cpp
app/Platform/Win32/EditorUtilityWindowRegistry.cpp
app/Platform/Win32/EditorWorkspaceWindowContentController.cpp
app/Platform/Win32/Win32SystemInteractionHost.cpp
app/Platform/Win32/WindowManager/EditorWindowHostRuntime.cpp
app/Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.cpp
app/Platform/Win32/WindowManager/EditorWindowManager.cpp
app/Platform/Win32/WindowManager/EditorWindowMessageDispatcher.cpp
app/Platform/Win32/WindowManager/EditorUtilityWindowCoordinator.cpp
app/Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.cpp
app/Platform/Win32/Windowing/EditorWindow.cpp
app/Platform/Win32/Windowing/EditorFloatingWindowPlacement.cpp
app/Platform/Win32/Content/EditorUtilityWindowContentController.cpp
app/Platform/Win32/Chrome/EditorWindowChromeController.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/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

View File

@@ -1,11 +1,11 @@
#include "Bootstrap/Application.h"
#include "Bootstrap/Application.h"
#include "Bootstrap/EditorResources.h"
#include "Ports/SystemInteractionPort.h"
#include "System/SystemInteractionService.h"
#include "Composition/EditorContext.h"
#include "Platform/Win32/EditorWindowManager.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWorkspaceWindowContentController.h"
#include "Platform/Win32/Win32SystemInteractionHost.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"

View File

@@ -15,8 +15,8 @@ class EditorContext;
class EditorWindowManager;
}
namespace Ports {
class SystemInteractionPort;
namespace System {
class SystemInteractionService;
}
}
@@ -48,7 +48,7 @@ private:
std::filesystem::path m_repoRoot = {};
std::unique_ptr<App::EditorContext> m_editorContext = {};
std::unique_ptr<App::EditorWindowManager> m_windowManager = {};
std::unique_ptr<Ports::SystemInteractionPort> m_systemInteractionHost = {};
std::unique_ptr<System::SystemInteractionService> m_systemInteractionHost = {};
};
int RunXCUIEditorApp(HINSTANCE hInstance, int nCmdShow);

View File

@@ -93,7 +93,7 @@ void EditorContext::AttachTextMeasurer(
m_shellServices.textMeasurer = &textMeasurer;
}
void EditorContext::SetSystemInteractionHost(Ports::SystemInteractionPort* systemInteractionHost) {
void EditorContext::SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost) {
m_systemInteractionHost = systemInteractionHost;
}
@@ -194,11 +194,11 @@ void EditorContext::SyncSessionFromCommandFocusService() {
ResolveEditorActionRoute(m_session.activePanelId));
}
Ports::SystemInteractionPort* EditorContext::GetSystemInteractionHost() {
System::SystemInteractionService* EditorContext::GetSystemInteractionHost() {
return m_systemInteractionHost;
}
const Ports::SystemInteractionPort* EditorContext::GetSystemInteractionHost() const {
const System::SystemInteractionService* EditorContext::GetSystemInteractionHost() const {
return m_systemInteractionHost;
}

View File

@@ -3,6 +3,7 @@
#include "Composition/EditorShellVariant.h"
#include "Project/EditorProjectRuntime.h"
#include "Scene/EditorSceneRuntime.h"
#include "UtilityWindows/EditorUtilityWindowKind.h"
#include "Commands/EditorHostCommandBridge.h"
#include "State/EditorColorPickerToolState.h"
@@ -21,8 +22,8 @@
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor::Ports {
class SystemInteractionPort;
namespace XCEngine::UI::Editor::System {
class SystemInteractionService;
}
namespace XCEngine::UI::Editor::App {
@@ -33,7 +34,7 @@ class EditorContext {
public:
bool Initialize(const std::filesystem::path& repoRoot);
void AttachTextMeasurer(const UIEditorTextMeasurer& textMeasurer);
void SetSystemInteractionHost(Ports::SystemInteractionPort* systemInteractionHost);
void SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost);
void BindEditCommandRoutes(
EditorEditCommandRoute* hierarchyRoute,
EditorEditCommandRoute* projectRoute,
@@ -60,8 +61,8 @@ public:
void ClearSelection();
void SyncSessionFromSelectionService();
void SyncSessionFromCommandFocusService();
Ports::SystemInteractionPort* GetSystemInteractionHost();
const Ports::SystemInteractionPort* GetSystemInteractionHost() const;
System::SystemInteractionService* GetSystemInteractionHost();
const System::SystemInteractionService* GetSystemInteractionHost() const;
UIEditorWorkspaceController BuildWorkspaceController() const;
const UIEditorShellInteractionServices& GetShellServices() const;
@@ -95,7 +96,7 @@ private:
EditorColorPickerToolState m_colorPickerToolState = {};
EditorUtilityWindowRequestState m_utilityWindowRequestState = {};
EditorHostCommandBridge m_hostCommandBridge = {};
Ports::SystemInteractionPort* m_systemInteractionHost = nullptr;
System::SystemInteractionService* m_systemInteractionHost = nullptr;
std::string m_lastStatus = {};
std::string m_lastMessage = {};
};

View File

@@ -1,6 +1,6 @@
#include "Composition/EditorShellRuntime.h"
#include "Ports/TexturePort.h"
#include "Ports/ViewportRenderPort.h"
#include "Rendering/Host/UiTextureHost.h"
#include "Rendering/Host/ViewportRenderHost.h"
#include "Composition/EditorContext.h"
#include "Composition/EditorPanelIds.h"
#include <XCEditor/Shell/UIEditorShellCapturePolicy.h>
@@ -10,7 +10,7 @@ namespace XCEngine::UI::Editor::App {
void EditorShellRuntime::Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
UIEditorTextMeasurer& textMeasurer) {
m_textureHost = &textureHost;
m_builtInIcons.Initialize(textureHost);
@@ -26,7 +26,7 @@ void EditorShellRuntime::Initialize(
m_hierarchyPanel.Initialize();
}
void EditorShellRuntime::AttachViewportWindowRenderer(Ports::ViewportRenderPort& renderer) {
void EditorShellRuntime::AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer) {
m_viewportHostService.AttachWindowRenderer(renderer);
}

View File

@@ -33,12 +33,12 @@ class EditorContext;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::Rendering::Host {
class TexturePort;
class ViewportRenderPort;
class UiTextureHost;
class ViewportRenderHost;
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::Rendering {
@@ -52,11 +52,11 @@ class EditorShellRuntime {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
UIEditorTextMeasurer& textMeasurer);
void Shutdown();
void ResetInteractionState();
void AttachViewportWindowRenderer(Ports::ViewportRenderPort& renderer);
void AttachViewportWindowRenderer(Rendering::Host::ViewportRenderHost& renderer);
void DetachViewportWindowRenderer();
void SetViewportSurfacePresentationEnabled(bool enabled);
@@ -99,7 +99,7 @@ private:
ViewportHostService m_viewportHostService = {};
SceneViewportFeature m_sceneViewportFeature = {};
BuiltInIcons m_builtInIcons = {};
Ports::TexturePort* m_textureHost = nullptr;
Rendering::Host::UiTextureHost* m_textureHost = nullptr;
ConsolePanel m_consolePanel = {};
HierarchyPanel m_hierarchyPanel = {};
InspectorPanel m_inspectorPanel = {};

View File

@@ -1,140 +1,12 @@
#include "Composition/EditorWindowWorkspaceStore.h"
#include "Composition/EditorWindowWorkspaceStore.h"
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
#include <algorithm>
#include <sstream>
#include <utility>
namespace XCEngine::UI::Editor::App {
namespace {
UIEditorWindowWorkspaceState BuildWindowState(
std::string_view windowId,
const UIEditorWorkspaceController& workspaceController) {
UIEditorWindowWorkspaceState state = {};
state.windowId = std::string(windowId);
state.workspace = workspaceController.GetWorkspace();
state.session = workspaceController.GetSession();
return state;
}
std::string ResolveFallbackWindowId(const UIEditorWindowWorkspaceSet& windowSet) {
if (!windowSet.primaryWindowId.empty() &&
FindUIEditorWindowWorkspaceState(windowSet, windowSet.primaryWindowId) != nullptr) {
return windowSet.primaryWindowId;
}
return windowSet.windows.empty() ? std::string() : windowSet.windows.front().windowId;
}
void UpsertWindowState(
UIEditorWindowWorkspaceSet& windowSet,
UIEditorWindowWorkspaceState windowState) {
if (UIEditorWindowWorkspaceState* existing =
FindMutableUIEditorWindowWorkspaceState(windowSet, windowState.windowId);
existing != nullptr) {
*existing = std::move(windowState);
return;
}
windowSet.windows.push_back(std::move(windowState));
}
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();
}
} // namespace
EditorWindowWorkspaceStore::EditorWindowWorkspaceStore(UIEditorPanelRegistry panelRegistry)
: m_panelRegistry(std::move(panelRegistry)) {}
UIEditorWindowWorkspaceController EditorWindowWorkspaceStore::BuildMutationController() const {
return UIEditorWindowWorkspaceController(m_panelRegistry, m_windowSet);
}
bool EditorWindowWorkspaceStore::RegisterWindowProjection(
std::string_view windowId,
bool primary,
const UIEditorWorkspaceController& workspaceController,
std::string& outError) {
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
UpsertWindowState(nextWindowSet, BuildWindowState(windowId, workspaceController));
if (primary) {
if (!nextWindowSet.primaryWindowId.empty() && nextWindowSet.primaryWindowId != windowId) {
outError =
"Cannot register a second primary window '" + std::string(windowId) +
"' while '" + nextWindowSet.primaryWindowId + "' is still primary.";
return false;
}
nextWindowSet.primaryWindowId = std::string(windowId);
} else if (nextWindowSet.primaryWindowId.empty()) {
outError =
"Cannot register detached window '" + std::string(windowId) +
"' before the primary window exists.";
return false;
}
if (nextWindowSet.activeWindowId.empty() ||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
}
if (!ValidateWindowSet(nextWindowSet, outError)) {
return false;
}
ReplaceWindowSet(std::move(nextWindowSet));
outError.clear();
return true;
}
bool EditorWindowWorkspaceStore::CommitWindowProjection(
std::string_view windowId,
const UIEditorWorkspaceController& workspaceController,
std::string& outError) {
UIEditorWindowWorkspaceSet nextWindowSet = m_windowSet;
UIEditorWindowWorkspaceState* existingWindow =
FindMutableUIEditorWindowWorkspaceState(nextWindowSet, windowId);
if (existingWindow == nullptr) {
outError = "Window '" + std::string(windowId) + "' is not registered in the workspace store.";
return false;
}
existingWindow->workspace = workspaceController.GetWorkspace();
existingWindow->session = workspaceController.GetSession();
if (nextWindowSet.activeWindowId.empty() ||
FindUIEditorWindowWorkspaceState(nextWindowSet, nextWindowSet.activeWindowId) == nullptr) {
nextWindowSet.activeWindowId = ResolveFallbackWindowId(nextWindowSet);
}
if (!ValidateWindowSet(nextWindowSet, outError)) {
return false;
}
ReplaceWindowSet(std::move(nextWindowSet));
outError.clear();
return true;
}
bool EditorWindowWorkspaceStore::ValidateWindowSet(
const UIEditorWindowWorkspaceSet& windowSet,
std::string& outError) const {
@@ -149,62 +21,4 @@ bool EditorWindowWorkspaceStore::ValidateWindowSet(
return true;
}
void EditorWindowWorkspaceStore::ReplaceWindowSet(UIEditorWindowWorkspaceSet windowSet) {
m_windowSet = std::move(windowSet);
}
void EditorWindowWorkspaceStore::RemoveWindow(std::string_view windowId, bool primary) {
const std::string beforeState = DescribeWindowSetState(m_windowSet);
if (m_windowSet.windows.empty()) {
AppendUIEditorRuntimeTrace(
"window-close",
"store remove skipped windowId='" + std::string(windowId) +
"' primaryArg=" + (primary ? "1" : "0") +
" stateBefore=" + beforeState);
return;
}
if (primary || m_windowSet.primaryWindowId == windowId) {
m_windowSet = {};
AppendUIEditorRuntimeTrace(
"window-close",
"store remove cleared all windows windowId='" + std::string(windowId) +
"' primaryArg=" + (primary ? "1" : "0") +
" stateBefore=" + beforeState +
" stateAfter=" + DescribeWindowSetState(m_windowSet));
return;
}
m_windowSet.windows.erase(
std::remove_if(
m_windowSet.windows.begin(),
m_windowSet.windows.end(),
[windowId](const UIEditorWindowWorkspaceState& state) {
return state.windowId == windowId;
}),
m_windowSet.windows.end());
if (m_windowSet.windows.empty()) {
m_windowSet = {};
return;
}
if (FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.primaryWindowId) == nullptr) {
m_windowSet.primaryWindowId = ResolveFallbackWindowId(m_windowSet);
}
if (m_windowSet.activeWindowId == windowId ||
FindUIEditorWindowWorkspaceState(m_windowSet, m_windowSet.activeWindowId) == nullptr) {
m_windowSet.activeWindowId = ResolveFallbackWindowId(m_windowSet);
}
AppendUIEditorRuntimeTrace(
"window-close",
"store remove completed windowId='" + std::string(windowId) +
"' primaryArg=" + (primary ? "1" : "0") +
" stateBefore=" + beforeState +
" stateAfter=" + DescribeWindowSetState(m_windowSet));
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,10 +1,8 @@
#pragma once
#include <XCEditor/Workspace/UIEditorWindowWorkspaceController.h>
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
#include <string>
#include <string_view>
namespace XCEngine::UI::Editor::App {
@@ -16,38 +14,12 @@ public:
return m_panelRegistry;
}
bool HasState() const {
return !m_windowSet.windows.empty();
}
const UIEditorWindowWorkspaceSet& GetWindowSet() const {
return m_windowSet;
}
UIEditorWindowWorkspaceController BuildMutationController() const;
bool RegisterWindowProjection(
std::string_view windowId,
bool primary,
const UIEditorWorkspaceController& workspaceController,
std::string& outError);
bool CommitWindowProjection(
std::string_view windowId,
const UIEditorWorkspaceController& workspaceController,
std::string& outError);
bool ValidateWindowSet(
const UIEditorWindowWorkspaceSet& windowSet,
std::string& outError) const;
void ReplaceWindowSet(UIEditorWindowWorkspaceSet windowSet);
void RemoveWindow(std::string_view windowId, bool primary);
private:
UIEditorPanelRegistry m_panelRegistry = {};
UIEditorWindowWorkspaceSet m_windowSet = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -89,7 +89,7 @@ void ColorPickerPanel::ResetInteractionState() {
void ColorPickerPanel::Update(
EditorContext& context,
const ColorPickerPanelHostContext& hostContext,
const EditorUtilityWindowHostContext& hostContext,
const std::vector<UIInputEvent>& inputEvents) {
if (!hostContext.mounted) {
ResetPanelState();

View File

@@ -1,33 +1,24 @@
#pragma once
#include "UtilityWindows/EditorUtilityWindowPanel.h"
#include <XCEditor/Fields/UIEditorColorFieldInteraction.h>
#include <XCEngine/UI/DrawData.h>
#include <string>
#include <vector>
namespace XCEngine::UI::Editor::App {
class EditorContext;
struct ColorPickerPanelHostContext {
bool mounted = false;
::XCEngine::UI::UIRect bounds = {};
bool allowInteraction = false;
bool focused = false;
bool focusGained = false;
bool focusLost = false;
};
class ColorPickerPanel {
class ColorPickerPanel final : public EditorUtilityWindowPanel {
public:
void ResetInteractionState();
std::string_view GetDrawListId() const override {
return "XCEditorUtility.ColorPicker";
}
void ResetInteractionState() override;
void Update(
EditorContext& context,
const ColorPickerPanelHostContext& hostContext,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents);
void Append(::XCEngine::UI::UIDrawList& drawList) const;
const EditorUtilityWindowHostContext& hostContext,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override;
void Append(::XCEngine::UI::UIDrawList& drawList) const override;
private:
void ResetPanelState();

View File

@@ -155,7 +155,7 @@ std::size_t AddComponentPanel::HitTestEntry(const UIPoint& point) const {
void AddComponentPanel::Update(
EditorContext& context,
const AddComponentPanelHostContext& hostContext,
const EditorUtilityWindowHostContext& hostContext,
const std::vector<UIInputEvent>& inputEvents) {
if (!hostContext.mounted) {
ResetPanelState();

View File

@@ -1,6 +1,6 @@
#pragma once
#include <XCEngine/UI/DrawData.h>
#include "UtilityWindows/EditorUtilityWindowPanel.h"
#include <cstddef>
#include <string>
@@ -12,24 +12,17 @@ class GameObject;
namespace XCEngine::UI::Editor::App {
class EditorContext;
struct AddComponentPanelHostContext {
bool mounted = false;
::XCEngine::UI::UIRect bounds = {};
bool focused = false;
bool focusGained = false;
bool focusLost = false;
};
class AddComponentPanel {
class AddComponentPanel final : public EditorUtilityWindowPanel {
public:
void ResetInteractionState();
std::string_view GetDrawListId() const override {
return "XCEditorUtility.AddComponent";
}
void ResetInteractionState() override;
void Update(
EditorContext& context,
const AddComponentPanelHostContext& hostContext,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents);
void Append(::XCEngine::UI::UIDrawList& drawList) const;
const EditorUtilityWindowHostContext& hostContext,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents) override;
void Append(::XCEngine::UI::UIDrawList& drawList) const override;
private:
struct EntryPresentation {

View File

@@ -324,6 +324,7 @@ InspectorFieldBinding BuildInspectorVector3FieldBinding(
label,
getter(),
options.step,
options.controlMinWidth,
options.integerMode,
options.minValue,
options.maxValue);

View File

@@ -27,6 +27,7 @@ struct InspectorColorFieldBindingOptions {
struct InspectorVector3FieldBindingOptions {
double step = 0.1;
float controlMinWidth = kDefaultInspectorFieldControlMinWidth;
bool integerMode = false;
double minValue = -1000000.0;
double maxValue = 1000000.0;

View File

@@ -18,6 +18,8 @@
namespace XCEngine::UI::Editor::App {
inline constexpr float kDefaultInspectorFieldControlMinWidth = 160.0f;
inline std::string BuildInspectorComponentSectionId(
std::string_view componentId,
std::string_view sectionSuffix = {}) {
@@ -50,6 +52,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorReadOnlyTextField(
field.kind = Widgets::UIEditorPropertyGridFieldKind::Text;
field.valueText = std::move(value);
field.readOnly = true;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -64,6 +67,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorTextField(
field.kind = Widgets::UIEditorPropertyGridFieldKind::Text;
field.valueText = std::move(value);
field.readOnly = readOnly;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -76,6 +80,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorBoolField(
field.label = std::move(label);
field.kind = Widgets::UIEditorPropertyGridFieldKind::Bool;
field.boolValue = value;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -107,6 +112,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorNumberField(
field.numberValue.minValue = minValue;
field.numberValue.maxValue = maxValue;
field.numberValue.integerMode = integerMode;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -132,6 +138,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorEnumField(
field.kind = Widgets::UIEditorPropertyGridFieldKind::Enum;
field.enumValue.options = std::move(options);
field.enumValue.selectedIndex = selectedIndex;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -184,6 +191,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorAssetField(
field.assetValue.emptyText = std::move(emptyText);
field.assetValue.showPickerButton = showPickerButton;
field.assetValue.showStatusBadge = !field.assetValue.statusText.empty();
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -227,6 +235,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorColorField(
field.kind = Widgets::UIEditorPropertyGridFieldKind::Color;
field.colorValue.value = ToUIEditorColor(value);
field.colorValue.showAlpha = showAlpha;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}
@@ -265,6 +274,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorVector3Field(
std::string label,
const ::XCEngine::Math::Vector3& value,
double step,
float controlMinWidth = kDefaultInspectorFieldControlMinWidth,
bool integerMode = false,
double minValue = -1000000.0,
double maxValue = 1000000.0) {
@@ -277,6 +287,7 @@ inline Widgets::UIEditorPropertyGridField BuildInspectorVector3Field(
field.vector3Value.minValue = minValue;
field.vector3Value.maxValue = maxValue;
field.vector3Value.integerMode = integerMode;
field.controlMinWidth = controlMinWidth;
return field;
}

View File

@@ -36,7 +36,7 @@ void TransformInspectorComponentEditor::BuildBindingSections(
section.fields.push_back(BuildInspectorVector3FieldBinding(
"position",
"Position",
InspectorVector3FieldBindingOptions{ .step = 0.1 },
InspectorVector3FieldBindingOptions{ .step = 0.1, .controlMinWidth = 240.0f },
[transform]() { return transform->GetLocalPosition(); },
[](EditorSceneRuntime& sceneRuntime,
const InspectorComponentEditorContext& bindingContext,
@@ -48,7 +48,7 @@ void TransformInspectorComponentEditor::BuildBindingSections(
section.fields.push_back(BuildInspectorVector3FieldBinding(
"rotation",
"Rotation",
InspectorVector3FieldBindingOptions{ .step = 1.0 },
InspectorVector3FieldBindingOptions{ .step = 1.0, .controlMinWidth = 240.0f },
[transform]() { return transform->GetLocalEulerAngles(); },
[](EditorSceneRuntime& sceneRuntime,
const InspectorComponentEditorContext& bindingContext,
@@ -60,7 +60,7 @@ void TransformInspectorComponentEditor::BuildBindingSections(
section.fields.push_back(BuildInspectorVector3FieldBinding(
"scale",
"Scale",
InspectorVector3FieldBindingOptions{ .step = 0.1 },
InspectorVector3FieldBindingOptions{ .step = 0.1, .controlMinWidth = 240.0f },
[transform]() { return transform->GetLocalScale(); },
[](EditorSceneRuntime& sceneRuntime,
const InspectorComponentEditorContext& bindingContext,

View File

@@ -60,6 +60,7 @@ UIEditorPropertyGridField BuildReadOnlyTextField(
field.kind = UIEditorPropertyGridFieldKind::Text;
field.valueText = std::move(value);
field.readOnly = true;
field.controlMinWidth = kDefaultInspectorFieldControlMinWidth;
return field;
}

View File

@@ -6,7 +6,7 @@
#include <algorithm>
#include <cmath>
#include <string_view>
#include "Ports/SystemInteractionPort.h"
#include "System/SystemInteractionService.h"
#include "Project/EditorProjectRuntime.h"
#include "State/EditorCommandFocusService.h"
#include <XCEditor/Fields/UIEditorFieldStyle.h>
@@ -46,8 +46,8 @@ inline constexpr float kGridTileWidth = 92.0f;
inline constexpr float kGridTileHeight = 92.0f;
inline constexpr float kGridTileGapX = 12.0f;
inline constexpr float kGridTileGapY = 12.0f;
inline constexpr float kGridPreviewWidth = 68.0f;
inline constexpr float kGridPreviewHeight = 54.0f;
inline constexpr float kGridPreviewWidth = 80.0f;
inline constexpr float kGridPreviewHeight = 64.0f;
inline constexpr float kHeaderFontSize = 12.0f;
inline constexpr float kTileLabelFontSize = 11.0f;
@@ -298,6 +298,48 @@ void AppendContextMenuSeparator(
items.push_back(BuildContextMenuSeparatorItem(std::move(itemId)));
}
std::size_t FindContextMenuItemIndexById(
const std::vector<Widgets::UIEditorMenuPopupItem>& items,
std::string_view itemId) {
for (std::size_t index = 0u; index < items.size(); ++index) {
if (items[index].itemId == itemId) {
return index;
}
}
return Widgets::UIEditorMenuPopupInvalidIndex;
}
Widgets::UIEditorMenuPopupState PreserveContextMenuWidgetState(
const std::vector<Widgets::UIEditorMenuPopupItem>& previousItems,
const Widgets::UIEditorMenuPopupState& previousState,
const std::vector<Widgets::UIEditorMenuPopupItem>& rebuiltItems) {
Widgets::UIEditorMenuPopupState preserved = {};
preserved.focused = previousState.focused;
if (previousState.hoveredIndex < previousItems.size()) {
const std::size_t hoveredIndex =
FindContextMenuItemIndexById(
rebuiltItems,
previousItems[previousState.hoveredIndex].itemId);
if (hoveredIndex < rebuiltItems.size() && rebuiltItems[hoveredIndex].enabled) {
preserved.hoveredIndex = hoveredIndex;
}
}
if (previousState.submenuOpenIndex < previousItems.size()) {
const std::size_t submenuOpenIndex =
FindContextMenuItemIndexById(
rebuiltItems,
previousItems[previousState.submenuOpenIndex].itemId);
if (submenuOpenIndex < rebuiltItems.size() && rebuiltItems[submenuOpenIndex].enabled) {
preserved.submenuOpenIndex = submenuOpenIndex;
}
}
return preserved;
}
} // namespace
EditorProjectRuntime* ProjectPanel::ResolveProjectRuntime() {
@@ -371,7 +413,7 @@ void ProjectPanel::SetCommandFocusService(
}
void ProjectPanel::SetSystemInteractionHost(
Ports::SystemInteractionPort* systemInteractionHost) {
System::SystemInteractionService* systemInteractionHost) {
m_systemInteractionHost = systemInteractionHost;
}
@@ -883,6 +925,11 @@ void ProjectPanel::RebuildContextMenu() {
return;
}
const std::vector<Widgets::UIEditorMenuPopupItem> previousItems =
m_contextMenu.items;
const Widgets::UIEditorMenuPopupState previousWidgetState =
m_contextMenu.widgetState;
const AssetCommandTarget assetTarget =
ResolveAssetCommandTarget(
m_contextMenu.targetItemId,
@@ -1008,7 +1055,11 @@ void ProjectPanel::RebuildContextMenu() {
placement.rect,
m_contextMenu.items,
popupMetrics);
m_contextMenu.widgetState = {};
m_contextMenu.widgetState =
PreserveContextMenuWidgetState(
previousItems,
previousWidgetState,
m_contextMenu.items);
m_contextMenu.widgetState.focused = true;
}
@@ -1057,8 +1108,8 @@ bool ProjectPanel::HandleContextMenuEvent(const UIInputEvent& event) {
hitTarget.index < m_contextMenu.items.size() &&
m_contextMenu.items[hitTarget.index].enabled) {
const std::string itemId = m_contextMenu.items[hitTarget.index].itemId;
DispatchContextMenuItem(itemId);
CloseContextMenu();
DispatchContextMenuItem(itemId);
return true;
}
@@ -1539,6 +1590,14 @@ UIEditorHostCommandDispatchResult ProjectPanel::DispatchEditCommand(
m_hoveredAssetItemId.clear();
m_lastPrimaryClickedAssetId.clear();
m_lastPrimaryClickTime = {};
if (HasValidBounds(m_layout.bounds)) {
RebuildPanelLayout(m_layout.bounds);
RebuildBrowserScrollLayout();
ApplyBrowserLayout(
m_layout.bounds,
m_browserScrollFrame.layout.contentRect,
m_browserVerticalOffset);
}
if (hadAssetSelection && !ResolveProjectRuntime()->HasSelection()) {
EmitSelectionClearedEvent(EventSource::GridPrimary);
}
@@ -2218,12 +2277,12 @@ ProjectPanel::Layout ProjectPanel::BuildLayout(
tile.tileRect = UIRect(tileX, tileY, kGridTileWidth, kGridTileHeight);
tile.previewRect = UIRect(
tile.tileRect.x + (tile.tileRect.width - kGridPreviewWidth) * 0.5f,
tile.tileRect.y + 6.0f,
tile.tileRect.y + 4.0f,
kGridPreviewWidth,
kGridPreviewHeight);
tile.labelRect = UIRect(
tile.tileRect.x + 4.0f,
tile.previewRect.y + tile.previewRect.height + 8.0f,
tile.previewRect.y + tile.previewRect.height + 6.0f,
tile.tileRect.width - 8.0f,
18.0f);
layout.assetTiles.push_back(tile);

View File

@@ -34,11 +34,11 @@ class EditorCommandFocusService;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::System {
class SystemInteractionPort;
class SystemInteractionService;
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::System
namespace XCEngine::UI::Editor::App {
@@ -85,7 +85,7 @@ public:
void Initialize(const std::filesystem::path& repoRoot);
void SetProjectRuntime(EditorProjectRuntime* projectRuntime);
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);
void SetSystemInteractionHost(Ports::SystemInteractionPort* systemInteractionHost);
void SetSystemInteractionHost(System::SystemInteractionService* systemInteractionHost);
void SetBuiltInIcons(BuiltInIcons* icons);
void SetTextMeasurer(const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer);
void ResetInteractionState();
@@ -253,7 +253,7 @@ private:
std::unique_ptr<EditorProjectRuntime> m_ownedProjectRuntime = {};
EditorProjectRuntime* m_projectRuntime = nullptr;
EditorCommandFocusService* m_commandFocusService = nullptr;
Ports::SystemInteractionPort* m_systemInteractionHost = nullptr;
System::SystemInteractionService* m_systemInteractionHost = nullptr;
BuiltInIcons* m_icons = nullptr;
const ::XCEngine::UI::Editor::UIEditorTextMeasurer* m_textMeasurer = nullptr;
std::vector<Widgets::UIEditorTreeViewItem> m_windowTreeItems = {};

View File

@@ -138,14 +138,14 @@ void ApplySceneViewportToggleButton(
void SceneViewportController::Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& renderer,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons) {
m_toolOverlay.Initialize(repoRoot, renderer);
m_sceneOverlay.SetBuiltInIcons(builtInIcons);
ResetInteractionState();
}
void SceneViewportController::Shutdown(Ports::TexturePort& renderer) {
void SceneViewportController::Shutdown(Rendering::Host::UiTextureHost& renderer) {
m_toolOverlay.Shutdown(renderer);
ResetInteractionState();
}

View File

@@ -21,11 +21,11 @@ class IViewportObjectPickerService;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::Rendering::Host {
class TexturePort;
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
@@ -33,9 +33,9 @@ class SceneViewportController {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& renderer,
Rendering::Host::UiTextureHost& renderer,
const BuiltInIcons* builtInIcons);
void Shutdown(Ports::TexturePort& renderer);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);

View File

@@ -1,7 +1,7 @@
#include "Features/Scene/SceneViewportFeature.h"
#include "Composition/EditorPanelIds.h"
#include "Ports/TexturePort.h"
#include "Rendering/Host/UiTextureHost.h"
#include "Rendering/Viewport/ViewportHostService.h"
#include "Scene/EditorSceneRuntime.h"
#include "State/EditorCommandFocusService.h"
@@ -10,7 +10,7 @@ namespace XCEngine::UI::Editor::App {
void SceneViewportFeature::Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService) {
viewportHostService.SetContentRenderer(
@@ -21,7 +21,7 @@ void SceneViewportFeature::Initialize(
}
void SceneViewportFeature::Shutdown(
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService) {
viewportHostService.SetContentRenderer(kScenePanelId, nullptr, {});
m_controller.Shutdown(textureHost);

View File

@@ -17,11 +17,11 @@ class EditorSceneRuntime;
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::Rendering::Host {
class TexturePort;
class UiTextureHost;
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
@@ -31,11 +31,11 @@ class SceneViewportFeature {
public:
void Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
const BuiltInIcons* builtInIcons,
ViewportHostService& viewportHostService);
void Shutdown(
Ports::TexturePort& textureHost,
Rendering::Host::UiTextureHost& textureHost,
ViewportHostService& viewportHostService);
void ResetInteractionState();
void SetCommandFocusService(EditorCommandFocusService* commandFocusService);

View File

@@ -1,6 +1,6 @@
#include "Features/Scene/SceneViewportToolOverlay.h"
#include "Ports/TexturePort.h"
#include "Rendering/Host/UiTextureHost.h"
#include <XCEditor/Widgets/UIEditorTextLayout.h>
@@ -202,7 +202,7 @@ UIRect BuildToggleButtonRect(
bool SceneViewportToolOverlay::Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& renderer) {
Rendering::Host::UiTextureHost& renderer) {
Shutdown(renderer);
const std::filesystem::path iconRoot =
@@ -232,7 +232,7 @@ bool SceneViewportToolOverlay::Initialize(
return loadedAnyTexture;
}
void SceneViewportToolOverlay::Shutdown(Ports::TexturePort& renderer) {
void SceneViewportToolOverlay::Shutdown(Rendering::Host::UiTextureHost& renderer) {
for (ToolTextureSet& textureSet : m_toolTextures) {
renderer.ReleaseTexture(textureSet.inactiveTexture);
renderer.ReleaseTexture(textureSet.activeTexture);

View File

@@ -1,7 +1,7 @@
#pragma once
#include "Scene/SceneToolState.h"
#include "Ports/PortFwd.h"
#include "Rendering/Host/HostFwd.h"
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Types.h>
@@ -59,8 +59,8 @@ class SceneViewportToolOverlay {
public:
bool Initialize(
const std::filesystem::path& repoRoot,
Ports::TexturePort& renderer);
void Shutdown(Ports::TexturePort& renderer);
Rendering::Host::UiTextureHost& renderer);
void Shutdown(Rendering::Host::UiTextureHost& renderer);
void ResetFrame();
void BuildFrame(

View File

@@ -1,10 +1,10 @@
#include "Platform/Win32/EditorWindowChromeController.h"
#include "Platform/Win32/Chrome/EditorWindowChromeController.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowFrameDriver.h"
#include "Platform/Win32/EditorWindowRuntimeController.h"
#include "Platform/Win32/EditorWindowState.h"
#include "Platform/Win32/EditorWindowSupport.h"
#include "Platform/Win32/Windowing/EditorWindow.h"
#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h"
#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h"
#include "Platform/Win32/Windowing/EditorWindowState.h"
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
#include <XCEditor/Foundation/UIEditorTheme.h>
#include <XCEngine/UI/DrawData.h>
@@ -233,10 +233,6 @@ bool EditorWindowChromeController::HandleSystemCommand(
EditorContext& editorContext,
bool globalTabDragActive,
WPARAM wParam) {
if (!window.IsBorderlessWindowEnabled()) {
return false;
}
switch (wParam & 0xFFF0u) {
case SC_MAXIMIZE:
ToggleMaximizeRestore(window, editorContext, globalTabDragActive);
@@ -438,9 +434,7 @@ void EditorWindowChromeController::ForceClearResizeState(EditorWindow& window) {
Host::BorderlessWindowResizeEdge EditorWindowChromeController::HitTestResizeEdge(
const EditorWindow& window,
LPARAM lParam) const {
if (!window.IsBorderlessWindowEnabled() ||
window.m_state->window.hwnd == nullptr ||
window.IsBorderlessWindowMaximized()) {
if (window.m_state->window.hwnd == nullptr || IsBorderlessWindowMaximized()) {
return Host::BorderlessWindowResizeEdge::None;
}
@@ -499,7 +493,7 @@ bool EditorWindowChromeController::HandleChromeButtonDown(EditorWindow& window,
return true;
case Host::BorderlessWindowChromeHitTarget::DragRegion:
if (window.m_state->window.hwnd != nullptr) {
if (window.IsBorderlessWindowMaximized()) {
if (IsBorderlessWindowMaximized()) {
POINT screenPoint = {};
if (GetCursorPos(&screenPoint)) {
BeginBorderlessWindowDragRestore(screenPoint);
@@ -661,7 +655,7 @@ void EditorWindowChromeController::ClearChromeState(EditorWindow& window) {
Host::BorderlessWindowChromeHitTarget EditorWindowChromeController::HitTestChrome(
const EditorWindow& window,
LPARAM lParam) const {
if (!window.IsBorderlessWindowEnabled() || window.m_state->window.hwnd == nullptr) {
if (window.m_state->window.hwnd == nullptr) {
return Host::BorderlessWindowChromeHitTarget::None;
}
@@ -684,8 +678,12 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa
float clientWidthDips) const {
float leadingOccupiedRight = 0.0f;
if (ShouldUseDetachedTitleBarTabStrip(window)) {
const EditorWindowTitleBarBinding* titleBarBinding =
window.m_runtime->TryGetTitleBarBinding();
leadingOccupiedRight = ResolveDetachedTabWidth(
window.m_runtime->ResolveTabStripTitleText("Panel"),
titleBarBinding != nullptr
? titleBarBinding->ResolveTabStripTitleText("Panel")
: std::string("Panel"),
&window.m_runtime->GetTextMeasurer());
}
@@ -696,18 +694,16 @@ Host::BorderlessWindowChromeLayout EditorWindowChromeController::ResolveChromeLa
bool EditorWindowChromeController::ShouldUseDetachedTitleBarTabStrip(
const EditorWindow& window) const {
const EditorWindowTitleBarBinding* titleBarBinding = window.m_runtime->TryGetTitleBarBinding();
return !window.m_state->window.primary &&
window.m_runtime->ShouldUseDetachedTitleBarTabStrip();
titleBarBinding != nullptr &&
titleBarBinding->ShouldUseDetachedTitleBarTabStrip();
}
void EditorWindowChromeController::AppendChrome(
const EditorWindow& window,
UIDrawList& drawList,
float clientWidthDips) const {
if (!window.IsBorderlessWindowEnabled()) {
return;
}
const Host::BorderlessWindowChromeLayout layout =
ResolveChromeLayout(window, clientWidthDips);
const bool useDetachedTitleBarTabStrip = ShouldUseDetachedTitleBarTabStrip(window);
@@ -753,10 +749,17 @@ void EditorWindowChromeController::AppendChrome(
0.0f,
(layout.titleBarRect.height - kBorderlessTitleBarFontSize) * 0.5f -
1.0f)),
window.m_runtime->ResolveDetachedWindowTitleText(
window.m_state->window.titleText.empty()
? std::string_view("XCEngine Editor")
: std::string_view(window.m_state->window.titleText)),
[&window]() {
const std::string_view fallbackWindowTitle =
window.m_state->window.titleText.empty()
? std::string_view("XCEngine Editor")
: std::string_view(window.m_state->window.titleText);
const EditorWindowTitleBarBinding* titleBarBinding =
window.m_runtime->TryGetTitleBarBinding();
return titleBarBinding != nullptr
? titleBarBinding->ResolveDetachedWindowTitleText(fallbackWindowTitle)
: std::string(fallbackWindowTitle);
}(),
kShellTextColor,
kBorderlessTitleBarFontSize);
}
@@ -817,7 +820,7 @@ void EditorWindowChromeController::AppendChrome(
drawList,
layout,
GetChromeState(),
window.IsBorderlessWindowMaximized());
IsBorderlessWindowMaximized());
}
void EditorWindowChromeController::ApplyResizeCursorHoverPriority() {
@@ -903,7 +906,7 @@ void EditorWindowChromeController::ToggleMaximizeRestore(
return;
}
if (!window.IsBorderlessWindowMaximized()) {
if (!IsBorderlessWindowMaximized()) {
RECT currentRect = {};
RECT workAreaRect = {};
if (!QueryCurrentWindowRect(window, currentRect) ||

View File

@@ -1,7 +1,7 @@
#pragma once
#include <Platform/Win32/BorderlessWindowChrome.h>
#include <Platform/Win32/HostRuntimeState.h>
#include <Platform/Win32/Chrome/BorderlessWindowChrome.h>
#include <Platform/Win32/Chrome/HostRuntimeState.h>
namespace XCEngine::UI {

View File

@@ -1,51 +0,0 @@
#include "Platform/Win32/EditorAddComponentUtilityWindowContentController.h"
#include <XCEngine/UI/DrawData.h>
namespace XCEngine::UI::Editor::App {
EditorAddComponentUtilityWindowContentController::
EditorAddComponentUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize)
: EditorStandaloneUtilityWindowContentController(minimumOuterSize) {}
EditorAddComponentUtilityWindowContentController::
~EditorAddComponentUtilityWindowContentController() = default;
void EditorAddComponentUtilityWindowContentController::OnShutdown() {
m_addComponentPanel.ResetInteractionState();
}
void EditorAddComponentUtilityWindowContentController::OnResetInteractionState() {
m_addComponentPanel.ResetInteractionState();
}
EditorWindowFrameTransferRequests
EditorAddComponentUtilityWindowContentController::UpdateStandaloneContent(
const EditorStandaloneUtilityWindowFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) {
m_addComponentPanel.Update(
context.editorContext,
AddComponentPanelHostContext{
.mounted = true,
.bounds = context.bounds,
.focused = context.focused,
.focusGained = context.focusGained,
.focusLost = context.focusLost,
},
context.inputEvents);
::XCEngine::UI::UIDrawList& drawList =
drawData.EmplaceDrawList("XCEditorUtility.AddComponent");
m_addComponentPanel.Append(drawList);
return {};
}
std::unique_ptr<EditorWindowContentController>
CreateEditorAddComponentUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize) {
return std::make_unique<EditorAddComponentUtilityWindowContentController>(
minimumOuterSize);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,31 +0,0 @@
#pragma once
#include "Features/Inspector/AddComponentPanel.h"
#include "Platform/Win32/EditorStandaloneUtilityWindowContentController.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
class EditorAddComponentUtilityWindowContentController final
: public EditorStandaloneUtilityWindowContentController {
public:
explicit EditorAddComponentUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize);
~EditorAddComponentUtilityWindowContentController() override;
private:
void OnShutdown() override;
void OnResetInteractionState() override;
EditorWindowFrameTransferRequests UpdateStandaloneContent(
const EditorStandaloneUtilityWindowFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) override;
AddComponentPanel m_addComponentPanel = {};
};
std::unique_ptr<EditorWindowContentController>
CreateEditorAddComponentUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize);
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,52 +0,0 @@
#include "Platform/Win32/EditorColorPickerUtilityWindowContentController.h"
#include <XCEngine/UI/DrawData.h>
namespace XCEngine::UI::Editor::App {
EditorColorPickerUtilityWindowContentController::
EditorColorPickerUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize)
: EditorStandaloneUtilityWindowContentController(minimumOuterSize) {}
EditorColorPickerUtilityWindowContentController::
~EditorColorPickerUtilityWindowContentController() = default;
void EditorColorPickerUtilityWindowContentController::OnShutdown() {
m_colorPickerPanel.ResetInteractionState();
}
void EditorColorPickerUtilityWindowContentController::OnResetInteractionState() {
m_colorPickerPanel.ResetInteractionState();
}
EditorWindowFrameTransferRequests
EditorColorPickerUtilityWindowContentController::UpdateStandaloneContent(
const EditorStandaloneUtilityWindowFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) {
m_colorPickerPanel.Update(
context.editorContext,
ColorPickerPanelHostContext{
.mounted = true,
.bounds = context.bounds,
.allowInteraction = true,
.focused = context.focused,
.focusGained = context.focusGained,
.focusLost = context.focusLost,
},
context.inputEvents);
::XCEngine::UI::UIDrawList& drawList =
drawData.EmplaceDrawList("XCEditorUtility.ColorPicker");
m_colorPickerPanel.Append(drawList);
return {};
}
std::unique_ptr<EditorWindowContentController>
CreateEditorColorPickerUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize) {
return std::make_unique<EditorColorPickerUtilityWindowContentController>(
minimumOuterSize);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,31 +0,0 @@
#pragma once
#include "Features/ColorPicker/ColorPickerPanel.h"
#include "Platform/Win32/EditorStandaloneUtilityWindowContentController.h"
#include <memory>
namespace XCEngine::UI::Editor::App {
class EditorColorPickerUtilityWindowContentController final
: public EditorStandaloneUtilityWindowContentController {
public:
explicit EditorColorPickerUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize);
~EditorColorPickerUtilityWindowContentController() override;
private:
void OnShutdown() override;
void OnResetInteractionState() override;
EditorWindowFrameTransferRequests UpdateStandaloneContent(
const EditorStandaloneUtilityWindowFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) override;
ColorPickerPanel m_colorPickerPanel = {};
};
std::unique_ptr<EditorWindowContentController>
CreateEditorColorPickerUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize);
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,81 +0,0 @@
#include "Platform/Win32/EditorStandaloneUtilityWindowContentController.h"
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
namespace XCEngine::UI::Editor::App {
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
EditorStandaloneUtilityWindowContentController::
EditorStandaloneUtilityWindowContentController(
const ::XCEngine::UI::UISize& minimumOuterSize)
: m_minimumOuterSize(minimumOuterSize) {}
EditorStandaloneUtilityWindowContentController::
~EditorStandaloneUtilityWindowContentController() = default;
void EditorStandaloneUtilityWindowContentController::ReplaceWorkspaceController(
UIEditorWorkspaceController) {}
void EditorStandaloneUtilityWindowContentController::Shutdown() {
OnShutdown();
m_shellInteractionState = {};
m_shellFrame = {};
m_windowFocused = false;
}
void EditorStandaloneUtilityWindowContentController::ResetInteractionState() {
OnResetInteractionState();
}
EditorWindowFrameTransferRequests
EditorStandaloneUtilityWindowContentController::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;
return UpdateStandaloneContent(
EditorStandaloneUtilityWindowFrameContext{
.editorContext = context.editorContext,
.bounds = context.bounds,
.inputEvents = context.inputEvents,
.focused = m_windowFocused,
.focusGained = focusGained,
.focusLost = focusLost,
},
drawData);
}
const UIEditorShellInteractionFrame&
EditorStandaloneUtilityWindowContentController::GetShellFrame() const {
return m_shellFrame;
}
const UIEditorShellInteractionState&
EditorStandaloneUtilityWindowContentController::GetShellInteractionState() const {
return m_shellInteractionState;
}
::XCEngine::UI::UISize
EditorStandaloneUtilityWindowContentController::ResolveMinimumOuterSize() const {
return m_minimumOuterSize;
}
void EditorStandaloneUtilityWindowContentController::OnShutdown() {}
void EditorStandaloneUtilityWindowContentController::OnResetInteractionState() {}
} // namespace XCEngine::UI::Editor::App

View File

@@ -0,0 +1,103 @@
#include "Platform/Win32/Content/EditorUtilityWindowContentController.h"
#include "UtilityWindows/EditorUtilityWindowPanel.h"
#include "UtilityWindows/EditorUtilityWindowRegistry.h"
#include <XCEngine/UI/DrawData.h>
namespace XCEngine::UI::Editor::App {
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
EditorUtilityWindowContentController::EditorUtilityWindowContentController(
std::unique_ptr<EditorUtilityWindowPanel> 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<EditorWindowContentController> CreateEditorUtilityWindowContentController(
const EditorUtilityWindowDescriptor& descriptor) {
std::unique_ptr<EditorUtilityWindowPanel> panel =
CreateEditorUtilityWindowPanel(descriptor.kind);
if (panel == nullptr) {
return nullptr;
}
return std::make_unique<EditorUtilityWindowContentController>(
std::move(panel),
descriptor.minimumOuterSize);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/Content/EditorWindowContentController.h"
#include <XCEditor/Shell/UIEditorShellInteraction.h>
@@ -10,47 +10,35 @@
namespace XCEngine::UI::Editor::App {
struct EditorStandaloneUtilityWindowFrameContext {
EditorContext& editorContext;
const ::XCEngine::UI::UIRect& bounds;
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents;
bool focused = false;
bool focusGained = false;
bool focusLost = false;
};
class EditorUtilityWindowPanel;
struct EditorUtilityWindowDescriptor;
class EditorStandaloneUtilityWindowContentController
class EditorUtilityWindowContentController final
: public EditorWindowContentController {
public:
explicit EditorStandaloneUtilityWindowContentController(
EditorUtilityWindowContentController(
std::unique_ptr<EditorUtilityWindowPanel> panel,
const ::XCEngine::UI::UISize& minimumOuterSize);
~EditorStandaloneUtilityWindowContentController() override;
~EditorUtilityWindowContentController() override;
void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) 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;
protected:
virtual void OnShutdown();
virtual void OnResetInteractionState();
virtual EditorWindowFrameTransferRequests UpdateStandaloneContent(
const EditorStandaloneUtilityWindowFrameContext& context,
::XCEngine::UI::UIDrawData& drawData) = 0;
private:
std::unique_ptr<EditorUtilityWindowPanel> m_panel = {};
::XCEngine::UI::UISize m_minimumOuterSize = {};
UIEditorShellInteractionState m_shellInteractionState = {};
UIEditorShellInteractionFrame m_shellFrame = {};
bool m_windowFocused = true;
};
std::unique_ptr<EditorWindowContentController> CreateEditorUtilityWindowContentController(
const EditorUtilityWindowDescriptor& descriptor);
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
@@ -41,12 +41,12 @@ struct UIEditorDockHostDropPreviewState;
} // namespace XCEngine::UI::Editor
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::Rendering::Host {
class TexturePort;
class ViewportRenderPort;
class UiTextureHost;
class ViewportRenderHost;
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host
namespace XCEngine::UI::Editor::App {
@@ -58,12 +58,57 @@ enum class EditorWindowContentCursorKind : std::uint8_t {
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;
Ports::TexturePort& textureHost;
Rendering::Host::UiTextureHost& textureHost;
UIEditorTextMeasurer& textMeasurer;
Ports::ViewportRenderPort& viewportRenderer;
Rendering::Host::ViewportRenderHost& viewportRenderer;
};
struct EditorWindowContentFrameContext {
@@ -80,13 +125,24 @@ class EditorWindowContentController {
public:
virtual ~EditorWindowContentController() = default;
virtual const UIEditorWorkspaceController* TryGetWorkspaceController() const {
virtual EditorWindowWorkspaceBinding* TryGetWorkspaceBinding() {
return nullptr;
}
virtual UIEditorWorkspaceController* TryGetMutableWorkspaceController() {
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 ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) = 0;
virtual void Initialize(const EditorWindowContentInitializationContext&) {}
virtual void Shutdown() {}
@@ -101,49 +157,7 @@ public:
virtual const UIEditorShellInteractionFrame& GetShellFrame() const = 0;
virtual const UIEditorShellInteractionState& GetShellInteractionState() const = 0;
virtual void SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState&) {}
virtual void ClearExternalDockHostDropPreview() {}
virtual bool TryResolveDockTabDragHotspot(
std::string_view,
std::string_view,
const ::XCEngine::UI::UIPoint&,
::XCEngine::UI::UIPoint&) const {
return false;
}
virtual UIEditorDockHostTabDropTarget ResolveDockTabDropTarget(
const ::XCEngine::UI::UIPoint&) const {
return {};
}
virtual bool HasHostedContentCapture() const {
return false;
}
virtual bool HasShellInteractiveCapture() const {
return false;
}
virtual bool HasInteractiveCapture() const {
return false;
}
virtual EditorWindowContentCursorKind GetHostedContentCursorKind() const {
return EditorWindowContentCursorKind::Arrow;
}
virtual EditorWindowContentCursorKind GetDockCursorKind() const {
return EditorWindowContentCursorKind::Arrow;
}
virtual ::XCEngine::UI::UISize ResolveMinimumOuterSize() const = 0;
virtual bool ShouldUseDetachedTitleBarTabStrip() const {
return false;
}
virtual std::string ResolveTabStripTitleText(std::string_view fallbackTitle) const {
return std::string(fallbackTitle);
}
virtual std::string ResolveDetachedWindowTitleText(
std::string_view fallbackWindowTitle) const {
return std::string(fallbackWindowTitle);
}
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,4 +1,4 @@
#include "Platform/Win32/EditorWorkspaceWindowContentController.h"
#include "Platform/Win32/Content/EditorWorkspaceWindowContentController.h"
#include <XCEditor/Workspace/UIEditorDetachedWindowPolicy.h>
@@ -37,13 +37,36 @@ EditorWorkspaceWindowContentController::EditorWorkspaceWindowContentController(
EditorWorkspaceWindowContentController::~EditorWorkspaceWindowContentController() = default;
const UIEditorWorkspaceController*
EditorWorkspaceWindowContentController::TryGetWorkspaceController() const {
return &m_workspaceController;
EditorWindowWorkspaceBinding* EditorWorkspaceWindowContentController::TryGetWorkspaceBinding() {
return this;
}
UIEditorWorkspaceController*
EditorWorkspaceWindowContentController::TryGetMutableWorkspaceController() {
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;
}
@@ -161,6 +184,11 @@ std::string EditorWorkspaceWindowContentController::ResolveTabStripTitleText(
return ResolveUIEditorDetachedWorkspaceTitle(m_workspaceController, fallbackTitle);
}
std::string EditorWorkspaceWindowContentController::ResolveDetachedWindowTitleText(
std::string_view fallbackWindowTitle) const {
return ResolveUIEditorDetachedWorkspaceTitle(m_workspaceController, fallbackWindowTitle);
}
std::unique_ptr<EditorWindowContentController> CreateEditorWorkspaceWindowContentController(
UIEditorWorkspaceController workspaceController) {
return std::make_unique<EditorWorkspaceWindowContentController>(

View File

@@ -1,8 +1,8 @@
#pragma once
#include "Composition/EditorShellRuntime.h"
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/EditorWindowFrameOrchestrator.h"
#include "Platform/Win32/Content/EditorWindowContentController.h"
#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h"
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
@@ -10,13 +10,23 @@
namespace XCEngine::UI::Editor::App {
class EditorWorkspaceWindowContentController final : public EditorWindowContentController {
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;
UIEditorWorkspaceController* TryGetMutableWorkspaceController() override;
void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) override;
void Initialize(const EditorWindowContentInitializationContext& context) override;
@@ -54,6 +64,8 @@ public:
::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 = {};

View File

@@ -1,7 +1,7 @@
#include "Platform/Win32/EditorWindowFrameDriver.h"
#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h"
#include "Platform/Win32/EditorWindowChromeController.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/Chrome/EditorWindowChromeController.h"
#include "Platform/Win32/Windowing/EditorWindow.h"
namespace XCEngine::UI::Editor::App {

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
namespace XCEngine::UI::Editor::App {

View File

@@ -1,9 +1,9 @@
#include "Platform/Win32/EditorWindowFrameOrchestrator.h"
#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h"
#include "Composition/EditorContext.h"
#include "Composition/EditorShellRuntime.h"
#include "Composition/EditorShellVariant.h"
#include "Platform/Win32/EditorWindowSupport.h"
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
#include <XCEngine/UI/DrawData.h>

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <XCEngine/UI/Types.h>

View File

@@ -1,4 +1,4 @@
#include "Platform/Win32/EditorWindowInputController.h"
#include "Platform/Win32/Runtime/EditorWindowInputController.h"
#include <XCEngine/Input/InputTypes.h>

View File

@@ -4,9 +4,9 @@
#define NOMINMAX
#endif
#include "Platform/Win32/EditorWindowPointerCapture.h"
#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h"
#include <Platform/Win32/InputModifierTracker.h>
#include <Platform/Win32/Runtime/InputModifierTracker.h>
#include <XCEngine/UI/Types.h>

View File

@@ -1,8 +1,8 @@
#include "Platform/Win32/EditorWindowRuntimeController.h"
#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h"
#include "Bootstrap/EditorResources.h"
#include "Composition/EditorContext.h"
#include "Platform/Win32/EditorWindowSupport.h"
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
#include "Support/EmbeddedPngLoader.h"
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
@@ -36,34 +36,41 @@ bool EditorWindowRuntimeController::IsReady() const {
return m_ready;
}
const UIEditorWorkspaceController* EditorWindowRuntimeController::TryGetWorkspaceController() const {
EditorWindowWorkspaceBinding* EditorWindowRuntimeController::TryGetWorkspaceBinding() {
return m_contentController != nullptr
? m_contentController->TryGetWorkspaceController()
? m_contentController->TryGetWorkspaceBinding()
: nullptr;
}
UIEditorWorkspaceController* EditorWindowRuntimeController::TryGetMutableWorkspaceController() {
const EditorWindowWorkspaceBinding* EditorWindowRuntimeController::TryGetWorkspaceBinding() const {
return m_contentController != nullptr
? m_contentController->TryGetMutableWorkspaceController()
? m_contentController->TryGetWorkspaceBinding()
: nullptr;
}
const UIEditorWorkspaceController& EditorWindowRuntimeController::GetWorkspaceController() const {
const UIEditorWorkspaceController* workspaceController = TryGetWorkspaceController();
assert(workspaceController != nullptr);
return *workspaceController;
EditorWindowDockHostBinding* EditorWindowRuntimeController::TryGetDockHostBinding() {
return m_contentController != nullptr
? m_contentController->TryGetDockHostBinding()
: nullptr;
}
UIEditorWorkspaceController& EditorWindowRuntimeController::GetMutableWorkspaceController() {
UIEditorWorkspaceController* workspaceController = TryGetMutableWorkspaceController();
assert(workspaceController != nullptr);
return *workspaceController;
const EditorWindowDockHostBinding* EditorWindowRuntimeController::TryGetDockHostBinding() const {
return m_contentController != nullptr
? m_contentController->TryGetDockHostBinding()
: nullptr;
}
void EditorWindowRuntimeController::ReplaceWorkspaceController(
UIEditorWorkspaceController workspaceController) {
assert(m_contentController != nullptr);
m_contentController->ReplaceWorkspaceController(std::move(workspaceController));
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 {
@@ -77,88 +84,11 @@ const UIEditorShellInteractionState& EditorWindowRuntimeController::GetShellInte
return m_contentController->GetShellInteractionState();
}
void EditorWindowRuntimeController::SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState& preview) {
assert(m_contentController != nullptr);
m_contentController->SetExternalDockHostDropPreview(preview);
}
void EditorWindowRuntimeController::ClearExternalDockHostDropPreview() {
if (m_contentController != nullptr) {
m_contentController->ClearExternalDockHostDropPreview();
}
}
bool EditorWindowRuntimeController::TryResolveDockTabDragHotspot(
std::string_view nodeId,
std::string_view panelId,
const ::XCEngine::UI::UIPoint& point,
::XCEngine::UI::UIPoint& outHotspot) const {
return m_contentController != nullptr &&
m_contentController->TryResolveDockTabDragHotspot(
nodeId,
panelId,
point,
outHotspot);
}
UIEditorDockHostTabDropTarget EditorWindowRuntimeController::ResolveDockTabDropTarget(
const ::XCEngine::UI::UIPoint& point) const {
assert(m_contentController != nullptr);
return m_contentController->ResolveDockTabDropTarget(point);
}
bool EditorWindowRuntimeController::HasHostedContentCapture() const {
return m_contentController != nullptr &&
m_contentController->HasHostedContentCapture();
}
bool EditorWindowRuntimeController::HasShellInteractiveCapture() const {
return m_contentController != nullptr &&
m_contentController->HasShellInteractiveCapture();
}
bool EditorWindowRuntimeController::HasInteractiveCapture() const {
return m_contentController != nullptr &&
m_contentController->HasInteractiveCapture();
}
EditorWindowContentCursorKind EditorWindowRuntimeController::GetHostedContentCursorKind() const {
return m_contentController != nullptr
? m_contentController->GetHostedContentCursorKind()
: EditorWindowContentCursorKind::Arrow;
}
EditorWindowContentCursorKind EditorWindowRuntimeController::GetDockCursorKind() const {
return m_contentController != nullptr
? m_contentController->GetDockCursorKind()
: EditorWindowContentCursorKind::Arrow;
}
::XCEngine::UI::UISize EditorWindowRuntimeController::ResolveMinimumOuterSize() const {
assert(m_contentController != nullptr);
return m_contentController->ResolveMinimumOuterSize();
}
bool EditorWindowRuntimeController::ShouldUseDetachedTitleBarTabStrip() const {
return m_contentController != nullptr &&
m_contentController->ShouldUseDetachedTitleBarTabStrip();
}
std::string EditorWindowRuntimeController::ResolveTabStripTitleText(
std::string_view fallbackTitle) const {
return m_contentController != nullptr
? m_contentController->ResolveTabStripTitleText(fallbackTitle)
: std::string(fallbackTitle);
}
std::string EditorWindowRuntimeController::ResolveDetachedWindowTitleText(
std::string_view fallbackWindowTitle) const {
return m_contentController != nullptr
? m_contentController->ResolveDetachedWindowTitleText(fallbackWindowTitle)
: std::string(fallbackWindowTitle);
}
void EditorWindowRuntimeController::SetDpiScale(float dpiScale) {
m_dpiScale = dpiScale > 0.0f ? dpiScale : 1.0f;
m_textSystem.SetDpiScale(m_dpiScale);
@@ -248,8 +178,11 @@ bool EditorWindowRuntimeController::Initialize(
LogRuntimeTrace("icons", "titlebar logo_icon.png: " + titleBarLogoError);
}
if (const UIEditorWorkspaceController* workspaceController = TryGetWorkspaceController();
workspaceController != nullptr) {
if (const EditorWindowWorkspaceBinding* workspaceBinding = TryGetWorkspaceBinding();
workspaceBinding != nullptr) {
const UIEditorWorkspaceController* workspaceController =
workspaceBinding->TryGetWorkspaceController();
assert(workspaceController != nullptr);
LogRuntimeTrace(
"app",
"shell runtime initialized: " +

View File

@@ -4,8 +4,8 @@
#define NOMINMAX
#endif
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/EditorWindowScreenshotController.h"
#include "Platform/Win32/Content/EditorWindowContentController.h"
#include "Platform/Win32/Runtime/EditorWindowScreenshotController.h"
#include <Rendering/D3D12/D3D12UiRenderer.h>
#include <Rendering/D3D12/D3D12UiTextSystem.h>
@@ -39,35 +39,16 @@ public:
bool IsReady() const;
const UIEditorWorkspaceController* TryGetWorkspaceController() const;
UIEditorWorkspaceController* TryGetMutableWorkspaceController();
const UIEditorWorkspaceController& GetWorkspaceController() const;
UIEditorWorkspaceController& GetMutableWorkspaceController();
void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController);
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;
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;
bool HasHostedContentCapture() const;
bool HasShellInteractiveCapture() const;
bool HasInteractiveCapture() const;
EditorWindowContentCursorKind GetHostedContentCursorKind() const;
EditorWindowContentCursorKind GetDockCursorKind() const;
::XCEngine::UI::UISize ResolveMinimumOuterSize() const;
bool ShouldUseDetachedTitleBarTabStrip() const;
std::string ResolveTabStripTitleText(std::string_view fallbackTitle) const;
std::string ResolveDetachedWindowTitleText(
std::string_view fallbackWindowTitle) const;
void SetDpiScale(float dpiScale);
::XCEngine::UI::Editor::UIEditorTextMeasurer& GetTextMeasurer();

View File

@@ -1,4 +1,4 @@
#include "Platform/Win32/EditorWindowScreenshotController.h"
#include "Platform/Win32/Runtime/EditorWindowScreenshotController.h"
#include "Support/ExecutablePath.h"

View File

@@ -1,4 +1,4 @@
#include "Platform/Win32/Win32SystemInteractionHost.h"
#include "Platform/Win32/System/Win32SystemInteractionHost.h"
#include "Support/StringEncoding.h"

View File

@@ -1,10 +1,10 @@
#pragma once
#include "Ports/SystemInteractionPort.h"
#include "System/SystemInteractionService.h"
namespace XCEngine::UI::Editor::Host {
class Win32SystemInteractionHost final : public Ports::SystemInteractionPort {
class Win32SystemInteractionHost final : public System::SystemInteractionService {
public:
bool CopyTextToClipboard(std::string_view text) override;
bool RevealPathInFileBrowser(

View File

@@ -1,4 +1,4 @@
#include "Platform/Win32/EditorFloatingWindowPlacement.h"
#include "Platform/Win32/Windowing/EditorFloatingWindowPlacement.h"
#include <algorithm>

View File

@@ -1,11 +1,12 @@
#include "Platform/Win32/WindowManager/EditorUtilityWindowCoordinator.h"
#include "Platform/Win32/Windowing/EditorUtilityWindowCoordinator.h"
#include "Platform/Win32/EditorFloatingWindowPlacement.h"
#include "Platform/Win32/EditorUtilityWindowRegistry.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.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 <cmath>
@@ -88,7 +89,7 @@ bool EditorUtilityWindowCoordinator::TryProcessOpenUtilityWindowRequest(
}
std::unique_ptr<EditorWindowContentController> contentController =
CreateEditorUtilityWindowContentController(request.kind);
CreateEditorUtilityWindowContentController(*descriptor);
if (contentController == nullptr) {
LogRuntimeTrace(
"utility",

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <string_view>

View File

@@ -1,18 +1,19 @@
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/Windowing/EditorWindow.h"
#include "Bootstrap/EditorResources.h"
#include "Platform/Win32/EditorWindowChromeController.h"
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/EditorWindowFrameDriver.h"
#include "Platform/Win32/EditorWindowSupport.h"
#include "Platform/Win32/EditorWindowFrameOrchestrator.h"
#include "Platform/Win32/EditorWindowInputController.h"
#include "Platform/Win32/EditorWindowState.h"
#include "Platform/Win32/EditorWindowRuntimeController.h"
#include "Platform/Win32/Chrome/EditorWindowChromeController.h"
#include "Platform/Win32/Content/EditorWindowContentController.h"
#include "Platform/Win32/Runtime/EditorWindowFrameDriver.h"
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
#include "Platform/Win32/Runtime/EditorWindowFrameOrchestrator.h"
#include "Platform/Win32/Runtime/EditorWindowInputController.h"
#include "Platform/Win32/Windowing/EditorWindowState.h"
#include "Platform/Win32/Runtime/EditorWindowRuntimeController.h"
#include "Composition/EditorContext.h"
#include <XCEditor/Docking/UIEditorDockHostTransfer.h>
#include <XCEditor/Foundation/UIEditorRuntimeTrace.h>
#include <XCEditor/Shell/UIEditorShellInteraction.h>
#include <XCEngine/UI/Types.h>
#include <cassert>
#include <algorithm>
#include <sstream>
#include <windowsx.h>
@@ -124,46 +125,21 @@ bool EditorWindow::IsRenderReady() const {
return m_runtime->IsReady();
}
bool EditorWindow::IsTrackingMouseLeave() const {
return m_inputController->IsTrackingMouseLeave();
}
bool EditorWindow::HasHoveredBorderlessResizeEdge() const {
return m_chromeController->GetHoveredBorderlessResizeEdge() !=
Host::BorderlessWindowResizeEdge::None;
}
const std::wstring& EditorWindow::GetTitle() const {
return m_state->window.title;
}
const UIEditorWorkspaceController* EditorWindow::TryGetWorkspaceController() const {
return m_runtime->TryGetWorkspaceController();
const EditorWindowWorkspaceBinding* workspaceBinding = m_runtime->TryGetWorkspaceBinding();
return workspaceBinding != nullptr
? workspaceBinding->TryGetWorkspaceController()
: nullptr;
}
const UIEditorWorkspaceController& EditorWindow::GetWorkspaceController() const {
return m_runtime->GetWorkspaceController();
}
UIEditorWorkspaceController& EditorWindow::GetMutableWorkspaceController() {
return m_runtime->GetMutableWorkspaceController();
}
bool EditorWindow::HasHostedContentCapture() const {
return m_runtime->HasHostedContentCapture();
}
bool EditorWindow::HasShellInteractiveCapture() const {
return m_runtime->HasShellInteractiveCapture();
}
void EditorWindow::SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState& preview) {
m_runtime->SetExternalDockHostDropPreview(preview);
}
void EditorWindow::ClearExternalDockHostDropPreview() {
m_runtime->ClearExternalDockHostDropPreview();
const UIEditorWorkspaceController* workspaceController = TryGetWorkspaceController();
assert(workspaceController != nullptr);
return *workspaceController;
}
void EditorWindow::AttachHwnd(HWND hwnd) {
@@ -193,17 +169,15 @@ void EditorWindow::SetPrimary(bool primary) {
m_state->window.primary = primary;
}
void EditorWindow::SetTrackingMouseLeave(bool trackingMouseLeave) {
m_inputController->SetTrackingMouseLeave(trackingMouseLeave);
}
void EditorWindow::SetTitle(std::wstring title) {
m_state->window.title = std::move(title);
UpdateCachedTitleText();
}
void EditorWindow::ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController) {
m_runtime->ReplaceWorkspaceController(std::move(workspaceController));
EditorWindowWorkspaceBinding* workspaceBinding = m_runtime->TryGetWorkspaceBinding();
assert(workspaceBinding != nullptr);
workspaceBinding->ReplaceWorkspaceController(std::move(workspaceController));
}
void EditorWindow::InvalidateHostWindow() const {
@@ -357,9 +331,15 @@ bool EditorWindow::TryResolveDockTabDragHotspot(
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 (!m_runtime->TryResolveDockTabDragHotspot(
if (!dockHostBinding->TryResolveDockTabDragHotspot(
nodeId,
panelId,
clientPointDips,
@@ -377,7 +357,13 @@ bool EditorWindow::TryResolveDockTabDragHotspot(
bool EditorWindow::TryResolveDockTabDropTarget(
const POINT& screenPoint,
UIEditorDockHostTabDropTarget& outTarget) const {
outTarget = m_runtime->ResolveDockTabDropTarget(
const EditorWindowDockHostBinding* dockHostBinding = m_runtime->TryGetDockHostBinding();
if (dockHostBinding == nullptr) {
outTarget = {};
return false;
}
outTarget = dockHostBinding->ResolveDockTabDropTarget(
ConvertScreenPixelsToClientDips(screenPoint));
return outTarget.valid;
}
@@ -388,7 +374,7 @@ bool EditorWindow::OnResize(UINT width, UINT height) {
if (!matchedPresentedPrediction) {
m_chromeController->ClearPredictedClientPixelSize();
}
if (IsBorderlessWindowEnabled() && m_state->window.hwnd != nullptr) {
if (m_state->window.hwnd != nullptr) {
Host::RefreshBorderlessWindowDwmDecorations(m_state->window.hwnd);
}
@@ -457,106 +443,6 @@ void EditorWindow::UpdateCachedTitleText() {
namespace XCEngine::UI::Editor::App {
bool EditorWindow::IsBorderlessWindowEnabled() const {
return true;
}
bool EditorWindow::IsBorderlessWindowMaximized() const {
return m_chromeController->IsBorderlessWindowMaximized();
}
bool EditorWindow::HandleBorderlessWindowSystemCommand(
EditorContext& editorContext,
bool globalTabDragActive,
WPARAM wParam) {
return m_chromeController->HandleSystemCommand(
*this,
editorContext,
globalTabDragActive,
wParam);
}
bool EditorWindow::HandleBorderlessWindowGetMinMaxInfo(LPARAM lParam) const {
return m_chromeController->HandleGetMinMaxInfo(*this, lParam);
}
LRESULT EditorWindow::HandleBorderlessWindowNcCalcSize(WPARAM wParam, LPARAM lParam) const {
return m_chromeController->HandleNcCalcSize(*this, wParam, lParam);
}
bool EditorWindow::QueryCurrentWindowRect(RECT& outRect) const {
return m_chromeController->QueryCurrentWindowRect(*this, outRect);
}
bool EditorWindow::QueryBorderlessWindowWorkAreaRect(RECT& outRect) const {
return m_chromeController->QueryBorderlessWindowWorkAreaRect(*this, outRect);
}
bool EditorWindow::ApplyPredictedWindowRectTransition(
EditorContext& editorContext,
bool globalTabDragActive,
const RECT& targetRect) {
return m_chromeController->ApplyPredictedWindowRectTransition(
*this,
editorContext,
globalTabDragActive,
targetRect);
}
void EditorWindow::ToggleBorderlessWindowMaximizeRestore(
EditorContext& editorContext,
bool globalTabDragActive) {
m_chromeController->ToggleMaximizeRestore(*this, editorContext, globalTabDragActive);
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
using ::XCEngine::UI::UIRect;
bool EditorWindow::UpdateBorderlessWindowResizeHover(LPARAM lParam) {
return m_chromeController->UpdateResizeHover(*this, lParam);
}
bool EditorWindow::HandleBorderlessWindowResizeButtonDown(LPARAM lParam) {
return m_chromeController->HandleResizeButtonDown(*this, lParam);
}
bool EditorWindow::HandleBorderlessWindowResizeButtonUp() {
return m_chromeController->HandleResizeButtonUp(*this);
}
bool EditorWindow::HandleBorderlessWindowResizePointerMove(
EditorContext& editorContext,
bool globalTabDragActive) {
return m_chromeController->HandleResizePointerMove(
*this,
editorContext,
globalTabDragActive);
}
void EditorWindow::ClearBorderlessWindowResizeState() {
m_chromeController->ClearResizeState(*this);
}
void EditorWindow::ForceClearBorderlessWindowResizeState() {
m_chromeController->ForceClearResizeState(*this);
}
Host::BorderlessWindowResizeEdge EditorWindow::HitTestBorderlessWindowResizeEdge(
LPARAM lParam) const {
return m_chromeController->HitTestResizeEdge(*this, lParam);
}
void EditorWindow::ApplyBorderlessWindowResizeCursorHoverPriority() {
m_chromeController->ApplyResizeCursorHoverPriority();
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
using namespace EditorWindowSupport;
using ::XCEngine::UI::UIDrawData;
using ::XCEngine::UI::UIDrawList;
@@ -656,7 +542,7 @@ EditorWindowFrameTransferRequests EditorWindow::RenderFrame(
}
UIDrawList& windowChromeDrawList = drawData.EmplaceDrawList("XCEditorWindow.Chrome");
AppendBorderlessWindowChrome(windowChromeDrawList, width);
m_chromeController->AppendChrome(*this, windowChromeDrawList, width);
const Host::D3D12WindowRenderLoopPresentResult presentResult = m_runtime->Present(drawData);
if (!presentResult.warning.empty()) {
@@ -714,11 +600,7 @@ EditorWindow::ConsumeQueuedCompletedImmediateFrameTransferRequests() {
}
UIRect EditorWindow::ResolveWorkspaceBounds(float clientWidthDips, float clientHeightDips) const {
if (!IsBorderlessWindowEnabled()) {
return UIRect(0.0f, 0.0f, clientWidthDips, clientHeightDips);
}
if (ShouldUseDetachedTitleBarTabStrip()) {
if (m_chromeController->ShouldUseDetachedTitleBarTabStrip(*this)) {
return UIRect(0.0f, 0.0f, clientWidthDips, clientHeightDips);
}
@@ -737,7 +619,8 @@ EditorWindowFrameTransferRequests EditorWindow::RenderRuntimeFrame(
UIDrawData& drawData) {
SyncShellCapturedPointerButtonsFromSystemState();
std::vector<UIInputEvent> frameEvents = m_inputController->TakePendingEvents();
const bool useDetachedTitleBarTabStrip = ShouldUseDetachedTitleBarTabStrip();
const bool useDetachedTitleBarTabStrip =
m_chromeController->ShouldUseDetachedTitleBarTabStrip(*this);
editorContext.AttachTextMeasurer(m_runtime->GetTextMeasurer());
const Host::D3D12WindowRenderLoopFrameContext frameContext = m_runtime->BeginFrame();
if (!frameContext.warning.empty()) {
@@ -784,12 +667,16 @@ void EditorWindow::SyncShellCapturedPointerButtonsFromSystemState() {
}
void EditorWindow::ApplyShellRuntimePointerCapture() {
if (m_runtime->HasShellInteractiveCapture()) {
const EditorWindowInputFeedbackBinding* inputFeedbackBinding =
m_runtime->TryGetInputFeedbackBinding();
if (inputFeedbackBinding != nullptr &&
inputFeedbackBinding->HasShellInteractiveCapture()) {
AcquirePointerCapture(EditorWindowPointerCaptureOwner::Shell);
return;
}
if (m_runtime->HasHostedContentCapture()) {
if (inputFeedbackBinding != nullptr &&
inputFeedbackBinding->HasHostedContentCapture()) {
AcquirePointerCapture(EditorWindowPointerCaptureOwner::HostedContent);
return;
}
@@ -807,7 +694,6 @@ void EditorWindow::ApplyShellRuntimePointerCapture() {
namespace XCEngine::UI::Editor::App {
using ::XCEngine::UI::UIInputEvent;
using ::XCEngine::UI::UIInputEventType;
using ::XCEngine::UI::UIPointerButton;
@@ -849,16 +735,14 @@ bool EditorWindow::ApplyCurrentCursor() const {
bool EditorWindow::HasInteractiveCaptureState() const {
return m_runtime->HasInteractiveCapture() ||
const EditorWindowInputFeedbackBinding* inputFeedbackBinding =
m_runtime->TryGetInputFeedbackBinding();
return (inputFeedbackBinding != nullptr && inputFeedbackBinding->HasInteractiveCapture()) ||
m_chromeController->IsBorderlessWindowDragRestoreArmed() ||
m_chromeController->IsBorderlessResizeActive() ||
m_inputController->HasPointerCaptureOwner();
}
EditorWindowPointerCaptureOwner EditorWindow::GetPointerCaptureOwner() const {
return m_inputController->GetPointerCaptureOwner();
}
bool EditorWindow::OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const {
return m_inputController->OwnsPointerCapture(owner);
}
@@ -875,10 +759,6 @@ void EditorWindow::ForceReleasePointerCapture() {
m_inputController->ForceReleasePointerCapture(m_state->window.hwnd);
}
void EditorWindow::ClearPointerCaptureOwner() {
m_inputController->ClearPointerCaptureOwner();
}
void EditorWindow::TryStartImmediateShellPointerCapture(LPARAM lParam) {
if (m_state->window.hwnd == nullptr ||
!IsWindow(m_state->window.hwnd) ||
@@ -904,7 +784,6 @@ void EditorWindow::QueuePointerEvent(
WPARAM wParam,
LPARAM lParam,
bool doubleClick) {
UIInputEvent event = {};
m_inputController->QueuePointerEvent(
type,
button,
@@ -960,30 +839,6 @@ void EditorWindow::QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARA
wParam);
}
void EditorWindow::QueueKeyEvent(UIInputEventType type, WPARAM wParam, LPARAM lParam) {
m_inputController->QueueKeyEvent(type, wParam, lParam);
}
void EditorWindow::QueueCharacterEvent(WPARAM wParam, LPARAM) {
m_inputController->QueueCharacterEvent(wParam);
}
void EditorWindow::QueueWindowFocusEvent(UIInputEventType type) {
m_inputController->QueueWindowFocusEvent(type);
}
void EditorWindow::SyncInputModifiersFromSystemState() {
m_inputController->SyncInputModifiersFromSystemState();
}
void EditorWindow::ResetInputModifiers() {
m_inputController->ResetInputModifiers();
}
void EditorWindow::RequestManualScreenshot() {
m_runtime->RequestManualScreenshot("manual_f12");
}
bool EditorWindow::IsPointerInsideClientArea() const {
if (m_state->window.hwnd == nullptr || !IsWindow(m_state->window.hwnd)) {
return false;
@@ -1005,6 +860,8 @@ bool EditorWindow::IsPointerInsideClientArea() const {
}
LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
const EditorWindowInputFeedbackBinding* inputFeedbackBinding =
m_runtime->TryGetInputFeedbackBinding();
const Host::BorderlessWindowResizeEdge borderlessResizeEdge =
m_chromeController->IsBorderlessResizeActive()
? m_chromeController->GetBorderlessResizeEdge()
@@ -1013,7 +870,11 @@ LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
return Host::ResolveBorderlessWindowResizeCursor(borderlessResizeEdge);
}
switch (m_runtime->GetHostedContentCursorKind()) {
const EditorWindowContentCursorKind hostedContentCursorKind =
inputFeedbackBinding != nullptr
? inputFeedbackBinding->GetHostedContentCursorKind()
: EditorWindowContentCursorKind::Arrow;
switch (hostedContentCursorKind) {
case EditorWindowContentCursorKind::ResizeEW:
return IDC_SIZEWE;
case EditorWindowContentCursorKind::ResizeNS:
@@ -1023,7 +884,11 @@ LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
break;
}
switch (m_runtime->GetDockCursorKind()) {
const EditorWindowContentCursorKind dockCursorKind =
inputFeedbackBinding != nullptr
? inputFeedbackBinding->GetDockCursorKind()
: EditorWindowContentCursorKind::Arrow;
switch (dockCursorKind) {
case EditorWindowContentCursorKind::ResizeEW:
return IDC_SIZEWE;
case EditorWindowContentCursorKind::ResizeNS:
@@ -1037,88 +902,3 @@ LPCWSTR EditorWindow::ResolveCurrentCursorResource() const {
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
using namespace EditorWindowSupport;
bool EditorWindow::UpdateBorderlessWindowChromeHover(LPARAM lParam) {
return m_chromeController->UpdateChromeHover(*this, lParam);
}
bool EditorWindow::HandleBorderlessWindowChromeButtonDown(LPARAM lParam) {
return m_chromeController->HandleChromeButtonDown(*this, lParam);
}
bool EditorWindow::HandleBorderlessWindowChromeButtonUp(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam) {
return m_chromeController->HandleChromeButtonUp(
*this,
editorContext,
globalTabDragActive,
lParam);
}
bool EditorWindow::HandleBorderlessWindowChromeDoubleClick(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam) {
return m_chromeController->HandleChromeDoubleClick(
*this,
editorContext,
globalTabDragActive,
lParam);
}
bool EditorWindow::HandleBorderlessWindowChromeDragRestorePointerMove(
EditorContext& editorContext,
bool globalTabDragActive) {
return m_chromeController->HandleChromeDragRestorePointerMove(
*this,
editorContext,
globalTabDragActive);
}
void EditorWindow::ClearBorderlessWindowChromeDragRestoreState() {
m_chromeController->ClearChromeDragRestoreState(*this);
}
void EditorWindow::ClearBorderlessWindowChromeState() {
m_chromeController->ClearChromeState(*this);
}
void EditorWindow::ExecuteBorderlessWindowChromeAction(
EditorContext& editorContext,
bool globalTabDragActive,
Host::BorderlessWindowChromeHitTarget target) {
m_chromeController->ExecuteChromeAction(*this, editorContext, globalTabDragActive, target);
}
} // namespace XCEngine::UI::Editor::App
namespace XCEngine::UI::Editor::App {
bool EditorWindow::ShouldUseDetachedTitleBarTabStrip() const {
return m_chromeController->ShouldUseDetachedTitleBarTabStrip(*this);
}
Host::BorderlessWindowChromeHitTarget EditorWindow::HitTestBorderlessWindowChrome(
LPARAM lParam) const {
return m_chromeController->HitTestChrome(*this, lParam);
}
Host::BorderlessWindowChromeLayout EditorWindow::ResolveBorderlessWindowChromeLayout(
float clientWidthDips) const {
return m_chromeController->ResolveChromeLayout(*this, clientWidthDips);
}
void EditorWindow::AppendBorderlessWindowChrome(
::XCEngine::UI::UIDrawList& drawList,
float clientWidthDips) const {
m_chromeController->AppendChrome(*this, drawList, clientWidthDips);
}
} // namespace XCEngine::UI::Editor::App

View File

@@ -4,9 +4,9 @@
#define NOMINMAX
#endif
#include "Platform/Win32/EditorWindowPointerCapture.h"
#include "Platform/Win32/EditorWindowState.h"
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowPointerCapture.h"
#include "Platform/Win32/Windowing/EditorWindowState.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <windows.h>
@@ -48,15 +48,6 @@ struct UIEditorDockHostDropPreviewState;
} // namespace XCEngine::UI::Editor
namespace XCEngine::UI::Editor::Host {
enum class BorderlessWindowChromeHitTarget : std::uint8_t;
enum class BorderlessWindowResizeEdge : std::uint8_t;
struct BorderlessWindowChromeLayout;
} // namespace XCEngine::UI::Editor::Host
namespace XCEngine::UI::Editor::App {
class EditorContext;
@@ -107,10 +98,6 @@ private:
friend class EditorWindowWorkspaceCoordinator;
bool IsRenderReady() const;
bool IsTrackingMouseLeave() const;
bool HasHoveredBorderlessResizeEdge() const;
bool HasHostedContentCapture() const;
bool HasShellInteractiveCapture() const;
bool TryResolveDockTabDragHotspot(
std::string_view nodeId,
std::string_view panelId,
@@ -120,9 +107,6 @@ private:
const POINT& screenPoint,
UIEditorDockHostTabDropTarget& outTarget) const;
void InvalidateHostWindow() const;
void SetExternalDockHostDropPreview(
const Widgets::UIEditorDockHostDropPreviewState& preview);
void ClearExternalDockHostDropPreview();
void AttachHwnd(HWND hwnd);
void MarkInitializing();
@@ -130,10 +114,8 @@ private:
void MarkDestroyed();
void MarkClosing();
void SetPrimary(bool primary);
void SetTrackingMouseLeave(bool trackingMouseLeave);
void SetTitle(std::wstring title);
void ReplaceWorkspaceController(UIEditorWorkspaceController workspaceController);
UIEditorWorkspaceController& GetMutableWorkspaceController();
bool Initialize(
const std::filesystem::path& repoRoot,
@@ -158,46 +140,12 @@ private:
bool OnExitSizeMove();
void OnDpiChanged(UINT dpi, const RECT& suggestedRect);
bool IsBorderlessWindowEnabled() const;
bool IsBorderlessWindowMaximized() const;
bool HandleBorderlessWindowSystemCommand(
EditorContext& editorContext,
bool globalTabDragActive,
WPARAM wParam);
bool HandleBorderlessWindowGetMinMaxInfo(LPARAM lParam) const;
LRESULT HandleBorderlessWindowNcCalcSize(WPARAM wParam, LPARAM lParam) const;
bool ApplyCurrentCursor() const;
bool UpdateBorderlessWindowResizeHover(LPARAM lParam);
bool HandleBorderlessWindowResizeButtonDown(LPARAM lParam);
bool HandleBorderlessWindowResizeButtonUp();
bool HandleBorderlessWindowResizePointerMove(
EditorContext& editorContext,
bool globalTabDragActive);
void ClearBorderlessWindowResizeState();
void ForceClearBorderlessWindowResizeState();
Host::BorderlessWindowChromeHitTarget HitTestBorderlessWindowChrome(LPARAM lParam) const;
bool UpdateBorderlessWindowChromeHover(LPARAM lParam);
bool HandleBorderlessWindowChromeButtonDown(LPARAM lParam);
bool HandleBorderlessWindowChromeButtonUp(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam);
bool HandleBorderlessWindowChromeDoubleClick(
EditorContext& editorContext,
bool globalTabDragActive,
LPARAM lParam);
bool HandleBorderlessWindowChromeDragRestorePointerMove(
EditorContext& editorContext,
bool globalTabDragActive);
void ClearBorderlessWindowChromeDragRestoreState();
void ClearBorderlessWindowChromeState();
bool HasInteractiveCaptureState() const;
EditorWindowPointerCaptureOwner GetPointerCaptureOwner() const;
bool OwnsPointerCapture(EditorWindowPointerCaptureOwner owner) const;
void AcquirePointerCapture(EditorWindowPointerCaptureOwner owner);
void ReleasePointerCapture(EditorWindowPointerCaptureOwner owner);
void ForceReleasePointerCapture();
void ClearPointerCaptureOwner();
void TryStartImmediateShellPointerCapture(LPARAM lParam);
void QueuePointerEvent(
@@ -210,13 +158,7 @@ private:
const ::XCEngine::UI::UIInputModifiers& modifiers);
void QueuePointerLeaveEvent();
void QueuePointerWheelEvent(short wheelDelta, WPARAM wParam, LPARAM lParam);
void QueueKeyEvent(::XCEngine::UI::UIInputEventType type, WPARAM wParam, LPARAM lParam);
void QueueCharacterEvent(WPARAM wParam, LPARAM lParam);
void QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType type);
void SyncInputModifiersFromSystemState();
void SyncShellCapturedPointerButtonsFromSystemState();
void ResetInputModifiers();
void RequestManualScreenshot();
bool ApplyWindowResize(UINT width, UINT height);
bool QueryCurrentClientPixelSize(UINT& outWidth, UINT& outHeight) const;
@@ -235,27 +177,6 @@ private:
float PixelsToDips(float pixels) const;
::XCEngine::UI::UIPoint ConvertClientPixelsToDips(LONG x, LONG y) const;
void ApplyShellRuntimePointerCapture();
Host::BorderlessWindowResizeEdge HitTestBorderlessWindowResizeEdge(LPARAM lParam) const;
void ApplyBorderlessWindowResizeCursorHoverPriority();
Host::BorderlessWindowChromeLayout ResolveBorderlessWindowChromeLayout(
float clientWidthDips) const;
bool QueryCurrentWindowRect(RECT& outRect) const;
bool QueryBorderlessWindowWorkAreaRect(RECT& outRect) const;
bool ApplyPredictedWindowRectTransition(
EditorContext& editorContext,
bool globalTabDragActive,
const RECT& targetRect);
bool ShouldUseDetachedTitleBarTabStrip() const;
void ToggleBorderlessWindowMaximizeRestore(
EditorContext& editorContext,
bool globalTabDragActive);
void AppendBorderlessWindowChrome(
::XCEngine::UI::UIDrawList& drawList,
float clientWidthDips) const;
void ExecuteBorderlessWindowChromeAction(
EditorContext& editorContext,
bool globalTabDragActive,
Host::BorderlessWindowChromeHitTarget target);
void UpdateCachedTitleText();
static bool IsVerboseRuntimeTraceEnabled();

View File

@@ -1,14 +1,14 @@
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h"
#include "Bootstrap/EditorResources.h"
#include "Composition/EditorContext.h"
#include "Platform/Win32/EditorWindowChromeController.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/EditorWindowFrameDriver.h"
#include "Platform/Win32/WindowManager/EditorUtilityWindowCoordinator.h"
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.h"
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.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 <XCEditor/Foundation/UIEditorRuntimeTrace.h>

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorWindowManager.h"
#include "Platform/Win32/Windowing/EditorWindowManager.h"
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>

View File

@@ -1,8 +1,8 @@
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.h"
#include "Platform/Win32/Windowing/EditorWindowLifecycleCoordinator.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.h"
#include "Platform/Win32/Windowing/EditorWindow.h"
#include "Platform/Win32/Windowing/EditorWindowHostRuntime.h"
#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h"
#include <algorithm>
#include <cstdint>

View File

@@ -1,12 +1,12 @@
#include "Platform/Win32/EditorWindowManager.h"
#include "Platform/Win32/Windowing/EditorWindowManager.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowContentController.h"
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.h"
#include "Platform/Win32/WindowManager/EditorUtilityWindowCoordinator.h"
#include "Platform/Win32/WindowManager/EditorWindowMessageDispatcher.h"
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.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 <utility>

View File

@@ -1,13 +1,16 @@
#include "Platform/Win32/WindowManager/EditorWindowMessageDispatcher.h"
#include "Platform/Win32/Windowing/EditorWindowMessageDispatcher.h"
#include "Platform/Win32/BorderlessWindowChrome.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorWindowFrameDriver.h"
#include "Platform/Win32/EditorWindowPointerCapture.h"
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.h"
#include "Platform/Win32/WindowManager/EditorUtilityWindowCoordinator.h"
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.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 <cstdint>
#include <sstream>
@@ -106,7 +109,7 @@ void EditorWindowMessageDispatcher::RenderAndHandleWindowFrame(const DispatchCon
}
bool EditorWindowMessageDispatcher::EnsureTrackingMouseLeave(const DispatchContext& context) {
if (context.window.IsTrackingMouseLeave()) {
if (context.window.m_inputController->IsTrackingMouseLeave()) {
return true;
}
@@ -118,7 +121,7 @@ bool EditorWindowMessageDispatcher::EnsureTrackingMouseLeave(const DispatchConte
return false;
}
context.window.SetTrackingMouseLeave(true);
context.window.m_inputController->SetTrackingMouseLeave(true);
return true;
}
@@ -126,15 +129,22 @@ 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(
context.window.GetPointerCaptureOwner(),
context.window.HasShellInteractiveCapture(),
context.window.HasHostedContentCapture())) {
inputController.GetPointerCaptureOwner(),
inputFeedbackBinding != nullptr &&
inputFeedbackBinding->HasShellInteractiveCapture(),
inputFeedbackBinding != nullptr &&
inputFeedbackBinding->HasHostedContentCapture())) {
return false;
}
const bool resizeHoverChanged = context.window.UpdateBorderlessWindowResizeHover(lParam);
if (context.window.UpdateBorderlessWindowChromeHover(lParam)) {
const bool resizeHoverChanged = chromeController.UpdateResizeHover(context.window, lParam);
if (chromeController.UpdateChromeHover(context.window, lParam)) {
context.window.InvalidateHostWindow();
}
if (resizeHoverChanged) {
@@ -142,13 +152,14 @@ bool EditorWindowMessageDispatcher::TryHandleChromeHoverConsumption(
}
EnsureTrackingMouseLeave(context);
if (context.window.HasHoveredBorderlessResizeEdge()) {
if (chromeController.GetHoveredBorderlessResizeEdge() !=
Host::BorderlessWindowResizeEdge::None) {
outResult = 0;
return true;
}
const Host::BorderlessWindowChromeHitTarget chromeHitTarget =
context.window.HitTestBorderlessWindowChrome(lParam);
chromeController.HitTestChrome(context.window, lParam);
if (chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MinimizeButton ||
chromeHitTarget == Host::BorderlessWindowChromeHitTarget::MaximizeRestoreButton ||
chromeHitTarget == Host::BorderlessWindowChromeHitTarget::CloseButton) {
@@ -165,26 +176,31 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage(
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(
context.window.GetPointerCaptureOwner(),
inputController.GetPointerCaptureOwner(),
context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) &&
context.workspaceCoordinator.HandleGlobalTabDragPointerMove(context.hwnd)) {
outResult = 0;
return true;
}
if (CanRouteEditorWindowBorderlessResizePointerMessages(
context.window.GetPointerCaptureOwner()) &&
context.window.HandleBorderlessWindowResizePointerMove(
inputController.GetPointerCaptureOwner()) &&
chromeController.HandleResizePointerMove(
context.window,
context.hostRuntime.GetEditorContext(),
context.workspaceCoordinator.IsGlobalTabDragActive())) {
outResult = 0;
return true;
}
if (CanRouteEditorWindowBorderlessChromePointerMessages(
context.window.GetPointerCaptureOwner()) &&
context.window.HandleBorderlessWindowChromeDragRestorePointerMove(
inputController.GetPointerCaptureOwner()) &&
chromeController.HandleChromeDragRestorePointerMove(
context.window,
context.hostRuntime.GetEditorContext(),
context.workspaceCoordinator.IsGlobalTabDragActive())) {
outResult = 0;
@@ -202,10 +218,10 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage(
outResult = 0;
return true;
case WM_MOUSELEAVE:
context.window.SetTrackingMouseLeave(false);
context.window.ClearBorderlessWindowResizeState();
context.window.ClearBorderlessWindowChromeDragRestoreState();
context.window.ClearBorderlessWindowChromeState();
inputController.SetTrackingMouseLeave(false);
chromeController.ClearResizeState(context.window);
chromeController.ClearChromeDragRestoreState(context.window);
chromeController.ClearChromeState(context.window);
context.window.QueuePointerLeaveEvent();
outResult = 0;
return true;
@@ -213,11 +229,11 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage(
if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) {
context.workspaceCoordinator.EndGlobalTabDragSession();
}
if (context.window.HandleBorderlessWindowResizeButtonDown(lParam)) {
if (chromeController.HandleResizeButtonDown(context.window, lParam)) {
outResult = 0;
return true;
}
if (context.window.HandleBorderlessWindowChromeButtonDown(lParam)) {
if (chromeController.HandleChromeButtonDown(context.window, lParam)) {
outResult = 0;
return true;
}
@@ -255,21 +271,22 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage(
return true;
case WM_LBUTTONUP:
if (CanRouteEditorWindowGlobalTabDragPointerMessages(
context.window.GetPointerCaptureOwner(),
inputController.GetPointerCaptureOwner(),
context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId())) &&
context.workspaceCoordinator.HandleGlobalTabDragPointerButtonUp(context.hwnd)) {
outResult = 0;
return true;
}
if (CanRouteEditorWindowBorderlessResizePointerMessages(
context.window.GetPointerCaptureOwner()) &&
context.window.HandleBorderlessWindowResizeButtonUp()) {
inputController.GetPointerCaptureOwner()) &&
chromeController.HandleResizeButtonUp(context.window)) {
outResult = 0;
return true;
}
if (CanRouteEditorWindowBorderlessChromePointerMessages(
context.window.GetPointerCaptureOwner()) &&
context.window.HandleBorderlessWindowChromeButtonUp(
inputController.GetPointerCaptureOwner()) &&
chromeController.HandleChromeButtonUp(
context.window,
context.hostRuntime.GetEditorContext(),
context.workspaceCoordinator.IsGlobalTabDragActive(),
lParam)) {
@@ -300,7 +317,8 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowPointerMessage(
outResult = 0;
return true;
case WM_LBUTTONDBLCLK:
if (context.window.HandleBorderlessWindowChromeDoubleClick(
if (chromeController.HandleChromeDoubleClick(
context.window,
context.hostRuntime.GetEditorContext(),
context.workspaceCoordinator.IsGlobalTabDragActive(),
lParam)) {
@@ -351,24 +369,27 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowInputMessage(
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:
context.window.SyncInputModifiersFromSystemState();
context.window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusGained);
inputController.SyncInputModifiersFromSystemState();
inputController.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusGained);
outResult = 0;
return true;
case WM_KILLFOCUS:
context.window.ResetInputModifiers();
context.window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost);
inputController.ResetInputModifiers();
inputController.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost);
outResult = 0;
return true;
case WM_CAPTURECHANGED:
if (reinterpret_cast<HWND>(lParam) != context.hwnd) {
context.window.ClearPointerCaptureOwner();
inputController.ClearPointerCaptureOwner();
}
if (context.workspaceCoordinator.OwnsActiveGlobalTabDrag(context.window.GetWindowId()) &&
reinterpret_cast<HWND>(lParam) != context.hwnd) {
@@ -378,34 +399,34 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowInputMessage(
}
if (reinterpret_cast<HWND>(lParam) != context.hwnd &&
context.window.HasInteractiveCaptureState()) {
context.window.QueueWindowFocusEvent(::XCEngine::UI::UIInputEventType::FocusLost);
context.window.ForceClearBorderlessWindowResizeState();
context.window.ClearBorderlessWindowChromeDragRestoreState();
context.window.ClearBorderlessWindowChromeState();
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<HWND>(lParam) != context.hwnd) {
context.window.ForceClearBorderlessWindowResizeState();
context.window.ClearBorderlessWindowChromeDragRestoreState();
context.window.ClearBorderlessWindowChromeState();
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.RequestManualScreenshot();
context.window.m_runtime->RequestManualScreenshot("manual_f12");
}
context.window.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyDown, wParam, lParam);
inputController.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyDown, wParam, lParam);
outResult = 0;
return true;
case WM_KEYUP:
case WM_SYSKEYUP:
context.window.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyUp, wParam, lParam);
inputController.QueueKeyEvent(::XCEngine::UI::UIInputEventType::KeyUp, wParam, lParam);
outResult = 0;
return true;
case WM_CHAR:
context.window.QueueCharacterEvent(wParam, lParam);
inputController.QueueCharacterEvent(wParam);
outResult = 0;
return true;
default:
@@ -481,42 +502,32 @@ bool EditorWindowMessageDispatcher::TryDispatchWindowChromeMessage(
WPARAM wParam,
LPARAM lParam,
LRESULT& outResult) {
EditorWindowChromeController& chromeController = *context.window.m_chromeController;
switch (message) {
case WM_GETMINMAXINFO:
if (context.window.IsBorderlessWindowEnabled() &&
context.window.HandleBorderlessWindowGetMinMaxInfo(lParam)) {
if (chromeController.HandleGetMinMaxInfo(context.window, lParam)) {
outResult = 0;
return true;
}
return false;
case WM_NCCALCSIZE:
if (context.window.IsBorderlessWindowEnabled()) {
outResult = context.window.HandleBorderlessWindowNcCalcSize(wParam, lParam);
return true;
}
return false;
outResult = chromeController.HandleNcCalcSize(context.window, wParam, lParam);
return true;
case WM_NCACTIVATE:
if (context.window.IsBorderlessWindowEnabled()) {
outResult = TRUE;
return true;
}
return false;
outResult = TRUE;
return true;
case WM_NCHITTEST:
if (context.window.IsBorderlessWindowEnabled()) {
outResult = HTCLIENT;
return true;
}
return false;
outResult = HTCLIENT;
return true;
case WM_NCPAINT:
case kMessageNcUaDrawCaption:
case kMessageNcUaDrawFrame:
if (context.window.IsBorderlessWindowEnabled()) {
outResult = 0;
return true;
}
return false;
outResult = 0;
return true;
case WM_SYSCOMMAND:
if (context.window.HandleBorderlessWindowSystemCommand(
if (chromeController.HandleSystemCommand(
context.window,
context.hostRuntime.GetEditorContext(),
context.workspaceCoordinator.IsGlobalTabDragActive(),
wParam)) {

View File

@@ -1,10 +1,10 @@
#pragma once
#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <windows.h>

View File

@@ -4,7 +4,7 @@
#define NOMINMAX
#endif
#include "Platform/Win32/EditorUtilityWindowKind.h"
#include "UtilityWindows/EditorUtilityWindowKind.h"
#include <windows.h>

View File

@@ -1,11 +1,12 @@
#include "Platform/Win32/WindowManager/EditorWindowWorkspaceCoordinator.h"
#include "Platform/Win32/Windowing/EditorWindowWorkspaceCoordinator.h"
#include "Composition/EditorContext.h"
#include "Platform/Win32/EditorWindow.h"
#include "Platform/Win32/EditorFloatingWindowPlacement.h"
#include "Platform/Win32/EditorWorkspaceWindowContentController.h"
#include "Platform/Win32/WindowManager/EditorWindowHostRuntime.h"
#include "Platform/Win32/WindowManager/EditorWindowLifecycleCoordinator.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 <XCEditor/Docking/UIEditorDockHostTransfer.h>
#include <XCEditor/Workspace/UIEditorDetachedWindowPolicy.h>
@@ -469,8 +470,12 @@ void EditorWindowWorkspaceCoordinator::ClearGlobalTabDragDropPreview() {
if (EditorWindow* previewWindow = m_hostRuntime.FindWindow(m_globalTabDragSession.previewWindowId);
IsLiveInteractiveWindow(previewWindow)) {
previewWindow->ClearExternalDockHostDropPreview();
previewWindow->InvalidateHostWindow();
if (EditorWindowDockHostBinding* dockHostBinding =
previewWindow->m_runtime->TryGetDockHostBinding();
dockHostBinding != nullptr) {
dockHostBinding->ClearExternalDockHostDropPreview();
previewWindow->InvalidateHostWindow();
}
}
m_globalTabDragSession.previewWindowId.clear();
}
@@ -508,8 +513,12 @@ void EditorWindowWorkspaceCoordinator::UpdateGlobalTabDragDropPreview() {
preview.targetNodeId = dropTarget.nodeId;
preview.placement = dropTarget.placement;
preview.insertionIndex = dropTarget.insertionIndex;
targetWindow->SetExternalDockHostDropPreview(preview);
targetWindow->InvalidateHostWindow();
if (EditorWindowDockHostBinding* dockHostBinding =
targetWindow->m_runtime->TryGetDockHostBinding();
dockHostBinding != nullptr) {
dockHostBinding->SetExternalDockHostDropPreview(preview);
targetWindow->InvalidateHostWindow();
}
m_globalTabDragSession.previewWindowId = std::string(targetWindow->GetWindowId());
}

View File

@@ -5,7 +5,7 @@
#endif
#include "Composition/EditorWindowWorkspaceStore.h"
#include "Platform/Win32/EditorWindowTransferRequests.h"
#include "Platform/Win32/Windowing/EditorWindowTransferRequests.h"
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>

View File

@@ -1,10 +0,0 @@
#pragma once
namespace XCEngine::UI::Editor::Ports {
class ShaderResourceDescriptorAllocatorPort;
class SystemInteractionPort;
class TexturePort;
class ViewportRenderPort;
} // namespace XCEngine::UI::Editor::Ports

View File

@@ -1,31 +0,0 @@
#pragma once
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <XCEngine/RHI/RHIDevice.h>
#include <XCEngine/RHI/RHITexture.h>
#include <d3d12.h>
namespace XCEngine::UI::Editor::Ports {
class ShaderResourceDescriptorAllocatorPort {
public:
virtual ~ShaderResourceDescriptorAllocatorPort() = default;
virtual bool Initialize(::XCEngine::RHI::RHIDevice& device, UINT descriptorCount = 64u) = 0;
virtual void Shutdown() = 0;
[[nodiscard]] virtual bool IsInitialized() const = 0;
virtual bool CreateTextureDescriptor(
::XCEngine::RHI::RHITexture* texture,
D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle,
D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle) = 0;
virtual void Free(
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle,
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle) = 0;
};
} // namespace XCEngine::UI::Editor::Ports

View File

@@ -1,7 +1,7 @@
#include "BuiltInIcons.h"
#include "Bootstrap/EditorResources.h"
#include "Ports/TexturePort.h"
#include "Rendering/Host/UiTextureHost.h"
#include "Support/EmbeddedPngLoader.h"
#include "Support/StringEncoding.h"
@@ -63,7 +63,7 @@ void AppendLoadError(
}
void LoadEmbeddedIconTexture(
Ports::TexturePort& renderer,
Rendering::Host::UiTextureHost& renderer,
UINT resourceId,
std::string_view label,
::XCEngine::UI::UITextureHandle& outTexture,
@@ -494,7 +494,7 @@ bool DecodeTextureFromFile(
} // namespace
void BuiltInIcons::Initialize(Ports::TexturePort& renderer) {
void BuiltInIcons::Initialize(Rendering::Host::UiTextureHost& renderer) {
Shutdown();
m_renderer = &renderer;

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Ports/PortFwd.h"
#include "Rendering/Host/HostFwd.h"
#include <XCEngine/UI/Types.h>
@@ -32,7 +32,7 @@ enum class BuiltInIconKind : std::uint8_t {
class BuiltInIcons {
public:
void Initialize(Ports::TexturePort& renderer);
void Initialize(Rendering::Host::UiTextureHost& renderer);
void Shutdown();
void BeginFrame();
@@ -108,7 +108,7 @@ private:
const std::filesystem::path& projectRoot);
void PruneAssetPreviewCache();
Ports::TexturePort* m_renderer = nullptr;
Rendering::Host::UiTextureHost* m_renderer = nullptr;
::XCEngine::UI::UITextureHandle m_folderIcon = {};
::XCEngine::UI::UITextureHandle m_gameObjectIcon = {};
::XCEngine::UI::UITextureHandle m_sceneIcon = {};

View File

@@ -4,8 +4,6 @@
#define NOMINMAX
#endif
#include "Ports/ShaderResourceDescriptorAllocatorPort.h"
#include <XCEngine/RHI/D3D12/D3D12DescriptorHeap.h>
#include <XCEngine/RHI/D3D12/D3D12Device.h>
#include <XCEngine/RHI/D3D12/D3D12Texture.h>
@@ -20,13 +18,12 @@
namespace XCEngine::UI::Editor::Host {
class D3D12ShaderResourceDescriptorAllocator
: public Ports::ShaderResourceDescriptorAllocatorPort {
class D3D12ShaderResourceDescriptorAllocator {
public:
bool Initialize(::XCEngine::RHI::RHIDevice& device, UINT descriptorCount = 64u) override;
void Shutdown() override;
bool Initialize(::XCEngine::RHI::RHIDevice& device, UINT descriptorCount = 64u);
void Shutdown();
bool IsInitialized() const override;
bool IsInitialized() const;
ID3D12DescriptorHeap* GetDescriptorHeap() const;
UINT GetDescriptorSize() const;
UINT GetDescriptorCount() const;
@@ -37,10 +34,10 @@ public:
bool CreateTextureDescriptor(
::XCEngine::RHI::RHITexture* texture,
D3D12_CPU_DESCRIPTOR_HANDLE* outCpuHandle,
D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle) override;
D3D12_GPU_DESCRIPTOR_HANDLE* outGpuHandle);
void Free(
D3D12_CPU_DESCRIPTOR_HANDLE cpuHandle,
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle) override;
D3D12_GPU_DESCRIPTOR_HANDLE gpuHandle);
private:
void AllocateInternal(

View File

@@ -651,6 +651,44 @@ float D3D12UiTextSystem::MeasureTextWidth(
return std::ceil(width * dpiScale) / dpiScale;
}
float D3D12UiTextSystem::MeasureTextAdvance(
const ::XCEngine::UI::Editor::UIEditorTextMeasureRequest& request) const {
if (!m_dwriteFactory || request.text.empty()) {
return 0.0f;
}
const std::wstring text = Utf8ToWide(request.text);
if (text.empty()) {
return 0.0f;
}
const float dpiScale = ClampDpiScale(m_dpiScale);
const float resolvedFontSize = ResolveDisplayFontSize(request.fontSize);
IDWriteTextFormat* textFormat = GetTextFormat(resolvedFontSize);
if (textFormat == nullptr) {
return 0.0f;
}
Microsoft::WRL::ComPtr<IDWriteTextLayout> textLayout = {};
const HRESULT hr = m_dwriteFactory->CreateTextLayout(
text.c_str(),
static_cast<UINT32>(text.size()),
textFormat,
4096.0f,
resolvedFontSize * 2.0f,
textLayout.ReleaseAndGetAddressOf());
if (FAILED(hr) || textLayout == nullptr) {
return 0.0f;
}
DWRITE_TEXT_METRICS textMetrics = {};
if (FAILED(textLayout->GetMetrics(&textMetrics))) {
return 0.0f;
}
return std::ceil(textMetrics.widthIncludingTrailingWhitespace * dpiScale) / dpiScale;
}
bool D3D12UiTextSystem::RasterizeTextMask(
std::string_view text,
float fontSize,

View File

@@ -63,6 +63,8 @@ public:
float MeasureTextWidth(
const ::XCEngine::UI::Editor::UIEditorTextMeasureRequest& request) const override;
float MeasureTextAdvance(
const ::XCEngine::UI::Editor::UIEditorTextMeasureRequest& request) const override;
bool ShapeTextRun(
std::string_view text,
float fontSize,

View File

@@ -4,7 +4,7 @@
#define NOMINMAX
#endif
#include "Ports/TexturePort.h"
#include "Rendering/Host/UiTextureHost.h"
#include <Rendering/D3D12/D3D12WindowRenderer.h>
@@ -24,7 +24,7 @@
namespace XCEngine::UI::Editor::Host {
class D3D12UiTextureHost final : public Ports::TexturePort {
class D3D12UiTextureHost final : public Rendering::Host::UiTextureHost {
public:
bool Initialize(D3D12WindowRenderer& windowRenderer);
void Shutdown();

View File

@@ -4,7 +4,7 @@
#define NOMINMAX
#endif
#include "Ports/ViewportRenderPort.h"
#include "Rendering/Host/ViewportRenderHost.h"
#include "D3D12HostDevice.h"
#include "D3D12ShaderResourceDescriptorAllocator.h"
#include "D3D12WindowCapture.h"
@@ -23,7 +23,7 @@
namespace XCEngine::UI::Editor::Host {
class D3D12WindowRenderer : public Ports::ViewportRenderPort {
class D3D12WindowRenderer : public Rendering::Host::ViewportRenderHost {
public:
static constexpr std::uint32_t kFrameContextCount =
D3D12HostDevice::kFrameContextCount;

View File

@@ -0,0 +1,8 @@
#pragma once
namespace XCEngine::UI::Editor::Rendering::Host {
class UiTextureHost;
class ViewportRenderHost;
} // namespace XCEngine::UI::Editor::Rendering::Host

View File

@@ -7,11 +7,11 @@
#include <filesystem>
#include <string>
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::Rendering::Host {
class TexturePort {
class UiTextureHost {
public:
virtual ~TexturePort() = default;
virtual ~UiTextureHost() = default;
virtual bool LoadTextureFromFile(
const std::filesystem::path& path,
@@ -31,4 +31,4 @@ public:
virtual void ReleaseTexture(::XCEngine::UI::UITextureHandle& texture) = 0;
};
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host

View File

@@ -4,13 +4,17 @@
#include <XCEngine/RHI/RHITexture.h>
#include <XCEngine/UI/Types.h>
namespace XCEngine::UI::Editor::Ports {
#include <cstdint>
class ViewportRenderPort {
namespace XCEngine::UI::Editor::Rendering::Host {
class ViewportRenderHost {
public:
virtual ~ViewportRenderPort() = default;
virtual ~ViewportRenderHost() = default;
[[nodiscard]] virtual ::XCEngine::RHI::RHIDevice* GetRHIDevice() const = 0;
[[nodiscard]] virtual std::uint32_t GetViewportResourceRetirementSlotCount() const = 0;
virtual bool TryGetActiveViewportResourceRetirementSlot(std::uint32_t& outSlot) const = 0;
virtual bool CreateViewportTextureHandle(
::XCEngine::RHI::RHITexture& texture,
std::uint32_t width,
@@ -20,4 +24,4 @@ public:
::XCEngine::UI::UITextureHandle& texture) = 0;
};
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::Rendering::Host

View File

@@ -1,6 +1,6 @@
#include "ViewportHostService.h"
#include "Ports/ViewportRenderPort.h"
#include "Rendering/Host/ViewportRenderHost.h"
#include <XCEngine/RHI/RHICommandList.h>
@@ -19,15 +19,17 @@ ViewportHostService::ViewportHostService() = default;
ViewportHostService::~ViewportHostService() = default;
void ViewportHostService::AttachWindowRenderer(
Ports::ViewportRenderPort& windowRenderer) {
Rendering::Host::ViewportRenderHost& windowRenderer) {
if (m_windowRenderer == &windowRenderer) {
m_device = windowRenderer.GetRHIDevice();
m_retiredTargetsBySlot.resize(windowRenderer.GetViewportResourceRetirementSlotCount());
return;
}
ReleaseWindowResources();
m_windowRenderer = &windowRenderer;
m_device = windowRenderer.GetRHIDevice();
m_retiredTargetsBySlot.resize(windowRenderer.GetViewportResourceRetirementSlotCount());
}
void ViewportHostService::DetachWindowRenderer() {
@@ -51,14 +53,17 @@ void ViewportHostService::Shutdown() {
for (auto& [viewportId, entry] : m_entries) {
DestroyViewportEntry(entry);
}
DestroyRetiredTargets();
m_windowRenderer = nullptr;
m_device = nullptr;
m_surfacePresentationEnabled = false;
m_entries.clear();
m_retiredTargetsBySlot.clear();
}
void ViewportHostService::BeginFrame() {
ReclaimRetiredTargetsForCurrentSlot();
for (auto& [viewportId, entry] : m_entries) {
entry.requestedWidth = 0;
entry.requestedHeight = 0;
@@ -71,10 +76,12 @@ void ViewportHostService::ReleaseWindowResources() {
for (auto& [viewportId, entry] : m_entries) {
DestroyViewportEntry(entry);
}
DestroyRetiredTargets();
m_windowRenderer = nullptr;
m_device = nullptr;
m_surfacePresentationEnabled = false;
m_retiredTargetsBySlot.clear();
}
ViewportHostService::ViewportEntry& ViewportHostService::GetOrCreateEntry(
@@ -96,6 +103,58 @@ void ViewportHostService::DestroyViewportEntry(ViewportEntry& entry) {
entry.statusText.clear();
}
void ViewportHostService::DestroyRetiredTargets() {
for (auto& retiredTargets : m_retiredTargetsBySlot) {
for (ViewportRenderTargets& targets : retiredTargets) {
m_renderTargetManager.DestroyTargets(m_windowRenderer, targets);
}
retiredTargets.clear();
}
}
void ViewportHostService::ReclaimRetiredTargetsForCurrentSlot() {
if (m_windowRenderer == nullptr || m_retiredTargetsBySlot.empty()) {
return;
}
std::uint32_t activeSlot = 0u;
if (!m_windowRenderer->TryGetActiveViewportResourceRetirementSlot(activeSlot) ||
activeSlot >= m_retiredTargetsBySlot.size()) {
return;
}
for (ViewportRenderTargets& targets : m_retiredTargetsBySlot[activeSlot]) {
m_renderTargetManager.DestroyTargets(m_windowRenderer, targets);
}
m_retiredTargetsBySlot[activeSlot].clear();
}
void ViewportHostService::RetireViewportTargets(ViewportRenderTargets& targets) {
if (targets.colorTexture == nullptr &&
targets.colorView == nullptr &&
targets.depthTexture == nullptr &&
targets.depthView == nullptr &&
!targets.textureHandle.IsValid()) {
targets = {};
return;
}
if (m_windowRenderer == nullptr || m_retiredTargetsBySlot.empty()) {
m_renderTargetManager.DestroyTargets(nullptr, targets);
return;
}
std::uint32_t activeSlot = 0u;
if (!m_windowRenderer->TryGetActiveViewportResourceRetirementSlot(activeSlot) ||
activeSlot >= m_retiredTargetsBySlot.size()) {
m_renderTargetManager.DestroyTargets(m_windowRenderer, targets);
return;
}
m_retiredTargetsBySlot[activeSlot].push_back({});
std::swap(m_retiredTargetsBySlot[activeSlot].back(), targets);
}
ViewportFrame ViewportHostService::RequestViewport(
std::string_view viewportId,
const ::XCEngine::UI::UISize& requestedSize) {
@@ -175,13 +234,22 @@ bool ViewportHostService::EnsureViewportResources(ViewportEntry& entry) {
return false;
}
return m_renderTargetManager.EnsureTargets(
ViewportRenderTargets nextTargets = {};
if (!m_renderTargetManager.CreateTargets(
entry.requirements,
entry.requestedWidth,
entry.requestedHeight,
*m_device,
*m_windowRenderer,
entry.renderTargets);
nextTargets)) {
return false;
}
ViewportRenderTargets retiredTargets = {};
std::swap(retiredTargets, entry.renderTargets);
std::swap(entry.renderTargets, nextTargets);
RetireViewportTargets(retiredTargets);
return true;
}
void ViewportHostService::ApplyViewportFallback(

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Ports/PortFwd.h"
#include "Rendering/Host/HostFwd.h"
#include "Rendering/Viewport/ViewportContentRenderer.h"
#include "ViewportRenderTargets.h"
@@ -11,6 +11,7 @@
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>
namespace XCEngine::UI::Editor::App {
@@ -19,7 +20,7 @@ public:
ViewportHostService();
~ViewportHostService();
void AttachWindowRenderer(Ports::ViewportRenderPort& windowRenderer);
void AttachWindowRenderer(Rendering::Host::ViewportRenderHost& windowRenderer);
void DetachWindowRenderer();
void SetSurfacePresentationEnabled(bool enabled);
void SetContentRenderer(
@@ -52,6 +53,9 @@ private:
void ReleaseWindowResources();
ViewportEntry& GetOrCreateEntry(std::string_view viewportId);
void DestroyViewportEntry(ViewportEntry& entry);
void DestroyRetiredTargets();
void ReclaimRetiredTargetsForCurrentSlot();
void RetireViewportTargets(ViewportRenderTargets& targets);
bool EnsureViewportResources(ViewportEntry& entry);
void ApplyViewportFallback(
ViewportEntry& entry,
@@ -68,11 +72,12 @@ private:
const ViewportEntry& entry,
const ::XCEngine::UI::UISize& requestedSize) const;
Ports::ViewportRenderPort* m_windowRenderer = nullptr;
Rendering::Host::ViewportRenderHost* m_windowRenderer = nullptr;
::XCEngine::RHI::RHIDevice* m_device = nullptr;
ViewportRenderTargetManager m_renderTargetManager = {};
bool m_surfacePresentationEnabled = false;
std::unordered_map<std::string, ViewportEntry> m_entries = {};
std::vector<std::vector<ViewportRenderTargets>> m_retiredTargetsBySlot = {};
};
} // namespace XCEngine::UI::Editor::App

View File

@@ -1,6 +1,6 @@
#include "Rendering/Viewport/ViewportRenderTargets.h"
#include "Ports/ViewportRenderPort.h"
#include "Rendering/Host/ViewportRenderHost.h"
namespace XCEngine::UI::Editor::App {
@@ -118,7 +118,7 @@ bool CreateViewportSelectionMaskResources(
}
bool CreateViewportTextureHandle(
Ports::ViewportRenderPort& renderHost,
Rendering::Host::ViewportRenderHost& renderHost,
ViewportRenderTargets& targets) {
if (targets.colorTexture == nullptr) {
return false;
@@ -213,18 +213,17 @@ ViewportResourceReuseQuery BuildViewportRenderTargetsReuseQuery(
targets.selectionMaskState);
}
bool ViewportRenderTargetManager::EnsureTargets(
bool ViewportRenderTargetManager::CreateTargets(
const ViewportResourceRequirements& requirements,
std::uint32_t width,
std::uint32_t height,
::XCEngine::RHI::RHIDevice& device,
Ports::ViewportRenderPort& renderHost,
Rendering::Host::ViewportRenderHost& renderHost,
ViewportRenderTargets& targets) const {
if (width == 0u || height == 0u) {
return false;
}
DestroyTargets(&renderHost, targets);
targets.width = width;
targets.height = height;
@@ -251,7 +250,7 @@ bool ViewportRenderTargetManager::EnsureTargets(
}
void ViewportRenderTargetManager::DestroyTargets(
Ports::ViewportRenderPort* renderHost,
Rendering::Host::ViewportRenderHost* renderHost,
ViewportRenderTargets& targets) const {
if (renderHost != nullptr && targets.textureHandle.IsValid()) {
renderHost->ReleaseViewportTextureHandle(targets.textureHandle);

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Ports/PortFwd.h"
#include "Rendering/Host/HostFwd.h"
#include "ViewportRenderTargetUtils.h"
#include <XCEngine/RHI/RHIDevice.h>
@@ -49,15 +49,15 @@ ViewportResourceReuseQuery BuildViewportRenderTargetsReuseQuery(
class ViewportRenderTargetManager {
public:
bool EnsureTargets(
bool CreateTargets(
const ViewportResourceRequirements& requirements,
std::uint32_t width,
std::uint32_t height,
::XCEngine::RHI::RHIDevice& device,
Ports::ViewportRenderPort& renderHost,
Rendering::Host::ViewportRenderHost& renderHost,
ViewportRenderTargets& targets) const;
void DestroyTargets(
Ports::ViewportRenderPort* renderHost,
Rendering::Host::ViewportRenderHost* renderHost,
ViewportRenderTargets& targets) const;
};

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Platform/Win32/EditorUtilityWindowKind.h"
#include "UtilityWindows/EditorUtilityWindowKind.h"
#include <optional>

View File

@@ -1,6 +1,6 @@
#include "Support/EmbeddedPngLoader.h"
#include "Ports/TexturePort.h"
#include "Rendering/Host/UiTextureHost.h"
namespace XCEngine::UI::Editor::App {
@@ -49,7 +49,7 @@ bool LoadEmbeddedPngBytes(
}
bool LoadEmbeddedPngTexture(
Ports::TexturePort& renderer,
Rendering::Host::UiTextureHost& renderer,
UINT resourceId,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError) {

View File

@@ -1,6 +1,6 @@
#pragma once
#include "Ports/PortFwd.h"
#include "Rendering/Host/HostFwd.h"
#include <XCEngine/UI/Types.h>
@@ -23,7 +23,7 @@ bool LoadEmbeddedPngBytes(
std::string& outError);
bool LoadEmbeddedPngTexture(
Ports::TexturePort& renderer,
Rendering::Host::UiTextureHost& renderer,
UINT resourceId,
::XCEngine::UI::UITextureHandle& outTexture,
std::string& outError);

View File

@@ -3,11 +3,11 @@
#include <filesystem>
#include <string_view>
namespace XCEngine::UI::Editor::Ports {
namespace XCEngine::UI::Editor::System {
class SystemInteractionPort {
class SystemInteractionService {
public:
virtual ~SystemInteractionPort() = default;
virtual ~SystemInteractionService() = default;
virtual bool CopyTextToClipboard(std::string_view text) = 0;
virtual bool RevealPathInFileBrowser(
@@ -15,4 +15,4 @@ public:
bool selectTarget) = 0;
};
} // namespace XCEngine::UI::Editor::Ports
} // namespace XCEngine::UI::Editor::System

View File

@@ -0,0 +1,34 @@
#pragma once
#include <XCEngine/UI/DrawData.h>
#include <string_view>
#include <vector>
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

View File

@@ -1,7 +1,7 @@
#include "Platform/Win32/EditorUtilityWindowRegistry.h"
#include "UtilityWindows/EditorUtilityWindowRegistry.h"
#include "Platform/Win32/EditorAddComponentUtilityWindowContentController.h"
#include "Platform/Win32/EditorColorPickerUtilityWindowContentController.h"
#include "Features/ColorPicker/ColorPickerPanel.h"
#include "Features/Inspector/AddComponentPanel.h"
namespace XCEngine::UI::Editor::App {
@@ -25,7 +25,7 @@ constexpr EditorUtilityWindowDescriptor kAddComponentUtilityWindowDescriptor = {
.minimumOuterSize = UISize(320.0f, 460.0f),
};
}
} // namespace
const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor(
EditorUtilityWindowKind kind) {
@@ -40,21 +40,13 @@ const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor(
}
}
std::unique_ptr<EditorWindowContentController> CreateEditorUtilityWindowContentController(
std::unique_ptr<EditorUtilityWindowPanel> CreateEditorUtilityWindowPanel(
EditorUtilityWindowKind kind) {
const EditorUtilityWindowDescriptor* descriptor =
ResolveEditorUtilityWindowDescriptor(kind);
if (descriptor == nullptr) {
return nullptr;
}
switch (kind) {
case EditorUtilityWindowKind::ColorPicker:
return CreateEditorColorPickerUtilityWindowContentController(
descriptor->minimumOuterSize);
return std::make_unique<ColorPickerPanel>();
case EditorUtilityWindowKind::AddComponent:
return CreateEditorAddComponentUtilityWindowContentController(
descriptor->minimumOuterSize);
return std::make_unique<AddComponentPanel>();
case EditorUtilityWindowKind::None:
default:
return nullptr;

View File

@@ -1,6 +1,7 @@
#pragma once
#include "Platform/Win32/EditorUtilityWindowKind.h"
#include "UtilityWindows/EditorUtilityWindowKind.h"
#include "UtilityWindows/EditorUtilityWindowPanel.h"
#include <XCEngine/UI/Types.h>
@@ -9,8 +10,6 @@
namespace XCEngine::UI::Editor::App {
class EditorWindowContentController;
struct EditorUtilityWindowDescriptor {
EditorUtilityWindowKind kind = EditorUtilityWindowKind::None;
std::string_view windowId = {};
@@ -22,7 +21,7 @@ struct EditorUtilityWindowDescriptor {
const EditorUtilityWindowDescriptor* ResolveEditorUtilityWindowDescriptor(
EditorUtilityWindowKind kind);
std::unique_ptr<EditorWindowContentController> CreateEditorUtilityWindowContentController(
std::unique_ptr<EditorUtilityWindowPanel> CreateEditorUtilityWindowPanel(
EditorUtilityWindowKind kind);
} // namespace XCEngine::UI::Editor::App

View File

@@ -40,7 +40,7 @@ struct UIEditorAssetFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float valueBoxMinWidth = 116.0f;
float controlInsetY = 1.0f;

View File

@@ -31,7 +31,7 @@ struct UIEditorBoolFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float checkboxSize = 18.0f;
float labelTextInsetY = 0.0f;

View File

@@ -44,7 +44,7 @@ struct UIEditorColorFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float swatchWidth = 54.0f;
float swatchInsetY = 1.0f;

View File

@@ -100,6 +100,9 @@ void RecordUIEditorEditableFieldClick(
std::int32_t keyCode,
const ::XCEngine::UI::UIInputModifiers& modifiers);
bool IsUIEditorEditableFieldCharacterInsertable(
std::uint32_t character);
bool InsertUIEditorEditableFieldCharacter(
UIEditorEditableFieldSession& session,
std::uint32_t character);

View File

@@ -36,7 +36,7 @@ struct UIEditorEnumFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float valueBoxMinWidth = 96.0f;
float controlInsetY = 1.0f;

View File

@@ -43,7 +43,7 @@ struct UIEditorNumberFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float valueBoxMinWidth = 96.0f;
float controlInsetY = 1.0f;

View File

@@ -38,7 +38,7 @@ struct UIEditorObjectFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float valueBoxMinWidth = 96.0f;
float controlInsetY = 1.0f;

View File

@@ -126,6 +126,7 @@ struct UIEditorPropertyGridField {
std::string valueText = {};
bool readOnly = false;
float desiredHeight = 0.0f;
float controlMinWidth = 0.0f;
UIEditorPropertyGridFieldKind kind = UIEditorPropertyGridFieldKind::Text;
bool boolValue = false;
UIEditorPropertyGridNumberFieldValue numberValue = {};
@@ -199,7 +200,6 @@ struct UIEditorPropertyGridMetrics {
float horizontalPadding = 12.0f;
float sectionHeaderHorizontalPadding = 6.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float labelControlGap = 20.0f;
float disclosureExtent = 12.0f;
float disclosureLabelGap = 8.0f;

View File

@@ -38,7 +38,7 @@ struct UIEditorTextFieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float valueBoxMinWidth = 96.0f;
float controlInsetY = 1.0f;

View File

@@ -49,7 +49,7 @@ struct UIEditorVector2FieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float controlInsetY = 1.0f;
float componentGap = 6.0f;

View File

@@ -49,7 +49,7 @@ struct UIEditorVector3FieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float controlInsetY = 1.0f;
float componentGap = 6.0f;

View File

@@ -60,7 +60,7 @@ struct UIEditorVector4FieldMetrics {
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float sharedControlColumnMinWidth = 0.0f;
float controlMinWidth = 0.0f;
float controlTrailingInset = 8.0f;
float controlInsetY = 1.0f;
float componentGap = 6.0f;

Some files were not shown because too many files have changed in this diff Show More