Chapter 173 · XUI 专业控件

CodeEdit 架构

CodeEdit 代码编辑器控件,采用文档/视图/边栏分离架构,支持多语言、主题、Provider 扩展。

173

概念

CodeEdit 是专业代码编辑器,核心架构分层:
• Document:文本存储(xui_code_document),管理行/偏移/Undo
• Selection:选区模型(xui_code_selection_model),多光标
• Theme:语法着色主题(xui_code_theme)
• Margin:边栏(行号/标记/折叠/诊断)
• Provider:补全/悬停/签名/命令扩展
• CommandMap:快捷键→命令映射

API 速查

函数说明
int xuiCodeEditCreate(xui_context pCtx, xui_widget* ppW, const xui_code_edit_desc_t* pDesc)创建编辑器
xui_code_document xuiCodeEditGetDocument(xui_widget pW)获取文档
xui_code_selection_model xuiCodeEditGetSelection(xui_widget pW)获取选区
int xuiCodeEditSetTheme(xui_widget pW, xui_code_theme pTheme)设置主题
int xuiCodeEditSetLanguage(xui_widget pW, const char* sLanguage)设置语言
int xuiCodeEditSetText(xui_widget pW, const char* sText)设置文本
int xuiCodeEditLoadTextFile(xui_widget pW, const char* sPath, int iCharset)加载文件
int xuiCodeEditSetFont(xui_widget pW, xui_font pFont)字体
xui_code_margin_model xuiCodeEditGetMargins(xui_widget pW)边栏模型
xui_code_provider_set xuiCodeEditGetProviders(xui_widget pW)Provider 集
xui_code_command_map xuiCodeEditGetCommandMap(xui_widget pW)快捷键映射

编译本章示例

gcc -O2 -I. -o ch173.exe ch173_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch173.exe

示例:创建代码编辑器

xui_code_edit_desc_t desc = { 0 };

xui_widget pEditor;
xuiCodeEditCreate(pCtx, &pEditor, &desc);

// 设置等宽字体
xuiCodeEditSetFont(pEditor, pMonoFont);

// 默认边栏:行号 + 折叠
xuiCodeEditSetDefaultMargins(pEditor, 1, 0, 1, 0);

// 设置语言
xuiCodeEditSetLanguage(pEditor, "c");

// 加载文件
xuiCodeEditLoadTextFile(pEditor, "main.c", 0);

// Tab 设置
xuiCodeEditSetTabColumns(pEditor, 4);
xuiCodeEditSetExpandTabs(pEditor, 1);

xuiWidgetAddChild(pCenterDock, pEditor);

完整代码

将以下代码保存为 ch173_main.c,编译后运行即可看到一个带行号和折叠栏的代码编辑器:

#include "xge.h"
#include "xui.h"

static xui_context g_pCtx;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x1E1E1EFF);
    xui_vec2_t pos;
    xgeMouseGet(&pos.x, &pos.y);
    xuiInputPointerMove(g_pCtx, pos.x, pos.y);
    if (xgeMouseDown(XGE_MOUSE_LEFT))
        xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
    else
        xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
    xuiUpdate(g_pCtx, xgeGetDelta());
    xuiLayout(g_pCtx);
    xuiRender(g_pCtx, NULL, NULL, 0);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = { 0 };
    d.iWidth = 900; d.iHeight = 640;
    d.sTitle = "ch173 - CodeEdit";
    d.iFlags = XGE_INIT_VSYNC;
    xgeInit(&d);

    xuiCreate(&g_pCtx);
    extern const xui_proxy_t tXgeProxy;
    xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
    xuiSetViewportSize(g_pCtx, 900, 640);

    // 创建代码编辑器
    xui_code_edit_desc_t desc = { 0 };
    xui_widget pEditor;
    xuiCodeEditCreate(g_pCtx, &pEditor, &desc);

    // 行号 + 折叠边栏
    xuiCodeEditSetDefaultMargins(pEditor, 1, 0, 1, 0);

    // C 语言高亮
    xuiCodeEditSetLanguage(pEditor, "c");

    // 设置示例文本
    const char* sCode =
        "#include <stdio.h>\n"
        "\n"
        "int main(void) {\n"
        "    printf(\"Hello XGE!\\n\");\n"
        "    return 0;\n"
        "}\n";
    xuiCodeEditSetText(pEditor, sCode);

    // Tab = 4 空格
    xuiCodeEditSetTabColumns(pEditor, 4);
    xuiCodeEditSetExpandTabs(pEditor, 1);

    // 加入控件树
    xui_widget pRoot = xuiGetRootWidget(g_pCtx);
    xuiWidgetAddChild(pRoot, pEditor);
    xuiWidgetSetRect(pEditor, (xui_rect_t){0, 0, 900, 640});

    xgeRun(onFrame, NULL);
    xuiDestroy(g_pCtx);
    xgeUnit();
    return 0;
}

代码讲解

  • xuiCodeEditCreate:创建编辑器实例,desc 可配置只读/换行等选项。
  • SetDefaultMargins:参数依次为行号、标记、折叠、诊断,这里启用行号和折叠。
  • SetLanguage("c"):激活 C 语言词法分析器,实现关键字/字符串/注释着色。
  • SetText:直接设置文档内容,也可用 LoadTextFile 从磁盘加载。
  • SetTabColumns + SetExpandTabs:Tab 键插入 4 个空格而非制表符。

要点与陷阱

  • Document 独立:Document 可脱离 Widget 存在,支持多视图共享。
  • Provider:通过 ProviderSet 注册补全/悬停回调实现 IDE 功能。
  • CommandMap:LoadDefaults 加载标准快捷键,Bind 自定义。
  • Language:语言决定词法分析器和注释/缩进规则。

进阶练习

  1. 多标签编辑器:Tabs + 多个 CodeEdit 实例切换。
  2. 自定义主题:创建暗色主题并映射 Token 颜色。
CodeEdit 架构效果
图:CodeEdit 架构渲染效果