CodeEdit + MenuBar + StatusBar + Tabs:构建完整的代码编辑环境。
构建一个代码编辑器(类 VS Code 精简版):
• 编辑区:CodeEdit 多标签页
• 菜单栏:MenuBar(文件/编辑/视图/帮助)
• 状态栏:StatusBar(行号/编码/语言)
• 文件树:TreeView 侧边栏
• 终端:Terminal 底部面板
| 模块 | XUI API |
|---|---|
编辑器 | xuiCodeEditCreate + Lexer + Theme |
标签页 | xuiTabsCreate(可关闭/拖拽排序) |
菜单 | xuiMenuBarCreate + 快捷键 |
状态栏 | xuiStatusBarCreate(三段式) |
文件树 | xuiTreeViewCreate(懒加载) |
终端 | xuiTerminalCreate(ConPTY) |
gcc -O2 -I. -o ch204.exe ch204_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch204.exe
// 打开文件到新标签
void OpenFile(const char* sPath) {
// 创建 CodeEdit
xui_code_edit_desc_t tDesc = { 0 };
xui_widget pEdit;
xuiCodeEditCreate(pCtx, &pEdit, &tDesc);
// 加载文件内容
char* sContent = ReadFile(sPath);
xuiCodeEditSetText(pEdit, sContent);
// 设置语法高亮
xuiCodeEditSetLanguage(pEdit,
GetLexerByExt(GetExt(sPath)));
// 添加到标签页
xuiTabsAddPage(pTabs, pEdit,
GetFileName(sPath), 1);
}
// 保存当前文件(Ctrl+S)
void OnSave(void) {
xui_widget pEdit =
xuiTabsGetClientWidget(pTabs);
const char* sText =
xuiCodeEditGetText(pEdit);
WriteFile(g_sCurrentPath, sText);
xuiStatusBarAddText(pStatus,
0, "已保存", 0.0f, 0, 0);
}将以下代码保存为 ch204_main.c,编译后运行即可看到简化版代码编辑器框架(标签页 + CodeEdit + 状态栏):
#include "xge.h"
#include "xui.h"
static xui_context g_pCtx;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x1e1e2e);
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 = "ch204 - Code Editor";
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_widget pRoot;
xuiPanelCreate(g_pCtx, &pRoot, NULL);
xuiWidgetSetRect(pRoot, (xui_rect_t){0, 0, 960, 640});
/* 标签页 */
xui_widget pTabs;
xuiTabsCreate(g_pCtx, &pTabs, NULL);
xuiWidgetAddChild(pRoot, pTabs);
xuiWidgetSetRect(pTabs, (xui_rect_t){0, 0, 960, 600});
xuiWidgetSetRect(pTabs, (xui_rect_t){0, 0, 960, 600});
/* CodeEdit 编辑区 */
xui_code_edit_desc_t tCE = {0};
xui_widget pEdit;
xuiCodeEditCreate(g_pCtx, &pEdit, &tCE);
xuiCodeEditSetText(pEdit, "#include <stdio.h>\nint main() {\n return 0;\n}");
/* 状态栏 */
xui_widget pStatus;
xuiPanelCreate(g_pCtx, &pStatus, NULL);
xuiWidgetAddChild(pRoot, pStatus);
xuiWidgetSetRect(pStatus, (xui_rect_t){0, 600, 960, 40});
xuiWidgetSetRect(pStatus, (xui_rect_t){0, 0, 960, 40});
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}