Chapter 177 · XUI 专业控件

CodeEdit 折叠与标记

代码折叠(Fold)、边栏标记(Marker)、诊断(Diagnostic)与 Annotation 注释存储。

177

概念

CodeEdit 边栏系统支持四种 Margin:
• LineNumber:行号栏
• Marker:断点/书签标记栏
• Fold:代码折叠栏(点击折叠/展开代码块)
• Diagnostic:诊断信息栏(错误/警告波浪线)
FoldState 管理折叠状态,AnnotationStore 存储行级注释。

API 速查

函数说明
int xuiCodeEditSetDefaultMargins(pW, bLineNum, bMarker, bFold, bDiag)配置边栏
xui_code_fold_state xuiCodeEditGetFoldState(xui_widget pW)折叠状态
xui_code_annotation_store xuiCodeEditGetAnnotations(xui_widget pW)注释存储
xui_code_margin_model xuiCodeEditGetMargins(xui_widget pW)边栏模型
int xuiCodeMarginModelAdd(pModel, pDesc)添加自定义边栏
int xuiCodeMarginModelSetVisible(pModel, iId, bVisible)显隐边栏
int xuiCodeMarginModelSetWidth(pModel, iId, fWidth)边栏宽度
int xuiCodeEditHitTestDiagnostic(pW, fX, fY, pHit)诊断命中
int xuiCodeEditSetDiagnosticHover(pW, onHover, pUser)诊断悬停

编译本章示例

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

示例:配置边栏与诊断

// 启用全部四种边栏
xuiCodeEditSetDefaultMargins(pEditor, 1, 1, 1, 1);

// 获取边栏模型,调整宽度
xui_code_margin_model pMargins = xuiCodeEditGetMargins(pEditor);
xuiCodeMarginModelSetWidth(pMargins, 0, 50.0f); // 行号栏

// 诊断悬停回调
xuiCodeEditSetDiagnosticHover(pEditor, OnDiagHover, NULL);

// 折叠状态查询
xui_code_fold_state pFold = xuiCodeEditGetFoldState(pEditor);

// 注释存储(断点/书签等标记数据)
xui_code_annotation_store pAnno = xuiCodeEditGetAnnotations(pEditor);

完整代码

将以下代码保存为 ch177_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 = 960; d.iHeight = 640;
    d.sTitle = "ch177 - Margins";
    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, 960, 640);

    // 创建编辑器,启用全部四种边栏
    xui_code_edit_desc_t desc = { 0 };
    xui_widget pEditor;
    xuiCodeEditCreate(g_pCtx, &pEditor, &desc);
    xuiCodeEditSetDefaultMargins(pEditor, 1, 1, 1, 1);
    xuiCodeEditSetLanguage(pEditor, "c");

    // 调整行号栏宽度
    xui_code_margin_model pMargins = xuiCodeEditGetMargins(pEditor);
    xuiCodeMarginModelSetWidth(pMargins, 0, 50.0f);

    // 获取折叠状态和注释存储
    xui_code_fold_state pFold = xuiCodeEditGetFoldState(pEditor);
    xui_code_annotation_store pAnno = xuiCodeEditGetAnnotations(pEditor);
    (void)pFold; (void)pAnno;

    // 设置示例代码
    const char* sCode =
        "#include <stdio.h>\n"
        "\n"
        "int add(int a, int b) {\n"
        "    return a + b;\n"
        "}\n"
        "\n"
        "int main(void) {\n"
        "    printf(\"%d\\n\", add(1, 2));\n"
        "    return 0;\n"
        "}\n";
    xuiCodeEditSetText(pEditor, sCode);

    xui_widget pRoot = xuiGetRootWidget(g_pCtx);
    xuiWidgetAddChild(pRoot, pEditor);
    xuiWidgetSetRect(pEditor, (xui_rect_t){0, 0, 960, 640});

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

代码讲解

  • SetDefaultMargins(1,1,1,1):依次启用行号、标记、折叠、诊断四种边栏。
  • GetMargins + SetWidth:获取边栏模型后可调整各栏宽度。
  • GetFoldState:折叠状态对象,语言分析器自动识别可折叠区域。
  • GetAnnotations:行级元数据存储,用于断点/书签/错误标记持久化。

要点与陷阱

  • MarginModel:支持自定义 Margin,通过 Add 添加并指定渲染回调。
  • Fold 自动:语言分析器自动识别可折叠区域(花括号/缩进)。
  • Diagnostic:HitTestDiagnostic 检测鼠标下方诊断,配合 Tooltip 显示。
  • Annotation:行级元数据存储,用于断点/书签/错误标记持久化。

进阶练习

  1. 断点交互:点击 Marker 边栏切换断点标记。
  2. 错误面板:诊断信息列表,双击跳转到对应行。
CodeEdit 折叠与标记效果
图:CodeEdit 折叠与标记渲染效果