Files
cKit/Foundation/c_Console.h
T

242 lines
7.7 KiB
C
Raw Normal View History

2026-08-30 02:51:25 +08:00
#ifndef INCLUDED_C_CONSOLE_H
#define INCLUDED_C_CONSOLE_H
#ifndef INCLUDED_C_TYPES_H
#include <c_Types.h>
#endif /*INCLUDED_C_TYPES_H*/
#ifndef INCLUDED_STDIO_H
#define INCLUDED_STDIO_H
#include <stdio.h>
#endif /*INCLUDED_STDIO_H*/
#if defined(_WIN32) || defined(_WIN64)
#include <conio.h>
#include <windows.h>
#else
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#endif
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
// ==========================================
// 2. 终端控制 ANSI 转义宏 (全平台通用)
// ==========================================
#define CONSOLE_CLEAR() printf("\033[2J\033[H") // 清屏并将光标归位
#define CONSOLE_GOTOXY(x, y) printf("\033[%d;%dH", (y), (x)) // 移动光标 (1-based)
#define CONSOLE_HIDE_CURSOR() printf("\033[?25l") // 隐藏光标
#define CONSOLE_SHOW_CURSOR() printf("\033[?25h") // 显示光标
#define CONSOLE_COLOR_RESET() printf("\033[0m") // 重置属性
#define CONSOLE_COLOR_RED() printf("\033[1;31m") // 高亮红
#define CONSOLE_COLOR_GREEN() printf("\033[1;32m") // 高亮绿
#define CONSOLE_COLOR_BLUE() printf("\033[1;34m") // 高亮蓝
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/**
* @brief 控制台 16 色标准颜色枚举(同时适用于前景色和背景色计算)
*/
typedef enum {
C_COLOR_BLACK = 0,
C_COLOR_RED = 1,
C_COLOR_GREEN = 2,
C_COLOR_YELLOW = 3,
C_COLOR_BLUE = 4,
C_COLOR_MAGENTA = 5,
C_COLOR_CYAN = 6,
C_COLOR_WHITE = 7,
// 高亮色系列(加粗/明亮)
C_COLOR_BRIGHT_BLACK = 8,
C_COLOR_BRIGHT_RED = 9,
C_COLOR_BRIGHT_GREEN = 10,
C_COLOR_BRIGHT_YELLOW = 11,
C_COLOR_BRIGHT_BLUE = 12,
C_COLOR_BRIGHT_MAGENTA = 13,
C_COLOR_BRIGHT_CYAN = 14,
C_COLOR_BRIGHT_WHITE = 15,
C_COLOR_NONE = -1 // 不改变原有颜色(保持默认)
} c_ConsoleColor_t;
// 鼠标事件类型
typedef enum {
MOUSE_EVENT_NONE = 0,
MOUSE_EVENT_PRESS_LEFT, // 左键按下
MOUSE_EVENT_PRESS_RIGHT, // 右键按下
MOUSE_EVENT_PRESS_MIDDLE, // 中键按下
MOUSE_EVENT_RELEASE, // 任意键释放
MOUSE_EVENT_WHEEL_UP, // 滚轮向上滚动
MOUSE_EVENT_WHEEL_DOWN, // 滚轮向下滚动
MOUSE_EVENT_MOVE // 鼠标移动
} c_ConsoleMouseEventType_t;
// 统一的鼠标事件结构体
typedef struct {
c_ConsoleMouseEventType_t type; // 事件类型
int x; // 触发时的列坐标 (从 1 开始)
int y; // 触发时的行坐标 (从 1 开始)
} c_ConsoleMouseEvent_t;
typedef enum {
// 基础控制键(单字节即可判定的按键)
C_KEY_UNKNOWN = 0,
C_KEY_ENTER = 13, // 统一回车键
C_KEY_ESC = 27, // 统一 ESC 键
C_KEY_SPACE = 32, // 空格键
C_KEY_BACKSPACE = 127,// 退格键
// 特殊扩展按键(方向键)
C_KEY_UP = 1001,
C_KEY_DOWN = 1002,
C_KEY_LEFT = 1003,
C_KEY_RIGHT = 1004
} c_ConsoleKeyCode_t;
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
/**
* @brief 跨平台初始化控制台环境
* Windows: 激活全局 ANSI 转义序列支持
* Linux/macOS: 关闭行缓冲、关闭按键回显,并注册退出恢复钩子
*/
void c_Console_Init(void);
/**
* @brief 跨平台非阻塞检查是否有键盘输入
* @return
*/
int c_Console_kbhit(void);
/**
* @brief 跨平台直接读取单个按键字符
* @return
*/
int c_Console_getch(void);
/**
*
* @param milliseconds
*/
void c_Console_Sleep(int milliseconds);
/**
* @brief 跨平台清除控制台中的指定行
* @param y 目标行的纵坐标 (从 1 开始计)
*/
void c_Console_BlankLine(int y);
/**
* @brief 从指定坐标 (x, y) 开始清空到该行的末尾
*/
void c_Console_BlankLineFrom(int x, int y);
/**
* @brief 跨平台移动控制台光标到指定坐标
* @param x 目标列坐标 (Column/Horizontal),从 1 开始计,自左向右递增
* @param y 目标行坐标 (Row/Vertical),从 1 开始计,自上向下递增
*/
void c_Console_GotoXY(int x, int y);
/**
* @brief 跨平台获取当前控制台窗口的大小(宽高)
* @param width 用于接收总列数(X方向字符数)的指针
* @param height 用于接收总行数(Y方向字符数)的指针
*/
void c_Console_GetSize(int *width, int *height);
/**
* @brief 在控制台指定行的指定总宽度内,将 UTF-8 文本居中打印
* @param y 目标行坐标 (从 1 开始)
* @param box_width 容器的总宽度(例如整个控制台的宽度,或一个 UI 矩形框的宽度)
* @param str 要打印的 UTF-8 字符串
*/
void c_Console_PrintCenter(int y, int box_width, const char *str);
/**
* @brief 精准计算一个 UTF-8 字符串在控制台上的实际“光标显示宽度”
* @param str 输入的 UTF-8 字符串
* @return 屏幕实际占用的列数(英文字符算 1,中文/日文/韩文等全角字符算 2)
*/
int c_Console_GetVisualWidth(const char *str);
/**
* @brief 格式化等宽对齐打印(常用于表格、菜单选项对齐)
* @param str 要打印的文本
* @param align_len 限定的视觉总宽度(若文本不足此宽度,自动在右侧补齐空格)
*/
void c_Console_PrintLeftAligned(const char *str, int align_len);
/**
* @brief 跨平台在指定坐标处格式化输出 UTF-8 文本
* @param x 目标列坐标 (从 1 开始计)
* @param y 目标行坐标 (从 1 开始计)
* @param format 格式化字符串 (与 printf 完全一致,如 "Score: %d")
* @param ... 可变参数
* @return 成功打印的物理字节数(若失败返回负数)
*/
int c_Console_WriteXY(int x, int y, const char *format, ...);
/**
* @brief 跨平台在指定坐标处,以指定的颜色格式化输出文本
* @param x 目标列坐标 (从 1 开始)
* @param y 目标行坐标 (从 1 开始)
* @param fg 前景色 (文字颜色),传入 C_COLOR_NONE 表示不修改
* @param bg 背景色 (文字底色),传入 C_COLOR_NONE 表示不修改
* @param format 格式化字符串
* @param ... 可变参数
* @return 成功打印的物理字节数
*/
int c_Console_WriteColorXY(int x, int y, c_ConsoleColor_t fg, c_ConsoleColor_t bg, const char *format, ...);
/**
* @brief 开启鼠标事件追踪
*/
void c_Console_EnableMouse(void);
/**
* @brief 关闭鼠标事件追踪(程序退出时必须调用,避免污染用户终端)
*/
void c_Console_DisableMouse(void);
/**
* @brief 跨平台非阻塞读取鼠标事件
* @param mouse_evt 用于接收转换后的通用鼠标事件结构体
* @return int 如果成功捕获到鼠标事件返回 1,否则返回 0
*/
int c_Console_ReadMouse(c_ConsoleMouseEvent_t *mouse_evt);
/**
* @brief 跨平台精准读取并转换键盘按键(包含方向键、Esc、Enter)
* @note 必须确保终端已通过 c_Console_Init() 切换到非阻塞/Raw 模式
* @return int 返回转换后的统一 c_ConsoleKeyCode_t 键值,若为普通字符则原样返回其 ASCII 码
*/
int c_Console_ReadKey(void);
/* ------------------------------------------------------------------------------------------------------------------ */
/* */
C_STATIC_FORCE_INLINE
void c_Console_HideCursor(void) {
printf("\033[?25l");
}
C_STATIC_FORCE_INLINE
void c_Console_ShowCursor(void) {
printf("\033[?25h");
}
#endif /*INCLUDED_C_CONSOLE_H*/