#pragma once #include #include #include #include #include #include namespace XCEngine::UI::Editor::Widgets { inline constexpr std::size_t UIEditorVector3FieldInvalidComponentIndex = static_cast(-1); enum class UIEditorVector3FieldHitTargetKind : std::uint8_t { None = 0, Row, Component }; struct UIEditorVector3FieldSpec { std::string fieldId = {}; std::string label = {}; std::array values = { 0.0, 0.0, 0.0 }; std::array componentLabels = { std::string("X"), std::string("Y"), std::string("Z") }; double step = 0.1; double minValue = -1000000.0; double maxValue = 1000000.0; bool integerMode = false; bool readOnly = false; }; struct UIEditorVector3FieldState { UIEditorVector3FieldHitTargetKind hoveredTarget = UIEditorVector3FieldHitTargetKind::None; UIEditorVector3FieldHitTargetKind activeTarget = UIEditorVector3FieldHitTargetKind::None; std::size_t hoveredComponentIndex = UIEditorVector3FieldInvalidComponentIndex; std::size_t activeComponentIndex = UIEditorVector3FieldInvalidComponentIndex; std::size_t selectedComponentIndex = UIEditorVector3FieldInvalidComponentIndex; bool focused = false; bool editing = false; std::size_t caretOffset = 0u; std::uint64_t caretBlinkStartNanoseconds = 0u; std::array displayTexts = { std::string(), std::string(), std::string() }; }; struct UIEditorVector3FieldMetrics { float rowHeight = 22.0f; float horizontalPadding = 12.0f; float labelControlGap = 20.0f; float controlColumnStart = 236.0f; float controlMinWidth = 0.0f; float controlTrailingInset = 8.0f; float controlInsetY = 1.0f; float componentGap = 6.0f; float componentMinWidth = 72.0f; float componentPrefixWidth = 9.0f; float componentLabelGap = 4.0f; float labelTextInsetY = 0.0f; float labelFontSize = 11.0f; float valueTextInsetX = 5.0f; float valueTextInsetY = 0.0f; float valueFontSize = 12.0f; float prefixTextInsetX = 0.0f; float prefixTextInsetY = -1.0f; float prefixFontSize = 11.0f; float cornerRounding = 0.0f; float componentRounding = 2.0f; float borderThickness = 1.0f; float focusedBorderThickness = 1.0f; }; struct UIEditorVector3FieldPalette { ::XCEngine::UI::UIColor surfaceColor = ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f); ::XCEngine::UI::UIColor borderColor = ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f); ::XCEngine::UI::UIColor focusedBorderColor = ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f); ::XCEngine::UI::UIColor rowHoverColor = ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f); ::XCEngine::UI::UIColor rowActiveColor = ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f); ::XCEngine::UI::UIColor componentColor = ::XCEngine::UI::UIColor(0.12f, 0.12f, 0.12f, 1.0f); ::XCEngine::UI::UIColor componentHoverColor = ::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f); ::XCEngine::UI::UIColor componentEditingColor = ::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f); ::XCEngine::UI::UIColor readOnlyColor = ::XCEngine::UI::UIColor(0.10f, 0.10f, 0.10f, 1.0f); ::XCEngine::UI::UIColor componentBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); ::XCEngine::UI::UIColor componentFocusedBorderColor = ::XCEngine::UI::UIColor(0.19f, 0.19f, 0.19f, 1.0f); ::XCEngine::UI::UIColor prefixColor = ::XCEngine::UI::UIColor(0.13f, 0.13f, 0.13f, 1.0f); ::XCEngine::UI::UIColor prefixBorderColor = ::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f); ::XCEngine::UI::UIColor labelColor = ::XCEngine::UI::UIColor(0.72f, 0.72f, 0.72f, 1.0f); ::XCEngine::UI::UIColor valueColor = ::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f); ::XCEngine::UI::UIColor readOnlyValueColor = ::XCEngine::UI::UIColor(0.60f, 0.60f, 0.60f, 1.0f); ::XCEngine::UI::UIColor axisXColor = ::XCEngine::UI::UIColor(0.78f, 0.42f, 0.42f, 1.0f); ::XCEngine::UI::UIColor axisYColor = ::XCEngine::UI::UIColor(0.56f, 0.72f, 0.46f, 1.0f); ::XCEngine::UI::UIColor axisZColor = ::XCEngine::UI::UIColor(0.45f, 0.62f, 0.82f, 1.0f); }; struct UIEditorVector3FieldLayout { ::XCEngine::UI::UIRect bounds = {}; ::XCEngine::UI::UIRect labelRect = {}; ::XCEngine::UI::UIRect controlRect = {}; std::array<::XCEngine::UI::UIRect, 3u> componentRects = {}; std::array<::XCEngine::UI::UIRect, 3u> componentPrefixRects = {}; std::array<::XCEngine::UI::UIRect, 3u> componentValueRects = {}; }; struct UIEditorVector3FieldHitTarget { UIEditorVector3FieldHitTargetKind kind = UIEditorVector3FieldHitTargetKind::None; std::size_t componentIndex = UIEditorVector3FieldInvalidComponentIndex; }; bool IsUIEditorVector3FieldPointInside( const ::XCEngine::UI::UIRect& rect, const ::XCEngine::UI::UIPoint& point); double NormalizeUIEditorVector3FieldComponentValue( const UIEditorVector3FieldSpec& spec, double value); bool TryParseUIEditorVector3FieldComponentValue( const UIEditorVector3FieldSpec& spec, std::string_view text, double& outValue); std::string FormatUIEditorVector3FieldComponentValue( const UIEditorVector3FieldSpec& spec, std::size_t componentIndex); UIEditorVector3FieldLayout BuildUIEditorVector3FieldLayout( const ::XCEngine::UI::UIRect& bounds, const UIEditorVector3FieldSpec& spec, const UIEditorVector3FieldMetrics& metrics = {}); UIEditorVector3FieldHitTarget HitTestUIEditorVector3Field( const UIEditorVector3FieldLayout& layout, const ::XCEngine::UI::UIPoint& point); void AppendUIEditorVector3FieldBackground( ::XCEngine::UI::UIDrawList& drawList, const UIEditorVector3FieldLayout& layout, const UIEditorVector3FieldSpec& spec, const UIEditorVector3FieldState& state, const UIEditorVector3FieldPalette& palette = {}, const UIEditorVector3FieldMetrics& metrics = {}); void AppendUIEditorVector3FieldForeground( ::XCEngine::UI::UIDrawList& drawList, const UIEditorVector3FieldLayout& layout, const UIEditorVector3FieldSpec& spec, const UIEditorVector3FieldState& state, const UIEditorVector3FieldPalette& palette = {}, const UIEditorVector3FieldMetrics& metrics = {}, const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer = nullptr); void AppendUIEditorVector3Field( ::XCEngine::UI::UIDrawList& drawList, const ::XCEngine::UI::UIRect& bounds, const UIEditorVector3FieldSpec& spec, const UIEditorVector3FieldState& state, const UIEditorVector3FieldPalette& palette = {}, const UIEditorVector3FieldMetrics& metrics = {}, const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer = nullptr); } // namespace XCEngine::UI::Editor::Widgets