添加creeper-qt最新依赖

This commit is contained in:
2025-11-25 15:59:47 +08:00
parent 0ec07218ab
commit fb1a30fc94
89 changed files with 8520 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
#pragma once
#include <qcolor.h>
#include <qfont.h>
namespace creeper::theme {
enum class ColorMode { LIGHT, DARK };
struct ColorScheme {
QColor primary;
QColor on_primary;
QColor primary_container;
QColor on_primary_container;
QColor secondary;
QColor on_secondary;
QColor secondary_container;
QColor on_secondary_container;
QColor tertiary;
QColor on_tertiary;
QColor tertiary_container;
QColor on_tertiary_container;
QColor error;
QColor on_error;
QColor error_container;
QColor on_error_container;
QColor background;
QColor on_background;
QColor surface;
QColor on_surface;
QColor surface_variant;
QColor on_surface_variant;
QColor outline;
QColor outline_variant;
QColor shadow;
QColor scrim;
QColor inverse_surface;
QColor inverse_on_surface;
QColor inverse_primary;
QColor surface_container_highest;
QColor surface_container_high;
QColor surface_container;
QColor surface_container_low;
QColor surface_container_lowest;
};
struct Typography {
QFont body;
QFont title;
QFont button;
};
}

View File

@@ -0,0 +1,101 @@
#pragma once
#include "creeper-qt/utility/theme/theme.hh"
namespace creeper {
constexpr auto kBlueMikuLightColorScheme = ColorScheme {
// 蓝色初音亮色
.primary = QColor(0, 89, 199),
.on_primary = QColor(255, 255, 255),
.primary_container = QColor(217, 226, 255),
.on_primary_container = QColor(0, 26, 67),
.secondary = QColor(87, 94, 113),
.on_secondary = QColor(255, 255, 255),
.secondary_container = QColor(219, 226, 249),
.on_secondary_container = QColor(20, 27, 44),
.tertiary = QColor(114, 85, 115),
.on_tertiary = QColor(255, 255, 255),
.tertiary_container = QColor(252, 215, 251),
.on_tertiary_container = QColor(42, 19, 45),
.error = QColor(186, 26, 26),
.on_error = QColor(255, 255, 255),
.error_container = QColor(255, 218, 214),
.on_error_container = QColor(65, 0, 2),
.background = QColor(254, 251, 255),
.on_background = QColor(27, 27, 31),
.surface = QColor(254, 251, 255),
.on_surface = QColor(27, 27, 31),
.surface_variant = QColor(225, 226, 236),
.on_surface_variant = QColor(68, 70, 79),
.outline = QColor(117, 119, 128),
.outline_variant = QColor(197, 198, 208),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(48, 48, 52),
.inverse_on_surface = QColor(242, 240, 244),
.inverse_primary = QColor(175, 198, 255),
.surface_container_highest = QColor(224, 232, 248),
.surface_container_high = QColor(226, 233, 249),
.surface_container = QColor(234, 238, 251),
.surface_container_low = QColor(242, 243, 252),
.surface_container_lowest = QColor(254, 251, 255),
};
constexpr auto kBlueMikuDarkColorScheme = ColorScheme {
// 蓝色初音暗色
.primary = QColor(175, 198, 255),
.on_primary = QColor(0, 45, 108),
.primary_container = QColor(0, 67, 152),
.on_primary_container = QColor(217, 226, 255),
.secondary = QColor(191, 198, 220),
.on_secondary = QColor(41, 48, 66),
.secondary_container = QColor(63, 71, 89),
.on_secondary_container = QColor(219, 226, 249),
.tertiary = QColor(223, 187, 222),
.on_tertiary = QColor(64, 39, 67),
.tertiary_container = QColor(89, 62, 90),
.on_tertiary_container = QColor(252, 215, 251),
.error = QColor(255, 180, 171),
.on_error = QColor(105, 0, 5),
.error_container = QColor(147, 0, 10),
.on_error_container = QColor(255, 180, 171),
.background = QColor(27, 27, 31),
.on_background = QColor(227, 226, 230),
.surface = QColor(27, 27, 31),
.on_surface = QColor(227, 226, 230),
.surface_variant = QColor(68, 70, 79),
.on_surface_variant = QColor(197, 198, 208),
.outline = QColor(143, 144, 153),
.outline_variant = QColor(68, 70, 79),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(227, 226, 230),
.inverse_on_surface = QColor(48, 48, 52),
.inverse_primary = QColor(0, 89, 199),
.surface_container_highest = QColor(44, 47, 57),
.surface_container_high = QColor(43, 46, 56),
.surface_container = QColor(39, 40, 49),
.surface_container_low = QColor(34, 35, 42),
.surface_container_lowest = QColor(27, 27, 31),
};
constexpr auto kBlueMikuThemePack = ThemePack {
.light = kBlueMikuLightColorScheme,
.dark = kBlueMikuDarkColorScheme,
};
}

