#pragma once #include #include #include namespace XCEngine::UI::Editor::Widgets { struct UIEditorPanelChromeState { bool active = false; bool hovered = false; }; struct UIEditorPanelChromeText { std::string_view title = {}; std::string_view subtitle = {}; std::string_view footer = {}; }; struct UIEditorPanelChromeMetrics { float cornerRounding = 18.0f; float headerHeight = 42.0f; float titleInsetX = 16.0f; float titleInsetY = 12.0f; float subtitleInsetY = 28.0f; float footerInsetX = 16.0f; float footerInsetBottom = 18.0f; float activeBorderThickness = 2.0f; float inactiveBorderThickness = 1.0f; }; struct UIEditorPanelChromePalette { ::XCEngine::UI::UIColor surfaceColor = ::XCEngine::UI::UIColor(9.0f / 255.0f, 13.0f / 255.0f, 18.0f / 255.0f, 212.0f / 255.0f); ::XCEngine::UI::UIColor borderColor = ::XCEngine::UI::UIColor(53.0f / 255.0f, 72.0f / 255.0f, 96.0f / 255.0f, 1.0f); ::XCEngine::UI::UIColor accentColor = ::XCEngine::UI::UIColor(84.0f / 255.0f, 176.0f / 255.0f, 244.0f / 255.0f, 1.0f); ::XCEngine::UI::UIColor hoveredAccentColor = ::XCEngine::UI::UIColor(1.0f, 206.0f / 255.0f, 112.0f / 255.0f, 1.0f); ::XCEngine::UI::UIColor headerColor = ::XCEngine::UI::UIColor(13.0f / 255.0f, 20.0f / 255.0f, 28.0f / 255.0f, 242.0f / 255.0f); ::XCEngine::UI::UIColor textPrimary = ::XCEngine::UI::UIColor(232.0f / 255.0f, 238.0f / 255.0f, 246.0f / 255.0f, 1.0f); ::XCEngine::UI::UIColor textSecondary = ::XCEngine::UI::UIColor(150.0f / 255.0f, 164.0f / 255.0f, 184.0f / 255.0f, 1.0f); ::XCEngine::UI::UIColor textMuted = ::XCEngine::UI::UIColor(108.0f / 255.0f, 123.0f / 255.0f, 145.0f / 255.0f, 1.0f); }; inline ::XCEngine::UI::UIRect BuildUIEditorPanelChromeHeaderRect( const ::XCEngine::UI::UIRect& panelRect, const UIEditorPanelChromeMetrics& metrics = {}) { return ::XCEngine::UI::UIRect( panelRect.x, panelRect.y, panelRect.width, metrics.headerHeight); } inline ::XCEngine::UI::UIColor ResolveUIEditorPanelChromeBorderColor( const UIEditorPanelChromeState& state, const UIEditorPanelChromePalette& palette = {}) { if (state.active) { return palette.accentColor; } if (state.hovered) { return palette.hoveredAccentColor; } return palette.borderColor; } inline float ResolveUIEditorPanelChromeBorderThickness( const UIEditorPanelChromeState& state, const UIEditorPanelChromeMetrics& metrics = {}) { return state.active ? metrics.activeBorderThickness : metrics.inactiveBorderThickness; } inline void AppendUIEditorPanelChromeBackground( ::XCEngine::UI::UIDrawList& drawList, const ::XCEngine::UI::UIRect& panelRect, const UIEditorPanelChromeState& state, const UIEditorPanelChromePalette& palette = {}, const UIEditorPanelChromeMetrics& metrics = {}) { drawList.AddFilledRect(panelRect, palette.surfaceColor, metrics.cornerRounding); drawList.AddRectOutline( panelRect, ResolveUIEditorPanelChromeBorderColor(state, palette), ResolveUIEditorPanelChromeBorderThickness(state, metrics), metrics.cornerRounding); drawList.AddFilledRect( BuildUIEditorPanelChromeHeaderRect(panelRect, metrics), palette.headerColor, metrics.cornerRounding); } inline void AppendUIEditorPanelChromeForeground( ::XCEngine::UI::UIDrawList& drawList, const ::XCEngine::UI::UIRect& panelRect, const UIEditorPanelChromeText& text, const UIEditorPanelChromePalette& palette = {}, const UIEditorPanelChromeMetrics& metrics = {}) { if (!text.title.empty()) { drawList.AddText( ::XCEngine::UI::UIPoint(panelRect.x + metrics.titleInsetX, panelRect.y + metrics.titleInsetY), std::string(text.title), palette.textPrimary); } if (!text.subtitle.empty()) { drawList.AddText( ::XCEngine::UI::UIPoint(panelRect.x + metrics.titleInsetX, panelRect.y + metrics.subtitleInsetY), std::string(text.subtitle), palette.textSecondary); } if (!text.footer.empty()) { drawList.AddText( ::XCEngine::UI::UIPoint( panelRect.x + metrics.footerInsetX, panelRect.y + panelRect.height - metrics.footerInsetBottom), std::string(text.footer), palette.textMuted); } } } // namespace XCEngine::UI::Editor::Widgets