#include #include namespace XCEngine::UI::Editor::Widgets { namespace { bool ContainsPoint(const ::XCEngine::UI::UIRect& rect, const ::XCEngine::UI::UIPoint& point) { return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height; } } // namespace UIEditorBoolFieldLayout BuildUIEditorBoolFieldLayout( const ::XCEngine::UI::UIRect& bounds, const UIEditorBoolFieldSpec& spec, const UIEditorBoolFieldMetrics& metrics) { UIEditorBoolFieldLayout layout = {}; layout.bounds = bounds; const float controlX = (std::min)( bounds.x + bounds.width - metrics.horizontalPadding - metrics.toggleWidth, bounds.x + metrics.controlColumnStart); const float labelWidth = (std::max)( 0.0f, controlX - bounds.x - metrics.horizontalPadding - metrics.labelControlGap); layout.labelRect = ::XCEngine::UI::UIRect( bounds.x + metrics.horizontalPadding, bounds.y, labelWidth, bounds.height); layout.toggleRect = ::XCEngine::UI::UIRect( controlX, bounds.y + (std::max)(0.0f, (bounds.height - metrics.toggleHeight) * 0.5f), metrics.toggleWidth, metrics.toggleHeight); const float knobSize = (std::max)(0.0f, layout.toggleRect.height - metrics.toggleKnobInset * 2.0f); const float knobX = spec.value ? layout.toggleRect.x + layout.toggleRect.width - metrics.toggleKnobInset - knobSize : layout.toggleRect.x + metrics.toggleKnobInset; layout.knobRect = ::XCEngine::UI::UIRect( knobX, layout.toggleRect.y + metrics.toggleKnobInset, knobSize, knobSize); return layout; } UIEditorBoolFieldHitTarget HitTestUIEditorBoolField( const UIEditorBoolFieldLayout& layout, const ::XCEngine::UI::UIPoint& point) { if (!ContainsPoint(layout.bounds, point)) { return {}; } if (ContainsPoint(layout.toggleRect, point)) { return { UIEditorBoolFieldHitTargetKind::Toggle }; } return { UIEditorBoolFieldHitTargetKind::Row }; } void AppendUIEditorBoolFieldBackground( ::XCEngine::UI::UIDrawList& drawList, const UIEditorBoolFieldLayout& layout, const UIEditorBoolFieldSpec& spec, const UIEditorBoolFieldState& state, const UIEditorBoolFieldPalette& palette, const UIEditorBoolFieldMetrics& metrics) { const bool hovered = state.hoveredTarget != UIEditorBoolFieldHitTargetKind::None; const ::XCEngine::UI::UIColor rowColor = state.active ? palette.rowActiveColor : (hovered ? palette.rowHoverColor : palette.surfaceColor); drawList.AddFilledRect(layout.bounds, rowColor, metrics.cornerRounding); drawList.AddRectOutline( layout.bounds, state.focused ? palette.focusedBorderColor : palette.borderColor, state.focused ? metrics.focusedBorderThickness : metrics.borderThickness, metrics.cornerRounding); const ::XCEngine::UI::UIColor toggleColor = spec.readOnly ? palette.toggleReadOnlyColor : (spec.value ? palette.toggleOnColor : palette.toggleOffColor); drawList.AddFilledRect(layout.toggleRect, toggleColor, layout.toggleRect.height * 0.5f); drawList.AddRectOutline( layout.toggleRect, palette.toggleBorderColor, metrics.borderThickness, layout.toggleRect.height * 0.5f); drawList.AddFilledRect(layout.knobRect, palette.knobColor, layout.knobRect.height * 0.5f); } void AppendUIEditorBoolFieldForeground( ::XCEngine::UI::UIDrawList& drawList, const UIEditorBoolFieldLayout& layout, const UIEditorBoolFieldSpec& spec, const UIEditorBoolFieldPalette& palette, const UIEditorBoolFieldMetrics& metrics) { drawList.PushClipRect(layout.labelRect); drawList.AddText( ::XCEngine::UI::UIPoint(layout.labelRect.x, layout.labelRect.y + metrics.textInsetY), spec.label, palette.labelColor, 12.0f); drawList.PopClipRect(); drawList.AddText( ::XCEngine::UI::UIPoint( layout.toggleRect.x - 42.0f, layout.bounds.y + metrics.textInsetY), spec.value ? "On" : "Off", palette.valueColor, 12.0f); } void AppendUIEditorBoolField( ::XCEngine::UI::UIDrawList& drawList, const ::XCEngine::UI::UIRect& bounds, const UIEditorBoolFieldSpec& spec, const UIEditorBoolFieldState& state, const UIEditorBoolFieldPalette& palette, const UIEditorBoolFieldMetrics& metrics) { const UIEditorBoolFieldLayout layout = BuildUIEditorBoolFieldLayout(bounds, spec, metrics); AppendUIEditorBoolFieldBackground(drawList, layout, spec, state, palette, metrics); AppendUIEditorBoolFieldForeground(drawList, layout, spec, palette, metrics); } } // namespace XCEngine::UI::Editor::Widgets