mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-06-29 01:45:54 +08:00
feat(ui): 添加深色模式支持
- 新增深色/浅色模式切换按钮,位于主窗口底部 - 在配置文件中定义主题颜色(浅色/深色背景、列表背景、前景色) - 更新 UI 工具函数以支持动态主题切换,包括列表斑马纹适配 - 添加翻译条目(Dark Mode/Light Mode)并更新编译脚本 - 修改主窗口创建逻辑,集成主题切换回调 - 调整列表背景色属性从 BACKCOLOR 改为 BGCOLOR 以保持一致性
This commit is contained in:
@@ -226,3 +226,36 @@ int dlg_k_any_cb(Ihandle *self, int c)
|
||||
}
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
// 深色模式切换回调
|
||||
int darkmode_cb(Ihandle *self)
|
||||
{
|
||||
Ihandle *dlg = IupGetDialog(self);
|
||||
int dark = !get_dark_mode();
|
||||
set_dark_mode(dark);
|
||||
|
||||
IupSetAttribute(dlg, "BGCOLOR", dark
|
||||
? lua_config_get_string("theme", "dark_bg")
|
||||
: lua_config_get_string("theme", "light_bg"));
|
||||
|
||||
IupSetAttribute(self, "TITLE", _(dark
|
||||
? lua_config_get_string("button", "lightmode")
|
||||
: lua_config_get_string("button", "darkmode")));
|
||||
|
||||
Ihandle *lists[] = {
|
||||
IupGetDialogChild(dlg, CTRL_LIST_SYS),
|
||||
IupGetDialogChild(dlg, CTRL_LIST_USER),
|
||||
IupGetDialogChild(dlg, CTRL_LIST_MERGED),
|
||||
NULL
|
||||
};
|
||||
for (int i = 0; lists[i]; i++)
|
||||
{
|
||||
const char *list_bg = dark
|
||||
? lua_config_get_string("theme", "dark_list_bg")
|
||||
: lua_config_get_string("theme", "light_list_bg");
|
||||
IupSetAttribute(lists[i], "BGCOLOR", list_bg);
|
||||
refresh_single_list_style(lists[i]);
|
||||
}
|
||||
|
||||
return IUP_DEFAULT;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,14 @@ static const char *get_string_default(const char *section, const char *key)
|
||||
return "取消";
|
||||
if (strcmp(key, "help") == 0)
|
||||
return "帮助(?)";
|
||||
if (strcmp(key, "undo") == 0)
|
||||
return "撤销";
|
||||
if (strcmp(key, "redo") == 0)
|
||||
return "重做";
|
||||
if (strcmp(key, "darkmode") == 0)
|
||||
return "深色模式";
|
||||
if (strcmp(key, "lightmode") == 0)
|
||||
return "浅色模式";
|
||||
}
|
||||
else if (strcmp(section, "label") == 0)
|
||||
{
|
||||
@@ -74,11 +82,32 @@ static const char *get_string_default(const char *section, const char *key)
|
||||
return "系统变量 (System)";
|
||||
if (strcmp(key, "tab_user") == 0)
|
||||
return "用户变量 (User)";
|
||||
if (strcmp(key, "tab_merged") == 0)
|
||||
return "合并预览";
|
||||
if (strcmp(key, "export_title") == 0)
|
||||
return "导出 PATH";
|
||||
if (strcmp(key, "import_title") == 0)
|
||||
return "导入 PATH";
|
||||
}
|
||||
else if (strcmp(section, "theme") == 0)
|
||||
{
|
||||
if (strcmp(key, "light_bg") == 0)
|
||||
return "240 240 240";
|
||||
if (strcmp(key, "light_list_bg") == 0)
|
||||
return "255 255 255";
|
||||
if (strcmp(key, "light_list_alt") == 0)
|
||||
return "245 245 245";
|
||||
if (strcmp(key, "light_fg") == 0)
|
||||
return "0 0 0";
|
||||
if (strcmp(key, "dark_bg") == 0)
|
||||
return "30 30 30";
|
||||
if (strcmp(key, "dark_list_bg") == 0)
|
||||
return "40 40 40";
|
||||
if (strcmp(key, "dark_list_alt") == 0)
|
||||
return "50 50 50";
|
||||
if (strcmp(key, "dark_fg") == 0)
|
||||
return "220 220 220";
|
||||
}
|
||||
else if (strcmp(section, "layout") == 0)
|
||||
{
|
||||
if (strcmp(key, "vbox_gap") == 0)
|
||||
|
||||
+18
-4
@@ -1,4 +1,5 @@
|
||||
#include "ui/main_window.h"
|
||||
#include "ui/ui_utils.h"
|
||||
#include "controller/callbacks.h"
|
||||
#include "controller/callbacks_internal.h"
|
||||
#include "core/lua_config.h"
|
||||
@@ -14,7 +15,7 @@ static Ihandle *create_path_list(const char *name)
|
||||
IupSetAttribute(list, "NAME", name);
|
||||
IupSetAttribute(list, "EXPAND", "YES");
|
||||
IupSetAttribute(list, "ITEMPADDING", lua_config_get_string("list", "item_padding"));
|
||||
IupSetAttribute(list, "BACKCOLOR", lua_config_get_string("list", "backcolor"));
|
||||
IupSetAttribute(list, "BGCOLOR", lua_config_get_string("list", "backcolor"));
|
||||
IupSetAttribute(list, "BORDER", "YES");
|
||||
IupSetAttribute(list, "CANFOCUS", "YES");
|
||||
IupSetAttribute(list, "HLINE", "NO");
|
||||
@@ -47,10 +48,10 @@ Ihandle *create_main_window(void)
|
||||
IupSetAttribute(list_merged, "NAME", CTRL_LIST_MERGED);
|
||||
IupSetAttribute(list_merged, "EXPAND", "YES");
|
||||
IupSetAttribute(list_merged, "ITEMPADDING", lua_config_get_string("list", "item_padding"));
|
||||
IupSetAttribute(list_merged, "BACKCOLOR", lua_config_get_string("list", "backcolor"));
|
||||
IupSetAttribute(list_merged, "BGCOLOR", lua_config_get_string("list", "backcolor"));
|
||||
IupSetAttribute(list_merged, "BORDER", "YES");
|
||||
IupSetAttribute(list_merged, "HLINE", "NO");
|
||||
IupSetAttribute(list_merged, "ACTIVE", "NO"); // 只读
|
||||
// 不设置 ACTIVE=NO,否则会禁用滚动;合并列表无编辑回调,已是只读
|
||||
|
||||
// 创建搜索框
|
||||
Ihandle *txt_search = IupText(NULL);
|
||||
@@ -113,6 +114,11 @@ Ihandle *create_main_window(void)
|
||||
IupSetAttribute(btn_lang, "NAME", CTRL_BTN_LANG);
|
||||
IupSetCallback(btn_lang, "ACTION", (Icallback)btn_lang_cb);
|
||||
|
||||
// 创建深色模式切换按钮
|
||||
Ihandle *btn_darkmode = IupButton(_(lua_config_get_string("button", "darkmode")), NULL);
|
||||
IupSetAttribute(btn_darkmode, "NAME", CTRL_BTN_DARKMODE);
|
||||
IupSetCallback(btn_darkmode, "ACTION", (Icallback)darkmode_cb);
|
||||
|
||||
// 设置按钮回调
|
||||
IupSetCallback(btn_new, "ACTION", (Icallback)btn_new_cb);
|
||||
IupSetCallback(btn_edit, "ACTION", (Icallback)btn_edit_cb);
|
||||
@@ -140,6 +146,7 @@ Ihandle *create_main_window(void)
|
||||
IupSetAttribute(btn_undo, "RASTERSIZE", btn_size);
|
||||
IupSetAttribute(btn_redo, "RASTERSIZE", btn_size);
|
||||
IupSetAttribute(btn_lang, "RASTERSIZE", btn_size);
|
||||
IupSetAttribute(btn_darkmode, "RASTERSIZE", btn_size);
|
||||
|
||||
// 创建操作按钮垂直布局
|
||||
Ihandle *vbox_btns = IupVbox(
|
||||
@@ -183,7 +190,7 @@ Ihandle *create_main_window(void)
|
||||
IupSetAttribute(btn_help, "RASTERSIZE", btn_size);
|
||||
|
||||
// 创建底部按钮水平布局
|
||||
Ihandle *hbox_bottom = IupHbox(lbl_status, IupFill(), btn_help, btn_lang, btn_ok, btn_cancel, NULL);
|
||||
Ihandle *hbox_bottom = IupHbox(lbl_status, IupFill(), btn_help, btn_darkmode, btn_lang, btn_ok, btn_cancel, NULL);
|
||||
IupSetAttribute(hbox_bottom, "GAP", lua_config_get_string("layout", "hbox_gap"));
|
||||
IupSetAttribute(hbox_bottom, "MARGIN", lua_config_get_string("layout", "hbox_margin"));
|
||||
IupSetAttribute(hbox_bottom, "ALIGNMENT", lua_config_get_string("layout", "hbox_alignment"));
|
||||
@@ -255,4 +262,11 @@ void refresh_main_window_ui(Ihandle *main_dlg)
|
||||
Ihandle *btn_lang = IupGetDialogChild(main_dlg, CTRL_BTN_LANG);
|
||||
if (btn_lang)
|
||||
IupSetAttribute(btn_lang, "TITLE", _("Language"));
|
||||
|
||||
// 深色模式按钮文字根据当前模式更新
|
||||
Ihandle *btn_darkmode = IupGetDialogChild(main_dlg, CTRL_BTN_DARKMODE);
|
||||
if (btn_darkmode)
|
||||
IupSetAttribute(btn_darkmode, "TITLE", get_dark_mode()
|
||||
? _(lua_config_get_string("button", "lightmode"))
|
||||
: _(lua_config_get_string("button", "darkmode")));
|
||||
}
|
||||
+40
-21
@@ -1,10 +1,23 @@
|
||||
#include "ui/ui_utils.h"
|
||||
#include "utils/os_env.h"
|
||||
#include "utils/string_ext.h"
|
||||
#include "core/lua_config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int g_dark_mode = 0;
|
||||
|
||||
void set_dark_mode(int enabled)
|
||||
{
|
||||
g_dark_mode = enabled;
|
||||
}
|
||||
|
||||
int get_dark_mode(void)
|
||||
{
|
||||
return g_dark_mode;
|
||||
}
|
||||
|
||||
// 刷新列表样式(斑马纹 + 有效性检查)
|
||||
void refresh_single_list_style(Ihandle *list)
|
||||
{
|
||||
@@ -12,30 +25,42 @@ void refresh_single_list_style(Ihandle *list)
|
||||
return;
|
||||
int count = IupGetInt(list, "COUNT");
|
||||
|
||||
// 读取主题颜色,带默认值保护
|
||||
const char *alt_color = g_dark_mode
|
||||
? lua_config_get_string("theme", "dark_list_alt")
|
||||
: lua_config_get_string("theme", "light_list_alt");
|
||||
const char *bg_color = g_dark_mode
|
||||
? lua_config_get_string("theme", "dark_list_bg")
|
||||
: lua_config_get_string("theme", "light_list_bg");
|
||||
const char *fg_default = g_dark_mode
|
||||
? lua_config_get_string("theme", "dark_fg")
|
||||
: lua_config_get_string("theme", "light_fg");
|
||||
|
||||
// 防止 NULL 或空字符串,使用硬编码默认值
|
||||
if (!alt_color || !*alt_color) alt_color = g_dark_mode ? "50 50 50" : "245 245 245";
|
||||
if (!bg_color || !*bg_color) bg_color = g_dark_mode ? "40 40 40" : "255 255 255";
|
||||
if (!fg_default || !*fg_default) fg_default = g_dark_mode ? "220 220 220" : "0 0 0";
|
||||
|
||||
for (int i = 1; i <= count; i++)
|
||||
{
|
||||
char *item = IupGetAttributeId(list, "", i);
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
// 默认颜色:黑字
|
||||
char fg_color[32] = "0 0 0";
|
||||
char fg_color[32];
|
||||
sprintf(fg_color, "%s", fg_default);
|
||||
|
||||
// 1. 检查有效性
|
||||
if (!is_path_valid(item))
|
||||
{
|
||||
// 无效路径:红色
|
||||
sprintf(fg_color, "255 0 0");
|
||||
}
|
||||
sprintf(fg_color, "255 0 0"); // 无效路径:红色
|
||||
|
||||
// 2. 检查重复 (只检查当前项之前的项,如果之前出现过,当前项标橙)
|
||||
// 2. 检查重复
|
||||
for (int j = 1; j < i; j++)
|
||||
{
|
||||
char *prev_item = IupGetAttributeId(list, "", j);
|
||||
if (prev_item && _stricmp(item, prev_item) == 0) // Windows 路径不区分大小写
|
||||
if (prev_item && _stricmp(item, prev_item) == 0)
|
||||
{
|
||||
// 重复路径:橙色
|
||||
sprintf(fg_color, "255 128 0");
|
||||
sprintf(fg_color, "255 128 0"); // 重复路径:橙色
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -43,14 +68,8 @@ void refresh_single_list_style(Ihandle *list)
|
||||
IupSetAttributeId(list, "ITEMFGCOLOR", i, fg_color);
|
||||
|
||||
// 斑马纹背景
|
||||
if (i % 2 == 0)
|
||||
{
|
||||
IupSetAttributeId(list, "ITEMBGCOLOR", i, "245 245 245");
|
||||
}
|
||||
else
|
||||
{
|
||||
IupSetAttributeId(list, "ITEMBGCOLOR", i, "255 255 255");
|
||||
}
|
||||
IupSetAttributeId(list, "ITEMBGCOLOR", i,
|
||||
(i % 2 == 0) ? alt_color : bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +79,7 @@ void sync_string_list_to_ui(Ihandle *list_ui, const StringList *str_list)
|
||||
if (!list_ui || !str_list) return;
|
||||
|
||||
IupSetAttribute(list_ui, "REMOVEITEM", "ALL");
|
||||
|
||||
|
||||
for (int i = 0; i < str_list->count; i++)
|
||||
{
|
||||
const char *item = string_list_get(str_list, i);
|
||||
@@ -78,6 +97,6 @@ void sync_string_list_to_ui(Ihandle *list_ui, const StringList *str_list)
|
||||
}
|
||||
}
|
||||
IupSetInt(list_ui, "COUNT", str_list->count);
|
||||
|
||||
|
||||
refresh_single_list_style(list_ui);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user