TextEdit 多行文本编辑器,支持自动换行、行号、选区、查找替换、撤销重做与滚动。
TextEdit 是功能完整的多行编辑器:
• WordWrap:自动换行
• LineNumbers:行号侧栏
• Find/Replace:内置查找替换面板
• Undo/Redo:操作历史
• Scroll:内置水平/垂直滚动条
| 函数 | 说明 |
|---|---|
int xuiTextEditCreate(xui_context pCtx, xui_widget* ppW, const xui_text_edit_desc_t* pDesc) | 创建多行编辑 |
int xuiTextEditSetText(xui_widget pW, const char* sText) | 设置文本 |
const char* xuiTextEditGetText(xui_widget pW) | 获取文本 |
int xuiTextEditSetWordWrap(xui_widget pW, int bWrap) | 自动换行 |
int xuiTextEditSetLineNumbers(xui_widget pW, int bVisible, float fWidth) | 行号 |
int xuiTextEditSetSelection(xui_widget pW, int iStart, int iEnd) | 设置选区 |
int xuiTextEditFindNext(xui_widget pW, const xui_find_options_t* pOpt) | 查找下一个 |
int xuiTextEditReplaceAll(xui_widget pW, const xui_find_options_t* pOpt, int* pCount) | 全部替换 |
int xuiTextEditUndo(xui_widget pW) | 撤销 |
int xuiTextEditRedo(xui_widget pW) | 重做 |
int xuiTextEditGetLineCount(xui_widget pW) | 行数 |
int xuiTextEditSetScroll(xui_widget pW, float fX, float fY) | 滚动位置 |
gcc -O2 -I. -o ch140.exe ch140_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch140.exe
xui_text_edit_desc_t desc = { 0 };
xui_widget pEdit;
xuiTextEditCreate(pCtx, &pEdit, &desc);
// 只读 + 行号 + 自动换行
xuiTextEditSetReadonly(pEdit, 1);
xuiTextEditSetLineNumbers(pEdit, 1, 48.0f);
xuiTextEditSetWordWrap(pEdit, 1);
// 追加日志
char buf[4096];
snprintf(buf, sizeof(buf), "%s[INFO] Frame %d\n",
xuiTextEditGetText(pEdit), iFrame);
xuiTextEditSetText(pEdit, buf);
// 滚动到底部
xuiTextEditSetScroll(pEdit, 0,
xuiTextEditGetLineCount(pEdit) * 20.0f);
// 查找功能
xui_find_options_t opt = { .sPattern = "ERROR" };
xuiTextEditFindNext(pEdit, &opt);将以下代码保存为 ch140_main.c,编译后运行即可看到多行文本编辑器:
#include "xge.h"
#include "xui.h"
#include <stdio.h>
static xui_context g_pCtx;
static xui_widget g_pEdit;
static int g_nFrame = 0;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x081114FF);
float mx, my;
xgeMouseGet(&mx, &my);
xuiInputPointerMove(g_pCtx, mx, my, 0);
if (xgeMouseDown(XGE_MOUSE_LEFT))
xuiInputPointerDown(g_pCtx, mx, my, 0, 1);
if (!xgeMouseDown(XGE_MOUSE_LEFT) /* 释放边沿建议改用事件 */)
xuiInputPointerUp(g_pCtx, mx, my, 0, 0);
// 每 60 帧追加一行日志
if (++g_nFrame % 60 == 0) {
char buf[4096];
snprintf(buf, sizeof(buf),
"%s[INFO] Frame %d\n",
xuiTextEditGetText(g_pEdit),
g_nFrame);
xuiTextEditSetText(g_pEdit, buf);
}
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 = 800;
d.iHeight = 600;
d.sTitle = "ch140 - TextEdit";
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, 800, 600);
// 创建多行编辑器
xui_text_edit_desc_t desc = { 0 };
xuiTextEditCreate(g_pCtx, &g_pEdit, &desc);
xuiTextEditSetLineNumbers(g_pEdit, 1, 48.0f);
xuiTextEditSetWordWrap(g_pEdit, 1);
xuiWidgetSetRect(g_pEdit,
(xui_rect_t){ 50, 50, 700, 500 });
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}