#include #include namespace XCEngine { namespace UI { namespace Style { void UIThemeDefinition::SetToken(const std::string& tokenName, const UIStyleValue& value) { tokens[tokenName] = value; } const UIStyleValue* UIThemeDefinition::FindToken(const std::string& tokenName) const { const auto it = tokens.find(tokenName); return it != tokens.end() ? &it->second : nullptr; } UITheme::UITheme(const UIThemeDefinition& definition) : m_name(definition.name) , m_tokens(definition.tokens) { } void UITheme::SetName(const std::string& name) { m_name = name; } const std::string& UITheme::GetName() const { return m_name; } void UITheme::SetParent(const UITheme* parent) { m_parent = parent; } const UITheme* UITheme::GetParent() const { return m_parent; } void UITheme::SetToken(const std::string& tokenName, const UIStyleValue& value) { m_tokens[tokenName] = value; } bool UITheme::RemoveToken(const std::string& tokenName) { return m_tokens.erase(tokenName) > 0u; } const UIStyleValue* UITheme::FindToken(const std::string& tokenName) const { const auto it = m_tokens.find(tokenName); if (it != m_tokens.end()) { return &it->second; } return m_parent != nullptr ? m_parent->FindToken(tokenName) : nullptr; } const std::map& UITheme::GetTokens() const { return m_tokens; } UITokenResolveResult UITheme::ResolveToken( const std::string& tokenName, UIStyleValueType expectedType) const { std::vector visiting = {}; return ResolveTokenRecursive(tokenName, expectedType, visiting); } UITokenResolveResult UITheme::ResolveTokenRecursive( const std::string& tokenName, UIStyleValueType expectedType, std::vector& visiting) const { UITokenResolveResult result = {}; if (tokenName.empty()) { result.status = UITokenResolveStatus::MissingToken; return result; } if (std::find(visiting.begin(), visiting.end(), tokenName) != visiting.end()) { result.status = UITokenResolveStatus::CycleDetected; return result; } const UIStyleValue* value = FindToken(tokenName); if (value == nullptr || !value->IsSet()) { result.status = UITokenResolveStatus::MissingToken; return result; } if (const UITokenReference* tokenReference = value->TryGetTokenReference()) { visiting.push_back(tokenName); result = ResolveTokenRecursive(tokenReference->name, expectedType, visiting); visiting.pop_back(); return result; } if (expectedType != UIStyleValueType::None && value->GetType() != expectedType) { result.status = UITokenResolveStatus::TypeMismatch; return result; } result.status = UITokenResolveStatus::Resolved; result.value = *value; return result; } UITheme BuildTheme(const UIThemeDefinition& definition, const UITheme* parent) { UITheme theme(definition); theme.SetParent(parent); return theme; } UITheme BuildBuiltinTheme(UIBuiltinThemeKind themeKind) { UIThemeDefinition definition = {}; if (themeKind == UIBuiltinThemeKind::NeutralLight) { definition.name = "NeutralLight"; definition.SetToken("color.surface", UIStyleValue(Math::Color(0.93f, 0.94f, 0.96f, 1.0f))); definition.SetToken("color.surface.elevated", UIStyleValue(Math::Color(1.0f, 1.0f, 1.0f, 1.0f))); definition.SetToken("color.text.primary", UIStyleValue(Math::Color(0.10f, 0.11f, 0.14f, 1.0f))); definition.SetToken("color.accent", UIStyleValue(Math::Color(0.14f, 0.43f, 0.88f, 1.0f))); definition.SetToken("space.compact", UIStyleValue(6.0f)); definition.SetToken("space.regular", UIStyleValue(10.0f)); definition.SetToken("padding.control", UIStyleValue(UIThickness::Uniform(10.0f))); definition.SetToken("radius.control", UIStyleValue(UICornerRadius::Uniform(6.0f))); definition.SetToken("font.body", UIStyleValue(14.0f)); definition.SetToken("line.default", UIStyleValue(1.0f)); return BuildTheme(definition); } definition.name = "NeutralDark"; definition.SetToken("color.surface", UIStyleValue(Math::Color(0.13f, 0.14f, 0.16f, 1.0f))); definition.SetToken("color.surface.elevated", UIStyleValue(Math::Color(0.18f, 0.19f, 0.22f, 1.0f))); definition.SetToken("color.text.primary", UIStyleValue(Math::Color(0.92f, 0.93f, 0.95f, 1.0f))); definition.SetToken("color.accent", UIStyleValue(Math::Color(0.98f, 0.53f, 0.17f, 1.0f))); definition.SetToken("space.compact", UIStyleValue(6.0f)); definition.SetToken("space.regular", UIStyleValue(10.0f)); definition.SetToken("padding.control", UIStyleValue(UIThickness::Uniform(10.0f))); definition.SetToken("radius.control", UIStyleValue(UICornerRadius::Uniform(6.0f))); definition.SetToken("font.body", UIStyleValue(14.0f)); definition.SetToken("line.default", UIStyleValue(1.0f)); return BuildTheme(definition); } } // namespace Style } // namespace UI } // namespace XCEngine