delete unneccessary code
This commit is contained in:
parent
3ad296ba0f
commit
e3ee79c3e8
@ -3,9 +3,8 @@ import dlib;
|
|||||||
import vulkan;
|
import vulkan;
|
||||||
import std.format : sformat;
|
import std.format : sformat;
|
||||||
import buffer;
|
import buffer;
|
||||||
|
import ui : Nil;
|
||||||
import ui;
|
import ui;
|
||||||
import widgets : Nil;
|
|
||||||
import widgets;
|
|
||||||
import parsing;
|
import parsing;
|
||||||
|
|
||||||
import std.format;
|
import std.format;
|
||||||
@ -148,7 +147,17 @@ Cycle(EditorCtx* ctx, Inputs* inputs)
|
|||||||
|
|
||||||
for(auto p = ctx.base_panel; !Nil(p); p = Recurse(p))
|
for(auto p = ctx.base_panel; !Nil(p); p = Recurse(p))
|
||||||
{
|
{
|
||||||
Panel2(p);
|
Panel(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx.state == ES.CmdOpen)
|
||||||
|
{
|
||||||
|
if(ctx.cmd.commands.length == 0 && ctx.cmd.icount == 0)
|
||||||
|
{
|
||||||
|
GetCommands(&ctx.cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
CommandPalette(&ctx.cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
EndUI();
|
EndUI();
|
||||||
|
|||||||
1448
src/editor/ui.d
1448
src/editor/ui.d
File diff suppressed because it is too large
Load Diff
@ -1,986 +0,0 @@
|
|||||||
import dlib;
|
|
||||||
|
|
||||||
import vulkan;
|
|
||||||
import buffer;
|
|
||||||
import ui : Nil;
|
|
||||||
import ui;
|
|
||||||
import parsing;
|
|
||||||
import editor;
|
|
||||||
import std.format : sformat;
|
|
||||||
import std.math.rounding : ceil, floor;
|
|
||||||
import std.math.exponential : pow;
|
|
||||||
import core.stdc.math : fabsf;
|
|
||||||
import std.conv;
|
|
||||||
import core.stdc.stdio : sprintf;
|
|
||||||
|
|
||||||
const Vec4[4] DEFAULT_COL = Vec4(0.13, 0.13, 0.13, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] CMD_PALETTE_COL = Vec4(0.21, 0.21, 0.21, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] DEFAULT_BORDER_COL = Vec4(0.254, 0.254, 0.266, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] HL_BORDER_COL = Vec4(0.035, 0.549, 0.824, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] LC_COLOR = Vec4(0.12, 0.12, 0.12, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] LC_HL_COLOR = Vec4(0.012, 0.176, 0.29, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] CMD_PALETTE_INPUT_HL = Vec4(0.24, 0.45, 0.81, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] CMD_INPUT_BORDER_COL = Vec4(0.003, 0.48, 0.68, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] CMD_INPUT_BORDER_HL = Vec4(0.05, 0.56, 0.76, 1.0);
|
|
||||||
|
|
||||||
const Vec4[4] CMD_PALETTE_INPUT_COL = [
|
|
||||||
Vec4(0.14, 0.14, 0.14, 1.0),
|
|
||||||
Vec4(0.14, 0.14, 0.14, 1.0),
|
|
||||||
Vec4(0.17, 0.17, 0.17, 1.0),
|
|
||||||
Vec4(0.17, 0.17, 0.17, 1.0),
|
|
||||||
];
|
|
||||||
|
|
||||||
// TODO: add setting
|
|
||||||
const f32 TEXT_SIZE = 16.0;
|
|
||||||
|
|
||||||
const UIPanel g_ui_nil_panel;
|
|
||||||
UIPanel* g_UI_NIL_PANEL;
|
|
||||||
|
|
||||||
UIPanel g_root_panel;
|
|
||||||
|
|
||||||
WidgetCtx g_widget_ctx;
|
|
||||||
|
|
||||||
struct WidgetCtx
|
|
||||||
{
|
|
||||||
UIPanel* parent;
|
|
||||||
UIPanel* focused_panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UIPanel
|
|
||||||
{
|
|
||||||
AnimState anim;
|
|
||||||
u8[] id;
|
|
||||||
Editor* ed;
|
|
||||||
|
|
||||||
UIPanel* parent;
|
|
||||||
UIPanel* next;
|
|
||||||
UIPanel* prev;
|
|
||||||
UIPanel* first;
|
|
||||||
UIPanel* last;
|
|
||||||
|
|
||||||
UIPanel* list_next;
|
|
||||||
|
|
||||||
Axis2D axis;
|
|
||||||
SizeType size_type;
|
|
||||||
f32 pct;
|
|
||||||
Vec4 color;
|
|
||||||
|
|
||||||
i64 prev_offset;
|
|
||||||
i64 start_row;
|
|
||||||
i64 end_row;
|
|
||||||
|
|
||||||
Rect rect;
|
|
||||||
Vec2 size;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AnimState
|
|
||||||
{
|
|
||||||
f32 start_value;
|
|
||||||
f32 end_value;
|
|
||||||
f32 start_time;
|
|
||||||
f32 remaining_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct TextPart
|
|
||||||
{
|
|
||||||
UIItem* item;
|
|
||||||
TextPart* next;
|
|
||||||
u32 count;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
Root()
|
|
||||||
{
|
|
||||||
Vec2 d = RootSize();
|
|
||||||
|
|
||||||
Push!("color")(DEFAULT_COL);
|
|
||||||
Push!("layout_axis")(A2D.Y);
|
|
||||||
|
|
||||||
UIItem* root = Get("##root_item");
|
|
||||||
BuildItem(root, UISize(ST.Pixels, d.x), UISize(ST.Pixels, d.y), UIF.DrawBackground);
|
|
||||||
|
|
||||||
g_root_panel.pct = 1.0;
|
|
||||||
g_root_panel.axis = A2D.Y;
|
|
||||||
g_root_panel.color = Vec4(Vec3(0.0), 1.0);
|
|
||||||
g_root_panel.list_next = g_root_panel.parent = g_root_panel.next = g_root_panel.prev = g_root_panel.first = g_root_panel.last = g_UI_NIL_PANEL;
|
|
||||||
|
|
||||||
g_widget_ctx.parent = &g_root_panel;
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
BeginUI(EditorCtx* edctx, Inputs* inputs)
|
|
||||||
{
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
|
|
||||||
Reset(&ctx.temp_arena);
|
|
||||||
|
|
||||||
ctx.f_idx = ctx.frame%FRAME_OVERLAP;
|
|
||||||
ctx.inputs = inputs;
|
|
||||||
|
|
||||||
PrepRendering(ctx);
|
|
||||||
|
|
||||||
SetPanelSizes(edctx.base_panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EndUI()
|
|
||||||
{
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
|
|
||||||
with(ctx)
|
|
||||||
{
|
|
||||||
BindBuffers(&rd, &buffers[f_idx].m_idx, &buffers[f_idx].m_vtx);
|
|
||||||
DrawIndexed(&rd, 6, buffers[f_idx].count, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompleteRendering(ctx);
|
|
||||||
|
|
||||||
ctx.frame += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetPanelSizes(UIPanel* panel)
|
|
||||||
{
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
|
|
||||||
panel.size.x = ctx.res.x;
|
|
||||||
panel.size.y = ctx.res.y;
|
|
||||||
panel.rect.vec0 = 0.0;
|
|
||||||
panel.rect.vec1 = 0.0;
|
|
||||||
|
|
||||||
static foreach(axis; A2D.min .. A2D.max)
|
|
||||||
{
|
|
||||||
for(UIPanel* p = panel; !Nil(p); p = Recurse(p))
|
|
||||||
{
|
|
||||||
f32 pos = p.rect.vec0.v[axis];
|
|
||||||
for(UIPanel* c = p.first; !Nil(c); c = c.next)
|
|
||||||
{
|
|
||||||
c.size.v[axis] = p.axis == axis ? c.pct * p.size.v[axis] : p.size.v[axis];
|
|
||||||
c.rect.vec0.v[axis] = pos;
|
|
||||||
c.rect.vec1.v[axis] = pos + c.size.v[axis];
|
|
||||||
|
|
||||||
if(axis == p.axis)
|
|
||||||
{
|
|
||||||
pos += c.size.v[axis];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline) void
|
|
||||||
DrawChar(FontAtlas* atlas, u8 ch, f32* x_pos, f32 y, Vec4 col = Vec4(1.0))
|
|
||||||
{
|
|
||||||
if(ch < atlas.glyphs.length)
|
|
||||||
{
|
|
||||||
Glyph* g = atlas.glyphs.ptr + ch;
|
|
||||||
DrawGlyph(g, 1.0, x_pos, y, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Panel2(UIPanel* panel)
|
|
||||||
{
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
UIItem* item = Get(panel.id);
|
|
||||||
Editor* ed = panel.ed;
|
|
||||||
bool focused = GetFocusedPanel() == panel;
|
|
||||||
|
|
||||||
UIPanel* parent = panel.parent;
|
|
||||||
UIPanel* prev = panel.prev;
|
|
||||||
|
|
||||||
Axis2D pax = parent.axis;
|
|
||||||
|
|
||||||
Vec2 adj = Vec2(
|
|
||||||
parent.axis == A2D.X ? 10 : 0,
|
|
||||||
parent.axis == A2D.Y ? 10 : 0
|
|
||||||
);
|
|
||||||
|
|
||||||
Vec2 p0 = panel.rect.vec0-adj;
|
|
||||||
Vec2 p1 = panel.rect.vec1+adj;
|
|
||||||
|
|
||||||
if(!Nil(prev)) with(panel)
|
|
||||||
{
|
|
||||||
if(Dragged(item, p0, p1) && item.dragged.v[pax] != 0.0)
|
|
||||||
{
|
|
||||||
f32 mov_pct = Remap(item.dragged.v[pax], 0.0, size.v[pax], 0.0, 1.0);
|
|
||||||
if(CheckPanelBounds(pct + mov_pct) && CheckPanelBounds(panel.prev.pct - mov_pct))
|
|
||||||
{
|
|
||||||
pct += mov_pct;
|
|
||||||
panel.prev.pct -= mov_pct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(panel.ed != null)
|
|
||||||
{
|
|
||||||
if(Clicked(item, p0, p1))
|
|
||||||
{
|
|
||||||
SetFocusedPanel(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawBorderedRect(panel.rect.vec0, panel.size, 2.0, 2.0, 0.1, DEFAULT_COL, focused ? HL_BORDER_COL : DEFAULT_BORDER_COL);
|
|
||||||
|
|
||||||
i64 rows = cast(i64)ceil(panel.size.y/TEXT_SIZE);
|
|
||||||
|
|
||||||
GetLines(&ed.buf, &ed.linebufs, rows);
|
|
||||||
|
|
||||||
char[64] ch_buf = '\0';
|
|
||||||
char[] fmt = ch_buf.sformat("%%0%ss", u64(ed.linebufs.end.toChars().length));
|
|
||||||
|
|
||||||
u8[] end_line_text = ScratchAlloc!(u8)(ed.linebufs.end.toChars().length, '0');
|
|
||||||
|
|
||||||
f32 lcw = CalcTextWidth(end_line_text);
|
|
||||||
f32 padding = 4.0;
|
|
||||||
|
|
||||||
DrawRect(panel.rect.vec0, panel.rect.vec1+Vec2(lcw+padding*2, panel.size.y), 0.0, 0.0, focused ? LC_HL_COLOR : LC_COLOR);
|
|
||||||
|
|
||||||
f32 x = panel.rect.x0;
|
|
||||||
f32 y = panel.rect.y0 + TEXT_SIZE;
|
|
||||||
|
|
||||||
FontAtlas* atlas = &ctx.atlas_buf.atlas;
|
|
||||||
bool edit = EditModeActive();
|
|
||||||
U64Vec2 pos = VecPos(&ed.buf);
|
|
||||||
u64 i;
|
|
||||||
for(auto buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1)
|
|
||||||
{
|
|
||||||
f32 x_pos = x + padding;
|
|
||||||
|
|
||||||
DrawLineCount(atlas, fmt, &x_pos, y, ed.linebufs.start+i);
|
|
||||||
|
|
||||||
x_pos += padding;
|
|
||||||
|
|
||||||
u64 ch_offset;
|
|
||||||
auto parts = MakeMultiline(buf.text, panel.size.x-lcw, buf.style);
|
|
||||||
for(auto n = parts; n != null; n = n.next)
|
|
||||||
{
|
|
||||||
auto l = &n.value;
|
|
||||||
|
|
||||||
if(pos.y == i)
|
|
||||||
{
|
|
||||||
DrawCursor(atlas, l.text, pos.x, x+lcw+padding*2.0, y, ch_offset, edit);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach(j; 0 .. l.text.length)
|
|
||||||
{
|
|
||||||
bool hl = pos.y == i && !edit && j == pos.x-ch_offset;
|
|
||||||
DrawChar(atlas, l.text[j], &x_pos, y, hl ? Vec4(Vec3(0.0), 1.0) : SYNTAX_COLORS[l.style[j]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += TEXT_SIZE;
|
|
||||||
x_pos = x + lcw + padding*2.0;
|
|
||||||
ch_offset += l.text.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline) void
|
|
||||||
DrawCursor(FontAtlas* atlas, u8[] text, u64 ch_x, f32 x, f32 y, u64 offset, bool edit)
|
|
||||||
{
|
|
||||||
Glyph* g = GetGlyph(' ');
|
|
||||||
foreach(j; 0 .. text.length)
|
|
||||||
{
|
|
||||||
bool hl = j == ch_x-offset;
|
|
||||||
if(hl)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g = j == text.length-1 ? GetGlyph(' ') : GetGlyph(text[j]);
|
|
||||||
x += GlyphWidth(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawRect(x, y, atlas, cast(u8)g.ch, Vec4(1.0), edit);
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma(inline) void
|
|
||||||
DrawLineCount(FontAtlas* atlas, char[] fmt, f32* x_pos, f32 y, u64 line)
|
|
||||||
{
|
|
||||||
char[32] line_buf = '\0';
|
|
||||||
char[] line_str = sformat(line_buf, fmt, line);
|
|
||||||
|
|
||||||
foreach(j; 0 .. line_str.length)
|
|
||||||
{
|
|
||||||
DrawChar(atlas, line_str[j], x_pos, y, Vec4(1.0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f32
|
|
||||||
LineCounter2(UIPanel* panel, i64 start_row, i64 end_row)
|
|
||||||
{
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
|
|
||||||
f32 lc_width = 0.0;
|
|
||||||
f32 padding = 4.0;
|
|
||||||
|
|
||||||
UIItem* item = Get(ScratchName(panel.id, "linec"));
|
|
||||||
|
|
||||||
u8[] max_line_text;
|
|
||||||
u8[][] line_counts = ScratchAlloc!(u8[])(end_row-start_row);
|
|
||||||
|
|
||||||
u64 width = u64(end_row.toChars().length);
|
|
||||||
|
|
||||||
char[32] buf = '\0';
|
|
||||||
char[] fmt = buf.sformat("%%0%sllu", width);
|
|
||||||
|
|
||||||
if(line_counts.length > 0)
|
|
||||||
{
|
|
||||||
for(u64 i = 0; start_row+i < end_row; i += 1)
|
|
||||||
{
|
|
||||||
line_counts[i] = ScratchAlloc!(u8)(width);
|
|
||||||
sprintf(cast(char*)line_counts[i].ptr, fmt.ptr, start_row+i);
|
|
||||||
}
|
|
||||||
|
|
||||||
max_line_text = ScratchAlloc!(u8)(width, '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
lc_width = CalcTextWidth(max_line_text) + padding*2.0;
|
|
||||||
|
|
||||||
f32 x = panel.rect.x0 + padding;
|
|
||||||
f32 y = panel.rect.y0 + TEXT_SIZE;
|
|
||||||
|
|
||||||
foreach(i; 0 .. line_counts.length)
|
|
||||||
{
|
|
||||||
f32 x_pos = x;
|
|
||||||
|
|
||||||
foreach(j; 0 .. line_counts[i].length)
|
|
||||||
{
|
|
||||||
DrawChar(&ctx.atlas_buf.atlas, line_counts[i][j], &x_pos, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
y += TEXT_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lc_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
Panel(UIPanel* panel, UIFlags flags = UIF.None)
|
|
||||||
{
|
|
||||||
Push!("color")(DEFAULT_COL);
|
|
||||||
Push!("layout_axis")(panel.axis);
|
|
||||||
|
|
||||||
UIItem* item = Get(panel.id);
|
|
||||||
UIItem* separator = g_UI_NIL;
|
|
||||||
|
|
||||||
UIPanel* parent_pn = panel.parent;
|
|
||||||
|
|
||||||
UIItem* next = !Nil(panel.next) ? Get(panel.next.id) : g_UI_NIL;
|
|
||||||
UIItem* prev = !Nil(panel.prev) ? Get(panel.prev.id) : g_UI_NIL;
|
|
||||||
UIItem* parent = !Nil(parent_pn) ? Get(parent_pn.id) : PeekParent();
|
|
||||||
|
|
||||||
f32 x_pct = 1.0, y_pct = 1.0;
|
|
||||||
if(!Nil(parent_pn))
|
|
||||||
{
|
|
||||||
x_pct = parent_pn.axis == A2D.X ? panel.pct : 1.0;
|
|
||||||
y_pct = parent_pn.axis == A2D.Y ? panel.pct : 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item.signal & UIS.Clicked)
|
|
||||||
{
|
|
||||||
SetFocusedPanel(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 adj_x = 0.0, adj_y = 0.0;
|
|
||||||
if(!Nil(prev) || !Nil(next))
|
|
||||||
{
|
|
||||||
A2D p_axis = parent_pn.axis;
|
|
||||||
UIS prev_signal = p_axis == A2D.X ? UIS.BorderX0 : UIS.BorderY0;
|
|
||||||
UIS next_signal = p_axis == A2D.X ? UIS.BorderX1 : UIS.BorderY1;
|
|
||||||
|
|
||||||
if(p_axis == A2D.X)
|
|
||||||
{
|
|
||||||
flags |= !Nil(prev) ? UIF.BorderX0 : UIF.None;
|
|
||||||
flags |= !Nil(next) ? UIF.BorderX1 : UIF.None;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flags |= !Nil(prev) ? UIF.BorderY0 : UIF.None;
|
|
||||||
flags |= !Nil(next) ? UIF.BorderY1 : UIF.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
Signal(item);
|
|
||||||
|
|
||||||
f32 p_start = parent.rect.vec0.v[p_axis];
|
|
||||||
f32 p_end = parent.rect.vec1.v[p_axis];
|
|
||||||
f32 pos = item.dragged.v[p_axis];
|
|
||||||
if(!Nil(prev) && item.signal & UIS.DraggedBorder && item.signal & prev_signal && pos != 0.0)
|
|
||||||
{
|
|
||||||
f32 pct = Remap(pos, 0.0, p_start-p_end, 0.0, 1.0);
|
|
||||||
if(CheckPanelBounds(panel.pct - pct) && CheckPanelBounds(panel.prev.pct + pct))
|
|
||||||
{
|
|
||||||
panel.pct -= pct;
|
|
||||||
panel.prev.pct += pct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(!Nil(next) && item.signal & UIS.DraggedBorder && item.signal & next_signal && pos != 0.0)
|
|
||||||
{
|
|
||||||
f32 pct = Remap(pos, 0.0, p_start-p_end, 0.0, 1.0);
|
|
||||||
if(CheckPanelBounds(panel.next.pct - pct) && CheckPanelBounds(panel.pct + pct))
|
|
||||||
{
|
|
||||||
panel.next.pct -= pct;
|
|
||||||
panel.pct += pct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildItem(item, UISize(ST.Percentage, x_pct), UISize(ST.Percentage, y_pct), UIF.DrawBackground|UIF.DragBorder|flags);
|
|
||||||
|
|
||||||
PushParent(item);
|
|
||||||
|
|
||||||
Pop!("color", "layout_axis");
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
LineCounter(u8[] parent_id, FlatBuffer* buf, f32 offset, i64 start_row, i64 end_row, bool focused)
|
|
||||||
{
|
|
||||||
f32 padding = 4.0;
|
|
||||||
|
|
||||||
Push!("padding")(Vec2(padding, 0.0));
|
|
||||||
Push!("color")(focused ? LC_HL_COLOR : LC_COLOR);
|
|
||||||
|
|
||||||
u8[] id = ScratchName(parent_id, "linec");
|
|
||||||
u8[] max_row_text;
|
|
||||||
u8[][] line_counts = ScratchAlloc!(u8[])(end_row-start_row);
|
|
||||||
|
|
||||||
u64 width = u64(end_row.toChars().length);
|
|
||||||
|
|
||||||
if(line_counts.length > 0)
|
|
||||||
{
|
|
||||||
for(u64 i = 0; start_row+i < end_row; i += 1)
|
|
||||||
{
|
|
||||||
line_counts[i] = ScratchName(width, parent_id, start_row+i);
|
|
||||||
}
|
|
||||||
|
|
||||||
max_row_text = ScratchAlloc!(u8)(width);
|
|
||||||
max_row_text[] = cast(u8)'0';
|
|
||||||
}
|
|
||||||
|
|
||||||
UISize s_x = UISize(ST.Pixels, CalcTextWidth(max_row_text) + (padding*2.0));
|
|
||||||
UISize s_y = UISize(ST.Percentage, 1.0);
|
|
||||||
|
|
||||||
UIItem* item = Container(ScratchName(parent_id, "linec"), s_x, s_y, A2D.Y, UIF.DrawBackground);
|
|
||||||
{
|
|
||||||
UIItem* inner = Container(ScratchName(parent_id, "lcinner"), s_x, s_y, A2D.Y, UIF.None);
|
|
||||||
{
|
|
||||||
for(u64 i = 0; i < line_counts.length; i += 1)
|
|
||||||
{
|
|
||||||
if(i == 0)
|
|
||||||
{
|
|
||||||
Push!("offset")(Vec2(0.0, offset));
|
|
||||||
UIItem* line = Text(line_counts[i]);
|
|
||||||
Pop!("offset");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
UIItem* line = Text(line_counts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EndContainer();
|
|
||||||
}
|
|
||||||
EndContainer();
|
|
||||||
|
|
||||||
Pop!("padding", "color");
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
Container(u8[] text, UISize size_x, UISize size_y, Axis2D axis, UIF flags = UIF.None)
|
|
||||||
{
|
|
||||||
Push!("layout_axis")(axis);
|
|
||||||
|
|
||||||
UIItem* item = Get(text);
|
|
||||||
BuildItem(item, size_x, size_y, flags);
|
|
||||||
PushParent(item);
|
|
||||||
|
|
||||||
Pop!("layout_axis");
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EndContainer()
|
|
||||||
{
|
|
||||||
PopParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
Text(u8[] text)
|
|
||||||
{
|
|
||||||
UIItem* item = Get(text);
|
|
||||||
f32 width = CalcTextWidth(item.key.text);
|
|
||||||
BuildItem(item, UISize(ST.Pixels, width), UISize(ST.Pixels, 16.0), UIF.DrawText);
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetPanelScroll(UIPanel* panel, i64 rows, f32 text_size)
|
|
||||||
{
|
|
||||||
i64 low = panel.prev_offset < panel.ed.buf.offset ? panel.prev_offset : panel.ed.buf.offset;
|
|
||||||
i64 high = panel.prev_offset < panel.ed.buf.offset ? panel.ed.buf.offset + rows : panel.prev_offset + rows;
|
|
||||||
|
|
||||||
panel.start_row = low;
|
|
||||||
panel.end_row = high;
|
|
||||||
|
|
||||||
f32 start = panel.anim.start_value;
|
|
||||||
f32 end = panel.anim.end_value;
|
|
||||||
|
|
||||||
f32 offset = (panel.prev_offset-panel.ed.buf.offset) * text_size;
|
|
||||||
if(offset > 0.0)
|
|
||||||
{
|
|
||||||
end = -offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
start = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
with(panel.anim)
|
|
||||||
{
|
|
||||||
start_value = start;
|
|
||||||
end_value = end;
|
|
||||||
|
|
||||||
start_time = 0.1;
|
|
||||||
remaining_time = remaining_time > 0.05 ? 0.04 : 0.1;
|
|
||||||
|
|
||||||
panel.prev_offset = panel.ed.buf.offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f32
|
|
||||||
EaseOutExp(f32 v)
|
|
||||||
{
|
|
||||||
return fabsf(1.0 - v) <= 0.00009 ? 1.0 : 1.0 - pow(2, -10 * v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EditorView(UIPanel* panel)
|
|
||||||
{
|
|
||||||
bool focused = panel == GetFocusedPanel();
|
|
||||||
|
|
||||||
UICtx* ctx = GetCtx();
|
|
||||||
Editor* ed = panel.ed;
|
|
||||||
|
|
||||||
Push!("border_thickness")(2.0);
|
|
||||||
Push!("border_color")(focused ? HL_BORDER_COL : DEFAULT_BORDER_COL);
|
|
||||||
|
|
||||||
UIItem* item = Panel(panel, UIF.Clickable|UIF.DeferredBorder);
|
|
||||||
{
|
|
||||||
Pop!("border_thickness", "border_color");
|
|
||||||
|
|
||||||
Container(ScratchName(panel.id, "cntr"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.X);
|
|
||||||
{
|
|
||||||
f32 text_size = 16.0;
|
|
||||||
f32 height = 0.0;
|
|
||||||
|
|
||||||
i64 rows = cast(i64)ceil(item.size.y/text_size);
|
|
||||||
if(ed.buf.rows != rows)
|
|
||||||
{
|
|
||||||
ed.buf.rows = rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(panel.prev_offset != ed.buf.offset)
|
|
||||||
{
|
|
||||||
SetPanelScroll(panel, rows, text_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 offset = 0.0;
|
|
||||||
i64 line_offset = ed.buf.offset;
|
|
||||||
i64 line_rows = rows;
|
|
||||||
if(panel.anim.remaining_time > 0.0) with(panel.anim)
|
|
||||||
{
|
|
||||||
remaining_time -= g_delta;
|
|
||||||
if(remaining_time < 0.0)
|
|
||||||
{
|
|
||||||
remaining_time = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset = Remap(remaining_time, 0.0, start_time, 0.0, 1.0);
|
|
||||||
offset = Remap(EaseOutExp(offset), 0.0, 1.0, start_value, end_value);
|
|
||||||
|
|
||||||
line_offset = panel.start_row;
|
|
||||||
line_rows = panel.end_row-panel.start_row;
|
|
||||||
GetLines(&ed.buf, &ed.linebufs, panel.start_row, panel.end_row-panel.start_row);
|
|
||||||
|
|
||||||
if(remaining_time == 0.0)
|
|
||||||
{
|
|
||||||
start_value = end_value = start_time = 0.0;
|
|
||||||
panel.start_row = panel.end_row = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GetLines(&ed.buf, &ed.linebufs, rows);
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem* lc = LineCounter(panel.id, &panel.ed.buf, offset, line_offset, line_offset+line_rows, focused);
|
|
||||||
|
|
||||||
Container(ScratchName(panel.id, "lines"), UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0), A2D.Y);
|
|
||||||
{
|
|
||||||
I64Vec2 sel = ed.buf.sel;
|
|
||||||
if(sel.x > sel.y)
|
|
||||||
{
|
|
||||||
i64 t = sel.y;
|
|
||||||
sel.y = sel.x;
|
|
||||||
sel.x = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
U64Vec2 pos = VecPos(&ed.buf);
|
|
||||||
SelectMode sm = ed.buf.sel_mode;
|
|
||||||
u64 i = 0;
|
|
||||||
for(LineBuffer* buf = ed.linebufs.first; buf != null; buf = buf.next, i += 1)
|
|
||||||
{
|
|
||||||
if(buf == ed.linebufs.first)
|
|
||||||
{
|
|
||||||
Push!("offset")(Vec2(0.0, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buf.text.length > 0)
|
|
||||||
{
|
|
||||||
i64 line_no = i+line_offset;
|
|
||||||
|
|
||||||
if(sm == SM.Line && line_no >= sel.x && line_no <= sel.y)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TextPart* tp = WrappedTextLine(buf.text, panel.id, text_size, line_no, buf.style, &pos, focused);
|
|
||||||
height += (text_size * tp.count);
|
|
||||||
if(TextClicked(tp))
|
|
||||||
{
|
|
||||||
SetFocusedPanel(panel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buf == ed.linebufs.first)
|
|
||||||
{
|
|
||||||
Pop!("offset");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EndContainer();
|
|
||||||
}
|
|
||||||
EndContainer();
|
|
||||||
}
|
|
||||||
EndPanel();
|
|
||||||
|
|
||||||
if(item.signal & UIS.Clicked)
|
|
||||||
{
|
|
||||||
SetFocusedPanel(panel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TextClicked(TextPart* text_part)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
alias result res;
|
|
||||||
|
|
||||||
for(TextPart* tp = text_part; !Nil(tp.item); tp = tp.next)
|
|
||||||
{
|
|
||||||
if(tp.item.signal & UIS.Clicked)
|
|
||||||
{
|
|
||||||
res = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
TextPart*
|
|
||||||
WrappedTextLine(u8[] text, u8[] parent_id, f32 text_size, u64 line_no, TS[] style = [], U64Vec2* hl_pos, bool focused)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Push!("color")(Vec4(1.0));
|
|
||||||
Push!("text_size")(text_size);
|
|
||||||
|
|
||||||
UIItem* parent = PeekParent();
|
|
||||||
TextPart* part = ScratchAlloc!(TextPart)();
|
|
||||||
part.item = g_UI_NIL;
|
|
||||||
|
|
||||||
i64 hl = -1;
|
|
||||||
if(hl_pos.y == line_no)
|
|
||||||
{
|
|
||||||
hl = hl_pos.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
f32 parent_width = parent.size.x - (parent.border_thickness * 2);
|
|
||||||
Logf("w %f", parent_width);
|
|
||||||
|
|
||||||
u64 chars;
|
|
||||||
TextPart* tp = part;
|
|
||||||
Node!(TextBuffer)* lines = MakeMultiline(text, parent_width, parent_id, line_no, style);
|
|
||||||
for(Node!(TextBuffer)* line = lines; line != null; line = line.next, tp = tp.next)
|
|
||||||
{
|
|
||||||
part.count += 1;
|
|
||||||
|
|
||||||
tp.item = Get(line.value.text);
|
|
||||||
tp.next = ScratchAlloc!(TextPart)();
|
|
||||||
tp.next.item = g_UI_NIL;
|
|
||||||
|
|
||||||
tp.item.token_styles = line.value.style;
|
|
||||||
|
|
||||||
if(focused && hl >= 0)
|
|
||||||
{
|
|
||||||
if(hl <= tp.item.key.text.length)
|
|
||||||
{
|
|
||||||
Push!("highlighted_char")(hl);
|
|
||||||
hl = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hl -= tp.item.key.text.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Signal(tp.item);
|
|
||||||
|
|
||||||
if(tp.item.signal & UIS.Clicked)
|
|
||||||
{
|
|
||||||
ClickedCharIndex(tp.item);
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildItem(tp.item, UISize(ST.Percentage, 1.0), UISize(ST.Pixels, text_size), UIF.DrawText|UIF.Clickable|UIF.Draggable);
|
|
||||||
|
|
||||||
Push!("highlighted_char")(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pop!("color");
|
|
||||||
|
|
||||||
return part;
|
|
||||||
*/
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
TextInput(u8[] text, u8[] hash, f32 x, f32 y, f32 w_pct, f32 h, f32 text_size, Vec4[4] bg_cols, Vec4[4] border_col)
|
|
||||||
{
|
|
||||||
UIItem* input = Get(ScratchName(text, hash));
|
|
||||||
|
|
||||||
Push!("padding")(Vec2(6.0, (h-(text_size))*0.5)-2.0);
|
|
||||||
|
|
||||||
Push!("offset")(Vec2(x, y));
|
|
||||||
Push!("border_color")(border_col);
|
|
||||||
Push!("color")(bg_cols);
|
|
||||||
|
|
||||||
Container(ScratchName(hash, "_cntr"), UISize(ST.Percentage, w_pct), UISize(ST.Pixels, h), A2D.Y, UIF.DrawBackground|UIF.DrawBorder);
|
|
||||||
|
|
||||||
Pop!("color", "offset", "border_color");
|
|
||||||
|
|
||||||
Push!("color")(Vec4(1.0));
|
|
||||||
Push!("text_size")(text_size);
|
|
||||||
|
|
||||||
BuildItem(input, UISize(ST.Percentage, 1.0), UISize(ST.Pixels, text_size), UIF.DrawText);
|
|
||||||
|
|
||||||
EndContainer();
|
|
||||||
|
|
||||||
Pop!("color", "padding");
|
|
||||||
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CommandPalette(CmdPalette* cmd)
|
|
||||||
{
|
|
||||||
u8[] text = cmd.buffer[0 .. cmd.icount];
|
|
||||||
u8[][] options = cmd.opt_strs;
|
|
||||||
|
|
||||||
Vec2 size = RootSize();
|
|
||||||
|
|
||||||
f32 x = size.x*0.15;
|
|
||||||
f32 y = size.y*0.1;
|
|
||||||
f32 w = size.x*0.7;
|
|
||||||
f32 h = size.y*0.8;
|
|
||||||
|
|
||||||
Push!("color")(CMD_PALETTE_COL);
|
|
||||||
|
|
||||||
UIItem* window = Window(CastStr!(u8)("##cmd_palette"), x, y, w, 40.0*(options.length+1));
|
|
||||||
|
|
||||||
Push!("corner_radius")(2.0);
|
|
||||||
Push!("edge_softness")(0.1);
|
|
||||||
Push!("border_thickness")(2.0);
|
|
||||||
|
|
||||||
UIItem* text_box = TextInput(text, CastStr!(u8)("###cmd_palette_input"), 0.0, 0.0, 1.0, 40.0, 16.0, CMD_PALETTE_INPUT_COL, CMD_INPUT_BORDER_COL);
|
|
||||||
|
|
||||||
for(u64 i = 0; i < options.length; i += 1)
|
|
||||||
{
|
|
||||||
TextInput(
|
|
||||||
options[i],
|
|
||||||
ScratchName("###cmd%04s", 10, i),
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
1.0,
|
|
||||||
40.0,
|
|
||||||
16.0,
|
|
||||||
i == cmd.selected ? CMD_PALETTE_INPUT_HL : CMD_PALETTE_INPUT_COL,
|
|
||||||
i == cmd.selected ? CMD_INPUT_BORDER_HL : CMD_INPUT_BORDER_COL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndWindow();
|
|
||||||
|
|
||||||
Pop!("border_thickness", "corner_radius", "edge_softness", "color");
|
|
||||||
}
|
|
||||||
|
|
||||||
UIItem*
|
|
||||||
Window(u8[] id, f32 x, f32 y, f32 w, f32 h)
|
|
||||||
{
|
|
||||||
UIItem* item = Get(id);
|
|
||||||
|
|
||||||
Push!("offset")(Vec2(x, y));
|
|
||||||
|
|
||||||
BuildItem(item, UISize(ST.Pixels, w), UISize(ST.Pixels, h), UIF.Window|UIF.DrawBackground|UIF.DrawBorder);
|
|
||||||
|
|
||||||
Pop!("offset");
|
|
||||||
|
|
||||||
PushParent(item);
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EndWindow()
|
|
||||||
{
|
|
||||||
PopParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
EndPanel()
|
|
||||||
{
|
|
||||||
PopParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DrawPanels(UIPanel* panel)
|
|
||||||
{
|
|
||||||
if(!Nil(panel))
|
|
||||||
{
|
|
||||||
debug
|
|
||||||
{
|
|
||||||
import core.stdc.math : fabsf;
|
|
||||||
|
|
||||||
if(!Nil(panel.first))
|
|
||||||
{
|
|
||||||
f32 total = 1.0;
|
|
||||||
for(UIPanel* child = panel.first; !Nil(child); child = child.next)
|
|
||||||
{
|
|
||||||
total -= child.pct;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(total > 0.00009)
|
|
||||||
{
|
|
||||||
Logf("%s failed with %f", cast(char[])panel.id, total);
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(panel.ed)
|
|
||||||
{
|
|
||||||
EditorView(panel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Panel(panel);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawPanels(panel.first);
|
|
||||||
|
|
||||||
if(panel.ed == null)
|
|
||||||
{
|
|
||||||
EndPanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawPanels(panel.next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UIPanel*
|
|
||||||
Recurse(UIPanel* panel)
|
|
||||||
{
|
|
||||||
UIPanel* result = g_UI_NIL_PANEL;
|
|
||||||
if(!Nil(panel.first))
|
|
||||||
{
|
|
||||||
result = panel.first;
|
|
||||||
}
|
|
||||||
else if(!Nil(panel.next))
|
|
||||||
{
|
|
||||||
result = panel.next;
|
|
||||||
}
|
|
||||||
else for(UIPanel* p = panel.parent; !Nil(p); p = p.parent)
|
|
||||||
{
|
|
||||||
if(!Nil(p.next))
|
|
||||||
{
|
|
||||||
result = p.next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
CheckPanelBounds(f32 pct)
|
|
||||||
{
|
|
||||||
return pct >= 0.0 && pct <= 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PushPanel(UIPanel* parent, UIPanel* panel)
|
|
||||||
{
|
|
||||||
DLLPush(parent, panel, g_UI_NIL_PANEL);
|
|
||||||
panel.parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InsertPanel(UIPanel* parent, UIPanel* prev, UIPanel* panel)
|
|
||||||
{
|
|
||||||
DLLInsert(parent, panel, prev, g_UI_NIL_PANEL);
|
|
||||||
panel.parent = prev.parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InitWidgets()
|
|
||||||
{
|
|
||||||
g_UI_NIL_PANEL = cast(UIPanel*)&g_ui_nil_panel;
|
|
||||||
g_widget_ctx.parent = g_UI_NIL_PANEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
SetFocusedPanel(UIPanel* panel)
|
|
||||||
{
|
|
||||||
if(!CheckNil(g_UI_NIL_PANEL, panel))
|
|
||||||
{
|
|
||||||
g_widget_ctx.focused_panel = panel;
|
|
||||||
SetFocus(Get(panel.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UIPanel*
|
|
||||||
GetFocusedPanel()
|
|
||||||
{
|
|
||||||
return Nil(g_widget_ctx.focused_panel) ? g_UI_NIL_PANEL : g_widget_ctx.focused_panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Nil(UIPanel* panel)
|
|
||||||
{
|
|
||||||
return panel == null || panel == g_UI_NIL_PANEL;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user