begin work on UI
This commit is contained in:
parent
5eca5811fb
commit
ef5ea1d90a
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit 69f5cd1a76ce0ee4f61201a5cae460664a5d8ca9
|
||||
Subproject commit 6a757dd36b29f553c290d7188e8e02400cd25ba9
|
||||
@ -6,6 +6,7 @@ import vulkan;
|
||||
import dlib.math;
|
||||
import dlib.alloc;
|
||||
import buffer;
|
||||
import ui;
|
||||
|
||||
import std.stdio;
|
||||
import std.exception;
|
||||
@ -23,6 +24,8 @@ struct Editor
|
||||
Arena temp_arena;
|
||||
PlatformWindow* window;
|
||||
|
||||
UIContext ctx;
|
||||
|
||||
Renderer rd;
|
||||
ImageView font_atlas;
|
||||
Pipeline pipeline;
|
||||
@ -32,9 +35,6 @@ struct Editor
|
||||
PushConst pc;
|
||||
MappedBuffer!(Vertex) m_vertex_buf;
|
||||
MappedBuffer!(u32) m_index_buf;
|
||||
Vertex[] vertices;
|
||||
u32[] indices;
|
||||
u32 ui_count;
|
||||
|
||||
FlatBuffer[] buffers;
|
||||
Tokenizer[] tokenizers;
|
||||
@ -50,6 +50,13 @@ struct Editor
|
||||
UVec2 res;
|
||||
}
|
||||
|
||||
struct UIBuffer
|
||||
{
|
||||
Vertex[] vtx;
|
||||
u32[] idx;
|
||||
u32 count;
|
||||
}
|
||||
|
||||
struct PushConst
|
||||
{
|
||||
Mat4 projection;
|
||||
@ -72,19 +79,17 @@ struct Vertex
|
||||
void
|
||||
Cycle(Editor* ed)
|
||||
{
|
||||
ed.ui_count = 0;
|
||||
|
||||
Reset(&ed.temp_arena);
|
||||
Reset(&ed.ctx);
|
||||
|
||||
|
||||
//DrawRect(ed, 200.0, 200.0, 300.0, 300.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
|
||||
//DrawRect(ed, 330.0, 330.0, 430.0, 430.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
|
||||
//DrawRect(&ed.ctx, 200.0, 200.0, 300.0, 300.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
|
||||
//DrawRect(&ed.ctx, 330.0, 330.0, 430.0, 430.0, 0.0, 0.0, 0.0, Vec4(0.2, 0.4, 0.8, 1.0));
|
||||
Vec4 col = Vec4(0.2, 0.5, 0.9, 1.0);
|
||||
Vec4 col2 = Vec4(0.2, 0.4, 0.7, 1.0);
|
||||
Vec4 col3 = Vec4(0.2, 0.3, 0.65, 1.0);
|
||||
Vec4 black = Vec4(0.0, 0.0, 0.0, 1.0);
|
||||
DrawRect(ed, -1000.0, -1000.0, 3000.0, 3000.0, 0.0, 0.0, 0.0, 0.0, [black, black, black, black]);
|
||||
//DrawRect(ed, 450.0, 450.0, 550.0, 550.0, 2.0, 5.0, 0.2, 20.0, [black, black, black, black]);
|
||||
DrawRect(&ed.ctx, -1000.0, -1000.0, 3000.0, 3000.0, 0.0, 0.0, 0.0, 0.0, col);
|
||||
//DrawRect(&ed.ctx, 450.0, 450.0, 550.0, 550.0, 2.0, 5.0, 0.2, 20.0, [black, black, black, black]);
|
||||
|
||||
f32 pos = 0.0;
|
||||
f32 h = ed.atlas_buf.atlas.size;
|
||||
@ -107,7 +112,7 @@ Cycle(Editor* ed)
|
||||
|
||||
BindBuffers(&ed.rd, &ed.m_index_buf, &ed.m_vertex_buf);
|
||||
|
||||
DrawIndexed(&ed.rd, 6, ed.ui_count, 0);
|
||||
DrawIndexed(&ed.rd, 6, ed.ctx.buffer.count, 0);
|
||||
|
||||
FinishRendering(&ed.rd);
|
||||
|
||||
@ -228,8 +233,8 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
|
||||
|
||||
editor.m_vertex_buf = CreateMappedBuffer!(Vertex)(&editor.rd, BT.Vertex, Vertex.sizeof * UI_COUNT);
|
||||
editor.m_index_buf = CreateMappedBuffer!(u32)(&editor.rd, BT.Index, u32.sizeof * UI_COUNT);
|
||||
editor.vertices = editor.m_vertex_buf.data;
|
||||
editor.indices = editor.m_index_buf.data;
|
||||
|
||||
editor.ctx = CreateUIContext(editor.m_vertex_buf.data, editor.m_index_buf.data);
|
||||
|
||||
CreateImageView(&editor.rd, &editor.font_atlas, editor.atlas_buf.atlas.width, editor.atlas_buf.atlas.height, 4, editor.atlas_buf.data);
|
||||
|
||||
@ -249,6 +254,44 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, string str)
|
||||
DrawText(ed, x, y, px, str_buf);
|
||||
}
|
||||
|
||||
void
|
||||
DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
|
||||
{
|
||||
u32 tab_count = 2;
|
||||
f32 x_pos = x;
|
||||
f32 scale = px / ed.atlas_buf.atlas.size;
|
||||
foreach(ch; str)
|
||||
{
|
||||
foreach(glyph; ed.atlas_buf.atlas.glyphs)
|
||||
{
|
||||
if (ch == glyph.ch)
|
||||
{
|
||||
if (ch == '\t')
|
||||
{
|
||||
Glyph g = glyph;
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
foreach(i; 0 .. tab_count)
|
||||
{
|
||||
DrawGlyph(&ed.ctx, &g, scale, &x_pos, y);
|
||||
}
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
Glyph g = glyph;
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
DrawGlyph(&ed.ctx, &g, scale, &x_pos, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGlyph(&ed.ctx, &glyph, scale, &x_pos, y);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawBuffer(Editor* ed, f32 x, f32 y, f32 px, FlatBuffer* fb)
|
||||
{
|
||||
@ -288,126 +331,21 @@ DrawBuffer(Editor* ed, f32 x, f32 y, f32 px, FlatBuffer* fb)
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
foreach(j; 0 .. tab_count)
|
||||
{
|
||||
DrawGlyph(ed, g, scale, &x_pos, y_pos);
|
||||
DrawGlyph(&ed.ctx, g, scale, &x_pos, y_pos);
|
||||
}
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
DrawGlyph(ed, g, scale, &x_pos, y_pos);
|
||||
DrawGlyph(&ed.ctx, g, scale, &x_pos, y_pos);
|
||||
y_pos += px;
|
||||
x_pos = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGlyph(ed, g, scale, &x_pos, y_pos, cols[fb.tk.buffer[i]]);
|
||||
DrawGlyph(&ed.ctx, g, scale, &x_pos, y_pos, cols[fb.tk.buffer[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
|
||||
{
|
||||
u32 tab_count = 2;
|
||||
f32 x_pos = x;
|
||||
f32 scale = px / ed.atlas_buf.atlas.size;
|
||||
foreach(ch; str)
|
||||
{
|
||||
foreach(glyph; ed.atlas_buf.atlas.glyphs)
|
||||
{
|
||||
if (ch == glyph.ch)
|
||||
{
|
||||
if (ch == '\t')
|
||||
{
|
||||
Glyph g = glyph;
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
foreach(i; 0 .. tab_count)
|
||||
{
|
||||
DrawGlyph(ed, &g, scale, &x_pos, y);
|
||||
}
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
Glyph g = glyph;
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
DrawGlyph(ed, &g, scale, &x_pos, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGlyph(ed, &glyph, scale, &x_pos, y);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawGlyph(Editor* ed, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
|
||||
{
|
||||
if (glyph.atlas_left != glyph.atlas_right)
|
||||
{
|
||||
Vertex* v = ed.vertices.ptr + ed.ui_count;
|
||||
|
||||
f32 r = glyph.plane_right * scale;
|
||||
f32 l = glyph.plane_left * scale;
|
||||
f32 w = r - l;
|
||||
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
|
||||
f32 y_pos = glyph.plane_top * scale;
|
||||
|
||||
v.dst_start.x = *x_pos + l;
|
||||
v.dst_start.y = y - y_pos;
|
||||
v.dst_end.x = *x_pos + w + l;
|
||||
v.dst_end.y = y + h - y_pos;
|
||||
|
||||
v.src_start.x = glyph.atlas_left;
|
||||
v.src_start.y = glyph.atlas_top;
|
||||
v.src_end.x = glyph.atlas_right;
|
||||
v.src_end.y = glyph.atlas_bottom;
|
||||
|
||||
v.cols[0] = col;
|
||||
v.cols[1] = col;
|
||||
v.cols[2] = col;
|
||||
v.cols[3] = col;
|
||||
|
||||
v.texture = 1;
|
||||
|
||||
AddUIIndices(ed);
|
||||
}
|
||||
|
||||
*x_pos += glyph.advance * scale;
|
||||
}
|
||||
|
||||
pragma(inline) void
|
||||
DrawRect(Editor* ed, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, f32 raised, Vec4[4] cols)
|
||||
{
|
||||
// Y reversed
|
||||
Vertex* v = ed.vertices.ptr + ed.ui_count;
|
||||
v.dst_start.x = p0_x;
|
||||
v.dst_start.y = p0_y;
|
||||
v.dst_end.x = p1_x;
|
||||
v.dst_end.y = p1_y;
|
||||
v.cols = cols;
|
||||
v.border_thickness = border;
|
||||
v.corner_radius = corner;
|
||||
v.edge_softness = softness;
|
||||
v.raised = raised;
|
||||
|
||||
AddUIIndices(ed);
|
||||
}
|
||||
|
||||
void
|
||||
AddUIIndices(Editor* ed)
|
||||
{
|
||||
ed.indices[0] = 0;
|
||||
ed.indices[1] = 1;
|
||||
ed.indices[2] = 2;
|
||||
ed.indices[3] = 2;
|
||||
ed.indices[4] = 1;
|
||||
ed.indices[5] = 3;
|
||||
|
||||
ed.ui_count += 1;
|
||||
}
|
||||
|
||||
184
src/editor/ui.d
Normal file
184
src/editor/ui.d
Normal file
@ -0,0 +1,184 @@
|
||||
import dlib.aliases;
|
||||
import dlib.math;
|
||||
import dlib.util;
|
||||
import dlib.alloc;
|
||||
import dlib.fonts;
|
||||
import vulkan;
|
||||
|
||||
import editor;
|
||||
|
||||
enum BaseFlags : u32
|
||||
{
|
||||
Clickable = (1<<0),
|
||||
ViewScroll = (1<<1),
|
||||
DrawText = (1<<2),
|
||||
DrawBackground = (1<<3),
|
||||
DrawBorder = (1<<4),
|
||||
Resizeable = (1<<5),
|
||||
Draggable = (1<<6),
|
||||
}
|
||||
|
||||
union Rect
|
||||
{
|
||||
struct
|
||||
{
|
||||
Vec2 vec0;
|
||||
Vec2 vec1;
|
||||
};
|
||||
struct
|
||||
{
|
||||
f32 x0;
|
||||
f32 y0;
|
||||
f32 x1;
|
||||
f32 y1;
|
||||
};
|
||||
}
|
||||
|
||||
alias UIHash = u64;
|
||||
|
||||
alias UIPair = KVPair!(UIHash, UIItem*);
|
||||
|
||||
struct UIItem
|
||||
{
|
||||
BaseFlags flags;
|
||||
Rect rect;
|
||||
}
|
||||
|
||||
struct UIContext
|
||||
{
|
||||
HashTable!(UIHash, UIItem*) items;
|
||||
Arena arena;
|
||||
|
||||
UIBuffer buffer;
|
||||
|
||||
Vec4[4] bg_cols;
|
||||
Vec4[4] border_color;
|
||||
}
|
||||
|
||||
void
|
||||
Reset(UIContext* ctx)
|
||||
{
|
||||
ctx.buffer.count = 0;
|
||||
}
|
||||
|
||||
UIContext
|
||||
CreateUIContext(Vertex[] vtx, u32[] idx)
|
||||
{
|
||||
UIContext ctx = {
|
||||
items: CreateHashTable!(UIHash, UIItem*)(16),
|
||||
arena: CreateArena(MB(8)),
|
||||
buffer: {
|
||||
vtx: vtx,
|
||||
idx: idx,
|
||||
},
|
||||
};
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
SetBgCols(UIContext* ctx, Vec4[4] cols)
|
||||
{
|
||||
ctx.bg_cols = cols;
|
||||
}
|
||||
|
||||
void
|
||||
SetBorderCols(UIContext* ctx, Vec4[4] cols)
|
||||
{
|
||||
ctx.border_color = cols;
|
||||
}
|
||||
|
||||
UIItem*
|
||||
Find(UIContext* ctx, u8[] id)
|
||||
{
|
||||
u64 hash = Hash(id);
|
||||
Result!(UIItem*) result = ctx.items[hash];
|
||||
if (!result.ok)
|
||||
{
|
||||
result.value = Alloc!(UIItem)(&ctx.arena);
|
||||
Push(&ctx.items, hash, result.value);
|
||||
}
|
||||
|
||||
return result.value;
|
||||
}
|
||||
|
||||
bool
|
||||
UIWindow(UIContext* ctx, Rect rect, f32 border_px, u8[] text)
|
||||
{
|
||||
UIItem* item = Find(ctx, text);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawGlyph(UIContext* ctx, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
|
||||
{
|
||||
if (glyph.atlas_left != glyph.atlas_right)
|
||||
{
|
||||
Vertex* v = ctx.buffer.vtx.ptr + ctx.buffer.count;
|
||||
|
||||
f32 r = glyph.plane_right * scale;
|
||||
f32 l = glyph.plane_left * scale;
|
||||
f32 w = r - l;
|
||||
f32 h = (glyph.plane_bottom - glyph.plane_top) * scale;
|
||||
f32 y_pos = glyph.plane_top * scale;
|
||||
|
||||
v.dst_start.x = *x_pos + l;
|
||||
v.dst_start.y = y - y_pos;
|
||||
v.dst_end.x = *x_pos + w + l;
|
||||
v.dst_end.y = y + h - y_pos;
|
||||
|
||||
v.src_start.x = glyph.atlas_left;
|
||||
v.src_start.y = glyph.atlas_top;
|
||||
v.src_end.x = glyph.atlas_right;
|
||||
v.src_end.y = glyph.atlas_bottom;
|
||||
|
||||
v.cols[0] = col;
|
||||
v.cols[1] = col;
|
||||
v.cols[2] = col;
|
||||
v.cols[3] = col;
|
||||
|
||||
v.texture = 1;
|
||||
|
||||
AddUIIndices(ctx);
|
||||
}
|
||||
|
||||
*x_pos += glyph.advance * scale;
|
||||
}
|
||||
|
||||
pragma(inline) void
|
||||
DrawRect(UIContext* ctx, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, f32 raised, Vec4 col)
|
||||
{
|
||||
DrawRect(ctx, p0_x, p0_y, p1_x, p1_y, border, corner, softness, raised, [col, col, col, col]);
|
||||
}
|
||||
|
||||
pragma(inline) void
|
||||
DrawRect(UIContext* ctx, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32 corner, f32 softness, f32 raised, Vec4[4] cols)
|
||||
{
|
||||
// Y reversed
|
||||
Vertex* v = ctx.buffer.vtx.ptr + ctx.buffer.count;
|
||||
v.dst_start.x = p0_x;
|
||||
v.dst_start.y = p0_y;
|
||||
v.dst_end.x = p1_x;
|
||||
v.dst_end.y = p1_y;
|
||||
v.cols = cols;
|
||||
v.border_thickness = border;
|
||||
v.corner_radius = corner;
|
||||
v.edge_softness = softness;
|
||||
v.raised = raised;
|
||||
|
||||
AddUIIndices(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
AddUIIndices(UIContext* ctx)
|
||||
{
|
||||
ctx.buffer.idx[0] = 0;
|
||||
ctx.buffer.idx[1] = 1;
|
||||
ctx.buffer.idx[2] = 2;
|
||||
ctx.buffer.idx[3] = 2;
|
||||
ctx.buffer.idx[4] = 1;
|
||||
ctx.buffer.idx[5] = 3;
|
||||
|
||||
ctx.buffer.count += 1;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user