fix line counter on text wrap, readd cursor

This commit is contained in:
Matthew 2025-10-12 13:53:42 +11:00
parent 00949428b8
commit ada1f5a70a
3 changed files with 121 additions and 43 deletions

View File

@ -248,6 +248,7 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
if(new_ch == '\n' && pos > 0)
{
Logf("yeah");
u8 l = fb.data[pos-1];
u8 r = fb.data[pos];
bool expand = (l == '(' && r == ')') || (l == '{' && r == '}') || (l == '[' && r == ']');
@ -271,7 +272,7 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
}
}
}
else if(new_ch > 0)
else if(new_ch != '\n' && new_ch > 0)
{
length += 1;
insert[1] = new_ch;

View File

@ -1229,7 +1229,7 @@ struct TextBuffer
}
Node!(TextBuffer)*
MakeMultiline(u8[] text, f32 width, u8[] parent_id, u64 line_no, TS[] style = [])
MakeMultiline(u8[] text, f32 width, TS[] style = [])
{
f32 scaled_width = width * (g_ui_ctx.atlas_buf.atlas.size/g_ui_ctx.text_size);
f32 text_width = CalcTextWidth(text);
@ -1249,19 +1249,13 @@ MakeMultiline(u8[] text, f32 width, u8[] parent_id, u64 line_no, TS[] style = []
if(ch_w + w > scaled_width || i == text.length-1)
{
u64 len = i-start;
u8[extra_buf] buf = 0;
(cast(char[])buf).sformat("%s%05s%05s", cast(char[])parent_id, line_no, line);
u8[] str = ScratchAlloc!(u8)(len+extra_buf);
str[0 .. len] = text[start .. start+len];
str[len .. len+extra_buf] = buf[0 .. $];
u8[] str = ScratchAllocCopySlice!(u8)(text, start, len);
TS[] stl = [];
if(style.length > 0)
{
stl = ScratchAlloc!(TS)(len);
stl[0 .. len] = style[start .. start+len];
stl = ScratchAllocCopySlice!(TS)(style, start, len);
}
Node!(TextBuffer)* n = node;
@ -1606,6 +1600,21 @@ DrawBorderedRect(Vec2 pos, Vec2 size, f32 border, f32 radius, f32 softness, Vec4
DrawBorder(pos, size, border, radius, softness, border_col);
}
pragma(inline) Glyph*
GetGlyph(u8 ch)
{
FontAtlas* a = &g_ui_ctx.atlas_buf.atlas;
return ch < a.glyphs.length ? a.glyphs.ptr + ch : a.glyphs.ptr;
}
void
DrawRect(f32 x, f32 y, FontAtlas* atlas, u8 ch, Vec4 col, bool edit_mode)
{
Glyph* g = ch < atlas.glyphs.length ? atlas.glyphs.ptr + ch : atlas.glyphs.ptr;
Vec4[4] cols = col;
DrawRect(Vec2(x, y-TEXT_SIZE*0.8), Vec2(edit_mode ? 1.0 : g.advance, TEXT_SIZE), 0.0, 0.0, cols);
}
void
DrawRect(Vec2 pos, Vec2 size, f32 corner_radius, f32 border, Vec4[4] cols)
{

View File

@ -176,25 +176,36 @@ SetPanelSizes(UIPanel* panel)
}
}
pragma(inline) void
DrawChar(FontAtlas* atlas, u8 ch, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
{
if(ch < atlas.glyphs.length)
{
Glyph* g = atlas.glyphs.ptr + ch;
DrawGlyph(g, 1.0, x_pos, y, col);
}
}
void
Panel2(UIPanel* panel)
{
if(panel.ed == null) return;
UICtx* ctx = GetCtx();
UIItem* item = Get(panel.id);
Editor* ed = panel.ed;
bool focused = GetFocusedPanel() == panel;
UIPanel* parent = panel.parent;
UIPanel* prev = panel.prev;
Vec2 click_adjust = Vec2(
parent.axis == A2D.X ? 10 : 0,
parent.axis == A2D.Y ? 10 : 0
);
if(!Nil(prev))
{
Vec2 p0, p1;
p0.x = parent.axis == A2D.X ? panel.pos.x - 10 : panel.pos.x;
p0.y = parent.axis == A2D.Y ? panel.pos.y - 10 : panel.pos.y;
p1.x = parent.axis == A2D.X ? panel.pos.x + 10 : panel.pos.x + panel.size.x;
p1.y = parent.axis == A2D.Y ? panel.pos.y + 10 : panel.pos.y + panel.size.y;
Vec2 p0 = panel.pos-click_adjust;
Vec2 p1 = panel.pos+panel.size+click_adjust;
if(Dragged(item, p0, p1))
{
@ -215,31 +226,89 @@ Panel2(UIPanel* panel)
}
}
DrawBorderedRect(panel.pos, panel.size, 2.0, 2.0, 0.1, DEFAULT_COL, DEFAULT_BORDER_COL);
i64 rows = cast(i64)ceil(panel.size.y/TEXT_SIZE);
f32 lcw = LineCounter2(panel, 0, rows);
GetLines(&ed.buf, &ed.linebufs, rows);
f32 x = panel.pos.x + lcw;
f32 y = panel.pos.y + TEXT_SIZE;
for(auto buf = ed.linebufs.first; buf != null; buf = buf.next)
if(panel.ed != null)
{
f32 x_pos = x;
foreach(i; 0 .. buf.text.length)
if(Clicked(item, panel.pos, panel.pos+panel.size-click_adjust))
{
if(buf.text[i] < ctx.atlas_buf.atlas.glyphs.length)
{
Glyph* g = ctx.atlas_buf.atlas.glyphs.ptr + buf.text[i];
DrawGlyph(g, 1.0, &x_pos, y, buf.style[i]);
}
SetFocusedPanel(panel);
}
y += TEXT_SIZE;
DrawBorderedRect(panel.pos, panel.size, 2.0, 2.0, 0.1, DEFAULT_COL, focused ? HL_BORDER_COL : DEFAULT_BORDER_COL);
i64 rows = cast(i64)ceil(panel.size.y/TEXT_SIZE);
GetLines(&ed.buf, &ed.linebufs, rows);
i64 offset = ed.buf.offset;
i64 end = offset + ed.linebufs.count;
char[64] ch_buf = '\0';
char[] fmt = ch_buf.sformat("%%0%ss", u64(end.toChars().length));
u8[] end_line_text = ScratchAlloc!(u8)(end.toChars().length);
end_line_text[] = '0';
f32 lcw = CalcTextWidth(end_line_text);
f32 padding = 4.0;
DrawRect(panel.pos, panel.pos+Vec2(lcw+padding*2, panel.size.y), 0.0, 0.0, focused ? LC_HL_COLOR : LC_COLOR);
f32 x = panel.pos.x;
f32 y = panel.pos.y + TEXT_SIZE;
auto atlas = &ctx.atlas_buf.atlas;
bool edit = EditModeActive();
U64Vec2 pos = VecPos(&ed.buf);
u64 i;
for(auto buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1)
{
f32 x_pos = x + padding;
char[32] line_buf = '\0';
char[] line_str = sformat(line_buf, fmt, offset+i);
foreach(j; 0 .. line_str.length)
{
DrawChar(&ctx.atlas_buf.atlas, line_str[j], &x_pos, y, Vec4(1.0));
}
x_pos += padding;
u64 ch_offset;
auto parts = MakeMultiline(buf.text, panel.size.x-lcw, buf.style);
for(auto n = parts; n != null; n = n.next)
{
auto l = &n.value;
if(pos.y == i)
{
f32 hl_x = x + lcw + padding*2.0;
Glyph* g = GetGlyph(' ');
foreach(j; 0 .. l.text.length)
{
bool hl = j == pos.x-ch_offset;
if(hl)
{
break;
}
g = j == l.text.length-1 ? GetGlyph(' ') : GetGlyph(l.text[j]);
hl_x += GlyphWidth(g);
}
DrawRect(hl_x, y, atlas, cast(u8)g.ch, Vec4(1.0), edit);
}
foreach(j; 0 .. l.text.length)
{
bool hl = pos.y == i && !edit && j == pos.x-ch_offset;
DrawChar(&ctx.atlas_buf.atlas, l.text[j], &x_pos, y, hl ? Vec4(Vec3(0.0), 1.0) : SYNTAX_COLORS[l.style[j]]);
}
y += TEXT_SIZE;
x_pos = x + lcw + padding*2.0;
ch_offset += l.text.length;
}
}
}
}
@ -284,11 +353,7 @@ LineCounter2(UIPanel* panel, i64 start_row, i64 end_row)
foreach(j; 0 .. line_counts[i].length)
{
if(line_counts[i][j] < ctx.atlas_buf.atlas.glyphs.length)
{
Glyph* g = ctx.atlas_buf.atlas.glyphs.ptr + line_counts[i][j];
DrawGlyph(g, 1.0, &x_pos, y, Vec4(1.0));
}
DrawChar(&ctx.atlas_buf.atlas, line_counts[i][j], &x_pos, y);
}
y += TEXT_SIZE;
@ -639,6 +704,7 @@ TextClicked(TextPart* text_part)
TextPart*
WrappedTextLine(u8[] text, u8[] parent_id, f32 text_size, u64 line_no, TS[] style = [], U64Vec2* hl_pos, bool focused)
{
/*
Push!("color")(Vec4(1.0));
Push!("text_size")(text_size);
@ -696,6 +762,8 @@ WrappedTextLine(u8[] text, u8[] parent_id, f32 text_size, u64 line_no, TS[] styl
Pop!("color");
return part;
*/
return null;
}
UIItem*