跳转至

material_factory.hpp - Material 工厂函数

material_factory.hpp 提供了一套自由函数风格的工厂 API,用于创建 Material Design 3 的各个组件。相比 MaterialFactory 类,这套 API 更轻量,不需要实例化工厂对象——直接调用函数就行。

颜色方案工厂

创建颜色方案是最常用的功能:

#include "material_factory.hpp"

// 默认浅色方案
auto light = cf::ui::core::material::light();

// 默认深色方案
auto dark = cf::ui::core::material::dark();

这两个函数返回 MaterialColorScheme 对象(不是指针),可以直接使用或移动。

从种子颜色生成

Material You 的核心功能——动态颜色生成:

#include "base/color.h"

// 从任意颜色生成
CFColor seed("#6750A4");
auto scheme = cf::ui::core::material::fromKeyColor(seed);

// 生成深色版本
auto darkScheme = cf::ui::core::material::fromKeyColor(seed, true);

种子颜色可以是用户选择的品牌色、墙纸的主色等等。生成的配色会自动计算 26 个颜色角色的值,确保视觉协调。

从 JSON 创建(带错误处理)

fromJson 返回 cf::expected 类型,支持详细的错误处理:

QByteArray json = loadFromFile();
auto result = cf::ui::core::material::fromJson(json);

if (result) {
    auto scheme = std::move(*result);
    // 使用 scheme
} else {
    const auto& err = result.error();
    switch (err.kind) {
        case MaterialSchemeError::Kind::InvalidJson:
            qDebug() << "JSON 格式错误:" << err.message.c_str();
            break;
        case MaterialSchemeError::Kind::MissingColor:
            qDebug() << "缺少必需颜色:" << err.message.c_str();
            break;
        case MaterialSchemeError::Kind::InvalidColorFormat:
            qDebug() << "颜色格式错误:" << err.message.c_str();
            break;
        case MaterialSchemeError::Kind::GenerationFailed:
            qDebug() << "颜色生成失败:" << err.message.c_str();
            break;
    }
}

这个错误处理比 MaterialFactory::fromJson 的空指针友好得多。

导出到 JSON

可以把配色导出为 JSON:

auto scheme = material::light();
QByteArray json = material::toJson(scheme);

// 保存到文件
QFile file("theme.json");
file.open(QIODevice::WriteOnly);
file.write(json);

导出的格式兼容 Material Theme Builder。

字体工厂

创建默认排版系统:

auto typography = cf::ui::core::material::defaultTypography();

QFont titleFont = typography.queryTargetFont("md.typography.titleLarge");
QFont bodyFont = typography.queryTargetFont("md.typography.bodyMedium");

默认字体会根据平台自动选择——Windows 用 Segoe UI,macOS 用 .SF NS Text,Linux 用 Ubuntu。

圆角工厂

创建默认圆角系统:

auto radius = cf::ui::core::material::defaultRadiusScale();

float small = radius.queryRadiusScale("md.shape.cornerSmall");   // 8.0f
float medium = radius.queryRadiusScale("md.shape.cornerMedium"); // 12.0f
float large = radius.queryRadiusScale("md.shape.cornerLarge");   // 16.0f

动画工厂

创建默认运动系统:

auto motion = cf::ui::core::material::motion();

int duration = motion.queryDuration("shortEnter");  // 200
auto spec = motion.getMotionSpec("mediumExit");

完整工作流

一个典型的使用流程是组合各个组件创建完整主题:

#include "material_factory.hpp"

// 创建各个组件
auto colors = material::fromKeyColor("#6750A4");
auto typography = material::defaultTypography();
auto radius = material::defaultRadiusScale();
auto motion = material::motion();

// 使用组件...
QColor primary = colors.queryExpectedColor("md.primary");
QFont titleFont = typography.queryTargetFont("md.typography.titleLarge");
float cardRadius = radius.queryRadiusScale("md.shape.cornerMedium");
auto enterSpec = motion.getMotionSpec("mediumEnter");

如果需要完整的 MaterialTheme 对象,还是得用 MaterialFactory 类。

自定义主题示例

可以从种子颜色生成主题并应用:

void applyCustomTheme(const QColor& brandColor) {
    using namespace cf::ui::core::material;

    // 从品牌色生成配色
    CFColor keyColor(brandColor);
    auto scheme = fromKeyColor(keyColor, isDarkMode());

    // 获取其他默认组件
    auto typography = defaultTypography();
    auto radius = defaultRadiusScale();
    auto motion = motion();

    // 应用到应用...
    updateColorScheme(&scheme);
    updateTypography(&typography);
    // ...
}

这种方式让应用可以轻松实现"品牌色换肤"功能。

与 MaterialFactory 的选择

两套 API 的区别:

特性 material_factory.hpp MaterialFactory 类
使用方式 自由函数 类实例
错误处理 cf::expected 空指针
主题创建 不支持 支持
适用场景 独立组件创建 完整主题管理

如果只需要创建颜色/字体/圆角等单个组件,用自由函数 API 更简洁。如果需要创建完整 MaterialTheme 对象,得用 MaterialFactory 类。

相关文档