View File

@@ -0,0 +1,103 @@
#pragma once
#include "creeper-qt/utility/theme/theme.hh"
namespace creeper {
// 丰收金色亮色主题 (Golden Harvest Light Scheme)
constexpr auto kGoldenHarvestLightColorScheme = ColorScheme {
.primary = QColor(124, 94, 0),
.on_primary = QColor(255, 255, 255),
.primary_container = QColor(255, 223, 128),
.on_primary_container = QColor(38, 28, 0),
.secondary = QColor(98, 91, 66),
.on_secondary = QColor(255, 255, 255),
.secondary_container = QColor(232, 224, 198),
.on_secondary_container = QColor(30, 26, 10),
.tertiary = QColor(0, 77, 78),
.on_tertiary = QColor(255, 255, 255),
.tertiary_container = QColor(160, 232, 212),
.on_tertiary_container = QColor(0, 32, 33),
.error = QColor(186, 26, 26),
.on_error = QColor(255, 255, 255),
.error_container = QColor(255, 218, 214),
.on_error_container = QColor(65, 0, 2),
.background = QColor(255, 248, 236),
.on_background = QColor(30, 26, 10),
.surface = QColor(255, 248, 236),
.on_surface = QColor(30, 26, 10),
.surface_variant = QColor(232, 224, 198),
.on_surface_variant = QColor(74, 69, 50),
.outline = QColor(124, 117, 89),
.outline_variant = QColor(202, 196, 168),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(51, 47, 30),
.inverse_on_surface = QColor(250, 245, 230),
.inverse_primary = QColor(255, 223, 128),
.surface_container_highest = QColor(240, 235, 220),
.surface_container_high = QColor(245, 240, 225),
.surface_container = QColor(250, 245, 230),
.surface_container_low = QColor(255, 250, 235),
.surface_container_lowest = QColor(255, 253, 240),
};
// 丰收金色暗色主题 (Golden Harvest Dark Scheme)
constexpr auto kGoldenHarvestDarkColorScheme = ColorScheme {
.primary = QColor(255, 223, 128),
.on_primary = QColor(38, 28, 0),
.primary_container = QColor(124, 94, 0),
.on_primary_container = QColor(255, 255, 255),
.secondary = QColor(204, 196, 168),
.on_secondary = QColor(51, 47, 30),
.secondary_container = QColor(74, 69, 50),
.on_secondary_container = QColor(232, 224, 198),
.tertiary = QColor(160, 232, 212),
.on_tertiary = QColor(0, 32, 33),
.tertiary_container = QColor(0, 77, 78),
.on_tertiary_container = QColor(160, 232, 212),
.error = QColor(255, 180, 171),
.on_error = QColor(105, 0, 5),
.error_container = QColor(147, 0, 10),
.on_error_container = QColor(255, 180, 171),
.background = QColor(30, 26, 10),
.on_background = QColor(240, 235, 220),
.surface = QColor(30, 26, 10),
.on_surface = QColor(240, 235, 220),
.surface_variant = QColor(74, 69, 50),
.on_surface_variant = QColor(202, 196, 168),
.outline = QColor(146, 144, 137),
.outline_variant = QColor(78, 75, 65),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(240, 235, 220),
.inverse_on_surface = QColor(51, 47, 30),
.inverse_primary = QColor(124, 94, 0),
.surface_container_highest = QColor(50, 48, 41),
.surface_container_high = QColor(45, 43, 37),
.surface_container = QColor(40, 38, 32),
.surface_container_low = QColor(35, 33, 27),
.surface_container_lowest = QColor(30, 26, 10),
};
// 丰收金色主题包
constexpr auto kGoldenHarvestThemePack = ThemePack {
.light = kGoldenHarvestLightColorScheme,
.dark = kGoldenHarvestDarkColorScheme,
};
}

View File

