implement scrolling, various fixes
This commit is contained in:
parent
39ab34ebeb
commit
ace749228d
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit 7f4c109106eaabda180158a8f7a92c9d2e60d3db
|
||||
Subproject commit 809814577db807d5911e79216d6e114a2d5a2dfd
|
||||
278
src/editor/ui.d
278
src/editor/ui.d
@ -154,7 +154,11 @@ struct UIInput
|
||||
UIInput* next, prev;
|
||||
union
|
||||
{
|
||||
Input key;
|
||||
struct
|
||||
{
|
||||
Input key;
|
||||
string text;
|
||||
};
|
||||
IVec2 rel;
|
||||
IVec2 pos;
|
||||
}
|
||||
@ -168,8 +172,8 @@ UICtxParameter(T, string name)
|
||||
{
|
||||
import std.traits, std.array;
|
||||
|
||||
string stack_top = "\tStackTop!("~T.stringof~") "~name~";\n";
|
||||
string stack = "\tStack!("~T.stringof~")* "~name~"_top;\n";
|
||||
string stack_top = "\tStackTop!("~T.stringof~") "~name~";\n";
|
||||
string stack = "\tStack!("~T.stringof~")* "~name~"_top;\n";
|
||||
|
||||
return stack_top~stack;
|
||||
}
|
||||
@ -177,7 +181,8 @@ UICtxParameter(T, string name)
|
||||
mixin(CtxParameterGen!(T, name)());
|
||||
}
|
||||
|
||||
template CtxMemberInfo(int i)
|
||||
template
|
||||
CtxMemberInfo(int i)
|
||||
{
|
||||
import std.string : endsWith, startsWith;
|
||||
import std.traits : isInstanceOf, isPointer;
|
||||
@ -274,31 +279,32 @@ struct StackTop(T)
|
||||
Stack!(T)* free;
|
||||
}
|
||||
|
||||
mixin template UIItemParameters()
|
||||
static string
|
||||
UIItemParameterGen()
|
||||
{
|
||||
static string
|
||||
UIItemParameterGen()
|
||||
string fields = "";
|
||||
static foreach(i, m; UICtx.tupleof)
|
||||
{
|
||||
string fields = "";
|
||||
static foreach(i, m; UICtx.tupleof)
|
||||
{
|
||||
enum info = CtxMemberInfo!(i);
|
||||
static if(info.is_stack)
|
||||
{
|
||||
enum info = CtxMemberInfo!(i);
|
||||
static if(info.is_stack)
|
||||
fields ~= typeof(UICtx.tupleof[i].top.value).stringof ~ " " ~ info.id;
|
||||
static if(is(typeof(UICtx.tupleof[i]): f32))
|
||||
{
|
||||
fields ~= typeof(UICtx.tupleof[i].top.value).stringof ~ " " ~ info.id;
|
||||
static if(is(typeof(UICtx.tupleof[i]): f32))
|
||||
{
|
||||
fields ~= " = 0.0";
|
||||
}
|
||||
fields ~= ";\n";
|
||||
fields ~= " = 0.0";
|
||||
}
|
||||
fields ~= ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
mixin template
|
||||
UIItemParameters()
|
||||
{
|
||||
mixin(UIItemParameterGen());
|
||||
}
|
||||
|
||||
@ -677,17 +683,21 @@ InitSingleLine:
|
||||
{
|
||||
if(item.flags & (UIF.ScrollX << axis))
|
||||
{
|
||||
item.scroll_offset.v[axis] += scroll_speed * (item.scroll_target.v[axis] - item.scroll_offset.v[axis]);
|
||||
|
||||
if(fabsf(item.scroll_offset.v[axis] - item.scroll_target.v[axis]) < 2.0)
|
||||
if(fabsf(item.scroll_offset.v[axis] - item.scroll_target.v[axis]) > 0.0009)
|
||||
{
|
||||
item.scroll_offset.v[axis] = item.scroll_target.v[axis];
|
||||
f32 v = scroll_speed * (item.scroll_target.v[axis] - item.scroll_offset.v[axis]);
|
||||
item.scroll_offset.v[axis] += v;
|
||||
|
||||
if(fabsf(item.scroll_offset.v[axis] - item.scroll_target.v[axis]) < 2.0)
|
||||
{
|
||||
item.scroll_offset.v[axis] = item.scroll_target.v[axis];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(item.flags & (UIF.ClampX << axis))
|
||||
{
|
||||
item.scroll_offset = clamp(item.scroll_offset.v[axis], item.scroll_clamp[axis].x, item.scroll_clamp[axis].y);
|
||||
item.scroll_offset.v[axis] = clamp(item.scroll_offset.v[axis], item.scroll_clamp[axis].x, item.scroll_clamp[axis].y);
|
||||
}
|
||||
}
|
||||
|
||||
@ -822,7 +832,7 @@ BeginUI(Inputs* inputs)
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
PushUIEvent(ctx, UIInput(type: UIE.Press, key: i.key));
|
||||
PushUIEvent(ctx, UIInput(type: UIE.Press, key: i.key, text: i.pressed ? i.text : []));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@ -851,7 +861,7 @@ BeginUI(Inputs* inputs)
|
||||
// Ctx state
|
||||
ctx.f_idx = ctx.frame%FRAME_OVERLAP;
|
||||
ctx.inputs = inputs;
|
||||
ctx.char_width = GlyphWidth(&ctx.atlas_buf.atlas.glyphs['0']);
|
||||
ctx.char_width = GlyphWidth(&ctx.atlas_buf.atlas.glyphs[' ']);
|
||||
|
||||
ResetStacks(ctx);
|
||||
|
||||
@ -880,13 +890,13 @@ BeginUI(Inputs* inputs)
|
||||
|
||||
// Root Item
|
||||
UISize[2] sizes = [UISize(ST.Pixels, ctx.res.x), UISize(ST.Pixels, ctx.res.y)];
|
||||
Push!("size_info")(ctx, sizes);
|
||||
Push!("size_info")(sizes);
|
||||
|
||||
ctx.root = MakeItem("###root");
|
||||
ctx.window_root = MakeItem("###window_root");
|
||||
|
||||
Pop!("size_info")(ctx);
|
||||
Push!("parent")(ctx, ctx.root);
|
||||
Pop!("size_info");
|
||||
Push!("parent")(ctx.root);
|
||||
}
|
||||
|
||||
void
|
||||
@ -999,7 +1009,7 @@ EndUI()
|
||||
{
|
||||
f32 size = InnerSize!(axis)(item);
|
||||
|
||||
if(item.flags & (UIF.PortalX << axis))
|
||||
if(item.flags & (UIF.PortalViewX << axis))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1067,7 +1077,7 @@ EndUI()
|
||||
}
|
||||
else if(item == item.parent.first)
|
||||
{
|
||||
pos += item.parent.padding.v[axis];
|
||||
pos += item.parent.padding.v[axis] + item.parent.view_offset.v[axis];
|
||||
}
|
||||
|
||||
f32 inner_pos = pos;
|
||||
@ -1082,6 +1092,7 @@ EndUI()
|
||||
assert(!isNaN(item.rect.p0.v[axis]));
|
||||
assert(!isNaN(item.rect.p1.v[axis]));
|
||||
|
||||
/*
|
||||
debug
|
||||
{
|
||||
bool portal = cast(bool)(item.parent.flags & (UIF.PortalViewX << axis));
|
||||
@ -1103,6 +1114,7 @@ EndUI()
|
||||
assert(in_bounds_start && in_bounds_end);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if(!Nil(item.first))
|
||||
{
|
||||
@ -1169,8 +1181,8 @@ RenderItem(UICtx* ctx, UIItem* item)
|
||||
{
|
||||
DrawUI(ctx);
|
||||
|
||||
u32 x = cast(u32)(scissor_x ? floor(item.rect.p0.x) : ctx.res.x);
|
||||
u32 y = cast(u32)(scissor_y ? floor(item.rect.p0.y) : ctx.res.y);
|
||||
u32 x = cast(u32)(scissor_x ? floor(item.rect.p0.x) : 0);
|
||||
u32 y = cast(u32)(scissor_y ? floor(item.rect.p0.y) : 0);
|
||||
u32 w = cast(u32)(scissor_x ? floor(item.rect.p1.x) - x : ctx.res.x);
|
||||
u32 h = cast(u32)(scissor_y ? floor(item.rect.p1.y) - y : ctx.res.y);
|
||||
SetScissor(&ctx.rd, x, y, w, h);
|
||||
@ -1178,7 +1190,6 @@ RenderItem(UICtx* ctx, UIItem* item)
|
||||
|
||||
if(item.flags & UIF.DrawBackground)
|
||||
{
|
||||
// DrawRect
|
||||
Vertex* v = GetVertex(ctx);
|
||||
v.dst_start = item.rect.p0 + item.border_thickness;
|
||||
v.dst_end = item.rect.p1 - item.border_thickness;
|
||||
@ -1284,23 +1295,117 @@ GetExtent(Renderer* rd)
|
||||
}
|
||||
|
||||
template
|
||||
StackIDs(string stack)
|
||||
StackIDs(string stack, string ctx = "ctx")
|
||||
{
|
||||
import std.string : replace;
|
||||
struct Identifiers { string stack, stack_top_node; }
|
||||
|
||||
enum Identifiers StackIDs = {
|
||||
stack: replace("ctx.@", "@", stack),
|
||||
stack_top_node: replace("ctx.@_top", "@", stack),
|
||||
stack: replace(ctx~".@", "@", stack),
|
||||
stack_top_node: replace(ctx~".@_top", "@", stack),
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
Push(string stack_str, bool auto_pop = false, T)(UICtx* ctx, T value)
|
||||
PushSizeInfoVec(int i)(SizeType type, f32 value, f32 strictness = 1.0, bool auto_pop = false)
|
||||
{
|
||||
UISize[2] size_info = g_size_info_default;
|
||||
|
||||
size_info[i].type = type;
|
||||
size_info[i].value = value;
|
||||
size_info[i].strictness = strictness;
|
||||
|
||||
Push!("size_info")(size_info, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushSizeInfoX(SizeType type, f32 value, f32 strictness = 1.0, bool auto_pop = false)
|
||||
{
|
||||
PushSizeInfoVec!(0)(type, value, strictness, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushSizeInfoY(SizeType type, f32 value, f32 strictness = 1.0, bool auto_pop = false)
|
||||
{
|
||||
PushSizeInfoVec!(1)(type, value, strictness, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushScrollClampVec(int i)(Vec2 clamp, bool auto_pop)
|
||||
{
|
||||
Vec2[2] scroll_clamp = g_scroll_clamp_default;
|
||||
scroll_clamp[i] = clamp;
|
||||
Push!("scroll_clamp")(scroll_clamp, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushScrollClampX(f32 start, f32 end, bool auto_pop = false)
|
||||
{
|
||||
PushScrollClampVec!(0)(Vec2(start, end), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushScrollClampY(f32 start, f32 end, bool auto_pop = false)
|
||||
{
|
||||
PushScrollClampVec!(1)(Vec2(start, end), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushBorderCol(Vec4 col, bool auto_pop = false)
|
||||
{
|
||||
Vec4[4] arr = col;
|
||||
PushBorderCol(arr, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushBgCol(Vec4 col, bool auto_pop = false)
|
||||
{
|
||||
Vec4[4] arr = col;
|
||||
PushBgCol(arr, auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushPaddingX(f32 padding, bool auto_pop = false)
|
||||
{
|
||||
PushPadding(Vec2(padding, 0.0), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushPaddingY(f32 padding, bool auto_pop = false)
|
||||
{
|
||||
PushPadding(Vec2(0.0, padding), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushViewOffsetX(f32 offset, bool auto_pop = false)
|
||||
{
|
||||
PushViewOffset(Vec2(offset, 0.0), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushViewOffsetY(f32 offset, bool auto_pop = false)
|
||||
{
|
||||
PushViewOffset(Vec2(0.0, offset), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushScrollTargetX(f32 target, bool auto_pop = false)
|
||||
{
|
||||
PushScrollTarget(Vec2(target, 0.0), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
PushScrollTargetY(f32 target, bool auto_pop = false)
|
||||
{
|
||||
PushScrollTarget(Vec2(0.0, target), auto_pop);
|
||||
}
|
||||
|
||||
void
|
||||
Push(string stack_str, T)(T value, bool auto_pop = false)
|
||||
{
|
||||
import std.string : replace;
|
||||
|
||||
enum ids = StackIDs!(stack_str);
|
||||
enum ids = StackIDs!(stack_str, "g_ui_ctx");
|
||||
|
||||
auto stack = &mixin(ids.stack);
|
||||
auto top = mixin(ids.stack_top_node);
|
||||
@ -1312,7 +1417,7 @@ Push(string stack_str, bool auto_pop = false, T)(UICtx* ctx, T value)
|
||||
}
|
||||
else
|
||||
{
|
||||
node = Alloc!(Stack!(T))(&ctx.temp_arena);
|
||||
node = Alloc!(Stack!(T))(&g_ui_ctx.temp_arena);
|
||||
}
|
||||
|
||||
node.next = stack.top;
|
||||
@ -1322,12 +1427,29 @@ Push(string stack_str, bool auto_pop = false, T)(UICtx* ctx, T value)
|
||||
stack.top = node;
|
||||
}
|
||||
|
||||
static string
|
||||
PushScope(string stack_str, alias __value)()
|
||||
{
|
||||
enum string id = __traits(identifier, __value);
|
||||
static if(id == "__value")
|
||||
{
|
||||
string value_str = "cast(typeof("~StackIDs!(stack_str, "g_ui_ctx").stack~".top.value))(" ~ __value.stringof ~ ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
string value_str = __traits(identifier, __value);
|
||||
}
|
||||
|
||||
|
||||
return "Push!(\"" ~ stack_str ~ "\")(" ~ value_str ~ ");\n scope(exit) Pop!(\"" ~ stack_str ~ "\");";
|
||||
}
|
||||
|
||||
auto
|
||||
Pop(string stack_str)(UICtx* ctx)
|
||||
Pop(string stack_str)()
|
||||
{
|
||||
import std.string : replace;
|
||||
|
||||
enum ids = StackIDs!(stack_str);
|
||||
enum ids = StackIDs!(stack_str, "g_ui_ctx");
|
||||
|
||||
auto stack = &mixin(ids.stack);
|
||||
auto top = mixin(ids.stack_top_node);
|
||||
@ -1345,14 +1467,52 @@ Pop(string stack_str)(UICtx* ctx)
|
||||
}
|
||||
|
||||
void
|
||||
Pop(stack_strs...)(UICtx* ctx)
|
||||
Pop(stack_strs...)()
|
||||
{
|
||||
static foreach(stack; stack_strs)
|
||||
{
|
||||
Pop!(stack)(ctx);
|
||||
Pop!(stack)();
|
||||
}
|
||||
}
|
||||
|
||||
static string
|
||||
GenPushFuncs()
|
||||
{
|
||||
import std.array : split;
|
||||
import std.uni : toUpper;
|
||||
|
||||
string funcs = "";
|
||||
static foreach(i, m; UICtx.tupleof)
|
||||
{
|
||||
{
|
||||
enum info = CtxMemberInfo!(i);
|
||||
static if(info.is_stack)
|
||||
{
|
||||
string[] parts = split(info.id, "_");
|
||||
|
||||
string fn_name = "Push";
|
||||
foreach(p; parts)
|
||||
{
|
||||
if(p.length == 1)
|
||||
{
|
||||
fn_name ~= toUpper(p[0 .. 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
fn_name ~= toUpper(p[0 .. 1]) ~ p[1 .. $];
|
||||
}
|
||||
}
|
||||
|
||||
funcs ~= "pragma(inline) void " ~ fn_name ~ "(T)(T value, bool auto_pop = false){ Push!(\"" ~ info.id ~ "\")(value, auto_pop); }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return funcs;
|
||||
}
|
||||
|
||||
mixin(GenPushFuncs());
|
||||
|
||||
void
|
||||
AutoPopStacks(UICtx* ctx)
|
||||
{
|
||||
@ -1368,7 +1528,7 @@ AutoPopStacks(UICtx* ctx)
|
||||
if(ctx.tupleof[i].top.auto_pop)
|
||||
{
|
||||
ctx.tupleof[i].top.auto_pop = false;
|
||||
Pop!(member_info.id)(ctx);
|
||||
Pop!(member_info.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1595,8 +1755,6 @@ NewItem(UICtx* ctx)
|
||||
item = Alloc!(UIItem)(&ctx.arena);
|
||||
}
|
||||
|
||||
item.last_frame = ctx.frame-2;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
@ -1666,8 +1824,7 @@ CalcTextWidth(string str)
|
||||
pragma(inline) f32
|
||||
GlyphWidth(Glyph* g)
|
||||
{
|
||||
f32 width = 0.0;
|
||||
width += g.ch == '\t' ? (g_ui_ctx.atlas_buf.atlas.glyphs[' '].advance*cast(f32)(g_ui_ctx.tab_width)) : g.advance;
|
||||
f32 width = g.ch == '\t' ? (g_ui_ctx.atlas_buf.atlas.glyphs[' '].advance*cast(f32)(g_ui_ctx.tab_width)) : g.advance;
|
||||
|
||||
return width;
|
||||
}
|
||||
@ -1962,11 +2119,22 @@ Dragged(UIItem* item, Rect* rect)
|
||||
return result;
|
||||
}
|
||||
|
||||
pragma(inline) Vec4[4]
|
||||
Vec4Arr(Vec4 col)
|
||||
static Vec4[4]
|
||||
Vec4Arr(Vec4 vec)
|
||||
{
|
||||
Vec4[4] arr = col;
|
||||
return arr;
|
||||
return [vec, vec, vec, vec];
|
||||
}
|
||||
|
||||
static Vec2[2]
|
||||
Vec2ArrX(alias Vec2 vec)()
|
||||
{
|
||||
return [vec, Vec2(0.0)];
|
||||
}
|
||||
|
||||
static Vec2[2]
|
||||
Vec2ArrY(alias Vec2 vec)()
|
||||
{
|
||||
return [Vec2(0.0), vec];
|
||||
}
|
||||
|
||||
unittest
|
||||
@ -1995,7 +2163,7 @@ unittest
|
||||
Vec4 w = Vec4(1.0);
|
||||
Vec4[4] col = w;
|
||||
|
||||
Push!("bg_col")(ctx, col);
|
||||
Push!("bg_col")(col);
|
||||
assert(ctx.bg_col.top.value == col);
|
||||
|
||||
EndUI();
|
||||
@ -2011,7 +2179,7 @@ unittest
|
||||
{
|
||||
BeginUI(&inputs);
|
||||
|
||||
Push!("size_info")(ctx, MakeUISizeX(ST.Percentage, 0.5));
|
||||
Push!("size_info")(MakeUISizeX(ST.Percentage, 0.5));
|
||||
UIItem* root = ctx.root;
|
||||
|
||||
UIItem* i0 = MakeItem("###i0");
|
||||
|
||||
@ -14,6 +14,93 @@ Nil(UIPanel* panel)
|
||||
return panel == null || panel == g_UI_NIL_PANEL;
|
||||
}
|
||||
|
||||
void
|
||||
LineCounterView(u64 max_line, u64 lines, u64 line_offset, f32 view_offset)
|
||||
{
|
||||
UICtx* ctx = GetCtx();
|
||||
UIKey zero = ZeroKey();
|
||||
|
||||
u64 ch_width = max_line.toChars().length;
|
||||
f32 lc_width = cast(f32)(ch_width+1)*ctx.char_width; // Should figure out how to accurately measure text width
|
||||
|
||||
PushLayoutAxis(A2D.Y, true);
|
||||
PushViewOffsetY(view_offset, true);
|
||||
PushPaddingX(4.0, true);
|
||||
PushSizeInfoX(ST.Pixels, lc_width, 1.0, true);
|
||||
|
||||
UIItem* line_count = MakeItem(zero, UIF.DrawBorder|UIF.PortalViewY);
|
||||
|
||||
PushTextCol(Vec4(1.0));
|
||||
PushSizeInfoY(ST.Pixels, TEXT_SIZE);
|
||||
PushParent(line_count);
|
||||
|
||||
u64 end_line = lines+line_offset;
|
||||
for(u64 i = line_offset; i < end_line; i += 1)
|
||||
{
|
||||
char[] buf = ScratchAlloc!(char)(ch_width);
|
||||
Push!("display_string")(ConvToStr(sformat(buf, "%s", i)), true);
|
||||
MakeItem(zero, UIF.DrawText);
|
||||
}
|
||||
|
||||
Pop!("text_col", "size_info", "parent");
|
||||
}
|
||||
|
||||
void
|
||||
EditorTextView(UIItem* editor, Editor* ed, u64 lines, u64 line_offset, f32 view_offset)
|
||||
{
|
||||
PushLayoutAxis(A2D.Y, true);
|
||||
|
||||
f32 clamp_y = cast(f32)(ed.buf.line_count-lines)*TEXT_SIZE;
|
||||
f32 scroll_pos = cast(f32)(ed.line_offset)*TEXT_SIZE;
|
||||
|
||||
PushLayoutAxis(A2D.Y, true);
|
||||
PushScrollClampY(0.0, clamp_y, true);
|
||||
PushSizeInfo(g_size_info_default, true);
|
||||
PushBorderCol(Vec4(1.0), true);
|
||||
PushScrollTargetY(scroll_pos, true);
|
||||
PushViewOffsetY(view_offset, true);
|
||||
|
||||
static bool end;
|
||||
static f32 count = 0.0;
|
||||
|
||||
if(!end)
|
||||
{
|
||||
ed.cursor_pos.y = 500;
|
||||
count += g_delta;
|
||||
if(count > 0.5)
|
||||
{
|
||||
end = !end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ed.cursor_pos.y = 0;
|
||||
count -= g_delta;
|
||||
if(count <= 0.0)
|
||||
{
|
||||
end = !end;
|
||||
}
|
||||
}
|
||||
|
||||
editor = MakeItem(editor.key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY);
|
||||
|
||||
u64 end_line = line_offset+lines;
|
||||
|
||||
UIKey zero = ZeroKey();
|
||||
|
||||
PushSizeInfoY(ST.TextSize, 1.0);
|
||||
PushParent(editor);
|
||||
|
||||
scope(exit) Pop!("size_info", "parent");
|
||||
|
||||
u64 i = line_offset;
|
||||
for(LineBuffer* lb = GetLine(&ed.buf, i); !CheckNil(g_NIL_LINE_BUF, lb) && i < line_offset+lines; i += 1, lb = GetLine(&ed.buf, i))
|
||||
{
|
||||
PushDisplayString(ConvToStr(lb.text), true);
|
||||
UIItem* line = MakeItem(zero, UIF.DrawText);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
EditorView(Editor* ed)
|
||||
{
|
||||
@ -23,83 +110,44 @@ EditorView(Editor* ed)
|
||||
UIItem* editor = Get(ed_key);
|
||||
|
||||
u64 frame_line_offset = ed.line_offset;
|
||||
f32 frame_view_offset = editor.scroll_offset.y%TEXT_SIZE;
|
||||
f32 frame_view_offset = -(editor.scroll_offset.y%TEXT_SIZE);
|
||||
|
||||
PushBgCol(Vec4(0.2, 0.3, 0.8, 1.0), true);
|
||||
PushSizeInfoX(ST.Percentage, 1.0, 1.0, true);
|
||||
|
||||
Push!("bg_col", true)(ctx, Vec4Arr(Vec4(0.2, 0.3, 0.8, 1.0)));
|
||||
Push!("size_info", true)(ctx, MakeUISizeX(ST.Percentage, 1.0));
|
||||
UIItem* container = MakeItem(zero, UIF.DrawBackground);
|
||||
|
||||
Push!("parent")(ctx, container);
|
||||
PushParent(container);
|
||||
PushBorderCol(Vec4(1.0));
|
||||
|
||||
Push!("border_col")(ctx, Vec4Arr(Vec4(1.0)));
|
||||
|
||||
// Line Counter
|
||||
f32 lc_width = ed.buf.line_count.toChars().length*ctx.char_width;
|
||||
|
||||
Push!("layout_axis", true)(ctx, A2D.Y);
|
||||
Push!("view_offset" )(ctx, Vec2(0.0, frame_view_offset));
|
||||
Push!("padding", true)(ctx, Vec2(4.0, 0.0));
|
||||
Push!("size_info", true)(ctx, MakeUISizeX(ST.Pixels, lc_width));
|
||||
|
||||
UIItem* line_count = MakeItem(zero, UIF.DrawBorder);
|
||||
|
||||
// Editor
|
||||
f32 scroll_pos = cast(f32)(ed.line_offset)*TEXT_SIZE;
|
||||
|
||||
Push!("layout_axis", true)(ctx, A2D.Y);
|
||||
Push!("scroll_clamp", true)(ctx, cast(Vec2[2])[Vec2(0.0), Vec2(0.0, cast(f32)(ed.buf.line_count)*TEXT_SIZE)]);
|
||||
Push!("size_info", true)(ctx, MakeUISize(UISize(ST.Percentage, 1.0), UISize(ST.Percentage, 1.0)));
|
||||
Push!("border_col", true)(ctx, Vec4Arr(Vec4(1.0)));
|
||||
Push!("scroll_target", true)(ctx, Vec2(0.0, scroll_pos));
|
||||
|
||||
editor = MakeItem(ed_key, UIF.DrawBorder|UIF.ScrollY|UIF.ClampY);
|
||||
|
||||
Pop!("view_offset")(ctx);
|
||||
scope(exit) Pop!("parent", "border_col");
|
||||
|
||||
u64 view_lines;
|
||||
if(editor.size.y > 0.0)
|
||||
{
|
||||
view_lines = cast(u64)ceil(editor.size.y/TEXT_SIZE);
|
||||
view_lines = cast(u64)ceil(editor.size.y/TEXT_SIZE)+1;
|
||||
|
||||
const u64 SCROLL_BUFFER = 2;
|
||||
const u64 SCROLL_BUFFER = 4;
|
||||
|
||||
u64 start = ed.line_offset;
|
||||
u64 end = start+view_lines;
|
||||
|
||||
if(ed.cursor_pos.y < start)
|
||||
{
|
||||
ed.line_offset = clamp(ed.cursor_pos.y - SCROLL_BUFFER, 0, ed.buf.line_count);
|
||||
u64 pos = ed.cursor_pos.y > SCROLL_BUFFER ? ed.cursor_pos.y - SCROLL_BUFFER : ed.cursor_pos.y;
|
||||
ed.line_offset = clamp(pos, 0, ed.buf.line_count);
|
||||
}
|
||||
else if(ed.cursor_pos.y > end)
|
||||
{
|
||||
ed.line_offset = clamp(ed.cursor_pos.y + SCROLL_BUFFER - view_lines, 0, ed.buf.line_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Push!("size_info")(ctx, MakeUISizeY(ST.Pixels, TEXT_SIZE));
|
||||
Push!("parent" )(ctx, line_count);
|
||||
Push!("text_col" )(ctx, Vec4(1.0));
|
||||
u64 start = cast(u64)floor(editor.scroll_offset.y/TEXT_SIZE);
|
||||
|
||||
u64 end_line = frame_line_offset+view_lines;
|
||||
LineCounterView(ed.buf.line_count, view_lines, start, frame_view_offset);
|
||||
|
||||
for(u64 i = frame_line_offset; i < end_line; i += 1)
|
||||
{
|
||||
MakeItem("%s##ed_%s", i, ed.editor_id, UIF.DrawText);
|
||||
}
|
||||
|
||||
Pop!("parent", "size_info")(ctx);
|
||||
|
||||
Push!("size_info")(ctx, MakeUISizeY(ST.TextSize, 1.0));
|
||||
Push!("parent")(ctx, editor);
|
||||
|
||||
u64 i = frame_line_offset;
|
||||
for(LineBuffer* lb = GetLine(&ed.buf, i); !CheckNil(g_NIL_LINE_BUF, lb) && i < end_line; i += 1, lb = GetLine(&ed.buf, i))
|
||||
{
|
||||
Push!("display_string", true)(ctx, ConvToStr(lb.text));
|
||||
UIItem* line = MakeItem(zero, UIF.DrawText);
|
||||
}
|
||||
|
||||
Pop!("parent", "parent", "text_col")(ctx);
|
||||
EditorTextView(editor, ed, view_lines, start, frame_view_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user