start work on ui layout frameowkr
This commit is contained in:
parent
91f2914c46
commit
e30d8f6689
@ -679,6 +679,7 @@ unittest
|
||||
|
||||
// FlatBuffer lines
|
||||
{
|
||||
/*
|
||||
u8[] data = StringToU8("This is a line.\nThis is a second line,\nalong with a third line.");
|
||||
FlatBuffer buf = CreateFlatBuffer(data);
|
||||
|
||||
@ -727,5 +728,6 @@ unittest
|
||||
assert(lines[i][j] == ch, "FlatBuffer GetLines 2 failure: result strings do not match");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,8 +24,6 @@ struct Editor
|
||||
Arena temp_arena;
|
||||
PlatformWindow* window;
|
||||
|
||||
UIContext ctx;
|
||||
|
||||
Renderer rd;
|
||||
ImageView font_atlas;
|
||||
Pipeline pipeline;
|
||||
@ -33,8 +31,6 @@ struct Editor
|
||||
DescSet desc_set;
|
||||
PipelineLayout pipeline_layout;
|
||||
PushConst pc;
|
||||
MappedBuffer!(Vertex) m_vertex_buf;
|
||||
MappedBuffer!(u32) m_index_buf;
|
||||
|
||||
FlatBuffer[] buffers;
|
||||
Tokenizer[] tokenizers;
|
||||
@ -50,13 +46,6 @@ struct Editor
|
||||
UVec2 res;
|
||||
}
|
||||
|
||||
struct UIBuffer
|
||||
{
|
||||
Vertex[] vtx;
|
||||
u32[] idx;
|
||||
u32 count;
|
||||
}
|
||||
|
||||
struct PushConst
|
||||
{
|
||||
Mat4 projection;
|
||||
@ -76,69 +65,6 @@ struct Vertex
|
||||
u32 texture;
|
||||
}
|
||||
|
||||
void
|
||||
Cycle(Editor* ed)
|
||||
{
|
||||
Reset(&ed.temp_arena);
|
||||
Reset(&ed.ctx);
|
||||
|
||||
//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.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;
|
||||
DrawBuffer(ed, 0.0, 0.0, h, ed.active_buffer);
|
||||
|
||||
BeginFrame(&ed.rd);
|
||||
|
||||
UVec2 ext = UVec2(GetExtent(&ed.rd));
|
||||
if (ext != ed.res)
|
||||
{
|
||||
ed.res = ext;
|
||||
Ortho(&ed.pc.projection, 0.0, 0.0, cast(f32)(ext.x), cast(f32)(ext.y), 1000.0, 0.1);
|
||||
}
|
||||
|
||||
BeginRendering(&ed.rd);
|
||||
|
||||
PushConstants(&ed.rd, ed.pipeline, &ed.pc);
|
||||
|
||||
Bind(&ed.rd, ed.pipeline, ed.desc_set);
|
||||
|
||||
BindBuffers(&ed.rd, &ed.m_index_buf, &ed.m_vertex_buf);
|
||||
|
||||
DrawIndexed(&ed.rd, 6, ed.ctx.buffer.count, 0);
|
||||
|
||||
FinishRendering(&ed.rd);
|
||||
|
||||
SubmitAndPresent(&ed.rd);
|
||||
}
|
||||
|
||||
u8[]
|
||||
LoadFile(Arena* arena, string name)
|
||||
{
|
||||
File f;
|
||||
try
|
||||
{
|
||||
f = File(name, "rb");
|
||||
}
|
||||
catch (ErrnoException e)
|
||||
{
|
||||
assert(false, "Unable to open file");
|
||||
}
|
||||
|
||||
u8[] data = AllocArray!(u8)(arena, f.size());
|
||||
f.rawRead(data);
|
||||
f.close();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
Editor
|
||||
CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
|
||||
{
|
||||
@ -231,10 +157,8 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
|
||||
|
||||
assert(CreateGraphicsPipeline(&editor.rd, &editor.pipeline, &ui_info), "Unable to build UI pipeline");
|
||||
|
||||
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.ctx = CreateUIContext(editor.m_vertex_buf.data, editor.m_index_buf.data);
|
||||
InitUIContext(&editor.rd);
|
||||
SetProp!(CtxP.FontAtlas)(editor.atlas_buf.atlas);
|
||||
|
||||
CreateImageView(&editor.rd, &editor.font_atlas, editor.atlas_buf.atlas.width, editor.atlas_buf.atlas.height, 4, editor.atlas_buf.data);
|
||||
|
||||
@ -247,6 +171,36 @@ CreateEditor(PlatformWindow* window, u8[] buffer_data, u8[] buffer_name)
|
||||
return editor;
|
||||
}
|
||||
|
||||
void
|
||||
Cycle(Editor* ed)
|
||||
{
|
||||
Reset(&ed.temp_arena);
|
||||
UIBeginFrame();
|
||||
|
||||
f32 pos = 0.0;
|
||||
f32 h = ed.atlas_buf.atlas.size;
|
||||
DrawBuffer(ed, 0.0, 0.0, h, ed.active_buffer);
|
||||
|
||||
BeginFrame(&ed.rd);
|
||||
|
||||
UVec2 ext = UVec2(GetExtent(&ed.rd));
|
||||
if (ext != ed.res)
|
||||
{
|
||||
ed.res = ext;
|
||||
Ortho(&ed.pc.projection, 0.0, 0.0, cast(f32)(ext.x), cast(f32)(ext.y), 1000.0, 0.1);
|
||||
}
|
||||
|
||||
BeginRendering(&ed.rd);
|
||||
|
||||
PushConstants(&ed.rd, ed.pipeline, &ed.pc);
|
||||
|
||||
Bind(&ed.rd, ed.pipeline, ed.desc_set);
|
||||
|
||||
FinishRendering(&ed.rd);
|
||||
|
||||
SubmitAndPresent(&ed.rd);
|
||||
}
|
||||
|
||||
void
|
||||
DrawText(Editor* ed, f32 x, f32 y, f32 px, string str)
|
||||
{
|
||||
@ -272,18 +226,18 @@ DrawText(Editor* ed, f32 x, f32 y, f32 px, u8[] str)
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
foreach(i; 0 .. tab_count)
|
||||
{
|
||||
DrawGlyph(&ed.ctx, &g, scale, &x_pos, y);
|
||||
DrawGlyph(&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);
|
||||
DrawGlyph(&g, scale, &x_pos, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGlyph(&ed.ctx, &glyph, scale, &x_pos, y);
|
||||
DrawGlyph(&glyph, scale, &x_pos, y);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -331,19 +285,19 @@ 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.ctx, g, scale, &x_pos, y_pos);
|
||||
DrawGlyph(g, scale, &x_pos, y_pos);
|
||||
}
|
||||
}
|
||||
else if (ch == '\n')
|
||||
{
|
||||
g.atlas_left = g.atlas_right = 0.0;
|
||||
DrawGlyph(&ed.ctx, g, scale, &x_pos, y_pos);
|
||||
DrawGlyph(g, scale, &x_pos, y_pos);
|
||||
y_pos += px;
|
||||
x_pos = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawGlyph(&ed.ctx, g, scale, &x_pos, y_pos, cols[fb.tk.buffer[i]]);
|
||||
DrawGlyph(g, scale, &x_pos, y_pos, cols[fb.tk.buffer[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,7 +618,7 @@ ParseId(FlatBuffer* fb)
|
||||
assert(t.start < t.end, "ParseId failure: start is lower or equal to end");
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
pragma(inline) bool
|
||||
CheckEOL(u8 ch)
|
||||
{
|
||||
return ch == 0x0D||
|
||||
@ -627,7 +627,7 @@ CheckEOL(u8 ch)
|
||||
ch == 0x0C;
|
||||
}
|
||||
|
||||
pragma(inline): bool
|
||||
pragma(inline) bool
|
||||
CheckWhiteSpace(u8 ch)
|
||||
{
|
||||
return ch == ' ' ||
|
||||
|
||||
375
src/editor/ui.d
375
src/editor/ui.d
@ -7,7 +7,75 @@ import vulkan;
|
||||
|
||||
import editor;
|
||||
|
||||
enum BaseFlags : u32
|
||||
UIContext g_ui_ctx;
|
||||
const UIItem g_ui_nil_item;
|
||||
UIItem* g_UI_NIL;
|
||||
|
||||
struct UIContext
|
||||
{
|
||||
HashTable!(UIHash, UIItem*) items;
|
||||
Arena arena;
|
||||
Renderer* rd;
|
||||
|
||||
UIBuffer buffer;
|
||||
|
||||
UIItem* root;
|
||||
|
||||
// UI builder state
|
||||
FontAtlas atlas;
|
||||
Vec4[4] bg_cols;
|
||||
Vec4[4] border_cols;
|
||||
UISize[A2D.max] size_axes;
|
||||
Rect padding;
|
||||
u32 tab_width;
|
||||
f32 text_scale;
|
||||
}
|
||||
|
||||
struct UIBuffer
|
||||
{
|
||||
MappedBuffer!(Vertex) mapped_vtx;
|
||||
MappedBuffer!(u32) mapped_idx;
|
||||
Vertex[] vtx;
|
||||
u32[] idx;
|
||||
u32 count;
|
||||
}
|
||||
|
||||
enum CtxProperty
|
||||
{
|
||||
None,
|
||||
BackgroundColor,
|
||||
BorderColor,
|
||||
SizeKind,
|
||||
SizeValue,
|
||||
SizeStrictness,
|
||||
FontAtlas,
|
||||
AxisX,
|
||||
AxisY,
|
||||
Padding,
|
||||
TextScale,
|
||||
TabWidth,
|
||||
}
|
||||
|
||||
alias CtxP = CtxProperty;
|
||||
|
||||
enum Axis2D
|
||||
{
|
||||
X,
|
||||
Y,
|
||||
Max,
|
||||
}
|
||||
|
||||
alias A2D = Axis2D;
|
||||
|
||||
enum UIRecurse
|
||||
{
|
||||
PostOrder,
|
||||
PreOrder,
|
||||
}
|
||||
|
||||
alias UIR = UIRecurse;
|
||||
|
||||
enum UIProperties : u64
|
||||
{
|
||||
Clickable = (1<<0),
|
||||
ViewScroll = (1<<1),
|
||||
@ -18,6 +86,19 @@ enum BaseFlags : u32
|
||||
Draggable = (1<<6),
|
||||
}
|
||||
|
||||
alias UIP = UIProperties;
|
||||
|
||||
enum SizeKind : u64
|
||||
{
|
||||
None,
|
||||
Pixels,
|
||||
TextContent,
|
||||
PercentOfParent,
|
||||
ChildrenSum,
|
||||
}
|
||||
|
||||
alias SK = SizeKind;
|
||||
|
||||
union Rect
|
||||
{
|
||||
struct
|
||||
@ -38,87 +119,169 @@ alias UIHash = u64;
|
||||
|
||||
alias UIPair = KVPair!(UIHash, UIItem*);
|
||||
|
||||
struct UISize
|
||||
{
|
||||
SizeKind kind;
|
||||
f32 value;
|
||||
f32 strictness;
|
||||
}
|
||||
|
||||
struct UIItem
|
||||
{
|
||||
BaseFlags flags;
|
||||
UIProperties flags;
|
||||
|
||||
UIItem* first;
|
||||
UIItem* last;
|
||||
UIItem* next;
|
||||
UIItem* prev;
|
||||
UIItem* parent;
|
||||
|
||||
UISize[A2D.max] size;
|
||||
Rect padding;
|
||||
f32[A2D.max] computed_rel_pos;
|
||||
f32[A2D.max] computed_size;
|
||||
Rect rect;
|
||||
f32 text_scale;
|
||||
}
|
||||
|
||||
struct UIContext
|
||||
struct UIKey
|
||||
{
|
||||
HashTable!(UIHash, UIItem*) items;
|
||||
Arena arena;
|
||||
|
||||
UIBuffer buffer;
|
||||
|
||||
Vec4[4] bg_cols;
|
||||
Vec4[4] border_cols;
|
||||
u8[] text;
|
||||
u64 hash;
|
||||
}
|
||||
|
||||
void
|
||||
Reset(UIContext* ctx)
|
||||
UIBeginFrame()
|
||||
{
|
||||
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;
|
||||
g_ui_ctx.buffer.count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SetBgCols(UIContext* ctx, Vec4[4] cols)
|
||||
UIFrameSubmit()
|
||||
{
|
||||
ctx.bg_cols = cols;
|
||||
BindBuffers(g_ui_ctx.rd, &g_ui_ctx.buffer.mapped_idx, &g_ui_ctx.buffer.mapped_vtx);
|
||||
DrawIndexed(g_ui_ctx.rd, 6, g_ui_ctx.buffer.count, 0);
|
||||
}
|
||||
|
||||
void
|
||||
SetBorderCols(UIContext* ctx, Vec4[4] cols)
|
||||
InitUIContext(Renderer* rd)
|
||||
{
|
||||
ctx.border_cols = cols;
|
||||
g_UI_NIL = cast(UIItem*)&g_ui_nil_item;
|
||||
|
||||
auto vtx = CreateMappedBuffer!(Vertex)(rd, BT.Vertex, Vertex.sizeof * UI_COUNT);
|
||||
auto idx = CreateMappedBuffer!(u32)(rd, BT.Index, u32.sizeof * UI_COUNT);
|
||||
|
||||
g_ui_ctx.root = g_UI_NIL;
|
||||
g_ui_ctx.items = CreateHashTable!(UIHash, UIItem*)(16);
|
||||
g_ui_ctx.arena = CreateArena(MB(8));
|
||||
g_ui_ctx.rd = rd;
|
||||
g_ui_ctx.buffer.mapped_vtx = vtx;
|
||||
g_ui_ctx.buffer.mapped_idx = idx;
|
||||
g_ui_ctx.buffer.vtx = vtx.data;
|
||||
g_ui_ctx.buffer.idx = idx.data;
|
||||
}
|
||||
|
||||
UIKey
|
||||
MakeKey(u8[] id)
|
||||
{
|
||||
UIKey key;
|
||||
|
||||
u32 pos = 0;
|
||||
u32 hash_count = 0;
|
||||
for(u32 i = 0; i < id.length; i += 1)
|
||||
{
|
||||
if (hash_count == 2)
|
||||
{
|
||||
if (id[i] == '#')
|
||||
{
|
||||
hash_count += 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (id[i] == '#')
|
||||
{
|
||||
if (hash_count == 0)
|
||||
{
|
||||
pos = i;
|
||||
}
|
||||
|
||||
hash_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (hash_count == 2)
|
||||
{
|
||||
key.text = id[0 .. pos];
|
||||
key.hash = Hash(id);
|
||||
}
|
||||
else if (hash_count == 3)
|
||||
{
|
||||
key.text = id[0 .. pos];
|
||||
key.hash = Hash(id[pos+hash_count .. $]);
|
||||
}
|
||||
else
|
||||
{
|
||||
key.text = id;
|
||||
key.hash = Hash(id);
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
|
||||
UIItem*
|
||||
Find(UIContext* ctx, u8[] id)
|
||||
Find(u8[] id)
|
||||
{
|
||||
u64 hash = Hash(id);
|
||||
Result!(UIItem*) result = ctx.items[hash];
|
||||
Result!(UIItem*) result = g_ui_ctx.items[hash];
|
||||
if (!result.ok)
|
||||
{
|
||||
result.value = Alloc!(UIItem)(&ctx.arena);
|
||||
Push(&ctx.items, hash, result.value);
|
||||
result.value = Alloc!(UIItem)(&g_ui_ctx.arena);
|
||||
Push(&g_ui_ctx.items, hash, result.value);
|
||||
}
|
||||
|
||||
return result.value;
|
||||
}
|
||||
|
||||
bool
|
||||
UIWindow(UIContext* ctx, Rect rect, f32 border_px, u8[] text)
|
||||
UIWindow(Rect rect, f32 border_px, u8[] text)
|
||||
{
|
||||
UIItem* item = Find(ctx, text);
|
||||
|
||||
DrawRect(ctx, rect.x0, rect.y0, rect.x1, rect.y1, 0.0, 0.0, 0.0, 0.0, ctx.bg_cols);
|
||||
DrawRect(ctx, rect.x0, rect.y0, rect.x1, rect.y1, border_px, 0.0, 0.0, 0.0, ctx.border_cols);
|
||||
UIItem* item = Find(text);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
pragma(inline): void
|
||||
DrawGlyph(UIContext* ctx, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
|
||||
f32
|
||||
CalcTextWidth(u8[] str)
|
||||
{
|
||||
u32 tab_width = g_ui_ctx.tab_width;
|
||||
Glyph* space = g_ui_ctx.atlas.glyphs.ptr + ' ';
|
||||
|
||||
f32 width;
|
||||
for(u64 i = 0; i < str.length; i += 1)
|
||||
{
|
||||
Glyph* g = g_ui_ctx.atlas.glyphs.ptr + str.ptr[i];
|
||||
|
||||
if (g.ch == '\t')
|
||||
{
|
||||
width += space.advance * cast(f32)(tab_width);
|
||||
}
|
||||
else
|
||||
{
|
||||
width += g.advance;
|
||||
}
|
||||
}
|
||||
|
||||
return width * g_ui_ctx.text_scale;
|
||||
}
|
||||
|
||||
pragma(inline) void
|
||||
DrawGlyph(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;
|
||||
Vertex* v = g_ui_ctx.buffer.vtx.ptr + g_ui_ctx.buffer.count;
|
||||
|
||||
f32 r = glyph.plane_right * scale;
|
||||
f32 l = glyph.plane_left * scale;
|
||||
@ -143,23 +306,18 @@ DrawGlyph(UIContext* ctx, Glyph* glyph, f32 scale, f32* x_pos, f32 y, Vec4 col =
|
||||
|
||||
v.texture = 1;
|
||||
|
||||
AddUIIndices(ctx);
|
||||
AddUIIndices();
|
||||
}
|
||||
|
||||
*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;
|
||||
Vertex* v = g_ui_ctx.buffer.vtx.ptr + g_ui_ctx.buffer.count;
|
||||
v.dst_start.x = p0_x;
|
||||
v.dst_start.y = p0_y;
|
||||
v.dst_end.x = p1_x;
|
||||
@ -172,16 +330,115 @@ DrawRect(UIContext* ctx, f32 p0_x, f32 p0_y, f32 p1_x, f32 p1_y, f32 border, f32
|
||||
|
||||
AddUIIndices(ctx);
|
||||
}
|
||||
*/
|
||||
|
||||
void
|
||||
AddUIIndices(UIContext* ctx)
|
||||
AddUIIndices()
|
||||
{
|
||||
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;
|
||||
g_ui_ctx.buffer.idx[0] = 0;
|
||||
g_ui_ctx.buffer.idx[1] = 1;
|
||||
g_ui_ctx.buffer.idx[2] = 2;
|
||||
g_ui_ctx.buffer.idx[3] = 2;
|
||||
g_ui_ctx.buffer.idx[4] = 1;
|
||||
g_ui_ctx.buffer.idx[5] = 3;
|
||||
|
||||
ctx.buffer.count += 1;
|
||||
g_ui_ctx.buffer.count += 1;
|
||||
}
|
||||
|
||||
bool
|
||||
Nil(UIItem* item)
|
||||
{
|
||||
return item == null || item == g_UI_NIL;
|
||||
}
|
||||
|
||||
UIItem*
|
||||
Recurse(alias mode)(UIItem* item, UIItem* root)
|
||||
{
|
||||
UIItem* sibling, child, result = g_UI_NIL;
|
||||
|
||||
static if (mode == UIR.PostOrder) sibling = item.next; else sibling = item.prev;
|
||||
static if (mode == UIR.PostOrder) child = item.prev; else child = item.last;
|
||||
|
||||
if (!Nil(child))
|
||||
{
|
||||
result = sibling;
|
||||
}
|
||||
else for(UIItem* i = sibling; !Nil(i) && i != root; i = i.parent)
|
||||
{
|
||||
static if (mode == UIR.PostOrder) sibling = i.next; else sibling = i.prev;
|
||||
|
||||
if (!Nil(sibling))
|
||||
{
|
||||
result = sibling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Setter function in case I need to change to using a mutex
|
||||
pragma(inline) void
|
||||
SetProp(alias P, T)(T value)
|
||||
{
|
||||
static if (is(T: Vec4[4]))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.BackgroundColor) { g_ui_ctx.bg_cols = value; }
|
||||
else static if (P == CtxP.BorderColor) g_ui_ctx.border_cols = value;
|
||||
else static assert(false, "Unknown Property for type Vec4[4]");
|
||||
}
|
||||
else static if (is(T: SizeKind) && P == CtxP.SizeKind)
|
||||
{
|
||||
g_ui_ctx.size_kind = value;
|
||||
}
|
||||
else static if (is(T: UISize))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.AxisX) g_ui_ctx.size_axes[A2D.X] = value;
|
||||
else static if (P == CtxP.AxisY) g_ui_ctx.size_axes[A2D.Y] = value;
|
||||
else static assert(false, "Unknown Property for type UISize");
|
||||
}
|
||||
else static if (is(T: FontAtlas))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.FontAtlas) g_ui_ctx.atlas = value;
|
||||
else static assert(false, "Unknown Property for type FontAtlas");
|
||||
}
|
||||
else static if (is(T: Rect))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.Padding) g_ui_ctx.padding = value;
|
||||
}
|
||||
else static if (is(T: f32))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.TextScale) g_ui_ctx.text_scale = value;
|
||||
else static assert(false, "Unknown property for type f32");
|
||||
}
|
||||
else static if (is(T: u32))
|
||||
{
|
||||
static if (0) {}
|
||||
else static if (P == CtxP.TabWidth) g_ui_ctx.tab_width = value;
|
||||
else static assert(false, "Unknown property for type u32");
|
||||
}
|
||||
else static assert(false, "Unknown Type");
|
||||
}
|
||||
|
||||
unittest
|
||||
{
|
||||
{ // UI Key
|
||||
u8[] str = cast(u8[])r"Test String##123";
|
||||
UIKey key = MakeKey(str);
|
||||
|
||||
assert(key.text == cast(u8[])r"Test String");
|
||||
assert(key.hash == Hash(str));
|
||||
|
||||
u8[] str1 = cast(u8[])r"Test String###123123";
|
||||
key = MakeKey(str1);
|
||||
|
||||
assert(key.text == cast(u8[])r"Test String");
|
||||
assert(key.hash == Hash(r"123123"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user