text buffer working
This commit is contained in:
parent
d233c65304
commit
6503dae769
@ -8,11 +8,11 @@ struct FlatBuffer
|
|||||||
{
|
{
|
||||||
Tokenizer tk;
|
Tokenizer tk;
|
||||||
Arena arena;
|
Arena arena;
|
||||||
U64Vec2 pos;
|
I64Vec2 pos;
|
||||||
u8[] data;
|
u8[] data;
|
||||||
u64 length;
|
u64 length;
|
||||||
u64 line_count;
|
u64 lf_count;
|
||||||
u64 buf_pos;
|
i64 buf_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LineBuffers
|
struct LineBuffers
|
||||||
@ -21,6 +21,13 @@ struct LineBuffers
|
|||||||
u8[][] lines;
|
u8[][] lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum WalkDir
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Backward = -1,
|
||||||
|
Forward = +1,
|
||||||
|
}
|
||||||
|
|
||||||
FlatBuffer
|
FlatBuffer
|
||||||
CreateFlatBuffer(u8[] data)
|
CreateFlatBuffer(u8[] data)
|
||||||
{
|
{
|
||||||
@ -29,12 +36,12 @@ CreateFlatBuffer(u8[] data)
|
|||||||
u8[] buf = MAllocArray!(u8)(capacity);
|
u8[] buf = MAllocArray!(u8)(capacity);
|
||||||
buf[0 .. data.length] = data[0 .. data.length];
|
buf[0 .. data.length] = data[0 .. data.length];
|
||||||
|
|
||||||
u64 line_count = 1;
|
u64 lf_count = 0;
|
||||||
for(u64 i = 0; i < cast(u64)data.length; i += 1)
|
for(u64 i = 0; i < cast(u64)data.length; i += 1)
|
||||||
{
|
{
|
||||||
if(data.ptr[i] == '\n')
|
if(data.ptr[i] == '\n')
|
||||||
{
|
{
|
||||||
line_count += 1;
|
lf_count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +49,7 @@ CreateFlatBuffer(u8[] data)
|
|||||||
arena: CreateArena(MB(1)),
|
arena: CreateArena(MB(1)),
|
||||||
data: buf,
|
data: buf,
|
||||||
length: cast(u64)data.length,
|
length: cast(u64)data.length,
|
||||||
line_count: line_count,
|
lf_count: lf_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
fb.tk = CreateTokenizer(&fb);
|
fb.tk = CreateTokenizer(&fb);
|
||||||
@ -73,9 +80,14 @@ Insert(FlatBuffer* buffer, u8[] insert, u64 length, u64 pos)
|
|||||||
|
|
||||||
for(u64 i = 0; i < length; i += 1)
|
for(u64 i = 0; i < length; i += 1)
|
||||||
{
|
{
|
||||||
|
buffer.buf_pos += 1;
|
||||||
|
buffer.pos.x += 1;
|
||||||
|
|
||||||
if(insert.ptr[i] == '\n')
|
if(insert.ptr[i] == '\n')
|
||||||
{
|
{
|
||||||
buffer.line_count += 1;
|
buffer.lf_count += 1;
|
||||||
|
buffer.pos.y += 1;
|
||||||
|
buffer.pos.x = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,19 +105,25 @@ Insert(FlatBuffer* buffer, u8[] insert, u64 length, u64 pos)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Insert(FlatBuffer* buffer, u8[] insert, u64 length, UVec2 pos)
|
Insert(FlatBuffer* buffer, u8[] insert, u64 length)
|
||||||
{
|
{
|
||||||
assert(pos.y <= buffer.line_count, "Insert failure: y provided is greater than line_count");
|
Insert(buffer, insert, length, buffer.buf_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Insert(FlatBuffer* buffer, u8[] insert, u64 length, I64Vec2 pos)
|
||||||
|
{
|
||||||
|
assert(pos.y <= buffer.lf_count, "Insert failure: y provided is greater than lf_count");
|
||||||
|
|
||||||
Insert(buffer, insert, length, VecToPos(buffer, pos));
|
Insert(buffer, insert, length, VecToPos(buffer, pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle case for when lines are longer than line buffer
|
|
||||||
void
|
void
|
||||||
GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
|
GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
|
||||||
{
|
{
|
||||||
assert(linebufs != null, "GetLines failure: linebufs is null");
|
assert(linebufs != null, "GetLines failure: linebufs is null");
|
||||||
length = length > buffer.line_count ? buffer.line_count : length;
|
u64 line_count = buffer.lf_count + 1;
|
||||||
|
length = length > line_count ? line_count : length;
|
||||||
|
|
||||||
Reset(&linebufs.arena);
|
Reset(&linebufs.arena);
|
||||||
linebufs.lines = AllocArray!(u8[])(&linebufs.arena, length);
|
linebufs.lines = AllocArray!(u8[])(&linebufs.arena, length);
|
||||||
@ -138,7 +156,6 @@ GetLines(FlatBuffer* buffer, LineBuffers* linebufs, u64 start_line, u64 length)
|
|||||||
if(start < 0)
|
if(start < 0)
|
||||||
{
|
{
|
||||||
start = cast(i64)i;
|
start = cast(i64)i;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_line)
|
if(new_line)
|
||||||
@ -210,45 +227,95 @@ Move(FlatBuffer* buffer, Input key, Modifier md)
|
|||||||
switch(key)
|
switch(key)
|
||||||
{
|
{
|
||||||
case Input.Down:
|
case Input.Down:
|
||||||
|
{
|
||||||
|
if(buffer.pos.y < buffer.lf_count)
|
||||||
|
{
|
||||||
|
i64 x = buffer.pos.x;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(buffer.data[buffer.buf_pos] == '\n')
|
||||||
|
{
|
||||||
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(buffer.data[buffer.buf_pos] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer.pos.x == x)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case Input.Up:
|
case Input.Up:
|
||||||
{
|
{
|
||||||
if((Input.Up && buffer.pos.y > 0) || (Input.Down && buffer.pos.y < buffer.line_count))
|
if(buffer.pos.y > 0)
|
||||||
{
|
{
|
||||||
u32 x = buffer.pos.x;
|
i64 new_l = 0;
|
||||||
buffer.pos.x = 0;
|
i64 x = buffer.pos.x;
|
||||||
buffer.pos.y += key == Input.Down ? 1 : -1;
|
for(;;)
|
||||||
u64 pos = VecToPos(buffer, buffer.pos);
|
{
|
||||||
u64 i = pos;
|
if(buffer.buf_pos == 0)
|
||||||
for(; i < pos+x && buffer.data[i] != '\n'; i += 1) {}
|
{
|
||||||
buffer.pos.x = cast(u32)(i - pos);
|
break;
|
||||||
buffer.buf_pos = i;
|
}
|
||||||
|
|
||||||
|
Walk!(WalkDir.Backward)(buffer);
|
||||||
|
|
||||||
|
if(buffer.data[buffer.buf_pos] == '\n')
|
||||||
|
{
|
||||||
|
Logf("1");
|
||||||
|
new_l += 1;
|
||||||
|
if(new_l == 2)
|
||||||
|
{
|
||||||
|
Logf("2");
|
||||||
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logf("sol reached %s", buffer.pos.v);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if(buffer.data[buffer.buf_pos] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer.pos.x >= x)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case Input.Left:
|
case Input.Left:
|
||||||
|
{
|
||||||
|
if(buffer.pos.x != 0)
|
||||||
|
{
|
||||||
|
Walk!(WalkDir.Backward)(buffer);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case Input.Right:
|
case Input.Right:
|
||||||
{
|
{
|
||||||
if((Input.Left && buffer.buf_pos > 0) || (Input.Right && buffer.buf_pos < buffer.length))
|
if(buffer.buf_pos < buffer.length && buffer.data[buffer.buf_pos] != '\n')
|
||||||
{
|
{
|
||||||
u64 move = key == Input.Left ? -1 : +1;
|
Walk!(WalkDir.Forward)(buffer);
|
||||||
buffer.buf_pos += move;
|
|
||||||
if(buffer.data[buffer.buf_pos] == '\n')
|
|
||||||
{
|
|
||||||
u64 x = buffer.pos.x;
|
|
||||||
buffer.pos.y += move;
|
|
||||||
buffer.pos.x = 0;
|
|
||||||
if(key == Input.Left)
|
|
||||||
{
|
|
||||||
u64 pos = VecToPos(buffer, buffer.pos);
|
|
||||||
u64 i = pos;
|
|
||||||
for(; i < pos+x && buffer.data[i] != '\n'; i += 1) {}
|
|
||||||
buffer.pos.x = cast(u32)(i - pos);
|
|
||||||
buffer.buf_pos = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer.pos.x += move;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
@ -256,19 +323,19 @@ Move(FlatBuffer* buffer, Input key, Modifier md)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logf("%s %s", buffer.buf_pos, buffer.pos.v);
|
Logf("%s %s", buffer.buf_pos, buffer.pos.v);
|
||||||
|
//VerifyPosition(buffer, key, md);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64
|
u64
|
||||||
RelVecToPos(FlatBuffer* buffer, U64Vec2 vec)
|
VecToPos(FlatBuffer* buffer, I64Vec2 vec)
|
||||||
{
|
{
|
||||||
u64 pos = 0;
|
u64 pos, line, col;
|
||||||
bool closer_to_start = abs(buffer.pos.y - vec.x) > vec.x;
|
bool closer_to_start = abs(buffer.pos.y - vec.x) > vec.x;
|
||||||
if(closer_to_start)
|
if(closer_to_start)
|
||||||
{
|
{
|
||||||
u32 line, col;
|
for(; pos < buffer.length; pos += 1)
|
||||||
for(; i < buffer.length; pos += 1)
|
|
||||||
{
|
{
|
||||||
if(range.y == line)
|
if(vec.y == line)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -279,31 +346,248 @@ RelVecToPos(FlatBuffer* buffer, U64Vec2 vec)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(; buffer_pos < buffer.length; pos += 1)
|
for(; pos < buffer.length; pos += 1)
|
||||||
{
|
{
|
||||||
if(col == range.x)
|
if(buffer.data.ptr[pos] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(col == vec.x)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
col += 1;
|
col += 1;
|
||||||
|
|
||||||
assert(buffer.data.ptr[i] != '\n', "Insert FlatBuffer Range failure: x position not in range of line");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u64 move = buffer.pos.y < vec.y || (buffer.pos.y == vec.y && buffer.pos.x < vec.pos.x) ? -1 : +1;
|
u64 move = buffer.pos.y < vec.y || (buffer.pos.y == vec.y && buffer.pos.x < vec.x) ? -1 : +1;
|
||||||
|
for(pos = buffer.buf_pos; pos < buffer.length && pos > 0; pos += move)
|
||||||
|
{
|
||||||
|
if(vec.y == line)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer.data.ptr[pos] == '\n')
|
||||||
|
{
|
||||||
|
line += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; pos < buffer.length; pos += move)
|
||||||
|
{
|
||||||
|
if(col == vec.x)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer.data.ptr[pos] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
col += move;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64
|
void
|
||||||
VecToPos(FlatBuffer* buffer, U64Vec2 vec)
|
Backspace(FlatBuffer* buffer, u64 length)
|
||||||
{
|
{
|
||||||
|
if(buffer.buf_pos-length > 0)
|
||||||
|
{
|
||||||
|
u8[] del = buffer.data[buffer.buf_pos-length .. buffer.buf_pos];
|
||||||
|
u8 ch = buffer.data[buffer.buf_pos];
|
||||||
|
buffer.buf_pos -= 1;
|
||||||
|
Delete(buffer, length, buffer.buf_pos);
|
||||||
|
if(ch == '\n')
|
||||||
|
{
|
||||||
|
|
||||||
return buffer_pos;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AdjustLinePos(FlatBuffer* buffer, i64 adj)
|
||||||
|
{
|
||||||
|
if(buffer.buf_pos+adj <= 0)
|
||||||
|
{
|
||||||
|
buffer.buf_pos = 0;
|
||||||
|
buffer.pos = 0;
|
||||||
|
}
|
||||||
|
else if(buffer.buf_pos+adj >= buffer.length)
|
||||||
|
{
|
||||||
|
buffer.buf_pos = buffer.length;
|
||||||
|
buffer.pos.y = buffer.lf_count;
|
||||||
|
buffer.pos.x = PosInLine(buffer, buffer.buf_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline) i64
|
||||||
|
MoveToPrevLine(FlatBuffer* buffer)
|
||||||
|
{
|
||||||
|
i64 adj = 0;
|
||||||
|
|
||||||
|
with(buffer)
|
||||||
|
{
|
||||||
|
if(pos.y == 0)
|
||||||
|
{
|
||||||
|
adj = -pos.x;
|
||||||
|
pos.x = 0;
|
||||||
|
buf_pos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i64 p = buf_pos;
|
||||||
|
if(buffer.data[p] == '\n')
|
||||||
|
{
|
||||||
|
p -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; p > 0 && data[p] != '\n'; p -= 1) {}
|
||||||
|
|
||||||
|
buf_pos = p;
|
||||||
|
pos.y -= 1;
|
||||||
|
Logf("pos in line %s", PosInLine(buffer, p));
|
||||||
|
pos.x = PosInLine(buffer, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adj;
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline) i64
|
||||||
|
MoveToNextLine(FlatBuffer* buffer)
|
||||||
|
{
|
||||||
|
i64 adj = 0;
|
||||||
|
|
||||||
|
with(buffer)
|
||||||
|
{
|
||||||
|
if(pos.y == lf_count)
|
||||||
|
{
|
||||||
|
Logf("upper");
|
||||||
|
adj = length - buf_pos;
|
||||||
|
pos.x += adj;
|
||||||
|
buf_pos += adj;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logf("lower");
|
||||||
|
i64 p = buf_pos;
|
||||||
|
u8 prev = 0;
|
||||||
|
for(; p < length; p += 1)
|
||||||
|
{
|
||||||
|
if(p > 0 && data[p-1] == '\n')
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.x = 0;
|
||||||
|
pos.y += 1;
|
||||||
|
buf_pos = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return adj;
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline) void
|
||||||
|
Walk(alias dir)(FlatBuffer* buffer)
|
||||||
|
{
|
||||||
|
Logf("%s", buffer.pos.v);
|
||||||
|
static if(dir == WalkDir.Backward)
|
||||||
|
{
|
||||||
|
buffer.buf_pos -= 1;
|
||||||
|
if(buffer.data[buffer.buf_pos] == '\n')
|
||||||
|
{
|
||||||
|
buffer.pos.y -= 1;
|
||||||
|
buffer.pos.x = PosInLine(buffer, buffer.buf_pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.pos.x -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(buffer.pos.y >= 0);
|
||||||
|
assert(buffer.pos.x >= 0);
|
||||||
|
}
|
||||||
|
else static if(dir == WalkDir.Forward)
|
||||||
|
{
|
||||||
|
buffer.buf_pos += 1;
|
||||||
|
if(buffer.data[buffer.buf_pos-1] == '\n')
|
||||||
|
{
|
||||||
|
buffer.pos.y += 1;
|
||||||
|
buffer.pos.x = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.pos.x += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Logf("%s", buffer.pos.v);
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline) void
|
||||||
|
VerifyPosition(FlatBuffer* buffer, Input input, Modifier md)
|
||||||
|
{
|
||||||
|
debug
|
||||||
|
{
|
||||||
|
with(buffer)
|
||||||
|
{
|
||||||
|
I64Vec2 p = 0;
|
||||||
|
i64 i = 0;
|
||||||
|
for(; i < length && p != pos; i += 1)
|
||||||
|
{
|
||||||
|
if(data[i] == '\n')
|
||||||
|
{
|
||||||
|
p.x = 0;
|
||||||
|
p.y += 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p.x += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logf("%s %s", p.v, pos.v);
|
||||||
|
|
||||||
|
assert(p.y <= pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i != buf_pos || p != pos)
|
||||||
|
{
|
||||||
|
Logf("Buffer positions not in sync: expected: %s %s %s result: %s %s %s", i, p.v, cast(char)data[i], buf_pos, pos.v, cast(char)data[buf_pos]);
|
||||||
|
Logf("Input: %s Shift: %s Ctrl: %s", input, md & (MD.LeftShift|MD.RightShift), md & (MD.LeftCtrl|MD.RightCtrl));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma(inline) i64
|
||||||
|
PosInLine(FlatBuffer* buffer, i64 pos)
|
||||||
|
{
|
||||||
|
assert(pos >= 0 && pos <= buffer.length);
|
||||||
|
|
||||||
|
i64 p = pos;
|
||||||
|
i64 line_pos = 0;
|
||||||
|
if(buffer.data[p] == '\n')
|
||||||
|
{
|
||||||
|
p -= 1;
|
||||||
|
line_pos += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; p > 0 && buffer.data[p] != '\n'; p -= 1, line_pos += 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return line_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -786,7 +1070,7 @@ unittest
|
|||||||
u8[] data = StringToU8("This is a line.\nThis is a second line,\nalong with a third line.");
|
u8[] data = StringToU8("This is a line.\nThis is a second line,\nalong with a third line.");
|
||||||
FlatBuffer buf = CreateFlatBuffer(data);
|
FlatBuffer buf = CreateFlatBuffer(data);
|
||||||
|
|
||||||
assert(buf.line_count == 3, "FlatBuffer line count mismatch");
|
assert(buf.lf_count == 3, "FlatBuffer line count mismatch");
|
||||||
|
|
||||||
u8[] insert = StringToU8("Maybe, ");
|
u8[] insert = StringToU8("Maybe, ");
|
||||||
Insert(&buf, insert, insert.length, Range(x: 0, y: 1));
|
Insert(&buf, insert, insert.length, Range(x: 0, y: 1));
|
||||||
|
|||||||
@ -49,11 +49,13 @@ enum EditState
|
|||||||
NormalMode,
|
NormalMode,
|
||||||
InputMode,
|
InputMode,
|
||||||
CmdOpen,
|
CmdOpen,
|
||||||
SetPanelFocus,
|
SetPanelFocus, // if moving left/right move up parent tree until one is found with a2d.x, same thing for up/down a2d.y
|
||||||
}
|
}
|
||||||
|
|
||||||
alias ES = EditState;
|
alias ES = EditState;
|
||||||
|
|
||||||
|
bool g_input_mode = false;
|
||||||
|
|
||||||
void
|
void
|
||||||
Cycle(EditorCtx* ctx, Inputs* inputs)
|
Cycle(EditorCtx* ctx, Inputs* inputs)
|
||||||
{
|
{
|
||||||
@ -63,6 +65,8 @@ Cycle(EditorCtx* ctx, Inputs* inputs)
|
|||||||
|
|
||||||
HandleInputs(ctx, inputs);
|
HandleInputs(ctx, inputs);
|
||||||
|
|
||||||
|
g_input_mode = ctx.state == ES.InputMode;
|
||||||
|
|
||||||
BeginBuild(inputs);
|
BeginBuild(inputs);
|
||||||
|
|
||||||
DrawPanels(ctx.base_panel);
|
DrawPanels(ctx.base_panel);
|
||||||
@ -103,6 +107,12 @@ CreatePanel(EditorCtx* ctx)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
EditModeActive()
|
||||||
|
{
|
||||||
|
return g_input_mode;
|
||||||
|
}
|
||||||
|
|
||||||
// Load all files then move things into editor after being created when selected
|
// Load all files then move things into editor after being created when selected
|
||||||
|
|
||||||
Editor*
|
Editor*
|
||||||
@ -203,7 +213,7 @@ InsertInputToBuf(EditorCtx* ctx)
|
|||||||
UIPanel* p = GetFocusedPanel();
|
UIPanel* p = GetFocusedPanel();
|
||||||
if(!Nil(p))
|
if(!Nil(p))
|
||||||
{
|
{
|
||||||
Insert(&p.ed.buf, ctx.input_buf, ctx.icount, 0);
|
Insert(&p.ed.buf, ctx.input_buf, ctx.icount);
|
||||||
ctx.icount = 0;
|
ctx.icount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -312,6 +322,10 @@ HandleInputMode(EditorCtx* ctx, InputEvent ev)
|
|||||||
switch(ev.key)
|
switch(ev.key)
|
||||||
{
|
{
|
||||||
mixin(CharCases());
|
mixin(CharCases());
|
||||||
|
case Input.Backspace:
|
||||||
|
{
|
||||||
|
|
||||||
|
} break;
|
||||||
case Input.Escape:
|
case Input.Escape:
|
||||||
{
|
{
|
||||||
ctx.state = ES.NormalMode;
|
ctx.state = ES.NormalMode;
|
||||||
|
|||||||
@ -111,6 +111,7 @@ struct UICtx
|
|||||||
f32 border_thickness;
|
f32 border_thickness;
|
||||||
f32 corner_radius;
|
f32 corner_radius;
|
||||||
f32 edge_softness;
|
f32 edge_softness;
|
||||||
|
i64 highlighted_char;
|
||||||
|
|
||||||
debug u32 item_count;
|
debug u32 item_count;
|
||||||
debug u32 final_count;
|
debug u32 final_count;
|
||||||
@ -149,6 +150,7 @@ struct UIItem
|
|||||||
Axis2D layout_axis;
|
Axis2D layout_axis;
|
||||||
UISize[2] size_info;
|
UISize[2] size_info;
|
||||||
Vec2 adjustment;
|
Vec2 adjustment;
|
||||||
|
i64 highlighted_char;
|
||||||
|
|
||||||
// Calculated Parameters
|
// Calculated Parameters
|
||||||
Vec2 size;
|
Vec2 size;
|
||||||
@ -481,10 +483,15 @@ SetAdjustment(Vec2 adj)
|
|||||||
g_ui_ctx.adjustment = adj;
|
g_ui_ctx.adjustment = adj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetHighlightedChar(i64 pos)
|
||||||
|
{
|
||||||
|
g_ui_ctx.highlighted_char = pos;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SetDebug(bool dbg)
|
SetDebug(bool dbg)
|
||||||
{
|
{
|
||||||
Logf("Set");
|
|
||||||
debug
|
debug
|
||||||
{
|
{
|
||||||
g_ui_ctx.dbg = dbg;
|
g_ui_ctx.dbg = dbg;
|
||||||
@ -578,10 +585,6 @@ BeginBuild(Inputs* inputs)
|
|||||||
|
|
||||||
ctx.inputs = inputs;
|
ctx.inputs = inputs;
|
||||||
|
|
||||||
memset(ctx.buffers[ctx.f_idx].vtx.ptr, 0, Vertex.sizeof * ctx.buffers[ctx.f_idx].count);
|
|
||||||
memset(ctx.buffers[ctx.f_idx].idx.ptr, 0, u32.sizeof * ctx.buffers[ctx.f_idx].count);
|
|
||||||
ctx.buffers[ctx.f_idx].count = 0;
|
|
||||||
|
|
||||||
ctx.panel_level = 0;
|
ctx.panel_level = 0;
|
||||||
|
|
||||||
ctx.root = Root();
|
ctx.root = Root();
|
||||||
@ -651,6 +654,10 @@ PrepRendering(UICtx* ctx)
|
|||||||
PushConstants(&ctx.rd, ctx.pipeline, &ctx.pc);
|
PushConstants(&ctx.rd, ctx.pipeline, &ctx.pc);
|
||||||
|
|
||||||
Bind(&ctx.rd, ctx.pipeline, ctx.desc_set);
|
Bind(&ctx.rd, ctx.pipeline, ctx.desc_set);
|
||||||
|
|
||||||
|
memset(ctx.buffers[ctx.f_idx].vtx.ptr, 0, Vertex.sizeof * ctx.buffers[ctx.f_idx].count);
|
||||||
|
memset(ctx.buffers[ctx.f_idx].idx.ptr, 0, u32.sizeof * ctx.buffers[ctx.f_idx].count);
|
||||||
|
ctx.buffers[ctx.f_idx].count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -825,6 +832,7 @@ BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties)
|
|||||||
item.corner_radius = ctx.corner_radius;
|
item.corner_radius = ctx.corner_radius;
|
||||||
item.edge_softness = ctx.edge_softness;
|
item.edge_softness = ctx.edge_softness;
|
||||||
item.last_frame = ctx.frame;
|
item.last_frame = ctx.frame;
|
||||||
|
item.highlighted_char = ctx.highlighted_char;
|
||||||
|
|
||||||
item.parent = ctx.top_parent == g_UI_NIL_NODE ? g_UI_NIL : ctx.top_parent.item;
|
item.parent = ctx.top_parent == g_UI_NIL_NODE ? g_UI_NIL : ctx.top_parent.item;
|
||||||
if(!Nil(item.parent))
|
if(!Nil(item.parent))
|
||||||
@ -1100,7 +1108,7 @@ DrawPanelDebug(UICtx* ctx, UIItem* item)
|
|||||||
f32 x0 = x;
|
f32 x0 = x;
|
||||||
for(u64 i = 0; i < text.length; i += 1)
|
for(u64 i = 0; i < text.length; i += 1)
|
||||||
{
|
{
|
||||||
DrawGlyph(&ctx.atlas_buf.atlas.glyphs[text[i]], ctx.atlas_buf.atlas.size/ctx.text_size, &x0, y);
|
DrawGlyph(item, &ctx.atlas_buf.atlas.glyphs[text[i]], ctx.atlas_buf.atlas.size/ctx.text_size, &x0, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
f32 pct = item.parent.layout_axis == A2D.X ? item.size_info[A2D.X].value : item.size_info[A2D.Y].value;
|
f32 pct = item.parent.layout_axis == A2D.X ? item.size_info[A2D.X].value : item.size_info[A2D.Y].value;
|
||||||
@ -1110,7 +1118,7 @@ DrawPanelDebug(UICtx* ctx, UIItem* item)
|
|||||||
y += 16.0;
|
y += 16.0;
|
||||||
for(u64 i = 0; i < buf.length && buf[i] != 0; i += 1)
|
for(u64 i = 0; i < buf.length && buf[i] != 0; i += 1)
|
||||||
{
|
{
|
||||||
DrawGlyph(&ctx.atlas_buf.atlas.glyphs[buf[i]], ctx.atlas_buf.atlas.size/ctx.text_size, &x, y);;
|
DrawGlyph(item, &ctx.atlas_buf.atlas.glyphs[buf[i]], ctx.atlas_buf.atlas.size/ctx.text_size, &x, y);;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1128,22 +1136,46 @@ DrawLine(UIItem* item)
|
|||||||
u8 ch = item.key.text.ptr[i];
|
u8 ch = item.key.text.ptr[i];
|
||||||
if(ch < 128)
|
if(ch < 128)
|
||||||
{
|
{
|
||||||
DrawGlyph(&atlas.glyphs[ch], atlas.size/ctx.text_size, &x, y);
|
DrawGlyph(item, &atlas.glyphs[ch], atlas.size/ctx.text_size, &x, y, i == item.highlighted_char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(item.highlighted_char >= 0)
|
||||||
|
{
|
||||||
|
y = item.rect.y0 + 2;
|
||||||
|
x = item.rect.x0;
|
||||||
|
UIPanel* panel = GetFocusedPanel();
|
||||||
|
bool text_in_focus = panel.id == item.parent.key.text;
|
||||||
|
|
||||||
|
f32 adv = atlas.glyphs[' '].advance;
|
||||||
|
Vertex* v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count;
|
||||||
|
for(u64 i = 0; i < item.highlighted_char; i += 1)
|
||||||
|
{
|
||||||
|
x += adv;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.dst_start.x = x;
|
||||||
|
v.dst_start.y = y;
|
||||||
|
v.dst_end.x = x + adv;
|
||||||
|
v.dst_end.y = y + ctx.text_size - 2;
|
||||||
|
v.cols = Vec4(1.0);
|
||||||
|
|
||||||
|
if(text_in_focus)
|
||||||
|
{
|
||||||
|
v.dst_end.x = v.dst_start.x + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
AddUIIndices(ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline) void
|
pragma(inline) void
|
||||||
DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool draw_bg = false, Vec4 col = Vec4(1.0))
|
DrawGlyph(UIItem* item, Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool highlight = false, Vec4 col = Vec4(1.0))
|
||||||
{
|
{
|
||||||
UICtx* ctx = GetCtx();
|
UICtx* ctx = GetCtx();
|
||||||
Vertex* bg_v = null, v = null;
|
Vertex* bg_v = null, v = null;
|
||||||
f32 h;
|
f32 h;
|
||||||
if(draw_bg)
|
bool text_in_focus = false;
|
||||||
{
|
|
||||||
bg_v = ctx.buffers[ctx.f_idx].vtx.ptr + ctx.buffers[ctx.f_idx].count;
|
|
||||||
AddUIIndices(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(glyph.ch == '\t')
|
if(glyph.ch == '\t')
|
||||||
{
|
{
|
||||||
@ -1178,15 +1210,6 @@ DrawGlyph(Glyph* glyph, f32 scale, f32* x_pos, f32 y, bool draw_bg = false, Vec4
|
|||||||
AddUIIndices(ctx);
|
AddUIIndices(ctx);
|
||||||
|
|
||||||
*x_pos += glyph.advance * scale;
|
*x_pos += glyph.advance * scale;
|
||||||
|
|
||||||
if(draw_bg)
|
|
||||||
{
|
|
||||||
Vec4 white = Vec4(1.0);
|
|
||||||
|
|
||||||
bg_v.dst_start = v.dst_start;
|
|
||||||
bg_v.dst_end = v.dst_end;
|
|
||||||
bg_v.cols = white;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline) void
|
pragma(inline) void
|
||||||
|
|||||||
@ -176,6 +176,7 @@ EditorView(UIPanel* panel)
|
|||||||
UICtx* ctx = GetCtx();
|
UICtx* ctx = GetCtx();
|
||||||
UIItem* item = Panel(panel, UIF.Clickable);
|
UIItem* item = Panel(panel, UIF.Clickable);
|
||||||
|
|
||||||
|
bool focused = panel == GetFocusedPanel();
|
||||||
u64 rows = cast(u64)ceil(item.size.y/16.0);
|
u64 rows = cast(u64)ceil(item.size.y/16.0);
|
||||||
GetLines(&panel.ed.buf, &panel.ed.linebufs, 0, rows);
|
GetLines(&panel.ed.buf, &panel.ed.linebufs, 0, rows);
|
||||||
for(u64 i = 0; i < panel.ed.linebufs.lines.length; i += 1)
|
for(u64 i = 0; i < panel.ed.linebufs.lines.length; i += 1)
|
||||||
@ -183,14 +184,23 @@ EditorView(UIPanel* panel)
|
|||||||
u8[] line = panel.ed.linebufs.lines[i];
|
u8[] line = panel.ed.linebufs.lines[i];
|
||||||
if(line.length > 0)
|
if(line.length > 0)
|
||||||
{
|
{
|
||||||
|
if(panel.ed.buf.pos.y == i && focused)
|
||||||
|
{
|
||||||
|
SetHighlightedChar(panel.ed.buf.pos.x);
|
||||||
|
}
|
||||||
|
|
||||||
TextPart* tp = WrappedTextLine(line, panel.id, 16.0, i);
|
TextPart* tp = WrappedTextLine(line, panel.id, 16.0, i);
|
||||||
if(TextClicked(tp))
|
if(TextClicked(tp))
|
||||||
{
|
{
|
||||||
SetFocusedPanel(panel);
|
SetFocusedPanel(panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetHighlightedChar(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Signal(item);
|
Signal(item);
|
||||||
|
|
||||||
if(item.signal & UIS.Clicked)
|
if(item.signal & UIS.Clicked)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user