engine: sync editor rendering and ui changes

This commit is contained in:
2026-04-08 16:09:15 +08:00
parent 31756847ab
commit 162f1cc12e
153 changed files with 4454 additions and 2990 deletions

View File

@@ -3,12 +3,14 @@ set(CORE_UI_TEST_SOURCES
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_input_modifier_tracker.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_layout_engine.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_core.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_draw_data.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_expansion_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_flat_hierarchy_helpers.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_input_dispatcher.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_keyboard_navigation_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_popup_overlay_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_property_edit_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_scroll_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_selection_model.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_style_system.cpp
${CMAKE_SOURCE_DIR}/tests/UI/Core/unit/test_ui_shortcut_scope.cpp

View File

@@ -0,0 +1,82 @@
#include <gtest/gtest.h>
#include <XCEngine/UI/DrawData.h>
namespace {
using XCEngine::UI::UIColor;
using XCEngine::UI::UIDrawCommandType;
using XCEngine::UI::UIDrawData;
using XCEngine::UI::UIDrawList;
using XCEngine::UI::UILinearGradientDirection;
using XCEngine::UI::UIPoint;
using XCEngine::UI::UIRect;
TEST(UIDrawDataTest, DrawListPreservesGradientLineAndCirclePayload) {
UIDrawList drawList("CorePrimitives");
drawList.AddFilledRectLinearGradient(
UIRect(10.0f, 20.0f, 140.0f, 24.0f),
UIColor(1.0f, 0.0f, 0.0f, 1.0f),
UIColor(0.0f, 0.0f, 1.0f, 1.0f),
UILinearGradientDirection::Vertical,
3.0f);
drawList.AddLine(
UIPoint(8.0f, 12.0f),
UIPoint(28.0f, 36.0f),
UIColor(0.9f, 0.9f, 0.9f, 1.0f),
2.0f);
drawList.AddFilledCircle(
UIPoint(48.0f, 52.0f),
6.0f,
UIColor(0.2f, 0.6f, 0.9f, 1.0f));
drawList.AddCircleOutline(
UIPoint(48.0f, 52.0f),
9.0f,
UIColor(1.0f, 1.0f, 1.0f, 1.0f),
1.5f);
ASSERT_EQ(drawList.GetCommandCount(), 4u);
const auto& commands = drawList.GetCommands();
EXPECT_EQ(commands[0].type, UIDrawCommandType::FilledRectLinearGradient);
EXPECT_FLOAT_EQ(commands[0].rect.width, 140.0f);
EXPECT_EQ(commands[0].gradientDirection, UILinearGradientDirection::Vertical);
EXPECT_FLOAT_EQ(commands[0].secondaryColor.b, 1.0f);
EXPECT_FLOAT_EQ(commands[0].rounding, 3.0f);
EXPECT_EQ(commands[1].type, UIDrawCommandType::Line);
EXPECT_FLOAT_EQ(commands[1].position.x, 8.0f);
EXPECT_FLOAT_EQ(commands[1].uvMin.x, 28.0f);
EXPECT_FLOAT_EQ(commands[1].thickness, 2.0f);
EXPECT_EQ(commands[2].type, UIDrawCommandType::FilledCircle);
EXPECT_FLOAT_EQ(commands[2].position.x, 48.0f);
EXPECT_FLOAT_EQ(commands[2].radius, 6.0f);
EXPECT_EQ(commands[3].type, UIDrawCommandType::CircleOutline);
EXPECT_FLOAT_EQ(commands[3].position.y, 52.0f);
EXPECT_FLOAT_EQ(commands[3].radius, 9.0f);
EXPECT_FLOAT_EQ(commands[3].thickness, 1.5f);
}
TEST(UIDrawDataTest, DrawDataAggregatesNewPrimitiveCommands) {
UIDrawData drawData = {};
auto& first = drawData.EmplaceDrawList("Gradients");
first.AddFilledRectLinearGradient(
UIRect(0.0f, 0.0f, 50.0f, 12.0f),
UIColor(0.0f, 0.0f, 0.0f, 1.0f),
UIColor(1.0f, 1.0f, 1.0f, 1.0f));
auto& second = drawData.EmplaceDrawList("Handles");
second.AddFilledCircle(UIPoint(12.0f, 12.0f), 4.0f, UIColor(1.0f, 0.0f, 0.0f, 1.0f));
second.AddCircleOutline(UIPoint(12.0f, 12.0f), 6.0f, UIColor(1.0f, 1.0f, 1.0f, 1.0f));
second.AddLine(
UIPoint(0.0f, 24.0f),
UIPoint(32.0f, 24.0f),
UIColor(0.7f, 0.7f, 0.7f, 1.0f));
EXPECT_EQ(drawData.GetDrawListCount(), 2u);
EXPECT_EQ(drawData.GetTotalCommandCount(), 4u);
}
} // namespace

View File

@@ -0,0 +1,53 @@
#include <gtest/gtest.h>
#include <XCEngine/UI/Widgets/UIScrollModel.h>
namespace {
using XCEngine::UI::Widgets::ApplyUIScrollWheel;
using XCEngine::UI::Widgets::ClampUIScrollOffset;
using XCEngine::UI::Widgets::ComputeUIScrollOverflow;
using XCEngine::UI::Widgets::EnsureUIScrollOffsetVisible;
TEST(UIScrollModelTest, OverflowAndClampUseViewportBounds) {
EXPECT_FLOAT_EQ(ComputeUIScrollOverflow(80.0f, 120.0f), 0.0f);
EXPECT_FLOAT_EQ(ComputeUIScrollOverflow(240.0f, 120.0f), 120.0f);
EXPECT_FLOAT_EQ(ClampUIScrollOffset(-20.0f, 240.0f, 120.0f), 0.0f);
EXPECT_FLOAT_EQ(ClampUIScrollOffset(40.0f, 240.0f, 120.0f), 40.0f);
EXPECT_FLOAT_EQ(ClampUIScrollOffset(180.0f, 240.0f, 120.0f), 120.0f);
}
TEST(UIScrollModelTest, WheelMutationUsesDefaultStepAndReportsClampedNoops) {
const auto scrollDown = ApplyUIScrollWheel(48.0f, -120.0f, 360.0f, 120.0f);
EXPECT_TRUE(scrollDown.changed);
EXPECT_FLOAT_EQ(scrollDown.overflow, 240.0f);
EXPECT_FLOAT_EQ(scrollDown.offsetBefore, 48.0f);
EXPECT_FLOAT_EQ(scrollDown.offsetAfter, 96.0f);
const auto clamped = ApplyUIScrollWheel(0.0f, 120.0f, 360.0f, 120.0f);
EXPECT_FALSE(clamped.changed);
EXPECT_FLOAT_EQ(clamped.offsetBefore, 0.0f);
EXPECT_FLOAT_EQ(clamped.offsetAfter, 0.0f);
const auto noOverflow = ApplyUIScrollWheel(0.0f, -120.0f, 80.0f, 120.0f);
EXPECT_FALSE(noOverflow.changed);
EXPECT_FLOAT_EQ(noOverflow.overflow, 0.0f);
}
TEST(UIScrollModelTest, EnsureVisibleKeepsRowsInsideViewport) {
EXPECT_FLOAT_EQ(
EnsureUIScrollOffsetVisible(24.0f, 12.0f, 20.0f, 300.0f, 120.0f),
12.0f);
EXPECT_FLOAT_EQ(
EnsureUIScrollOffsetVisible(24.0f, 96.0f, 36.0f, 300.0f, 120.0f),
24.0f);
EXPECT_FLOAT_EQ(
EnsureUIScrollOffsetVisible(24.0f, 164.0f, 28.0f, 300.0f, 120.0f),
72.0f);
EXPECT_FLOAT_EQ(
EnsureUIScrollOffsetVisible(180.0f, 260.0f, 60.0f, 300.0f, 120.0f),
180.0f);
}
} // namespace