Files
VoiletMark/src/ThemeManager.h
T
liyepan 233d732604 feat: v0.8.0 —— 修复围栏空行断状态,代码块改为真正的语法高亮
修复
- highlightBlock 遇到空行直接 return,把围栏状态重置了:代码块中间只要有一条
  空行,后面的行就不再按代码处理(这正是 #include 之后代码变回普通文本的原因)
- 空行现在会延续围栏状态;闭合围栏行也不再被误判成新的开围栏

语法高亮
- 新增 CodeHighlight:自己写的轻量 tokenizer,不依赖第三方库
- 支持 C / C++ / Python / JavaScript / TypeScript / Java / Rust / Go /
  JSON / Bash / SQL / YAML,按 info string 识别
- 关键字、类型、字符串、数字、行/块注释(支持跨行)、C/C++ 预处理指令分色
- 围栏行在源码模式下改成灰色标记色,不再是代码红
- 编辑模式与源代码模式共用同一套 token 着色

其它
- 主题新增 5 个代码 token 颜色(浅色 / 深色各一套)
- 版本 0.8.0,README 补充支持语言
2026-10-22 18:14:34 +08:00

124 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <QColor>
#include <QObject>
class QTimer;
/// 一份完整的主题配色。界面控件与语法高亮共用同一套颜色,
/// 切换方案时只需要重建这一个结构体。
struct ThemeColors
{
// 窗口与控件
QColor window;
QColor windowText;
QColor base;
QColor alternateBase;
QColor text;
QColor button;
QColor buttonText;
QColor border;
QColor accent;
QColor highlight;
QColor highlightedText;
QColor disabled;
QColor placeholder;
QColor menuBackground;
QColor scrollHandle;
QColor scrollHandleHover;
QColor sidebarBackground;
QColor hoverBackground;
// 编辑器
QColor editorBase;
QColor editorText;
QColor gutterBackground;
QColor gutterText;
QColor gutterActiveText;
QColor currentLine;
// Markdown 语法
QColor heading;
QColor headingMarker;
QColor strong;
QColor emphasis;
QColor code;
QColor codeBackground;
QColor codeKeyword;
QColor codeString;
QColor codeNumber;
QColor codeComment;
QColor codePreprocessor;
QColor link;
QColor linkUrl;
QColor quote;
QColor quoteMarker;
QColor listMarker;
QColor rule;
QColor taskDone;
};
/// 负责“跟随系统自动切换浅色 / 深色主题”。
///
/// 四种模式:跟随系统 / 浅色 / 深色 / 按时段自动(6:00 起浅色、18:00 起深色)。
/// 跟随系统时的检测顺序:显式覆盖(环境变量 / 命令行)→ 平台自身设置
/// (Windows 注册表、macOS defaults、Linux 的 KDE / GTK / XFCE / gsettings)
/// → 启动时的调色板亮度兜底。
/// 每 2 秒轮询一次,变化后立即重绘整个界面。
class ThemeManager : public QObject
{
Q_OBJECT
public:
enum class Mode { System, Light, Dark, Schedule };
enum class Scheme { Light, Dark };
static ThemeManager *instance();
/// 由 main() 在 QApplication 之后调用一次。
void initialize(Mode forcedMode, bool persist);
Mode mode() const { return m_mode; }
void setMode(Mode mode, bool persist = true);
Scheme scheme() const { return m_scheme; }
const ThemeColors &colors() const { return m_colors; }
static QString modeToString(Mode mode);
static Mode modeFromString(const QString &value, bool *ok = nullptr);
static QString modeLabel(Mode mode);
signals:
void schemeChanged(ThemeManager::Scheme scheme);
private slots:
void pollSystemTheme();
private:
explicit ThemeManager(QObject *parent = nullptr);
void applyScheme(Scheme scheme, bool force);
void buildColors(Scheme scheme);
void applyToApplication();
QString styleSheet() const;
Scheme detectSystemScheme() const;
/// 6:00–18:00 浅色,其余时间深色。
Scheme scheduleScheme() const;
Scheme schemeForMode(Mode mode) const;
Mode m_mode = Mode::System;
Scheme m_scheme = Scheme::Light;
ThemeColors m_colors;
QTimer *m_pollTimer = nullptr;
/// 启动时读取的 QPalette 亮度,作为所有检测手段失败后的兜底。
Scheme m_paletteGuess = Scheme::Light;
/// gsettings 调用比较昂贵,做一次短时缓存。
mutable qint64 m_lastGsettingsCheck = 0;
mutable QString m_cachedColorScheme;
mutable QString m_cachedGtkTheme;
};