refactor: 将IUP控件从IupMatrix迁移到IupFlatList

简化代码结构并移除对iupcontrols库的依赖。主要变更包括:
- 用IupFlatList替换IupMatrix,简化列表操作API
- 移除iupcontrols.dll和iupimglib.dll依赖,减少部署文件大小
- 更新CMake配置和安装脚本以匹配新的依赖关系
- 重写列表操作函数以使用IupFlatList的API(VALUE、COUNT等属性)
- 调整回调函数签名以匹配新控件的事件参数
- 简化UI创建代码,移除不再需要的图标和属性设置
This commit is contained in:
2026-03-19 20:03:29 +08:00
parent 6a22202ce5
commit c92d20b4b3
11 changed files with 133 additions and 293 deletions
+5 -17
View File
@@ -48,21 +48,15 @@ target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/libs/IUP/include
)
# 设置库文件搜索路径IUP 库和 CD 库)
# 设置库文件搜索路径
target_link_directories(${PROJECT_NAME} PRIVATE
${CMAKE_SOURCE_DIR}/libs/IUP
${CMAKE_SOURCE_DIR}/libs/CD
)
# 链接所需库
target_link_libraries(${PROJECT_NAME} PRIVATE
iupcontrols
iupimglib
iup
iupcd
cd
freetype6
zlib1
gdi32
comdlg32
comctl32
@@ -71,17 +65,11 @@ target_link_libraries(${PROJECT_NAME} PRIVATE
advapi32
)
# 编译完成后,将所需的 DLL 文件复制到构建输出目录
# 我们只复制当前程序真正依赖的 DLL,避免 build 文件夹臃肿
# 编译完成后,将 DLL 文件复制到构建输出目录
file(GLOB IUP_DLLS "${CMAKE_CURRENT_SOURCE_DIR}/libs/IUP/*.dll")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CMAKE_SOURCE_DIR}/libs/IUP/iup.dll"
"${CMAKE_SOURCE_DIR}/libs/IUP/iupimglib.dll"
"${CMAKE_SOURCE_DIR}/libs/IUP/iupcontrols.dll"
"${CMAKE_SOURCE_DIR}/libs/IUP/iupcd.dll"
"${CMAKE_SOURCE_DIR}/libs/CD/cd.dll"
"${CMAKE_SOURCE_DIR}/libs/CD/freetype6.dll"
"${CMAKE_SOURCE_DIR}/libs/CD/zlib1.dll"
${IUP_DLLS}
"$<TARGET_FILE_DIR:${PROJECT_NAME}>"
COMMENT "Copying essential DLLs to build directory..."
COMMENT "Copying DLLs to build directory..."
)
+1 -7
View File
@@ -38,13 +38,7 @@ Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{
[Files]
Source: "d:\Code\doing_exercises\programs\PathEditor\build\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\iup.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\iupimglib.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\iupcontrols.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\iupcd.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\cd.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\freetype6.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "d:\Code\doing_exercises\programs\PathEditor\build\*.dll"; DestDir: "{app}"; Flags: ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Icons]
+1 -2
View File
@@ -6,8 +6,7 @@
// 编辑相关回调
int btn_new_cb(Ihandle *self);
int btn_edit_cb(Ihandle *self);
int list_dblclick_cb(Ihandle *self, int lin, int col, char *status);
int matrix_edition_cb(Ihandle *self, int lin, int col, int mode, int update);
int list_dblclick_cb(Ihandle *self, int item, char *text);
int btn_del_cb(Ihandle *self);
int btn_up_cb(Ihandle *self);
int btn_down_cb(Ihandle *self);
+1 -1
View File
@@ -6,7 +6,7 @@
// 主界面交互回调
int txt_search_cb(Ihandle *self);
int list_k_any_cb(Ihandle *self, int c);
int list_motion_cb(Ihandle *self, int lin, int col);
int list_motion_cb(Ihandle *self, int x, int y, char *status);
int dialog_k_any_cb(Ihandle *self, int c);
int btn_ok_cb(Ihandle *self);
int btn_cancel_cb(Ihandle *self);
+42 -121
View File
@@ -17,10 +17,10 @@ int btn_new_cb(Ihandle *self)
record_history();
Ihandle *current_list = get_current_list();
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
count++;
IupSetInt(current_list, "NUMLIN", count);
IupSetAttributeId2(current_list, "", count, 1, buffer);
IupSetAttributeId(current_list, "", count, buffer);
IupSetInt(current_list, "COUNT", count);
// 更新选中状态
set_single_selection(current_list, count);
@@ -47,7 +47,7 @@ int btn_edit_cb(Ihandle *self)
if (selected == 0)
return IUP_DEFAULT;
char *current_val = IupGetAttributeId2(current_list, "", selected, 1);
char *current_val = IupGetAttributeId(current_list, "", selected);
char buffer[4096]; // 假设单个路径不超过4096
if (current_val)
{
@@ -67,7 +67,7 @@ int btn_edit_cb(Ihandle *self)
record_history();
// 更新 UI
IupSetAttributeId2(current_list, "", selected, 1, buffer);
IupSetAttributeId(current_list, "", selected, buffer);
// 更新 raw_data
int pos = IupGetInt(tabs_main, "VALUEPOS");
@@ -89,111 +89,32 @@ int btn_edit_cb(Ihandle *self)
return IUP_DEFAULT;
}
// 单击/双击回调 (用于 IupMatrix 的 CLICK_CB)
int list_dblclick_cb(Ihandle *self, int lin, int col, char *status)
// 双击回调
int list_dblclick_cb(Ihandle *self, int item, char *text)
{
if (lin > 0)
// 这里的 self 就是触发双击的列表控件
if (item > 0)
{
// 如果是双击
if (strchr(status, 'D') || strchr(status, 'd'))
{
// 选中该行 (单选)
set_single_selection(self, lin);
// 如果双击的不是第一列(路径),则调用弹窗编辑
if (col != 1) {
btn_edit_cb(NULL);
}
// 如果是第一列,默认进入内联编辑,无需干预
}
// 如果是右键点击 (status包含 '3')
else if (strchr(status, '3'))
{
// 选中该行
set_single_selection(self, lin);
// 创建右键菜单
Ihandle *item_new = IupItem("新建", NULL);
IupSetAttribute(item_new, "IMAGE", "IUP_FileNew");
IupSetCallback(item_new, "ACTION", (Icallback)btn_new_cb);
Ihandle *item_edit = IupItem("编辑", NULL);
IupSetAttribute(item_edit, "IMAGE", "IUP_EditCopy");
IupSetCallback(item_edit, "ACTION", (Icallback)btn_edit_cb);
Ihandle *item_del = IupItem("删除", NULL);
IupSetAttribute(item_del, "IMAGE", "IUP_EditErase");
IupSetCallback(item_del, "ACTION", (Icallback)btn_del_cb);
Ihandle *item_up = IupItem("上移", NULL);
IupSetAttribute(item_up, "IMAGE", "IUP_ArrowUp");
IupSetCallback(item_up, "ACTION", (Icallback)btn_up_cb);
Ihandle *item_down = IupItem("下移", NULL);
IupSetAttribute(item_down, "IMAGE", "IUP_ArrowDown");
IupSetCallback(item_down, "ACTION", (Icallback)btn_down_cb);
Ihandle *menu = IupMenu(
item_new,
item_edit,
item_del,
IupSeparator(),
item_up,
item_down,
NULL
);
IupPopup(menu, IUP_MOUSEPOS, IUP_MOUSEPOS);
IupDestroy(menu);
}
// 选中该行 (单选)
set_single_selection(self, item);
// 调用编辑逻辑
btn_edit_cb(NULL);
}
return IUP_DEFAULT;
}
// 内联编辑回调
int matrix_edition_cb(Ihandle *self, int lin, int col, int mode, int update)
{
if (mode == 1)
{
// 进入编辑模式前,记录历史
record_history();
}
else if (mode == 0 && update == 1)
{
// 结束编辑并更新了值
// 同步到 raw_data
int pos = IupGetInt(tabs_main, "VALUEPOS");
StringList *raw_data = (pos == 0) ? &raw_sys_paths : &raw_user_paths;
char *filter = IupGetAttribute(txt_search, "VALUE");
if (!filter || strlen(filter) == 0) {
if (raw_data && lin > 0 && lin <= raw_data->count) {
char *new_val = IupGetAttributeId2(self, "", lin, 1);
if (new_val) {
free(raw_data->items[lin-1]);
raw_data->items[lin-1] = _strdup(new_val);
}
}
}
refresh_single_list_style(self);
}
return IUP_DEFAULT;
}
// 按钮回调:删除 (支持多选)
int btn_del_cb(Ihandle *self)
{
Ihandle *current_list = get_current_list();
char *value = IupGetAttribute(current_list, "MARKED");
char *value = IupGetAttribute(current_list, "VALUE");
if (!value)
return IUP_DEFAULT;
int len = strlen(value);
int has_selection = 0;
for (int i = 0; i < len; i++) {
if (value[i] == '1') {
if (value[i] == '+') {
has_selection = 1;
break;
}
@@ -215,10 +136,10 @@ int btn_del_cb(Ihandle *self)
// 从后往前遍历删除,避免索引错位
for (int i = len - 1; i >= 0; i--)
{
if (value[i] == '1')
if (value[i] == '+')
{
int item_index = i + 1; // IUP 索引从 1 开始
char *val = IupGetAttributeId2(current_list, "", item_index, 1);
char *val = IupGetAttributeId(current_list, "", item_index);
// 从缓存删除
if (val && raw_data)
@@ -229,7 +150,7 @@ int btn_del_cb(Ihandle *self)
}
// 从界面删除
IupSetInt(current_list, "DELLIN", item_index);
IupSetInt(current_list, "REMOVEITEM", item_index);
}
}
@@ -246,7 +167,7 @@ int btn_del_cb(Ihandle *self)
int btn_up_cb(Ihandle *self)
{
Ihandle *current_list = get_current_list();
char *value = IupGetAttribute(current_list, "MARKED");
char *value = IupGetAttribute(current_list, "VALUE");
if (!value)
return IUP_DEFAULT;
@@ -256,7 +177,7 @@ int btn_up_cb(Ihandle *self)
// 预检查是否有移动
for (int i = 1; i < len; i++) {
if (new_value[i] == '1' && new_value[i - 1] == '0') {
if (new_value[i] == '+' && new_value[i - 1] == '-') {
moved = 1;
break;
}
@@ -273,18 +194,18 @@ int btn_up_cb(Ihandle *self)
// 从前往后遍历,如果当前项被选中且前一项未选中,则交换
for (int i = 1; i < len; i++)
{
if (new_value[i] == '1' && new_value[i - 1] == '0')
if (new_value[i] == '+' && new_value[i - 1] == '-')
{
// 交换列表项内容
char *curr_text = IupGetAttributeId2(current_list, "", i + 1, 1);
char *prev_text = IupGetAttributeId2(current_list, "", i, 1);
char *curr_text = IupGetAttributeId(current_list, "", i + 1);
char *prev_text = IupGetAttributeId(current_list, "", i);
// 需要复制,防止指针失效
char *curr_copy = curr_text ? _strdup(curr_text) : NULL;
char *prev_copy = prev_text ? _strdup(prev_text) : NULL;
IupSetAttributeId2(current_list, "", i, 1, curr_copy);
IupSetAttributeId2(current_list, "", i + 1, 1, prev_copy);
IupSetAttributeId(current_list, "", i, curr_copy);
IupSetAttributeId(current_list, "", i + 1, prev_copy);
if (curr_copy) free(curr_copy);
if (prev_copy) free(prev_copy);
@@ -297,13 +218,13 @@ int btn_up_cb(Ihandle *self)
}
// 交换选中状态
new_value[i] = '0';
new_value[i - 1] = '1';
new_value[i] = '-';
new_value[i - 1] = '+';
}
}
// 更新选中状态
IupSetAttribute(current_list, "MARKED", new_value);
IupSetAttribute(current_list, "VALUE", new_value);
refresh_single_list_style(current_list);
}
free(new_value);
@@ -314,7 +235,7 @@ int btn_up_cb(Ihandle *self)
int btn_down_cb(Ihandle *self)
{
Ihandle *current_list = get_current_list();
char *value = IupGetAttribute(current_list, "MARKED");
char *value = IupGetAttribute(current_list, "VALUE");
if (!value)
return IUP_DEFAULT;
@@ -324,7 +245,7 @@ int btn_down_cb(Ihandle *self)
// 预检查
for (int i = len - 2; i >= 0; i--) {
if (new_value[i] == '1' && new_value[i + 1] == '0') {
if (new_value[i] == '+' && new_value[i + 1] == '-') {
moved = 1;
break;
}
@@ -341,18 +262,18 @@ int btn_down_cb(Ihandle *self)
// 从后往前遍历,如果当前项被选中且后一项未选中,则交换
for (int i = len - 2; i >= 0; i--)
{
if (new_value[i] == '1' && new_value[i + 1] == '0')
if (new_value[i] == '+' && new_value[i + 1] == '-')
{
// 交换列表项内容
char *curr_text = IupGetAttributeId2(current_list, "", i + 1, 1);
char *next_text = IupGetAttributeId2(current_list, "", i + 2, 1);
char *curr_text = IupGetAttributeId(current_list, "", i + 1);
char *next_text = IupGetAttributeId(current_list, "", i + 2);
// 需要复制
char *curr_copy = curr_text ? _strdup(curr_text) : NULL;
char *next_copy = next_text ? _strdup(next_text) : NULL;
IupSetAttributeId2(current_list, "", i + 2, 1, curr_copy);
IupSetAttributeId2(current_list, "", i + 1, 1, next_copy);
IupSetAttributeId(current_list, "", i + 2, curr_copy);
IupSetAttributeId(current_list, "", i + 1, next_copy);
if (curr_copy) free(curr_copy);
if (next_copy) free(next_copy);
@@ -365,13 +286,13 @@ int btn_down_cb(Ihandle *self)
}
// 交换选中状态
new_value[i] = '0';
new_value[i + 1] = '1';
new_value[i] = '-';
new_value[i + 1] = '+';
}
}
// 更新选中状态
IupSetAttribute(current_list, "MARKED", new_value);
IupSetAttribute(current_list, "VALUE", new_value);
refresh_single_list_style(current_list);
}
free(new_value);
@@ -382,7 +303,7 @@ int btn_down_cb(Ihandle *self)
int btn_clean_cb(Ihandle *self)
{
Ihandle *current_list = get_current_list();
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
if (count == 0)
return IUP_DEFAULT;
@@ -402,7 +323,7 @@ int btn_clean_cb(Ihandle *self)
// 从后往前遍历删除,避免索引错位
for (int i = count; i >= 1; i--)
{
char *item = IupGetAttributeId2(current_list, "", i, 1);
char *item = IupGetAttributeId(current_list, "", i);
if (!item)
continue;
@@ -419,7 +340,7 @@ int btn_clean_cb(Ihandle *self)
// 注意:这里需要再次遍历,性能稍低但最稳妥
for (int j = 1; j < i; j++)
{
char *prev_item = IupGetAttributeId2(current_list, "", j, 1);
char *prev_item = IupGetAttributeId(current_list, "", j);
if (prev_item && _stricmp(item, prev_item) == 0)
{
should_remove = 1;
@@ -437,7 +358,7 @@ int btn_clean_cb(Ihandle *self)
free(val_copy);
}
IupSetInt(current_list, "DELLIN", i);
IupSetAttributeId(current_list, "REMOVEITEM", i, NULL);
}
}
+11 -11
View File
@@ -25,10 +25,10 @@ int btn_browse_cb(Ihandle *self)
record_history();
Ihandle *current_list = get_current_list();
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
count++;
IupSetInt(current_list, "NUMLIN", count);
IupSetAttributeId2(current_list, "", count, 1, value);
IupSetAttributeId(current_list, "", count, value);
IupSetInt(current_list, "COUNT", count);
// 更新选中状态
set_single_selection(current_list, count);
@@ -101,7 +101,7 @@ int btn_redo_cb(Ihandle *self)
int btn_export_cb(Ihandle *self)
{
Ihandle *current_list = get_current_list();
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
if (count == 0) {
IupMessage("提示", "当前列表为空,无法导出");
return IUP_DEFAULT;
@@ -133,7 +133,7 @@ int btn_export_cb(Ihandle *self)
FILE *fp = fopen(final_path, "w");
if (fp) {
for (int i = 1; i <= count; i++) {
char *item = IupGetAttributeId2(current_list, "", i, 1);
char *item = IupGetAttributeId(current_list, "", i);
if (item) fprintf(fp, "%s\n", item);
}
fclose(fp);
@@ -181,10 +181,10 @@ int btn_import_cb(Ihandle *self)
}
if (len > 0) {
// Add to UI
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
count++;
IupSetInt(current_list, "NUMLIN", count);
IupSetAttributeId2(current_list, "", count, 1, line);
IupSetAttributeId(current_list, "", count, line);
IupSetInt(current_list, "COUNT", count);
// Add to raw_data
if (raw_data) add_string_list(raw_data, line);
@@ -234,10 +234,10 @@ int list_dropfiles_cb(Ihandle *self, const char *filename, int num, int x, int y
IupSetAttribute(txt_search, "VALUE", "");
// 添加到列表末尾
int count = IupGetInt(current_list, "NUMLIN");
int count = IupGetInt(current_list, "COUNT");
count++;
IupSetInt(current_list, "NUMLIN", count);
IupSetAttributeId2(current_list, "", count, 1, filename);
IupSetAttributeId(current_list, "", count, filename);
IupSetInt(current_list, "COUNT", count);
// 更新选中状态
set_single_selection(current_list, count);
+12 -12
View File
@@ -22,7 +22,7 @@ int txt_search_cb(Ihandle *self)
StringList *raw_data = (pos == 0) ? &raw_sys_paths : &raw_user_paths;
// 清空列表
IupSetInt(current_list, "NUMLIN", 0);
IupSetAttribute(current_list, "REMOVEITEM", "ALL");
// 重新填充
int count = 0;
@@ -32,11 +32,11 @@ int txt_search_cb(Ihandle *self)
if (strlen(filter) == 0 || stristr(raw_data->items[i], filter) != NULL)
{
count++;
IupSetInt(current_list, "NUMLIN", count);
IupSetAttributeId2(current_list, "", count, 1, raw_data->items[i]);
IupSetAttributeId(current_list, "", count, raw_data->items[i]);
}
}
IupSetInt(current_list, "COUNT", count);
refresh_single_list_style(current_list);
return IUP_DEFAULT;
@@ -54,12 +54,13 @@ int list_k_any_cb(Ihandle *self, int c)
return IUP_DEFAULT;
}
// 鼠标移动回调 (用于 IupMatrix 的 MOUSEMOVE_CB)
int list_motion_cb(Ihandle *self, int lin, int col)
// 鼠标移动回调
int list_motion_cb(Ihandle *self, int x, int y, char *status)
{
if (lin > 0)
int pos = IupConvertXYToPos(self, x, y);
if (pos > 0)
{
char *item = IupGetAttributeId2(self, "", lin, 1);
char *item = IupGetAttributeId(self, "", pos);
if (item)
{
char *expanded = expand_env_vars(item);
@@ -161,25 +162,24 @@ int tabs_tabchange_cb(Ihandle *self, int new_pos, int old_pos)
if (new_pos == 2)
{
// 合并预览模式
IupSetInt(list_merged, "NUMLIN", 0);
IupSetAttribute(list_merged, "REMOVEITEM", "ALL");
int count = 0;
// 添加系统变量
for (int i = 0; i < raw_sys_paths.count; i++)
{
count++;
IupSetInt(list_merged, "NUMLIN", count);
IupSetAttributeId2(list_merged, "", count, 1, raw_sys_paths.items[i]);
IupSetAttributeId(list_merged, "", count, raw_sys_paths.items[i]);
}
// 添加用户变量
for (int i = 0; i < raw_user_paths.count; i++)
{
count++;
IupSetInt(list_merged, "NUMLIN", count);
IupSetAttributeId2(list_merged, "", count, 1, raw_user_paths.items[i]);
IupSetAttributeId(list_merged, "", count, raw_user_paths.items[i]);
}
IupSetInt(list_merged, "COUNT", count);
refresh_single_list_style(list_merged);
// 禁用编辑按钮
-5
View File
@@ -1,5 +1,4 @@
#include <iup.h>
#include <iupcontrols.h>
#include <stdio.h>
#include <stdlib.h>
#include "globals.h"
@@ -26,10 +25,6 @@ int main(int argc, char **argv)
return 1;
}
// 初始化扩展库
IupImageLibOpen();
IupControlsOpen();
// 开启 UTF-8 支持
IupSetGlobal("UTF8MODE", "YES");
+6 -45
View File
@@ -1,5 +1,4 @@
#include "ui.h"
#include <iupcontrols.h>
#include "config.h"
#include "globals.h"
#include "ui_utils.h"
@@ -11,26 +10,18 @@
// 创建列表控件
Ihandle *create_path_list()
{
Ihandle *list = IupMatrix(NULL);
IupSetAttribute(list, "NUMCOL", "2");
IupSetAttribute(list, "NUMLIN", "0");
IupSetAttribute(list, "MARKMODE", "LIN");
IupSetAttribute(list, "MARKMULTIPLE", "YES");
IupSetAttribute(list, "READONLY", "NO");
IupSetAttribute(list, "0:1", "路径");
IupSetAttribute(list, "0:2", "状态");
IupSetAttribute(list, "ALIGNMENT1", "ALEFT");
IupSetAttribute(list, "ALIGNMENT2", "ACENTER");
Ihandle *list = IupFlatList();
IupSetAttribute(list, "EXPAND", "YES");
IupSetAttribute(list, "MULTIPLE", "YES");
IupSetAttribute(list, "ITEMPADDING", UI_LIST_ITEM_PADDING);
IupSetAttribute(list, "BACKCOLOR", UI_LIST_BGCOLOR);
IupSetAttribute(list, "BORDER", "YES");
IupSetAttribute(list, "CANFOCUS", "YES");
IupSetCallback(list, "CLICK_CB", (Icallback)list_dblclick_cb);
IupSetCallback(list, "EDITION_CB", (Icallback)matrix_edition_cb);
IupSetAttribute(list, "HLINE", "NO");
IupSetCallback(list, "DBLCLICK_CB", (Icallback)list_dblclick_cb);
IupSetCallback(list, "DROPFILES_CB", (Icallback)list_dropfiles_cb);
IupSetCallback(list, "K_ANY", (Icallback)list_k_any_cb);
IupSetCallback(list, "MOUSEMOVE_CB", (Icallback)list_motion_cb);
IupSetCallback(list, "MOTION_CB", (Icallback)list_motion_cb);
return list;
}
@@ -39,32 +30,14 @@ Ihandle *create_main_buttons()
{
// 创建右侧按钮
btn_new = IupButton("新建(N)", NULL);
IupSetAttribute(btn_new, "IMAGE", "IUP_FileNew");
IupSetAttribute(btn_new, "TITLE", "新建(N)");
btn_edit = IupButton("编辑(E)", NULL);
IupSetAttribute(btn_edit, "IMAGE", "IUP_EditCopy");
IupSetAttribute(btn_edit, "TITLE", "编辑(E)");
btn_browse = IupButton("浏览(B)...", NULL);
IupSetAttribute(btn_browse, "IMAGE", "IUP_FileOpen");
IupSetAttribute(btn_browse, "TITLE", "浏览(B)...");
btn_del = IupButton("删除(D)", NULL);
IupSetAttribute(btn_del, "IMAGE", "IUP_EditErase");
IupSetAttribute(btn_del, "TITLE", "删除(D)");
btn_undo = IupButton("撤销(Z)", NULL);
IupSetAttribute(btn_undo, "IMAGE", "IUP_EditUndo");
IupSetAttribute(btn_undo, "TITLE", "撤销(Z)");
btn_redo = IupButton("重做(Y)", NULL);
IupSetAttribute(btn_redo, "IMAGE", "IUP_EditRedo");
IupSetAttribute(btn_redo, "TITLE", "重做(Y)");
btn_up = IupButton("上移(U)", NULL);
IupSetAttribute(btn_up, "IMAGE", "IUP_ArrowUp");
IupSetAttribute(btn_up, "TITLE", "上移(U)");
btn_down = IupButton("下移(O)", NULL);
IupSetAttribute(btn_down, "IMAGE", "IUP_ArrowDown");
IupSetAttribute(btn_down, "TITLE", "下移(O)");
btn_clean = IupButton("一键清理", NULL);
IupSetAttribute(btn_clean, "IMAGE", "IUP_ToolsSettings");
IupSetAttribute(btn_clean, "TITLE", "一键清理");
// 设置按钮回调
IupSetCallback(btn_new, "ACTION", (Icallback)btn_new_cb);
@@ -108,14 +81,10 @@ Ihandle *create_bottom_buttons()
{
// 创建底部按钮
btn_help = IupButton("帮助(H)", NULL);
IupSetAttribute(btn_help, "IMAGE", "IUP_MessageInfo");
IupSetAttribute(btn_help, "TITLE", "帮助(H)"); // Force title
IupSetCallback(btn_help, "ACTION", (Icallback)btn_help_cb);
IupSetAttribute(btn_help, "RASTERSIZE", UI_BUTTON_SMALL_SIZE);
btn_theme = IupButton("深色模式", NULL);
IupSetAttribute(btn_theme, "IMAGE", "IUP_WebFormat"); // Fixed icon
IupSetAttribute(btn_theme, "TITLE", "深色模式"); // Force title
IupSetCallback(btn_theme, "ACTION", (Icallback)btn_theme_cb);
IupSetAttribute(btn_theme, "RASTERSIZE", UI_BUTTON_SMALL_SIZE);
@@ -123,26 +92,18 @@ Ihandle *create_bottom_buttons()
IupSetAttribute(lbl_status, "EXPAND", "HORIZONTAL");
btn_import = IupButton("导入配置", NULL);
IupSetAttribute(btn_import, "IMAGE", "IUP_FileOpen");
IupSetAttribute(btn_import, "TITLE", "导入配置"); // Force title
IupSetCallback(btn_import, "ACTION", (Icallback)btn_import_cb);
IupSetAttribute(btn_import, "RASTERSIZE", UI_BUTTON_SIZE);
btn_export = IupButton("导出配置", NULL);
IupSetAttribute(btn_export, "IMAGE", "IUP_FileSave"); // Fixed icon
IupSetAttribute(btn_export, "TITLE", "导出配置"); // Force title
IupSetCallback(btn_export, "ACTION", (Icallback)btn_export_cb);
IupSetAttribute(btn_export, "RASTERSIZE", UI_BUTTON_SIZE);
btn_ok = IupButton("确定(O)", NULL);
IupSetAttribute(btn_ok, "IMAGE", "IUP_FileSave");
IupSetAttribute(btn_ok, "TITLE", "确定(O)"); // Force title
IupSetCallback(btn_ok, "ACTION", (Icallback)btn_ok_cb);
IupSetAttribute(btn_ok, "RASTERSIZE", UI_BUTTON_SIZE);
btn_cancel = IupButton("取消(C)", NULL);
IupSetAttribute(btn_cancel, "IMAGE", "IUP_MessageError");
IupSetAttribute(btn_cancel, "TITLE", "取消(C)"); // Force title
IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_cancel_cb);
IupSetAttribute(btn_cancel, "RASTERSIZE", UI_BUTTON_SIZE);
@@ -172,7 +133,7 @@ Ihandle *create_main_dialog()
list_merged = create_path_list();
IupSetAttribute(list_merged, "READONLY", "YES");
IupSetAttribute(list_merged, "MARKMULTIPLE", "NO");
IupSetAttribute(list_merged, "MULTIPLE", "NO");
IupSetAttribute(list_merged, "BGCOLOR", UI_LIST_MERGED_BGCOLOR); // 灰色背景
// 创建标签页
+9 -10
View File
@@ -8,13 +8,13 @@
// 获取第一个选中的索引(1-based),如果没有选中则返回 0
int get_first_selected_index(Ihandle *list)
{
char *value = IupGetAttribute(list, "MARKED");
char *value = IupGetAttribute(list, "VALUE");
if (!value)
return 0;
int len = strlen(value);
for (int i = 0; i < len; i++)
{
if (value[i] == '1')
if (value[i] == '+')
return i + 1;
}
return 0;
@@ -23,7 +23,7 @@ int get_first_selected_index(Ihandle *list)
// 设置单选(1-based
void set_single_selection(Ihandle *list, int index)
{
int count = IupGetInt(list, "NUMLIN");
int count = IupGetInt(list, "COUNT");
if (count <= 0)
return;
@@ -33,29 +33,28 @@ void set_single_selection(Ihandle *list, int index)
for (int i = 0; i < count; i++)
{
new_val[i] = '0';
new_val[i] = '-';
}
new_val[count] = '\0';
if (index >= 1 && index <= count)
{
new_val[index - 1] = '1';
new_val[index - 1] = '+';
}
IupSetAttribute(list, "MARKED", new_val);
IupSetAttribute(list, "VALUE", new_val);
free(new_val);
}
// 从原始数据刷新UI
void refresh_ui_from_raw(Ihandle *list, StringList *raw)
{
IupSetInt(list, "NUMLIN", 0);
IupSetInt(list, "NUMLIN", raw->count);
IupSetAttribute(list, "REMOVEITEM", "ALL");
for (int i = 0; i < raw->count; i++)
{
IupSetAttributeId2(list, "", i + 1, 1, raw->items[i]);
IupSetAttributeId(list, "", i + 1, raw->items[i]);
}
IupSetAttribute(list, "REDRAW", "ALL"); // Force matrix redraw
IupSetInt(list, "COUNT", raw->count);
refresh_single_list_style(list);
}
+39 -56
View File
@@ -43,19 +43,16 @@ int check_admin()
}
// 展开环境变量
char *expand_env_vars(const char *path)
char* expand_env_vars(const char* path)
{
if (!path)
return NULL;
if (!path) return NULL;
// 先转换为宽字符,因为ExpandEnvironmentStringsW不支持UTF-8
wchar_t *wpath = utf8_to_wide(path);
if (!wpath)
return NULL;
if (!wpath) return NULL;
DWORD size = ExpandEnvironmentStringsW(wpath, NULL, 0);
if (size == 0)
{
if (size == 0) {
free(wpath);
return NULL;
}
@@ -102,75 +99,61 @@ void refresh_single_list_style(Ihandle *list)
{
if (!list)
return;
int count = IupGetInt(list, "NUMLIN");
int count = IupGetInt(list, "COUNT");
// 用于查重的简单数组(实际项目可以用哈希表)
// 为了简单,我们只用双重循环检查重复,性能在几百个条目下没问题
for (int i = 1; i <= count; i++)
{
char *item = IupGetAttributeId2(list, "", i, 1);
char *item = IupGetAttributeId(list, "", i);
if (!item)
continue;
const char *status_str = "正常";
char bg_color[32] = "";
// 默认颜色:黑字
char fg_color[32];
if (is_dark_mode)
strcpy(fg_color, "255 255 255");
else
strcpy(fg_color, "0 0 0");
// 1. 检查有效性
if (!path_exists(item))
{
// 无效路径:红色背景
strcpy(bg_color, "255 100 100"); // 柔和的红色
status_str = "无效";
// 无效路径:红色
sprintf(fg_color, "255 0 0");
}
else
// 2. 检查重复 (只检查当前项之前的项,如果之前出现过,当前项标橙)
for (int j = 1; j < i; j++)
{
// 2. 检查重复 (只检查当前项之前的项,如果之前出现过,当前项标橙)
for (int j = 1; j < i; j++)
char *prev_item = IupGetAttributeId(list, "", j);
if (prev_item && _stricmp(item, prev_item) == 0) // Windows 路径不区分大小写
{
char *prev_item = IupGetAttributeId2(list, "", j, 1);
if (prev_item && _stricmp(item, prev_item) == 0) // Windows 路径不区分大小写
{
// 重复路径:橙色背景
strcpy(bg_color, "255 165 0");
status_str = "重复";
break;
}
// 重复路径:橙色
sprintf(fg_color, "255 128 0");
break;
}
}
IupSetAttributeId2(list, "", i, 2, status_str);
IupSetAttributeId(list, "ITEMFGCOLOR", i, fg_color);
// 如果没有特殊状态,使用斑马纹背景
if (strlen(bg_color) == 0)
{
if (is_dark_mode)
{
if (i % 2 == 0)
strcpy(bg_color, "60 60 60");
else
strcpy(bg_color, "50 50 50");
}
else
{
if (i % 2 == 0)
strcpy(bg_color, "245 245 245");
else
strcpy(bg_color, "255 255 255");
}
}
char attr_bg[32];
sprintf(attr_bg, "BGCOLOR%d:*", i);
IupSetAttribute(list, attr_bg, bg_color);
// 恢复前景色
char attr_fg[32];
sprintf(attr_fg, "FGCOLOR%d:*", i);
// 斑马纹背景
if (is_dark_mode)
IupSetAttribute(list, attr_fg, "255 255 255");
{
if (i % 2 == 0)
IupSetAttributeId(list, "ITEMBGCOLOR", i, "60 60 60");
else
IupSetAttributeId(list, "ITEMBGCOLOR", i, "50 50 50");
}
else
IupSetAttribute(list, attr_fg, "0 0 0");
{
if (i % 2 == 0)
IupSetAttributeId(list, "ITEMBGCOLOR", i, "245 245 245");
else
IupSetAttributeId(list, "ITEMBGCOLOR", i, "255 255 255");
}
}
IupSetAttribute(list, "REDRAW", "ALL"); // Ensure Matrix repaints colors
}
// 刷新所有列表样式