resources: formalize internal shader ir
This commit is contained in:
@@ -1 +0,0 @@
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ using XCEngine::UI::Editor::BuildUIEditorWorkspacePanel;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
||||
using XCEngine::UI::Editor::CollectUIEditorWorkspaceVisiblePanels;
|
||||
using XCEngine::UI::Editor::FindUIEditorWorkspaceViewportPresentationFrame;
|
||||
using XCEngine::UI::Editor::GetUIEditorCommandDispatchStatusName;
|
||||
using XCEngine::UI::Editor::UpdateUIEditorShellInteraction;
|
||||
using XCEngine::UI::Editor::UIEditorCommandDispatchResult;
|
||||
@@ -63,6 +64,7 @@ using XCEngine::UI::Editor::UIEditorShellInteractionFrame;
|
||||
using XCEngine::UI::Editor::UIEditorShellInteractionModel;
|
||||
using XCEngine::UI::Editor::UIEditorShellInteractionResult;
|
||||
using XCEngine::UI::Editor::UIEditorShellInteractionState;
|
||||
using XCEngine::UI::Editor::UIEditorViewportInputBridgeFrame;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommandKind;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceController;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceModel;
|
||||
@@ -120,11 +122,15 @@ bool ContainsPoint(const UIRect& rect, float x, float y) {
|
||||
|
||||
bool HasMeaningfulInteractionResult(const UIEditorShellInteractionResult& result) {
|
||||
return result.consumed ||
|
||||
result.requestPointerCapture ||
|
||||
result.releasePointerCapture ||
|
||||
result.commandTriggered ||
|
||||
result.menuMutation.changed ||
|
||||
result.workspaceResult.consumed ||
|
||||
!result.menuId.empty() ||
|
||||
!result.popupId.empty() ||
|
||||
!result.itemId.empty() ||
|
||||
!result.viewportPanelId.empty() ||
|
||||
!result.commandId.empty();
|
||||
}
|
||||
|
||||
@@ -149,6 +155,34 @@ std::string FormatDismissReason(UIPopupDismissReason reason) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
std::string DescribeViewportEvent(const UIEditorViewportInputBridgeFrame& frame) {
|
||||
if (frame.captureStarted) {
|
||||
return "Viewport CaptureStarted";
|
||||
}
|
||||
if (frame.captureEnded) {
|
||||
return "Viewport CaptureEnded";
|
||||
}
|
||||
if (frame.focusGained) {
|
||||
return "Viewport FocusGained";
|
||||
}
|
||||
if (frame.focusLost) {
|
||||
return "Viewport FocusLost";
|
||||
}
|
||||
if (frame.pointerPressedInside) {
|
||||
return "Viewport PointerDownInside";
|
||||
}
|
||||
if (frame.pointerReleasedInside) {
|
||||
return "Viewport PointerUpInside";
|
||||
}
|
||||
if (frame.pointerMoved) {
|
||||
return "Viewport PointerMove";
|
||||
}
|
||||
if (frame.wheelDelta != 0.0f) {
|
||||
return "Viewport Wheel";
|
||||
}
|
||||
return "Viewport Input";
|
||||
}
|
||||
|
||||
std::string JoinVisiblePanelIds(
|
||||
const UIEditorWorkspaceModel& workspace,
|
||||
const UIEditorWorkspaceSession& session) {
|
||||
@@ -357,8 +391,11 @@ private:
|
||||
void UpdateLayout();
|
||||
void HandleMouseMove(float x, float y);
|
||||
void HandleLeftButtonDown(float x, float y);
|
||||
void HandleLeftButtonUp(float x, float y);
|
||||
void ExecuteAction(ActionId action);
|
||||
UIEditorShellInteractionModel BuildInteractionModel() const;
|
||||
bool HasInteractiveCaptureState() const;
|
||||
void ApplyHostCaptureRequests(const UIEditorShellInteractionResult& result);
|
||||
void SetInteractionResult(const UIEditorShellInteractionResult& result);
|
||||
void SetDispatchResult(const UIEditorCommandDispatchResult& result);
|
||||
void RenderFrame();
|
||||
@@ -464,6 +501,12 @@ LRESULT CALLBACK ScenarioApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_LBUTTONUP:
|
||||
if (app != nullptr) {
|
||||
app->HandleLeftButtonUp(static_cast<float>(GET_X_LPARAM(lParam)), static_cast<float>(GET_Y_LPARAM(lParam)));
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_SETFOCUS:
|
||||
if (app != nullptr) {
|
||||
UIInputEvent event = {};
|
||||
@@ -480,6 +523,16 @@ LRESULT CALLBACK ScenarioApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LP
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_CAPTURECHANGED:
|
||||
if (app != nullptr &&
|
||||
reinterpret_cast<HWND>(lParam) != hwnd &&
|
||||
app->HasInteractiveCaptureState()) {
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::FocusLost;
|
||||
app->m_pendingInputEvents.push_back(event);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
if (app != nullptr) {
|
||||
@@ -553,6 +606,9 @@ bool ScenarioApp::Initialize(HINSTANCE hInstance, int nCmdShow) {
|
||||
}
|
||||
|
||||
void ScenarioApp::Shutdown() {
|
||||
if (GetCapture() == m_hwnd) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
m_autoScreenshot.Shutdown();
|
||||
m_renderer.Shutdown();
|
||||
if (m_hwnd != nullptr && IsWindow(m_hwnd)) {
|
||||
@@ -564,6 +620,9 @@ void ScenarioApp::Shutdown() {
|
||||
}
|
||||
|
||||
void ScenarioApp::ResetScenario() {
|
||||
if (GetCapture() == m_hwnd) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
m_controller = BuildDefaultUIEditorWorkspaceController(BuildPanelRegistry(), BuildWorkspace());
|
||||
m_commandDispatcher = UIEditorCommandDispatcher(BuildCommandRegistry());
|
||||
m_menuModel = BuildMenuModel();
|
||||
@@ -627,6 +686,14 @@ void ScenarioApp::HandleLeftButtonDown(float x, float y) {
|
||||
m_pendingInputEvents.push_back(event);
|
||||
}
|
||||
|
||||
void ScenarioApp::HandleLeftButtonUp(float x, float y) {
|
||||
UIInputEvent event = {};
|
||||
event.type = UIInputEventType::PointerButtonUp;
|
||||
event.position = UIPoint(x, y);
|
||||
event.pointerButton = UIPointerButton::Left;
|
||||
m_pendingInputEvents.push_back(event);
|
||||
}
|
||||
|
||||
void ScenarioApp::ExecuteAction(ActionId action) {
|
||||
if (action == ActionId::Reset) {
|
||||
ResetScenario();
|
||||
@@ -642,6 +709,29 @@ void ScenarioApp::ExecuteAction(ActionId action) {
|
||||
m_lastColor = kWarning;
|
||||
}
|
||||
|
||||
bool ScenarioApp::HasInteractiveCaptureState() const {
|
||||
if (m_interactionState.workspaceInteractionState.dockHostInteractionState.splitterDragState.active) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& panelState : m_interactionState.workspaceInteractionState.composeState.panelStates) {
|
||||
if (panelState.viewportShellState.inputBridgeState.captured) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScenarioApp::ApplyHostCaptureRequests(const UIEditorShellInteractionResult& result) {
|
||||
if (result.requestPointerCapture && GetCapture() != m_hwnd) {
|
||||
SetCapture(m_hwnd);
|
||||
}
|
||||
if (result.releasePointerCapture && GetCapture() == m_hwnd) {
|
||||
ReleaseCapture();
|
||||
}
|
||||
}
|
||||
|
||||
UIEditorShellInteractionModel ScenarioApp::BuildInteractionModel() const {
|
||||
UIEditorShellInteractionModel model = {};
|
||||
model.resolvedMenuModel = BuildUIEditorResolvedMenuModel(
|
||||
@@ -720,6 +810,46 @@ void ScenarioApp::SetInteractionResult(const UIEditorShellInteractionResult& res
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.workspaceResult.dockHostResult.layoutResult.status !=
|
||||
XCEngine::UI::Editor::UIEditorWorkspaceLayoutOperationStatus::Rejected) {
|
||||
m_lastStatus = "WorkspaceLayout";
|
||||
m_lastMessage = result.workspaceResult.dockHostResult.layoutResult.message;
|
||||
m_lastColor = kSuccess;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.workspaceResult.dockHostResult.commandResult.status !=
|
||||
XCEngine::UI::Editor::UIEditorWorkspaceCommandStatus::Rejected) {
|
||||
m_lastStatus = "WorkspaceCommand";
|
||||
m_lastMessage = result.workspaceResult.dockHostResult.commandResult.message;
|
||||
m_lastColor = kSuccess;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!result.viewportPanelId.empty()) {
|
||||
m_lastStatus = result.viewportPanelId;
|
||||
m_lastMessage = DescribeViewportEvent(result.viewportInputFrame);
|
||||
m_lastColor =
|
||||
result.viewportInputFrame.captureStarted || result.viewportInputFrame.focusGained
|
||||
? kSuccess
|
||||
: kWarning;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.requestPointerCapture) {
|
||||
m_lastStatus = "Capture";
|
||||
m_lastMessage = "宿主已收到 root shell 返回的 pointer capture 请求。";
|
||||
m_lastColor = kSuccess;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.releasePointerCapture) {
|
||||
m_lastStatus = "Release";
|
||||
m_lastMessage = "宿主已执行 root shell 返回的 pointer release。";
|
||||
m_lastColor = kWarning;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.consumed) {
|
||||
m_lastStatus = "NoOp";
|
||||
m_lastMessage = "这次输入被根壳交互层消费,但没有触发额外状态变化。";
|
||||
@@ -738,27 +868,29 @@ void ScenarioApp::RenderFrame() {
|
||||
m_cachedModel = BuildInteractionModel();
|
||||
m_cachedFrame = UpdateUIEditorShellInteraction(
|
||||
m_interactionState,
|
||||
m_controller,
|
||||
m_shellRect,
|
||||
m_controller.GetPanelRegistry(),
|
||||
m_controller.GetWorkspace(),
|
||||
m_controller.GetSession(),
|
||||
m_cachedModel,
|
||||
m_pendingInputEvents);
|
||||
m_pendingInputEvents.clear();
|
||||
ApplyHostCaptureRequests(m_cachedFrame.result);
|
||||
SetInteractionResult(m_cachedFrame.result);
|
||||
|
||||
if (m_cachedFrame.result.commandTriggered) {
|
||||
m_cachedModel = BuildInteractionModel();
|
||||
m_cachedFrame = UpdateUIEditorShellInteraction(
|
||||
m_interactionState,
|
||||
m_controller,
|
||||
m_shellRect,
|
||||
m_controller.GetPanelRegistry(),
|
||||
m_controller.GetWorkspace(),
|
||||
m_controller.GetSession(),
|
||||
m_cachedModel,
|
||||
{});
|
||||
}
|
||||
|
||||
const auto* viewportFrame =
|
||||
FindUIEditorWorkspaceViewportPresentationFrame(m_cachedFrame.workspaceInteractionFrame.composeFrame, "scene");
|
||||
const std::string selectedPresentation =
|
||||
viewportFrame != nullptr ? "ViewportShell" : "DockHost Placeholder";
|
||||
|
||||
RECT clientRect = {};
|
||||
GetClientRect(m_hwnd, &clientRect);
|
||||
const float width = static_cast<float>((std::max)(clientRect.right - clientRect.left, 1L));
|
||||
@@ -772,9 +904,9 @@ void ScenarioApp::RenderFrame() {
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 70.0f), "1. 验证 MenuBar 的 root open / root switch 行为是否统一稳定。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 92.0f), "2. 验证 hover 子菜单时,child popup 是否直接展开,不需要额外点击。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 114.0f), "3. 验证 outside pointer down / Esc / focus loss 是否能正确收起 popup chain。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 136.0f), "4. 验证预览区是真实 root shell:MenuBar + Workspace + StatusBar + popup overlay。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 158.0f), "5. 验证 command 只通过最小 dispatch hook 回传,不接旧 editor 业务。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 182.0f), "建议操作:点击 File,hover `Workspace Tools`,再按 Esc 或点预览区外空白处。", kTextWeak, 11.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 136.0f), "4. 验证菜单打开时会屏蔽 workspace 输入;菜单关闭后,workspace 交互立即恢复。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 158.0f), "5. 验证 root shell 会继续透传 viewport / splitter 的 capture 请求,不接旧 editor 业务。", kTextPrimary, 12.0f);
|
||||
drawList.AddText(UIPoint(m_introRect.x + 16.0f, m_introRect.y + 182.0f), "建议操作:点击 File,hover `Workspace Tools`,点预览外空白处,再点 `Document` 或拖 splitter。", kTextWeak, 11.0f);
|
||||
|
||||
DrawCard(drawList, m_controlsRect, "操作", "只保留这个场景必要的控制。");
|
||||
for (const ButtonState& button : m_buttons) {
|
||||
@@ -791,13 +923,16 @@ void ScenarioApp::RenderFrame() {
|
||||
addStateLine("Open Root", m_cachedFrame.openRootMenuId.empty() ? "(none)" : m_cachedFrame.openRootMenuId, kTextPrimary);
|
||||
addStateLine("Popup Chain", JoinPopupChainIds(m_interactionState), kTextPrimary, 11.0f);
|
||||
addStateLine("Submenu Path", JoinSubmenuPathIds(m_interactionState), kTextPrimary, 11.0f);
|
||||
addStateLine("Selected Presentation", selectedPresentation, kTextPrimary, 11.0f);
|
||||
addStateLine("Active Panel", m_controller.GetWorkspace().activePanelId.empty() ? "(none)" : m_controller.GetWorkspace().activePanelId, kTextPrimary, 11.0f);
|
||||
addStateLine("Focused", FormatBool(m_cachedFrame.focused), m_cachedFrame.focused ? kSuccess : kTextMuted);
|
||||
addStateLine("Result", m_lastStatus, m_lastColor);
|
||||
drawList.AddText(UIPoint(m_stateRect.x + 16.0f, stateY + 4.0f), m_lastMessage, kTextMuted, 11.0f);
|
||||
stateY += 34.0f;
|
||||
addStateLine("Visible Panels", JoinVisiblePanelIds(m_controller.GetWorkspace(), m_controller.GetSession()), kTextWeak, 11.0f);
|
||||
addStateLine("Host Capture", FormatBool(GetCapture() == m_hwnd), GetCapture() == m_hwnd ? kSuccess : kTextMuted, 11.0f);
|
||||
addStateLine(
|
||||
"Capture",
|
||||
"Screenshot",
|
||||
m_autoScreenshot.HasPendingCapture()
|
||||
? "截图排队中..."
|
||||
: (m_autoScreenshot.GetLastCaptureSummary().empty()
|
||||
|
||||
Reference in New Issue
Block a user