Add editor panel content host contract
This commit is contained in:
@@ -9,6 +9,7 @@ set(EDITOR_UI_UNIT_TEST_SOURCES
|
||||
test_ui_editor_menu_session.cpp
|
||||
test_ui_editor_menu_bar.cpp
|
||||
test_ui_editor_menu_popup.cpp
|
||||
test_ui_editor_panel_content_host.cpp
|
||||
test_ui_editor_panel_host_lifecycle.cpp
|
||||
test_ui_editor_panel_registry.cpp
|
||||
test_ui_editor_shell_compose.cpp
|
||||
|
||||
181
tests/UI/Editor/unit/test_ui_editor_panel_content_host.cpp
Normal file
181
tests/UI/Editor/unit/test_ui_editor_panel_content_host.cpp
Normal file
@@ -0,0 +1,181 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <XCEditor/Core/UIEditorPanelContentHost.h>
|
||||
#include <XCEditor/Core/UIEditorWorkspaceSession.h>
|
||||
#include <XCEditor/Widgets/UIEditorDockHost.h>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::UI::UIRect;
|
||||
using XCEngine::UI::Editor::BuildDefaultUIEditorWorkspaceSession;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspacePanel;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
||||
using XCEngine::UI::Editor::CollectMountedUIEditorPanelContentHostPanelIds;
|
||||
using XCEngine::UI::Editor::FindUIEditorPanelContentHostMountRequest;
|
||||
using XCEngine::UI::Editor::FindUIEditorPanelContentHostPanelState;
|
||||
using XCEngine::UI::Editor::GetUIEditorPanelContentHostEventKindName;
|
||||
using XCEngine::UI::Editor::ResolveUIEditorPanelContentHostRequest;
|
||||
using XCEngine::UI::Editor::UIEditorPanelContentHostBinding;
|
||||
using XCEngine::UI::Editor::UIEditorPanelContentHostState;
|
||||
using XCEngine::UI::Editor::UIEditorPanelPresentationKind;
|
||||
using XCEngine::UI::Editor::UIEditorPanelRegistry;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceModel;
|
||||
using XCEngine::UI::Editor::UIEditorWorkspaceSplitAxis;
|
||||
using XCEngine::UI::Editor::UpdateUIEditorPanelContentHost;
|
||||
using XCEngine::UI::Editor::Widgets::BuildUIEditorDockHostLayout;
|
||||
|
||||
UIEditorPanelRegistry BuildPanelRegistry() {
|
||||
UIEditorPanelRegistry registry = {};
|
||||
registry.panels = {
|
||||
{ "doc-a", "Document A", UIEditorPanelPresentationKind::HostedContent, false, true, true },
|
||||
{ "doc-b", "Document B", UIEditorPanelPresentationKind::HostedContent, false, true, true },
|
||||
{ "console", "Console", UIEditorPanelPresentationKind::Placeholder, true, true, true },
|
||||
{ "inspector", "Inspector", UIEditorPanelPresentationKind::HostedContent, false, true, true }
|
||||
};
|
||||
return registry;
|
||||
}
|
||||
|
||||
UIEditorWorkspaceModel BuildWorkspace() {
|
||||
UIEditorWorkspaceModel workspace = {};
|
||||
workspace.root = BuildUIEditorWorkspaceSplit(
|
||||
"root",
|
||||
UIEditorWorkspaceSplitAxis::Horizontal,
|
||||
0.68f,
|
||||
BuildUIEditorWorkspaceTabStack(
|
||||
"documents",
|
||||
{
|
||||
BuildUIEditorWorkspacePanel("doc-a-node", "doc-a", "Document A"),
|
||||
BuildUIEditorWorkspacePanel("doc-b-node", "doc-b", "Document B"),
|
||||
BuildUIEditorWorkspacePanel("console-node", "console", "Console", true)
|
||||
},
|
||||
1u),
|
||||
BuildUIEditorWorkspacePanel("inspector-node", "inspector", "Inspector"));
|
||||
workspace.activePanelId = "doc-b";
|
||||
return workspace;
|
||||
}
|
||||
|
||||
std::vector<UIEditorPanelContentHostBinding> BuildBindings() {
|
||||
return {
|
||||
{ "doc-a", UIEditorPanelPresentationKind::HostedContent },
|
||||
{ "doc-b", UIEditorPanelPresentationKind::HostedContent },
|
||||
{ "console", UIEditorPanelPresentationKind::Placeholder },
|
||||
{ "inspector", UIEditorPanelPresentationKind::HostedContent }
|
||||
};
|
||||
}
|
||||
|
||||
std::vector<std::string> FormatEvents(
|
||||
const std::vector<XCEngine::UI::Editor::UIEditorPanelContentHostEvent>& events) {
|
||||
std::vector<std::string> formatted = {};
|
||||
formatted.reserve(events.size());
|
||||
for (const auto& event : events) {
|
||||
formatted.push_back(
|
||||
std::string(GetUIEditorPanelContentHostEventKindName(event.kind)) + ":" + event.panelId);
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(UIEditorPanelContentHostTest, ResolveRequestMountsSelectedHostedTabAndStandaloneHostedPanel) {
|
||||
const UIEditorPanelRegistry registry = BuildPanelRegistry();
|
||||
const UIEditorWorkspaceModel workspace = BuildWorkspace();
|
||||
const auto session = BuildDefaultUIEditorWorkspaceSession(registry, workspace);
|
||||
const auto layout = BuildUIEditorDockHostLayout(
|
||||
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session);
|
||||
|
||||
const auto request = ResolveUIEditorPanelContentHostRequest(
|
||||
layout,
|
||||
registry,
|
||||
BuildBindings());
|
||||
|
||||
ASSERT_EQ(request.mountRequests.size(), 2u);
|
||||
EXPECT_NE(FindUIEditorPanelContentHostMountRequest(request, "doc-b"), nullptr);
|
||||
EXPECT_NE(FindUIEditorPanelContentHostMountRequest(request, "inspector"), nullptr);
|
||||
EXPECT_EQ(FindUIEditorPanelContentHostMountRequest(request, "doc-a"), nullptr);
|
||||
EXPECT_EQ(FindUIEditorPanelContentHostMountRequest(request, "console"), nullptr);
|
||||
}
|
||||
|
||||
TEST(UIEditorPanelContentHostTest, UpdateEmitsMountedAndUnmountedWhenHostedTabSelectionChanges) {
|
||||
const UIEditorPanelRegistry registry = BuildPanelRegistry();
|
||||
UIEditorWorkspaceModel workspace = BuildWorkspace();
|
||||
const auto session = BuildDefaultUIEditorWorkspaceSession(registry, workspace);
|
||||
|
||||
UIEditorPanelContentHostState state = {};
|
||||
auto layout = BuildUIEditorDockHostLayout(
|
||||
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session);
|
||||
auto request = ResolveUIEditorPanelContentHostRequest(layout, registry, BuildBindings());
|
||||
const auto initialFrame = UpdateUIEditorPanelContentHost(
|
||||
state,
|
||||
request,
|
||||
registry,
|
||||
BuildBindings());
|
||||
EXPECT_EQ(
|
||||
FormatEvents(initialFrame.events),
|
||||
std::vector<std::string>({ "Mounted:doc-b", "Mounted:inspector" }));
|
||||
EXPECT_EQ(
|
||||
CollectMountedUIEditorPanelContentHostPanelIds(initialFrame),
|
||||
std::vector<std::string>({ "doc-b", "inspector" }));
|
||||
|
||||
workspace.root.children[0].selectedTabIndex = 0u;
|
||||
workspace.activePanelId = "doc-a";
|
||||
layout = BuildUIEditorDockHostLayout(
|
||||
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session);
|
||||
request = ResolveUIEditorPanelContentHostRequest(layout, registry, BuildBindings());
|
||||
const auto switchedFrame = UpdateUIEditorPanelContentHost(
|
||||
state,
|
||||
request,
|
||||
registry,
|
||||
BuildBindings());
|
||||
|
||||
EXPECT_EQ(
|
||||
FormatEvents(switchedFrame.events),
|
||||
std::vector<std::string>({ "Mounted:doc-a", "Unmounted:doc-b" }));
|
||||
|
||||
const auto* docAState = FindUIEditorPanelContentHostPanelState(switchedFrame, "doc-a");
|
||||
const auto* docBState = FindUIEditorPanelContentHostPanelState(switchedFrame, "doc-b");
|
||||
ASSERT_NE(docAState, nullptr);
|
||||
ASSERT_NE(docBState, nullptr);
|
||||
EXPECT_TRUE(docAState->mounted);
|
||||
EXPECT_FALSE(docBState->mounted);
|
||||
}
|
||||
|
||||
TEST(UIEditorPanelContentHostTest, UpdateEmitsBoundsChangedForMountedHostedPanelsWhenLayoutChanges) {
|
||||
const UIEditorPanelRegistry registry = BuildPanelRegistry();
|
||||
const UIEditorWorkspaceModel workspace = BuildWorkspace();
|
||||
const auto session = BuildDefaultUIEditorWorkspaceSession(registry, workspace);
|
||||
|
||||
UIEditorPanelContentHostState state = {};
|
||||
auto layout = BuildUIEditorDockHostLayout(
|
||||
UIRect(0.0f, 0.0f, 1280.0f, 720.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session);
|
||||
auto request = ResolveUIEditorPanelContentHostRequest(layout, registry, BuildBindings());
|
||||
UpdateUIEditorPanelContentHost(state, request, registry, BuildBindings());
|
||||
|
||||
layout = BuildUIEditorDockHostLayout(
|
||||
UIRect(0.0f, 0.0f, 1440.0f, 800.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session);
|
||||
request = ResolveUIEditorPanelContentHostRequest(layout, registry, BuildBindings());
|
||||
const auto resizedFrame = UpdateUIEditorPanelContentHost(
|
||||
state,
|
||||
request,
|
||||
registry,
|
||||
BuildBindings());
|
||||
|
||||
EXPECT_EQ(
|
||||
FormatEvents(resizedFrame.events),
|
||||
std::vector<std::string>({ "BoundsChanged:doc-b", "BoundsChanged:inspector" }));
|
||||
}
|
||||
@@ -10,6 +10,7 @@ using XCEngine::UI::UIInputEventType;
|
||||
using XCEngine::UI::UIPoint;
|
||||
using XCEngine::UI::UIPointerButton;
|
||||
using XCEngine::UI::Editor::BuildDefaultUIEditorWorkspaceSession;
|
||||
using XCEngine::UI::Editor::CollectUIEditorWorkspaceComposeExternalBodyPanelIds;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspacePanel;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceSplit;
|
||||
using XCEngine::UI::Editor::BuildUIEditorWorkspaceTabStack;
|
||||
@@ -88,6 +89,42 @@ XCEngine::UI::Editor::UIEditorViewportShellModel BuildViewportShellModel(std::st
|
||||
return model;
|
||||
}
|
||||
|
||||
UIEditorPanelRegistry BuildRegistryWithHostedContentPanels() {
|
||||
UIEditorPanelRegistry registry = {};
|
||||
registry.panels = {
|
||||
{ "doc-a", "Document A", UIEditorPanelPresentationKind::HostedContent, false, true, true },
|
||||
{ "doc-b", "Document B", UIEditorPanelPresentationKind::HostedContent, false, true, true },
|
||||
{ "inspector", "Inspector", UIEditorPanelPresentationKind::HostedContent, false, true, true }
|
||||
};
|
||||
return registry;
|
||||
}
|
||||
|
||||
UIEditorWorkspaceModel BuildHostedContentWorkspace() {
|
||||
UIEditorWorkspaceModel workspace = {};
|
||||
workspace.root = BuildUIEditorWorkspaceSplit(
|
||||
"root",
|
||||
UIEditorWorkspaceSplitAxis::Horizontal,
|
||||
0.68f,
|
||||
BuildUIEditorWorkspaceTabStack(
|
||||
"documents",
|
||||
{
|
||||
BuildUIEditorWorkspacePanel("doc-a-node", "doc-a", "Document A"),
|
||||
BuildUIEditorWorkspacePanel("doc-b-node", "doc-b", "Document B")
|
||||
},
|
||||
1u),
|
||||
BuildUIEditorWorkspacePanel("inspector-node", "inspector", "Inspector"));
|
||||
workspace.activePanelId = "doc-b";
|
||||
return workspace;
|
||||
}
|
||||
|
||||
UIEditorWorkspacePanelPresentationModel BuildHostedContentPresentationModel(
|
||||
std::string panelId) {
|
||||
UIEditorWorkspacePanelPresentationModel model = {};
|
||||
model.panelId = std::move(panelId);
|
||||
model.kind = UIEditorPanelPresentationKind::HostedContent;
|
||||
return model;
|
||||
}
|
||||
|
||||
UIEditorWorkspacePanelPresentationModel BuildViewportPresentationModel(
|
||||
std::string panelId,
|
||||
std::string title) {
|
||||
@@ -267,3 +304,29 @@ TEST(UIEditorWorkspaceComposeTest, HiddenViewportTabResetsCapturedAndFocusedStat
|
||||
EXPECT_FALSE(viewportBStateAfterHide->viewportShellState.inputBridgeState.focused);
|
||||
EXPECT_FALSE(viewportBStateAfterHide->viewportShellState.inputBridgeState.captured);
|
||||
}
|
||||
|
||||
TEST(UIEditorWorkspaceComposeTest, HostedContentPanelsFlowThroughContentHostAndSuppressDockPlaceholder) {
|
||||
const auto registry = BuildRegistryWithHostedContentPanels();
|
||||
const UIEditorWorkspaceModel workspace = BuildHostedContentWorkspace();
|
||||
const auto session = BuildDefaultUIEditorWorkspaceSession(registry, workspace);
|
||||
const std::vector<UIEditorWorkspacePanelPresentationModel> presentationModels = {
|
||||
BuildHostedContentPresentationModel("doc-a"),
|
||||
BuildHostedContentPresentationModel("doc-b"),
|
||||
BuildHostedContentPresentationModel("inspector")
|
||||
};
|
||||
|
||||
UIEditorWorkspaceComposeState state = {};
|
||||
const UIEditorWorkspaceComposeFrame frame = UpdateUIEditorWorkspaceCompose(
|
||||
state,
|
||||
UIRect(0.0f, 0.0f, 1200.0f, 760.0f),
|
||||
registry,
|
||||
workspace,
|
||||
session,
|
||||
presentationModels,
|
||||
{});
|
||||
|
||||
EXPECT_TRUE(frame.viewportFrames.empty());
|
||||
EXPECT_EQ(
|
||||
CollectUIEditorWorkspaceComposeExternalBodyPanelIds(frame),
|
||||
std::vector<std::string>({ "doc-b", "inspector" }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user