From dcd1fccaeda3629c0530642e4d391040851219b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 23:17:15 +0000 Subject: [PATCH] Add comprehensive dark theme documentation Co-authored-by: 78 <4488133+78@users.noreply.github.com> --- README.md | 1 + README_en.md | 1 + README_ja.md | 1 + docs/dark-theme.md | 337 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 docs/dark-theme.md diff --git a/README.md b/README.md index 9026ec9f..65a0b248 100644 --- a/README.md +++ b/README.md @@ -122,6 +122,7 @@ v1 的稳定版本为 1.9.2,可以通过 `git checkout v1` 来切换到 v1 版 ### 开发者文档 - [自定义开发板指南](docs/custom-board.md) - 学习如何为小智 AI 创建自定义开发板 +- [深色主题配置](docs/dark-theme.md) - 了解如何配置和使用深色主题 - [MCP 协议物联网控制用法说明](docs/mcp-usage.md) - 了解如何通过 MCP 协议控制物联网设备 - [MCP 协议交互流程](docs/mcp-protocol.md) - 设备端 MCP 协议的实现方式 - [MQTT + UDP 混合通信协议文档](docs/mqtt-udp.md) diff --git a/README_en.md b/README_en.md index d3ad0f05..d26a1996 100644 --- a/README_en.md +++ b/README_en.md @@ -122,6 +122,7 @@ The firmware connects to the official [xiaozhi.me](https://xiaozhi.me) server by ### Developer Documentation - [Custom Board Guide](docs/custom-board.md) - Learn how to create custom boards for XiaoZhi AI +- [Dark Theme Configuration](docs/dark-theme.md) - Learn how to configure and use dark theme - [MCP Protocol IoT Control Usage](docs/mcp-usage.md) - Learn how to control IoT devices via MCP protocol - [MCP Protocol Interaction Flow](docs/mcp-protocol.md) - Device-side MCP protocol implementation - [MQTT + UDP Hybrid Communication Protocol Document](docs/mqtt-udp.md) diff --git a/README_ja.md b/README_ja.md index c7dd029e..e5aaa8f3 100644 --- a/README_ja.md +++ b/README_ja.md @@ -122,6 +122,7 @@ Feishuドキュメントチュートリアルをご覧ください: ### 開発者ドキュメント - [カスタム開発ボードガイド](docs/custom-board.md) - シャオジーAI用のカスタム開発ボード作成方法 +- [ダークテーマ設定](docs/dark-theme.md) - ダークテーマの設定と使用方法 - [MCPプロトコルIoT制御使用法](docs/mcp-usage.md) - MCPプロトコルでIoTデバイスを制御する方法 - [MCPプロトコルインタラクションフロー](docs/mcp-protocol.md) - デバイス側MCPプロトコルの実装方法 - [MQTT + UDP ハイブリッド通信プロトコルドキュメント](docs/mqtt-udp.md) diff --git a/docs/dark-theme.md b/docs/dark-theme.md new file mode 100644 index 00000000..53cf9447 --- /dev/null +++ b/docs/dark-theme.md @@ -0,0 +1,337 @@ +# Dark Theme Configuration + +[English](#english) | [中文](#中文) + +--- + +## English + +### Overview + +The Xiaozhi ESP32 project includes a built-in theme system with two available themes: +- **Light Theme** (default) +- **Dark Theme** + +The theme setting is stored in the device's NVS (Non-Volatile Storage) and persists across reboots. + +### Available Themes + +#### Light Theme +- Background: White (`#FFFFFF`) +- Text: Black (`#000000`) +- Chat Background: Light Gray (`#E0E0E0`) +- User Bubble: Green (`#00FF00`) +- Assistant Bubble: Light Gray (`#DDDDDD`) +- Border: Black (`#000000`) + +#### Dark Theme +- Background: Black (`#000000`) +- Text: White (`#FFFFFF`) +- Chat Background: Dark Gray (`#1F1F1F`) +- User Bubble: Green (`#00FF00`) +- Assistant Bubble: Dark Gray (`#222222`) +- Border: White (`#FFFFFF`) +- Low Battery: Red (`#FF0000`) + +### How Themes Work + +The theme system is implemented in the display layer: +- Theme configuration is defined in `main/display/lcd_display.cc` +- Theme preference is stored in NVS under the namespace `"display"` with key `"theme"` +- Default theme is `"light"` if no NVS value exists +- Themes are registered with the `LvglThemeManager` at initialization + +### Setting Dark Theme as Default + +There are several ways to set the dark theme as default: + +#### Method 1: Via MCP Protocol (Recommended) + +If your device supports MCP (Model Context Protocol), you can change the theme using the `self.screen.set_theme` tool: + +```json +{ + "theme": "dark" +} +``` + +This will immediately switch to dark theme and save the preference to NVS. + +#### Method 2: Modify NVS Partition Before Flashing + +1. Create or modify an NVS partition CSV file with the theme setting: + +```csv +key,type,encoding,value +display,namespace,, +theme,data,string,dark +``` + +2. Generate the NVS binary: + +```bash +python $IDF_PATH/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate nvs.csv nvs.bin 0x4000 +``` + +3. Flash the NVS partition to your device: + +```bash +esptool.py --chip esp32s3 --port /dev/ttyUSB0 write_flash 0x9000 nvs.bin +``` + +**Note:** The NVS partition address (`0x9000`) may vary depending on your board's partition table. Check your `partitions.csv` file for the correct address. + +#### Method 3: Modify NVS at Runtime + +You can modify the NVS storage programmatically by adding code to set the theme preference during initialization: + +```cpp +#include "settings.h" + +// In your initialization code +Settings settings("display", true); +settings.SetString("theme", "dark"); +``` + +#### Method 4: Modify Default in Source Code + +If you want to change the default theme in the source code, modify `main/display/lcd_display.cc`: + +```cpp +// Find this line (around line 74): +std::string theme_name = settings.GetString("theme", "light"); + +// Change the default from "light" to "dark": +std::string theme_name = settings.GetString("theme", "dark"); +``` + +Then rebuild and flash the firmware. + +### Why No Menuconfig Option? + +The theme setting is implemented as a runtime configuration stored in NVS rather than a compile-time configuration. This design choice allows: + +1. **Runtime Changes**: Users can switch themes without reflashing firmware +2. **User Preferences**: Each device can maintain its own theme preference +3. **Remote Control**: Themes can be changed via MCP protocol or other remote interfaces +4. **Persistence**: Theme preference survives firmware updates (when NVS partition is preserved) + +If a menuconfig option is desired, it could be added to set the **default** theme when NVS is empty, but the current architecture favors runtime configurability. + +### Implementation Details + +The theme system consists of several components: + +1. **Theme Base Class** (`main/display/display.h`) + - Abstract base class for all themes + - Stores theme name + +2. **LvglTheme Class** (`main/display/lvgl_display/lvgl_theme.h`) + - Implements theme for LVGL-based displays + - Stores colors, fonts, and styling information + +3. **LvglThemeManager** (`main/display/lvgl_display/lvgl_theme.h`) + - Singleton manager for registered themes + - Provides theme lookup by name + +4. **Settings Class** (`main/settings.h`) + - Wrapper for NVS storage operations + - Handles reading/writing theme preferences + +5. **Display Initialization** (`main/display/lcd_display.cc`) + - Registers available themes + - Loads theme preference from NVS + - Applies theme to display + +### Troubleshooting + +#### Theme doesn't persist after reboot +- Ensure NVS partition is properly initialized +- Check that the NVS partition is not being erased during flash operations +- Verify Settings class is opened with `read_write = true` when setting values + +#### Dark theme not available +- Verify your board uses LCD display (themes are not implemented for OLED displays) +- Check that `InitializeLcdThemes()` is being called during display initialization +- Ensure you're using a recent version of the firmware + +#### Cannot change theme via MCP +- Verify MCP protocol is enabled and working +- Check that your display supports the theme system (should have `GetTheme() != nullptr`) +- Review MCP server logs for errors + +### Future Enhancements + +Possible future improvements to the theme system: +- Custom themes loaded from assets partition +- Additional built-in themes +- Per-element theme customization via MCP +- Theme preview before applying +- Automatic theme switching based on time of day + +--- + +## 中文 + +### 概述 + +小智 ESP32 项目内置了主题系统,提供两种可用主题: +- **浅色主题**(默认) +- **深色主题** + +主题设置存储在设备的 NVS(非易失性存储)中,重启后保持不变。 + +### 可用主题 + +#### 浅色主题 +- 背景:白色 (`#FFFFFF`) +- 文本:黑色 (`#000000`) +- 聊天背景:浅灰色 (`#E0E0E0`) +- 用户气泡:绿色 (`#00FF00`) +- 助手气泡:浅灰色 (`#DDDDDD`) +- 边框:黑色 (`#000000`) + +#### 深色主题 +- 背景:黑色 (`#000000`) +- 文本:白色 (`#FFFFFF`) +- 聊天背景:深灰色 (`#1F1F1F`) +- 用户气泡:绿色 (`#00FF00`) +- 助手气泡:深灰色 (`#222222`) +- 边框:白色 (`#FFFFFF`) +- 低电量:红色 (`#FF0000`) + +### 主题工作原理 + +主题系统在显示层实现: +- 主题配置定义在 `main/display/lcd_display.cc` +- 主题偏好存储在 NVS 中,命名空间为 `"display"`,键为 `"theme"` +- 如果 NVS 中没有值,默认主题为 `"light"` +- 主题在初始化时注册到 `LvglThemeManager` + +### 将深色主题设置为默认 + +有几种方法可以将深色主题设置为默认: + +#### 方法 1:通过 MCP 协议(推荐) + +如果您的设备支持 MCP(模型上下文协议),可以使用 `self.screen.set_theme` 工具更改主题: + +```json +{ + "theme": "dark" +} +``` + +这将立即切换到深色主题并将偏好保存到 NVS。 + +#### 方法 2:烧录前修改 NVS 分区 + +1. 创建或修改带有主题设置的 NVS 分区 CSV 文件: + +```csv +key,type,encoding,value +display,namespace,, +theme,data,string,dark +``` + +2. 生成 NVS 二进制文件: + +```bash +python $IDF_PATH/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate nvs.csv nvs.bin 0x4000 +``` + +3. 将 NVS 分区烧录到设备: + +```bash +esptool.py --chip esp32s3 --port /dev/ttyUSB0 write_flash 0x9000 nvs.bin +``` + +**注意:** NVS 分区地址(`0x9000`)可能因开发板的分区表而异。请检查您的 `partitions.csv` 文件以获取正确的地址。 + +#### 方法 3:运行时修改 NVS + +您可以通过编程方式修改 NVS 存储,在初始化期间添加代码来设置主题偏好: + +```cpp +#include "settings.h" + +// 在初始化代码中 +Settings settings("display", true); +settings.SetString("theme", "dark"); +``` + +#### 方法 4:修改源代码中的默认值 + +如果您想在源代码中更改默认主题,请修改 `main/display/lcd_display.cc`: + +```cpp +// 找到这一行(大约在第 74 行): +std::string theme_name = settings.GetString("theme", "light"); + +// 将默认值从 "light" 改为 "dark": +std::string theme_name = settings.GetString("theme", "dark"); +``` + +然后重新构建并烧录固件。 + +### 为什么没有 Menuconfig 选项? + +主题设置作为运行时配置存储在 NVS 中,而不是编译时配置。这种设计选择的优点: + +1. **运行时更改**:用户可以在不重新烧录固件的情况下切换主题 +2. **用户偏好**:每个设备可以保持自己的主题偏好 +3. **远程控制**:可以通过 MCP 协议或其他远程接口更改主题 +4. **持久性**:主题偏好在固件更新时保留(当 NVS 分区被保留时) + +如果需要 menuconfig 选项,可以添加一个选项来设置 NVS 为空时的**默认**主题,但当前架构更倾向于运行时可配置性。 + +### 实现细节 + +主题系统由几个组件组成: + +1. **主题基类** (`main/display/display.h`) + - 所有主题的抽象基类 + - 存储主题名称 + +2. **LvglTheme 类** (`main/display/lvgl_display/lvgl_theme.h`) + - 为基于 LVGL 的显示器实现主题 + - 存储颜色、字体和样式信息 + +3. **LvglThemeManager** (`main/display/lvgl_display/lvgl_theme.h`) + - 已注册主题的单例管理器 + - 按名称提供主题查找 + +4. **Settings 类** (`main/settings.h`) + - NVS 存储操作的包装器 + - 处理主题偏好的读写 + +5. **显示初始化** (`main/display/lcd_display.cc`) + - 注册可用主题 + - 从 NVS 加载主题偏好 + - 将主题应用到显示器 + +### 故障排除 + +#### 重启后主题不保持 +- 确保 NVS 分区已正确初始化 +- 检查在烧录操作期间 NVS 分区未被擦除 +- 验证设置值时 Settings 类以 `read_write = true` 打开 + +#### 深色主题不可用 +- 验证您的开发板使用 LCD 显示器(主题未针对 OLED 显示器实现) +- 检查在显示初始化期间是否调用了 `InitializeLcdThemes()` +- 确保您使用的是最新版本的固件 + +#### 无法通过 MCP 更改主题 +- 验证 MCP 协议已启用并正常工作 +- 检查您的显示器支持主题系统(应该有 `GetTheme() != nullptr`) +- 查看 MCP 服务器日志中的错误 + +### 未来增强 + +主题系统可能的未来改进: +- 从资源分区加载自定义主题 +- 额外的内置主题 +- 通过 MCP 进行逐元素主题自定义 +- 应用前的主题预览 +- 基于时间的自动主题切换