@@ -0,0 +1,107 @@
#pragma once
#include "creeper-qt/utility/theme/theme.hh"
namespace creeper {
// 橄榄绿亮色主题 (Light Theme)
constexpr auto kGreenLightColorScheme = ColorScheme {
// Light Scheme (Primary: #386A20)
.primary = QColor(56, 106, 32),
.on_primary = QColor(255, 255, 255),
.primary_container = QColor(184, 246, 150),
.on_primary_container = QColor(1, 34, 0),
.secondary = QColor(86, 98, 75),
.on_secondary = QColor(255, 255, 255),
.secondary_container = QColor(217, 231, 202),
.on_secondary_container = QColor(20, 31, 11),
.tertiary = QColor(56, 102, 99),
.on_tertiary = QColor(255, 255, 255),
.tertiary_container = QColor(187, 236, 231),
.on_tertiary_container = QColor(0, 32, 31),
.error = QColor(186, 26, 26),
.on_error = QColor(255, 255, 255),
.error_container = QColor(255, 218, 214),
.on_error_container = QColor(65, 0, 2),
.background = QColor(252, 253, 246),
.on_background = QColor(26, 28, 24),
.surface = QColor(252, 253, 246),
.on_surface = QColor(26, 28, 24),
.surface_variant = QColor(222, 229, 212),
.on_surface_variant = QColor(67, 72, 62),
.outline = QColor(116, 121, 109),
.outline_variant = QColor(195, 201, 188),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(47, 49, 45),
.inverse_on_surface = QColor(241, 241, 235),
.inverse_primary = QColor(157, 218, 125),
// Surface steps for Light Theme
.surface_container_highest = QColor(230, 230, 223), // Surface 4
.surface_container_high = QColor(236, 236, 229), // Surface 3
.surface_container = QColor(241, 241, 235), // Surface 2
.surface_container_low = QColor(246, 247, 240), // Surface 1
.surface_container_lowest = QColor(255, 255, 255), // Surface 0
};
// 橄榄绿暗色主题 (Dark Theme)
constexpr auto kGreenDarkColorScheme = ColorScheme {
// Dark Scheme (Primary: #9DDA7D)
.primary = QColor(157, 218, 125),
.on_primary = QColor(15, 57, 0),
.primary_container = QColor(33, 81, 6),
.on_primary_container = QColor(184, 246, 150),
.secondary = QColor(189, 203, 176),
.on_secondary = QColor(42, 52, 32),
.secondary_container = QColor(64, 74, 54),
.on_secondary_container = QColor(217, 231, 202),
.tertiary = QColor(160, 208, 204),
.on_tertiary = QColor(1, 55, 53),
.tertiary_container = QColor(31, 78, 76),
.on_tertiary_container = QColor(187, 236, 231),
.error = QColor(255, 180, 171),
.on_error = QColor(105, 0, 5),
.error_container = QColor(147, 0, 10),
.on_error_container = QColor(255, 218, 214),
.background = QColor(26, 28, 24),
.on_background = QColor(227, 227, 220),
.surface = QColor(26, 28, 24),
.on_surface = QColor(227, 227, 220),
.surface_variant = QColor(67, 72, 62),
.on_surface_variant = QColor(195, 201, 188),
.outline = QColor(142, 146, 135),
.outline_variant = QColor(67, 72, 62),
.shadow = QColor(0, 0, 0),
.scrim = QColor(0, 0, 0),
.inverse_surface = QColor(227, 227, 220),
.inverse_on_surface = QColor(47, 49, 45),
.inverse_primary = QColor(56, 106, 32),
// Surface steps for Dark Theme
.surface_container_highest = QColor(60, 65, 60), // Surface 4
.surface_container_high = QColor(49, 54, 49), // Surface 3
.surface_container = QColor(38, 43, 37), // Surface 2
.surface_container_low = QColor(34, 37, 33), // Surface 1
.surface_container_lowest = QColor(15, 20, 12), // Surface 0
};
// 橄榄绿主题包
constexpr auto kGreenThemePack = ThemePack {
.light = kGreenLightColorScheme,
.dark = kGreenDarkColorScheme,
};
}

View File

@@ -0,0 +1,72 @@
#include "creeper-qt/utility/theme/theme.hh"
using namespace creeper::theme;
using Handler = ThemeManager::Handler;
struct ThemeManager::Impl {
using Key = const QObject*;
std::unordered_map<Key, Handler> handlers;
std::vector<Handler> begin_callbacks;
std::vector<Handler> final_callbacks;
ThemePack theme_pack;
ColorMode color_mode;
auto apply_theme(const ThemeManager& manager) const {
for (auto const& callback : begin_callbacks)
callback(manager);
for (auto& [_, callback] : handlers)
callback(manager);
for (auto const& callback : final_callbacks)
callback(manager);
}
auto append_handler(Key key, const Handler& handler) {
handlers[key] = handler;
QObject::connect(key, &QObject::destroyed, [this, key] { remove_handler(key); });
}
void remove_handler(Key key) { handlers.erase(key); }
};
ThemeManager::ThemeManager()
: pimpl(std::make_unique<Impl>()) { }
ThemeManager::ThemeManager(const ThemePack& pack, ColorMode mode)
: pimpl(std::make_unique<Impl>()) {
pimpl->theme_pack = pack;
pimpl->color_mode = mode;
}
ThemeManager::~ThemeManager() = default;
void ThemeManager::apply_theme() const { pimpl->apply_theme(*this); }
void ThemeManager::append_handler(const QObject* key, const Handler& handler) {
pimpl->append_handler(key, handler);
}
auto ThemeManager::append_begin_callback(const Handler& callback) noexcept -> void {
pimpl->begin_callbacks.push_back(callback);
}
auto ThemeManager::append_final_callback(const Handler& callback) noexcept -> void {
pimpl->final_callbacks.push_back(callback);
}
void ThemeManager::remove_handler(const QObject* key) { pimpl->remove_handler(key); }
void ThemeManager::set_theme_pack(const ThemePack& pack) { pimpl->theme_pack = pack; }
void ThemeManager::set_color_mode(const ColorMode& mode) { pimpl->color_mode = mode; }
void ThemeManager::toggle_color_mode() {
pimpl->color_mode = (pimpl->color_mode == ColorMode::LIGHT) //
? ColorMode::DARK
: ColorMode::LIGHT;
}
ThemePack ThemeManager::theme_pack() const { return pimpl->theme_pack; }
ColorMode ThemeManager::color_mode() const { return pimpl->color_mode; }
ColorScheme ThemeManager::color_scheme() const {
return pimpl->theme_pack.color_scheme(pimpl->color_mode);
}

