Files
XCEngine/editor/include/XCEditor/Fields/UIEditorVector2Field.h

179 lines
6.7 KiB
C
Raw Normal View History

2026-04-08 02:52:28 +08:00
#pragma once
2026-04-23 01:43:23 +08:00
#include <XCEditor/Foundation/UIEditorTextMeasurement.h>
2026-04-08 02:52:28 +08:00
#include <XCEngine/UI/DrawData.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
namespace XCEngine::UI::Editor::Widgets {
inline constexpr std::size_t UIEditorVector2FieldInvalidComponentIndex = static_cast<std::size_t>(-1);
enum class UIEditorVector2FieldHitTargetKind : std::uint8_t {
None = 0,
Row,
Component
};
struct UIEditorVector2FieldSpec {
std::string fieldId = {};
std::string label = {};
std::array<double, 2u> values = { 0.0, 0.0 };
std::array<std::string, 2u> componentLabels = { std::string("X"), std::string("Y") };
double step = 0.1;
double minValue = -1000000.0;
double maxValue = 1000000.0;
bool integerMode = false;
bool readOnly = false;
};
struct UIEditorVector2FieldState {
UIEditorVector2FieldHitTargetKind hoveredTarget = UIEditorVector2FieldHitTargetKind::None;
UIEditorVector2FieldHitTargetKind activeTarget = UIEditorVector2FieldHitTargetKind::None;
std::size_t hoveredComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
std::size_t activeComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
std::size_t selectedComponentIndex = UIEditorVector2FieldInvalidComponentIndex;
bool focused = false;
bool editing = false;
std::size_t caretOffset = 0u;
std::uint64_t caretBlinkStartNanoseconds = 0u;
2026-04-08 02:52:28 +08:00
std::array<std::string, 2u> displayTexts = { std::string(), std::string() };
};
struct UIEditorVector2FieldMetrics {
float rowHeight = 22.0f;
float horizontalPadding = 12.0f;
float labelControlGap = 20.0f;
float controlColumnStart = 236.0f;
float controlMinWidth = 0.0f;
2026-04-08 02:52:28 +08:00
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 UIEditorVector2FieldPalette {
::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);
2026-04-08 02:52:28 +08:00
::XCEngine::UI::UIColor componentHoverColor =
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
2026-04-08 02:52:28 +08:00
::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);
2026-04-08 02:52:28 +08:00
::XCEngine::UI::UIColor componentBorderColor =
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
2026-04-08 02:52:28 +08:00
::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);
2026-04-08 02:52:28 +08:00
::XCEngine::UI::UIColor labelColor =
::XCEngine::UI::UIColor(0.72f, 0.72f, 0.72f, 1.0f);
2026-04-08 02:52:28 +08:00
::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);
2026-04-08 02:52:28 +08:00
::XCEngine::UI::UIColor axisXColor =
::XCEngine::UI::UIColor(0.78f, 0.42f, 0.42f, 1.0f);
2026-04-08 02:52:28 +08:00
::XCEngine::UI::UIColor axisYColor =
::XCEngine::UI::UIColor(0.56f, 0.72f, 0.46f, 1.0f);
2026-04-08 02:52:28 +08:00
};
struct UIEditorVector2FieldLayout {
::XCEngine::UI::UIRect bounds = {};
::XCEngine::UI::UIRect labelRect = {};
::XCEngine::UI::UIRect controlRect = {};
std::array<::XCEngine::UI::UIRect, 2u> componentRects = {};
std::array<::XCEngine::UI::UIRect, 2u> componentPrefixRects = {};
std::array<::XCEngine::UI::UIRect, 2u> componentValueRects = {};
};
struct UIEditorVector2FieldHitTarget {
UIEditorVector2FieldHitTargetKind kind = UIEditorVector2FieldHitTargetKind::None;
std::size_t componentIndex = UIEditorVector2FieldInvalidComponentIndex;
};
bool IsUIEditorVector2FieldPointInside(
const ::XCEngine::UI::UIRect& rect,
const ::XCEngine::UI::UIPoint& point);
double NormalizeUIEditorVector2FieldComponentValue(
const UIEditorVector2FieldSpec& spec,
double value);
bool TryParseUIEditorVector2FieldComponentValue(
const UIEditorVector2FieldSpec& spec,
std::string_view text,
double& outValue);
std::string FormatUIEditorVector2FieldComponentValue(
const UIEditorVector2FieldSpec& spec,
std::size_t componentIndex);
UIEditorVector2FieldLayout BuildUIEditorVector2FieldLayout(
const ::XCEngine::UI::UIRect& bounds,
const UIEditorVector2FieldSpec& spec,
const UIEditorVector2FieldMetrics& metrics = {});
UIEditorVector2FieldHitTarget HitTestUIEditorVector2Field(
const UIEditorVector2FieldLayout& layout,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorVector2FieldBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorVector2FieldLayout& layout,
const UIEditorVector2FieldSpec& spec,
const UIEditorVector2FieldState& state,
const UIEditorVector2FieldPalette& palette = {},
const UIEditorVector2FieldMetrics& metrics = {});
void AppendUIEditorVector2FieldForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorVector2FieldLayout& layout,
const UIEditorVector2FieldSpec& spec,
const UIEditorVector2FieldState& state,
const UIEditorVector2FieldPalette& palette = {},
2026-04-23 01:43:23 +08:00
const UIEditorVector2FieldMetrics& metrics = {},
const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer = nullptr);
2026-04-08 02:52:28 +08:00
void AppendUIEditorVector2Field(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const UIEditorVector2FieldSpec& spec,
const UIEditorVector2FieldState& state,
const UIEditorVector2FieldPalette& palette = {},
2026-04-23 01:43:23 +08:00
const UIEditorVector2FieldMetrics& metrics = {},
const ::XCEngine::UI::Editor::UIEditorTextMeasurer* textMeasurer = nullptr);
2026-04-08 02:52:28 +08:00
} // namespace XCEngine::UI::Editor::Widgets