2026-04-08 02:52:28 +08:00
|
|
|
#include <XCEditor/Widgets/UIEditorFieldRowLayout.h>
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
2026-04-10 00:41:28 +08:00
|
|
|
#include <cmath>
|
2026-04-08 02:52:28 +08:00
|
|
|
|
|
|
|
|
namespace XCEngine::UI::Editor::Widgets {
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
float ClampNonNegative(float value) {
|
|
|
|
|
return (std::max)(0.0f, value);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-10 00:41:28 +08:00
|
|
|
bool AreEqual(float lhs, float rhs) {
|
|
|
|
|
return std::abs(lhs - rhs) <= 0.001f;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 02:52:28 +08:00
|
|
|
} // namespace
|
|
|
|
|
|
2026-04-10 00:41:28 +08:00
|
|
|
const UIEditorInspectorFieldStyleTokens& GetUIEditorInspectorFieldStyleTokens() {
|
|
|
|
|
static const UIEditorInspectorFieldStyleTokens kTokens = {};
|
|
|
|
|
return kTokens;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AreUIEditorFieldMetricsEqual(float lhs, float rhs) {
|
|
|
|
|
return AreEqual(lhs, rhs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool AreUIEditorFieldColorsEqual(
|
|
|
|
|
const ::XCEngine::UI::UIColor& lhs,
|
|
|
|
|
const ::XCEngine::UI::UIColor& rhs) {
|
|
|
|
|
return AreEqual(lhs.r, rhs.r) &&
|
|
|
|
|
AreEqual(lhs.g, rhs.g) &&
|
|
|
|
|
AreEqual(lhs.b, rhs.b) &&
|
|
|
|
|
AreEqual(lhs.a, rhs.a);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-08 02:52:28 +08:00
|
|
|
UIEditorFieldRowLayout BuildUIEditorFieldRowLayout(
|
|
|
|
|
const ::XCEngine::UI::UIRect& bounds,
|
|
|
|
|
float minimumControlWidth,
|
|
|
|
|
const UIEditorFieldRowLayoutMetrics& metrics) {
|
|
|
|
|
const float rowHeight = bounds.height > 0.0f ? bounds.height : metrics.rowHeight;
|
|
|
|
|
const ::XCEngine::UI::UIRect rowBounds(bounds.x, bounds.y, bounds.width, rowHeight);
|
|
|
|
|
|
|
|
|
|
const float resolvedMinimumControlWidth =
|
|
|
|
|
ClampNonNegative((std::min)(minimumControlWidth, rowBounds.width));
|
|
|
|
|
const float preferredControlX = rowBounds.x + metrics.controlColumnStart;
|
|
|
|
|
const float maximumControlX =
|
|
|
|
|
rowBounds.x + rowBounds.width - metrics.controlTrailingInset - resolvedMinimumControlWidth;
|
|
|
|
|
const float controlX =
|
|
|
|
|
(std::clamp)(
|
|
|
|
|
(std::min)(preferredControlX, maximumControlX),
|
|
|
|
|
rowBounds.x,
|
|
|
|
|
rowBounds.x + rowBounds.width - metrics.controlTrailingInset);
|
|
|
|
|
const float controlInsetY = (std::min)(metrics.controlInsetY, rowBounds.height * 0.25f);
|
|
|
|
|
const float controlWidth =
|
|
|
|
|
ClampNonNegative(rowBounds.x + rowBounds.width - metrics.controlTrailingInset - controlX);
|
|
|
|
|
|
|
|
|
|
UIEditorFieldRowLayout layout = {};
|
|
|
|
|
layout.bounds = rowBounds;
|
|
|
|
|
layout.labelRect = ::XCEngine::UI::UIRect(
|
|
|
|
|
rowBounds.x + metrics.horizontalPadding,
|
|
|
|
|
rowBounds.y,
|
|
|
|
|
ClampNonNegative(controlX - metrics.labelControlGap - rowBounds.x - metrics.horizontalPadding),
|
|
|
|
|
rowBounds.height);
|
|
|
|
|
layout.controlRect = ::XCEngine::UI::UIRect(
|
|
|
|
|
controlX,
|
|
|
|
|
rowBounds.y + controlInsetY,
|
|
|
|
|
controlWidth,
|
|
|
|
|
ClampNonNegative(rowBounds.height - controlInsetY * 2.0f));
|
|
|
|
|
return layout;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace XCEngine::UI::Editor::Widgets
|