✨ 新增: 添加自定义主题设置相关函数
parent
0a57dae39c
commit
57cac6a451
|
@ -5,7 +5,26 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <imgui.h>
|
|
||||||
|
#include "imgui.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct LogColors {
|
||||||
|
ImVec4 error_color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f);
|
||||||
|
ImVec4 warn_color = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||||
|
ImVec4 info_color = ImVec4(0.4f, 1.0f, 0.4f, 1.0f);
|
||||||
|
ImVec4 debug_color = ImVec4(0.6f, 0.6f, 1.0f, 1.0f);
|
||||||
|
ImVec4 trace_color = ImVec4(0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
|
||||||
|
void ResetToDefaults() {
|
||||||
|
error_color = ImVec4(1.0f, 0.4f, 0.4f, 1.0f);
|
||||||
|
warn_color = ImVec4(1.0f, 1.0f, 0.4f, 1.0f);
|
||||||
|
info_color = ImVec4(0.4f, 1.0f, 0.4f, 1.0f);
|
||||||
|
debug_color = ImVec4(0.6f, 0.6f, 1.0f, 1.0f);
|
||||||
|
trace_color = ImVec4(0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class AppState {
|
class AppState {
|
||||||
public:
|
public:
|
||||||
|
@ -50,8 +69,12 @@ public:
|
||||||
std::vector<std::string> command_history;
|
std::vector<std::string> command_history;
|
||||||
int max_command_history;
|
int max_command_history;
|
||||||
|
|
||||||
|
LogColors log_colors;
|
||||||
|
bool use_custom_log_colors = false;
|
||||||
|
bool use_ansi_colors = true;
|
||||||
bool settings_dirty;
|
bool settings_dirty;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 环境变量序列化辅助函数
|
// 环境变量序列化辅助函数
|
||||||
std::string SerializeEnvironmentVariables() const;
|
std::string SerializeEnvironmentVariables() const;
|
||||||
|
@ -60,8 +83,11 @@ private:
|
||||||
// 编码序列化辅助函数
|
// 编码序列化辅助函数
|
||||||
std::string SerializeOutputEncoding() const;
|
std::string SerializeOutputEncoding() const;
|
||||||
void DeserializeOutputEncoding(const std::string& serialized);
|
void DeserializeOutputEncoding(const std::string& serialized);
|
||||||
|
// 日志颜色序列化辅助
|
||||||
|
std::string SerializeLogColors() const;
|
||||||
|
void DeserializeLogColors(const std::string &serialized);
|
||||||
|
|
||||||
// 新增:命令历史记录序列化辅助函数
|
// 命令历史记录序列化辅助函数
|
||||||
std::string SerializeCommandHistory() const;
|
std::string SerializeCommandHistory() const;
|
||||||
void DeserializeCommandHistory(const std::string& serialized);
|
void DeserializeCommandHistory(const std::string& serialized);
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "AppState.h"
|
#include "AppState.h"
|
||||||
#include "TrayIcon.h"
|
#include "TrayIcon.h"
|
||||||
|
|
||||||
|
|
||||||
class Manager {
|
class Manager {
|
||||||
public:
|
public:
|
||||||
// 构造函数和析构函数
|
// 构造函数和析构函数
|
||||||
|
@ -45,59 +46,68 @@ public:
|
||||||
~Manager();
|
~Manager();
|
||||||
|
|
||||||
// 核心生命周期管理
|
// 核心生命周期管理
|
||||||
bool Initialize(); // 初始化应用程序
|
bool Initialize(); // 初始化应用程序
|
||||||
void Run(); // 运行主循环
|
void Run(); // 运行主循环
|
||||||
void Shutdown(); // 关闭应用程序
|
void Shutdown(); // 关闭应用程序
|
||||||
|
|
||||||
// 托盘事件回调
|
// 托盘事件回调
|
||||||
void OnTrayShowWindow(); // 托盘显示窗口事件
|
void OnTrayShowWindow(); // 托盘显示窗口事件
|
||||||
void OnTrayExit(); // 托盘退出事件
|
void OnTrayExit(); // 托盘退出事件
|
||||||
|
|
||||||
// 公共成员变量
|
// 公共成员变量
|
||||||
AppState m_app_state; // 应用程序状态
|
AppState m_app_state; // 应用程序状态
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 枚举类型定义
|
// 枚举类型定义
|
||||||
enum class LayoutPreset {
|
enum class LayoutPreset {
|
||||||
Classic, // 经典布局
|
Classic, // 经典布局
|
||||||
Development, // 开发布局
|
Development, // 开发布局
|
||||||
Monitoring // 监控布局
|
Monitoring // 监控布局
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// UI渲染相关方法
|
// UI渲染相关方法
|
||||||
void RenderUI(); // 渲染主UI
|
void RenderUI(); // 渲染主UI
|
||||||
void RenderMenuBar(); // 渲染菜单栏
|
void RenderMenuBar(); // 渲染菜单栏
|
||||||
void RenderMainContent(); // 渲染主内容区域
|
void RenderMainContent(); // 渲染主内容区域
|
||||||
void RenderSettingsMenu(); // 渲染设置菜单
|
|
||||||
void RenderStopCommandSettings(); // 渲染停止命令设置
|
|
||||||
void RenderEnvironmentVariablesSettings(); // 渲染环境变量设置
|
void RenderSettingsMenu(); // 渲染设置菜单
|
||||||
void RenderOutputEncodingSettings(); // 渲染输出编码设置
|
void RenderStopCommandSettings(); // 渲染停止命令设置
|
||||||
void RenderControlPanel(float buttonWidth, float buttonHeight, float inputWidth); // 渲染控制面板
|
void RenderEnvironmentVariablesSettings(); // 渲染环境变量设置
|
||||||
void RenderCommandPanel(float buttonWidth, float inputWidth); // 渲染命令面板
|
void RenderOutputEncodingSettings(); // 渲染输出编码设置
|
||||||
void RenderLogPanel(); // 渲染日志面板
|
void RenderColorThemeSettings();
|
||||||
void RenderCommandHistory(); // 渲染命令历史
|
|
||||||
void RenderStatusMessages(); // 渲染状态消息
|
void RenderControlPanel(float buttonWidth, float buttonHeight, float inputWidth); // 渲染控制面板
|
||||||
|
void RenderCommandPanel(float buttonWidth, float inputWidth); // 渲染命令面板
|
||||||
|
void RenderLogPanel(); // 渲染日志面板
|
||||||
|
void RenderCommandHistory(); // 渲染命令历史
|
||||||
|
void RenderStatusMessages(); // 渲染状态消息
|
||||||
|
|
||||||
// 布局管理相关方法
|
// 布局管理相关方法
|
||||||
void SetupDefaultDockingLayout(ImGuiID dockspace_id); // 设置默认停靠布局
|
void SetupDefaultDockingLayout(ImGuiID dockspace_id); // 设置默认停靠布局
|
||||||
void RenderLayoutMenu(); // 渲染布局菜单
|
void RenderLayoutMenu(); // 渲染布局菜单
|
||||||
static void ApplyPresetLayout(LayoutPreset preset); // 应用预设布局
|
static void ApplyPresetLayout(LayoutPreset preset); // 应用预设布局
|
||||||
void SaveCurrentLayout(); // 保存当前布局
|
void SaveCurrentLayout(); // 保存当前布局
|
||||||
void LoadSavedLayout(); // 加载已保存布局
|
void LoadSavedLayout(); // 加载已保存布局
|
||||||
|
|
||||||
// 事件处理相关方法
|
// 事件处理相关方法
|
||||||
void HandleMessages(); // 处理消息
|
void HandleMessages(); // 处理消息
|
||||||
bool ShouldExit() const; // 检查是否应该退出
|
bool ShouldExit() const; // 检查是否应该退出
|
||||||
static void ContentScaleCallback(GLFWwindow *window, float xscale, float yscale); // 内容缩放回调
|
static void ContentScaleCallback(GLFWwindow *window, float xscale, float yscale); // 内容缩放回调
|
||||||
|
|
||||||
// 窗口管理相关方法
|
// 窗口管理相关方法
|
||||||
void ShowMainWindow(); // 显示主窗口
|
void ShowMainWindow(); // 显示主窗口
|
||||||
void HideMainWindow(); // 隐藏主窗口
|
void HideMainWindow(); // 隐藏主窗口
|
||||||
|
|
||||||
// DPI相关方法
|
// DPI相关方法
|
||||||
void UpdateDPIScale(); // 更新DPI缩放
|
void UpdateDPIScale(); // 更新DPI缩放
|
||||||
void ReloadFonts() const; // 重新加载字体
|
void ReloadFonts() const; // 重新加载字体
|
||||||
|
|
||||||
|
void SaveCurrentTheme();
|
||||||
|
void LoadSavedTheme();
|
||||||
|
|
||||||
|
ImVec4 GetCustomLogLevelColor(const std::string &log);
|
||||||
|
|
||||||
// 平台相关初始化方法
|
// 平台相关初始化方法
|
||||||
#ifdef USE_WIN32_BACKEND
|
#ifdef USE_WIN32_BACKEND
|
||||||
|
@ -108,17 +118,17 @@ private:
|
||||||
static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 窗口过程
|
static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 窗口过程
|
||||||
#else
|
#else
|
||||||
|
|
||||||
bool InitializeGLFW(); // 初始化GLFW
|
bool InitializeGLFW(); // 初始化GLFW
|
||||||
void CleanupGLFW(); // 清理GLFW
|
void CleanupGLFW(); // 清理GLFW
|
||||||
static void GlfwErrorCallback(int error, const char *description); // GLFW错误回调
|
static void GlfwErrorCallback(int error, const char *description); // GLFW错误回调
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 托盘相关方法
|
// 托盘相关方法
|
||||||
bool InitializeTray(); // 初始化托盘
|
bool InitializeTray(); // 初始化托盘
|
||||||
void CleanupTray(); // 清理托盘
|
void CleanupTray(); // 清理托盘
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
static HWND CreateHiddenWindow(); // 创建隐藏窗口
|
static HWND CreateHiddenWindow(); // 创建隐藏窗口
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 平台相关成员变量
|
// 平台相关成员变量
|
||||||
|
@ -130,41 +140,47 @@ private:
|
||||||
IDXGISwapChain* m_pSwapChain = nullptr; // 交换链
|
IDXGISwapChain* m_pSwapChain = nullptr; // 交换链
|
||||||
ID3D11RenderTargetView* m_mainRenderTargetView = nullptr; // 主渲染目标视图
|
ID3D11RenderTargetView* m_mainRenderTargetView = nullptr; // 主渲染目标视图
|
||||||
#else
|
#else
|
||||||
GLFWwindow *m_window = nullptr; // GLFW窗口
|
GLFWwindow *m_window = nullptr; // GLFW窗口
|
||||||
const char *m_glsl_version = nullptr; // GLSL版本
|
const char *m_glsl_version = nullptr; // GLSL版本
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 托盘相关成员变量
|
// 托盘相关成员变量
|
||||||
std::unique_ptr<TrayIcon> m_tray; // 托盘图标
|
std::unique_ptr<TrayIcon> m_tray; // 托盘图标
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
HWND m_tray_hwnd = nullptr; // 托盘窗口句柄
|
HWND m_tray_hwnd = nullptr; // 托盘窗口句柄
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 控制标志
|
// 控制标志
|
||||||
bool m_should_exit = false; // 是否应该退出
|
bool m_should_exit = false; // 是否应该退出
|
||||||
bool m_initialized = false; // 是否已初始化
|
bool m_initialized = false; // 是否已初始化
|
||||||
bool m_fullscreen = false;
|
bool m_fullscreen = false;
|
||||||
bool m_padding = false;
|
bool m_padding = false;
|
||||||
// DPI缩放相关
|
// DPI缩放相关
|
||||||
float m_dpi_scale = 1.0f; // 当前DPI缩放
|
float m_dpi_scale = 1.0f; // 当前DPI缩放
|
||||||
float m_last_dpi_scale = 1.0f; // 上次DPI缩放
|
float m_last_dpi_scale = 1.0f; // 上次DPI缩放
|
||||||
|
|
||||||
// 布局相关成员变量
|
// 布局相关成员变量
|
||||||
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_None;
|
||||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||||
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_MenuBar;
|
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_MenuBar;
|
||||||
bool m_apply_preset_layout = false; // 是否需要应用预设布局
|
bool m_apply_preset_layout = false; // 是否需要应用预设布局
|
||||||
LayoutPreset m_pending_preset = LayoutPreset::Classic; // 待应用的预设布局
|
LayoutPreset m_pending_preset = LayoutPreset::Classic; // 待应用的预设布局
|
||||||
bool m_reset_layout = false; // 是否重置布局
|
bool m_reset_layout = false; // 是否重置布局
|
||||||
bool m_show_save_success = false; // 是否显示保存成功消息
|
bool m_show_save_success = false; // 是否显示保存成功消息
|
||||||
bool m_show_load_success = false; // 是否显示加载成功消息
|
bool m_show_load_success = false; // 是否显示加载成功消息
|
||||||
float m_save_success_timer = 0.0f; // 保存成功消息计时器
|
float m_save_success_timer = 0.0f; // 保存成功消息计时器
|
||||||
float m_load_success_timer = 0.0f; // 加载成功消息计时器
|
float m_load_success_timer = 0.0f; // 加载成功消息计时器
|
||||||
|
|
||||||
// UI状态相关成员变量
|
// UI状态相关成员变量
|
||||||
char env_key_input_[256] = {}; // 环境变量键输入缓冲区
|
char env_key_input_[256] = {}; // 环境变量键输入缓冲区
|
||||||
char env_value_input_[512] = {}; // 环境变量值输入缓冲区
|
char env_value_input_[512] = {}; // 环境变量值输入缓冲区
|
||||||
bool show_env_settings_ = false; // 是否显示环境变量设置
|
bool show_env_settings_ = false; // 是否显示环境变量设置
|
||||||
bool show_encoding_settings_ = false; // 是否显示编码设置
|
bool show_encoding_settings_ = false; // 是否显示编码设置
|
||||||
bool show_command_history_ = false; // 是否显示命令历史
|
bool show_command_history_ = false; // 是否显示命令历史
|
||||||
|
|
||||||
|
bool m_show_theme_save_success = true;
|
||||||
|
float m_theme_save_success_timer = 3.0f;
|
||||||
|
|
||||||
|
float m_theme_load_success_timer = 0.0f;
|
||||||
|
bool m_show_theme_load_success = false;
|
||||||
};
|
};
|
||||||
|
|
|
@ -160,6 +160,82 @@ void AppState::DeserializeOutputEncoding(const std::string& serialized) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AppState::SerializeLogColors() const {
|
||||||
|
std::ostringstream oss;
|
||||||
|
|
||||||
|
// 按顺序保存每个颜色的RGBA值
|
||||||
|
oss << log_colors.error_color.x << ","
|
||||||
|
<< log_colors.error_color.y << ","
|
||||||
|
<< log_colors.error_color.z << ","
|
||||||
|
<< log_colors.error_color.w << "|";
|
||||||
|
|
||||||
|
oss << log_colors.warn_color.x << ","
|
||||||
|
<< log_colors.warn_color.y << ","
|
||||||
|
<< log_colors.warn_color.z << ","
|
||||||
|
<< log_colors.warn_color.w << "|";
|
||||||
|
|
||||||
|
oss << log_colors.info_color.x << ","
|
||||||
|
<< log_colors.info_color.y << ","
|
||||||
|
<< log_colors.info_color.z << ","
|
||||||
|
<< log_colors.info_color.w << "|";
|
||||||
|
|
||||||
|
oss << log_colors.debug_color.x << ","
|
||||||
|
<< log_colors.debug_color.y << ","
|
||||||
|
<< log_colors.debug_color.z << ","
|
||||||
|
<< log_colors.debug_color.w << "|";
|
||||||
|
|
||||||
|
oss << log_colors.trace_color.x << ","
|
||||||
|
<< log_colors.trace_color.y << ","
|
||||||
|
<< log_colors.trace_color.z << ","
|
||||||
|
<< log_colors.trace_color.w;
|
||||||
|
|
||||||
|
return oss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增:反序列化日志颜色
|
||||||
|
void AppState::DeserializeLogColors(const std::string& serialized) {
|
||||||
|
if (serialized.empty()) {
|
||||||
|
log_colors.ResetToDefaults();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istringstream iss(serialized);
|
||||||
|
std::string colorStr;
|
||||||
|
int colorIndex = 0;
|
||||||
|
|
||||||
|
while (std::getline(iss, colorStr, '|') && colorIndex < 5) {
|
||||||
|
std::istringstream colorIss(colorStr);
|
||||||
|
std::string component;
|
||||||
|
float rgba[4] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
while (std::getline(colorIss, component, ',') && i < 4) {
|
||||||
|
try {
|
||||||
|
rgba[i++] = std::stof(component);
|
||||||
|
} catch (const std::exception&) {
|
||||||
|
// 如果解析失败,使用默认值
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec4 color(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||||
|
|
||||||
|
switch (colorIndex) {
|
||||||
|
case 0: log_colors.error_color = color; break;
|
||||||
|
case 1: log_colors.warn_color = color; break;
|
||||||
|
case 2: log_colors.info_color = color; break;
|
||||||
|
case 3: log_colors.debug_color = color; break;
|
||||||
|
case 4: log_colors.trace_color = color; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
colorIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有足够的颜色数据,重置为默认值
|
||||||
|
if (colorIndex < 5) {
|
||||||
|
log_colors.ResetToDefaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AppState::LoadSettings() {
|
void AppState::LoadSettings() {
|
||||||
std::ifstream file("climanager_settings.ini");
|
std::ifstream file("climanager_settings.ini");
|
||||||
if (!file.is_open()) return;
|
if (!file.is_open()) return;
|
||||||
|
@ -234,6 +310,14 @@ void AppState::LoadSettings() {
|
||||||
else if (key == "MaxCommandHistory") {
|
else if (key == "MaxCommandHistory") {
|
||||||
max_command_history = std::stoi(value);
|
max_command_history = std::stoi(value);
|
||||||
max_command_history = std::max(5, std::min(max_command_history, 100));
|
max_command_history = std::max(5, std::min(max_command_history, 100));
|
||||||
|
}else if (key == "UseCustomLogColors") {
|
||||||
|
use_custom_log_colors = (value == "1");
|
||||||
|
}
|
||||||
|
else if (key == "UseAnsiColors") {
|
||||||
|
use_ansi_colors = (value == "1");
|
||||||
|
}
|
||||||
|
else if (key == "LogColors") {
|
||||||
|
DeserializeLogColors(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,6 +355,9 @@ void AppState::SaveSettings() {
|
||||||
file << "CommandHistory=" << SerializeCommandHistory() << "\n";
|
file << "CommandHistory=" << SerializeCommandHistory() << "\n";
|
||||||
file << "MaxCommandHistory=" << max_command_history << "\n";
|
file << "MaxCommandHistory=" << max_command_history << "\n";
|
||||||
|
|
||||||
|
file << "UseCustomLogColors=" << (use_custom_log_colors ? "1" : "0") << "\n";
|
||||||
|
file << "UseAnsiColors=" << (use_ansi_colors ? "1" : "0") << "\n";
|
||||||
|
file << "LogColors=" << SerializeLogColors() << "\n";
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
settings_dirty = false;
|
settings_dirty = false;
|
||||||
|
|
|
@ -28,10 +28,10 @@ bool Manager::Initialize() {
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
ImGuiIO &io = ImGui::GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||||
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||||
io.ConfigViewportsNoAutoMerge = true;
|
io.ConfigViewportsNoAutoMerge = true;
|
||||||
io.IniFilename = "imgui.ini";
|
io.IniFilename = "imgui.ini";
|
||||||
|
|
||||||
|
@ -67,10 +67,10 @@ bool Manager::Initialize() {
|
||||||
// 加载字体
|
// 加载字体
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
ImFont *font = io.Fonts->AddFontFromFileTTF(
|
ImFont *font = io.Fonts->AddFontFromFileTTF(
|
||||||
"C:/Windows/Fonts/msyh.ttc",
|
"C:/Windows/Fonts/msyh.ttc",
|
||||||
16.0f * m_dpi_scale,
|
16.0f * m_dpi_scale,
|
||||||
nullptr,
|
nullptr,
|
||||||
io.Fonts->GetGlyphRangesChineseFull()
|
io.Fonts->GetGlyphRangesChineseFull()
|
||||||
);
|
);
|
||||||
#elif __APPLE__
|
#elif __APPLE__
|
||||||
// macOS 中文字体路径
|
// macOS 中文字体路径
|
||||||
|
@ -113,6 +113,7 @@ bool Manager::Initialize() {
|
||||||
m_app_state.ApplySettings();
|
m_app_state.ApplySettings();
|
||||||
m_app_state.SaveSettings();
|
m_app_state.SaveSettings();
|
||||||
|
|
||||||
|
LoadSavedTheme();
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
m_tray->UpdateWebUrl(StringToWide(m_app_state.web_url));
|
m_tray->UpdateWebUrl(StringToWide(m_app_state.web_url));
|
||||||
|
|
||||||
|
@ -214,7 +215,7 @@ void Manager::RenderUI() {
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||||
ImGuiWindowFlags_NoMove;
|
ImGuiWindowFlags_NoMove;
|
||||||
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
window_flags |= ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
} else {
|
} else {
|
||||||
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
dockspace_flags &= ~ImGuiDockNodeFlags_PassthruCentralNode;
|
||||||
|
@ -226,7 +227,7 @@ void Manager::RenderUI() {
|
||||||
if (!m_padding)
|
if (!m_padding)
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
if (m_fullscreen)
|
if (m_fullscreen)
|
||||||
ImGui::PopStyleVar(2); // Submit the DockSpace
|
ImGui::PopStyleVar(2); // Submit the DockSpace
|
||||||
ImGui::Begin("CLI程序管理工具", &m_app_state.show_main_window,
|
ImGui::Begin("CLI程序管理工具", &m_app_state.show_main_window,
|
||||||
window_flags);
|
window_flags);
|
||||||
|
|
||||||
|
@ -302,9 +303,10 @@ void Manager::RenderMenuBar() {
|
||||||
|
|
||||||
// 添加主题菜单
|
// 添加主题菜单
|
||||||
if (ImGui::BeginMenu("主题")) {
|
if (ImGui::BeginMenu("主题")) {
|
||||||
if (ImGui::MenuItem("暗黑(Dark)")) { ImGui::StyleColorsDark(); }
|
// if (ImGui::MenuItem("暗黑(Dark)")) { ImGui::StyleColorsDark(); }
|
||||||
if (ImGui::MenuItem("明亮(Light)")) { ImGui::StyleColorsLight(); }
|
// if (ImGui::MenuItem("明亮(Light)")) { ImGui::StyleColorsLight(); }
|
||||||
if (ImGui::MenuItem("经典(Classic)")) { ImGui::StyleColorsClassic(); }
|
// if (ImGui::MenuItem("经典(Classic)")) { ImGui::StyleColorsClassic(); }
|
||||||
|
RenderColorThemeSettings();
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +315,7 @@ void Manager::RenderMenuBar() {
|
||||||
ImGui::MenuItem("填充(Padding)", nullptr, &m_padding);
|
ImGui::MenuItem("填充(Padding)", nullptr, &m_padding);
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::MenuItem("标志:不分割(Flag: NoSplit)", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) !=
|
if (ImGui::MenuItem("标志:不分割(Flag: NoSplit)", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) !=
|
||||||
0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; }
|
0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; }
|
||||||
if (ImGui::MenuItem("标志:不调整大小(Flag: NoResize)", "",
|
if (ImGui::MenuItem("标志:不调整大小(Flag: NoResize)", "",
|
||||||
(dockspace_flags & ImGuiDockNodeFlags_NoResize) !=
|
(dockspace_flags & ImGuiDockNodeFlags_NoResize) !=
|
||||||
0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoResize; }
|
0)) { dockspace_flags ^= ImGuiDockNodeFlags_NoResize; }
|
||||||
|
@ -510,6 +512,45 @@ void Manager::RenderStatusMessages() {
|
||||||
m_show_load_success = false;
|
m_show_load_success = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_show_theme_save_success) {
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(ImGui::GetMainViewport()->Size.x * 0.5f, 50), ImGuiCond_Always,
|
||||||
|
ImVec2(0.5f, 0.0f));
|
||||||
|
ImGui::SetNextWindowBgAlpha(0.8f);
|
||||||
|
|
||||||
|
if (ImGui::Begin("ThemeSaveSuccess", nullptr,
|
||||||
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||||
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "主题已保存");
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
m_theme_save_success_timer -= ImGui::GetIO().DeltaTime;
|
||||||
|
if (m_theme_save_success_timer <= 0.0f) {
|
||||||
|
m_show_theme_save_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染主题加载成功提示
|
||||||
|
if (m_show_theme_load_success) {
|
||||||
|
ImGui::SetNextWindowPos(ImVec2(ImGui::GetMainViewport()->Size.x * 0.5f, 50), ImGuiCond_Always,
|
||||||
|
ImVec2(0.5f, 0.0f));
|
||||||
|
ImGui::SetNextWindowBgAlpha(0.8f);
|
||||||
|
|
||||||
|
if (ImGui::Begin("ThemeLoadSuccess", nullptr,
|
||||||
|
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
|
||||||
|
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
|
||||||
|
ImGuiWindowFlags_AlwaysAutoResize)) {
|
||||||
|
ImGui::TextColored(ImVec4(0.0f, 1.0f, 0.0f, 1.0f), "主题已加载");
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
m_theme_load_success_timer -= ImGui::GetIO().DeltaTime;
|
||||||
|
if (m_theme_load_success_timer <= 0.0f) {
|
||||||
|
m_show_theme_load_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::RenderMainContent() {
|
void Manager::RenderMainContent() {
|
||||||
|
@ -585,6 +626,7 @@ void Manager::RenderSettingsMenu() {
|
||||||
RenderStopCommandSettings();
|
RenderStopCommandSettings();
|
||||||
RenderEnvironmentVariablesSettings();
|
RenderEnvironmentVariablesSettings();
|
||||||
RenderOutputEncodingSettings();
|
RenderOutputEncodingSettings();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::RenderStopCommandSettings() {
|
void Manager::RenderStopCommandSettings() {
|
||||||
|
@ -690,7 +732,7 @@ void Manager::RenderEnvironmentVariablesSettings() {
|
||||||
|
|
||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
ImGui::TextWrapped(
|
ImGui::TextWrapped(
|
||||||
"说明:启用后,CLI程序将使用这些自定义环境变量。这些变量会与系统环境变量合并,同名变量会被覆盖。");
|
"说明:启用后,CLI程序将使用这些自定义环境变量。这些变量会与系统环境变量合并,同名变量会被覆盖。");
|
||||||
|
|
||||||
ImGui::Unindent();
|
ImGui::Unindent();
|
||||||
} else {
|
} else {
|
||||||
|
@ -773,8 +815,9 @@ void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float in
|
||||||
m_app_state.AddCommandToHistory(m_app_state.command_input);
|
m_app_state.AddCommandToHistory(m_app_state.command_input);
|
||||||
if (strlen(m_app_state.working_directory) > 0) {
|
if (strlen(m_app_state.working_directory) > 0) {
|
||||||
m_app_state.cli_process.SetWorkingDirectory(m_app_state.working_directory);
|
m_app_state.cli_process.SetWorkingDirectory(m_app_state.working_directory);
|
||||||
}else {
|
} else {
|
||||||
strncpy_s(m_app_state.working_directory,m_app_state.cli_process.GetWorkingDirectory().c_str(),sizeof(m_app_state.working_directory)-1);
|
strncpy_s(m_app_state.working_directory, m_app_state.cli_process.GetWorkingDirectory().c_str(),
|
||||||
|
sizeof(m_app_state.working_directory) - 1);
|
||||||
}
|
}
|
||||||
m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止",
|
m_tray->UpdateStatus(m_app_state.cli_process.IsRunning() ? L"运行中" : L"已停止",
|
||||||
m_app_state.cli_process.GetPid());
|
m_app_state.cli_process.GetPid());
|
||||||
|
@ -800,9 +843,9 @@ void Manager::RenderControlPanel(float buttonWidth, float buttonHeight, float in
|
||||||
|
|
||||||
// 状态显示
|
// 状态显示
|
||||||
ImGui::SeparatorText("运行状态");
|
ImGui::SeparatorText("运行状态");
|
||||||
ImVec4 statusColor = m_app_state.cli_process.IsRunning() ?
|
ImVec4 statusColor = m_app_state.cli_process.IsRunning()
|
||||||
ImVec4(0.0f, 1.0f, 0.0f, 1.0f) :
|
? ImVec4(0.0f, 1.0f, 0.0f, 1.0f)
|
||||||
ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
: ImVec4(1.0f, 0.0f, 0.0f, 1.0f);
|
||||||
ImGui::TextColored(statusColor, "状态: %s",
|
ImGui::TextColored(statusColor, "状态: %s",
|
||||||
m_app_state.cli_process.IsRunning() ? "运行中" : "已停止");
|
m_app_state.cli_process.IsRunning() ? "运行中" : "已停止");
|
||||||
}
|
}
|
||||||
|
@ -875,11 +918,17 @@ void Manager::RenderLogPanel() {
|
||||||
const std::string &log = logs[i];
|
const std::string &log = logs[i];
|
||||||
|
|
||||||
if (m_app_state.enable_colored_logs) {
|
if (m_app_state.enable_colored_logs) {
|
||||||
RenderColoredLogLine(log);
|
if (m_app_state.use_ansi_colors) {
|
||||||
|
// 使用ANSI颜色转义序列解析
|
||||||
|
RenderColoredLogLine(log);
|
||||||
|
} else {
|
||||||
|
// 仅使用日志级别的颜色区分
|
||||||
|
ImVec4 textColor = GetCustomLogLevelColor(log);
|
||||||
|
ImGui::TextColored(textColor, "%s", log.c_str());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// 简单的日志级别颜色区分
|
// 不启用彩色显示,使用默认白色
|
||||||
ImVec4 textColor = GetLogLevelColor(log);
|
ImGui::TextUnformatted(log.c_str());
|
||||||
ImGui::TextColored(textColor, "%s", log.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1087,14 +1136,14 @@ HWND Manager::CreateHiddenWindow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return CreateWindowEx(
|
return CreateWindowEx(
|
||||||
0,
|
0,
|
||||||
wc.lpszClassName,
|
wc.lpszClassName,
|
||||||
L"CLI Manager Tray Window",
|
L"CLI Manager Tray Window",
|
||||||
0,
|
0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
wc.hInstance,
|
wc.hInstance,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1303,7 +1352,7 @@ bool Manager::InitializeGLFW() {
|
||||||
int windowWidth = static_cast<int>(screenWidth * 0.8);
|
int windowWidth = static_cast<int>(screenWidth * 0.8);
|
||||||
int windowHeight = static_cast<int>(screenHeight * 0.8);
|
int windowHeight = static_cast<int>(screenHeight * 0.8);
|
||||||
|
|
||||||
// glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);//窗口隐藏
|
// glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);//窗口隐藏
|
||||||
|
|
||||||
m_window = glfwCreateWindow(windowWidth, windowHeight, "CLI程序管理工具", nullptr, nullptr);
|
m_window = glfwCreateWindow(windowWidth, windowHeight, "CLI程序管理工具", nullptr, nullptr);
|
||||||
if (!m_window)
|
if (!m_window)
|
||||||
|
@ -1502,3 +1551,241 @@ extern "C" {
|
||||||
void* GetMacTrayIcon();
|
void* GetMacTrayIcon();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void Manager::RenderColorThemeSettings() {
|
||||||
|
// 预设主题
|
||||||
|
if (ImGui::MenuItem("暗黑(Dark)")) {
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("明亮(Light)")) {
|
||||||
|
ImGui::StyleColorsLight();
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("经典(Classic)")) {
|
||||||
|
ImGui::StyleColorsClassic();
|
||||||
|
}
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("颜色主题设置");
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("自定义日志颜色", &m_app_state.use_custom_log_colors)) {
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_app_state.use_custom_log_colors) {
|
||||||
|
ImGui::Indent();
|
||||||
|
|
||||||
|
ImGui::Text("日志级别颜色:");
|
||||||
|
|
||||||
|
// 编辑错误日志颜色
|
||||||
|
ImVec4 errorColor = ImVec4(
|
||||||
|
m_app_state.log_colors.error_color.x,
|
||||||
|
m_app_state.log_colors.error_color.y,
|
||||||
|
m_app_state.log_colors.error_color.z,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
if (ImGui::ColorEdit3("错误日志", (float *) &errorColor)) {
|
||||||
|
m_app_state.log_colors.error_color = errorColor;
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑警告日志颜色
|
||||||
|
ImVec4 warnColor = ImVec4(
|
||||||
|
m_app_state.log_colors.warn_color.x,
|
||||||
|
m_app_state.log_colors.warn_color.y,
|
||||||
|
m_app_state.log_colors.warn_color.z,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
if (ImGui::ColorEdit3("警告日志", (float *) &warnColor)) {
|
||||||
|
m_app_state.log_colors.warn_color = warnColor;
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑信息日志颜色
|
||||||
|
ImVec4 infoColor = ImVec4(
|
||||||
|
m_app_state.log_colors.info_color.x,
|
||||||
|
m_app_state.log_colors.info_color.y,
|
||||||
|
m_app_state.log_colors.info_color.z,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
if (ImGui::ColorEdit3("信息日志", (float *) &infoColor)) {
|
||||||
|
m_app_state.log_colors.info_color = infoColor;
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑调试日志颜色
|
||||||
|
ImVec4 debugColor = ImVec4(
|
||||||
|
m_app_state.log_colors.debug_color.x,
|
||||||
|
m_app_state.log_colors.debug_color.y,
|
||||||
|
m_app_state.log_colors.debug_color.z,
|
||||||
|
1.0f
|
||||||
|
);
|
||||||
|
if (ImGui::ColorEdit3("调试日志", (float *) &debugColor)) {
|
||||||
|
m_app_state.log_colors.debug_color = debugColor;
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置为默认颜色按钮
|
||||||
|
if (ImGui::Button("重置为默认颜色")) {
|
||||||
|
m_app_state.log_colors.ResetToDefaults();
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Unindent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ANSI颜色设置
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("使用ANSI颜色转义", &m_app_state.use_ansi_colors)) {
|
||||||
|
m_app_state.settings_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled("(?)");
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::BeginTooltip();
|
||||||
|
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||||
|
ImGui::TextUnformatted("启用后,日志中的ANSI颜色转义序列将被解析并显示为彩色文本。");
|
||||||
|
ImGui::TextUnformatted("例如: \\033[31m红色文本\\033[0m");
|
||||||
|
ImGui::PopTextWrapPos();
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 颜色样式设置
|
||||||
|
ImGui::Text("全局颜色样式:");
|
||||||
|
|
||||||
|
static int currentTheme = 0; // 默认暗色主题
|
||||||
|
const char *themes[] = {"暗黑 (Dark)", "明亮 (Light)", "经典 (Classic)", "自定义 (Custom)"};
|
||||||
|
|
||||||
|
if (ImGui::Combo("应用主题", ¤tTheme, themes, IM_ARRAYSIZE(themes))) {
|
||||||
|
switch (currentTheme) {
|
||||||
|
case 0: ImGui::StyleColorsDark();
|
||||||
|
break;
|
||||||
|
case 1: ImGui::StyleColorsLight();
|
||||||
|
break;
|
||||||
|
case 2: ImGui::StyleColorsClassic();
|
||||||
|
break;
|
||||||
|
case 3: /* 应用自定义主题 */ break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自定义主题编辑器(仅在选择"自定义"主题时显示)
|
||||||
|
if (currentTheme == 3) {
|
||||||
|
if (ImGui::TreeNode("自定义主题编辑器")) {
|
||||||
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
|
|
||||||
|
// 添加主题颜色编辑器
|
||||||
|
for (int i = 0; i < ImGuiCol_COUNT; i++) {
|
||||||
|
const char *name = ImGui::GetStyleColorName(i);
|
||||||
|
ImGui::ColorEdit4(name, (float *) &style.Colors[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加样式参数编辑器
|
||||||
|
ImGui::SliderFloat("窗口圆角", &style.WindowRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("子窗口圆角", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("框架圆角", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("弹出窗口圆角", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("滚动条圆角", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("抓取圆角", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
ImGui::SliderFloat("标签圆角", &style.TabRounding, 0.0f, 12.0f, "%.0f");
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
// 保存/加载主题按钮
|
||||||
|
if (ImGui::Button("保存当前主题")) {
|
||||||
|
SaveCurrentTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
if (ImGui::Button("加载保存的主题")) {
|
||||||
|
LoadSavedTheme();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存当前主题设置
|
||||||
|
void Manager::SaveCurrentTheme() {
|
||||||
|
std::ofstream file("theme.ini", std::ios::binary);
|
||||||
|
if (file.is_open()) {
|
||||||
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
|
|
||||||
|
// 保存主题颜色
|
||||||
|
for (int i = 0; i < ImGuiCol_COUNT; i++) {
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.Colors[i]), sizeof(ImVec4));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存样式参数
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.WindowRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.ChildRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.FrameRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.PopupRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.ScrollbarRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.GrabRounding), sizeof(float));
|
||||||
|
file.write(reinterpret_cast<const char *>(&style.TabRounding), sizeof(float));
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// 显示保存成功提示
|
||||||
|
m_show_theme_save_success = true;
|
||||||
|
m_theme_save_success_timer = 3.0f; // 3秒后消失
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载保存的主题设置
|
||||||
|
void Manager::LoadSavedTheme() {
|
||||||
|
std::ifstream file("theme.ini", std::ios::binary);
|
||||||
|
if (file.is_open()) {
|
||||||
|
ImGuiStyle &style = ImGui::GetStyle();
|
||||||
|
|
||||||
|
// 加载主题颜色
|
||||||
|
for (int i = 0; i < ImGuiCol_COUNT; i++) {
|
||||||
|
file.read(reinterpret_cast<char *>(&style.Colors[i]), sizeof(ImVec4));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载样式参数
|
||||||
|
file.read(reinterpret_cast<char *>(&style.WindowRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.ChildRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.FrameRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.PopupRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.ScrollbarRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.GrabRounding), sizeof(float));
|
||||||
|
file.read(reinterpret_cast<char *>(&style.TabRounding), sizeof(float));
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// 显示加载成功提示
|
||||||
|
m_show_theme_load_success = true;
|
||||||
|
m_theme_load_success_timer = 3.0f; // 3秒后消失
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec4 Manager::GetCustomLogLevelColor(const std::string &log) {
|
||||||
|
if (!m_app_state.use_custom_log_colors) {
|
||||||
|
// 使用默认颜色
|
||||||
|
return GetLogLevelColor(log);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用自定义颜色
|
||||||
|
if (log.find("错误") != std::string::npos || log.find("[E]") != std::string::npos ||
|
||||||
|
log.find("[ERROR]") != std::string::npos || log.find("error") != std::string::npos) {
|
||||||
|
return m_app_state.log_colors.error_color;
|
||||||
|
} else if (log.find("警告") != std::string::npos || log.find("[W]") != std::string::npos ||
|
||||||
|
log.find("[WARN]") != std::string::npos || log.find("warning") != std::string::npos) {
|
||||||
|
return m_app_state.log_colors.warn_color;
|
||||||
|
} else if (log.find("信息") != std::string::npos || log.find("[I]") != std::string::npos ||
|
||||||
|
log.find("[INFO]") != std::string::npos || log.find("info") != std::string::npos) {
|
||||||
|
return m_app_state.log_colors.info_color;
|
||||||
|
} else if (log.find("调试") != std::string::npos || log.find("[D]") != std::string::npos ||
|
||||||
|
log.find("[DEBUG]") != std::string::npos || log.find("debug") != std::string::npos) {
|
||||||
|
return m_app_state.log_colors.debug_color;
|
||||||
|
} else if (log.find("跟踪") != std::string::npos || log.find("[T]") != std::string::npos ||
|
||||||
|
log.find("[TRACE]") != std::string::npos || log.find("trace") != std::string::npos) {
|
||||||
|
return m_app_state.log_colors.trace_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // 默认白色
|
||||||
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
std::wstring StringToWide(const std::string& str) {
|
std::wstring StringToWide(const std::string &str) {
|
||||||
if (str.empty()) return L"";
|
if (str.empty()) return L"";
|
||||||
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
|
||||||
std::wstring wstr(size, 0);
|
std::wstring wstr(size, 0);
|
||||||
|
@ -14,7 +14,7 @@ std::wstring StringToWide(const std::string& str) {
|
||||||
return wstr;
|
return wstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string WideToString(const std::wstring& wstr) {
|
std::string WideToString(const std::wstring &wstr) {
|
||||||
if (wstr.empty()) return "";
|
if (wstr.empty()) return "";
|
||||||
int size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
int size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||||
std::string str(size, 0);
|
std::string str(size, 0);
|
||||||
|
@ -44,9 +44,8 @@ void SetAutoStart(bool enable) {
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
RegSetValueEx(hKey, keyName, 0, REG_SZ,
|
RegSetValueEx(hKey, keyName, 0, REG_SZ,
|
||||||
(BYTE*)exePath, (wcslen(exePath) + 1) * sizeof(WCHAR));
|
(BYTE *) exePath, (wcslen(exePath) + 1) * sizeof(WCHAR));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
RegDeleteValue(hKey, keyName);
|
RegDeleteValue(hKey, keyName);
|
||||||
}
|
}
|
||||||
RegCloseKey(hKey);
|
RegCloseKey(hKey);
|
||||||
|
@ -79,6 +78,7 @@ bool IsAutoStartEnabled() {
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 日志颜色处理函数
|
||||||
ImVec4 GetLogLevelColor(const std::string &log) {
|
ImVec4 GetLogLevelColor(const std::string &log) {
|
||||||
// 简单的日志级别颜色区分
|
// 简单的日志级别颜色区分
|
||||||
if (log.find("错误") != std::string::npos || log.find("[E]") != std::string::npos ||
|
if (log.find("错误") != std::string::npos || log.find("[E]") != std::string::npos ||
|
||||||
|
@ -90,11 +90,17 @@ ImVec4 GetLogLevelColor(const std::string &log) {
|
||||||
} else if (log.find("信息") != std::string::npos || log.find("[I]") != std::string::npos ||
|
} else if (log.find("信息") != std::string::npos || log.find("[I]") != std::string::npos ||
|
||||||
log.find("[INFO]") != std::string::npos || log.find("info") != std::string::npos) {
|
log.find("[INFO]") != std::string::npos || log.find("info") != std::string::npos) {
|
||||||
return ImVec4(0.4f, 1.0f, 0.4f, 1.0f); // 绿色
|
return ImVec4(0.4f, 1.0f, 0.4f, 1.0f); // 绿色
|
||||||
|
} else if (log.find("调试") != std::string::npos || log.find("[D]") != std::string::npos ||
|
||||||
|
log.find("[DEBUG]") != std::string::npos || log.find("debug") != std::string::npos) {
|
||||||
|
return ImVec4(0.6f, 0.6f, 1.0f, 1.0f); // 蓝色
|
||||||
|
} else if (log.find("跟踪") != std::string::npos || log.find("[T]") != std::string::npos ||
|
||||||
|
log.find("[TRACE]") != std::string::npos || log.find("trace") != std::string::npos) {
|
||||||
|
return ImVec4(0.8f, 0.8f, 0.8f, 1.0f); // 灰色
|
||||||
}
|
}
|
||||||
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // 默认白色
|
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // 默认白色
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ANSI颜色处理增强版本
|
||||||
void RenderColoredLogLine(const std::string &log) {
|
void RenderColoredLogLine(const std::string &log) {
|
||||||
auto segments = ParseAnsiColorCodes(log);
|
auto segments = ParseAnsiColorCodes(log);
|
||||||
|
|
||||||
|
@ -197,18 +203,18 @@ ParseAnsiColorCode(const std::string &code, const ImVec4 ¤tColor, bool cur
|
||||||
|
|
||||||
for (int colorCode: codes) {
|
for (int colorCode: codes) {
|
||||||
switch (colorCode) {
|
switch (colorCode) {
|
||||||
case 0: // 重置
|
case 0: // 重置
|
||||||
newColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
newColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
newBold = false;
|
newBold = false;
|
||||||
break;
|
break;
|
||||||
case 1: // 粗体/亮色
|
case 1: // 粗体/亮色
|
||||||
newBold = true;
|
newBold = true;
|
||||||
break;
|
break;
|
||||||
case 22: // 正常强度
|
case 22: // 正常强度
|
||||||
newBold = false;
|
newBold = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 前景色 (30-37)
|
// 前景色 (30-37)
|
||||||
case 30:
|
case 30:
|
||||||
newColor = GetAnsiColor(0, newBold);
|
newColor = GetAnsiColor(0, newBold);
|
||||||
break; // 黑色
|
break; // 黑色
|
||||||
|
@ -237,13 +243,13 @@ ParseAnsiColorCode(const std::string &code, const ImVec4 ¤tColor, bool cur
|
||||||
newColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
newColor = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
break; // 默认前景色
|
break; // 默认前景色
|
||||||
|
|
||||||
// 亮色前景色 (90-97)
|
// 亮色前景色 (90-97)
|
||||||
case 90:
|
case 90:
|
||||||
newColor = GetAnsiColor(8, false);
|
newColor = GetAnsiColor(8, false);
|
||||||
break; // 亮黑色(灰色)
|
break; // 亮黑色(灰色)
|
||||||
case 91:
|
case 91:
|
||||||
newColor = GetAnsiColor(9, false);
|
newColor = GetAnsiColor(9, false);
|
||||||
break; // 亮红色
|
break; // 亮红色
|
||||||
case 92:
|
case 92:
|
||||||
newColor = GetAnsiColor(10, false);
|
newColor = GetAnsiColor(10, false);
|
||||||
break; // 亮绿色
|
break; // 亮绿色
|
||||||
|
@ -263,10 +269,49 @@ ParseAnsiColorCode(const std::string &code, const ImVec4 ¤tColor, bool cur
|
||||||
newColor = GetAnsiColor(15, false);
|
newColor = GetAnsiColor(15, false);
|
||||||
break; // 亮白色
|
break; // 亮白色
|
||||||
|
|
||||||
// 背景色暂时忽略 (40-47, 100-107)
|
// 增加对背景色的支持 (40-47, 100-107)
|
||||||
|
case 40:
|
||||||
|
case 41:
|
||||||
|
case 42:
|
||||||
|
case 43:
|
||||||
|
case 44:
|
||||||
|
case 45:
|
||||||
|
case 46:
|
||||||
|
case 47:
|
||||||
|
case 100:
|
||||||
|
case 101:
|
||||||
|
case 102:
|
||||||
|
case 103:
|
||||||
|
case 104:
|
||||||
|
case 105:
|
||||||
|
case 106:
|
||||||
|
case 107:
|
||||||
|
// 背景色暂时不处理,因为ImGui不容易实现背景色
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// 处理256色和RGB色彩(38;5;n 和 38;2;r;g;b)
|
// 处理256色和RGB色彩(38;5;n 和 38;2;r;g;b)
|
||||||
// 这里可以根据需要扩展
|
if (colorCode == 38 || colorCode == 48) {
|
||||||
|
// 38=前景,48=背景
|
||||||
|
// 检查是否是256色模式或RGB模式
|
||||||
|
if (codes.size() > 1) {
|
||||||
|
if (codes[1] == 5 && codes.size() > 2) {
|
||||||
|
// 256色模式
|
||||||
|
// 暂时不实现所有256色,仅处理基本的16色
|
||||||
|
int colorIndex = codes[2];
|
||||||
|
if (colorIndex >= 0 && colorIndex < 16) {
|
||||||
|
newColor = GetAnsiColor(colorIndex, newBold);
|
||||||
|
}
|
||||||
|
} else if (codes[1] == 2 && codes.size() > 4) {
|
||||||
|
// RGB模式
|
||||||
|
// 处理RGB值
|
||||||
|
float r = static_cast<float>(codes[2]) / 255.0f;
|
||||||
|
float g = static_cast<float>(codes[3]) / 255.0f;
|
||||||
|
float b = static_cast<float>(codes[4]) / 255.0f;
|
||||||
|
newColor = ImVec4(r, g, b, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -277,25 +322,25 @@ ParseAnsiColorCode(const std::string &code, const ImVec4 ¤tColor, bool cur
|
||||||
ImVec4 GetAnsiColor(int colorIndex, bool bright) {
|
ImVec4 GetAnsiColor(int colorIndex, bool bright) {
|
||||||
// ANSI标准颜色表
|
// ANSI标准颜色表
|
||||||
static const ImVec4 ansiColors[16] = {
|
static const ImVec4 ansiColors[16] = {
|
||||||
// 标准颜色 (0-7)
|
// 标准颜色 (0-7)
|
||||||
ImVec4(0.0f, 0.0f, 0.0f, 1.0f), // 0: 黑色
|
ImVec4(0.0f, 0.0f, 0.0f, 1.0f), // 0: 黑色
|
||||||
ImVec4(0.8f, 0.0f, 0.0f, 1.0f), // 1: 红色
|
ImVec4(0.8f, 0.0f, 0.0f, 1.0f), // 1: 红色
|
||||||
ImVec4(0.0f, 0.8f, 0.0f, 1.0f), // 2: 绿色
|
ImVec4(0.0f, 0.8f, 0.0f, 1.0f), // 2: 绿色
|
||||||
ImVec4(0.8f, 0.8f, 0.0f, 1.0f), // 3: 黄色
|
ImVec4(0.8f, 0.8f, 0.0f, 1.0f), // 3: 黄色
|
||||||
ImVec4(0.0f, 0.0f, 0.8f, 1.0f), // 4: 蓝色
|
ImVec4(0.0f, 0.0f, 0.8f, 1.0f), // 4: 蓝色
|
||||||
ImVec4(0.8f, 0.0f, 0.8f, 1.0f), // 5: 洋红
|
ImVec4(0.8f, 0.0f, 0.8f, 1.0f), // 5: 洋红
|
||||||
ImVec4(0.0f, 0.8f, 0.8f, 1.0f), // 6: 青色
|
ImVec4(0.0f, 0.8f, 0.8f, 1.0f), // 6: 青色
|
||||||
ImVec4(0.8f, 0.8f, 0.8f, 1.0f), // 7: 白色
|
ImVec4(0.8f, 0.8f, 0.8f, 1.0f), // 7: 白色
|
||||||
|
|
||||||
// 亮色 (8-15)
|
// 亮色 (8-15)
|
||||||
ImVec4(0.5f, 0.5f, 0.5f, 1.0f), // 8: 亮黑色(灰色)
|
ImVec4(0.5f, 0.5f, 0.5f, 1.0f), // 8: 亮黑色(灰色)
|
||||||
ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // 9: 亮红色
|
ImVec4(1.0f, 0.0f, 0.0f, 1.0f), // 9: 亮红色
|
||||||
ImVec4(0.0f, 1.0f, 0.0f, 1.0f), // 10: 亮绿色
|
ImVec4(0.0f, 1.0f, 0.0f, 1.0f), // 10: 亮绿色
|
||||||
ImVec4(1.0f, 1.0f, 0.0f, 1.0f), // 11: 亮黄色
|
ImVec4(1.0f, 1.0f, 0.0f, 1.0f), // 11: 亮黄色
|
||||||
ImVec4(0.0f, 0.0f, 1.0f, 1.0f), // 12: 亮蓝色
|
ImVec4(0.0f, 0.0f, 1.0f, 1.0f), // 12: 亮蓝色
|
||||||
ImVec4(1.0f, 0.0f, 1.0f, 1.0f), // 13: 亮洋红
|
ImVec4(1.0f, 0.0f, 1.0f, 1.0f), // 13: 亮洋红
|
||||||
ImVec4(0.0f, 1.0f, 1.0f, 1.0f), // 14: 亮青色
|
ImVec4(0.0f, 1.0f, 1.0f, 1.0f), // 14: 亮青色
|
||||||
ImVec4(1.0f, 1.0f, 1.0f, 1.0f), // 15: 亮白色
|
ImVec4(1.0f, 1.0f, 1.0f, 1.0f), // 15: 亮白色
|
||||||
};
|
};
|
||||||
|
|
||||||
if (colorIndex >= 0 && colorIndex < 16) {
|
if (colorIndex >= 0 && colorIndex < 16) {
|
||||||
|
@ -313,3 +358,4 @@ ImVec4 GetAnsiColor(int colorIndex, bool bright) {
|
||||||
|
|
||||||
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // 默认白色
|
return ImVec4(1.0f, 1.0f, 1.0f, 1.0f); // 默认白色
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue