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 类。