continued ui work
This commit is contained in:
parent
cce502ae43
commit
9950647cf9
Binary file not shown.
Binary file not shown.
@ -12,25 +12,27 @@ struct FlatBuffer
|
|||||||
Arena arena;
|
Arena arena;
|
||||||
Arena ls_arena;
|
Arena ls_arena;
|
||||||
LineBuffers linebufs;
|
LineBuffers linebufs;
|
||||||
|
BufferInfo info;
|
||||||
|
|
||||||
u8[] file_name;
|
u8[] file_name;
|
||||||
|
u8[] data;
|
||||||
u8[] _buf;
|
|
||||||
u8* pbuf;
|
|
||||||
u64 length;
|
u64 length;
|
||||||
|
|
||||||
Line[] lines;
|
Line[] lines;
|
||||||
u64 line_count;
|
|
||||||
|
|
||||||
i64 pos;
|
i64 pos;
|
||||||
i64 col_pos;
|
i64 col_pos;
|
||||||
|
|
||||||
I64Vec2 sel;
|
|
||||||
SelectMode sel_mode;
|
SelectMode sel_mode;
|
||||||
|
|
||||||
f32 view_width;
|
|
||||||
|
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
|
||||||
|
alias info this;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BufferInfo
|
||||||
|
{
|
||||||
|
u64 line_count;
|
||||||
|
I64Vec2 selection;
|
||||||
|
IVec2 position;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SelectMode
|
enum SelectMode
|
||||||
@ -55,9 +57,6 @@ struct LineBuffers
|
|||||||
Arena arena;
|
Arena arena;
|
||||||
LineBuffer* first;
|
LineBuffer* first;
|
||||||
LineBuffer* last;
|
LineBuffer* last;
|
||||||
u64 count;
|
|
||||||
u64 start;
|
|
||||||
u64 end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LineBuffer
|
struct LineBuffer
|
||||||
@ -142,30 +141,29 @@ Init(FlatBuffer* fb, u8[] data, u8[] file_name)
|
|||||||
fb.file_name = file_name;
|
fb.file_name = file_name;
|
||||||
fb.line_count = CountLF(data);
|
fb.line_count = CountLF(data);
|
||||||
fb.length = data.length;
|
fb.length = data.length;
|
||||||
fb.sel = -1;
|
fb.selection = -1;
|
||||||
fb.sel_mode = SM.None;
|
fb.sel_mode = SM.None;
|
||||||
fb.linebufs = CreateLineBuffers(MB(1));
|
fb.linebufs = CreateLineBuffers(MB(1));
|
||||||
|
|
||||||
SetBuffers(fb, buf);
|
SetBuffers(fb, buf);
|
||||||
|
|
||||||
MemCpy(fb.pbuf, data.ptr, data.length);
|
MemCpy(fb.data.ptr, data.ptr, data.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SetBuffers(FlatBuffer* fb, u8[] data)
|
SetBuffers(FlatBuffer* fb, u8[] data)
|
||||||
{
|
{
|
||||||
fb._buf = data;
|
fb.data = data;
|
||||||
fb.pbuf = fb._buf.ptr+BUF_START;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Change(FlatBuffer* fb, u8[] data, u8[] file_name)
|
Change(FlatBuffer* fb, u8[] data, u8[] file_name)
|
||||||
{
|
{
|
||||||
Free(fb._buf);
|
Free(fb.data);
|
||||||
Reset(&fb.linebufs.arena);
|
Reset(&fb.linebufs.arena);
|
||||||
|
|
||||||
Init(fb, data, file_name);
|
Init(fb, data, file_name);
|
||||||
ResetTokenizer(&fb.tk, fb._buf.length);
|
ResetTokenizer(&fb.tk, fb.data.length);
|
||||||
Fix(fb);
|
Fix(fb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,14 +180,14 @@ CountLF(u8[] data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline) bool
|
pragma(inline) bool
|
||||||
ScanLineRightBrace(u8* pbuf, u64 start, u64 len)
|
ScanLineRightBrace(u8* data, u64 start, u64 len)
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
for(u64 i = start; i < len; i += 1)
|
for(u64 i = start; i < len; i += 1)
|
||||||
{
|
{
|
||||||
if(pbuf[i] == '\t' || pbuf[i] == ' ') continue;
|
if(data[i] == '\t' || data[i] == ' ') continue;
|
||||||
|
|
||||||
if(pbuf[i] == '}' || pbuf[i] == ']' || pbuf[i] == ')')
|
if(data[i] == '}' || data[i] == ']' || data[i] == ')')
|
||||||
{
|
{
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
@ -216,7 +214,7 @@ Fix(FlatBuffer* fb)
|
|||||||
u64 ls_idx = 1;
|
u64 ls_idx = 1;
|
||||||
for(u64 i = 0; i < length; i += 1)
|
for(u64 i = 0; i < length; i += 1)
|
||||||
{
|
{
|
||||||
if(pbuf[i] == '{' || pbuf[i] == '(' || pbuf[i] == '[')
|
if(data[i] == '{' || data[i] == '(' || data[i] == '[')
|
||||||
{
|
{
|
||||||
if(pending_level > 0)
|
if(pending_level > 0)
|
||||||
{
|
{
|
||||||
@ -228,7 +226,7 @@ Fix(FlatBuffer* fb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(pbuf[i] == '}' || pbuf[i] == ')' || pbuf[i] == ']')
|
else if(data[i] == '}' || data[i] == ')' || data[i] == ']')
|
||||||
{
|
{
|
||||||
if(ignore > 0)
|
if(ignore > 0)
|
||||||
{
|
{
|
||||||
@ -248,7 +246,7 @@ Fix(FlatBuffer* fb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pbuf[i] == '\n')
|
if(data[i] == '\n')
|
||||||
{
|
{
|
||||||
level += pending_level;
|
level += pending_level;
|
||||||
pending_level = 0;
|
pending_level = 0;
|
||||||
@ -284,10 +282,10 @@ CreateLineBuffers(u64 arena_size)
|
|||||||
void
|
void
|
||||||
Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
|
Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
|
||||||
{
|
{
|
||||||
if(fb.length + length > fb._buf.length-SPACING)
|
if(fb.length + length > fb.data.length-SPACING)
|
||||||
{
|
{
|
||||||
SetBuffers(&fb.tk, Realloc(fb.tk._tokens, fb._buf.length*2));
|
SetBuffers(&fb.tk, Realloc(fb.tk.tokens, fb.data.length*2));
|
||||||
SetBuffers(fb, Realloc(fb._buf, fb._buf.length*2));
|
SetBuffers(fb, Realloc(fb.data, fb.data.length*2));
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 new_lines;
|
u64 new_lines;
|
||||||
@ -311,8 +309,8 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
|
|||||||
|
|
||||||
if(new_ch == '\n' && pos > 0)
|
if(new_ch == '\n' && pos > 0)
|
||||||
{
|
{
|
||||||
u8 l = fb.pbuf[pos-1];
|
u8 l = fb.data[pos-1];
|
||||||
u8 r = fb.pbuf[pos];
|
u8 r = fb.data[pos];
|
||||||
bool expand = (l == '(' && r == ')') || (l == '{' && r == '}') || (l == '[' && r == ']');
|
bool expand = (l == '(' && r == ')') || (l == '{' && r == '}') || (l == '[' && r == ']');
|
||||||
|
|
||||||
u32 level = LevelFromPos(fb, pos) + u32(expand);
|
u32 level = LevelFromPos(fb, pos) + u32(expand);
|
||||||
@ -343,11 +341,11 @@ Insert(FlatBuffer* fb, u8[] insert, u64 length, u64 pos)
|
|||||||
|
|
||||||
u64 temp_len = fb.length-pos;
|
u64 temp_len = fb.length-pos;
|
||||||
|
|
||||||
u8[] temp = Alloc!(u8)(&fb.arena, fb.pbuf[pos .. pos+temp_len]);
|
u8[] temp = Alloc!(u8)(&fb.arena, fb.data[pos .. pos+temp_len]);
|
||||||
|
|
||||||
fb.pbuf[pos .. pos+length] = insert[0 .. length];
|
fb.data[pos .. pos+length] = insert[0 .. length];
|
||||||
pos += length;
|
pos += length;
|
||||||
fb.pbuf[pos .. pos+temp_len] = temp[0 .. temp_len];
|
fb.data[pos .. pos+temp_len] = temp[0 .. temp_len];
|
||||||
|
|
||||||
fb.length += length;
|
fb.length += length;
|
||||||
|
|
||||||
@ -378,19 +376,19 @@ StartSelection(FlatBuffer* fb, SelectMode mode)
|
|||||||
|
|
||||||
if(mode == SM.Normal)
|
if(mode == SM.Normal)
|
||||||
{
|
{
|
||||||
fb.sel = fb.pos;
|
fb.selection = fb.pos;
|
||||||
}
|
}
|
||||||
else if(mode == SM.Line)
|
else if(mode == SM.Line)
|
||||||
{
|
{
|
||||||
fb.sel = CurrentLine(fb);
|
fb.selection = CurrentLine(fb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EndSelection(FlatBuffer* fb)
|
EndSelection(FlatBuffer* fb)
|
||||||
{
|
{
|
||||||
fb.sel = -1;
|
fb.selection = -1;
|
||||||
fb.sel_mode = SM.None;
|
fb.sel_mode = SM.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -454,13 +452,6 @@ LineLength(FlatBuffer* fb, u64 line)
|
|||||||
return fb.lines[line].length;
|
return fb.lines[line].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
StartLineBuffer(FlatBuffer* fb, f32 view_width)
|
|
||||||
{
|
|
||||||
Reset(&fb.linebufs.arena);
|
|
||||||
fb.view_width = view_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
LineBuffer*
|
LineBuffer*
|
||||||
GetLine(FlatBuffer* fb, u64 line)
|
GetLine(FlatBuffer* fb, u64 line)
|
||||||
{
|
{
|
||||||
@ -479,9 +470,8 @@ SliceLineBuffer(FlatBuffer* fb, Line* ls)
|
|||||||
{
|
{
|
||||||
LineBuffer* lbuf = Alloc!(LineBuffer)(&fb.linebufs.arena);
|
LineBuffer* lbuf = Alloc!(LineBuffer)(&fb.linebufs.arena);
|
||||||
|
|
||||||
lbuf.text = fb.pbuf[ls.pos .. ls.pos+ls.length];
|
lbuf.text = fb.data[ls.pos .. ls.pos+ls.length];
|
||||||
lbuf.style = fb.tk.ptokens[ls.pos .. ls.pos+ls.length];
|
lbuf.style = fb.tk.tokens[ls.pos .. ls.pos+ls.length];
|
||||||
fb.linebufs.count += 1;
|
|
||||||
|
|
||||||
return lbuf;
|
return lbuf;
|
||||||
}
|
}
|
||||||
@ -489,7 +479,7 @@ SliceLineBuffer(FlatBuffer* fb, Line* ls)
|
|||||||
void
|
void
|
||||||
MoveToEOL(FlatBuffer* fb)
|
MoveToEOL(FlatBuffer* fb)
|
||||||
{
|
{
|
||||||
if(fb.pbuf[fb.pos] != '\n')
|
if(fb.data[fb.pos] != '\n')
|
||||||
{
|
{
|
||||||
for(u64 i = 0; i < fb.lines.length; i += 1)
|
for(u64 i = 0; i < fb.lines.length; i += 1)
|
||||||
{
|
{
|
||||||
@ -505,7 +495,7 @@ MoveToEOL(FlatBuffer* fb)
|
|||||||
void
|
void
|
||||||
MoveToSOL(FlatBuffer* fb)
|
MoveToSOL(FlatBuffer* fb)
|
||||||
{
|
{
|
||||||
if(fb.pos != 0 && fb.pbuf[fb.pos-1] != '\n')
|
if(fb.pos != 0 && fb.data[fb.pos-1] != '\n')
|
||||||
{
|
{
|
||||||
for(u64 i = 0; i < fb.lines.length; i += 1)
|
for(u64 i = 0; i < fb.lines.length; i += 1)
|
||||||
{
|
{
|
||||||
@ -577,7 +567,7 @@ MoveToEmptyLine(bool up)(FlatBuffer* fb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = fb.pbuf[i];
|
ch = fb.data[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
static if(up)
|
static if(up)
|
||||||
@ -588,10 +578,10 @@ MoveToEmptyLine(bool up)(FlatBuffer* fb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = fb.pbuf[i-1];
|
ch = fb.data[i-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(started && !CheckWhiteSpace(fb.pbuf[i]))
|
if(started && !CheckWhiteSpace(fb.data[i]))
|
||||||
{
|
{
|
||||||
started = false;
|
started = false;
|
||||||
}
|
}
|
||||||
@ -674,8 +664,8 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb)
|
|||||||
|
|
||||||
if((forward && fb.pos < fb.length-1) || (!forward && fb.pos > 0))
|
if((forward && fb.pos < fb.length-1) || (!forward && fb.pos > 0))
|
||||||
{
|
{
|
||||||
ChType type = GetChType(fb.pbuf[fb.pos]);
|
ChType type = GetChType(fb.data[fb.pos]);
|
||||||
if(type != GetChType(fb.pbuf[fb.pos+step]))
|
if(type != GetChType(fb.data[fb.pos+step]))
|
||||||
{
|
{
|
||||||
fb.pos += step;
|
fb.pos += step;
|
||||||
}
|
}
|
||||||
@ -683,11 +673,11 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb)
|
|||||||
{
|
{
|
||||||
static if(forward)
|
static if(forward)
|
||||||
{
|
{
|
||||||
u8 next = i < fb.length-1 ? fb.pbuf[i+1] : 0;
|
u8 next = i < fb.length-1 ? fb.data[i+1] : 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
u8 next = i > 1 ? fb.pbuf[i-1] : 0;
|
u8 next = i > 1 ? fb.data[i-1] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static if(forward) if(i == fb.length-2)
|
static if(forward) if(i == fb.length-2)
|
||||||
@ -712,7 +702,7 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(CheckWhiteSpace(fb.pbuf[fb.pos]))
|
while(CheckWhiteSpace(fb.data[fb.pos]))
|
||||||
{
|
{
|
||||||
bool exit = forward ? fb.pos == fb.length-1 : fb.pos == 0;
|
bool exit = forward ? fb.pos == fb.length-1 : fb.pos == 0;
|
||||||
if(exit) break;
|
if(exit) break;
|
||||||
@ -725,7 +715,7 @@ MoveToWordEdge(bool forward)(FlatBuffer* fb)
|
|||||||
void
|
void
|
||||||
MoveToNextWord(bool forward)(FlatBuffer* fb)
|
MoveToNextWord(bool forward)(FlatBuffer* fb)
|
||||||
{
|
{
|
||||||
ChType type = GetChType(fb.pbuf[fb.pos]);
|
ChType type = GetChType(fb.data[fb.pos]);
|
||||||
|
|
||||||
bool hit_ws;
|
bool hit_ws;
|
||||||
u64 step = forward ? 1 : -1;
|
u64 step = forward ? 1 : -1;
|
||||||
@ -743,7 +733,7 @@ MoveToNextWord(bool forward)(FlatBuffer* fb)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ch = fb.pbuf[i];
|
u8 ch = fb.data[i];
|
||||||
|
|
||||||
if(CheckWhiteSpace(ch))
|
if(CheckWhiteSpace(ch))
|
||||||
{
|
{
|
||||||
@ -847,7 +837,7 @@ Move(FlatBuffer* fb, Input key, Modifier md)
|
|||||||
} break;
|
} break;
|
||||||
case Left:
|
case Left:
|
||||||
{
|
{
|
||||||
if(fb.pos > 0 && fb.pbuf[fb.pos-1] != '\n')
|
if(fb.pos > 0 && fb.data[fb.pos-1] != '\n')
|
||||||
{
|
{
|
||||||
fb.pos -= 1;
|
fb.pos -= 1;
|
||||||
taken = true;
|
taken = true;
|
||||||
@ -855,7 +845,7 @@ Move(FlatBuffer* fb, Input key, Modifier md)
|
|||||||
} break;
|
} break;
|
||||||
case Right:
|
case Right:
|
||||||
{
|
{
|
||||||
if(fb.pos < fb.length && fb.pbuf[fb.pos] != '\n')
|
if(fb.pos < fb.length && fb.data[fb.pos] != '\n')
|
||||||
{
|
{
|
||||||
fb.pos += 1;
|
fb.pos += 1;
|
||||||
taken = true;
|
taken = true;
|
||||||
@ -874,7 +864,7 @@ Move(FlatBuffer* fb, Input key, Modifier md)
|
|||||||
|
|
||||||
UpdateSelection(fb);
|
UpdateSelection(fb);
|
||||||
|
|
||||||
Logf("selection %s", fb.sel.v);
|
Logf("selection %s", fb.selection.v);
|
||||||
|
|
||||||
return taken;
|
return taken;
|
||||||
}
|
}
|
||||||
@ -884,12 +874,12 @@ UpdateSelection(FlatBuffer* fb)
|
|||||||
{
|
{
|
||||||
if(fb.sel_mode == SM.Normal)
|
if(fb.sel_mode == SM.Normal)
|
||||||
{
|
{
|
||||||
fb.sel.y = fb.pos;
|
fb.selection.y = fb.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fb.sel_mode == SM.Line)
|
if(fb.sel_mode == SM.Line)
|
||||||
{
|
{
|
||||||
fb.sel.y = CurrentLine(fb);
|
fb.selection.y = CurrentLine(fb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +901,7 @@ Delete(FlatBuffer* fb, u64 length, u64 pos)
|
|||||||
|
|
||||||
for(u64 i = pos; i < fb.length && i < pos+length; i += 1)
|
for(u64 i = pos; i < fb.length && i < pos+length; i += 1)
|
||||||
{
|
{
|
||||||
if(fb.pbuf[i] == '\n')
|
if(fb.data[i] == '\n')
|
||||||
{
|
{
|
||||||
fb.line_count -= 1;
|
fb.line_count -= 1;
|
||||||
}
|
}
|
||||||
@ -921,8 +911,8 @@ Delete(FlatBuffer* fb, u64 length, u64 pos)
|
|||||||
if(end != fb.length)
|
if(end != fb.length)
|
||||||
{
|
{
|
||||||
temp = Alloc!(u8)(&fb.arena, fb.length-end);
|
temp = Alloc!(u8)(&fb.arena, fb.length-end);
|
||||||
temp[0 .. temp.length] = fb.pbuf[end .. fb.length];
|
temp[0 .. temp.length] = fb.data[end .. fb.length];
|
||||||
fb.pbuf[pos .. pos+temp.length] = temp[0 .. temp.length];
|
fb.data[pos .. pos+temp.length] = temp[0 .. temp.length];
|
||||||
}
|
}
|
||||||
|
|
||||||
fb.length -= length;
|
fb.length -= length;
|
||||||
|
|||||||
@ -28,6 +28,7 @@ struct EditorCtx
|
|||||||
EditState state;
|
EditState state;
|
||||||
u8[128] input_buf;
|
u8[128] input_buf;
|
||||||
u32 icount;
|
u32 icount;
|
||||||
|
u64 editor_id_incr;
|
||||||
Timer timer;
|
Timer timer;
|
||||||
CmdPalette cmd;
|
CmdPalette cmd;
|
||||||
u8[][] file_names;
|
u8[][] file_names;
|
||||||
@ -49,14 +50,17 @@ struct CmdPalette
|
|||||||
struct Editor
|
struct Editor
|
||||||
{
|
{
|
||||||
Arena arena;
|
Arena arena;
|
||||||
|
u64 editor_id;
|
||||||
|
|
||||||
FlatBuffer buf;
|
FlatBuffer buf;
|
||||||
Tokenizer tk;
|
Tokenizer tk;
|
||||||
|
|
||||||
Vec2 cursor_pos;
|
U64Vec2 cursor_pos;
|
||||||
Vec2 select_start;
|
Vec2 select_start;
|
||||||
Vec2 select_end;
|
Vec2 select_end;
|
||||||
|
|
||||||
|
u64 line_offset;
|
||||||
|
|
||||||
f32 text_size;
|
f32 text_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,7 +418,7 @@ SaveFile(Editor* ed, u8[] file_name)
|
|||||||
u64 tab_count;
|
u64 tab_count;
|
||||||
for(u64 i = 0; i < ed.buf.length; i += 1)
|
for(u64 i = 0; i < ed.buf.length; i += 1)
|
||||||
{
|
{
|
||||||
if(ed.buf.pbuf[i] == '\t')
|
if(ed.buf.data[i] == '\t')
|
||||||
{
|
{
|
||||||
tab_count += 1;
|
tab_count += 1;
|
||||||
}
|
}
|
||||||
@ -427,7 +431,7 @@ SaveFile(Editor* ed, u8[] file_name)
|
|||||||
u64 buf_pos;
|
u64 buf_pos;
|
||||||
for(u64 i = 0; i < ed.buf.length; i += 1)
|
for(u64 i = 0; i < ed.buf.length; i += 1)
|
||||||
{
|
{
|
||||||
if(ed.buf.pbuf[i] == '\t')
|
if(ed.buf.data[i] == '\t')
|
||||||
{
|
{
|
||||||
for(u64 j = 0; j < tab_width; j += 1)
|
for(u64 j = 0; j < tab_width; j += 1)
|
||||||
{
|
{
|
||||||
@ -436,7 +440,7 @@ SaveFile(Editor* ed, u8[] file_name)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp_buf[buf_pos++] = ed.buf.pbuf[i];
|
temp_buf[buf_pos++] = ed.buf.data[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,8 +492,9 @@ CreateEditor(EditorCtx* ctx)
|
|||||||
{
|
{
|
||||||
Editor* ed = Alloc!(Editor)(&ctx.arena);
|
Editor* ed = Alloc!(Editor)(&ctx.arena);
|
||||||
|
|
||||||
ed.arena = CreateArena(MB(4));
|
ed.arena = CreateArena(MB(4));
|
||||||
ed.buf = CreateFlatBuffer([], []);
|
ed.buf = CreateFlatBuffer([], []);
|
||||||
|
ed.editor_id = ctx.editor_id_incr++;
|
||||||
|
|
||||||
return ed;
|
return ed;
|
||||||
}
|
}
|
||||||
@ -596,10 +601,10 @@ ResetCtx(EditorCtx* ctx)
|
|||||||
{
|
{
|
||||||
InsertInputToBuf(ctx);
|
InsertInputToBuf(ctx);
|
||||||
|
|
||||||
ctx.state = ES.NormalMode;
|
ctx.state = ES.NormalMode;
|
||||||
ctx.cmd.icount = 0;
|
ctx.cmd.icount = 0;
|
||||||
ctx.cmd.commands = [];
|
ctx.cmd.commands = [];
|
||||||
ctx.cmd.current = cast(Command)NO_CMD;
|
ctx.cmd.current = cast(Command)NO_CMD;
|
||||||
ctx.cmd.selected = 0;
|
ctx.cmd.selected = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -389,8 +389,7 @@ struct Token
|
|||||||
struct Tokenizer
|
struct Tokenizer
|
||||||
{
|
{
|
||||||
Arena arena;
|
Arena arena;
|
||||||
TokenStyle[] _tokens;
|
TokenStyle[] tokens;
|
||||||
TokenStyle* ptokens;
|
|
||||||
u64 tk_count;
|
u64 tk_count;
|
||||||
u64 pos;
|
u64 pos;
|
||||||
Token* first;
|
Token* first;
|
||||||
@ -406,8 +405,7 @@ Nil(Token* tk)
|
|||||||
void
|
void
|
||||||
SetBuffers(Tokenizer* tk, TokenStyle[] tokens)
|
SetBuffers(Tokenizer* tk, TokenStyle[] tokens)
|
||||||
{
|
{
|
||||||
tk._tokens = tokens;
|
tk.tokens = tokens;
|
||||||
tk.ptokens = tokens.ptr+BUF_START;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tokenizer
|
Tokenizer
|
||||||
@ -417,7 +415,7 @@ CreateTokenizer(FlatBuffer* fb)
|
|||||||
arena: CreateArena(MB(4)),
|
arena: CreateArena(MB(4)),
|
||||||
};
|
};
|
||||||
|
|
||||||
SetBuffers(&tk, Alloc!(TS)(fb._buf.length));
|
SetBuffers(&tk, Alloc!(TS)(fb.data.length));
|
||||||
|
|
||||||
g_NIL_TOKEN = cast(Token*)&g_nil_tk;
|
g_NIL_TOKEN = cast(Token*)&g_nil_tk;
|
||||||
tk.first = tk.last = g_NIL_TOKEN;
|
tk.first = tk.last = g_NIL_TOKEN;
|
||||||
@ -445,7 +443,7 @@ void
|
|||||||
ResetTokenizer(Tokenizer* tk, u64 len)
|
ResetTokenizer(Tokenizer* tk, u64 len)
|
||||||
{
|
{
|
||||||
Reset(&tk.arena);
|
Reset(&tk.arena);
|
||||||
Free(tk._tokens);
|
Free(tk.tokens);
|
||||||
|
|
||||||
SetBuffers(tk, Alloc!(TS)(len));
|
SetBuffers(tk, Alloc!(TS)(len));
|
||||||
tk.pos = 0;
|
tk.pos = 0;
|
||||||
@ -469,7 +467,7 @@ MakeToken(Tokenizer* tk, TokenType type, u64 start, u64 end)
|
|||||||
u8
|
u8
|
||||||
Peek(FlatBuffer* fb)
|
Peek(FlatBuffer* fb)
|
||||||
{
|
{
|
||||||
return fb.tk.pos+1 < fb.length ? fb.pbuf[fb.tk.pos+1] : 0;
|
return fb.tk.pos+1 < fb.length ? fb.data[fb.tk.pos+1] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -483,7 +481,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length;)
|
for(; tk.pos < fb.length;)
|
||||||
{
|
{
|
||||||
u8 ch = fb.pbuf[tk.pos];
|
u8 ch = fb.data[tk.pos];
|
||||||
bool alpha = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
bool alpha = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
|
||||||
|
|
||||||
if(ch == ' ' || ch == '\t')
|
if(ch == ' ' || ch == '\t')
|
||||||
@ -492,7 +490,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(tk.pos += 1; tk.pos < fb.length; tk.pos += 1)
|
for(tk.pos += 1; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(fb.pbuf[tk.pos] != ' ' && fb.pbuf[tk.pos] != '\t')
|
if(fb.data[tk.pos] != ' ' && fb.data[tk.pos] != '\t')
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -577,7 +575,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
u8 c = fb.pbuf[tk.pos];
|
u8 c = fb.data[tk.pos];
|
||||||
|
|
||||||
if(CheckWhiteSpace(c)) break;
|
if(CheckWhiteSpace(c)) break;
|
||||||
if(!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z')) break;
|
if(!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z')) break;
|
||||||
@ -591,7 +589,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(fb.pbuf[tk.pos] != '.') break;
|
if(fb.data[tk.pos] != '.') break;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.end = tk.pos;
|
t.end = tk.pos;
|
||||||
@ -602,7 +600,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(CheckWhiteSpace(fb.pbuf[tk.pos])) break;
|
if(CheckWhiteSpace(fb.data[tk.pos])) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
t.end = tk.pos;
|
t.end = tk.pos;
|
||||||
@ -619,7 +617,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(CheckEOL(fb.pbuf[tk.pos]))
|
if(CheckEOL(fb.data[tk.pos]))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -634,7 +632,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(fb.pbuf[tk.pos] == '/' && fb.pbuf[tk.pos-1] == '*')
|
if(fb.data[tk.pos] == '/' && fb.data[tk.pos-1] == '*')
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -655,7 +653,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
if(CheckWhiteSpace(fb.pbuf[tk.pos]))
|
if(CheckWhiteSpace(fb.data[tk.pos]))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -716,7 +714,7 @@ TokenizeD(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(auto token = tk.first; !Nil(token); token = token.next)
|
for(auto token = tk.first; !Nil(token); token = token.next)
|
||||||
{
|
{
|
||||||
tk.ptokens[token.start .. token.end] = TOKEN_STYLES[token.type];
|
tk.tokens[token.start .. token.end] = TOKEN_STYLES[token.type];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,7 +824,7 @@ CheckFuncOrTemplateSig(FlatBuffer* fb, Token* token)
|
|||||||
u8[]
|
u8[]
|
||||||
TokenStr(FlatBuffer* fb, Token* t)
|
TokenStr(FlatBuffer* fb, Token* t)
|
||||||
{
|
{
|
||||||
return fb.pbuf[t.start .. t.end];
|
return fb.data[t.start .. t.end];
|
||||||
}
|
}
|
||||||
|
|
||||||
Token*
|
Token*
|
||||||
@ -911,7 +909,7 @@ ParseNum(FlatBuffer* fb)
|
|||||||
{
|
{
|
||||||
tk.pos += 1;
|
tk.pos += 1;
|
||||||
|
|
||||||
u8 ch = fb.pbuf[tk.pos];
|
u8 ch = fb.data[tk.pos];
|
||||||
|
|
||||||
if(ch != '_' && ch != '.' && !(ch >= '0' && ch <= '9') && ch != 'x' && ch != 'X' && !((ch == '-' || ch == '+') && first))
|
if(ch != '_' && ch != '.' && !(ch >= '0' && ch <= '9') && ch != 'x' && ch != 'X' && !((ch == '-' || ch == '+') && first))
|
||||||
{
|
{
|
||||||
@ -923,7 +921,7 @@ ParseNum(FlatBuffer* fb)
|
|||||||
|
|
||||||
while (tk.pos < fb.length)
|
while (tk.pos < fb.length)
|
||||||
{
|
{
|
||||||
u8 ch = fb.pbuf[tk.pos];
|
u8 ch = fb.data[tk.pos];
|
||||||
if(ch != 'l' && ch != 'u' && ch != 'U' && ch != 'L' && ch != 'f' && ch != 'F')
|
if(ch != 'l' && ch != 'u' && ch != 'U' && ch != 'L' && ch != 'f' && ch != 'F')
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -952,9 +950,9 @@ ParseStr(u8 str_ch)(FlatBuffer* fb)
|
|||||||
static if(str_ch == '`') tk.pos += 1;
|
static if(str_ch == '`') tk.pos += 1;
|
||||||
|
|
||||||
bool ignore = str_ch != '`';
|
bool ignore = str_ch != '`';
|
||||||
for(; (fb.pbuf[tk.pos] != str_ch || ignore) && tk.pos < fb.length; tk.pos += 1)
|
for(; (fb.data[tk.pos] != str_ch || ignore) && tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
static if(str_ch != '`') ignore = fb.pbuf[tk.pos] == '\\';
|
static if(str_ch != '`') ignore = fb.data[tk.pos] == '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
tk.pos += 1;
|
tk.pos += 1;
|
||||||
@ -971,7 +969,7 @@ ParseId(FlatBuffer* fb)
|
|||||||
|
|
||||||
for(; tk.pos < fb.length; tk.pos += 1)
|
for(; tk.pos < fb.length; tk.pos += 1)
|
||||||
{
|
{
|
||||||
u8 ch = fb.pbuf[tk.pos];
|
u8 ch = fb.data[tk.pos];
|
||||||
|
|
||||||
if(!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && ch != '.' && ch != '_' && !(ch >= '0' && ch <= '9'))
|
if(!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && ch != '.' && ch != '_' && !(ch >= '0' && ch <= '9'))
|
||||||
{
|
{
|
||||||
@ -980,11 +978,11 @@ ParseId(FlatBuffer* fb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 ch = fb.pbuf[t.start];
|
u8 ch = fb.data[t.start];
|
||||||
if(ch < D_KEYWORDS.length && D_KEYWORDS[ch] != null && D_KEYWORDS[ch].length > 0)
|
if(ch < D_KEYWORDS.length && D_KEYWORDS[ch] != null && D_KEYWORDS[ch].length > 0)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
u8[] id = fb.pbuf[t.start .. t.end];
|
u8[] id = fb.data[t.start .. t.end];
|
||||||
|
|
||||||
foreach(ref k; D_TYPES[ch])
|
foreach(ref k; D_TYPES[ch])
|
||||||
{
|
{
|
||||||
@ -1032,7 +1030,7 @@ FixOpAssign(FlatBuffer* fb, Token* t)
|
|||||||
{
|
{
|
||||||
if(t.end+1 < fb.length)
|
if(t.end+1 < fb.length)
|
||||||
{
|
{
|
||||||
u8[] str = fb.pbuf[t.start .. t.end+1];
|
u8[] str = fb.data[t.start .. t.end+1];
|
||||||
if(
|
if(
|
||||||
str == "/=" ||
|
str == "/=" ||
|
||||||
str == "+=" ||
|
str == "+=" ||
|
||||||
@ -1075,7 +1073,7 @@ SkipWhiteSpace(FlatBuffer* fb)
|
|||||||
{
|
{
|
||||||
while (fb.tk.pos < fb.length)
|
while (fb.tk.pos < fb.length)
|
||||||
{
|
{
|
||||||
u8 ch = fb.pbuf[fb.tk.pos];
|
u8 ch = fb.data[fb.tk.pos];
|
||||||
|
|
||||||
bool white_space = CheckWhiteSpace(ch);
|
bool white_space = CheckWhiteSpace(ch);
|
||||||
|
|
||||||
|
|||||||
166
src/editor/ui.d
166
src/editor/ui.d
@ -90,7 +90,7 @@ enum Axis2D
|
|||||||
{
|
{
|
||||||
X,
|
X,
|
||||||
Y,
|
Y,
|
||||||
Max
|
Max,
|
||||||
}
|
}
|
||||||
|
|
||||||
alias A2D = Axis2D;
|
alias A2D = Axis2D;
|
||||||
@ -111,10 +111,11 @@ enum UIFlags
|
|||||||
ResizeAdjacent = 1<<10,
|
ResizeAdjacent = 1<<10,
|
||||||
FloatingWindow = 1<<11,
|
FloatingWindow = 1<<11,
|
||||||
CenteredWindow = 1<<12,
|
CenteredWindow = 1<<12,
|
||||||
TextInput = 1<<13,
|
TextInput = 1<<13, // todo
|
||||||
RightAlignText = 1<<14,
|
RightAlignText = 1<<14,
|
||||||
CenterAlignText = 1<<15,
|
CenterAlignText = 1<<15, // todo
|
||||||
TextWrap = 1<<16,
|
TextWrap = 1<<16,
|
||||||
|
PortalView = 1<<17, // Stencil mask this area, no bounds checking children within (for views to drag and view elements)
|
||||||
|
|
||||||
Clamp = UIFlags.ClampX | UIFlags.ClampY,
|
Clamp = UIFlags.ClampX | UIFlags.ClampY,
|
||||||
}
|
}
|
||||||
@ -241,6 +242,7 @@ struct UICtx
|
|||||||
mixin UICtxParameter!(Vec4, "text_hl_col");
|
mixin UICtxParameter!(Vec4, "text_hl_col");
|
||||||
mixin UICtxParameter!(Vec2[2], "scroll_clamp");
|
mixin UICtxParameter!(Vec2[2], "scroll_clamp");
|
||||||
mixin UICtxParameter!(Vec2, "scroll_target");
|
mixin UICtxParameter!(Vec2, "scroll_target");
|
||||||
|
mixin UICtxParameter!(Vec2, "fixed_pos");
|
||||||
mixin UICtxParameter!(Vec2, "padding");
|
mixin UICtxParameter!(Vec2, "padding");
|
||||||
mixin UICtxParameter!(UIItem*, "parent");
|
mixin UICtxParameter!(UIItem*, "parent");
|
||||||
mixin UICtxParameter!(Axis2D, "layout_axis");
|
mixin UICtxParameter!(Axis2D, "layout_axis");
|
||||||
@ -357,6 +359,7 @@ struct VPos
|
|||||||
struct Vertex
|
struct Vertex
|
||||||
{
|
{
|
||||||
Vec4[4] cols;
|
Vec4[4] cols;
|
||||||
|
Vec2[2] bounds;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
VPos[2] pos;
|
VPos[2] pos;
|
||||||
@ -368,12 +371,11 @@ struct Vertex
|
|||||||
Vec2 src_end;
|
Vec2 src_end;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
f32 border_thickness;
|
f32 border_thickness;
|
||||||
f32 corner_radius;
|
f32 corner_radius;
|
||||||
f32 edge_softness;
|
f32 edge_softness;
|
||||||
f32 raised;
|
f32 raised;
|
||||||
f32 z_index;
|
u32 texture;
|
||||||
u32 texture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
union Rect
|
union Rect
|
||||||
@ -557,8 +559,6 @@ Set(UIItem* item, UICtx* ctx)
|
|||||||
UIItem*
|
UIItem*
|
||||||
MakeItem(Args...)(string str, Args args)
|
MakeItem(Args...)(string str, Args args)
|
||||||
{
|
{
|
||||||
UIItem* item = g_UI_NIL;
|
|
||||||
|
|
||||||
static if(Args.length)
|
static if(Args.length)
|
||||||
{
|
{
|
||||||
enum has_flag = Args[Args.length-1].stringof == UIFlags.stringof;
|
enum has_flag = Args[Args.length-1].stringof == UIFlags.stringof;
|
||||||
@ -567,11 +567,14 @@ MakeItem(Args...)(string str, Args args)
|
|||||||
enum len = has_flag ? Args.length-1 : Args.length;
|
enum len = has_flag ? Args.length-1 : Args.length;
|
||||||
|
|
||||||
char[] key = sformat(ScratchAlloc!(char)(cast(u64)(str.length*1.5)), str, args[0 .. len]);
|
char[] key = sformat(ScratchAlloc!(char)(cast(u64)(str.length*1.5)), str, args[0 .. len]);
|
||||||
|
}
|
||||||
item = MakeItem(key, flags);
|
else
|
||||||
|
{
|
||||||
|
char[] key = CastStr(char)(str);
|
||||||
|
UIFlags flags = UIF.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
return MakeItem(key, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
UIItem*
|
UIItem*
|
||||||
@ -802,7 +805,7 @@ BeginUI(Inputs* inputs)
|
|||||||
foreach(i; 0 .. items.length)
|
foreach(i; 0 .. items.length)
|
||||||
{
|
{
|
||||||
UIItem* item = items[i].value;
|
UIItem* item = items[i].value;
|
||||||
if(item.last_frame != ctx.frame)
|
if(item.last_frame != ctx.frame || ZeroKey(item.key))
|
||||||
{
|
{
|
||||||
Logf("discarding %s", cast(char[])item.key.hash_text);
|
Logf("discarding %s", cast(char[])item.key.hash_text);
|
||||||
item.first = item.last = item.parent = item.prev = item.next = g_UI_NIL;
|
item.first = item.last = item.parent = item.prev = item.next = g_UI_NIL;
|
||||||
@ -986,30 +989,6 @@ EndUI()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(excess > 0.0009)
|
|
||||||
{
|
|
||||||
for(UIItem* c = item.last; !Nil(c); c = c.prev)
|
|
||||||
{
|
|
||||||
f32 reduced = Min(excess, c.size[axis]);
|
|
||||||
excess -= reduced;
|
|
||||||
c.size.v[axis] -= reduced;
|
|
||||||
|
|
||||||
if(excess < 0.0009)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(excess < 0.0009);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(UIItem* c = item.first; !Nil(c); c = c.next)
|
|
||||||
{
|
|
||||||
c.size.v[axis] = c.size.v[axis] > size ? size : c.size.v[axis];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1108,6 +1087,7 @@ RenderItems(UIItem* root)
|
|||||||
v.dst_end = item.rect.p1 - item.border_thickness;
|
v.dst_end = item.rect.p1 - item.border_thickness;
|
||||||
v.cols = item.bg_col;
|
v.cols = item.bg_col;
|
||||||
v.corner_radius = item.corner_radius;
|
v.corner_radius = item.corner_radius;
|
||||||
|
v.bounds = ItemBounds(item.parent);
|
||||||
|
|
||||||
AddVertexCount(ctx);
|
AddVertexCount(ctx);
|
||||||
}
|
}
|
||||||
@ -1121,6 +1101,7 @@ RenderItems(UIItem* root)
|
|||||||
v.corner_radius = item.corner_radius;
|
v.corner_radius = item.corner_radius;
|
||||||
v.border_thickness = item.border_thickness;
|
v.border_thickness = item.border_thickness;
|
||||||
v.edge_softness = item.edge_softness;
|
v.edge_softness = item.edge_softness;
|
||||||
|
v.bounds = ItemBounds(item.parent);
|
||||||
|
|
||||||
AddVertexCount(ctx);
|
AddVertexCount(ctx);
|
||||||
}
|
}
|
||||||
@ -1389,6 +1370,13 @@ RootSize()
|
|||||||
return cast(Vec2)GetExtent(&g_ui_ctx.rd);
|
return cast(Vec2)GetExtent(&g_ui_ctx.rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UIKey
|
||||||
|
MakeKey(Args...)(string str, Args args)
|
||||||
|
{
|
||||||
|
char[] key = sformat(ScratchAlloc!(char)(cast(u64)(str.length)), str, args);
|
||||||
|
return MakeKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
UIKey
|
UIKey
|
||||||
MakeKey(T)(T str) if(StringType!T)
|
MakeKey(T)(T str) if(StringType!T)
|
||||||
{
|
{
|
||||||
@ -1403,50 +1391,72 @@ MakeKey(T)(T str) if(StringType!T)
|
|||||||
|
|
||||||
UIKey key;
|
UIKey key;
|
||||||
|
|
||||||
bool hash_only = false;
|
if(str.length)
|
||||||
i64 pos = 0;
|
|
||||||
u32 hash_count = 0;
|
|
||||||
for(i64 i = id.length-1; i >= 0; i -= 1)
|
|
||||||
{
|
{
|
||||||
if(i == 0 && id[i] == '#')
|
bool hash_only = false;
|
||||||
|
i64 pos = 0;
|
||||||
|
u32 hash_count = 0;
|
||||||
|
for(i64 i = id.length-1; i >= 0; i -= 1)
|
||||||
{
|
{
|
||||||
hash_only = true;
|
if(i == 0 && id[i] == '#')
|
||||||
}
|
|
||||||
|
|
||||||
if(hash_count == 2)
|
|
||||||
{
|
|
||||||
if(id[i] == '#')
|
|
||||||
{
|
{
|
||||||
hash_count += 1;
|
hash_only = true;
|
||||||
pos = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
if(hash_count == 2)
|
||||||
|
{
|
||||||
|
if(id[i] == '#')
|
||||||
|
{
|
||||||
|
hash_count += 1;
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(id[i] == '#')
|
||||||
|
{
|
||||||
|
pos = i;
|
||||||
|
hash_count += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(id[i] == '#')
|
if(hash_count < 2 || hash_only)
|
||||||
{
|
{
|
||||||
pos = i;
|
key.text = hash_only ? "" : id;
|
||||||
hash_count += 1;
|
key.hash_text = hash_only ? id : "";
|
||||||
|
key.hash = Hash(id);
|
||||||
|
}
|
||||||
|
else if(hash_count == 2 || hash_count == 3)
|
||||||
|
{
|
||||||
|
key.text = id[0 .. pos];
|
||||||
|
key.hash_text = id[pos .. $];
|
||||||
|
key.hash = hash_count == 2 ? Hash(id) : Hash(id[pos+hash_count .. $]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(hash_count < 2 || hash_only)
|
|
||||||
{
|
|
||||||
key.text = hash_only ? "" : id;
|
|
||||||
key.hash_text = hash_only ? id : "";
|
|
||||||
key.hash = Hash(id);
|
|
||||||
}
|
|
||||||
else if(hash_count == 2 || hash_count == 3)
|
|
||||||
{
|
|
||||||
key.text = id[0 .. pos];
|
|
||||||
key.hash_text = id[pos .. $];
|
|
||||||
key.hash = hash_count == 2 ? Hash(id) : Hash(id[pos+hash_count .. $]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UIKey
|
||||||
|
ZeroKey()
|
||||||
|
{
|
||||||
|
return UIKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ZeroKey(UIKey key)
|
||||||
|
{
|
||||||
|
return key.hash == 0 && key.hash_text.length == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UIItem*
|
||||||
|
Get(Args...)(string str, Args args)
|
||||||
|
{
|
||||||
|
char[] key = sformat(ScratchAlloc!(cast(u64)(str.length*1.5), str, args));
|
||||||
|
return Get(key);
|
||||||
|
}
|
||||||
|
|
||||||
pragma(inline) UIItem*
|
pragma(inline) UIItem*
|
||||||
Get(T)(T k) if(is(T: UIKey) || StringType!T)
|
Get(T)(T k) if(is(T: UIKey) || StringType!T)
|
||||||
{
|
{
|
||||||
@ -1550,6 +1560,7 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y)
|
|||||||
v.dst_end = Vec2(*x_pos+gb.w+gb.l, y+gb.h);
|
v.dst_end = Vec2(*x_pos+gb.w+gb.l, y+gb.h);
|
||||||
v.cols = item.text_col;
|
v.cols = item.text_col;
|
||||||
v.texture = true;
|
v.texture = true;
|
||||||
|
v.bounds = ItemBounds(item);
|
||||||
|
|
||||||
if(glyph.ch != '\t' && glyph.ch != '\n')
|
if(glyph.ch != '\t' && glyph.ch != '\n')
|
||||||
{
|
{
|
||||||
@ -1557,6 +1568,7 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y)
|
|||||||
v.src_end = Vec2(gb.atlas_r, gb.atlas_b);
|
v.src_end = Vec2(gb.atlas_r, gb.atlas_b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
f32 end_x = *x_pos + advance;
|
f32 end_x = *x_pos + advance;
|
||||||
f32 width = end_x - *x_pos;
|
f32 width = end_x - *x_pos;
|
||||||
f32 bound_x = item.flags & UIF.RightAlignText ? item.rect.p0.x : item.rect.p1.x;
|
f32 bound_x = item.flags & UIF.RightAlignText ? item.rect.p0.x : item.rect.p1.x;
|
||||||
@ -1589,6 +1601,7 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y)
|
|||||||
v.pos[i].end[axis] = v.pos[i].start.v[axis] > v.pos[i].end.v[axis] ? v.pos[i].start.v[axis] : v.pos[i].end.v[axis];
|
v.pos[i].end[axis] = v.pos[i].start.v[axis] > v.pos[i].end.v[axis] ? v.pos[i].start.v[axis] : v.pos[i].end.v[axis];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
AddVertexCount(ctx);
|
AddVertexCount(ctx);
|
||||||
|
|
||||||
@ -1596,6 +1609,12 @@ DrawGlyph(UIItem* item, Glyph* glyph, f32* x_pos, f32 y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma(inline) Vec2[2]
|
||||||
|
ItemBounds(UIItem* item)
|
||||||
|
{
|
||||||
|
return [item.rect.p0, item.rect.p1];
|
||||||
|
}
|
||||||
|
|
||||||
pragma(inline) f32
|
pragma(inline) f32
|
||||||
InnerSize(Axis2D axis)(UIItem* item)
|
InnerSize(Axis2D axis)(UIItem* item)
|
||||||
{
|
{
|
||||||
@ -1794,6 +1813,13 @@ Dragged(UIItem* item, Rect* rect)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma(inline) Vec4[4]
|
||||||
|
Vec4Arr(Vec4 col)
|
||||||
|
{
|
||||||
|
Vec4[4] arr = col;
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
{ // UI Key
|
{ // UI Key
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import editor;
|
|||||||
import parsing;
|
import parsing;
|
||||||
import buffer;
|
import buffer;
|
||||||
|
|
||||||
|
import std.algorithm.comparison : clamp;
|
||||||
import std.format;
|
import std.format;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
|
||||||
@ -13,6 +14,74 @@ Nil(UIPanel* panel)
|
|||||||
return panel == null || panel == g_UI_NIL_PANEL;
|
return panel == null || panel == g_UI_NIL_PANEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EditorView(Editor* ed)
|
||||||
|
{
|
||||||
|
UICtx* ctx = GetCtx();
|
||||||
|
UIKey zero = ZeroKey();
|
||||||
|
UIKey ed_key = MakeKey("###ed_%s", ed.editor_id);
|
||||||
|
UIItem* editor = Get(ed_key);
|
||||||
|
|
||||||
|
u64 frame_line_offset = ed.line_offset;
|
||||||
|
u64 frame_view_offset = editor.scroll_offset%TEXT_SIZE;
|
||||||
|
|
||||||
|
Push!("border_col" )(ctx, Vec4Arr(Vec4(1.0)));
|
||||||
|
|
||||||
|
// Line Counter
|
||||||
|
f32 lc_width = ed.buf.line_count.toChars().length*ctx.char_width;
|
||||||
|
|
||||||
|
Push!("view_offset" )(ctx, Vec2(0.0, frame_view_offset));
|
||||||
|
Push!("padding", true)(ctx, Vec2(4.0, 0.0));
|
||||||
|
Push!("size_info", true)(ctx, MakeUISizeX(ST.Pixels, lc_width));
|
||||||
|
|
||||||
|
UIItem* line_count = MakeItem(zero, UIF.DrawBorder);
|
||||||
|
|
||||||
|
// Editor
|
||||||
|
f32 scroll_pos = cast(f32)(ed.line_offset)*TEXT_SIZE;
|
||||||
|
|
||||||
|
Push!("scroll_clamp", true)(ctx, cast(Vec2[2])[Vec2(0.0), Vec2(0.0, cast(f32)(ed.buf.line_count)*TEXT_SIZE)]);
|
||||||
|
Push!("size_info", true)(ctx, MakeUISize(UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0)));
|
||||||
|
Push!("border_col", true)(ctx, Vec4Arr(Vec4(1.0)));
|
||||||
|
Push!("scroll_target", true)(ctx, Vec2(0.0, scroll_pos));
|
||||||
|
|
||||||
|
editor = MakeItem(ed_key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY);
|
||||||
|
|
||||||
|
Pop!("view_offset")(ctx);
|
||||||
|
|
||||||
|
u64 view_lines;
|
||||||
|
if(editor.size.y > 0.0)
|
||||||
|
{
|
||||||
|
view_lines = cast(u64)ceil(editor.size.y/TEXT_SIZE);
|
||||||
|
|
||||||
|
const u64 SCROLL_BUFFER = 2;
|
||||||
|
|
||||||
|
u64 start = ed.line_offset;
|
||||||
|
u64 end = start+view_lines;
|
||||||
|
|
||||||
|
if(ed.cursor_pos.y < start)
|
||||||
|
{
|
||||||
|
ed.line_offset = clamp(ed.cursor_pos.y - SCROLL_BUFFER, 0, ed.buf.line_count);
|
||||||
|
}
|
||||||
|
else if(ed.cursor_pos.y > end)
|
||||||
|
{
|
||||||
|
ed.line_offset = clamp(ed.cursor_pos.y + SCROLL_BUFFER - view_lines, 0, ed.buf.line_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Push!("size_info")(ctx, MakeUISizeY(ST.Pixels, TEXT_SIZE));
|
||||||
|
Push!("parent" )(ctx, line_count);
|
||||||
|
Push!("text_col" )(ctx, Vec4(1.0));
|
||||||
|
|
||||||
|
u64 i = prev_offset;
|
||||||
|
for(LineBuffer* lb = GetLine(&ed.buf, i); i < prev_offset+view_lines; i += 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Pop!("parent")(ctx);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void
|
void
|
||||||
Panel(UIPanel* panel)
|
Panel(UIPanel* panel)
|
||||||
|
|||||||
@ -14,6 +14,8 @@ layout (location = 1) in struct FragDataIn {
|
|||||||
vec2 dst_center;
|
vec2 dst_center;
|
||||||
vec2 dst_half_size;
|
vec2 dst_half_size;
|
||||||
vec2 sdf_sample_pos;
|
vec2 sdf_sample_pos;
|
||||||
|
vec2 bounds_p0;
|
||||||
|
vec2 bounds_p1;
|
||||||
float corner_radius;
|
float corner_radius;
|
||||||
float softness;
|
float softness;
|
||||||
float raised;
|
float raised;
|
||||||
|
|||||||
@ -4,19 +4,19 @@
|
|||||||
|
|
||||||
#include "gui.layout"
|
#include "gui.layout"
|
||||||
|
|
||||||
layout (location = 0) in vec4 in_col_1;
|
layout (location = 0) in vec4 in_col_1;
|
||||||
layout (location = 1) in vec4 in_col_2;
|
layout (location = 1) in vec4 in_col_2;
|
||||||
layout (location = 2) in vec4 in_col_3;
|
layout (location = 2) in vec4 in_col_3;
|
||||||
layout (location = 3) in vec4 in_col_4;
|
layout (location = 3) in vec4 in_col_4;
|
||||||
layout (location = 4) in vec2 in_dst_start;
|
layout (location = 4) in vec4 in_bounds;
|
||||||
layout (location = 5) in vec2 in_dst_end;
|
layout (location = 5) in vec2 in_dst_start;
|
||||||
layout (location = 6) in vec2 in_src_start;
|
layout (location = 6) in vec2 in_dst_end;
|
||||||
layout (location = 7) in vec2 in_src_end;
|
layout (location = 7) in vec2 in_src_start;
|
||||||
layout (location = 8) in float border_thickness;
|
layout (location = 8) in vec2 in_src_end;
|
||||||
layout (location = 9) in float corner_radius;
|
layout (location = 9) in float border_thickness;
|
||||||
layout (location = 10) in float edge_softness;
|
layout (location = 10) in float corner_radius;
|
||||||
layout (location = 11) in float raised;
|
layout (location = 11) in float edge_softness;
|
||||||
layout (location = 12) in float z_index;
|
layout (location = 12) in float raised;
|
||||||
layout (location = 13) in uint in_has_texture;
|
layout (location = 13) in uint in_has_texture;
|
||||||
|
|
||||||
layout (location = 0) flat out uint out_has_texture;
|
layout (location = 0) flat out uint out_has_texture;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user