start work on input handling
This commit is contained in:
parent
5ee1ae6d17
commit
55247980c1
159
src/editor/ui.d
159
src/editor/ui.d
@ -29,14 +29,23 @@ alias A2D = Axis2D;
|
|||||||
|
|
||||||
enum UIFlags
|
enum UIFlags
|
||||||
{
|
{
|
||||||
None,
|
None = 0x00,
|
||||||
DrawBackground,
|
DrawBackground = 0x01,
|
||||||
DragX,
|
Clickable = 0x02,
|
||||||
DragY,
|
Draggable = 0x04,
|
||||||
}
|
}
|
||||||
|
|
||||||
alias UIF = UIFlags;
|
alias UIF = UIFlags;
|
||||||
|
|
||||||
|
enum UISignal
|
||||||
|
{
|
||||||
|
None = 0x00,
|
||||||
|
Clicked = 0x01,
|
||||||
|
Dragged = 0x02,
|
||||||
|
}
|
||||||
|
|
||||||
|
alias UIS = UISignal;
|
||||||
|
|
||||||
enum SizeType
|
enum SizeType
|
||||||
{
|
{
|
||||||
Pixels,
|
Pixels,
|
||||||
@ -58,6 +67,7 @@ struct UIContext
|
|||||||
UIItemNode* top_parent;
|
UIItemNode* top_parent;
|
||||||
UIItemNode* prev_sibling;
|
UIItemNode* prev_sibling;
|
||||||
u32 panel_level;
|
u32 panel_level;
|
||||||
|
UIItem* drag_item;
|
||||||
|
|
||||||
UIItemStackList stack_free_list;
|
UIItemStackList stack_free_list;
|
||||||
|
|
||||||
@ -66,6 +76,7 @@ struct UIContext
|
|||||||
Vec4[4] border_color;
|
Vec4[4] border_color;
|
||||||
Vec4 text_color;
|
Vec4 text_color;
|
||||||
Axis2D layout_axis;
|
Axis2D layout_axis;
|
||||||
|
Vec2 adjustment;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UIItemStackList
|
struct UIItemStackList
|
||||||
@ -84,6 +95,7 @@ struct UIItem
|
|||||||
{
|
{
|
||||||
UIFlags flags;
|
UIFlags flags;
|
||||||
UIKey key;
|
UIKey key;
|
||||||
|
UISignal signal;
|
||||||
|
|
||||||
UIItem* next;
|
UIItem* next;
|
||||||
UIItem* prev;
|
UIItem* prev;
|
||||||
@ -96,6 +108,7 @@ struct UIItem
|
|||||||
// Build Parameters
|
// Build Parameters
|
||||||
Axis2D layout_axis;
|
Axis2D layout_axis;
|
||||||
UISize[2] size_info;
|
UISize[2] size_info;
|
||||||
|
Vec2 adjustment;
|
||||||
|
|
||||||
// Calculated Parameters
|
// Calculated Parameters
|
||||||
Vec2 size;
|
Vec2 size;
|
||||||
@ -164,6 +177,7 @@ InitUICtx(Renderer* rd, FontAtlas atlas)
|
|||||||
root: g_UI_NIL,
|
root: g_UI_NIL,
|
||||||
top_parent: g_UI_NIL_NODE,
|
top_parent: g_UI_NIL_NODE,
|
||||||
prev_sibling: g_UI_NIL_NODE,
|
prev_sibling: g_UI_NIL_NODE,
|
||||||
|
drag_item: g_UI_NIL,
|
||||||
buffer: {
|
buffer: {
|
||||||
mapped_vtx: m_vtx,
|
mapped_vtx: m_vtx,
|
||||||
mapped_idx: m_idx,
|
mapped_idx: m_idx,
|
||||||
@ -315,6 +329,12 @@ PushParent(UIItem* parent)
|
|||||||
ctx.panel_level += 1;
|
ctx.panel_level += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetAdjustment(Vec2 adj)
|
||||||
|
{
|
||||||
|
g_ui_ctx.adjustment = adj;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SetColor(Vec4 col)
|
SetColor(Vec4 col)
|
||||||
{
|
{
|
||||||
@ -383,7 +403,7 @@ CalcFixedSizes(UIItem* item)
|
|||||||
{
|
{
|
||||||
if (item.size_info[axis].type == ST.Pixels)
|
if (item.size_info[axis].type == ST.Pixels)
|
||||||
{
|
{
|
||||||
item.size.v[axis] = item.size_info[axis].value;
|
item.size.v[axis] = item.size_info[axis].value + item.adjustment.v[axis];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +421,7 @@ CalcPercentageSizes(UIItem* item)
|
|||||||
{
|
{
|
||||||
if (item.size_info[axis].type == ST.Percentage)
|
if (item.size_info[axis].type == ST.Percentage)
|
||||||
{
|
{
|
||||||
item.size.v[axis] = item.parent.size.v[axis] * item.size_info[axis].value;
|
item.size.v[axis] = (item.parent.size.v[axis]*item.size_info[axis].value) + item.adjustment.v[axis];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,29 +458,20 @@ DrawUI(UIContext* ctx, UIItem* item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UIItem*
|
void
|
||||||
BuildItem(string id, UISize size_x, UISize size_y, UIFlags properties)
|
BuildItem(UIItem* item, UISize size_x, UISize size_y, UIFlags properties)
|
||||||
{
|
|
||||||
u8[] u8_id = CastStr!(u8)(id);
|
|
||||||
return BuildItem(u8_id, size_x, size_y, properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
BuildItem(u8[] id, UISize size_x, UISize size_y, UIFlags properties)
|
|
||||||
{
|
{
|
||||||
UIContext* ctx = GetCtx();
|
UIContext* ctx = GetCtx();
|
||||||
UIKey key = MakeKey(id);
|
|
||||||
|
|
||||||
UIItem* item = Get(key);
|
|
||||||
item.first = item.last = item.next = item.prev = g_UI_NIL;
|
item.first = item.last = item.next = item.prev = g_UI_NIL;
|
||||||
|
|
||||||
item.key = key;
|
|
||||||
item.flags = properties;
|
item.flags = properties;
|
||||||
item.size_info[A2D.X] = size_x;
|
item.size_info[A2D.X] = size_x;
|
||||||
item.size_info[A2D.Y] = size_y;
|
item.size_info[A2D.Y] = size_y;
|
||||||
item.color = ctx.color;
|
item.color = ctx.color;
|
||||||
item.layout_axis = ctx.layout_axis;
|
item.layout_axis = ctx.layout_axis;
|
||||||
item.level = ctx.panel_level;
|
item.level = ctx.panel_level;
|
||||||
|
item.adjustment = ctx.adjustment;
|
||||||
|
|
||||||
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))
|
||||||
@ -468,7 +479,32 @@ BuildItem(u8[] id, UISize size_x, UISize size_y, UIFlags properties)
|
|||||||
DLLPush(item.parent, item, g_UI_NIL);
|
DLLPush(item.parent, item, g_UI_NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return item;
|
// Reset any once off values here
|
||||||
|
ctx.adjustment = Vec2(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Signal(UIItem* item)
|
||||||
|
{
|
||||||
|
UIContext* ctx = GetCtx();
|
||||||
|
|
||||||
|
item.signal = UIS.None;
|
||||||
|
|
||||||
|
for(DNode!(InputEvent)* n = ctx.inputs.list.first; !CheckNil(null, n); n = n.next)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (item.flags & UIF.Clickable && Clicked(item, n))
|
||||||
|
{
|
||||||
|
Logf("Clicked");
|
||||||
|
DLLRemove(&ctx.inputs.list, n, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.flags & UIF.Draggable && Clicked(item, n))
|
||||||
|
{
|
||||||
|
Logf("Dragged");
|
||||||
|
DLLRemove(&ctx.inputs.list, n, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UIContext*
|
UIContext*
|
||||||
@ -534,13 +570,23 @@ MakeKey(u8[] id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
UIItem*
|
UIItem*
|
||||||
Get(UIKey key)
|
Get(string id)
|
||||||
{
|
{
|
||||||
|
u8[] u8_id = CastStr!(u8)(id);
|
||||||
|
return Get(u8_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
UIItem*
|
||||||
|
Get(u8[] id)
|
||||||
|
{
|
||||||
|
UIKey key = MakeKey(id);
|
||||||
|
|
||||||
Result!(UIItem*) result = g_ui_ctx.items[key.hash];
|
Result!(UIItem*) result = g_ui_ctx.items[key.hash];
|
||||||
if (!result.ok)
|
if (!result.ok)
|
||||||
{
|
{
|
||||||
result.value = Alloc!(UIItem)(&g_ui_ctx.arena);
|
result.value = Alloc!(UIItem)(&g_ui_ctx.arena);
|
||||||
Push(&g_ui_ctx.items, key.hash, result.value);
|
Push(&g_ui_ctx.items, key.hash, result.value);
|
||||||
|
result.value.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.value;
|
return result.value;
|
||||||
@ -641,66 +687,27 @@ Nil(UIItem* item)
|
|||||||
return item == null || item == g_UI_NIL;
|
return item == null || item == g_UI_NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
bool
|
||||||
// Setter function in case I need to change to using a mutex
|
Clicked(UIItem* item, DNode!(InputEvent)* n)
|
||||||
pragma(inline) void
|
|
||||||
SetProp(alias P, T)(T value)
|
|
||||||
{
|
{
|
||||||
static if (is(T: Axis2D))
|
bool result = false;
|
||||||
|
InputEvent* ev = &n.value;
|
||||||
|
|
||||||
|
if (
|
||||||
|
ev.key == Input.LeftClick &&
|
||||||
|
ev.x >= item.rect.x0 &&
|
||||||
|
ev.x <= item.rect.x1 &&
|
||||||
|
ev.y >= item.rect.y0 &&
|
||||||
|
ev.y <= item.rect.y1 &&
|
||||||
|
ev.pressed
|
||||||
|
)
|
||||||
{
|
{
|
||||||
static if (P == CtxP.LayoutAxis) g_ui_ctx.layout_axis = value;
|
result = true;
|
||||||
else static assert(false, "Unknown property for type Axis2D");
|
|
||||||
}
|
}
|
||||||
else static if (is(T: Vec2))
|
|
||||||
{
|
return result;
|
||||||
static if (P == CtxP.Position) g_ui_ctx.position = value;
|
|
||||||
else static assert(false, "Unknown property for type Vec2");
|
|
||||||
}
|
|
||||||
else static if (is(T: Vec4))
|
|
||||||
{
|
|
||||||
static if (P == CtxP.BGColor) g_ui_ctx.bg_cols = [value, value, value, value];
|
|
||||||
else static if (P == CtxP.BorderColor) g_ui_ctx.border_cols = [value, value, value, value];
|
|
||||||
else static assert(false, "Unknown Property for type Vec4");
|
|
||||||
}
|
|
||||||
else static if (is(T: Vec4[4]))
|
|
||||||
{
|
|
||||||
static if (P == CtxP.BGColor) 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 (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 (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 (P == CtxP.Padding) g_ui_ctx.padding = value;
|
|
||||||
else static assert(false, "Unknown property for type Rect");
|
|
||||||
}
|
|
||||||
else static if (is(T: f32))
|
|
||||||
{
|
|
||||||
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 (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
|
unittest
|
||||||
{
|
{
|
||||||
|
|||||||
@ -8,7 +8,8 @@ Root()
|
|||||||
{
|
{
|
||||||
Vec2 d = RootSize();
|
Vec2 d = RootSize();
|
||||||
SetLayoutAxis(A2D.Y);
|
SetLayoutAxis(A2D.Y);
|
||||||
UIItem* root = BuildItem("##root_item", UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground);
|
UIItem* root = Get("##root_item");
|
||||||
|
BuildItem(root, UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground);
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
@ -16,32 +17,43 @@ Root()
|
|||||||
UIItem*
|
UIItem*
|
||||||
Panel(string id, f32 x_pct, f32 y_pct, Axis2D layout_axis, Vec4 color)
|
Panel(string id, f32 x_pct, f32 y_pct, Axis2D layout_axis, Vec4 color)
|
||||||
{
|
{
|
||||||
|
UIItem* item = Get(id);
|
||||||
|
UIItem* separator = g_UI_NIL;
|
||||||
|
|
||||||
UIItem* prev_panel = PeekSiblingPanel();
|
UIItem* prev_panel = PeekSiblingPanel();
|
||||||
UIItem* parent = PeekParent();
|
UIItem* parent = PeekParent();
|
||||||
|
|
||||||
|
Signal(item);
|
||||||
|
|
||||||
|
f32 adj_x = 0.0, adj_y = 0.0;
|
||||||
if (!Nil(prev_panel) && parent != prev_panel)
|
if (!Nil(prev_panel) && parent != prev_panel)
|
||||||
{
|
{
|
||||||
f32 sep_y = 1.0, sep_x = 1.0;
|
f32 sep_y = 1.0, sep_x = 1.0;
|
||||||
if (parent.layout_axis == A2D.X)
|
if (parent.layout_axis == A2D.X)
|
||||||
{
|
{
|
||||||
sep_x = 0.005;
|
sep_x = 5.0;
|
||||||
//x_pct -= 0.005;
|
adj_x = -5.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sep_y = 0.005;
|
sep_y = 5.0;
|
||||||
//y_pct -= 0.005;
|
adj_y = -5.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8[128] buf;
|
u8[128] buf = 0;
|
||||||
(cast(char[])buf).sformat("sep_%s", id);
|
(cast(char[])buf).sformat("sep_%s", id);
|
||||||
|
|
||||||
Separator(buf, sep_x, sep_y);
|
separator = Get(buf);
|
||||||
|
|
||||||
|
Separator(separator, sep_x, sep_y, parent.layout_axis);
|
||||||
|
|
||||||
|
Signal(separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetColor(color);
|
SetColor(color);
|
||||||
SetLayoutAxis(layout_axis);
|
SetLayoutAxis(layout_axis);
|
||||||
UIItem* item = BuildItem(id, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground);
|
|
||||||
|
BuildItem(item, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground);
|
||||||
|
|
||||||
UIItem* sibling = PrevSiblingPanel(item);
|
UIItem* sibling = PrevSiblingPanel(item);
|
||||||
|
|
||||||
@ -51,14 +63,15 @@ Panel(string id, f32 x_pct, f32 y_pct, Axis2D layout_axis, Vec4 color)
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIItem*
|
void
|
||||||
Separator(u8[] id, f32 x_pct, f32 y_pct)
|
Separator(UIItem* item, f32 x_size, f32 y_size, Axis2D axis)
|
||||||
{
|
{
|
||||||
SetColor(Vec4(0.0, 0.0, 0.0, 1.0));
|
SetColor(Vec4(0.0, 0.0, 0.0, 1.0));
|
||||||
|
|
||||||
UIItem* item = BuildItem(id, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground);
|
SizeType x_t = axis == A2D.X ? ST.Pixels : ST.Percentage;
|
||||||
|
SizeType y_t = axis == A2D.Y ? ST.Pixels : ST.Percentage;
|
||||||
|
|
||||||
return item;
|
BuildItem(item, UISize(x_t, x_size), UISize(y_t, y_size), UIF.DrawBackground|UIF.Draggable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user