View File

@@ -0,0 +1,112 @@
#pragma once
#include <qwidget.h>
#include "creeper-qt/utility/theme/color-scheme.hh"
#include "creeper-qt/utility/wrapper/common.hh"
#include "creeper-qt/utility/wrapper/pimpl.hh"
#include "creeper-qt/utility/wrapper/property.hh"
namespace creeper::theme {
class ThemeManager;
template <class T>
concept color_scheme_setter_trait = requires(T t) {
{ t.set_color_scheme(ColorScheme {}) };
};
template <class T>
concept theme_manager_loader_trait =
requires(T t, ThemeManager& manager) { t.load_theme_manager(manager); };
struct ThemePack {
ColorScheme light, dark;
auto color_scheme(this auto&& self, ColorMode mode) noexcept {
return (mode == ColorMode::LIGHT) ? self.light : self.dark;
}
};
class ThemeManager {
CREEPER_PIMPL_DEFINITION(ThemeManager)
public:
explicit ThemeManager(const ThemePack& pack, ColorMode mode = ColorMode::LIGHT);
void apply_theme() const;
using Handler = std::function<void(const ThemeManager&)>;
/// Registers a theme change callback for the specified widget.
///
/// When ThemeManager::apply_theme() is called, the registered handler will be executed.
///
/// Args:
/// key: Pointer to the widget. Serves as the key in the handler map.
/// handler: The callback function to register.
///
/// Note:
/// When the widget is destroyed, ThemeManager::remove_handler() will be called automatically
/// to remove the associated handler.
void append_handler(const QObject* key, const Handler& handler);
auto append_handler(color_scheme_setter_trait auto& widget) { append_handler(&widget, widget); }
auto append_handler(const QObject* key, color_scheme_setter_trait auto& widget) {
const auto handler = [&widget](const ThemeManager& manager) {
const auto color_mode = manager.color_mode();
const auto theme_pack = manager.theme_pack();
widget.set_color_scheme(theme_pack.color_scheme(color_mode));
};
append_handler(key, std::move(handler));
}
auto append_begin_callback(const Handler&) noexcept -> void;
auto append_final_callback(const Handler&) noexcept -> void;
void remove_handler(const QObject* key);
void set_theme_pack(const ThemePack& pack);
void set_color_mode(const ColorMode& mode);
void toggle_color_mode();
ThemePack theme_pack() const;
ColorMode color_mode() const;
ColorScheme color_scheme() const;
};
}
namespace creeper::theme::pro {
using Token = common::Token<ThemeManager>;
struct ColorScheme : public theme::ColorScheme, Token {
using theme::ColorScheme::ColorScheme;
explicit ColorScheme(const theme::ColorScheme& p)
: theme::ColorScheme(p) { }
auto apply(color_scheme_setter_trait auto& self) const noexcept -> void {
self.set_color_scheme(*this);
}
};
struct ThemeManager : Token {
theme::ThemeManager& manager;
explicit ThemeManager(theme::ThemeManager& p)
: manager(p) { }
auto apply(theme_manager_loader_trait auto& self) const noexcept -> void {
self.load_theme_manager(manager);
}
};
template <typename T>
concept trait = std::derived_from<T, Token>;
CREEPER_DEFINE_CHECKER(trait);
}
namespace creeper {
using ColorMode = theme::ColorMode;
using ColorScheme = theme::ColorScheme;
using ThemePack = theme::ThemePack;
using ThemeManager = theme::ThemeManager;
}