#include #include #include namespace XCEngine::UI::Editor::Widgets { namespace { float ClampNonNegative(float value) { return (std::max)(0.0f, value); } bool AreEqual(float lhs, float rhs) { return std::abs(lhs - rhs) <= 0.001f; } } // namespace const UIEditorInspectorFieldStyleTokens& GetUIEditorInspectorFieldStyleTokens() { static const UIEditorInspectorFieldStyleTokens kTokens = [] { UIEditorInspectorFieldStyleTokens tokens = {}; tokens.rowHoverColor = ::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f); tokens.rowActiveColor = ::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f); tokens.labelColor = ::XCEngine::UI::UIColor(0.72f, 0.72f, 0.72f, 1.0f); tokens.valueColor = ::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f); tokens.readOnlyValueColor = ::XCEngine::UI::UIColor(0.60f, 0.60f, 0.60f, 1.0f); tokens.controlColor = ::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f); tokens.controlHoverColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.controlEditingColor = ::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f); tokens.controlReadOnlyColor = ::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f); tokens.controlBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.controlFocusedBorderColor = ::XCEngine::UI::UIColor(0.19f, 0.19f, 0.19f, 1.0f); tokens.prefixColor = ::XCEngine::UI::UIColor(0.13f, 0.13f, 0.13f, 1.0f); tokens.prefixBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.popupColor = ::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f); tokens.popupBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.popupHeaderColor = ::XCEngine::UI::UIColor(0.11f, 0.11f, 0.11f, 1.0f); tokens.popupTitleColor = ::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f); tokens.popupTextColor = ::XCEngine::UI::UIColor(0.88f, 0.88f, 0.88f, 1.0f); tokens.popupTextMutedColor = ::XCEngine::UI::UIColor(0.66f, 0.66f, 0.66f, 1.0f); tokens.previewBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.previewBaseColor = ::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f); tokens.checkerLightColor = ::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f); tokens.checkerDarkColor = ::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f); tokens.sliderBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.numericBoxColor = ::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f); tokens.numericBoxBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.numericBoxTextColor = ::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f); tokens.closeButtonHoverColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); tokens.closeGlyphColor = ::XCEngine::UI::UIColor(0.86f, 0.86f, 0.86f, 1.0f); return tokens; }(); 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); } 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 horizontalPadding = ClampNonNegative(metrics.horizontalPadding); const float trailingInset = ClampNonNegative(metrics.controlTrailingInset); const float defaultGap = ClampNonNegative(metrics.labelControlGap); const float contentLeft = rowBounds.x + horizontalPadding; const float contentRight = rowBounds.x + ClampNonNegative(rowBounds.width) - trailingInset; const float contentWidth = ClampNonNegative(contentRight - contentLeft); const float requestedReservedControlWidth = ClampNonNegative( metrics.sharedControlColumnMinWidth > 0.0f ? metrics.sharedControlColumnMinWidth : minimumControlWidth); const float reservedControlWidth = ClampNonNegative((std::min)(requestedReservedControlWidth, contentWidth)); const float effectiveGap = (std::min)(defaultGap, ClampNonNegative(contentWidth - reservedControlWidth)); const float preferredControlX = (std::clamp)(rowBounds.x + metrics.controlColumnStart, contentLeft, contentRight); const float maximumControlX = contentRight - reservedControlWidth; const float controlX = (std::clamp)((std::min)(preferredControlX, maximumControlX), contentLeft, contentRight); const float controlInsetY = (std::min)(metrics.controlInsetY, rowBounds.height * 0.25f); const float controlWidth = ClampNonNegative(contentRight - controlX); UIEditorFieldRowLayout layout = {}; layout.bounds = rowBounds; layout.labelRect = ::XCEngine::UI::UIRect( contentLeft, rowBounds.y, ClampNonNegative(controlX - effectiveGap - contentLeft), 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