Refine editor window host structure and utility chrome
This commit is contained in:
215
editor/app/Windowing/Frame/EditorWindowFrameOrchestrator.cpp
Normal file
215
editor/app/Windowing/Frame/EditorWindowFrameOrchestrator.cpp
Normal file
@@ -0,0 +1,215 @@
|
||||
#include "Windowing/Frame/EditorWindowFrameOrchestrator.h"
|
||||
|
||||
#include "Composition/EditorContext.h"
|
||||
#include "Composition/EditorShellRuntime.h"
|
||||
#include "Composition/EditorShellVariant.h"
|
||||
#include "Platform/Win32/Windowing/EditorWindowSupport.h"
|
||||
|
||||
#include <XCEditor/Workspace/UIEditorWorkspaceController.h>
|
||||
#include <XCEngine/UI/DrawData.h>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace XCEngine::UI::Editor::App {
|
||||
|
||||
using namespace EditorWindowSupport;
|
||||
using ::XCEngine::UI::UIDrawData;
|
||||
using ::XCEngine::UI::UIDrawList;
|
||||
using ::XCEngine::UI::UIInputEvent;
|
||||
using ::XCEngine::UI::UIInputEventType;
|
||||
using ::XCEngine::UI::UIPoint;
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsVerboseRuntimeTraceEnabled() {
|
||||
static const bool s_enabled = ResolveVerboseRuntimeTraceEnabled();
|
||||
return s_enabled;
|
||||
}
|
||||
|
||||
std::string DescribeInputEventType(const UIInputEvent& event) {
|
||||
switch (event.type) {
|
||||
case UIInputEventType::PointerMove: return "PointerMove";
|
||||
case UIInputEventType::PointerEnter: return "PointerEnter";
|
||||
case UIInputEventType::PointerLeave: return "PointerLeave";
|
||||
case UIInputEventType::PointerButtonDown: return "PointerDown";
|
||||
case UIInputEventType::PointerButtonUp: return "PointerUp";
|
||||
case UIInputEventType::PointerWheel: return "PointerWheel";
|
||||
case UIInputEventType::KeyDown: return "KeyDown";
|
||||
case UIInputEventType::KeyUp: return "KeyUp";
|
||||
case UIInputEventType::Character: return "Character";
|
||||
case UIInputEventType::FocusGained: return "FocusGained";
|
||||
case UIInputEventType::FocusLost: return "FocusLost";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
EditorWindowFrameTransferRequests EditorWindowFrameOrchestrator::UpdateAndAppend(
|
||||
EditorContext& editorContext,
|
||||
UIEditorWorkspaceController& workspaceController,
|
||||
EditorShellRuntime& shellRuntime,
|
||||
const ::XCEngine::UI::UIRect& workspaceBounds,
|
||||
const std::vector<UIInputEvent>& frameEvents,
|
||||
std::string_view captureStatusText,
|
||||
bool primary,
|
||||
bool globalTabDragActive,
|
||||
bool useDetachedTitleBarTabStrip,
|
||||
UIDrawData& drawData) const {
|
||||
LogInputTrace(
|
||||
editorContext,
|
||||
workspaceController,
|
||||
shellRuntime.GetShellInteractionState(),
|
||||
frameEvents);
|
||||
|
||||
shellRuntime.Update(
|
||||
editorContext,
|
||||
workspaceController,
|
||||
workspaceBounds,
|
||||
frameEvents,
|
||||
captureStatusText,
|
||||
primary ? EditorShellVariant::Primary : EditorShellVariant::DetachedWindow,
|
||||
useDetachedTitleBarTabStrip,
|
||||
useDetachedTitleBarTabStrip ? kBorderlessTitleBarHeightDips : 0.0f,
|
||||
primary ? 0.0f : kBorderlessTitleBarHeightDips);
|
||||
const UIEditorShellInteractionFrame& shellFrame = shellRuntime.GetShellFrame();
|
||||
const UIEditorDockHostInteractionState& dockHostInteractionState =
|
||||
shellRuntime.GetShellInteractionState().workspaceInteractionState.dockHostInteractionState;
|
||||
|
||||
LogFrameInteractionTrace(workspaceController, frameEvents, shellFrame);
|
||||
EditorWindowFrameTransferRequests transferRequests =
|
||||
BuildShellTransferRequests(globalTabDragActive, dockHostInteractionState, shellFrame);
|
||||
POINT screenPoint = {};
|
||||
if (const std::optional<EditorUtilityWindowKind> requestedKind =
|
||||
editorContext.ConsumeOpenUtilityWindowRequest();
|
||||
requestedKind.has_value()) {
|
||||
transferRequests.utility.openUtilityWindow = EditorWindowOpenUtilityWindowRequest{
|
||||
.kind = *requestedKind,
|
||||
.useCursorPlacement = GetCursorPos(&screenPoint) != FALSE,
|
||||
};
|
||||
if (transferRequests.utility.openUtilityWindow->useCursorPlacement) {
|
||||
transferRequests.utility.openUtilityWindow->screenPoint = screenPoint;
|
||||
}
|
||||
}
|
||||
|
||||
for (const WorkspaceTraceEntry& entry : shellRuntime.GetTraceEntries()) {
|
||||
LogRuntimeTrace(entry.channel, entry.message);
|
||||
}
|
||||
|
||||
shellRuntime.Append(drawData);
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
void EditorWindowFrameOrchestrator::AppendInvalidFrame(
|
||||
EditorContext& editorContext,
|
||||
UIDrawList& drawList) const {
|
||||
drawList.AddText(
|
||||
UIPoint(28.0f, 28.0f),
|
||||
"Editor shell asset invalid.",
|
||||
kShellTextColor,
|
||||
16.0f);
|
||||
drawList.AddText(
|
||||
UIPoint(28.0f, 54.0f),
|
||||
editorContext.GetValidationMessage().empty()
|
||||
? std::string("Unknown validation error.")
|
||||
: editorContext.GetValidationMessage(),
|
||||
kShellMutedTextColor,
|
||||
12.0f);
|
||||
}
|
||||
|
||||
std::string EditorWindowFrameOrchestrator::DescribeInputEvents(
|
||||
const std::vector<UIInputEvent>& events) const {
|
||||
std::ostringstream stream = {};
|
||||
stream << "events=[";
|
||||
for (std::size_t index = 0; index < events.size(); ++index) {
|
||||
if (index > 0u) {
|
||||
stream << " | ";
|
||||
}
|
||||
|
||||
const UIInputEvent& event = events[index];
|
||||
stream << DescribeInputEventType(event)
|
||||
<< '@'
|
||||
<< static_cast<int>(event.position.x)
|
||||
<< ','
|
||||
<< static_cast<int>(event.position.y);
|
||||
}
|
||||
stream << ']';
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
void EditorWindowFrameOrchestrator::LogInputTrace(
|
||||
EditorContext& editorContext,
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
const UIEditorShellInteractionState& shellInteractionState,
|
||||
const std::vector<UIInputEvent>& frameEvents) const {
|
||||
if (frameEvents.empty() || !IsVerboseRuntimeTraceEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LogRuntimeTrace(
|
||||
"input",
|
||||
DescribeInputEvents(frameEvents) + " | " +
|
||||
editorContext.DescribeWorkspaceState(
|
||||
workspaceController,
|
||||
shellInteractionState));
|
||||
}
|
||||
|
||||
void EditorWindowFrameOrchestrator::LogFrameInteractionTrace(
|
||||
const UIEditorWorkspaceController& workspaceController,
|
||||
const std::vector<UIInputEvent>& frameEvents,
|
||||
const UIEditorShellInteractionFrame& shellFrame) const {
|
||||
if (!IsVerboseRuntimeTraceEnabled() ||
|
||||
(frameEvents.empty() &&
|
||||
!shellFrame.result.workspaceResult.dockHostResult.layoutChanged &&
|
||||
!shellFrame.result.workspaceResult.dockHostResult.commandExecuted)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::ostringstream frameTrace = {};
|
||||
frameTrace << "result consumed="
|
||||
<< (shellFrame.result.consumed ? "true" : "false")
|
||||
<< " layoutChanged="
|
||||
<< (shellFrame.result.workspaceResult.dockHostResult.layoutChanged ? "true"
|
||||
: "false")
|
||||
<< " commandExecuted="
|
||||
<< (shellFrame.result.workspaceResult.dockHostResult.commandExecuted ? "true"
|
||||
: "false")
|
||||
<< " active="
|
||||
<< workspaceController.GetWorkspace().activePanelId
|
||||
<< " message="
|
||||
<< shellFrame.result.workspaceResult.dockHostResult.layoutResult.message;
|
||||
LogRuntimeTrace("frame", frameTrace.str());
|
||||
}
|
||||
|
||||
EditorWindowFrameTransferRequests EditorWindowFrameOrchestrator::BuildShellTransferRequests(
|
||||
bool globalTabDragActive,
|
||||
const UIEditorDockHostInteractionState& dockHostInteractionState,
|
||||
const UIEditorShellInteractionFrame& shellFrame) const {
|
||||
EditorWindowFrameTransferRequests transferRequests = {};
|
||||
POINT screenPoint = {};
|
||||
const bool hasScreenPoint = GetCursorPos(&screenPoint) != FALSE;
|
||||
|
||||
if (!globalTabDragActive &&
|
||||
!dockHostInteractionState.activeTabDragNodeId.empty() &&
|
||||
!dockHostInteractionState.activeTabDragPanelId.empty() &&
|
||||
hasScreenPoint) {
|
||||
transferRequests.workspace.beginGlobalTabDrag = EditorWindowPanelTransferRequest{
|
||||
dockHostInteractionState.activeTabDragNodeId,
|
||||
dockHostInteractionState.activeTabDragPanelId,
|
||||
screenPoint,
|
||||
};
|
||||
}
|
||||
|
||||
if (shellFrame.result.workspaceResult.dockHostResult.detachRequested && hasScreenPoint) {
|
||||
transferRequests.workspace.detachPanel = EditorWindowPanelTransferRequest{
|
||||
shellFrame.result.workspaceResult.dockHostResult.detachedNodeId,
|
||||
shellFrame.result.workspaceResult.dockHostResult.detachedPanelId,
|
||||
screenPoint,
|
||||
};
|
||||
}
|
||||
|
||||
return transferRequests;
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::App
|
||||
|
||||
Reference in New Issue
Block a user