Add workspace interaction coordination contract

This commit is contained in:
2026-04-07 11:12:18 +08:00
parent 5d57101da3
commit 0d6a4113e7
11 changed files with 1140 additions and 0 deletions

View File

@@ -15,6 +15,7 @@ add_library(XCUIEditorLib STATIC
src/Core/EditorShellAsset.cpp
src/Core/UIEditorCommandDispatcher.cpp
src/Core/UIEditorCommandRegistry.cpp
src/Core/UIEditorDockHostInteraction.cpp
src/Core/UIEditorMenuModel.cpp
src/Core/UIEditorMenuSession.cpp
src/Core/UIEditorPanelRegistry.cpp
@@ -24,6 +25,7 @@ add_library(XCUIEditorLib STATIC
src/Core/UIEditorViewportInputBridge.cpp
src/Core/UIEditorViewportShell.cpp
src/Core/UIEditorWorkspaceCompose.cpp
src/Core/UIEditorWorkspaceInteraction.cpp
src/Core/UIEditorWorkspaceLayoutPersistence.cpp
src/Core/UIEditorWorkspaceController.cpp
src/Core/UIEditorWorkspaceModel.cpp

View File

@@ -0,0 +1,46 @@
#pragma once
#include <XCEditor/Core/UIEditorDockHostInteraction.h>
#include <XCEditor/Core/UIEditorWorkspaceCompose.h>
#include <XCEngine/UI/Types.h>
#include <string>
#include <vector>
namespace XCEngine::UI::Editor {
struct UIEditorWorkspaceInteractionModel {
std::vector<UIEditorWorkspacePanelPresentationModel> workspacePresentations = {};
};
struct UIEditorWorkspaceInteractionState {
UIEditorDockHostInteractionState dockHostInteractionState = {};
UIEditorWorkspaceComposeState composeState = {};
};
struct UIEditorWorkspaceInteractionResult {
bool consumed = false;
bool requestPointerCapture = false;
bool releasePointerCapture = false;
bool viewportInteractionChanged = false;
std::string viewportPanelId = {};
UIEditorViewportInputBridgeFrame viewportInputFrame = {};
UIEditorDockHostInteractionResult dockHostResult = {};
};
struct UIEditorWorkspaceInteractionFrame {
UIEditorDockHostInteractionFrame dockHostFrame = {};
UIEditorWorkspaceComposeFrame composeFrame = {};
UIEditorWorkspaceInteractionResult result = {};
};
UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
UIEditorWorkspaceInteractionState& state,
UIEditorWorkspaceController& controller,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorWorkspaceInteractionModel& model,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics = {});
} // namespace XCEngine::UI::Editor

View File

@@ -0,0 +1,86 @@
#include <XCEditor/Core/UIEditorWorkspaceInteraction.h>
#include <utility>
namespace XCEngine::UI::Editor {
namespace {
bool HasMeaningfulViewportInputFrame(const UIEditorViewportInputBridgeFrame& frame) {
return frame.pointerMoved ||
frame.pointerPressedInside ||
frame.pointerReleasedInside ||
frame.focusGained ||
frame.focusLost ||
frame.captureStarted ||
frame.captureEnded ||
frame.wheelDelta != 0.0f ||
!frame.pressedKeyCodes.empty() ||
!frame.releasedKeyCodes.empty() ||
!frame.characters.empty();
}
} // namespace
UIEditorWorkspaceInteractionFrame UpdateUIEditorWorkspaceInteraction(
UIEditorWorkspaceInteractionState& state,
UIEditorWorkspaceController& controller,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorWorkspaceInteractionModel& model,
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
const Widgets::UIEditorDockHostMetrics& dockHostMetrics) {
UIEditorWorkspaceInteractionFrame frame = {};
frame.dockHostFrame = UpdateUIEditorDockHostInteraction(
state.dockHostInteractionState,
controller,
bounds,
inputEvents,
dockHostMetrics);
frame.composeFrame = UpdateUIEditorWorkspaceCompose(
state.composeState,
bounds,
controller.GetPanelRegistry(),
controller.GetWorkspace(),
controller.GetSession(),
model.workspacePresentations,
inputEvents,
state.dockHostInteractionState.dockHostState,
dockHostMetrics);
frame.result.dockHostResult = frame.dockHostFrame.result;
frame.result.consumed = frame.dockHostFrame.result.consumed;
frame.result.requestPointerCapture = frame.dockHostFrame.result.requestPointerCapture;
frame.result.releasePointerCapture = frame.dockHostFrame.result.releasePointerCapture;
for (const UIEditorWorkspaceViewportComposeFrame& viewportFrame : frame.composeFrame.viewportFrames) {
const UIEditorViewportInputBridgeFrame& inputFrame =
viewportFrame.viewportShellFrame.inputFrame;
const bool meaningfulInput = HasMeaningfulViewportInputFrame(inputFrame);
if (!meaningfulInput &&
!inputFrame.captureStarted &&
!inputFrame.captureEnded) {
continue;
}
if (frame.result.viewportPanelId.empty()) {
frame.result.viewportPanelId = viewportFrame.panelId;
frame.result.viewportInputFrame = inputFrame;
}
frame.result.viewportInteractionChanged =
frame.result.viewportInteractionChanged || meaningfulInput;
frame.result.requestPointerCapture =
frame.result.requestPointerCapture || inputFrame.captureStarted;
frame.result.releasePointerCapture =
frame.result.releasePointerCapture || inputFrame.captureEnded;
}
frame.result.consumed =
frame.result.consumed ||
frame.result.viewportInteractionChanged ||
frame.result.requestPointerCapture ||
frame.result.releasePointerCapture;
return frame;
}
} // namespace XCEngine::UI::Editor