mirror of
https://github.com/LHY0125/Gobang-Game.git
synced 2026-06-28 16:35:55 +08:00
feat(gui): 经典木纹风格 UI 视觉美化
- 配色方案:暖木色棋盘、米白窗口背景、深棕按钮,统一视觉语言 - 主菜单:IupFrame 分组(选择模式/功能),主按钮深棕底白字 - 棋盘渲染:渐变棋子(3层同心圆模拟立体感)、坐标标注(A-O/1-15)、 蓝色圆环最后落子标记、深色棋盘边框、加大星位天元 - 侧边面板:IupFrame 包裹对局信息,按钮统一样式 - 设置页面:IupFrame 分组(基本/AI/大模型),按钮样式统一 - 网络/复盘对话框:IupFrame 分组,配色和按钮样式统一 - 全局字体:SimHei 11 作为默认字体 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -28,6 +28,9 @@ int init_gui()
|
||||
// 启用UTF-8模式,确保中文正常显示
|
||||
IupSetGlobal("UTF8MODE", "YES");
|
||||
|
||||
// 设置全局默认字体
|
||||
IupSetGlobal("DEFAULTFONT", "SimHei, 11");
|
||||
|
||||
create_main_menu();
|
||||
show_main_menu();
|
||||
|
||||
|
||||
+154
-61
@@ -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);
|
||||
|
||||
+204
-115
@@ -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);
|
||||
|
||||
+19
-9
@@ -4,6 +4,7 @@
|
||||
#include "globals.h"
|
||||
#include "gobang.h"
|
||||
#include "record.h"
|
||||
#include "config.h"
|
||||
#include <iup.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user