Refactor XCUI editor module layout
This commit is contained in:
227
new_editor/src/Fields/UIEditorTextField.cpp
Normal file
227
new_editor/src/Fields/UIEditorTextField.cpp
Normal file
@@ -0,0 +1,227 @@
|
||||
#include <XCEditor/Fields/UIEditorTextField.h>
|
||||
#include <XCEditor/Widgets/UIEditorFieldRowLayout.h>
|
||||
#include <XCEditor/Widgets/UIEditorTextLayout.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace XCEngine::UI::Editor::Widgets {
|
||||
|
||||
namespace {
|
||||
|
||||
using ::XCEngine::UI::UIDrawList;
|
||||
using ::XCEngine::UI::UIPoint;
|
||||
using ::XCEngine::UI::UIRect;
|
||||
|
||||
UIEditorTextFieldMetrics ResolveMetrics(const UIEditorTextFieldMetrics& metrics) {
|
||||
const auto& tokens = GetUIEditorInspectorFieldStyleTokens();
|
||||
|
||||
UIEditorTextFieldMetrics resolved = metrics;
|
||||
if (AreUIEditorFieldMetricsEqual(metrics.controlTrailingInset, 8.0f)) {
|
||||
resolved.controlTrailingInset = tokens.controlTrailingInset;
|
||||
}
|
||||
if (AreUIEditorFieldMetricsEqual(metrics.valueBoxMinWidth, 96.0f)) {
|
||||
resolved.valueBoxMinWidth = tokens.controlMinWidth;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
UIEditorTextFieldPalette ResolvePalette(const UIEditorTextFieldPalette& palette) {
|
||||
const auto& tokens = GetUIEditorInspectorFieldStyleTokens();
|
||||
|
||||
UIEditorTextFieldPalette resolved = palette;
|
||||
if (AreUIEditorFieldColorsEqual(palette.rowHoverColor, ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f))) {
|
||||
resolved.rowHoverColor = tokens.rowHoverColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.rowActiveColor, ::XCEngine::UI::UIColor(0.0f, 0.0f, 0.0f, 0.0f))) {
|
||||
resolved.rowActiveColor = tokens.rowActiveColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.valueBoxColor, ::XCEngine::UI::UIColor(0.18f, 0.18f, 0.18f, 1.0f))) {
|
||||
resolved.valueBoxColor = tokens.controlColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.valueBoxHoverColor, ::XCEngine::UI::UIColor(0.21f, 0.21f, 0.21f, 1.0f))) {
|
||||
resolved.valueBoxHoverColor = tokens.controlHoverColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.valueBoxEditingColor, ::XCEngine::UI::UIColor(0.24f, 0.24f, 0.24f, 1.0f))) {
|
||||
resolved.valueBoxEditingColor = tokens.controlEditingColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.readOnlyColor, ::XCEngine::UI::UIColor(0.17f, 0.17f, 0.17f, 1.0f))) {
|
||||
resolved.readOnlyColor = tokens.controlReadOnlyColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.controlBorderColor, ::XCEngine::UI::UIColor(0.14f, 0.14f, 0.14f, 1.0f))) {
|
||||
resolved.controlBorderColor = tokens.controlBorderColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(
|
||||
palette.controlFocusedBorderColor,
|
||||
::XCEngine::UI::UIColor(0.46f, 0.46f, 0.46f, 1.0f))) {
|
||||
resolved.controlFocusedBorderColor = tokens.controlFocusedBorderColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.labelColor, ::XCEngine::UI::UIColor(0.80f, 0.80f, 0.80f, 1.0f))) {
|
||||
resolved.labelColor = tokens.labelColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(palette.valueColor, ::XCEngine::UI::UIColor(0.92f, 0.92f, 0.92f, 1.0f))) {
|
||||
resolved.valueColor = tokens.valueColor;
|
||||
}
|
||||
if (AreUIEditorFieldColorsEqual(
|
||||
palette.readOnlyValueColor,
|
||||
::XCEngine::UI::UIColor(0.62f, 0.62f, 0.62f, 1.0f))) {
|
||||
resolved.readOnlyValueColor = tokens.readOnlyValueColor;
|
||||
}
|
||||
|
||||
return resolved;
|
||||
}
|
||||
|
||||
::XCEngine::UI::UIColor ResolveRowFillColor(
|
||||
const UIEditorTextFieldState& state,
|
||||
const UIEditorTextFieldPalette& palette) {
|
||||
if (state.activeTarget != UIEditorTextFieldHitTargetKind::None) {
|
||||
return palette.rowActiveColor;
|
||||
}
|
||||
if (state.hoveredTarget != UIEditorTextFieldHitTargetKind::None) {
|
||||
return palette.rowHoverColor;
|
||||
}
|
||||
return palette.surfaceColor;
|
||||
}
|
||||
|
||||
::XCEngine::UI::UIColor ResolveValueFillColor(
|
||||
const UIEditorTextFieldSpec& spec,
|
||||
const UIEditorTextFieldState& state,
|
||||
const UIEditorTextFieldPalette& palette) {
|
||||
if (spec.readOnly) {
|
||||
return palette.readOnlyColor;
|
||||
}
|
||||
if (state.editing) {
|
||||
return palette.valueBoxEditingColor;
|
||||
}
|
||||
if (state.hoveredTarget == UIEditorTextFieldHitTargetKind::ValueBox) {
|
||||
return palette.valueBoxHoverColor;
|
||||
}
|
||||
return palette.valueBoxColor;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool IsUIEditorTextFieldPointInside(
|
||||
const UIRect& rect,
|
||||
const UIPoint& point) {
|
||||
return point.x >= rect.x &&
|
||||
point.x <= rect.x + rect.width &&
|
||||
point.y >= rect.y &&
|
||||
point.y <= rect.y + rect.height;
|
||||
}
|
||||
|
||||
UIEditorTextFieldLayout BuildUIEditorTextFieldLayout(
|
||||
const UIRect& bounds,
|
||||
const UIEditorTextFieldSpec&,
|
||||
const UIEditorTextFieldMetrics& metrics) {
|
||||
const UIEditorTextFieldMetrics resolvedMetrics = ResolveMetrics(metrics);
|
||||
const UIEditorFieldRowLayout hostLayout = BuildUIEditorFieldRowLayout(
|
||||
bounds,
|
||||
resolvedMetrics.valueBoxMinWidth,
|
||||
UIEditorFieldRowLayoutMetrics {
|
||||
resolvedMetrics.rowHeight,
|
||||
resolvedMetrics.horizontalPadding,
|
||||
resolvedMetrics.labelControlGap,
|
||||
resolvedMetrics.controlColumnStart,
|
||||
resolvedMetrics.controlTrailingInset,
|
||||
resolvedMetrics.controlInsetY,
|
||||
});
|
||||
|
||||
UIEditorTextFieldLayout layout = {};
|
||||
layout.bounds = hostLayout.bounds;
|
||||
layout.labelRect = hostLayout.labelRect;
|
||||
layout.controlRect = hostLayout.controlRect;
|
||||
layout.valueRect = layout.controlRect;
|
||||
return layout;
|
||||
}
|
||||
|
||||
UIEditorTextFieldHitTarget HitTestUIEditorTextField(
|
||||
const UIEditorTextFieldLayout& layout,
|
||||
const UIPoint& point) {
|
||||
if (IsUIEditorTextFieldPointInside(layout.valueRect, point)) {
|
||||
return { UIEditorTextFieldHitTargetKind::ValueBox };
|
||||
}
|
||||
if (IsUIEditorTextFieldPointInside(layout.bounds, point)) {
|
||||
return { UIEditorTextFieldHitTargetKind::Row };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void AppendUIEditorTextFieldBackground(
|
||||
UIDrawList& drawList,
|
||||
const UIEditorTextFieldLayout& layout,
|
||||
const UIEditorTextFieldSpec& spec,
|
||||
const UIEditorTextFieldState& state,
|
||||
const UIEditorTextFieldPalette& palette,
|
||||
const UIEditorTextFieldMetrics& metrics) {
|
||||
const UIEditorTextFieldPalette resolvedPalette = ResolvePalette(palette);
|
||||
const UIEditorTextFieldMetrics resolvedMetrics = ResolveMetrics(metrics);
|
||||
const auto rowFillColor = ResolveRowFillColor(state, resolvedPalette);
|
||||
if (rowFillColor.a > 0.0f) {
|
||||
drawList.AddFilledRect(layout.bounds, rowFillColor, resolvedMetrics.cornerRounding);
|
||||
}
|
||||
const auto rowBorderColor = state.focused ? resolvedPalette.focusedBorderColor : resolvedPalette.borderColor;
|
||||
if (rowBorderColor.a > 0.0f) {
|
||||
drawList.AddRectOutline(
|
||||
layout.bounds,
|
||||
rowBorderColor,
|
||||
state.focused ? resolvedMetrics.focusedBorderThickness : resolvedMetrics.borderThickness,
|
||||
resolvedMetrics.cornerRounding);
|
||||
}
|
||||
|
||||
drawList.AddFilledRect(
|
||||
layout.valueRect,
|
||||
ResolveValueFillColor(spec, state, resolvedPalette),
|
||||
resolvedMetrics.valueBoxRounding);
|
||||
drawList.AddRectOutline(
|
||||
layout.valueRect,
|
||||
state.editing ? resolvedPalette.controlFocusedBorderColor : resolvedPalette.controlBorderColor,
|
||||
state.editing ? resolvedMetrics.focusedBorderThickness : resolvedMetrics.borderThickness,
|
||||
resolvedMetrics.valueBoxRounding);
|
||||
}
|
||||
|
||||
void AppendUIEditorTextFieldForeground(
|
||||
UIDrawList& drawList,
|
||||
const UIEditorTextFieldLayout& layout,
|
||||
const UIEditorTextFieldSpec& spec,
|
||||
const UIEditorTextFieldState& state,
|
||||
const UIEditorTextFieldPalette& palette,
|
||||
const UIEditorTextFieldMetrics& metrics) {
|
||||
const UIEditorTextFieldPalette resolvedPalette = ResolvePalette(palette);
|
||||
const UIEditorTextFieldMetrics resolvedMetrics = ResolveMetrics(metrics);
|
||||
drawList.PushClipRect(ResolveUIEditorTextClipRect(layout.labelRect, resolvedMetrics.labelFontSize));
|
||||
drawList.AddText(
|
||||
UIPoint(
|
||||
layout.labelRect.x,
|
||||
ResolveUIEditorTextTop(layout.labelRect, resolvedMetrics.labelFontSize, resolvedMetrics.labelTextInsetY)),
|
||||
spec.label,
|
||||
resolvedPalette.labelColor,
|
||||
resolvedMetrics.labelFontSize);
|
||||
drawList.PopClipRect();
|
||||
|
||||
drawList.PushClipRect(ResolveUIEditorTextClipRect(layout.valueRect, resolvedMetrics.valueFontSize));
|
||||
drawList.AddText(
|
||||
UIPoint(
|
||||
layout.valueRect.x + resolvedMetrics.valueTextInsetX,
|
||||
ResolveUIEditorTextTop(layout.valueRect, resolvedMetrics.valueFontSize, resolvedMetrics.valueTextInsetY)),
|
||||
state.editing ? state.displayText : spec.value,
|
||||
spec.readOnly ? resolvedPalette.readOnlyValueColor : resolvedPalette.valueColor,
|
||||
resolvedMetrics.valueFontSize);
|
||||
drawList.PopClipRect();
|
||||
}
|
||||
|
||||
void AppendUIEditorTextField(
|
||||
UIDrawList& drawList,
|
||||
const UIRect& bounds,
|
||||
const UIEditorTextFieldSpec& spec,
|
||||
const UIEditorTextFieldState& state,
|
||||
const UIEditorTextFieldPalette& palette,
|
||||
const UIEditorTextFieldMetrics& metrics) {
|
||||
const UIEditorTextFieldMetrics resolvedMetrics = ResolveMetrics(metrics);
|
||||
const UIEditorTextFieldPalette resolvedPalette = ResolvePalette(palette);
|
||||
const UIEditorTextFieldLayout layout = BuildUIEditorTextFieldLayout(bounds, spec, resolvedMetrics);
|
||||
AppendUIEditorTextFieldBackground(drawList, layout, spec, state, resolvedPalette, resolvedMetrics);
|
||||
AppendUIEditorTextFieldForeground(drawList, layout, spec, state, resolvedPalette, resolvedMetrics);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::Widgets
|
||||
Reference in New Issue
Block a user