Internalize shell command dispatch handling
This commit is contained in:
@@ -39,6 +39,10 @@ struct UIEditorShellInteractionPalette {
|
|||||||
Widgets::UIEditorMenuPopupPalette popupPalette = {};
|
Widgets::UIEditorMenuPopupPalette popupPalette = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UIEditorShellInteractionServices {
|
||||||
|
const UIEditorCommandDispatcher* commandDispatcher = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct UIEditorShellInteractionMenuButtonRequest {
|
struct UIEditorShellInteractionMenuButtonRequest {
|
||||||
std::string menuId = {};
|
std::string menuId = {};
|
||||||
std::string label = {};
|
std::string label = {};
|
||||||
@@ -84,10 +88,13 @@ struct UIEditorShellInteractionRequest {
|
|||||||
|
|
||||||
struct UIEditorShellInteractionResult {
|
struct UIEditorShellInteractionResult {
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
|
bool menuModal = false;
|
||||||
|
bool workspaceInputSuppressed = false;
|
||||||
bool requestPointerCapture = false;
|
bool requestPointerCapture = false;
|
||||||
bool releasePointerCapture = false;
|
bool releasePointerCapture = false;
|
||||||
bool viewportInteractionChanged = false;
|
bool viewportInteractionChanged = false;
|
||||||
bool commandTriggered = false;
|
bool commandTriggered = false;
|
||||||
|
bool commandDispatched = false;
|
||||||
std::string menuId = {};
|
std::string menuId = {};
|
||||||
std::string popupId = {};
|
std::string popupId = {};
|
||||||
std::string itemId = {};
|
std::string itemId = {};
|
||||||
@@ -95,6 +102,7 @@ struct UIEditorShellInteractionResult {
|
|||||||
std::string viewportPanelId = {};
|
std::string viewportPanelId = {};
|
||||||
UIEditorViewportInputBridgeFrame viewportInputFrame = {};
|
UIEditorViewportInputBridgeFrame viewportInputFrame = {};
|
||||||
UIEditorMenuSessionMutationResult menuMutation = {};
|
UIEditorMenuSessionMutationResult menuMutation = {};
|
||||||
|
UIEditorCommandDispatchResult commandDispatchResult = {};
|
||||||
UIEditorWorkspaceInteractionResult workspaceResult = {};
|
UIEditorWorkspaceInteractionResult workspaceResult = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,7 +129,8 @@ UIEditorShellInteractionRequest ResolveUIEditorShellInteractionRequest(
|
|||||||
const UIEditorWorkspaceController& controller,
|
const UIEditorWorkspaceController& controller,
|
||||||
const UIEditorShellInteractionModel& model,
|
const UIEditorShellInteractionModel& model,
|
||||||
const UIEditorShellInteractionState& state = {},
|
const UIEditorShellInteractionState& state = {},
|
||||||
const UIEditorShellInteractionMetrics& metrics = {});
|
const UIEditorShellInteractionMetrics& metrics = {},
|
||||||
|
const UIEditorShellInteractionServices& services = {});
|
||||||
|
|
||||||
UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
||||||
UIEditorShellInteractionState& state,
|
UIEditorShellInteractionState& state,
|
||||||
@@ -129,6 +138,7 @@ UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
|||||||
const ::XCEngine::UI::UIRect& bounds,
|
const ::XCEngine::UI::UIRect& bounds,
|
||||||
const UIEditorShellInteractionModel& model,
|
const UIEditorShellInteractionModel& model,
|
||||||
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
|
const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents,
|
||||||
|
const UIEditorShellInteractionServices& services = {},
|
||||||
const UIEditorShellInteractionMetrics& metrics = {});
|
const UIEditorShellInteractionMetrics& metrics = {});
|
||||||
|
|
||||||
void AppendUIEditorShellInteraction(
|
void AppendUIEditorShellInteraction(
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ bool HasMeaningfulInteractionResult(
|
|||||||
result.requestPointerCapture ||
|
result.requestPointerCapture ||
|
||||||
result.releasePointerCapture ||
|
result.releasePointerCapture ||
|
||||||
result.commandTriggered ||
|
result.commandTriggered ||
|
||||||
|
result.commandDispatched ||
|
||||||
result.menuMutation.changed ||
|
result.menuMutation.changed ||
|
||||||
result.workspaceResult.consumed ||
|
result.workspaceResult.consumed ||
|
||||||
!result.menuId.empty() ||
|
!result.menuId.empty() ||
|
||||||
@@ -469,7 +470,9 @@ UIEditorShellInteractionRequest ResolveUIEditorShellInteractionRequest(
|
|||||||
const UIEditorWorkspaceController& controller,
|
const UIEditorWorkspaceController& controller,
|
||||||
const UIEditorShellInteractionModel& model,
|
const UIEditorShellInteractionModel& model,
|
||||||
const UIEditorShellInteractionState& state,
|
const UIEditorShellInteractionState& state,
|
||||||
const UIEditorShellInteractionMetrics& metrics) {
|
const UIEditorShellInteractionMetrics& metrics,
|
||||||
|
const UIEditorShellInteractionServices& services) {
|
||||||
|
(void)services;
|
||||||
return BuildRequest(
|
return BuildRequest(
|
||||||
bounds,
|
bounds,
|
||||||
controller,
|
controller,
|
||||||
@@ -484,6 +487,7 @@ UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
|||||||
const UIRect& bounds,
|
const UIRect& bounds,
|
||||||
const UIEditorShellInteractionModel& model,
|
const UIEditorShellInteractionModel& model,
|
||||||
const std::vector<UIInputEvent>& inputEvents,
|
const std::vector<UIInputEvent>& inputEvents,
|
||||||
|
const UIEditorShellInteractionServices& services,
|
||||||
const UIEditorShellInteractionMetrics& metrics) {
|
const UIEditorShellInteractionMetrics& metrics) {
|
||||||
UIEditorShellInteractionResult interactionResult = {};
|
UIEditorShellInteractionResult interactionResult = {};
|
||||||
bool menuModalDuringFrame = state.menuSession.HasOpenMenu();
|
bool menuModalDuringFrame = state.menuSession.HasOpenMenu();
|
||||||
@@ -610,6 +614,13 @@ UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
|||||||
} else if (hit.popupItem->enabled) {
|
} else if (hit.popupItem->enabled) {
|
||||||
eventResult.commandTriggered = true;
|
eventResult.commandTriggered = true;
|
||||||
eventResult.commandId = hit.popupItem->commandId;
|
eventResult.commandId = hit.popupItem->commandId;
|
||||||
|
if (services.commandDispatcher != nullptr) {
|
||||||
|
eventResult.commandDispatchResult =
|
||||||
|
services.commandDispatcher->Dispatch(
|
||||||
|
eventResult.commandId,
|
||||||
|
controller);
|
||||||
|
eventResult.commandDispatched = true;
|
||||||
|
}
|
||||||
eventResult.menuMutation = state.menuSession.CloseAll();
|
eventResult.menuMutation = state.menuSession.CloseAll();
|
||||||
} else {
|
} else {
|
||||||
eventResult.menuMutation =
|
eventResult.menuMutation =
|
||||||
@@ -700,6 +711,8 @@ UIEditorShellInteractionFrame UpdateUIEditorShellInteraction(
|
|||||||
finalHit.popupItem != nullptr ? finalHit.popupItem->itemId : std::string();
|
finalHit.popupItem != nullptr ? finalHit.popupItem->itemId : std::string();
|
||||||
frame.focused = state.focused || state.menuSession.HasOpenMenu();
|
frame.focused = state.focused || state.menuSession.HasOpenMenu();
|
||||||
interactionResult.workspaceResult = frame.workspaceInteractionFrame.result;
|
interactionResult.workspaceResult = frame.workspaceInteractionFrame.result;
|
||||||
|
interactionResult.menuModal = state.menuSession.HasOpenMenu();
|
||||||
|
interactionResult.workspaceInputSuppressed = menuModalDuringFrame;
|
||||||
interactionResult.requestPointerCapture =
|
interactionResult.requestPointerCapture =
|
||||||
interactionResult.workspaceResult.requestPointerCapture;
|
interactionResult.workspaceResult.requestPointerCapture;
|
||||||
interactionResult.releasePointerCapture =
|
interactionResult.releasePointerCapture =
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ using XCEngine::UI::Editor::UIEditorPanelRegistry;
|
|||||||
using XCEngine::UI::Editor::UIEditorShellInteractionFrame;
|
using XCEngine::UI::Editor::UIEditorShellInteractionFrame;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionModel;
|
using XCEngine::UI::Editor::UIEditorShellInteractionModel;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionResult;
|
using XCEngine::UI::Editor::UIEditorShellInteractionResult;
|
||||||
|
using XCEngine::UI::Editor::UIEditorShellInteractionServices;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionState;
|
using XCEngine::UI::Editor::UIEditorShellInteractionState;
|
||||||
using XCEngine::UI::Editor::UIEditorViewportInputBridgeFrame;
|
using XCEngine::UI::Editor::UIEditorViewportInputBridgeFrame;
|
||||||
using XCEngine::UI::Editor::UIEditorWorkspaceCommandKind;
|
using XCEngine::UI::Editor::UIEditorWorkspaceCommandKind;
|
||||||
@@ -125,6 +126,7 @@ bool HasMeaningfulInteractionResult(const UIEditorShellInteractionResult& result
|
|||||||
result.requestPointerCapture ||
|
result.requestPointerCapture ||
|
||||||
result.releasePointerCapture ||
|
result.releasePointerCapture ||
|
||||||
result.commandTriggered ||
|
result.commandTriggered ||
|
||||||
|
result.commandDispatched ||
|
||||||
result.menuMutation.changed ||
|
result.menuMutation.changed ||
|
||||||
result.workspaceResult.consumed ||
|
result.workspaceResult.consumed ||
|
||||||
!result.menuId.empty() ||
|
!result.menuId.empty() ||
|
||||||
@@ -781,10 +783,15 @@ void ScenarioApp::SetInteractionResult(const UIEditorShellInteractionResult& res
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.commandDispatched) {
|
||||||
|
SetDispatchResult(result.commandDispatchResult);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (result.commandTriggered) {
|
if (result.commandTriggered) {
|
||||||
const UIEditorCommandDispatchResult dispatchResult =
|
m_lastStatus = "Triggered";
|
||||||
m_commandDispatcher.Dispatch(result.commandId, m_controller);
|
m_lastMessage = "命令已命中,但当前场景没有把 dispatcher 接到 root shell。";
|
||||||
SetDispatchResult(dispatchResult);
|
m_lastColor = kWarning;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,24 +873,28 @@ void ScenarioApp::SetDispatchResult(const UIEditorCommandDispatchResult& result)
|
|||||||
void ScenarioApp::RenderFrame() {
|
void ScenarioApp::RenderFrame() {
|
||||||
UpdateLayout();
|
UpdateLayout();
|
||||||
m_cachedModel = BuildInteractionModel();
|
m_cachedModel = BuildInteractionModel();
|
||||||
|
UIEditorShellInteractionServices services = {};
|
||||||
|
services.commandDispatcher = &m_commandDispatcher;
|
||||||
m_cachedFrame = UpdateUIEditorShellInteraction(
|
m_cachedFrame = UpdateUIEditorShellInteraction(
|
||||||
m_interactionState,
|
m_interactionState,
|
||||||
m_controller,
|
m_controller,
|
||||||
m_shellRect,
|
m_shellRect,
|
||||||
m_cachedModel,
|
m_cachedModel,
|
||||||
m_pendingInputEvents);
|
m_pendingInputEvents,
|
||||||
|
services);
|
||||||
m_pendingInputEvents.clear();
|
m_pendingInputEvents.clear();
|
||||||
ApplyHostCaptureRequests(m_cachedFrame.result);
|
ApplyHostCaptureRequests(m_cachedFrame.result);
|
||||||
SetInteractionResult(m_cachedFrame.result);
|
SetInteractionResult(m_cachedFrame.result);
|
||||||
|
|
||||||
if (m_cachedFrame.result.commandTriggered) {
|
if (m_cachedFrame.result.commandDispatched) {
|
||||||
m_cachedModel = BuildInteractionModel();
|
m_cachedModel = BuildInteractionModel();
|
||||||
m_cachedFrame = UpdateUIEditorShellInteraction(
|
m_cachedFrame = UpdateUIEditorShellInteraction(
|
||||||
m_interactionState,
|
m_interactionState,
|
||||||
m_controller,
|
m_controller,
|
||||||
m_shellRect,
|
m_shellRect,
|
||||||
m_cachedModel,
|
m_cachedModel,
|
||||||
{});
|
{},
|
||||||
|
services);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto* viewportFrame =
|
const auto* viewportFrame =
|
||||||
@@ -905,7 +916,7 @@ void ScenarioApp::RenderFrame() {
|
|||||||
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 + 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 + 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. 验证菜单打开时会屏蔽 workspace 输入;菜单关闭后,workspace 交互立即恢复。", kTextPrimary, 12.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 + 158.0f), "5. 验证菜单命令会在 root shell 内直接 dispatch,宿主不再二次派发。", 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);
|
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, "操作", "只保留这个场景必要的控制。");
|
DrawCard(drawList, m_controlsRect, "操作", "只保留这个场景必要的控制。");
|
||||||
@@ -926,6 +937,21 @@ void ScenarioApp::RenderFrame() {
|
|||||||
addStateLine("Selected Presentation", selectedPresentation, 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("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("Focused", FormatBool(m_cachedFrame.focused), m_cachedFrame.focused ? kSuccess : kTextMuted);
|
||||||
|
addStateLine("Menu Modal", FormatBool(m_cachedFrame.result.menuModal), m_cachedFrame.result.menuModal ? kSuccess : kTextMuted, 11.0f);
|
||||||
|
addStateLine(
|
||||||
|
"Workspace Suppressed",
|
||||||
|
FormatBool(m_cachedFrame.result.workspaceInputSuppressed),
|
||||||
|
m_cachedFrame.result.workspaceInputSuppressed ? kWarning : kTextMuted,
|
||||||
|
11.0f);
|
||||||
|
addStateLine(
|
||||||
|
"Command Dispatch",
|
||||||
|
m_cachedFrame.result.commandDispatched
|
||||||
|
? std::string(GetUIEditorCommandDispatchStatusName(m_cachedFrame.result.commandDispatchResult.status))
|
||||||
|
: std::string("(none)"),
|
||||||
|
m_cachedFrame.result.commandDispatched && m_cachedFrame.result.commandDispatchResult.commandExecuted
|
||||||
|
? kSuccess
|
||||||
|
: kTextMuted,
|
||||||
|
11.0f);
|
||||||
addStateLine("Result", m_lastStatus, m_lastColor);
|
addStateLine("Result", m_lastStatus, m_lastColor);
|
||||||
drawList.AddText(UIPoint(m_stateRect.x + 16.0f, stateY + 4.0f), m_lastMessage, kTextMuted, 11.0f);
|
drawList.AddText(UIPoint(m_stateRect.x + 16.0f, stateY + 4.0f), m_lastMessage, kTextMuted, 11.0f);
|
||||||
stateY += 34.0f;
|
stateY += 34.0f;
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ using XCEngine::UI::Editor::BuildUIEditorWorkspacePanel;
|
|||||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
||||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
||||||
using XCEngine::UI::Editor::ResolveUIEditorShellInteractionRequest;
|
using XCEngine::UI::Editor::ResolveUIEditorShellInteractionRequest;
|
||||||
|
using XCEngine::UI::Editor::UIEditorCommandDispatchStatus;
|
||||||
|
using XCEngine::UI::Editor::UIEditorCommandDispatcher;
|
||||||
|
using XCEngine::UI::Editor::UIEditorCommandPanelSource;
|
||||||
|
using XCEngine::UI::Editor::UIEditorCommandRegistry;
|
||||||
using XCEngine::UI::Editor::UIEditorMenuItemKind;
|
using XCEngine::UI::Editor::UIEditorMenuItemKind;
|
||||||
using XCEngine::UI::Editor::UIEditorPanelPresentationKind;
|
using XCEngine::UI::Editor::UIEditorPanelPresentationKind;
|
||||||
using XCEngine::UI::Editor::UIEditorPanelRegistry;
|
using XCEngine::UI::Editor::UIEditorPanelRegistry;
|
||||||
@@ -29,8 +33,11 @@ using XCEngine::UI::Editor::UIEditorShellInteractionFrame;
|
|||||||
using XCEngine::UI::Editor::UIEditorShellInteractionMenuButtonRequest;
|
using XCEngine::UI::Editor::UIEditorShellInteractionMenuButtonRequest;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionModel;
|
using XCEngine::UI::Editor::UIEditorShellInteractionModel;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionPopupItemRequest;
|
using XCEngine::UI::Editor::UIEditorShellInteractionPopupItemRequest;
|
||||||
|
using XCEngine::UI::Editor::UIEditorShellInteractionServices;
|
||||||
using XCEngine::UI::Editor::UIEditorShellInteractionState;
|
using XCEngine::UI::Editor::UIEditorShellInteractionState;
|
||||||
using XCEngine::UI::Editor::UIEditorWorkspaceController;
|
using XCEngine::UI::Editor::UIEditorWorkspaceController;
|
||||||
|
using XCEngine::UI::Editor::UIEditorWorkspaceCommandKind;
|
||||||
|
using XCEngine::UI::Editor::UIEditorWorkspaceCommandStatus;
|
||||||
using XCEngine::UI::Editor::UIEditorWorkspaceModel;
|
using XCEngine::UI::Editor::UIEditorWorkspaceModel;
|
||||||
using XCEngine::UI::Editor::UIEditorWorkspacePanelPresentationModel;
|
using XCEngine::UI::Editor::UIEditorWorkspacePanelPresentationModel;
|
||||||
using XCEngine::UI::Editor::UIEditorWorkspaceSplitAxis;
|
using XCEngine::UI::Editor::UIEditorWorkspaceSplitAxis;
|
||||||
@@ -66,6 +73,33 @@ UIEditorWorkspaceModel BuildWorkspace() {
|
|||||||
return workspace;
|
return workspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UIEditorCommandRegistry BuildCommandRegistry() {
|
||||||
|
UIEditorCommandRegistry registry = {};
|
||||||
|
registry.commands = {
|
||||||
|
{
|
||||||
|
"workspace.show_inspector",
|
||||||
|
"Show Inspector",
|
||||||
|
{ UIEditorWorkspaceCommandKind::ShowPanel, UIEditorCommandPanelSource::FixedPanelId, "inspector" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"workspace.focus_inspector",
|
||||||
|
"Focus Inspector",
|
||||||
|
{ UIEditorWorkspaceCommandKind::ActivatePanel, UIEditorCommandPanelSource::FixedPanelId, "inspector" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"workspace.reset_layout",
|
||||||
|
"Reset Layout",
|
||||||
|
{ UIEditorWorkspaceCommandKind::ResetWorkspace, UIEditorCommandPanelSource::None, {} }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"workspace.close",
|
||||||
|
"Close",
|
||||||
|
{ UIEditorWorkspaceCommandKind::HidePanel, UIEditorCommandPanelSource::ActivePanel, {} }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return registry;
|
||||||
|
}
|
||||||
|
|
||||||
UIEditorResolvedMenuModel BuildResolvedMenuModel() {
|
UIEditorResolvedMenuModel BuildResolvedMenuModel() {
|
||||||
UIEditorResolvedMenuModel model = {};
|
UIEditorResolvedMenuModel model = {};
|
||||||
|
|
||||||
@@ -334,11 +368,63 @@ TEST(UIEditorShellInteractionTest, ClickCommandReturnsDispatchHookAndClosesMenu)
|
|||||||
{ MakeLeftPointerDown(RectCenter(commandItem->rect)) });
|
{ MakeLeftPointerDown(RectCenter(commandItem->rect)) });
|
||||||
|
|
||||||
EXPECT_TRUE(frame.result.commandTriggered);
|
EXPECT_TRUE(frame.result.commandTriggered);
|
||||||
|
EXPECT_FALSE(frame.result.commandDispatched);
|
||||||
EXPECT_EQ(frame.result.commandId, "workspace.close");
|
EXPECT_EQ(frame.result.commandId, "workspace.close");
|
||||||
EXPECT_FALSE(state.menuSession.HasOpenMenu());
|
EXPECT_FALSE(state.menuSession.HasOpenMenu());
|
||||||
EXPECT_TRUE(frame.request.popupRequests.empty());
|
EXPECT_TRUE(frame.request.popupRequests.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(UIEditorShellInteractionTest, ClickCommandDispatchesInsideShellAndUpdatesWorkspaceSameFrame) {
|
||||||
|
auto controller = BuildController();
|
||||||
|
const auto model = BuildInteractionModel();
|
||||||
|
const UIEditorCommandDispatcher dispatcher(BuildCommandRegistry());
|
||||||
|
UIEditorShellInteractionServices services = {};
|
||||||
|
services.commandDispatcher = &dispatcher;
|
||||||
|
|
||||||
|
UIEditorShellInteractionState state = {};
|
||||||
|
auto frame = UpdateUIEditorShellInteraction(
|
||||||
|
state,
|
||||||
|
controller,
|
||||||
|
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||||
|
model,
|
||||||
|
{},
|
||||||
|
services);
|
||||||
|
const auto* windowButton = FindMenuButton(frame, "window");
|
||||||
|
ASSERT_NE(windowButton, nullptr);
|
||||||
|
|
||||||
|
frame = UpdateUIEditorShellInteraction(
|
||||||
|
state,
|
||||||
|
controller,
|
||||||
|
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||||
|
model,
|
||||||
|
{ MakeLeftPointerDown(RectCenter(windowButton->rect)) },
|
||||||
|
services);
|
||||||
|
const auto* commandItem = FindPopupItem(frame, "window-focus-inspector");
|
||||||
|
ASSERT_NE(commandItem, nullptr);
|
||||||
|
|
||||||
|
frame = UpdateUIEditorShellInteraction(
|
||||||
|
state,
|
||||||
|
controller,
|
||||||
|
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||||
|
model,
|
||||||
|
{ MakeLeftPointerDown(RectCenter(commandItem->rect)) },
|
||||||
|
services);
|
||||||
|
|
||||||
|
EXPECT_TRUE(frame.result.commandTriggered);
|
||||||
|
EXPECT_TRUE(frame.result.commandDispatched);
|
||||||
|
EXPECT_EQ(frame.result.commandId, "workspace.focus_inspector");
|
||||||
|
EXPECT_EQ(
|
||||||
|
frame.result.commandDispatchResult.status,
|
||||||
|
UIEditorCommandDispatchStatus::Dispatched);
|
||||||
|
EXPECT_TRUE(frame.result.commandDispatchResult.commandExecuted);
|
||||||
|
EXPECT_EQ(
|
||||||
|
frame.result.commandDispatchResult.commandResult.status,
|
||||||
|
UIEditorWorkspaceCommandStatus::Changed);
|
||||||
|
EXPECT_EQ(controller.GetWorkspace().activePanelId, "inspector");
|
||||||
|
EXPECT_FALSE(state.menuSession.HasOpenMenu());
|
||||||
|
EXPECT_TRUE(frame.request.popupRequests.empty());
|
||||||
|
}
|
||||||
|
|
||||||
TEST(UIEditorShellInteractionTest, PointerDownOutsideDismissesWholeMenuChain) {
|
TEST(UIEditorShellInteractionTest, PointerDownOutsideDismissesWholeMenuChain) {
|
||||||
auto controller = BuildController();
|
auto controller = BuildController();
|
||||||
const auto model = BuildInteractionModel();
|
const auto model = BuildInteractionModel();
|
||||||
|
|||||||
Reference in New Issue
Block a user