fix memory leaks and non-cached box interactions
parent
c955a2621b
commit
187f48aa87
4
Makefile
4
Makefile
|
@ -1,8 +1,8 @@
|
||||||
all: editor
|
all: editor
|
||||||
|
|
||||||
editor: src/*.odin grep odin_highlighter
|
editor: src/*.odin grep odin_highlighter
|
||||||
odin build src/ -out:bin/editor.o -build-mode:obj -debug
|
odin build src/ -out:bin/editor.o -build-mode:obj -debug -lld
|
||||||
dsymutil bin/editor.o -o bin/editor.dw
|
dsymutil bin/editor.o -o bin/editor.dSYM
|
||||||
odin build src/ -out:bin/editor -lld
|
odin build src/ -out:bin/editor -lld
|
||||||
|
|
||||||
odin_highlighter:
|
odin_highlighter:
|
||||||
|
|
BIN
liblua54.a
BIN
liblua54.a
Binary file not shown.
|
@ -271,7 +271,6 @@ pub extern "C" fn OnExit(_plugin: Plugin) {
|
||||||
extern "C" fn draw_window(plugin: Plugin, window: *const std::ffi::c_void) {
|
extern "C" fn draw_window(plugin: Plugin, window: *const std::ffi::c_void) {
|
||||||
let window = Box::leak(unsafe { Box::<GrepWindow>::from_raw(window as *mut GrepWindow) });
|
let window = Box::leak(unsafe { Box::<GrepWindow>::from_raw(window as *mut GrepWindow) });
|
||||||
|
|
||||||
let screen_width = (plugin.get_screen_width)() as i32;
|
|
||||||
let screen_height = (plugin.get_screen_height)() as i32;
|
let screen_height = (plugin.get_screen_height)() as i32;
|
||||||
|
|
||||||
let font_height = (plugin.get_font_height)() as i32;
|
let font_height = (plugin.get_font_height)() as i32;
|
||||||
|
|
|
@ -8,6 +8,12 @@ local SideBarSmoothedWidth = 128
|
||||||
local SideBarWidth = 128
|
local SideBarWidth = 128
|
||||||
local SideBarClosed = false
|
local SideBarClosed = false
|
||||||
|
|
||||||
|
local ActiveCodeView = nil
|
||||||
|
local CodeViews = {}
|
||||||
|
|
||||||
|
local MovingTab = nil
|
||||||
|
local MovingTabDest = nil
|
||||||
|
|
||||||
function buffer_list_iter()
|
function buffer_list_iter()
|
||||||
local idx = 0
|
local idx = 0
|
||||||
return function ()
|
return function ()
|
||||||
|
@ -36,10 +42,28 @@ function lerp(from, to, rate)
|
||||||
return (1 - rate) * from + rate*to
|
return (1 - rate) * from + rate*to
|
||||||
end
|
end
|
||||||
|
|
||||||
function ui_sidebar(ctx)
|
function add_buffer_to_code_view(code_view_index, file_path, buffer_index)
|
||||||
SideBarSmoothedWidth = slerp(SideBarSmoothedWidth, SideBarWidth, 0.3)
|
if code_view_index == nil then
|
||||||
|
code_view_index = 1
|
||||||
|
ActiveCodeView = 1
|
||||||
|
end
|
||||||
|
|
||||||
tabs = UI.push_rect(ctx, "sidebar", false, false, UI.Vertical, UI.Exact(SideBarSmoothedWidth), UI.Fill)
|
if CodeViews[code_view_index] == nil then
|
||||||
|
CodeViews[code_view_index] = {}
|
||||||
|
CodeViews[code_view_index].tabs = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
ActiveCodeView = code_view_index
|
||||||
|
|
||||||
|
CodeViews[code_view_index].tabs[file_path] = {}
|
||||||
|
CodeViews[code_view_index].tabs[file_path].buffer_index = buffer_index
|
||||||
|
CodeViews[code_view_index].current_tab = file_path
|
||||||
|
end
|
||||||
|
|
||||||
|
function ui_sidebar(ctx)
|
||||||
|
SideBarSmoothedWidth = lerp(SideBarSmoothedWidth, SideBarWidth, 0.3)
|
||||||
|
|
||||||
|
tabs = UI.push_rect(ctx, "for some reason it chooses this as the parent", false, false, UI.Vertical, UI.Exact(SideBarSmoothedWidth), UI.Fill)
|
||||||
UI.push_parent(ctx, tabs)
|
UI.push_parent(ctx, tabs)
|
||||||
UI.push_rect(ctx, "padded top open files", false, false, UI.Horizontal, UI.Fill, UI.Exact(8))
|
UI.push_rect(ctx, "padded top open files", false, false, UI.Horizontal, UI.Fill, UI.Exact(8))
|
||||||
UI.push_parent(ctx, UI.push_rect(ctx, "padded open files", false, false, UI.Horizontal, UI.Fill, UI.ChildrenSum))
|
UI.push_parent(ctx, UI.push_rect(ctx, "padded open files", false, false, UI.Horizontal, UI.Fill, UI.ChildrenSum))
|
||||||
|
@ -58,11 +82,13 @@ function ui_sidebar(ctx)
|
||||||
|
|
||||||
if UI.advanced_button(ctx, " x ", flags, UI.FitText, UI.FitText).clicked then
|
if UI.advanced_button(ctx, " x ", flags, UI.FitText, UI.FitText).clicked then
|
||||||
print("hahah, you can't close buffers yet silly")
|
print("hahah, you can't close buffers yet silly")
|
||||||
|
add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, i)
|
||||||
end
|
end
|
||||||
|
|
||||||
tab_button_interaction = UI.advanced_button(ctx, " "..buffer_info.file_path.." ", flags, UI.Fill, UI.FitText)
|
tab_button_interaction = UI.advanced_button(ctx, " "..buffer_info.file_path.." ", flags, UI.Fill, UI.FitText)
|
||||||
if tab_button_interaction.clicked then
|
if tab_button_interaction.clicked then
|
||||||
Editor.set_current_buffer_from_index(i)
|
Editor.set_current_buffer_from_index(i)
|
||||||
|
add_buffer_to_code_view(ActiveCodeView, buffer_info.file_path, i)
|
||||||
end
|
end
|
||||||
if tab_button_interaction.hovering then
|
if tab_button_interaction.hovering then
|
||||||
CurrentPreviewBufferIndex = i
|
CurrentPreviewBufferIndex = i
|
||||||
|
@ -74,12 +100,75 @@ function ui_sidebar(ctx)
|
||||||
UI.pop_parent(ctx)
|
UI.pop_parent(ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ui_tabs(ctx)
|
function ui_code_view(ctx, code_view_index)
|
||||||
UI.buffer(ctx, CurrentPreviewBufferIndex)
|
local code_view = CodeViews[code_view_index]
|
||||||
|
local is_tab_dest = MovingTab ~= nil and ActiveCodeView ~= code_view_index
|
||||||
|
|
||||||
|
UI.push_parent(ctx, UI.push_rect(ctx, code_view_index.." code view", ActiveCodeView ~= code_view_index, true, UI.Vertical, UI.Fill, UI.Fill))
|
||||||
|
if is_tab_dest then
|
||||||
|
tab_dest_region = UI.push_box(ctx, "code view tab dest", {"Hoverable"}, UI.Vertical, UI.Fill, UI.Fill)
|
||||||
|
tab_dest_interaction = UI.box_interaction(ctx, tab_dest_region)
|
||||||
|
UI.push_parent(ctx, tab_dest_region)
|
||||||
|
|
||||||
|
-- if tab_dest_interaction
|
||||||
|
end
|
||||||
|
|
||||||
|
UI.push_parent(ctx, UI.push_rect(ctx, "tabs", false, true, UI.Horizontal, UI.Fill, UI.ChildrenSum))
|
||||||
|
for k,v in pairs(code_view.tabs) do
|
||||||
|
show_border = v["buffer_index"] ~= code_view.current_buffer_index
|
||||||
|
background = not show_border
|
||||||
|
flags = {"Clickable", "Hoverable", "DrawText"}
|
||||||
|
|
||||||
|
UI.push_parent(ctx, UI.push_rect(ctx, k.." tab container", background, show_border, UI.Horizontal, UI.ChildrenSum, UI.ChildrenSum))
|
||||||
|
tab_button = UI.advanced_button(ctx, " "..k.." ", flags, UI.FitText, UI.Exact(32))
|
||||||
|
if tab_button.clicked then
|
||||||
|
ActiveCodeView = code_view_index
|
||||||
|
code_view.current_tab = k
|
||||||
|
end
|
||||||
|
|
||||||
|
local bb = "false"
|
||||||
|
if is_tab_dest then bb = "true" end
|
||||||
|
-- print("our code view "..code_view_index.." - "..k.." - is tab dest "..bb)
|
||||||
|
|
||||||
|
if tab_button.dragging then
|
||||||
|
if MovingTab == nil then
|
||||||
|
MovingTab = {}
|
||||||
|
MovingTab["code_view_index"] = code_view_index
|
||||||
|
MovingTab["tab"] = k
|
||||||
|
end
|
||||||
|
|
||||||
|
UI.push_parent(ctx, UI.push_floating(ctx, "dragging tab", x-(96/2), y-(32/2)))
|
||||||
|
UI.advanced_button(ctx, " "..k.." ", flags, UI.FitText, UI.Exact(32))
|
||||||
|
UI.pop_parent(ctx)
|
||||||
|
elseif MovingTab ~= nil and MovingTab["code_view_index"] == code_view_index and MovingTab["tab"] == k then
|
||||||
|
-- Editor.quit()
|
||||||
|
--print("attempting to move tab "..MovingTab["code_view_index"].." - "..MovingTab["tab"])
|
||||||
|
if MovingTabDest ~= nil then
|
||||||
|
print("attempting to place tab at code view "..MovingTabDest.code_view_index)
|
||||||
|
|
||||||
|
MovingTabDest = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
MovingTab = nil
|
||||||
|
end
|
||||||
|
UI.pop_parent(ctx)
|
||||||
|
end
|
||||||
|
UI.pop_parent(ctx)
|
||||||
|
|
||||||
|
current_tab = code_view.current_tab
|
||||||
|
buffer_index = code_view.tabs[current_tab].buffer_index
|
||||||
|
|
||||||
|
UI.buffer(ctx, buffer_index)
|
||||||
|
|
||||||
|
if is_tab_dest then
|
||||||
|
UI.pop_parent(ctx)
|
||||||
|
end
|
||||||
|
UI.pop_parent(ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
function render_ui_window(ctx)
|
function render_ui_window(ctx)
|
||||||
current_buffer_index = Editor.get_current_buffer_index()
|
current_buffer_index = Editor.get_current_buffer_index()
|
||||||
|
x,y = UI.get_mouse_pos(ctx)
|
||||||
|
|
||||||
numFrames = 7
|
numFrames = 7
|
||||||
CurrentPreviewBufferIndex = current_buffer_index
|
CurrentPreviewBufferIndex = current_buffer_index
|
||||||
|
@ -88,7 +177,6 @@ function render_ui_window(ctx)
|
||||||
ui_sidebar(ctx)
|
ui_sidebar(ctx)
|
||||||
end
|
end
|
||||||
if UI.advanced_button(ctx, "side bar grab handle", {"DrawBorder", "Hoverable"}, UI.Exact(16), UI.Fill).dragging then
|
if UI.advanced_button(ctx, "side bar grab handle", {"DrawBorder", "Hoverable"}, UI.Exact(16), UI.Fill).dragging then
|
||||||
x,y = UI.get_mouse_pos(ctx)
|
|
||||||
SideBarWidth = x-8
|
SideBarWidth = x-8
|
||||||
|
|
||||||
if SideBarWidth < 32 then
|
if SideBarWidth < 32 then
|
||||||
|
@ -104,7 +192,10 @@ function render_ui_window(ctx)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
ui_tabs(ctx)
|
for k in ipairs(CodeViews) do
|
||||||
|
ui_code_view(ctx, k)
|
||||||
|
end
|
||||||
|
|
||||||
render_buffer_search(ctx)
|
render_buffer_search(ctx)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1030,6 +1030,16 @@ main :: proc() {
|
||||||
|
|
||||||
bbb: [^]lua.L_Reg;
|
bbb: [^]lua.L_Reg;
|
||||||
editor_lib := [?]lua.L_Reg {
|
editor_lib := [?]lua.L_Reg {
|
||||||
|
lua.L_Reg {
|
||||||
|
"quit",
|
||||||
|
proc "c" (L: ^lua.State) -> i32 {
|
||||||
|
context = state.ctx;
|
||||||
|
|
||||||
|
|
||||||
|
state.should_close = true;
|
||||||
|
return i32(lua.OK);
|
||||||
|
}
|
||||||
|
},
|
||||||
lua.L_Reg {
|
lua.L_Reg {
|
||||||
"print",
|
"print",
|
||||||
proc "c" (L: ^lua.State) -> i32 {
|
proc "c" (L: ^lua.State) -> i32 {
|
||||||
|
@ -1337,6 +1347,50 @@ main :: proc() {
|
||||||
return i32(lua.ERRRUN);
|
return i32(lua.ERRRUN);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
lua.L_Reg {
|
||||||
|
"push_box",
|
||||||
|
proc "c" (L: ^lua.State) -> i32 {
|
||||||
|
context = state.ctx;
|
||||||
|
|
||||||
|
lua.L_checktype(L, 1, i32(lua.TLIGHTUSERDATA));
|
||||||
|
lua.pushvalue(L, 1);
|
||||||
|
ui_ctx := transmute(^ui.Context)lua.touserdata(L, -1);
|
||||||
|
if ui_ctx != nil {
|
||||||
|
label := lua.L_checkstring(L, 2);
|
||||||
|
flags, err := lua_ui_flags(L, 3);
|
||||||
|
axis := ui.Axis(lua.L_checkinteger(L, 4));
|
||||||
|
|
||||||
|
semantic_width := get_lua_semantic_size(L, 5);
|
||||||
|
semantic_height := get_lua_semantic_size(L, 6);
|
||||||
|
|
||||||
|
box := ui.push_box(ui_ctx, strings.clone(string(label), context.temp_allocator), flags, axis, { semantic_width, semantic_height });
|
||||||
|
lua.pushlightuserdata(L, box);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return i32(lua.ERRRUN);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lua.L_Reg {
|
||||||
|
"box_interaction",
|
||||||
|
proc "c" (L: ^lua.State) -> i32 {
|
||||||
|
context = state.ctx;
|
||||||
|
|
||||||
|
lua.L_checktype(L, 1, i32(lua.TLIGHTUSERDATA));
|
||||||
|
lua.pushvalue(L, 1);
|
||||||
|
ui_ctx := transmute(^ui.Context)lua.touserdata(L, -1);
|
||||||
|
if ui_ctx == nil { return i32(lua.ERRRUN); }
|
||||||
|
|
||||||
|
lua.L_checktype(L, 2, i32(lua.TLIGHTUSERDATA));
|
||||||
|
lua.pushvalue(L, 2);
|
||||||
|
box := transmute(^ui.Box)lua.touserdata(L, -1);
|
||||||
|
if box == nil { return i32(lua.ERRRUN); }
|
||||||
|
|
||||||
|
interaction := ui.test_box(ui_ctx, box);
|
||||||
|
push_lua_box_interaction(L, interaction)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
},
|
||||||
lua.L_Reg {
|
lua.L_Reg {
|
||||||
"push_rect",
|
"push_rect",
|
||||||
proc "c" (L: ^lua.State) -> i32 {
|
proc "c" (L: ^lua.State) -> i32 {
|
||||||
|
@ -1888,8 +1942,6 @@ main :: proc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ui.debug_print();
|
|
||||||
|
|
||||||
draw(&StateWithUi { &state, &ui_context });
|
draw(&StateWithUi { &state, &ui_context });
|
||||||
|
|
||||||
ui.prune(&ui_context);
|
ui.prune(&ui_context);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import "../theme"
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
root: ^Box,
|
root: ^Box,
|
||||||
current_parent: ^Box,
|
current_parent: ^Box,
|
||||||
persistent: map[Key]^Box,
|
persistent: map[string]^Box,
|
||||||
current_interaction_index: int,
|
current_interaction_index: int,
|
||||||
|
|
||||||
clips: [dynamic]Rect,
|
clips: [dynamic]Rect,
|
||||||
|
@ -103,24 +103,26 @@ Box :: struct {
|
||||||
init :: proc(renderer: ^sdl2.Renderer) -> Context {
|
init :: proc(renderer: ^sdl2.Renderer) -> Context {
|
||||||
root := new(Box);
|
root := new(Box);
|
||||||
root.key = gen_key(nil, "root", 69);
|
root.key = gen_key(nil, "root", 69);
|
||||||
|
root.label = strings.clone("root")
|
||||||
|
|
||||||
return Context {
|
return Context {
|
||||||
root = root,
|
root = root,
|
||||||
current_parent = root,
|
current_parent = root,
|
||||||
persistent = make(map[Key]^Box),
|
persistent = make(map[string]^Box),
|
||||||
clips = make([dynamic]Rect),
|
clips = make([dynamic]Rect),
|
||||||
renderer = renderer,
|
renderer = renderer,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_key :: proc(ctx: ^Context, label: string, value: int) -> Key {
|
gen_key :: proc(ctx: ^Context, label: string, value: int) -> Key {
|
||||||
key_label := ""
|
key_label: string;
|
||||||
|
|
||||||
if ctx != nil && (ctx.current_parent == nil || len(ctx.current_parent.key.label) < 1) {
|
if ctx != nil && (ctx.current_parent == nil || len(ctx.current_parent.key.label) < 1) {
|
||||||
key_label = label;
|
key_label = strings.clone(label);
|
||||||
} else if ctx != nil {
|
} else if ctx != nil {
|
||||||
key_label = fmt.tprintf("%s:%s", ctx.current_parent.key.label, label);
|
key_label = fmt.aprintf("%s:%s", ctx.current_parent.key.label, label);
|
||||||
} else {
|
} else {
|
||||||
key_label = fmt.tprintf("%s",label);
|
key_label = strings.clone(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Key {
|
return Key {
|
||||||
|
@ -133,23 +135,30 @@ gen_key :: proc(ctx: ^Context, label: string, value: int) -> Key {
|
||||||
make_box :: proc(ctx: ^Context, key: Key, label: string, flags: bit_set[Flag], axis: Axis, semantic_size: [2]SemanticSize) -> ^Box {
|
make_box :: proc(ctx: ^Context, key: Key, label: string, flags: bit_set[Flag], axis: Axis, semantic_size: [2]SemanticSize) -> ^Box {
|
||||||
box: ^Box = nil;
|
box: ^Box = nil;
|
||||||
|
|
||||||
if cached_box, exists := ctx.persistent[key]; exists {
|
if cached_box, exists := ctx.persistent[key.label]; exists {
|
||||||
if cached_box.last_interacted_index < ctx.current_interaction_index {
|
// NOTE(pcleavelin): its important to note that the _cached_ key _is not_ free'd
|
||||||
old_cached_box := ctx.persistent[key];
|
// as that would invalid the maps reference to the key causing memory leaks because
|
||||||
free(old_cached_box);
|
// the map would think that an entry doesn't exist (in some cases)
|
||||||
box = new(Box);
|
delete(key.label)
|
||||||
|
|
||||||
ctx.persistent[key] = box;
|
if cached_box.last_interacted_index < ctx.current_interaction_index-1 {
|
||||||
|
box = cached_box;
|
||||||
|
|
||||||
|
box.last_interacted_index = ctx.current_interaction_index;
|
||||||
|
box.hot = 0;
|
||||||
|
box.active = 0;
|
||||||
} else {
|
} else {
|
||||||
box = cached_box;
|
box = cached_box;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
box = new(Box);
|
box = new(Box);
|
||||||
ctx.persistent[key] = box;
|
ctx.persistent[key.label] = box;
|
||||||
|
|
||||||
|
box.key = key;
|
||||||
|
box.last_interacted_index = ctx.current_interaction_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
box.key = key;
|
box.label = strings.clone(label, context.temp_allocator);
|
||||||
box.label = label;
|
|
||||||
|
|
||||||
box.first = nil;
|
box.first = nil;
|
||||||
box.last = nil;
|
box.last = nil;
|
||||||
|
@ -206,8 +215,8 @@ Fill :[2]SemanticSize: {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText, value: int = 0) -> ^Box {
|
push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText) -> ^Box {
|
||||||
key := gen_key(ctx, label, value);
|
key := gen_key(ctx, label, 0);
|
||||||
box := make_box(ctx, key, label, flags, axis, semantic_size);
|
box := make_box(ctx, key, label, flags, axis, semantic_size);
|
||||||
|
|
||||||
return box;
|
return box;
|
||||||
|
@ -246,6 +255,9 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction {
|
||||||
box.active = 0;
|
box.active = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if box.hot > 0 || box.active > 0 {
|
||||||
|
box.last_interacted_index = ctx.current_interaction_index;
|
||||||
|
}
|
||||||
return Interaction {
|
return Interaction {
|
||||||
hovering = hovering || box.active > 0,
|
hovering = hovering || box.active > 0,
|
||||||
clicked = hovering && mouse_is_clicked,
|
clicked = hovering && mouse_is_clicked,
|
||||||
|
@ -264,7 +276,11 @@ delete_box_children :: proc(ctx: ^Context, box: ^Box, keep_persistent: bool = tr
|
||||||
delete_box :: proc(ctx: ^Context, box: ^Box, keep_persistent: bool = true) {
|
delete_box :: proc(ctx: ^Context, box: ^Box, keep_persistent: bool = true) {
|
||||||
delete_box_children(ctx, box, keep_persistent);
|
delete_box_children(ctx, box, keep_persistent);
|
||||||
|
|
||||||
if !(box.key in ctx.persistent) || !keep_persistent {
|
if box.last_interacted_index < ctx.current_interaction_index-1 {
|
||||||
|
delete_key(&ctx.persistent, box.key.label)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !(box.key.label in ctx.persistent) || !keep_persistent {
|
||||||
delete(box.key.label);
|
delete(box.key.label);
|
||||||
free(box);
|
free(box);
|
||||||
}
|
}
|
||||||
|
@ -276,21 +292,19 @@ prune :: proc(ctx: ^Context) {
|
||||||
for box in iterate_box(&iter) {
|
for box in iterate_box(&iter) {
|
||||||
delete_box_children(ctx, box);
|
delete_box_children(ctx, box);
|
||||||
|
|
||||||
if !(box.key in ctx.persistent) {
|
if !(box.key.label in ctx.persistent) && box != ctx.root {
|
||||||
free(box);
|
free(box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
computed_pos := ctx.root.computed_pos;
|
|
||||||
computed_size := ctx.root.computed_size;
|
|
||||||
root_key := ctx.root.key;
|
|
||||||
|
|
||||||
ctx.root.first = nil;
|
ctx.root.first = nil;
|
||||||
ctx.root.last = nil;
|
ctx.root.last = nil;
|
||||||
ctx.root.next = nil;
|
ctx.root.next = nil;
|
||||||
ctx.root.prev = nil;
|
ctx.root.prev = nil;
|
||||||
ctx.root.parent = nil;
|
ctx.root.parent = nil;
|
||||||
ctx.current_parent = ctx.root;
|
ctx.current_parent = ctx.root;
|
||||||
|
|
||||||
|
ctx.current_interaction_index += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider not using `ctx` here
|
// TODO: consider not using `ctx` here
|
||||||
|
@ -335,7 +349,7 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font
|
||||||
}
|
}
|
||||||
|
|
||||||
if .Floating in box.flags {
|
if .Floating in box.flags {
|
||||||
box.computed_pos = {0,0};
|
// box.computed_pos = {0,0};
|
||||||
} else if box.prev != nil {
|
} else if box.prev != nil {
|
||||||
prev := prev_non_floating_sibling(ctx, box);
|
prev := prev_non_floating_sibling(ctx, box);
|
||||||
|
|
||||||
|
@ -432,6 +446,8 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font
|
||||||
|
|
||||||
iter := BoxIter { box.first, 0 };
|
iter := BoxIter { box.first, 0 };
|
||||||
for child in iterate_box(&iter) {
|
for child in iterate_box(&iter) {
|
||||||
|
if .Floating in child.flags { continue; }
|
||||||
|
|
||||||
switch box.axis {
|
switch box.axis {
|
||||||
case .Horizontal: {
|
case .Horizontal: {
|
||||||
box.computed_size[Axis.Horizontal] += child.computed_size[Axis.Horizontal];
|
box.computed_size[Axis.Horizontal] += child.computed_size[Axis.Horizontal];
|
||||||
|
@ -449,6 +465,8 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font
|
||||||
|
|
||||||
iter := BoxIter { box.first, 0 };
|
iter := BoxIter { box.first, 0 };
|
||||||
for child in iterate_box(&iter) {
|
for child in iterate_box(&iter) {
|
||||||
|
if .Floating in child.flags { continue; }
|
||||||
|
|
||||||
switch box.axis {
|
switch box.axis {
|
||||||
case .Horizontal: {
|
case .Horizontal: {
|
||||||
if child.computed_size[Axis.Vertical] > box.computed_size[Axis.Vertical] {
|
if child.computed_size[Axis.Vertical] > box.computed_size[Axis.Vertical] {
|
||||||
|
@ -463,10 +481,10 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
push_clip :: proc(ctx: ^Context, pos: [2]int, size: [2]int) {
|
push_clip :: proc(ctx: ^Context, pos: [2]int, size: [2]int, inside_parent: bool = true) {
|
||||||
rect := Rect { pos, size };
|
rect := Rect { pos, size };
|
||||||
|
|
||||||
if len(ctx.clips) > 0 {
|
if len(ctx.clips) > 0 && inside_parent {
|
||||||
parent_rect := ctx.clips[len(ctx.clips)-1];
|
parent_rect := ctx.clips[len(ctx.clips)-1];
|
||||||
|
|
||||||
if rect.pos.x >= parent_rect.pos.x &&
|
if rect.pos.x >= parent_rect.pos.x &&
|
||||||
|
@ -515,7 +533,7 @@ pop_clip :: proc(ctx: ^Context) {
|
||||||
draw :: proc(ctx: ^Context, state: ^core.State, font_width: int, font_height: int, box: ^Box) {
|
draw :: proc(ctx: ^Context, state: ^core.State, font_width: int, font_height: int, box: ^Box) {
|
||||||
if box == nil { return; }
|
if box == nil { return; }
|
||||||
|
|
||||||
push_clip(ctx, box.computed_pos, box.computed_size);
|
push_clip(ctx, box.computed_pos, box.computed_size, !(.Floating in box.flags));
|
||||||
{
|
{
|
||||||
defer pop_clip(ctx);
|
defer pop_clip(ctx);
|
||||||
|
|
||||||
|
@ -597,7 +615,7 @@ debug_print :: proc(ctx: ^Context, box: ^Box, depth: int = 0) {
|
||||||
if depth > 0 {
|
if depth > 0 {
|
||||||
fmt.print(">");
|
fmt.print(">");
|
||||||
}
|
}
|
||||||
fmt.println(idx, "Box", box.label, "#", box.key.label, "first", transmute(rawptr)box.first, "parent", transmute(rawptr)box.parent, box.computed_size);
|
fmt.println(idx, "Box _", box.label, "#", box.key.label, "ptr", transmute(rawptr)box); //, "_ first", transmute(rawptr)box.first, "parent", transmute(rawptr)box.parent, box.computed_size);
|
||||||
debug_print(ctx, box, depth+1);
|
debug_print(ctx, box, depth+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue