Add XCUI expansion state and coverage tests
This commit is contained in:
@@ -100,6 +100,12 @@ set(NEW_EDITOR_STANDALONE_TEXT_ATLAS_PROVIDER_SOURCE
|
||||
set(NEW_EDITOR_HOSTED_PREVIEW_PRESENTER_HEADER
|
||||
${CMAKE_SOURCE_DIR}/new_editor/src/XCUIBackend/XCUIHostedPreviewPresenter.h
|
||||
)
|
||||
set(NEW_EDITOR_WINDOW_UI_COMPOSITOR_HEADER
|
||||
${CMAKE_SOURCE_DIR}/new_editor/src/XCUIBackend/IWindowUICompositor.h
|
||||
)
|
||||
set(NEW_EDITOR_IMGUI_WINDOW_UI_COMPOSITOR_HEADER
|
||||
${CMAKE_SOURCE_DIR}/new_editor/src/XCUIBackend/ImGuiWindowUICompositor.h
|
||||
)
|
||||
set(NEW_EDITOR_NATIVE_BACKDROP_RENDERER_HEADER
|
||||
${CMAKE_SOURCE_DIR}/new_editor/src/Rendering/MainWindowNativeBackdropRenderer.h
|
||||
)
|
||||
@@ -265,6 +271,37 @@ else()
|
||||
message(STATUS "Skipping new_editor_xcui_hosted_preview_presenter_tests because presenter header or ImGui sources are missing.")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${NEW_EDITOR_WINDOW_UI_COMPOSITOR_HEADER}" AND
|
||||
EXISTS "${NEW_EDITOR_IMGUI_WINDOW_UI_COMPOSITOR_HEADER}" AND
|
||||
EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test_imgui_window_ui_compositor.cpp")
|
||||
add_executable(new_editor_imgui_window_ui_compositor_tests
|
||||
test_imgui_window_ui_compositor.cpp
|
||||
)
|
||||
|
||||
xcengine_configure_new_editor_test_target(new_editor_imgui_window_ui_compositor_tests)
|
||||
|
||||
target_link_libraries(new_editor_imgui_window_ui_compositor_tests
|
||||
PRIVATE
|
||||
XCEngine
|
||||
GTest::gtest
|
||||
GTest::gtest_main
|
||||
user32
|
||||
comdlg32
|
||||
)
|
||||
|
||||
target_include_directories(new_editor_imgui_window_ui_compositor_tests PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/engine/include
|
||||
${CMAKE_SOURCE_DIR}/new_editor/src
|
||||
${CMAKE_SOURCE_DIR}/editor/src
|
||||
${CMAKE_BINARY_DIR}/_deps/imgui-src
|
||||
${CMAKE_BINARY_DIR}/_deps/imgui-src/backends
|
||||
)
|
||||
|
||||
xcengine_discover_new_editor_gtests(new_editor_imgui_window_ui_compositor_tests)
|
||||
else()
|
||||
message(STATUS "Skipping new_editor_imgui_window_ui_compositor_tests because compositor headers or the test source are missing.")
|
||||
endif()
|
||||
|
||||
if(EXISTS "${NEW_EDITOR_NATIVE_BACKDROP_RENDERER_HEADER}")
|
||||
add_executable(new_editor_native_backdrop_renderer_api_tests
|
||||
test_main_window_native_backdrop_renderer_api.cpp
|
||||
|
||||
283
tests/NewEditor/test_imgui_window_ui_compositor.cpp
Normal file
283
tests/NewEditor/test_imgui_window_ui_compositor.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "XCUIBackend/IEditorHostCompositor.h"
|
||||
#include "XCUIBackend/ImGuiWindowUICompositor.h"
|
||||
#include "XCUIBackend/UITextureRegistration.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace {
|
||||
|
||||
using XCEngine::Editor::Platform::D3D12WindowRenderer;
|
||||
using XCEngine::Editor::XCUIBackend::IEditorHostCompositor;
|
||||
using XCEngine::Editor::XCUIBackend::ImGuiWindowUICompositor;
|
||||
using XCEngine::Editor::XCUIBackend::UITextureRegistration;
|
||||
|
||||
class RecordingHostCompositor final : public IEditorHostCompositor {
|
||||
public:
|
||||
bool initializeResult = true;
|
||||
bool handleWindowMessageResult = false;
|
||||
bool createTextureDescriptorResult = false;
|
||||
bool invokeConfigureFonts = false;
|
||||
|
||||
int initializeCount = 0;
|
||||
int shutdownCount = 0;
|
||||
int beginFrameCount = 0;
|
||||
int endFrameCount = 0;
|
||||
int handleWindowMessageCount = 0;
|
||||
int createTextureDescriptorCount = 0;
|
||||
int freeTextureDescriptorCount = 0;
|
||||
|
||||
HWND lastHwnd = nullptr;
|
||||
UINT lastMessage = 0u;
|
||||
WPARAM lastWParam = 0u;
|
||||
LPARAM lastLParam = 0u;
|
||||
|
||||
D3D12WindowRenderer* initializedRenderer = nullptr;
|
||||
D3D12WindowRenderer* presentedRenderer = nullptr;
|
||||
::XCEngine::RHI::RHIDevice* lastDevice = nullptr;
|
||||
::XCEngine::RHI::RHITexture* lastTexture = nullptr;
|
||||
|
||||
bool beforeUiRenderProvided = false;
|
||||
bool afterUiRenderProvided = false;
|
||||
|
||||
std::array<float, 4> lastClearColor = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
UITextureRegistration nextRegistration = {};
|
||||
UITextureRegistration freedRegistration = {};
|
||||
std::vector<std::string> callOrder = {};
|
||||
|
||||
bool Initialize(
|
||||
HWND hwnd,
|
||||
D3D12WindowRenderer& windowRenderer,
|
||||
const ConfigureFontsCallback& configureFonts) override {
|
||||
++initializeCount;
|
||||
lastHwnd = hwnd;
|
||||
initializedRenderer = &windowRenderer;
|
||||
callOrder.push_back("initialize");
|
||||
if (invokeConfigureFonts && configureFonts) {
|
||||
configureFonts();
|
||||
}
|
||||
return initializeResult;
|
||||
}
|
||||
|
||||
void Shutdown() override {
|
||||
++shutdownCount;
|
||||
callOrder.push_back("shutdown");
|
||||
}
|
||||
|
||||
bool HandleWindowMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) override {
|
||||
++handleWindowMessageCount;
|
||||
lastHwnd = hwnd;
|
||||
lastMessage = message;
|
||||
lastWParam = wParam;
|
||||
lastLParam = lParam;
|
||||
callOrder.push_back("message");
|
||||
return handleWindowMessageResult;
|
||||
}
|
||||
|
||||
void BeginFrame() override {
|
||||
++beginFrameCount;
|
||||
callOrder.push_back("begin");
|
||||
}
|
||||
|
||||
void EndFrameAndPresent(
|
||||
D3D12WindowRenderer& windowRenderer,
|
||||
const float clearColor[4],
|
||||
const RenderCallback& beforeUiRender,
|
||||
const RenderCallback& afterUiRender) override {
|
||||
++endFrameCount;
|
||||
presentedRenderer = &windowRenderer;
|
||||
beforeUiRenderProvided = static_cast<bool>(beforeUiRender);
|
||||
afterUiRenderProvided = static_cast<bool>(afterUiRender);
|
||||
for (std::size_t index = 0; index < lastClearColor.size(); ++index) {
|
||||
lastClearColor[index] = clearColor[index];
|
||||
}
|
||||
callOrder.push_back("present");
|
||||
}
|
||||
|
||||
bool CreateTextureDescriptor(
|
||||
::XCEngine::RHI::RHIDevice* device,
|
||||
::XCEngine::RHI::RHITexture* texture,
|
||||
UITextureRegistration& outRegistration) override {
|
||||
++createTextureDescriptorCount;
|
||||
lastDevice = device;
|
||||
lastTexture = texture;
|
||||
if (createTextureDescriptorResult) {
|
||||
outRegistration = nextRegistration;
|
||||
}
|
||||
return createTextureDescriptorResult;
|
||||
}
|
||||
|
||||
void FreeTextureDescriptor(const UITextureRegistration& registration) override {
|
||||
++freeTextureDescriptorCount;
|
||||
freedRegistration = registration;
|
||||
}
|
||||
};
|
||||
|
||||
HWND MakeFakeHwnd() {
|
||||
return reinterpret_cast<HWND>(static_cast<std::uintptr_t>(0x1234u));
|
||||
}
|
||||
|
||||
UITextureRegistration MakeRegistration() {
|
||||
UITextureRegistration registration = {};
|
||||
registration.cpuHandle.ptr = 11u;
|
||||
registration.gpuHandle.ptr = 29u;
|
||||
registration.texture.nativeHandle = 43u;
|
||||
registration.texture.width = 256u;
|
||||
registration.texture.height = 128u;
|
||||
registration.texture.kind = ::XCEngine::UI::UITextureHandleKind::ShaderResourceView;
|
||||
return registration;
|
||||
}
|
||||
|
||||
TEST(ImGuiWindowUICompositorTest, InitializeForwardsToHostAndConfigureFontsCallback) {
|
||||
auto host = std::make_unique<RecordingHostCompositor>();
|
||||
RecordingHostCompositor* hostPtr = host.get();
|
||||
hostPtr->invokeConfigureFonts = true;
|
||||
|
||||
ImGuiWindowUICompositor compositor(std::move(host));
|
||||
D3D12WindowRenderer renderer = {};
|
||||
bool configureFontsCalled = false;
|
||||
|
||||
EXPECT_TRUE(compositor.Initialize(
|
||||
MakeFakeHwnd(),
|
||||
renderer,
|
||||
[&configureFontsCalled]() { configureFontsCalled = true; }));
|
||||
EXPECT_TRUE(configureFontsCalled);
|
||||
ASSERT_NE(hostPtr, nullptr);
|
||||
EXPECT_EQ(hostPtr->initializeCount, 1);
|
||||
EXPECT_EQ(hostPtr->lastHwnd, MakeFakeHwnd());
|
||||
EXPECT_EQ(hostPtr->initializedRenderer, &renderer);
|
||||
}
|
||||
|
||||
TEST(ImGuiWindowUICompositorTest, RenderFrameCallsHostBeginUiAndPresentInOrder) {
|
||||
auto host = std::make_unique<RecordingHostCompositor>();
|
||||
RecordingHostCompositor* hostPtr = host.get();
|
||||
|
||||
ImGuiWindowUICompositor compositor(std::move(host));
|
||||
D3D12WindowRenderer renderer = {};
|
||||
ASSERT_TRUE(compositor.Initialize(MakeFakeHwnd(), renderer, {}));
|
||||
hostPtr->callOrder.clear();
|
||||
|
||||
bool uiRendered = false;
|
||||
constexpr float clearColor[4] = { 0.1f, 0.2f, 0.3f, 0.4f };
|
||||
compositor.RenderFrame(
|
||||
clearColor,
|
||||
[&]() {
|
||||
uiRendered = true;
|
||||
hostPtr->callOrder.push_back("ui");
|
||||
},
|
||||
[](const ::XCEngine::Rendering::RenderContext&, const ::XCEngine::Rendering::RenderSurface&) {},
|
||||
[](const ::XCEngine::Rendering::RenderContext&, const ::XCEngine::Rendering::RenderSurface&) {});
|
||||
|
||||
EXPECT_TRUE(uiRendered);
|
||||
EXPECT_EQ(hostPtr->beginFrameCount, 1);
|
||||
EXPECT_EQ(hostPtr->endFrameCount, 1);
|
||||
EXPECT_EQ(hostPtr->presentedRenderer, &renderer);
|
||||
EXPECT_TRUE(hostPtr->beforeUiRenderProvided);
|
||||
EXPECT_TRUE(hostPtr->afterUiRenderProvided);
|
||||
EXPECT_EQ(hostPtr->lastClearColor[0], clearColor[0]);
|
||||
EXPECT_EQ(hostPtr->lastClearColor[1], clearColor[1]);
|
||||
EXPECT_EQ(hostPtr->lastClearColor[2], clearColor[2]);
|
||||
EXPECT_EQ(hostPtr->lastClearColor[3], clearColor[3]);
|
||||
EXPECT_EQ(
|
||||
hostPtr->callOrder,
|
||||
(std::vector<std::string>{ "begin", "ui", "present" }));
|
||||
}
|
||||
|
||||
TEST(ImGuiWindowUICompositorTest, HandleWindowMessageAndTextureRegistrationForwardToHost) {
|
||||
auto host = std::make_unique<RecordingHostCompositor>();
|
||||
RecordingHostCompositor* hostPtr = host.get();
|
||||
hostPtr->handleWindowMessageResult = true;
|
||||
hostPtr->createTextureDescriptorResult = true;
|
||||
hostPtr->nextRegistration = MakeRegistration();
|
||||
|
||||
ImGuiWindowUICompositor compositor(std::move(host));
|
||||
|
||||
EXPECT_TRUE(compositor.HandleWindowMessage(MakeFakeHwnd(), WM_SIZE, 7u, 19u));
|
||||
EXPECT_EQ(hostPtr->handleWindowMessageCount, 1);
|
||||
EXPECT_EQ(hostPtr->lastMessage, static_cast<UINT>(WM_SIZE));
|
||||
EXPECT_EQ(hostPtr->lastWParam, static_cast<WPARAM>(7u));
|
||||
EXPECT_EQ(hostPtr->lastLParam, static_cast<LPARAM>(19u));
|
||||
|
||||
UITextureRegistration registration = {};
|
||||
auto* fakeDevice = reinterpret_cast<::XCEngine::RHI::RHIDevice*>(static_cast<std::uintptr_t>(0x41u));
|
||||
auto* fakeTexture = reinterpret_cast<::XCEngine::RHI::RHITexture*>(static_cast<std::uintptr_t>(0x59u));
|
||||
EXPECT_TRUE(compositor.CreateTextureDescriptor(fakeDevice, fakeTexture, registration));
|
||||
EXPECT_EQ(hostPtr->createTextureDescriptorCount, 1);
|
||||
EXPECT_EQ(hostPtr->lastDevice, fakeDevice);
|
||||
EXPECT_EQ(hostPtr->lastTexture, fakeTexture);
|
||||
EXPECT_EQ(registration.cpuHandle.ptr, hostPtr->nextRegistration.cpuHandle.ptr);
|
||||
EXPECT_EQ(registration.gpuHandle.ptr, hostPtr->nextRegistration.gpuHandle.ptr);
|
||||
EXPECT_EQ(registration.texture.nativeHandle, hostPtr->nextRegistration.texture.nativeHandle);
|
||||
|
||||
compositor.FreeTextureDescriptor(registration);
|
||||
EXPECT_EQ(hostPtr->freeTextureDescriptorCount, 1);
|
||||
EXPECT_EQ(hostPtr->freedRegistration.cpuHandle.ptr, registration.cpuHandle.ptr);
|
||||
EXPECT_EQ(hostPtr->freedRegistration.gpuHandle.ptr, registration.gpuHandle.ptr);
|
||||
EXPECT_EQ(hostPtr->freedRegistration.texture.nativeHandle, registration.texture.nativeHandle);
|
||||
}
|
||||
|
||||
TEST(ImGuiWindowUICompositorTest, ShutdownClearsRendererBindingAndPreventsFurtherRender) {
|
||||
auto host = std::make_unique<RecordingHostCompositor>();
|
||||
RecordingHostCompositor* hostPtr = host.get();
|
||||
|
||||
ImGuiWindowUICompositor compositor(std::move(host));
|
||||
D3D12WindowRenderer renderer = {};
|
||||
ASSERT_TRUE(compositor.Initialize(MakeFakeHwnd(), renderer, {}));
|
||||
|
||||
bool firstUiRendered = false;
|
||||
compositor.RenderFrame(
|
||||
std::array<float, 4>{ 0.0f, 0.0f, 0.0f, 1.0f }.data(),
|
||||
[&]() { firstUiRendered = true; },
|
||||
{},
|
||||
{});
|
||||
EXPECT_TRUE(firstUiRendered);
|
||||
EXPECT_EQ(hostPtr->beginFrameCount, 1);
|
||||
EXPECT_EQ(hostPtr->endFrameCount, 1);
|
||||
|
||||
compositor.Shutdown();
|
||||
EXPECT_EQ(hostPtr->shutdownCount, 1);
|
||||
|
||||
bool secondUiRendered = false;
|
||||
compositor.RenderFrame(
|
||||
std::array<float, 4>{ 1.0f, 0.0f, 0.0f, 1.0f }.data(),
|
||||
[&]() { secondUiRendered = true; },
|
||||
{},
|
||||
{});
|
||||
EXPECT_FALSE(secondUiRendered);
|
||||
EXPECT_EQ(hostPtr->beginFrameCount, 1);
|
||||
EXPECT_EQ(hostPtr->endFrameCount, 1);
|
||||
}
|
||||
|
||||
TEST(ImGuiWindowUICompositorTest, NullHostCompositorReturnsSafeDefaults) {
|
||||
ImGuiWindowUICompositor compositor(std::unique_ptr<IEditorHostCompositor>{});
|
||||
D3D12WindowRenderer renderer = {};
|
||||
|
||||
bool configureFontsCalled = false;
|
||||
EXPECT_FALSE(compositor.Initialize(
|
||||
MakeFakeHwnd(),
|
||||
renderer,
|
||||
[&configureFontsCalled]() { configureFontsCalled = true; }));
|
||||
EXPECT_FALSE(configureFontsCalled);
|
||||
EXPECT_FALSE(compositor.HandleWindowMessage(MakeFakeHwnd(), WM_CLOSE, 0u, 0u));
|
||||
|
||||
UITextureRegistration registration = {};
|
||||
EXPECT_FALSE(compositor.CreateTextureDescriptor(nullptr, nullptr, registration));
|
||||
|
||||
bool uiRendered = false;
|
||||
compositor.RenderFrame(
|
||||
std::array<float, 4>{ 0.0f, 0.0f, 0.0f, 1.0f }.data(),
|
||||
[&]() { uiRendered = true; },
|
||||
{},
|
||||
{});
|
||||
EXPECT_FALSE(uiRendered);
|
||||
|
||||
compositor.Shutdown();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -250,3 +250,116 @@ TEST(NewEditorXCUILayoutLabRuntimeTest, ClickSelectionPersistsOnSharedCollection
|
||||
ASSERT_TRUE(persistedFrame.stats.documentsReady);
|
||||
EXPECT_EQ(persistedFrame.stats.selectedElementId, selectedElementId);
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabRuntimeTest, ClickingTreeRootTogglesIndentedChildrenVisibility) {
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabRuntime runtime;
|
||||
ASSERT_TRUE(runtime.ReloadDocuments());
|
||||
|
||||
const auto& baseline = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(baseline.stats.documentsReady);
|
||||
EXPECT_EQ(baseline.stats.expandedTreeItemCount, 1u);
|
||||
|
||||
XCEngine::UI::UIRect treeRootRect = {};
|
||||
XCEngine::UI::UIRect treeChildRect = {};
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("treeAssetsRoot", treeRootRect));
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("treeScenes", treeChildRect));
|
||||
ASSERT_GT(treeRootRect.width, 0.0f);
|
||||
ASSERT_GT(treeRootRect.height, 0.0f);
|
||||
|
||||
const XCEngine::UI::UIPoint rootClickPoint(
|
||||
treeRootRect.x + 18.0f,
|
||||
treeRootRect.y + treeRootRect.height * 0.5f);
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState hoverInput = BuildInputState();
|
||||
hoverInput.pointerPosition = rootClickPoint;
|
||||
const auto& hoveredFrame = runtime.Update(hoverInput);
|
||||
ASSERT_TRUE(hoveredFrame.stats.documentsReady);
|
||||
ASSERT_EQ(hoveredFrame.stats.hoveredElementId, "treeAssetsRoot")
|
||||
<< "treeRootRect=("
|
||||
<< treeRootRect.x << ", "
|
||||
<< treeRootRect.y << ", "
|
||||
<< treeRootRect.width << ", "
|
||||
<< treeRootRect.height << ")";
|
||||
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState collapseInput = BuildInputState();
|
||||
collapseInput.pointerPosition = rootClickPoint;
|
||||
collapseInput.pointerPressed = true;
|
||||
const auto& collapsedFrame = runtime.Update(collapseInput);
|
||||
|
||||
ASSERT_TRUE(collapsedFrame.stats.documentsReady);
|
||||
EXPECT_EQ(collapsedFrame.stats.selectedElementId, "treeAssetsRoot");
|
||||
const auto& collapsedPersistedFrame = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(collapsedPersistedFrame.stats.documentsReady);
|
||||
EXPECT_EQ(collapsedPersistedFrame.stats.selectedElementId, "treeAssetsRoot");
|
||||
EXPECT_EQ(collapsedPersistedFrame.stats.expandedTreeItemCount, 0u);
|
||||
EXPECT_FALSE(runtime.TryGetElementRect("treeScenes", treeChildRect));
|
||||
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("treeAssetsRoot", treeRootRect));
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState expandInput = BuildInputState();
|
||||
expandInput.pointerPosition = XCEngine::UI::UIPoint(
|
||||
treeRootRect.x + 18.0f,
|
||||
treeRootRect.y + treeRootRect.height * 0.5f);
|
||||
expandInput.pointerPressed = true;
|
||||
const auto& expandedClickFrame = runtime.Update(expandInput);
|
||||
|
||||
ASSERT_TRUE(expandedClickFrame.stats.documentsReady);
|
||||
const auto& expandedFrame = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(expandedFrame.stats.documentsReady);
|
||||
EXPECT_EQ(expandedFrame.stats.expandedTreeItemCount, 1u);
|
||||
EXPECT_TRUE(runtime.TryGetElementRect("treeScenes", treeChildRect));
|
||||
EXPECT_GT(treeChildRect.height, 0.0f);
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabRuntimeTest, ClickingPropertySectionHeaderTogglesFieldVisibility) {
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabRuntime runtime;
|
||||
ASSERT_TRUE(runtime.ReloadDocuments());
|
||||
|
||||
const auto& baseline = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(baseline.stats.documentsReady);
|
||||
|
||||
XCEngine::UI::UIRect sectionRect = {};
|
||||
XCEngine::UI::UIRect fieldRect = {};
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("inspectorTransform", sectionRect));
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("fieldPosition", fieldRect));
|
||||
const float expandedHeight = sectionRect.height;
|
||||
const XCEngine::UI::UIPoint sectionHeaderPoint(
|
||||
sectionRect.x + 18.0f,
|
||||
sectionRect.y + 10.0f);
|
||||
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState hoverInput = BuildInputState();
|
||||
hoverInput.pointerPosition = sectionHeaderPoint;
|
||||
const auto& hoveredFrame = runtime.Update(hoverInput);
|
||||
ASSERT_TRUE(hoveredFrame.stats.documentsReady);
|
||||
ASSERT_EQ(hoveredFrame.stats.hoveredElementId, "inspectorTransform")
|
||||
<< "sectionRect=("
|
||||
<< sectionRect.x << ", "
|
||||
<< sectionRect.y << ", "
|
||||
<< sectionRect.width << ", "
|
||||
<< sectionRect.height << "), expandedPropertySectionCount="
|
||||
<< baseline.stats.expandedPropertySectionCount;
|
||||
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState collapseInput = BuildInputState();
|
||||
collapseInput.pointerPosition = sectionHeaderPoint;
|
||||
collapseInput.pointerPressed = true;
|
||||
const auto& collapsedFrame = runtime.Update(collapseInput);
|
||||
|
||||
ASSERT_TRUE(collapsedFrame.stats.documentsReady);
|
||||
const auto& collapsedPersistedFrame = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(collapsedPersistedFrame.stats.documentsReady);
|
||||
EXPECT_EQ(collapsedPersistedFrame.stats.selectedElementId, "inspectorTransform");
|
||||
ASSERT_TRUE(runtime.TryGetElementRect("inspectorTransform", sectionRect));
|
||||
EXPECT_LT(sectionRect.height, expandedHeight);
|
||||
EXPECT_FALSE(runtime.TryGetElementRect("fieldPosition", fieldRect));
|
||||
|
||||
XCEngine::Editor::XCUIBackend::XCUILayoutLabInputState expandInput = BuildInputState();
|
||||
expandInput.pointerPosition = XCEngine::UI::UIPoint(
|
||||
sectionRect.x + 18.0f,
|
||||
sectionRect.y + 10.0f);
|
||||
expandInput.pointerPressed = true;
|
||||
const auto& expandedClickFrame = runtime.Update(expandInput);
|
||||
|
||||
ASSERT_TRUE(expandedClickFrame.stats.documentsReady);
|
||||
const auto& expandedFrame = runtime.Update(BuildInputState());
|
||||
ASSERT_TRUE(expandedFrame.stats.documentsReady);
|
||||
EXPECT_TRUE(runtime.TryGetElementRect("fieldPosition", fieldRect));
|
||||
EXPECT_GT(fieldRect.height, 0.0f);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user