Reuse panel frame composition in native XCUI shell
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -18,9 +19,16 @@ using XCEngine::Editor::XCUIBackend::IXCUIHostedPreviewPresenter;
|
||||
using XCEngine::Editor::XCUIBackend::IXCUIPanelCanvasHost;
|
||||
using XCEngine::Editor::XCUIBackend::ImGuiXCUIInputSnapshotSource;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIHostedPreviewFrame;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceDescriptor;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIHostedPreviewSurfaceImage;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIHostedPreviewStats;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIInputBridgeFrameSnapshot;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIInputBridgeKeyState;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasRequest;
|
||||
using XCEngine::Editor::XCUIBackend::XCUIPanelCanvasSession;
|
||||
using XCEngine::Input::KeyCode;
|
||||
using XCEngine::NewEditor::XCUILayoutLabFrameComposition;
|
||||
using XCEngine::NewEditor::XCUILayoutLabFrameCompositionRequest;
|
||||
using XCEngine::NewEditor::XCUILayoutLabPanel;
|
||||
|
||||
class ImGuiContextScope {
|
||||
@@ -50,6 +58,7 @@ void PrepareImGui(float width = 1280.0f, float height = 900.0f) {
|
||||
class StubHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
||||
public:
|
||||
bool Present(const XCUIHostedPreviewFrame& frame) override {
|
||||
++m_presentCallCount;
|
||||
m_lastStats = {};
|
||||
m_lastStats.presented = frame.drawData != nullptr;
|
||||
return m_lastStats.presented;
|
||||
@@ -59,10 +68,79 @@ public:
|
||||
return m_lastStats;
|
||||
}
|
||||
|
||||
std::size_t GetPresentCallCount() const {
|
||||
return m_presentCallCount;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t m_presentCallCount = 0u;
|
||||
XCUIHostedPreviewStats m_lastStats = {};
|
||||
};
|
||||
|
||||
class StubNativeHostedPreviewPresenter final : public IXCUIHostedPreviewPresenter {
|
||||
public:
|
||||
bool Present(const XCUIHostedPreviewFrame& frame) override {
|
||||
++m_presentCallCount;
|
||||
m_lastFrame = frame;
|
||||
m_lastStats = {};
|
||||
m_lastStats.presented = frame.drawData != nullptr;
|
||||
m_lastStats.queuedToNativePass = frame.drawData != nullptr;
|
||||
m_lastStats.submittedDrawListCount = frame.drawData != nullptr ? frame.drawData->GetDrawListCount() : 0u;
|
||||
m_lastStats.submittedCommandCount = frame.drawData != nullptr ? frame.drawData->GetTotalCommandCount() : 0u;
|
||||
return m_lastStats.presented;
|
||||
}
|
||||
|
||||
const XCUIHostedPreviewStats& GetLastStats() const override {
|
||||
return m_lastStats;
|
||||
}
|
||||
|
||||
bool IsNativeQueued() const override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryGetSurfaceImage(
|
||||
const char* debugName,
|
||||
XCUIHostedPreviewSurfaceImage& outImage) const override {
|
||||
outImage = {};
|
||||
if (debugName == nullptr || m_descriptor.debugName != debugName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outImage = m_descriptor.image;
|
||||
return outImage.IsValid();
|
||||
}
|
||||
|
||||
bool TryGetSurfaceDescriptor(
|
||||
const char* debugName,
|
||||
XCUIHostedPreviewSurfaceDescriptor& outDescriptor) const override {
|
||||
outDescriptor = {};
|
||||
if (debugName == nullptr || m_descriptor.debugName != debugName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
outDescriptor = m_descriptor;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetDescriptor(XCUIHostedPreviewSurfaceDescriptor descriptor) {
|
||||
m_descriptor = std::move(descriptor);
|
||||
}
|
||||
|
||||
std::size_t GetPresentCallCount() const {
|
||||
return m_presentCallCount;
|
||||
}
|
||||
|
||||
const XCUIHostedPreviewFrame& GetLastFrame() const {
|
||||
return m_lastFrame;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t m_presentCallCount = 0u;
|
||||
XCUIHostedPreviewFrame m_lastFrame = {};
|
||||
XCUIHostedPreviewStats m_lastStats = {};
|
||||
XCUIHostedPreviewSurfaceDescriptor m_descriptor = {};
|
||||
};
|
||||
|
||||
class StubCanvasHost final : public IXCUIPanelCanvasHost {
|
||||
public:
|
||||
const char* GetDebugName() const override {
|
||||
@@ -119,6 +197,91 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
std::uint64_t NextTimestampNanoseconds() {
|
||||
static std::uint64_t timestampNanoseconds = 1'000'000u;
|
||||
timestampNanoseconds += 16'666'667u;
|
||||
return timestampNanoseconds;
|
||||
}
|
||||
|
||||
XCUIPanelCanvasSession MakeCanvasSession() {
|
||||
XCUIPanelCanvasSession session = {};
|
||||
session.hostRect = XCEngine::UI::UIRect(0.0f, 0.0f, 960.0f, 640.0f);
|
||||
session.canvasRect = XCEngine::UI::UIRect(0.0f, 0.0f, 960.0f, 640.0f);
|
||||
session.pointerPosition = XCEngine::UI::UIPoint(120.0f, 120.0f);
|
||||
session.validCanvas = true;
|
||||
session.hovered = true;
|
||||
session.windowFocused = true;
|
||||
return session;
|
||||
}
|
||||
|
||||
XCEngine::UI::UITextureHandle MakeSurfaceTextureHandle(
|
||||
std::uintptr_t nativeHandle,
|
||||
std::uint32_t width,
|
||||
std::uint32_t height) {
|
||||
XCEngine::UI::UITextureHandle texture = {};
|
||||
texture.nativeHandle = nativeHandle;
|
||||
texture.width = width;
|
||||
texture.height = height;
|
||||
texture.kind = XCEngine::UI::UITextureHandleKind::ShaderResourceView;
|
||||
return texture;
|
||||
}
|
||||
|
||||
XCUIInputBridgeFrameSnapshot MakePointerSnapshot(
|
||||
const XCEngine::UI::UIPoint& pointerPosition,
|
||||
bool pointerInside,
|
||||
bool pointerDown,
|
||||
bool windowFocused) {
|
||||
XCUIInputBridgeFrameSnapshot snapshot = {};
|
||||
snapshot.pointerPosition = pointerPosition;
|
||||
snapshot.pointerInside = pointerInside;
|
||||
snapshot.pointerButtonsDown[0] = pointerDown;
|
||||
snapshot.windowFocused = windowFocused;
|
||||
snapshot.timestampNanoseconds = NextTimestampNanoseconds();
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
XCUIInputBridgeFrameSnapshot MakeKeyboardSnapshot(
|
||||
const XCEngine::UI::UIPoint& pointerPosition,
|
||||
bool pointerInside,
|
||||
bool windowFocused,
|
||||
KeyCode keyCode) {
|
||||
XCUIInputBridgeFrameSnapshot snapshot =
|
||||
MakePointerSnapshot(pointerPosition, pointerInside, false, windowFocused);
|
||||
snapshot.keys.push_back(XCUIInputBridgeKeyState {
|
||||
static_cast<std::int32_t>(keyCode),
|
||||
true,
|
||||
false
|
||||
});
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
const XCUILayoutLabFrameComposition& ComposePanelFrame(
|
||||
XCUILayoutLabPanel& panel,
|
||||
const XCUIPanelCanvasSession& canvasSession,
|
||||
const XCUIInputBridgeFrameSnapshot& snapshot) {
|
||||
XCUILayoutLabFrameCompositionRequest request = {};
|
||||
request.canvasSession = canvasSession;
|
||||
request.inputSnapshot = snapshot;
|
||||
return panel.ComposeFrame(request);
|
||||
}
|
||||
|
||||
void ClickElementWithComposition(
|
||||
XCUILayoutLabPanel& panel,
|
||||
const XCUIPanelCanvasSession& baseSession,
|
||||
const std::string& elementId) {
|
||||
XCEngine::UI::UIRect elementRect = {};
|
||||
ASSERT_TRUE(panel.TryGetElementRect(elementId, elementRect));
|
||||
const XCEngine::UI::UIPoint clickPoint(
|
||||
elementRect.x + elementRect.width * 0.5f,
|
||||
elementRect.y + elementRect.height * 0.5f);
|
||||
|
||||
XCUIPanelCanvasSession clickSession = baseSession;
|
||||
clickSession.pointerPosition = clickPoint;
|
||||
clickSession.hovered = true;
|
||||
ComposePanelFrame(panel, clickSession, MakePointerSnapshot(clickPoint, true, true, true));
|
||||
ComposePanelFrame(panel, clickSession, MakePointerSnapshot(clickPoint, true, false, true));
|
||||
}
|
||||
|
||||
void RenderPanelFrame(
|
||||
XCUILayoutLabPanel& panel,
|
||||
ImGuiContextScope&,
|
||||
@@ -181,68 +344,92 @@ void PressKeyOnce(
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabPanelTest, MapsPreviousNextHomeAndEndIntoRuntimeNavigation) {
|
||||
ImGuiContextScope contextScope;
|
||||
|
||||
auto previewPresenter = std::make_unique<StubHostedPreviewPresenter>();
|
||||
auto canvasHost = std::make_unique<StubCanvasHost>();
|
||||
StubCanvasHost* canvasHostPtr = canvasHost.get();
|
||||
ImGuiXCUIInputSnapshotSource inputSource(nullptr);
|
||||
|
||||
XCUILayoutLabPanel panel(&inputSource, std::move(previewPresenter), std::move(canvasHost));
|
||||
XCUILayoutLabPanel panel(nullptr, std::move(previewPresenter), std::move(canvasHost));
|
||||
panel.SetHostedPreviewEnabled(false);
|
||||
|
||||
RenderPanelFrame(panel, contextScope);
|
||||
ClickElement(panel, *canvasHostPtr, "assetLighting", contextScope);
|
||||
XCUIPanelCanvasSession session = MakeCanvasSession();
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, true, false, true));
|
||||
ClickElementWithComposition(panel, session, "assetLighting");
|
||||
ASSERT_EQ(panel.GetFrameResult().stats.selectedElementId, "assetLighting");
|
||||
|
||||
canvasHostPtr->SetHovered(false);
|
||||
canvasHostPtr->SetWindowFocused(true);
|
||||
session.hovered = false;
|
||||
session.windowFocused = true;
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_DownArrow);
|
||||
const XCUILayoutLabFrameComposition& downComposition = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Down));
|
||||
EXPECT_TRUE(downComposition.inputState.navigateNext);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "assetMaterials");
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_UpArrow);
|
||||
const XCUILayoutLabFrameComposition& upComposition = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Up));
|
||||
EXPECT_TRUE(upComposition.inputState.navigatePrevious);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "assetLighting");
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_End);
|
||||
const XCUILayoutLabFrameComposition& endComposition = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::End));
|
||||
EXPECT_TRUE(endComposition.inputState.navigateEnd);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
const std::string endSelection = panel.GetFrameResult().stats.selectedElementId;
|
||||
ASSERT_FALSE(endSelection.empty());
|
||||
EXPECT_NE(endSelection, "assetLighting");
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_Home);
|
||||
const XCUILayoutLabFrameComposition& homeComposition = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Home));
|
||||
EXPECT_TRUE(homeComposition.inputState.navigateHome);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "assetLighting");
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabPanelTest, MapsCollapseAndExpandIntoRuntimeNavigation) {
|
||||
ImGuiContextScope contextScope;
|
||||
|
||||
auto previewPresenter = std::make_unique<StubHostedPreviewPresenter>();
|
||||
auto canvasHost = std::make_unique<StubCanvasHost>();
|
||||
StubCanvasHost* canvasHostPtr = canvasHost.get();
|
||||
ImGuiXCUIInputSnapshotSource inputSource(nullptr);
|
||||
|
||||
XCUILayoutLabPanel panel(&inputSource, std::move(previewPresenter), std::move(canvasHost));
|
||||
XCUILayoutLabPanel panel(nullptr, std::move(previewPresenter), std::move(canvasHost));
|
||||
panel.SetHostedPreviewEnabled(false);
|
||||
|
||||
RenderPanelFrame(panel, contextScope);
|
||||
ClickElement(panel, *canvasHostPtr, "treeScenes", contextScope);
|
||||
XCUIPanelCanvasSession session = MakeCanvasSession();
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, true, false, true));
|
||||
ClickElementWithComposition(panel, session, "treeScenes");
|
||||
ASSERT_EQ(panel.GetFrameResult().stats.selectedElementId, "treeScenes");
|
||||
|
||||
canvasHostPtr->SetHovered(false);
|
||||
canvasHostPtr->SetWindowFocused(true);
|
||||
session.hovered = false;
|
||||
session.windowFocused = true;
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_LeftArrow);
|
||||
const XCUILayoutLabFrameComposition& collapseSelection = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Left));
|
||||
EXPECT_TRUE(collapseSelection.inputState.navigateCollapse);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "treeAssetsRoot");
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_LeftArrow);
|
||||
ComposePanelFrame(panel, session, MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Left));
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "treeAssetsRoot");
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.expandedTreeItemCount, 0u);
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_RightArrow);
|
||||
const XCUILayoutLabFrameComposition& expandRoot = ComposePanelFrame(
|
||||
panel,
|
||||
session,
|
||||
MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Right));
|
||||
EXPECT_TRUE(expandRoot.inputState.navigateExpand);
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "treeAssetsRoot");
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.expandedTreeItemCount, 1u);
|
||||
|
||||
PressKeyOnce(panel, contextScope, ImGuiKey_RightArrow);
|
||||
ComposePanelFrame(panel, session, MakeKeyboardSnapshot(session.pointerPosition, false, true, KeyCode::Right));
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, false, false, true));
|
||||
EXPECT_EQ(panel.GetFrameResult().stats.selectedElementId, "treeScenes");
|
||||
}
|
||||
|
||||
@@ -259,4 +446,81 @@ TEST(NewEditorXCUILayoutLabPanelTest, DefaultFallbackDoesNotCreateImplicitHosted
|
||||
EXPECT_EQ(panel.GetLastPreviewStats().submittedCommandCount, 0u);
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabPanelTest, ComposeFramePublishesShellAgnosticLastCompositionState) {
|
||||
auto previewPresenter = std::make_unique<StubHostedPreviewPresenter>();
|
||||
auto canvasHost = std::make_unique<StubCanvasHost>();
|
||||
|
||||
XCUILayoutLabPanel panel(nullptr, std::move(previewPresenter), std::move(canvasHost));
|
||||
|
||||
XCUIPanelCanvasSession session = MakeCanvasSession();
|
||||
const XCUILayoutLabFrameComposition& composition =
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, true, false, true));
|
||||
|
||||
EXPECT_EQ(&composition, &panel.GetLastFrameComposition());
|
||||
ASSERT_NE(composition.frameResult, nullptr);
|
||||
EXPECT_TRUE(composition.previewStats.presented);
|
||||
EXPECT_EQ(composition.previewPathLabel, "hosted presenter");
|
||||
EXPECT_EQ(composition.previewStateLabel, "live");
|
||||
EXPECT_EQ(composition.previewSourceLabel, "new_editor.panels.xcui_layout_lab");
|
||||
EXPECT_TRUE(composition.hostedPreviewEnabled);
|
||||
EXPECT_EQ(composition.inputState.canvasRect.width, session.canvasRect.width);
|
||||
EXPECT_EQ(composition.inputState.canvasRect.height, session.canvasRect.height);
|
||||
EXPECT_TRUE(composition.inputState.pointerInside);
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabPanelTest, ComposeFrameCarriesNativeQueuedPreviewMetadataIntoComposition) {
|
||||
auto previewPresenter = std::make_unique<StubNativeHostedPreviewPresenter>();
|
||||
XCUIHostedPreviewSurfaceDescriptor descriptor = {};
|
||||
descriptor.debugName = "XCUI Layout Lab";
|
||||
descriptor.debugSource = "tests.native_layout_preview";
|
||||
descriptor.logicalSize = XCEngine::UI::UISize(512.0f, 320.0f);
|
||||
descriptor.queuedFrameIndex = 7u;
|
||||
descriptor.image.texture = MakeSurfaceTextureHandle(42u, 512u, 320u);
|
||||
descriptor.image.surfaceWidth = 512u;
|
||||
descriptor.image.surfaceHeight = 320u;
|
||||
descriptor.image.renderedCanvasRect = XCEngine::UI::UIRect(0.0f, 0.0f, 512.0f, 320.0f);
|
||||
previewPresenter->SetDescriptor(std::move(descriptor));
|
||||
StubNativeHostedPreviewPresenter* previewPresenterRaw = previewPresenter.get();
|
||||
|
||||
XCUILayoutLabPanel panel(nullptr, std::move(previewPresenter), std::make_unique<StubCanvasHost>());
|
||||
|
||||
XCUIPanelCanvasSession session = MakeCanvasSession();
|
||||
const XCUILayoutLabFrameComposition& composition =
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, true, false, true));
|
||||
|
||||
EXPECT_TRUE(composition.hostedPreviewEnabled);
|
||||
EXPECT_TRUE(composition.nativeHostedPreview);
|
||||
EXPECT_TRUE(composition.hasHostedSurfaceDescriptor);
|
||||
EXPECT_TRUE(composition.showHostedSurfaceImage);
|
||||
EXPECT_EQ(composition.previewPathLabel, "native queued offscreen surface");
|
||||
EXPECT_EQ(composition.previewStateLabel, "live");
|
||||
EXPECT_EQ(composition.previewSourceLabel, "tests.native_layout_preview");
|
||||
EXPECT_EQ(composition.hostedSurfaceDescriptor.queuedFrameIndex, 7u);
|
||||
EXPECT_EQ(composition.hostedSurfaceImage.texture.nativeHandle, 42u);
|
||||
EXPECT_TRUE(composition.previewStats.presented);
|
||||
EXPECT_TRUE(composition.previewStats.queuedToNativePass);
|
||||
EXPECT_EQ(previewPresenterRaw->GetPresentCallCount(), 1u);
|
||||
EXPECT_EQ(previewPresenterRaw->GetLastFrame().debugName, std::string("XCUI Layout Lab"));
|
||||
EXPECT_EQ(previewPresenterRaw->GetLastFrame().debugSource, std::string("new_editor.panels.xcui_layout_lab"));
|
||||
EXPECT_FLOAT_EQ(previewPresenterRaw->GetLastFrame().logicalSize.width, session.canvasRect.width);
|
||||
EXPECT_FLOAT_EQ(previewPresenterRaw->GetLastFrame().logicalSize.height, session.canvasRect.height);
|
||||
}
|
||||
|
||||
TEST(NewEditorXCUILayoutLabPanelTest, ComposeFrameMarksPreviewDisabledWhenPresenterIsInjectedButDisabled) {
|
||||
auto previewPresenter = std::make_unique<StubHostedPreviewPresenter>();
|
||||
StubHostedPreviewPresenter* previewPresenterRaw = previewPresenter.get();
|
||||
XCUILayoutLabPanel panel(nullptr, std::move(previewPresenter), std::make_unique<StubCanvasHost>());
|
||||
panel.SetHostedPreviewEnabled(false);
|
||||
|
||||
XCUIPanelCanvasSession session = MakeCanvasSession();
|
||||
const XCUILayoutLabFrameComposition& composition =
|
||||
ComposePanelFrame(panel, session, MakePointerSnapshot(session.pointerPosition, true, false, true));
|
||||
|
||||
EXPECT_FALSE(composition.hostedPreviewEnabled);
|
||||
EXPECT_EQ(composition.previewStateLabel, "disabled");
|
||||
EXPECT_FALSE(composition.previewStats.presented);
|
||||
EXPECT_EQ(previewPresenterRaw->GetPresentCallCount(), 0u);
|
||||
EXPECT_FALSE(panel.GetLastPreviewStats().presented);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user