refactor + work

This commit is contained in:
Matthew 2026-01-20 06:12:12 +11:00
parent 1700119e57
commit f13daded03
4 changed files with 871 additions and 470 deletions

View File

@ -18,11 +18,61 @@ import core.stdc.stdio;
f32 g_delta = 0.0;
struct EditorCtx
struct RenderCtx
{
Arena arena;
PlatformWindow* window;
Panel* base_panel;
PlatformWindow* window;
Renderer rd;
Descriptor[FS][FO] font_descs;
Descriptor default_tex;
Descriptor sampler;
Pipeline pipeline;
DescSetLayout desc_set_layout;
DescSet[FO] desc_sets;
PipelineLayout pipeline_layout;
PushConst pc;
Vec2 res;
}
struct Ctx
{
RenderCtx rd_ctx;
HashTable!(UIHash, UIItem*) items;
UIItem* free_items;
UIItem* last_item;
Arena arena;
Arena temp_arena;
Inputs* inputs;
u64 frame;
u64 f_idx;
LinkedList!(UIInput) events;
IVec2 mouse_pos;
FontFace font;
FontGlyphs[FS] glyph_sets;
u32 glyph_sets_used;
bool[FO] glyphs_to_load;
bool prev_has_tex;
u32 prev_atlas_index;
UIBuffer[FO] buffers;
u32 tab_width;
Vec4[TS.max][UISH.max] syntax_colors;
UIKey drag_key;
UIKey hover_key;
UIKey focus_key;
u64 last_hover_frame;
f32 scroll_rate;
f32 animation_rate;
f32 fade_rate;
EditState state;
u8[128] input_buf;
u32 icount;
@ -32,7 +82,7 @@ struct EditorCtx
string[] file_names;
u64 panel_id;
Panel* focused_panel;
alias rd_ctx this;
}
struct CmdPalette
@ -60,6 +110,7 @@ struct Editor
Vec2 select_start;
Vec2 select_end;
i64 line_offset;
i64 line_height;
}
struct ChangeStacks
@ -79,12 +130,19 @@ struct EditorChange
EditorChange* next;
}
alias CmdFn = bool function(Ctx* ctx);
struct Command
{
string name;
string desc;
string cmd;
CmdType type;
union
{
CmdFn fn;
}
}
struct Parameter
@ -119,11 +177,11 @@ alias ES = EditState;
bool
CmdModeActive()
{
return g_ed_ctx.state == ES.CmdPalette;
return g_ctx.state == ES.CmdPalette;
}
__gshared bool g_input_mode = false;
__gshared EditorCtx g_ed_ctx;
__gshared bool g_input_mode = false;
__gshared Ctx g_ctx;
const Command NO_CMD = {
name: [],
@ -166,7 +224,20 @@ const Command[] CMD_LIST = [
bool
Active(EditState state)
{
return g_ed_ctx.state == state;
return g_ctx.state == state;
}
UIPanel*
MakePanel(UIPanel* parent = g_NIL_PANEL)
{
UIPanel* p = Alloc!(UIPanel);
static u32 id;
p.id = id++;
p.item = MakeItem("###panel_%s", p.id);
return p;
}
void
@ -174,33 +245,87 @@ Cycle(Inputs* inputs)
{
ResetScratch(MB(4));
g_delta = DeltaTime(&g_ed_ctx.timer);
g_delta = DeltaTime(&g_ctx.timer);
g_input_mode = Active(ES.InputMode);
BeginUI(inputs);
UICtx* ui_ctx = GetCtx();
Ctx* ctx = GetCtx();
static UIPanel* panel;
if(Nil(panel))
{
panel = MakePanel();
panel.pct = 1.0;
UIPanel* p0 = MakePanel();
UIPanel* p1 = MakePanel();
UIPanel* p2 = MakePanel();
UIPanel* p3 = MakePanel();
UIPanel* p4 = MakePanel();
UIPanel* p5 = MakePanel();
UIPanel* p6 = MakePanel();
p0.pct = 0.3;
p1.pct = 0.7;
p0.parent = panel;
p1.parent = panel;
DLLPush(panel, p0, g_NIL_PANEL);
DLLPush(panel, p1, g_NIL_PANEL);
p0.axis = A2D.Y;
p2.pct = 0.25;
p3.pct = 0.35;
p4.pct = 0.40;
p2.parent = p3.parent = p4.parent = p0;
DLLPush(p0, p2, g_NIL_PANEL);
DLLPush(p0, p3, g_NIL_PANEL);
DLLPush(p0, p4, g_NIL_PANEL);
p5.pct = 0.2;
p6.pct = 0.8;
p5.parent = p6.parent = p4;
DLLPush(p4, p5, g_NIL_PANEL);
DLLPush(p4, p6, g_NIL_PANEL);
p1.ed = CreateEditor();
p2.ed = CreateEditor();
p3.ed = CreateEditor();
p5.ed = CreateEditor();
p6.ed = CreateEditor();
OpenFile(p1.ed, "./src/VulkanRenderer/external/vma/vk_mem_alloc.h");
OpenFile(p3.ed, "./src/VulkanRenderer/external/vma/vk_mem_alloc.h");
OpenFile(p5.ed, "./src/VulkanRenderer/external/vma/vk_mem_alloc.h");
OpenFile(p6.ed, "./src/VulkanRenderer/external/vma/vk_mem_alloc.h");
}
Panel(ctx, panel);
EndUI();
}
void
InitEditorCtx(PlatformWindow* window)
InitCtx(PlatformWindow* window)
{
InitUICtx(window);
EditorCtx* ctx = &g_ed_ctx;
Ctx* ctx = &g_ctx;
ctx.window = window;
ctx.arena = CreateArena(MB(2));
ctx.cmd.arena = CreateArena(MB(1));
ctx.cmd.cmd_arena = CreateArena(MB(1));
ctx.cmd.buffer = Alloc!(u8)(1024);
ctx.base_panel = CreatePanel(CreateEditor());
//ctx.base_panel = CreatePanel(CreateEditor());
ctx.timer = CreateTimer();
FocusEditor(ctx.base_panel);
InitUI(ctx);
//FocusEditor(ctx.base_panel);
if(getcwd() != "/")
{
@ -234,26 +359,36 @@ InitEditorCtx(PlatformWindow* window)
}
}
Ctx*
GetCtx()
{
return &g_ctx;
}
/*
void
FocusEditor(Panel* p)
{
assert(p.ed);
g_ed_ctx.focused_panel = p;
g_ctx.focused_panel = p;
}
*/
/*
Panel*
CreatePanel(Editor* ed = null)
{
Panel* p = Alloc!(Panel)(&g_ed_ctx.arena);
Panel* p = Alloc!(Panel)(&g_ctx.arena);
p.layout_axis = A2D.Y;
p.ed = ed;
p.id = g_ed_ctx.panel_id++;
p.id = g_ctx.panel_id++;
p.text_size = 14;
p.parent = p.first = p.last = p.next = p.prev = g_NIL_PANEL;
return p;
}
*/
bool
EditModeActive()
@ -391,15 +526,16 @@ OpenFile(Editor* ed, string file_name)
Editor*
CreateEditor()
{
Editor* ed = Alloc!(Editor)(&g_ed_ctx.arena);
Editor* ed = Alloc!(Editor)(&g_ctx.arena);
ed.arena = CreateArena(MB(4));
ed.buf = CreateFlatBuffer([], []);
ed.editor_id = g_ed_ctx.editor_id_incr++;
ed.editor_id = g_ctx.editor_id_incr++;
return ed;
}
/*
void
AddEditor(Panel* target, Axis2D axis)
{
@ -441,20 +577,15 @@ AddEditor(Panel* target, Axis2D axis)
c.resize_pct = pct;
}
}
*/
* /
FocusEditor(panel);
}
}
UIItem*
GetEditorItem(Editor* ed)
{
return Get("###ed_%s", ed.editor_id);
}
*/
pragma(inline) void
InsertInputToBuf(EditorCtx* ctx, Editor* ed)
InsertInputToBuf(Ctx* ctx, Editor* ed)
{
if(ctx.icount > 0)
{
@ -466,18 +597,18 @@ InsertInputToBuf(EditorCtx* ctx, Editor* ed)
void
ResetCtx(Editor* ed)
{
InsertInputToBuf(&g_ed_ctx, ed);
InsertInputToBuf(&g_ctx, ed);
ResetCtx();
}
void
ResetCtx()
{
g_ed_ctx.state = ES.NormalMode;
g_ed_ctx.cmd.icount = 0;
g_ed_ctx.cmd.commands = [];
g_ed_ctx.cmd.current = cast(Command)NO_CMD;
g_ed_ctx.cmd.selected = 0;
g_ctx.state = ES.NormalMode;
g_ctx.cmd.icount = 0;
g_ctx.cmd.commands = [];
g_ctx.cmd.current = cast(Command)NO_CMD;
g_ctx.cmd.selected = 0;
}
bool
@ -534,12 +665,12 @@ MovePanelFocus(A2D axis, bool prev)(UIPanel* panel)
}
void
HandleInputs(Panel* p, LinkedList!(UIInput)* inputs)
HandleInputs(UIPanel* p, LinkedList!(UIInput)* inputs, bool hovered, bool focused)
{
Editor* ed = p.ed;
EditorCtx* ctx = &g_ed_ctx;
u8[] cb_text;
FlatBuffer* fb = &ed.buf;
Editor* ed = p.ed;
Ctx* ctx = &g_ctx;
FlatBuffer* fb = &ed.buf;
u8[] cb_text;
for(auto node = inputs.first; node != null; node = node.next)
{
@ -548,92 +679,121 @@ HandleInputs(Panel* p, LinkedList!(UIInput)* inputs)
Input key = node.key;
Modifier md = node.md;
if(key == Input.Escape)
switch(node.type)
{
ResetCtx(ed);
taken = true;
}
else if(ctx.state == ES.InputMode)
{
taken = HandleInputMode(ctx, p, node);
}
else if(ctx.state == ES.SetPanelFocus)
{
switch(key) with(Input)
{
case Escape:
case UIE.Click:
{
if(hovered)
{
ResetCtx(ed);
Focus(p);
taken = true;
} break;
default: break;
}
}
else
{
switch(key) with(Input)
{
case a, i:
}
else
{
if(key == a && Shift(md) && fb)
{
MoveToEOL(fb);
}
else if(key == a)
{
Move(fb, Right, MD.None);
}
else if(key == i && Shift(md))
{
MoveToSOL(fb);
}
ctx.state = ES.InputMode;
taken = true;
} break;
case Semicolon:
// TODO: set cursor pos
}
} break;
case UIE.Drag:
{
// TODO: did drag start on this panel and if so modify selection
} break;
case UIE.DragRelease:
{
// TODO: if dragged end selection
} break;
case UIE.DragStart:
{
if(hovered)
{
if(Shift(node.md))
{
ctx.state = ES.CmdPalette;
ctx.cmd.commands = cast(Command[])CMD_LIST;
ctx.cmd.icount = 0;
ctx.cmd.params = [];
taken = true;
}
} break;
case v:
// TODO: Selection
}
} break;
case UIE.Press:
{
if(focused)
{
if(Ctrl(md))
if(key == Input.Escape)
{
cb_text = ClipboardText(ctx.window);
ResetCtx(ed);
taken = true;
}
if(Shift(md))
else if(ctx.state == ES.InputMode)
{
ToggleSelection(fb, SM.Line);
taken = HandleInputMode(ctx, p, node);
}
else
{
ToggleSelection(fb, SM.Normal);
switch(key) with(Input)
{
case a, i:
{
if(key == a && Shift(md) && fb)
{
MoveToEOL(fb);
}
else if(key == a)
{
Move(fb, Right, MD.None);
}
else if(key == i && Shift(md))
{
MoveToSOL(fb);
}
ctx.state = ES.InputMode;
taken = true;
} break;
case Semicolon:
{
if(Shift(node.md))
{
ctx.state = ES.CmdPalette;
ctx.cmd.commands = cast(Command[])CMD_LIST;
ctx.cmd.icount = 0;
ctx.cmd.params = [];
taken = true;
}
} break;
case v:
{
if(Ctrl(md))
{
cb_text = ClipboardText(ctx.window);
}
if(Shift(md))
{
ToggleSelection(fb, SM.Line);
}
else
{
ToggleSelection(fb, SM.Normal);
}
} break;
case c:
{
if(Ctrl(md))
{
// TODO: Copy
taken = true;
}
} break;
default:
{
taken = MoveCursor(ed, node);
} break;
}
}
} break;
case c:
}
} break;
case UIE.Scroll:
{
if(hovered)
{
if(Ctrl(md))
{
// Copy
taken = true;
}
} break;
case w:
{
if(Ctrl(md))
{
ctx.state = ES.SetPanelFocus;
}
} break;
default: taken = Move(fb, key, md); break;
}
SetOffset(ed, node.scroll*30);
taken = true;
}
} break;
default: break;
}
if(taken)
@ -651,17 +811,48 @@ HandleInputs(Panel* p, LinkedList!(UIInput)* inputs)
}
void
SetOffset(Editor* ed, i64 adjust)
{
i64 max_offset = ed.buf.line_count-ed.line_height;
if(max_offset < 0)
{
max_offset = 0;
}
ed.line_offset = clamp(ed.line_offset+adjust, 0, max_offset);
}
bool
MoveCursor(Editor* ed, UIInput* ev)
{
bool taken;
switch(ev.key) with(Input)
{
case Up, Down, Left, Right: Move(&ed.buf, ev.key, ev.md); break;
case Up, Down, Left, Right: taken = Move(&ed.buf, ev.key, ev.md); break;
default: break;
}
if(taken)
{
I64Vec2 pos = VecPos(&ed.buf);
i64 min = ed.line_offset+2;
i64 max = clamp(ed.line_offset+ed.line_height-3, 0, ed.buf.line_count);
if(pos.y > max)
{
SetOffset(ed, pos.y-max);
}
else if(pos.y < min)
{
SetOffset(ed, -(min-pos.y));
}
}
return taken;
}
pragma(inline) void
InsertChar(EditorCtx* ctx, Input input, bool modified)
InsertChar(Ctx* ctx, Input input, bool modified)
{
ctx.input_buf[ctx.icount++] = InputToChar(input, modified);
}
@ -684,7 +875,7 @@ CharCases()
}
bool
HandleInputMode(EditorCtx* ctx, Panel* p, UIInput* ev)
HandleInputMode(Ctx* ctx, UIPanel* p, UIInput* ev)
{
bool taken = false;
@ -794,11 +985,12 @@ StrContains(bool begins_with, T, U)(T str_param, U match_param) if(StringType!(T
return count == match.length;
}
/*
bool
HandleCmdMode(CmdPalette* cmd, UIInput* ev)
{
bool taken;
Panel* panel = g_ed_ctx.focused_panel;
Panel* panel = g_ctx.focused_panel;
Editor* ed = panel.ed;
u64 prev_count = cmd.icount;
@ -809,7 +1001,7 @@ HandleCmdMode(CmdPalette* cmd, UIInput* ev)
if(cmd.current.type == CT.None && cmd.commands.length > 0)
{
cmd.current = cmd.commands[cmd.selected];
g_ed_ctx.state = ES.RunCmd;
g_ctx.state = ES.RunCmd;
}
} goto CmdInputEnd;
case Backspace:
@ -898,7 +1090,7 @@ HandleCmdMode(CmdPalette* cmd, UIInput* ev)
{
case OpenFile:
{
PopulateParams(cmd, g_ed_ctx.file_names);
PopulateParams(cmd, g_ctx.file_names);
} break;
case SaveFile:
{
@ -912,6 +1104,7 @@ CmdInputEnd:
return taken;
}
*/
pragma(inline) void
Check(CmdPalette* cmd, u64 length)

View File

@ -27,7 +27,7 @@ void main(string[] argv)
StartPlatformThread(&window);
InitEditorCtx(&window);
InitCtx(&window);
import ui;
import vulkan;
@ -41,9 +41,9 @@ void main(string[] argv)
break;
}
if(g_ui_ctx.rd.res != Vec2(window.w, window.h).v)
if(g_ctx.rd.res != Vec2(window.w, window.h).v)
{
SetExtent(&g_ui_ctx.rd, window.w, window.h);
SetExtent(&g_ctx.rd, window.w, window.h);
}
if(inputs.first == null)

File diff suppressed because it is too large Load Diff

View File

@ -9,11 +9,8 @@ import std.algorithm.comparison : clamp;
import std.format;
import std.conv;
__gshared const Panel g_nil_panel;
__gshared Panel* g_NIL_PANEL;
__gshared const Editor g_nil_ed;
__gshared Editor* g_NIL_ED;
__gshared const UIKey ZERO = ZeroKey();
/******
- Set up "themes" for different components (e.g. command palette window, editor view, status bar) then have the ability to create styles and apply them to different sections via a string lookup, e.g. start of function to draw cmd palette call ApplyTheme(selected_theme_name) then do code to draw things, get to options and call ApplyTheme(selected_theme_name_for_options), etc.
@ -27,15 +24,6 @@ const u32 CMD_SUB_PX = 10;
shared static this()
{
g_NIL_PANEL = cast(Panel* )&g_nil_panel;
g_NIL_ED = cast(Editor*)&g_nil_ed;
}
struct Panel
{
Panel* first, last, next, prev, parent;
Axis2D layout_axis;
Editor* ed;
u64 id;
u32 text_size;
}