From e41e856fe0b8be249ef3418a61c6540461d5d41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Sat, 2 May 2026 15:57:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(gui):=20=E7=BB=8F=E5=85=B8=E6=9C=A8?= =?UTF-8?q?=E7=BA=B9=E9=A3=8E=E6=A0=BC=20UI=20=E8=A7=86=E8=A7=89=E7=BE=8E?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 配色方案:暖木色棋盘、米白窗口背景、深棕按钮,统一视觉语言 - 主菜单:IupFrame 分组(选择模式/功能),主按钮深棕底白字 - 棋盘渲染:渐变棋子(3层同心圆模拟立体感)、坐标标注(A-O/1-15)、 蓝色圆环最后落子标记、深色棋盘边框、加大星位天元 - 侧边面板:IupFrame 包裹对局信息,按钮统一样式 - 设置页面:IupFrame 分组(基本/AI/大模型),按钮样式统一 - 网络/复盘对话框:IupFrame 分组,配色和按钮样式统一 - 全局字体:SimHei 11 作为默认字体 Co-Authored-By: Claude Opus 4.7 --- include/config.h | 54 ++++++-- src/gui/gui_core.c | 3 + src/gui/gui_game.c | 215 ++++++++++++++++++++--------- src/gui/gui_menu.c | 319 +++++++++++++++++++++++++++---------------- src/gui/gui_replay.c | 28 ++-- 5 files changed, 425 insertions(+), 194 deletions(-) diff --git a/include/config.h b/include/config.h index 1a768b6..b1db71f 100644 --- a/include/config.h +++ b/include/config.h @@ -118,17 +118,53 @@ // 窗口和棋盘配置 #define WINDOW_WIDTH 1000 #define WINDOW_HEIGHT 800 -#define BOARD_OFFSET_X 50 -#define BOARD_OFFSET_Y 50 +#define BOARD_OFFSET_X 45 +#define BOARD_OFFSET_Y 45 #define CELL_SIZE 30 -#define STONE_RADIUS 12 +#define STONE_RADIUS 13 -// 颜色定义 -#define GUI_COLOR_BACKGROUND {240, 217, 181, 255} -#define GUI_COLOR_BOARD_LINE {0, 0, 0, 255} -#define GUI_COLOR_BLACK_STONE {0, 0, 0, 255} -#define GUI_COLOR_WHITE_STONE {255, 255, 255, 255} -#define GUI_COLOR_STONE_BORDER {100, 100, 100, 255} +// 配色方案 - 经典木纹风格 (RGB) +#define CLR_BOARD_BG_R 0xD4 // 棋盘背景 - 暖木色 +#define CLR_BOARD_BG_G 0xA5 +#define CLR_BOARD_BG_B 0x74 +#define CLR_BOARD_BORDER_R 0x8B // 棋盘边框 - 深木色 +#define CLR_BOARD_BORDER_G 0x5E +#define CLR_BOARD_BORDER_B 0x3C +#define CLR_WINDOW_BG "245 240 235" // 窗口背景 - 米白 +#define CLR_PANEL_BG "237 229 218" // 面板背景 - 浅米色 +#define CLR_GRID_LINE_R 0x5C // 网格线 - 深棕 +#define CLR_GRID_LINE_G 0x3D +#define CLR_GRID_LINE_B 0x2E +#define CLR_TEXT_TITLE "60 36 21" // 标题文字 - 深棕 +#define CLR_TEXT_NORMAL "74 55 40" // 正文文字 - 中棕 +#define CLR_TEXT_SECONDARY "139 115 85" // 次要文字 - 浅棕 +#define CLR_BTN_PRIMARY_BG "139 94 60" // 主按钮背景 - 深棕 +#define CLR_BTN_PRIMARY_FG "255 255 255" // 主按钮文字 - 白色 +#define CLR_BTN_NORMAL_BG "237 229 218" // 普通按钮背景 - 浅棕 +#define CLR_BTN_NORMAL_FG "107 66 38" // 普通按钮文字 - 深棕 +#define CLR_LAST_MOVE_R 0x2E // 最后落子标记 - 蓝色 +#define CLR_LAST_MOVE_G 0x86 +#define CLR_LAST_MOVE_B 0xAB +#define CLR_STAR_POINT_R 0x3C // 星位/天元 - 深棕 +#define CLR_STAR_POINT_G 0x24 +#define CLR_STAR_POINT_B 0x15 +// 黑子渐变色 +#define CLR_BLACK_STONE_R 0x10 // 黑子外圈 +#define CLR_BLACK_STONE_G 0x10 +#define CLR_BLACK_STONE_B 0x10 +#define CLR_BLACK_HIGHLIGHT_R 0x50 // 黑子高光 +#define CLR_BLACK_HIGHLIGHT_G 0x50 +#define CLR_BLACK_HIGHLIGHT_B 0x50 +// 白子渐变色 +#define CLR_WHITE_STONE_R 0xF0 // 白子外圈 +#define CLR_WHITE_STONE_G 0xF0 +#define CLR_WHITE_STONE_B 0xF0 +#define CLR_WHITE_HIGHLIGHT_R 0xFF // 白子高光 +#define CLR_WHITE_HIGHLIGHT_G 0xFF +#define CLR_WHITE_HIGHLIGHT_B 0xFF +#define CLR_WHITE_BORDER_R 0xA0 // 白子边框 +#define CLR_WHITE_BORDER_G 0xA0 +#define CLR_WHITE_BORDER_B 0xA0 //---------- 文件路径参数 ----------// #define RECORDS_DIR "records" // 记录文件目录 diff --git a/src/gui/gui_core.c b/src/gui/gui_core.c index d4d2da8..3ca2493 100644 --- a/src/gui/gui_core.c +++ b/src/gui/gui_core.c @@ -28,6 +28,9 @@ int init_gui() // 启用UTF-8模式,确保中文正常显示 IupSetGlobal("UTF8MODE", "YES"); + // 设置全局默认字体 + IupSetGlobal("DEFAULTFONT", "SimHei, 11"); + create_main_menu(); show_main_menu(); diff --git a/src/gui/gui_game.c b/src/gui/gui_game.c index 0c57761..17bb03e 100644 --- a/src/gui/gui_game.c +++ b/src/gui/gui_game.c @@ -147,7 +147,7 @@ static int map_cb(Ihandle *ih) } /** - * @brief ACTION 回调:负责重绘 + * @brief ACTION 回调:负责重绘(经典木纹风格) */ int action_cb(Ihandle *ih) { @@ -162,29 +162,48 @@ int action_cb(Ihandle *ih) RECT rc; GetClientRect(hwnd, &rc); - // 预创建所有 GDI 对象(避免循环内反复创建销毁) - HBRUSH bg_brush = CreateSolidBrush(RGB(240, 217, 181)); - HBRUSH black_brush = CreateSolidBrush(RGB(0, 0, 0)); - HBRUSH white_brush = CreateSolidBrush(RGB(255, 255, 255)); - HBRUSH red_brush = CreateSolidBrush(RGB(255, 0, 0)); - HPEN grid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); - HPEN stone_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); + // === 预创建所有 GDI 对象 === + HBRUSH bg_brush = CreateSolidBrush(RGB(CLR_BOARD_BG_R, CLR_BOARD_BG_G, CLR_BOARD_BG_B)); + HBRUSH black_outer = CreateSolidBrush(RGB(CLR_BLACK_STONE_R, CLR_BLACK_STONE_G, CLR_BLACK_STONE_B)); + HBRUSH black_core = CreateSolidBrush(RGB(0, 0, 0)); + HBRUSH black_hl = CreateSolidBrush(RGB(CLR_BLACK_HIGHLIGHT_R, CLR_BLACK_HIGHLIGHT_G, CLR_BLACK_HIGHLIGHT_B)); + HBRUSH white_outer = CreateSolidBrush(RGB(CLR_WHITE_BORDER_R, CLR_WHITE_BORDER_G, CLR_WHITE_BORDER_B)); + HBRUSH white_core = CreateSolidBrush(RGB(CLR_WHITE_STONE_R, CLR_WHITE_STONE_G, CLR_WHITE_STONE_B)); + HBRUSH white_hl = CreateSolidBrush(RGB(CLR_WHITE_HIGHLIGHT_R, CLR_WHITE_HIGHLIGHT_G, CLR_WHITE_HIGHLIGHT_B)); + HBRUSH star_brush = CreateSolidBrush(RGB(CLR_STAR_POINT_R, CLR_STAR_POINT_G, CLR_STAR_POINT_B)); + HPEN grid_pen = CreatePen(PS_SOLID, 1, RGB(CLR_GRID_LINE_R, CLR_GRID_LINE_G, CLR_GRID_LINE_B)); + HPEN border_pen = CreatePen(PS_SOLID, 2, RGB(CLR_BOARD_BORDER_R, CLR_BOARD_BORDER_G, CLR_BOARD_BORDER_B)); + HPEN last_move_pen = CreatePen(PS_SOLID, 2, RGB(CLR_LAST_MOVE_R, CLR_LAST_MOVE_G, CLR_LAST_MOVE_B)); + HPEN null_pen = CreatePen(PS_NULL, 0, RGB(0, 0, 0)); + HFONT hfont_coord = CreateFont(12, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, 0, 0, 0, 0, "SimHei"); // 1. 填充背景 FillRect(hdc, &rc, bg_brush); - // 2. 绘制棋盘网格 - HPEN prev_pen = (HPEN)SelectObject(hdc, grid_pen); + // 2. 绘制棋盘边框(深色外框) + HPEN prev_pen = (HPEN)SelectObject(hdc, border_pen); + HBRUSH prev_brush = (HBRUSH)SelectObject(hdc, (HBRUSH)GetStockObject(NULL_BRUSH)); + int grid_left = BOARD_OFFSET_X; + int grid_top = BOARD_OFFSET_Y; + int grid_right = BOARD_OFFSET_X + (BOARD_SIZE - 1) * CELL_SIZE; + int grid_bottom = BOARD_OFFSET_Y + (BOARD_SIZE - 1) * CELL_SIZE; + Rectangle(hdc, grid_left - 2, grid_top - 2, grid_right + 3, grid_bottom + 3); + + // 3. 绘制棋盘网格 + SelectObject(hdc, grid_pen); + SelectObject(hdc, (HBRUSH)GetStockObject(NULL_BRUSH)); for (int i = 0; i < BOARD_SIZE; i++) { - MoveToEx(hdc, BOARD_OFFSET_X, BOARD_OFFSET_Y + i * CELL_SIZE, NULL); - LineTo(hdc, BOARD_OFFSET_X + (BOARD_SIZE - 1) * CELL_SIZE, BOARD_OFFSET_Y + i * CELL_SIZE); - MoveToEx(hdc, BOARD_OFFSET_X + i * CELL_SIZE, BOARD_OFFSET_Y, NULL); - LineTo(hdc, BOARD_OFFSET_X + i * CELL_SIZE, BOARD_OFFSET_Y + (BOARD_SIZE - 1) * CELL_SIZE); + MoveToEx(hdc, grid_left, BOARD_OFFSET_Y + i * CELL_SIZE, NULL); + LineTo(hdc, grid_right, BOARD_OFFSET_Y + i * CELL_SIZE); + MoveToEx(hdc, BOARD_OFFSET_X + i * CELL_SIZE, grid_top, NULL); + LineTo(hdc, BOARD_OFFSET_X + i * CELL_SIZE, grid_bottom); } - // 3. 星位/天元 - SelectObject(hdc, black_brush); + // 4. 星位/天元(实心圆) + SelectObject(hdc, null_pen); + SelectObject(hdc, star_brush); if (BOARD_SIZE == 15) { int stars[] = {3, 7, 11}; @@ -193,18 +212,44 @@ int action_cb(Ihandle *ih) { int cx = BOARD_OFFSET_X + stars[si] * CELL_SIZE; int cy = BOARD_OFFSET_Y + stars[sj] * CELL_SIZE; - Ellipse(hdc, cx - 3, cy - 3, cx + 4, cy + 4); + Ellipse(hdc, cx - 4, cy - 4, cx + 5, cy + 5); } } - else + else if (BOARD_SIZE >= 9) { int cx = BOARD_OFFSET_X + (BOARD_SIZE / 2) * CELL_SIZE; int cy = BOARD_OFFSET_Y + (BOARD_SIZE / 2) * CELL_SIZE; - Ellipse(hdc, cx - 3, cy - 3, cx + 4, cy + 4); + Ellipse(hdc, cx - 4, cy - 4, cx + 5, cy + 5); } - // 4. 绘制棋子 - SelectObject(hdc, stone_pen); + // 5. 绘制坐标标注 + { + HFONT prev_font = (HFONT)SelectObject(hdc, hfont_coord); + SetBkMode(hdc, TRANSPARENT); + SetTextColor(hdc, RGB(CLR_BOARD_BORDER_R, CLR_BOARD_BORDER_G, CLR_BOARD_BORDER_B)); + + // 列坐标 (A, B, C, ...) + for (int j = 0; j < BOARD_SIZE; j++) + { + char label[2] = {'A' + j, '\0'}; + int tx = BOARD_OFFSET_X + j * CELL_SIZE - 4; + TextOut(hdc, tx, grid_top - 18, label, 1); + TextOut(hdc, tx, grid_bottom + 5, label, 1); + } + // 行坐标 (1, 2, 3, ...) + for (int i = 0; i < BOARD_SIZE; i++) + { + char label[4]; + int len = snprintf(label, sizeof(label), "%d", i + 1); + int ty = BOARD_OFFSET_Y + i * CELL_SIZE - 7; + TextOut(hdc, grid_left - 18 - (len > 1 ? 4 : 0), ty, label, len); + TextOut(hdc, grid_right + 6, ty, label, len); + } + SelectObject(hdc, prev_font); + } + + // 6. 绘制棋子(渐变效果:3层同心圆) + SelectObject(hdc, null_pen); for (int i = 0; i < BOARD_SIZE; i++) for (int j = 0; j < BOARD_SIZE; j++) { @@ -215,34 +260,60 @@ int action_cb(Ihandle *ih) int cy = BOARD_OFFSET_Y + i * CELL_SIZE; if (board[i][j] == PLAYER) - SelectObject(hdc, black_brush); + { + // 黑子:外圈深灰 → 中圈黑 → 中心高光 + SelectObject(hdc, black_outer); + Ellipse(hdc, cx - STONE_RADIUS, cy - STONE_RADIUS, + cx + STONE_RADIUS + 1, cy + STONE_RADIUS + 1); + SelectObject(hdc, black_core); + Ellipse(hdc, cx - STONE_RADIUS + 2, cy - STONE_RADIUS + 2, + cx + STONE_RADIUS - 1, cy + STONE_RADIUS - 1); + SelectObject(hdc, black_hl); + Ellipse(hdc, cx - 4, cy - 5, cx - 1, cy - 2); + } else - SelectObject(hdc, white_brush); - - Ellipse(hdc, cx - STONE_RADIUS, cy - STONE_RADIUS, - cx + STONE_RADIUS + 1, cy + STONE_RADIUS + 1); + { + // 白子:外圈灰边 → 中圈白 → 中心高光 + SelectObject(hdc, white_outer); + Ellipse(hdc, cx - STONE_RADIUS, cy - STONE_RADIUS, + cx + STONE_RADIUS + 1, cy + STONE_RADIUS + 1); + SelectObject(hdc, white_core); + Ellipse(hdc, cx - STONE_RADIUS + 2, cy - STONE_RADIUS + 2, + cx + STONE_RADIUS - 1, cy + STONE_RADIUS - 1); + SelectObject(hdc, white_hl); + Ellipse(hdc, cx - 4, cy - 5, cx - 1, cy - 2); + } } - // 5. 标记最后落子位置(红色小方块) + // 7. 标记最后落子位置(蓝色圆环) if (step_count > 0 && step_count <= MAX_STEPS) { Step last = steps[step_count - 1]; int cx = BOARD_OFFSET_X + last.y * CELL_SIZE; int cy = BOARD_OFFSET_Y + last.x * CELL_SIZE; - RECT mark = {cx - 3, cy - 3, cx + 4, cy + 4}; - FillRect(hdc, &mark, red_brush); + SelectObject(hdc, last_move_pen); + SelectObject(hdc, (HBRUSH)GetStockObject(NULL_BRUSH)); + Ellipse(hdc, cx - 5, cy - 5, cx + 6, cy + 6); } // 恢复原始 GDI 对象,然后清理 SelectObject(hdc, prev_pen); + SelectObject(hdc, prev_brush); ReleaseDC(hwnd, hdc); DeleteObject(bg_brush); - DeleteObject(black_brush); - DeleteObject(white_brush); - DeleteObject(red_brush); + DeleteObject(black_outer); + DeleteObject(black_core); + DeleteObject(black_hl); + DeleteObject(white_outer); + DeleteObject(white_core); + DeleteObject(white_hl); + DeleteObject(star_brush); DeleteObject(grid_pen); - DeleteObject(stone_pen); + DeleteObject(border_pen); + DeleteObject(last_move_pen); + DeleteObject(null_pen); + DeleteObject(hfont_coord); return IUP_DEFAULT; } @@ -526,85 +597,107 @@ void create_game_window() IupSetCallback(board_canvas, "K_ANY", (Icallback)k_any_cb); IupSetCallback(board_canvas, "MAP_CB", (Icallback)map_cb); - // 计算棋盘像素大小 - int board_pixel_size = BOARD_SIZE * CELL_SIZE + BOARD_OFFSET_X * 2; + // 计算棋盘像素大小(含坐标标注区域) + int board_pixel_size = (BOARD_SIZE - 1) * CELL_SIZE + BOARD_OFFSET_X * 2 + 20; char size[32]; sprintf(size, "%dx%d", board_pixel_size, board_pixel_size); IupSetAttribute(board_canvas, "RASTERSIZE", size); IupSetAttribute(board_canvas, "EXPAND", "NO"); IupSetAttribute(board_canvas, "BORDER", "NO"); - IupSetAttribute(board_canvas, "BGCOLOR", "240 217 181"); + IupSetAttribute(board_canvas, "BGCOLOR", "212 165 116"); - // 创建标签 (玩家信息和游戏状态) + // === 创建标签 === lbl_player = IupLabel("当前玩家: 黑子"); + IupSetAttribute(lbl_player, "FONT", "SimHei, 13"); + IupSetAttribute(lbl_player, "FGCOLOR", CLR_TEXT_TITLE); + lbl_status = IupLabel("准备开始"); + IupSetAttribute(lbl_status, "FONT", "SimHei, 11"); + IupSetAttribute(lbl_status, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 对局信息面板 === + Ihandle *info_vbox = IupVbox(lbl_player, lbl_status, NULL); + IupSetAttribute(info_vbox, "GAP", "4"); + IupSetAttribute(info_vbox, "MARGIN", "10x8"); + Ihandle *frm_info = IupFrame(info_vbox); + IupSetAttribute(frm_info, "TITLE", "对局信息"); + IupSetAttribute(frm_info, "FONT", "SimHei, 11"); + IupSetAttribute(frm_info, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 按钮样式宏 === +#define SET_BTN_STYLE(btn, w, h, font) \ + IupSetAttribute(btn, "SIZE", #w "x" #h); \ + IupSetAttribute(btn, "FONT", font); \ + IupSetAttribute(btn, "BGCOLOR", CLR_BTN_NORMAL_BG); \ + IupSetAttribute(btn, "FGCOLOR", CLR_BTN_NORMAL_FG); \ + IupSetAttribute(btn, "FLAT", "YES") Ihandle *vbox_controls; if (gui_game_mode == 2) // 复盘模式 { - Ihandle *btn_prev = IupButton("上一步 (Prev)", NULL); + Ihandle *btn_prev = IupButton("上一步", NULL); IupSetCallback(btn_prev, "ACTION", (Icallback)btn_replay_prev_cb); - IupSetAttribute(btn_prev, "SIZE", "100x30"); + SET_BTN_STYLE(btn_prev, 120, 35, "SimHei, 11"); - Ihandle *btn_next = IupButton("下一步 (Next)", NULL); + Ihandle *btn_next = IupButton("下一步", NULL); IupSetCallback(btn_next, "ACTION", (Icallback)btn_replay_next_cb); - IupSetAttribute(btn_next, "SIZE", "100x30"); + SET_BTN_STYLE(btn_next, 120, 35, "SimHei, 11"); + + Ihandle *hbox_nav = IupHbox(btn_prev, btn_next, NULL); + IupSetAttribute(hbox_nav, "GAP", "8"); + IupSetAttribute(hbox_nav, "ALIGNMENT", "ACENTER"); Ihandle *btn_back = IupButton("返回菜单", NULL); IupSetCallback(btn_back, "ACTION", (Icallback)btn_back_cb); - IupSetAttribute(btn_back, "SIZE", "100x30"); + SET_BTN_STYLE(btn_back, 120, 35, "SimHei, 11"); vbox_controls = IupVbox( - lbl_player, - lbl_status, - IupLabel(NULL), // Spacer - btn_prev, - btn_next, - IupLabel(NULL), // Spacer + frm_info, + hbox_nav, btn_back, NULL); } - else // 游戏模式 (PvP / PvE) + else // 游戏模式 (PvP / PvE / Network) { - Ihandle *btn_undo = IupButton("悔棋 (Undo)", NULL); + Ihandle *btn_undo = IupButton("悔棋", NULL); IupSetCallback(btn_undo, "ACTION", (Icallback)btn_undo_cb); - IupSetAttribute(btn_undo, "SIZE", "100x30"); + SET_BTN_STYLE(btn_undo, 120, 35, "SimHei, 11"); - Ihandle *btn_save = IupButton("保存 (Save)", NULL); + Ihandle *btn_save = IupButton("保存棋谱", NULL); IupSetCallback(btn_save, "ACTION", (Icallback)btn_save_cb); - IupSetAttribute(btn_save, "SIZE", "100x30"); + SET_BTN_STYLE(btn_save, 120, 35, "SimHei, 11"); Ihandle *btn_back = IupButton("返回菜单", NULL); IupSetCallback(btn_back, "ACTION", (Icallback)btn_back_cb); - IupSetAttribute(btn_back, "SIZE", "100x30"); + SET_BTN_STYLE(btn_back, 120, 35, "SimHei, 11"); vbox_controls = IupVbox( - lbl_player, - lbl_status, - IupLabel(NULL), // Spacer + frm_info, btn_undo, btn_save, - IupLabel(NULL), // Spacer btn_back, NULL); } - IupSetAttribute(vbox_controls, "GAP", "15"); +#undef SET_BTN_STYLE + + IupSetAttribute(vbox_controls, "GAP", "10"); IupSetAttribute(vbox_controls, "MARGIN", "10x10"); IupSetAttribute(vbox_controls, "ALIGNMENT", "ACENTER"); Ihandle *hbox_main = IupHbox(board_canvas, vbox_controls, NULL); IupSetAttribute(hbox_main, "MARGIN", "10x10"); - IupSetAttribute(hbox_main, "GAP", "10"); + IupSetAttribute(hbox_main, "GAP", "8"); // 创建Dialog dlg = IupDialog(hbox_main); if (!dlg) printf("ERROR: Failed to create dialog\n"); - IupSetAttribute(dlg, "TITLE", "五子棋 - IUP版本"); + IupSetAttribute(dlg, "TITLE", "五子棋"); IupSetAttribute(dlg, "RESIZE", "NO"); + IupSetAttribute(dlg, "BGCOLOR", CLR_WINDOW_BG); // 设置 CLOSE_CB 回调,确保点击X也能正确返回菜单 IupSetCallback(dlg, "CLOSE_CB", (Icallback)btn_back_cb); diff --git a/src/gui/gui_menu.c b/src/gui/gui_menu.c index 735e45a..ca3dac7 100644 --- a/src/gui/gui_menu.c +++ b/src/gui/gui_menu.c @@ -84,42 +84,72 @@ static int btn_network_cb(Ihandle *ih) { (void)ih; + Ihandle *lbl_ip = IupLabel("目标 IP:"); Ihandle *txt_ip = IupText(NULL); IupSetAttribute(txt_ip, "NAME", "NET_IP"); IupSetAttribute(txt_ip, "VALUE", "127.0.0.1"); - IupSetAttribute(txt_ip, "SIZE", "100x"); + IupSetAttribute(txt_ip, "SIZE", "120x"); + Ihandle *hbox_ip = IupHbox(lbl_ip, txt_ip, NULL); + IupSetAttribute(hbox_ip, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_ip, "GAP", "10"); + + Ihandle *lbl_port = IupLabel("端口:"); Ihandle *txt_port = IupText(NULL); IupSetAttribute(txt_port, "NAME", "NET_PORT"); char port_str[16]; sprintf(port_str, "%d", DEFAULT_NETWORK_PORT); IupSetAttribute(txt_port, "VALUE", port_str); - IupSetAttribute(txt_port, "SIZE", "50x"); + IupSetAttribute(txt_port, "SIZE", "60x"); + + Ihandle *hbox_port = IupHbox(lbl_port, txt_port, NULL); + IupSetAttribute(hbox_port, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_port, "GAP", "10"); + + Ihandle *vbox_input = IupVbox(hbox_ip, hbox_port, NULL); + IupSetAttribute(vbox_input, "GAP", "8"); + IupSetAttribute(vbox_input, "MARGIN", "10x8"); + + Ihandle *frm_input = IupFrame(vbox_input); + IupSetAttribute(frm_input, "TITLE", "连接设置"); + IupSetAttribute(frm_input, "FONT", "SimHei, 11"); + IupSetAttribute(frm_input, "FGCOLOR", CLR_TEXT_NORMAL); Ihandle *btn_host = IupButton("创建房间", NULL); IupSetCallback(btn_host, "ACTION", (Icallback)btn_network_host_cb); - + IupSetAttribute(btn_host, "SIZE", "100x32"); + IupSetAttribute(btn_host, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_host, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_host, "FLAT", "YES"); + Ihandle *btn_join = IupButton("加入房间", NULL); IupSetCallback(btn_join, "ACTION", (Icallback)btn_network_join_cb); + IupSetAttribute(btn_join, "SIZE", "100x32"); + IupSetAttribute(btn_join, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_join, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_join, "FLAT", "YES"); Ihandle *btn_cancel = IupButton("取消", NULL); IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_network_cancel_cb); + IupSetAttribute(btn_cancel, "SIZE", "80x32"); + IupSetAttribute(btn_cancel, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_cancel, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_cancel, "FLAT", "YES"); - Ihandle *vbox = IupVbox( - IupHbox(IupLabel("目标 IP: "), txt_ip, NULL), - IupHbox(IupLabel("端口: "), txt_port, NULL), - IupLabel(""), - IupHbox(btn_host, btn_join, btn_cancel, NULL), - NULL - ); - IupSetAttribute(vbox, "MARGIN", "20x20"); - IupSetAttribute(vbox, "GAP", "10"); + Ihandle *hbox_btns = IupHbox(btn_host, btn_join, btn_cancel, NULL); + IupSetAttribute(hbox_btns, "GAP", "8"); + IupSetAttribute(hbox_btns, "ALIGNMENT", "ACENTER"); + + Ihandle *vbox = IupVbox(frm_input, hbox_btns, NULL); + IupSetAttribute(vbox, "MARGIN", "15x15"); + IupSetAttribute(vbox, "GAP", "12"); IupSetAttribute(vbox, "ALIGNMENT", "ACENTER"); Ihandle *dlg = IupDialog(vbox); IupSetAttribute(dlg, "TITLE", "局域网联机"); IupSetAttribute(dlg, "RESIZE", "NO"); - + IupSetAttribute(dlg, "BGCOLOR", CLR_WINDOW_BG); + IupPopup(dlg, IUP_CENTER, IUP_CENTER); IupDestroy(dlg); @@ -229,8 +259,8 @@ static int btn_settings_cb(Ihandle *ih) { (void)ih; - // 1. Board Size - Ihandle *lbl_board_size = IupLabel("棋盘大小 (5-25):"); + // === 基本设置 === + Ihandle *lbl_board_size = IupLabel("棋盘大小:"); Ihandle *txt_board_size = IupText(NULL); IupSetAttribute(txt_board_size, "NAME", "BOARD_SIZE"); IupSetAttribute(txt_board_size, "SPIN", "YES"); @@ -239,19 +269,20 @@ static int btn_settings_cb(Ihandle *ih) IupSetInt(txt_board_size, "VALUE", BOARD_SIZE); IupSetAttribute(txt_board_size, "SIZE", "50x"); - // 2. Forbidden Moves + Ihandle *hbox_board = IupHbox(lbl_board_size, txt_board_size, NULL); + IupSetAttribute(hbox_board, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_board, "GAP", "10"); + Ihandle *tgl_forbidden = IupToggle("启用禁手规则", NULL); IupSetAttribute(tgl_forbidden, "NAME", "FORBIDDEN"); IupSetInt(tgl_forbidden, "VALUE", use_forbidden_moves); - // 3. Timer Ihandle *tgl_timer = IupToggle("启用计时器", NULL); IupSetAttribute(tgl_timer, "NAME", "TIMER"); IupSetInt(tgl_timer, "VALUE", use_timer); IupSetCallback(tgl_timer, "ACTION", (Icallback)tgl_timer_cb); - // 4. Time Limit - Ihandle *lbl_time_limit = IupLabel("时间限制 (分钟):"); + Ihandle *lbl_time_limit = IupLabel("时间限制(分钟):"); Ihandle *txt_time_limit = IupText(NULL); IupSetAttribute(txt_time_limit, "NAME", "TIME_LIMIT"); IupSetAttribute(txt_time_limit, "SPIN", "YES"); @@ -261,24 +292,36 @@ static int btn_settings_cb(Ihandle *ih) IupSetAttribute(txt_time_limit, "ACTIVE", use_timer ? "YES" : "NO"); IupSetAttribute(txt_time_limit, "SIZE", "50x"); - // 5. AI Difficulty - Ihandle *lbl_ai = IupLabel("AI 难度 (1-5):"); + Ihandle *hbox_time = IupHbox(lbl_time_limit, txt_time_limit, NULL); + IupSetAttribute(hbox_time, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_time, "GAP", "10"); + + Ihandle *vbox_basic = IupVbox(hbox_board, tgl_forbidden, tgl_timer, hbox_time, NULL); + IupSetAttribute(vbox_basic, "GAP", "8"); + IupSetAttribute(vbox_basic, "MARGIN", "10x8"); + + Ihandle *frm_basic = IupFrame(vbox_basic); + IupSetAttribute(frm_basic, "TITLE", "基本设置"); + IupSetAttribute(frm_basic, "FONT", "SimHei, 11"); + IupSetAttribute(frm_basic, "FGCOLOR", CLR_TEXT_NORMAL); + + // === AI 设置 === + Ihandle *lbl_ai = IupLabel("AI 难度:"); Ihandle *lst_ai = IupList(NULL); IupSetAttribute(lst_ai, "NAME", "AI_DIFFICULTY"); IupSetAttribute(lst_ai, "DROPDOWN", "YES"); - IupSetAttribute(lst_ai, "1", "1 (简单)"); - IupSetAttribute(lst_ai, "2", "2 (普通)"); - IupSetAttribute(lst_ai, "3", "3 (中等)"); - IupSetAttribute(lst_ai, "4", "4 (困难)"); - IupSetAttribute(lst_ai, "5", "5 (专家)"); + IupSetAttribute(lst_ai, "1", "1 简单"); + IupSetAttribute(lst_ai, "2", "2 普通"); + IupSetAttribute(lst_ai, "3", "3 中等"); + IupSetAttribute(lst_ai, "4", "4 困难"); + IupSetAttribute(lst_ai, "5", "5 专家"); IupSetInt(lst_ai, "VALUE", ai_difficulty); IupSetAttribute(lst_ai, "SIZE", "80x"); - // === 大模型AI设置 === - Ihandle *lbl_llm_sep = IupLabel("--- 大模型AI设置 ---"); - IupSetAttribute(lbl_llm_sep, "ALIGNMENT", "ACENTER"); + Ihandle *hbox_ai = IupHbox(lbl_ai, lst_ai, NULL); + IupSetAttribute(hbox_ai, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_ai, "GAP", "10"); - // 6. AI 模式选择 Ihandle *lbl_ai_mode = IupLabel("AI模式:"); Ihandle *lst_ai_mode = IupList(NULL); IupSetAttribute(lst_ai_mode, "NAME", "AI_MODE"); @@ -288,14 +331,30 @@ static int btn_settings_cb(Ihandle *ih) IupSetInt(lst_ai_mode, "VALUE", llm_use ? 2 : 1); IupSetAttribute(lst_ai_mode, "SIZE", "120x"); - // 7. LLM API 地址 + Ihandle *hbox_ai_mode = IupHbox(lbl_ai_mode, lst_ai_mode, NULL); + IupSetAttribute(hbox_ai_mode, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_ai_mode, "GAP", "10"); + + Ihandle *vbox_ai = IupVbox(hbox_ai, hbox_ai_mode, NULL); + IupSetAttribute(vbox_ai, "GAP", "8"); + IupSetAttribute(vbox_ai, "MARGIN", "10x8"); + + Ihandle *frm_ai = IupFrame(vbox_ai); + IupSetAttribute(frm_ai, "TITLE", "AI 设置"); + IupSetAttribute(frm_ai, "FONT", "SimHei, 11"); + IupSetAttribute(frm_ai, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 大模型设置 === Ihandle *lbl_endpoint = IupLabel("API地址:"); Ihandle *txt_endpoint = IupText(NULL); IupSetAttribute(txt_endpoint, "NAME", "LLM_ENDPOINT"); IupSetAttribute(txt_endpoint, "VALUE", llm_endpoint); IupSetAttribute(txt_endpoint, "SIZE", "250x"); - // 8. LLM API Key + Ihandle *hbox_endpoint = IupHbox(lbl_endpoint, txt_endpoint, NULL); + IupSetAttribute(hbox_endpoint, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_endpoint, "GAP", "10"); + Ihandle *lbl_apikey = IupLabel("API Key:"); Ihandle *txt_apikey = IupText(NULL); IupSetAttribute(txt_apikey, "NAME", "LLM_API_KEY"); @@ -303,81 +362,60 @@ static int btn_settings_cb(Ihandle *ih) IupSetAttribute(txt_apikey, "PASSWORD", "YES"); IupSetAttribute(txt_apikey, "SIZE", "200x"); - // 9. LLM 模型名 + Ihandle *hbox_apikey = IupHbox(lbl_apikey, txt_apikey, NULL); + IupSetAttribute(hbox_apikey, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_apikey, "GAP", "10"); + Ihandle *lbl_model = IupLabel("模型名称:"); Ihandle *txt_model = IupText(NULL); IupSetAttribute(txt_model, "NAME", "LLM_MODEL"); IupSetAttribute(txt_model, "VALUE", llm_model); IupSetAttribute(txt_model, "SIZE", "150x"); - // Buttons - Ihandle *btn_save = IupButton("保存", NULL); - IupSetCallback(btn_save, "ACTION", (Icallback)btn_save_settings_cb); - IupSetAttribute(btn_save, "SIZE", "60x"); - - Ihandle *btn_cancel = IupButton("取消", NULL); - IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_cancel_settings_cb); - IupSetAttribute(btn_cancel, "SIZE", "60x"); - - // Layout - Ihandle *hbox_board = IupHbox(lbl_board_size, txt_board_size, NULL); - IupSetAttribute(hbox_board, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_board, "GAP", "10"); - - Ihandle *hbox_time = IupHbox(lbl_time_limit, txt_time_limit, NULL); - IupSetAttribute(hbox_time, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_time, "GAP", "10"); - - Ihandle *hbox_ai = IupHbox(lbl_ai, lst_ai, NULL); - IupSetAttribute(hbox_ai, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_ai, "GAP", "10"); - - // LLM 设置布局 - Ihandle *hbox_ai_mode = IupHbox(lbl_ai_mode, lst_ai_mode, NULL); - IupSetAttribute(hbox_ai_mode, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_ai_mode, "GAP", "10"); - - Ihandle *hbox_endpoint = IupHbox(lbl_endpoint, txt_endpoint, NULL); - IupSetAttribute(hbox_endpoint, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_endpoint, "GAP", "10"); - - Ihandle *hbox_apikey = IupHbox(lbl_apikey, txt_apikey, NULL); - IupSetAttribute(hbox_apikey, "ALIGNMENT", "ACENTER"); - IupSetAttribute(hbox_apikey, "GAP", "10"); - Ihandle *hbox_model = IupHbox(lbl_model, txt_model, NULL); IupSetAttribute(hbox_model, "ALIGNMENT", "ACENTER"); IupSetAttribute(hbox_model, "GAP", "10"); + Ihandle *vbox_llm = IupVbox(hbox_endpoint, hbox_apikey, hbox_model, NULL); + IupSetAttribute(vbox_llm, "GAP", "8"); + IupSetAttribute(vbox_llm, "MARGIN", "10x8"); + + Ihandle *frm_llm = IupFrame(vbox_llm); + IupSetAttribute(frm_llm, "TITLE", "大模型设置"); + IupSetAttribute(frm_llm, "FONT", "SimHei, 11"); + IupSetAttribute(frm_llm, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 按钮 === + Ihandle *btn_save = IupButton("保存", NULL); + IupSetCallback(btn_save, "ACTION", (Icallback)btn_save_settings_cb); + IupSetAttribute(btn_save, "SIZE", "80x30"); + IupSetAttribute(btn_save, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_save, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_save, "FLAT", "YES"); + + Ihandle *btn_cancel = IupButton("取消", NULL); + IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_cancel_settings_cb); + IupSetAttribute(btn_cancel, "SIZE", "80x30"); + IupSetAttribute(btn_cancel, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_cancel, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_cancel, "FLAT", "YES"); + Ihandle *hbox_btns = IupHbox(btn_save, btn_cancel, NULL); - IupSetAttribute(hbox_btns, "GAP", "20"); - IupSetAttribute(hbox_btns, "MARGIN", "10x0"); + IupSetAttribute(hbox_btns, "GAP", "15"); + IupSetAttribute(hbox_btns, "MARGIN", "5x0"); IupSetAttribute(hbox_btns, "ALIGNMENT", "ACENTER"); - Ihandle *vbox = IupVbox( - hbox_board, - tgl_forbidden, - tgl_timer, - hbox_time, - hbox_ai, - IupLabel(NULL), // Spacer - lbl_llm_sep, - hbox_ai_mode, - hbox_endpoint, - hbox_apikey, - hbox_model, - IupLabel(NULL), // Spacer - hbox_btns, - NULL); - + // === 主布局 === + Ihandle *vbox = IupVbox(frm_basic, frm_ai, frm_llm, hbox_btns, NULL); IupSetAttribute(vbox, "GAP", "10"); - IupSetAttribute(vbox, "MARGIN", "20x20"); + IupSetAttribute(vbox, "MARGIN", "15x15"); Ihandle *dlg = IupDialog(vbox); IupSetAttribute(dlg, "TITLE", "游戏设置"); IupSetAttribute(dlg, "RESIZE", "NO"); IupSetAttribute(dlg, "MINBOX", "NO"); IupSetAttribute(dlg, "MAXBOX", "NO"); + IupSetAttribute(dlg, "BGCOLOR", CLR_WINDOW_BG); IupPopup(dlg, IUP_CENTER, IUP_CENTER); IupDestroy(dlg); @@ -393,63 +431,114 @@ static int btn_exit_cb(Ihandle *ih) return IUP_DEFAULT; } +/** + * @brief 创建主菜单 + */ void create_main_menu() { if (menu_dlg) return; - Ihandle *lbl_title = IupLabel("五子棋 (Gobang)"); - IupSetAttribute(lbl_title, "FONT", "SimHei, 24"); + // === 标题区 === + Ihandle *lbl_title = IupLabel("五子棋"); + IupSetAttribute(lbl_title, "FONT", "SimHei, 32"); + IupSetAttribute(lbl_title, "FGCOLOR", CLR_TEXT_TITLE); IupSetAttribute(lbl_title, "ALIGNMENT", "ACENTER"); - Ihandle *btn_pvp = IupButton("玩家对战 (PvP)", NULL); - IupSetCallback(btn_pvp, "ACTION", (Icallback)btn_pvp_cb); - IupSetAttribute(btn_pvp, "SIZE", "120x30"); - IupSetAttribute(btn_pvp, "FONT", "SimHei, 12"); + Ihandle *lbl_subtitle = IupLabel("Gobang"); + IupSetAttribute(lbl_subtitle, "FONT", "SimHei, 14"); + IupSetAttribute(lbl_subtitle, "FGCOLOR", CLR_TEXT_SECONDARY); + IupSetAttribute(lbl_subtitle, "ALIGNMENT", "ACENTER"); - Ihandle *btn_pve = IupButton("人机对战 (PvE)", NULL); + // === 游戏模式按钮(主按钮样式:深棕底白字)=== + Ihandle *btn_pvp = IupButton("玩家对战", NULL); + IupSetCallback(btn_pvp, "ACTION", (Icallback)btn_pvp_cb); + IupSetAttribute(btn_pvp, "SIZE", "150x38"); + IupSetAttribute(btn_pvp, "FONT", "SimHei, 13"); + IupSetAttribute(btn_pvp, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_pvp, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_pvp, "FLAT", "YES"); + + Ihandle *btn_pve = IupButton("人机对战", NULL); IupSetCallback(btn_pve, "ACTION", (Icallback)btn_pve_cb); - IupSetAttribute(btn_pve, "SIZE", "120x30"); - IupSetAttribute(btn_pve, "FONT", "SimHei, 12"); + IupSetAttribute(btn_pve, "SIZE", "150x38"); + IupSetAttribute(btn_pve, "FONT", "SimHei, 13"); + IupSetAttribute(btn_pve, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_pve, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_pve, "FLAT", "YES"); Ihandle *btn_net = IupButton("局域网联机", NULL); IupSetCallback(btn_net, "ACTION", (Icallback)btn_network_cb); - IupSetAttribute(btn_net, "SIZE", "120x30"); - IupSetAttribute(btn_net, "FONT", "SimHei, 12"); + IupSetAttribute(btn_net, "SIZE", "150x38"); + IupSetAttribute(btn_net, "FONT", "SimHei, 13"); + IupSetAttribute(btn_net, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_net, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_net, "FLAT", "YES"); - Ihandle *btn_replay = IupButton("复盘模式", NULL); + Ihandle *vbox_modes = IupVbox(btn_pvp, btn_pve, btn_net, NULL); + IupSetAttribute(vbox_modes, "GAP", "8"); + IupSetAttribute(vbox_modes, "ALIGNMENT", "ACENTER"); + IupSetAttribute(vbox_modes, "MARGIN", "15x10"); + + Ihandle *frm_modes = IupFrame(vbox_modes); + IupSetAttribute(frm_modes, "TITLE", "选择模式"); + IupSetAttribute(frm_modes, "FONT", "SimHei, 11"); + IupSetAttribute(frm_modes, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 功能按钮(普通按钮样式:浅棕底深棕字)=== + Ihandle *btn_replay = IupButton("复盘回放", NULL); IupSetCallback(btn_replay, "ACTION", (Icallback)btn_replay_cb); - IupSetAttribute(btn_replay, "SIZE", "120x30"); - IupSetAttribute(btn_replay, "FONT", "SimHei, 12"); + IupSetAttribute(btn_replay, "SIZE", "120x32"); + IupSetAttribute(btn_replay, "FONT", "SimHei, 11"); + IupSetAttribute(btn_replay, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_replay, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_replay, "FLAT", "YES"); - Ihandle *btn_settings = IupButton("设置", NULL); + Ihandle *btn_settings = IupButton("游戏设置", NULL); IupSetCallback(btn_settings, "ACTION", (Icallback)btn_settings_cb); - IupSetAttribute(btn_settings, "SIZE", "120x30"); - IupSetAttribute(btn_settings, "FONT", "SimHei, 12"); + IupSetAttribute(btn_settings, "SIZE", "120x32"); + IupSetAttribute(btn_settings, "FONT", "SimHei, 11"); + IupSetAttribute(btn_settings, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_settings, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_settings, "FLAT", "YES"); - Ihandle *btn_exit = IupButton("退出", NULL); + Ihandle *btn_exit = IupButton("退出游戏", NULL); IupSetCallback(btn_exit, "ACTION", (Icallback)btn_exit_cb); - IupSetAttribute(btn_exit, "SIZE", "120x30"); - IupSetAttribute(btn_exit, "FONT", "SimHei, 12"); + IupSetAttribute(btn_exit, "SIZE", "120x32"); + IupSetAttribute(btn_exit, "FONT", "SimHei, 11"); + IupSetAttribute(btn_exit, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_exit, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_exit, "FLAT", "YES"); + Ihandle *hbox_func = IupHbox(btn_replay, btn_settings, btn_exit, NULL); + IupSetAttribute(hbox_func, "GAP", "10"); + IupSetAttribute(hbox_func, "ALIGNMENT", "ACENTER"); + IupSetAttribute(hbox_func, "MARGIN", "10x8"); + + Ihandle *frm_func = IupFrame(hbox_func); + IupSetAttribute(frm_func, "TITLE", "功能"); + IupSetAttribute(frm_func, "FONT", "SimHei, 11"); + IupSetAttribute(frm_func, "FGCOLOR", CLR_TEXT_NORMAL); + + // === 主布局 === Ihandle *vbox = IupVbox( lbl_title, - btn_pvp, - btn_pve, - btn_net, - btn_replay, - btn_settings, - btn_exit, + lbl_subtitle, + IupLabel(NULL), // 间隔 + frm_modes, + frm_func, NULL); IupSetAttribute(vbox, "ALIGNMENT", "ACENTER"); - IupSetAttribute(vbox, "GAP", "15"); - IupSetAttribute(vbox, "MARGIN", "40x40"); + IupSetAttribute(vbox, "GAP", "8"); + IupSetAttribute(vbox, "MARGIN", "30x25"); menu_dlg = IupDialog(vbox); IupSetAttribute(menu_dlg, "TITLE", "五子棋 - 主菜单"); IupSetAttribute(menu_dlg, "RESIZE", "NO"); IupSetAttribute(menu_dlg, "MINBOX", "NO"); IupSetAttribute(menu_dlg, "MAXBOX", "NO"); + IupSetAttribute(menu_dlg, "BGCOLOR", CLR_WINDOW_BG); + IupSetAttribute(menu_dlg, "SIZE", "360x480"); // 设置对话框关闭回调 (点X关闭程序) IupSetCallback(menu_dlg, "CLOSE_CB", (Icallback)btn_exit_cb); diff --git a/src/gui/gui_replay.c b/src/gui/gui_replay.c index 1256db0..5b4b48e 100644 --- a/src/gui/gui_replay.c +++ b/src/gui/gui_replay.c @@ -4,6 +4,7 @@ #include "globals.h" #include "gobang.h" #include "record.h" +#include "config.h" #include #include #include @@ -173,20 +174,28 @@ void select_replay_file_gui() // 创建确定和取消按钮 Ihandle *btn_ok = IupButton("确定", NULL); IupSetCallback(btn_ok, "ACTION", (Icallback)btn_replay_sel_ok_cb); - IupSetAttribute(btn_ok, "SIZE", "60x30"); + IupSetAttribute(btn_ok, "SIZE", "80x32"); + IupSetAttribute(btn_ok, "BGCOLOR", CLR_BTN_PRIMARY_BG); + IupSetAttribute(btn_ok, "FGCOLOR", CLR_BTN_PRIMARY_FG); + IupSetAttribute(btn_ok, "FLAT", "YES"); Ihandle *btn_cancel = IupButton("取消", NULL); IupSetCallback(btn_cancel, "ACTION", (Icallback)btn_replay_sel_cancel_cb); - IupSetAttribute(btn_cancel, "SIZE", "60x30"); + IupSetAttribute(btn_cancel, "SIZE", "80x32"); + IupSetAttribute(btn_cancel, "BGCOLOR", CLR_BTN_NORMAL_BG); + IupSetAttribute(btn_cancel, "FGCOLOR", CLR_BTN_NORMAL_FG); + IupSetAttribute(btn_cancel, "FLAT", "YES"); - Ihandle *vbox = IupVbox( - IupLabel("请选择复盘文件:"), - list, - IupHbox(btn_ok, btn_cancel, NULL), - NULL); + Ihandle *lbl_prompt = IupLabel("选择复盘文件:"); + IupSetAttribute(lbl_prompt, "FGCOLOR", CLR_TEXT_NORMAL); + Ihandle *hbox_btns = IupHbox(btn_ok, btn_cancel, NULL); + IupSetAttribute(hbox_btns, "GAP", "10"); + IupSetAttribute(hbox_btns, "ALIGNMENT", "ACENTER"); + + Ihandle *vbox = IupVbox(lbl_prompt, list, hbox_btns, NULL); IupSetAttribute(vbox, "GAP", "10"); - IupSetAttribute(vbox, "MARGIN", "10x10"); + IupSetAttribute(vbox, "MARGIN", "15x15"); IupSetAttribute(vbox, "ALIGNMENT", "ACENTER"); Ihandle *dlg_sel = IupDialog(vbox); @@ -195,10 +204,11 @@ void select_replay_file_gui() printf("ERROR: Failed to create selection dialog\n"); return; } - IupSetAttribute(dlg_sel, "TITLE", "选择复盘文件"); + IupSetAttribute(dlg_sel, "TITLE", "复盘回放"); IupSetAttribute(dlg_sel, "MINBOX", "NO"); IupSetAttribute(dlg_sel, "MAXBOX", "NO"); IupSetAttribute(dlg_sel, "RESIZE", "NO"); + IupSetAttribute(dlg_sel, "BGCOLOR", CLR_WINDOW_BG); // 存储列表框句柄到对话框属性 IupSetAttribute(dlg_sel, "MY_LIST", (char *)list);