Files
XCEngine/new_editor/include/XCEditor/Widgets/UIEditorPropertyGrid.h

289 lines
10 KiB
C++

#pragma once
#include <XCEngine/UI/DrawData.h>
#include <XCEngine/UI/Widgets/UIExpansionModel.h>
#include <XCEngine/UI/Widgets/UIPropertyEditModel.h>
#include <XCEngine/UI/Widgets/UISelectionModel.h>
#include <XCEditor/Widgets/UIEditorMenuPopup.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <string_view>
#include <vector>
namespace XCEngine::UI::Editor::Widgets {
inline constexpr std::size_t UIEditorPropertyGridInvalidIndex = static_cast<std::size_t>(-1);
enum class UIEditorPropertyGridFieldKind : std::uint8_t {
Text = 0,
Bool,
Number,
Enum,
Vector2,
Vector3,
Vector4
};
enum class UIEditorPropertyGridHitTargetKind : std::uint8_t {
None = 0,
SectionHeader,
FieldRow,
ValueBox
};
struct UIEditorPropertyGridFieldLocation {
std::size_t sectionIndex = UIEditorPropertyGridInvalidIndex;
std::size_t fieldIndex = UIEditorPropertyGridInvalidIndex;
constexpr bool IsValid() const {
return sectionIndex != UIEditorPropertyGridInvalidIndex &&
fieldIndex != UIEditorPropertyGridInvalidIndex;
}
};
struct UIEditorPropertyGridNumberFieldValue {
double value = 0.0;
double step = 1.0;
double minValue = 0.0;
double maxValue = 100.0;
bool integerMode = true;
};
struct UIEditorPropertyGridEnumFieldValue {
std::vector<std::string> options = {};
std::size_t selectedIndex = 0u;
};
struct UIEditorPropertyGridVector2FieldValue {
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;
};
struct UIEditorPropertyGridVector3FieldValue {
std::array<double, 3u> values = { 0.0, 0.0, 0.0 };
std::array<std::string, 3u> 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;
};
struct UIEditorPropertyGridVector4FieldValue {
std::array<double, 4u> values = { 0.0, 0.0, 0.0, 0.0 };
std::array<std::string, 4u> componentLabels = {
std::string("X"),
std::string("Y"),
std::string("Z"),
std::string("W")
};
double step = 0.1;
double minValue = -1000000.0;
double maxValue = 1000000.0;
bool integerMode = false;
};
struct UIEditorPropertyGridField {
std::string fieldId = {};
std::string label = {};
std::string valueText = {};
bool readOnly = false;
float desiredHeight = 0.0f;
UIEditorPropertyGridFieldKind kind = UIEditorPropertyGridFieldKind::Text;
bool boolValue = false;
UIEditorPropertyGridNumberFieldValue numberValue = {};
UIEditorPropertyGridEnumFieldValue enumValue = {};
UIEditorPropertyGridVector2FieldValue vector2Value = {};
UIEditorPropertyGridVector3FieldValue vector3Value = {};
UIEditorPropertyGridVector4FieldValue vector4Value = {};
};
struct UIEditorPropertyGridSection {
std::string sectionId = {};
std::string title = {};
std::vector<UIEditorPropertyGridField> fields = {};
float desiredHeaderHeight = 0.0f;
};
struct UIEditorPropertyGridState {
std::string hoveredSectionId = {};
std::string hoveredFieldId = {};
UIEditorPropertyGridHitTargetKind hoveredHitTarget = UIEditorPropertyGridHitTargetKind::None;
bool focused = false;
std::string pressedFieldId = {};
std::string popupFieldId = {};
std::size_t popupHighlightedIndex = UIEditorPropertyGridInvalidIndex;
};
struct UIEditorPropertyGridMetrics {
float contentInset = 8.0f;
float sectionGap = 8.0f;
float sectionHeaderHeight = 32.0f;
float fieldRowHeight = 32.0f;
float rowGap = 2.0f;
float horizontalPadding = 12.0f;
float controlColumnStart = 236.0f;
float labelControlGap = 20.0f;
float disclosureExtent = 12.0f;
float disclosureLabelGap = 8.0f;
float sectionTextInsetY = 8.0f;
float sectionFontSize = 12.0f;
float disclosureGlyphInsetX = 2.0f;
float disclosureGlyphInsetY = -1.0f;
float disclosureGlyphFontSize = 12.0f;
float labelTextInsetY = 8.0f;
float labelFontSize = 12.0f;
float valueTextInsetY = 8.0f;
float valueFontSize = 12.0f;
float valueBoxInsetY = 4.0f;
float valueBoxInsetX = 8.0f;
float tagFontSize = 11.0f;
float cornerRounding = 6.0f;
float valueBoxRounding = 5.0f;
float borderThickness = 1.0f;
float focusedBorderThickness = 2.0f;
float editOutlineThickness = 1.0f;
};
struct UIEditorPropertyGridPalette {
::XCEngine::UI::UIColor surfaceColor =
::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f);
::XCEngine::UI::UIColor borderColor =
::XCEngine::UI::UIColor(0.29f, 0.29f, 0.29f, 1.0f);
::XCEngine::UI::UIColor focusedBorderColor =
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
::XCEngine::UI::UIColor sectionHeaderColor =
::XCEngine::UI::UIColor(0.19f, 0.19f, 0.19f, 1.0f);
::XCEngine::UI::UIColor sectionHeaderHoverColor =
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
::XCEngine::UI::UIColor fieldHoverColor =
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
::XCEngine::UI::UIColor fieldSelectedColor =
::XCEngine::UI::UIColor(0.31f, 0.31f, 0.31f, 1.0f);
::XCEngine::UI::UIColor fieldSelectedFocusedColor =
::XCEngine::UI::UIColor(0.40f, 0.40f, 0.40f, 1.0f);
::XCEngine::UI::UIColor valueBoxColor =
::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f);
::XCEngine::UI::UIColor valueBoxHoverColor =
::XCEngine::UI::UIColor(0.22f, 0.22f, 0.22f, 1.0f);
::XCEngine::UI::UIColor valueBoxEditingColor =
::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f);
::XCEngine::UI::UIColor valueBoxReadOnlyColor =
::XCEngine::UI::UIColor(0.15f, 0.15f, 0.15f, 1.0f);
::XCEngine::UI::UIColor valueBoxBorderColor =
::XCEngine::UI::UIColor(0.32f, 0.32f, 0.32f, 1.0f);
::XCEngine::UI::UIColor valueBoxEditingBorderColor =
::XCEngine::UI::UIColor(0.75f, 0.75f, 0.75f, 1.0f);
::XCEngine::UI::UIColor disclosureColor =
::XCEngine::UI::UIColor(0.74f, 0.74f, 0.74f, 1.0f);
::XCEngine::UI::UIColor sectionTextColor =
::XCEngine::UI::UIColor(0.94f, 0.94f, 0.94f, 1.0f);
::XCEngine::UI::UIColor labelTextColor =
::XCEngine::UI::UIColor(0.84f, 0.84f, 0.84f, 1.0f);
::XCEngine::UI::UIColor valueTextColor =
::XCEngine::UI::UIColor(0.94f, 0.94f, 0.94f, 1.0f);
::XCEngine::UI::UIColor readOnlyValueTextColor =
::XCEngine::UI::UIColor(0.60f, 0.60f, 0.60f, 1.0f);
::XCEngine::UI::UIColor editTagColor =
::XCEngine::UI::UIColor(0.62f, 0.78f, 0.96f, 1.0f);
};
struct UIEditorPropertyGridLayout {
::XCEngine::UI::UIRect bounds = {};
std::vector<std::size_t> sectionIndices = {};
std::vector<::XCEngine::UI::UIRect> sectionHeaderRects = {};
std::vector<::XCEngine::UI::UIRect> sectionDisclosureRects = {};
std::vector<::XCEngine::UI::UIRect> sectionTitleRects = {};
std::vector<bool> sectionExpanded = {};
std::vector<std::size_t> visibleFieldSectionIndices = {};
std::vector<std::size_t> visibleFieldIndices = {};
std::vector<::XCEngine::UI::UIRect> fieldRowRects = {};
std::vector<::XCEngine::UI::UIRect> fieldLabelRects = {};
std::vector<::XCEngine::UI::UIRect> fieldValueRects = {};
std::vector<bool> fieldReadOnly = {};
};
struct UIEditorPropertyGridHitTarget {
UIEditorPropertyGridHitTargetKind kind = UIEditorPropertyGridHitTargetKind::None;
std::size_t sectionIndex = UIEditorPropertyGridInvalidIndex;
std::size_t fieldIndex = UIEditorPropertyGridInvalidIndex;
std::size_t visibleFieldIndex = UIEditorPropertyGridInvalidIndex;
};
bool IsUIEditorPropertyGridPointInside(
const ::XCEngine::UI::UIRect& rect,
const ::XCEngine::UI::UIPoint& point);
std::size_t FindUIEditorPropertyGridSectionIndex(
const std::vector<UIEditorPropertyGridSection>& sections,
std::string_view sectionId);
UIEditorPropertyGridFieldLocation FindUIEditorPropertyGridFieldLocation(
const std::vector<UIEditorPropertyGridSection>& sections,
std::string_view fieldId);
std::string ResolveUIEditorPropertyGridFieldValueText(
const UIEditorPropertyGridField& field);
std::size_t FindUIEditorPropertyGridVisibleFieldIndex(
const UIEditorPropertyGridLayout& layout,
std::string_view fieldId,
const std::vector<UIEditorPropertyGridSection>& sections);
UIEditorPropertyGridLayout BuildUIEditorPropertyGridLayout(
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorPropertyGridSection>& sections,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const UIEditorPropertyGridMetrics& metrics = {});
UIEditorPropertyGridHitTarget HitTestUIEditorPropertyGrid(
const UIEditorPropertyGridLayout& layout,
const ::XCEngine::UI::UIPoint& point);
void AppendUIEditorPropertyGridBackground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorPropertyGridLayout& layout,
const std::vector<UIEditorPropertyGridSection>& sections,
const ::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
const ::XCEngine::UI::Widgets::UIPropertyEditModel& propertyEditModel,
const UIEditorPropertyGridState& state,
const UIEditorPropertyGridPalette& palette = {},
const UIEditorPropertyGridMetrics& metrics = {});
void AppendUIEditorPropertyGridForeground(
::XCEngine::UI::UIDrawList& drawList,
const UIEditorPropertyGridLayout& layout,
const std::vector<UIEditorPropertyGridSection>& sections,
const UIEditorPropertyGridState& state,
const ::XCEngine::UI::Widgets::UIPropertyEditModel& propertyEditModel,
const UIEditorPropertyGridPalette& palette = {},
const UIEditorPropertyGridMetrics& metrics = {},
const UIEditorMenuPopupPalette& popupPalette = {},
const UIEditorMenuPopupMetrics& popupMetrics = {});
void AppendUIEditorPropertyGrid(
::XCEngine::UI::UIDrawList& drawList,
const ::XCEngine::UI::UIRect& bounds,
const std::vector<UIEditorPropertyGridSection>& sections,
const ::XCEngine::UI::Widgets::UISelectionModel& selectionModel,
const ::XCEngine::UI::Widgets::UIExpansionModel& expansionModel,
const ::XCEngine::UI::Widgets::UIPropertyEditModel& propertyEditModel,
const UIEditorPropertyGridState& state,
const UIEditorPropertyGridPalette& palette = {},
const UIEditorPropertyGridMetrics& metrics = {},
const UIEditorMenuPopupPalette& popupPalette = {},
const UIEditorMenuPopupMetrics& popupMetrics = {});
} // namespace XCEngine::UI::Editor::Widgets