get dragging working properly with clicking

rust-rewrite
Patrick Cleavelin 2024-02-18 14:39:28 -06:00
parent 187f48aa87
commit f01eb452a9
4 changed files with 202 additions and 171 deletions

View File

@ -14,6 +14,9 @@ local CodeViews = {}
local MovingTab = nil local MovingTab = nil
local MovingTabDest = nil local MovingTabDest = nil
local LastMouseX = 0
local LastMouseY = 0
function buffer_list_iter() function buffer_list_iter()
local idx = 0 local idx = 0
return function () return function ()
@ -42,15 +45,25 @@ function lerp(from, to, rate)
return (1 - rate) * from + rate*to return (1 - rate) * from + rate*to
end end
function remove_buffer_from_code_view(code_view_index, file_path)
if code_view_index ~= nil and CodeViews[code_view_index] ~= nil then
CodeViews[code_view_index].tabs[file_path] = nil
k,v = pairs(CodeViews[code_view_index].tabs)(CodeViews[code_view_index].tabs)
CodeViews[code_view_index].current_tab = k
end
end
function add_buffer_to_code_view(code_view_index, file_path, buffer_index) function add_buffer_to_code_view(code_view_index, file_path, buffer_index)
if code_view_index == nil then if code_view_index == nil then
code_view_index = 1 code_view_index = 1
ActiveCodeView = 1 ActiveCodeView = 1
end end
-- A new code view is being created
if CodeViews[code_view_index] == nil then if CodeViews[code_view_index] == nil then
CodeViews[code_view_index] = {} CodeViews[code_view_index] = {}
CodeViews[code_view_index].tabs = {} CodeViews[code_view_index].tabs = {}
CodeViews[code_view_index].width = UI.Fill
end end
ActiveCodeView = code_view_index ActiveCodeView = code_view_index
@ -63,7 +76,7 @@ end
function ui_sidebar(ctx) function ui_sidebar(ctx)
SideBarSmoothedWidth = lerp(SideBarSmoothedWidth, SideBarWidth, 0.3) 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) 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))
@ -82,6 +95,7 @@ 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")
Editor.set_current_buffer_from_index(i)
add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, i) add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, i)
end end
@ -104,31 +118,38 @@ function ui_code_view(ctx, code_view_index)
local code_view = CodeViews[code_view_index] local code_view = CodeViews[code_view_index]
local is_tab_dest = MovingTab ~= nil and ActiveCodeView ~= 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)) code_view_rect, code_view_interaction = UI.push_rect(ctx, code_view_index.." code view", ActiveCodeView ~= code_view_index, true, UI.Vertical, code_view.width, 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 UI.push_parent(ctx, code_view_rect)
tab_dest_flags = {}
if is_tab_dest then tab_dest_flags = {"Hoverable"} end
tab_dest_region, tab_dest_interaction = UI.push_box(ctx, "code view tab dest", tab_dest_flags, UI.Vertical, UI.Fill, UI.Fill)
UI.push_parent(ctx, tab_dest_region)
if is_tab_dest then
if tab_dest_interaction.hovering then
MovingTabDest = code_view_index
end
end end
UI.push_parent(ctx, UI.push_rect(ctx, "tabs", false, true, UI.Horizontal, UI.Fill, UI.ChildrenSum)) UI.push_parent(ctx, UI.push_rect(ctx, "tabs", false, false, UI.Horizontal, UI.Fill, UI.ChildrenSum))
for k,v in pairs(code_view.tabs) do for k,v in pairs(code_view.tabs) do
show_border = v["buffer_index"] ~= code_view.current_buffer_index show_border = k ~= code_view.current_tab
background = not show_border background = show_border
flags = {"Clickable", "Hoverable", "DrawText"} flags = {"Clickable", "DrawText"}
if show_border then
table.insert(flags, 1, "DrawBorder")
table.insert(flags, 1, "Hoverable")
end
UI.push_parent(ctx, UI.push_rect(ctx, k.." tab container", background, show_border, UI.Horizontal, UI.ChildrenSum, UI.ChildrenSum)) UI.push_parent(ctx, UI.push_rect(ctx, k.." tab container", background, false, UI.Horizontal, UI.ChildrenSum, UI.ChildrenSum))
tab_button = UI.advanced_button(ctx, " "..k.." ", flags, UI.FitText, UI.Exact(32)) tab_button = UI.advanced_button(ctx, " "..k.." ", flags, UI.FitText, UI.Exact(32))
if tab_button.clicked then if tab_button.clicked or tab_button.dragging then
ActiveCodeView = code_view_index ActiveCodeView = code_view_index
code_view.current_tab = k code_view.current_tab = k
end
local bb = "false" Editor.set_current_buffer_from_index(v["buffer_index"])
if is_tab_dest then bb = "true" end end
-- print("our code view "..code_view_index.." - "..k.." - is tab dest "..bb)
if tab_button.dragging then if tab_button.dragging then
if MovingTab == nil then if MovingTab == nil then
@ -138,13 +159,12 @@ function ui_code_view(ctx, code_view_index)
end end
UI.push_parent(ctx, UI.push_floating(ctx, "dragging tab", x-(96/2), y-(32/2))) 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.advanced_button(ctx, " "..k.." ", {"DrawText", "DrawBorder", "DrawBackground"}, UI.FitText, UI.Exact(32))
UI.pop_parent(ctx) UI.pop_parent(ctx)
elseif MovingTab ~= nil and MovingTab["code_view_index"] == code_view_index and MovingTab["tab"] == k then 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 if MovingTabDest ~= nil then
print("attempting to place tab at code view "..MovingTabDest.code_view_index) add_buffer_to_code_view(MovingTabDest, k, v["buffer_index"])
remove_buffer_from_code_view(code_view_index, k)
MovingTabDest = nil MovingTabDest = nil
end end
@ -156,19 +176,23 @@ function ui_code_view(ctx, code_view_index)
UI.pop_parent(ctx) UI.pop_parent(ctx)
current_tab = code_view.current_tab current_tab = code_view.current_tab
if code_view.tabs[current_tab] ~= nil then
buffer_index = code_view.tabs[current_tab].buffer_index buffer_index = code_view.tabs[current_tab].buffer_index
UI.buffer(ctx, buffer_index) UI.buffer(ctx, buffer_index)
if is_tab_dest then
UI.pop_parent(ctx)
end end
UI.pop_parent(ctx) UI.pop_parent(ctx)
UI.pop_parent(ctx)
return code_view_interaction
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) x,y = UI.get_mouse_pos(ctx)
delta_x = LastMouseX - x
delta_y = LastMouseY - y
numFrames = 7 numFrames = 7
CurrentPreviewBufferIndex = current_buffer_index CurrentPreviewBufferIndex = current_buffer_index
@ -192,11 +216,36 @@ function render_ui_window(ctx)
end end
end end
for k in ipairs(CodeViews) do for k,v in ipairs(CodeViews) do
ui_code_view(ctx, k) code_view_interaction = ui_code_view(ctx, k)
if next(CodeViews, k) ~= nil then
interaction = UI.advanced_button(ctx, k.."code view grab handle", {"DrawBorder", "Hoverable"}, UI.Exact(16), UI.Fill)
if interaction.dragging then
local width = math.max(32, x - code_view_interaction.box_pos.x)
v.width = UI.Exact(width)
elseif interaction.clicked then
v.width = UI.Fill
end
else
v.width = UI.Fill
end
end
for k,v in ipairs(CodeViews) do
if next(v.tabs) == nil then
table.remove(CodeViews, k)
if ActiveCodeView > k then
ActiveCodeView = ActiveCodeView - 1
end
end
end end
render_buffer_search(ctx) render_buffer_search(ctx)
LastMouseX = x
LastMouseY = y
end end
function render_buffer_search(ctx) function render_buffer_search(ctx)
@ -259,6 +308,9 @@ function OnInit()
)}, )},
{Editor.Key.Enter, "Switch to Buffer", ( {Editor.Key.Enter, "Switch to Buffer", (
function () function ()
buffer_info = Editor.buffer_info_from_index(BufferSearchIndex)
add_buffer_to_code_view(ActiveCodeView, buffer_info.file_path, BufferSearchIndex)
Editor.set_current_buffer_from_index(BufferSearchIndex) Editor.set_current_buffer_from_index(BufferSearchIndex)
Editor.request_window_close() Editor.request_window_close()
BufferSearchOpen = false BufferSearchOpen = false

View File

@ -120,6 +120,21 @@ draw_rect :: proc(state: ^State, x,y,w,h: int, color: theme.PaletteColor) {
sdl2.RenderFillRect(state.sdl_renderer, &sdl2.Rect { i32(x), i32(y), i32(w), i32(h) }); sdl2.RenderFillRect(state.sdl_renderer, &sdl2.Rect { i32(x), i32(y), i32(w), i32(h) });
} }
draw_rect_blend :: proc(state: ^State, x,y,w,h: int, color_from: theme.PaletteColor, color_to: theme.PaletteColor, t: f32) {
color_from := theme.get_palette_color(color_from);
color_to := theme.get_palette_color(color_to);
color_from_f32: [4]f32 = { f32(color_from.r), f32(color_from.g), f32(color_from.b), f32(color_from.a) };
color_to_f32: [4]f32 = { f32(color_to.r), f32(color_to.g), f32(color_to.b), f32(color_to.a) };
color_f32 := (1 - t) * color_from_f32 + t * color_to_f32;
color: [4]u8 = { u8(color_f32.r), u8(color_f32.g), u8(color_f32.b), u8(color_f32.a) };
sdl2.SetRenderDrawColor(state.sdl_renderer, color.r, color.g, color.b, color.a);
sdl2.RenderFillRect(state.sdl_renderer, &sdl2.Rect { i32(x), i32(y), i32(w), i32(h) });
}
draw_codepoint :: proc(state: ^State, codepoint: rune, x,y: int, color: theme.PaletteColor) { draw_codepoint :: proc(state: ^State, codepoint: rune, x,y: int, color: theme.PaletteColor) {
color := theme.get_palette_color(color); color := theme.get_palette_color(color);

View File

@ -301,13 +301,16 @@ ui_file_buffer :: proc(ctx: ^ui.Context, buffer: ^FileBuffer) -> ui.Interaction
}; };
relative_file_path, _ := filepath.rel(state.directory, buffer.file_path, context.temp_allocator) relative_file_path, _ := filepath.rel(state.directory, buffer.file_path, context.temp_allocator)
ui.push_parent(ctx, ui.push_box(ctx, relative_file_path, {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Fill)}));
buffer_container, _ := ui.push_box(ctx, relative_file_path, {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Fill)});
ui.push_parent(ctx, buffer_container);
defer ui.pop_parent(ctx); defer ui.pop_parent(ctx);
interaction := ui.custom(ctx, "buffer1", draw_func, transmute(rawptr)buffer); interaction := ui.custom(ctx, "buffer1", draw_func, transmute(rawptr)buffer);
{ {
ui.push_parent(ctx, ui.push_box(ctx, "buffer info", {}, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Exact, state.source_font_height)})); info_box, _ := ui.push_box(ctx, "buffer info", {}, semantic_size = {ui.make_semantic_size(.Fill), ui.make_semantic_size(.Exact, state.source_font_height)});
ui.push_parent(ctx, info_box);
defer ui.pop_parent(ctx); defer ui.pop_parent(ctx);
ui.label(ctx, relative_file_path); ui.label(ctx, relative_file_path);
@ -825,7 +828,8 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
ui_context := transmute(^ui.Context)ui_context; ui_context := transmute(^ui.Context)ui_context;
label := strings.clone(string(label), context.temp_allocator); label := strings.clone(string(label), context.temp_allocator);
return ui.push_floating(ui_context, label, pos); floating, _ := ui.push_floating(ui_context, label, pos);
return floating;
}, },
rect = proc "c" (ui_context: rawptr, label: cstring, background: bool, border: bool, axis: plugin.UiAxis, size: [2]plugin.UiSemanticSize) -> plugin.UiBox { rect = proc "c" (ui_context: rawptr, label: cstring, background: bool, border: bool, axis: plugin.UiAxis, size: [2]plugin.UiSemanticSize) -> plugin.UiBox {
context = state.ctx; context = state.ctx;
@ -843,7 +847,8 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
}, },
}; };
return ui.push_rect(ui_context, label, background, border, ui.Axis(axis), size); rect, _ := ui.push_rect(ui_context, label, background, border, ui.Axis(axis), size);
return rect;
}, },
label = proc "c" (ui_context: rawptr, label: cstring) -> plugin.UiInteraction { label = proc "c" (ui_context: rawptr, label: cstring) -> plugin.UiInteraction {
@ -1251,6 +1256,16 @@ main :: proc() {
lua.pushboolean(L, b32(interaction.dragging)); lua.pushboolean(L, b32(interaction.dragging));
lua.setfield(L, -2, "dragging"); lua.setfield(L, -2, "dragging");
lua.newtable(L);
{
lua.pushinteger(L, lua.Integer(interaction.box_pos.x));
lua.setfield(L, -2, "x");
lua.pushinteger(L, lua.Integer(interaction.box_pos.y));
lua.setfield(L, -2, "y");
}
lua.setfield(L, -2, "box_pos");
} }
} }
@ -1339,9 +1354,10 @@ main :: proc() {
x := int(lua.L_checkinteger(L, 3)); x := int(lua.L_checkinteger(L, 3));
y := int(lua.L_checkinteger(L, 4)); y := int(lua.L_checkinteger(L, 4));
box := ui.push_floating(ui_ctx, strings.clone(string(label), context.temp_allocator), {x,y}); box, interaction := ui.push_floating(ui_ctx, strings.clone(string(label), context.temp_allocator), {x,y});
lua.pushlightuserdata(L, box); lua.pushlightuserdata(L, box);
return 1; push_lua_box_interaction(L, interaction);
return 2;
} }
return i32(lua.ERRRUN); return i32(lua.ERRRUN);
@ -1363,16 +1379,18 @@ main :: proc() {
semantic_width := get_lua_semantic_size(L, 5); semantic_width := get_lua_semantic_size(L, 5);
semantic_height := get_lua_semantic_size(L, 6); 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 }); box, interaction := ui.push_box(ui_ctx, strings.clone(string(label), context.temp_allocator), flags, axis, { semantic_width, semantic_height });
lua.pushlightuserdata(L, box); lua.pushlightuserdata(L, box);
return 1; push_lua_box_interaction(L, interaction)
return 2;
} }
return i32(lua.ERRRUN); return i32(lua.ERRRUN);
} }
}, },
lua.L_Reg { lua.L_Reg {
"box_interaction", "_box_interaction",
proc "c" (L: ^lua.State) -> i32 { proc "c" (L: ^lua.State) -> i32 {
context = state.ctx; context = state.ctx;
@ -1408,35 +1426,10 @@ main :: proc() {
semantic_width := get_lua_semantic_size(L, 6); semantic_width := get_lua_semantic_size(L, 6);
semantic_height := get_lua_semantic_size(L, 7); semantic_height := get_lua_semantic_size(L, 7);
box := ui.push_rect(ui_ctx, strings.clone(string(label), context.temp_allocator), background, border, axis, { semantic_width, semantic_height }); box, interaction := ui.push_rect(ui_ctx, strings.clone(string(label), context.temp_allocator), background, border, axis, { semantic_width, semantic_height });
lua.pushlightuserdata(L, box); lua.pushlightuserdata(L, box);
return 1; push_lua_box_interaction(L, interaction)
} return 2;
return i32(lua.ERRRUN);
}
},
lua.L_Reg {
"push_centered",
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);
background := bool(lua.toboolean(L, 3));
border := bool(lua.toboolean(L, 4));
axis := ui.Axis(lua.L_checkinteger(L, 5));
semantic_width := get_lua_semantic_size(L, 6);
semantic_height := get_lua_semantic_size(L, 7);
box := ui.push_centered(ui_ctx, strings.clone(string(label), context.temp_allocator), {.DrawBackground if background else nil, .DrawBorder if border else nil}, axis, { semantic_width, semantic_height });
lua.pushlightuserdata(L, box);
return 1;
} }
return i32(lua.ERRRUN); return i32(lua.ERRRUN);
@ -1772,6 +1765,9 @@ main :: proc() {
ui_context.last_mouse_left_down = ui_context.mouse_left_down; ui_context.last_mouse_left_down = ui_context.mouse_left_down;
ui_context.last_mouse_right_down = ui_context.mouse_right_down; ui_context.last_mouse_right_down = ui_context.mouse_right_down;
ui_context.last_mouse_x = ui_context.mouse_x;
ui_context.last_mouse_y = ui_context.mouse_y;
sdl_event: sdl2.Event; sdl_event: sdl2.Event;
for(sdl2.PollEvent(&sdl_event)) { for(sdl2.PollEvent(&sdl_event)) {
if sdl_event.type == .QUIT { if sdl_event.type == .QUIT {

View File

@ -17,6 +17,9 @@ Context :: struct {
clips: [dynamic]Rect, clips: [dynamic]Rect,
renderer: ^sdl2.Renderer, renderer: ^sdl2.Renderer,
last_mouse_x: int,
last_mouse_y: int,
mouse_x: int, mouse_x: int,
mouse_y: int, mouse_y: int,
@ -41,6 +44,9 @@ Interaction :: struct {
hovering: bool, hovering: bool,
clicked: bool, clicked: bool,
dragging: bool, dragging: bool,
box_pos: [2]int,
box_size: [2]int,
} }
Flag :: enum { Flag :: enum {
@ -93,6 +99,8 @@ Box :: struct {
computed_size: [2]int, computed_size: [2]int,
computed_pos: [2]int, computed_pos: [2]int,
scroll_offset: int,
hot: int, hot: int,
active: int, active: int,
@ -215,11 +223,12 @@ Fill :[2]SemanticSize: {
} }
}; };
push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText) -> ^Box { push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText) -> (^Box, Interaction) {
key := gen_key(ctx, label, 0); 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);
interaction := test_box(ctx, box);
return box; return box, interaction;
} }
push_parent :: proc(ctx: ^Context, box: ^Box) { push_parent :: proc(ctx: ^Context, box: ^Box) {
@ -236,11 +245,19 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction {
hovering: bool; hovering: bool;
mouse_is_clicked := !ctx.last_mouse_left_down && ctx.mouse_left_down; mouse_is_clicked := !ctx.last_mouse_left_down && ctx.mouse_left_down;
mouse_is_released := ctx.last_mouse_left_down && !ctx.mouse_left_down;
mouse_is_dragging := !mouse_is_clicked && ctx.mouse_left_down && (ctx.last_mouse_x != ctx.mouse_x || ctx.last_mouse_y != ctx.mouse_y);
if ctx.mouse_x >= box.computed_pos.x && ctx.mouse_x <= box.computed_pos.x + box.computed_size.x && if ctx.mouse_x >= box.computed_pos.x && ctx.mouse_x <= box.computed_pos.x + box.computed_size.x &&
ctx.mouse_y >= box.computed_pos.y && ctx.mouse_y <= box.computed_pos.y + box.computed_size.y ctx.mouse_y >= box.computed_pos.y && ctx.mouse_y <= box.computed_pos.y + box.computed_size.y
{
if box.parent != nil && ctx.mouse_x >= box.parent.computed_pos.x && ctx.mouse_x <= box.parent.computed_pos.x + box.parent.computed_size.x &&
ctx.mouse_y >= box.parent.computed_pos.y && ctx.mouse_y <= box.parent.computed_pos.y + box.parent.computed_size.y
{ {
hovering = true; hovering = true;
} else if box.parent == nil {
hovering = true;
}
} }
if hovering || box.active > 0 { if hovering || box.active > 0 {
@ -249,9 +266,11 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction {
box.hot = 0; box.hot = 0;
} }
if hovering && mouse_is_clicked { if hovering && mouse_is_clicked && !mouse_is_dragging {
box.active = 1;
} else if hovering && mouse_is_dragging && box.active > 0 {
box.active += 1; box.active += 1;
} else if !ctx.mouse_left_down { } else if !ctx.mouse_left_down && !mouse_is_released {
box.active = 0; box.active = 0;
} }
@ -260,8 +279,11 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction {
} }
return Interaction { return Interaction {
hovering = hovering || box.active > 0, hovering = hovering || box.active > 0,
clicked = hovering && mouse_is_clicked, clicked = hovering && mouse_is_released && box.active > 0,
dragging = box.active > 0 dragging = box.active > 1,
box_pos = box.computed_pos,
box_size = box.computed_size,
}; };
} }
@ -345,7 +367,7 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font
axis := Axis.Horizontal; axis := Axis.Horizontal;
if box.parent != nil && !(.Floating in box.flags) { if box.parent != nil && !(.Floating in box.flags) {
axis = box.parent.axis; axis = box.parent.axis;
box.computed_pos = box.parent.computed_pos; box.computed_pos = box.parent.computed_pos - { 0, box.parent.scroll_offset };
} }
if .Floating in box.flags { if .Floating in box.flags {
@ -538,13 +560,15 @@ draw :: proc(ctx: ^Context, state: ^core.State, font_width: int, font_height: in
defer pop_clip(ctx); defer pop_clip(ctx);
if .Hoverable in box.flags && box.hot > 0 { if .Hoverable in box.flags && box.hot > 0 {
core.draw_rect( core.draw_rect_blend(
state, state,
box.computed_pos.x, box.computed_pos.x,
box.computed_pos.y, box.computed_pos.y,
box.computed_size.x, box.computed_size.x,
box.computed_size.y, box.computed_size.y,
.Background2 .Background1,
.Background2,
f32(math.min(box.hot, 20))/20.0
); );
} else if .DrawBackground in box.flags { } else if .DrawBackground in box.flags {
core.draw_rect( core.draw_rect(
@ -628,50 +652,26 @@ debug_print :: proc(ctx: ^Context, box: ^Box, depth: int = 0) {
} }
spacer :: proc(ctx: ^Context, label: string, flags: bit_set[Flag] = {}, semantic_size: [2]SemanticSize = {{.Fill, 0}, {.Fill,0}}) -> Interaction { spacer :: proc(ctx: ^Context, label: string, flags: bit_set[Flag] = {}, semantic_size: [2]SemanticSize = {{.Fill, 0}, {.Fill,0}}) -> Interaction {
box := push_box(ctx, label, flags, semantic_size = semantic_size); box, interaction := push_box(ctx, label, flags, semantic_size = semantic_size);
return test_box(ctx, box); return interaction;
} }
push_floating :: proc(ctx: ^Context, label: string, pos: [2]int, flags: bit_set[Flag] = {.Floating}, axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = Fill) -> ^Box { push_floating :: proc(ctx: ^Context, label: string, pos: [2]int, flags: bit_set[Flag] = {.Floating}, axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = Fill) -> (^Box, Interaction) {
box := push_box(ctx, label, flags, semantic_size = semantic_size); box, interaction := push_box(ctx, label, flags, semantic_size = semantic_size);
box.computed_pos = pos; box.computed_pos = pos;
return box; return box, interaction;
} }
push_rect :: proc(ctx: ^Context, label: string, background: bool = true, border: bool = true, axis: Axis = .Vertical, semantic_size: [2]SemanticSize = Fill) -> ^Box { push_rect :: proc(ctx: ^Context, label: string, background: bool = true, border: bool = true, axis: Axis = .Vertical, semantic_size: [2]SemanticSize = Fill) -> (^Box, Interaction) {
return push_box(ctx, label, {.DrawBackground if background else nil, .DrawBorder if border else nil}, axis, semantic_size = semantic_size); return push_box(ctx, label, {.DrawBackground if background else nil, .DrawBorder if border else nil}, axis, semantic_size = semantic_size);
} }
push_centered :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis = .Horizontal, semantic_size: [2]SemanticSize = FitText) -> ^Box {
box: ^Box;
push_parent(ctx, push_box(ctx, label, {}, semantic_size = { {.Fill,0}, semantic_size.y }))
{
defer pop_parent(ctx);
spacer(ctx, "left spacer");
halfway_centered := push_rect(ctx, "halfway centered", false, false, .Vertical, { {.Fill, 0}, {.Fill,0} });
push_parent(ctx, halfway_centered);
{
defer pop_parent(ctx);
spacer(ctx, "top spacer");
box = push_box(ctx, label, flags, axis, FitText);
spacer(ctx, "bottom spacer");
}
spacer(ctx, "right spacer");
}
return box;
}
label :: proc(ctx: ^Context, label: string) -> Interaction { label :: proc(ctx: ^Context, label: string) -> Interaction {
box := push_box(ctx, label, {.DrawText}); box, interaction := push_box(ctx, label, {.DrawText});
return test_box(ctx, box); return interaction;
} }
button :: proc(ctx: ^Context, label: string) -> Interaction { button :: proc(ctx: ^Context, label: string) -> Interaction {
@ -679,47 +679,15 @@ button :: proc(ctx: ^Context, label: string) -> Interaction {
} }
advanced_button :: proc(ctx: ^Context, label: string, flags: bit_set[Flag] = {.Clickable, .Hoverable, .DrawText, .DrawBorder, .DrawBackground}, semantic_size: [2]SemanticSize = FitText) -> Interaction { advanced_button :: proc(ctx: ^Context, label: string, flags: bit_set[Flag] = {.Clickable, .Hoverable, .DrawText, .DrawBorder, .DrawBackground}, semantic_size: [2]SemanticSize = FitText) -> Interaction {
box := push_box(ctx, label, flags, semantic_size = semantic_size); box, interaction := push_box(ctx, label, flags, semantic_size = semantic_size);
return test_box(ctx, box); return interaction;
} }
custom :: proc(ctx: ^Context, label: string, draw_func: CustomDrawFunc, user_data: rawptr) -> Interaction { custom :: proc(ctx: ^Context, label: string, draw_func: CustomDrawFunc, user_data: rawptr) -> Interaction {
box := push_box(ctx, label, {.CustomDrawFunc}, semantic_size = { make_semantic_size(.Fill), make_semantic_size(.Fill) }); box, interaction := push_box(ctx, label, {.CustomDrawFunc}, semantic_size = { make_semantic_size(.Fill), make_semantic_size(.Fill) });
box.custom_draw_func = draw_func; box.custom_draw_func = draw_func;
box.user_data = user_data; box.user_data = user_data;
return test_box(ctx, box); return interaction;
}
two_buttons_test :: proc(ctx: ^Context, label1: string, label2: string) {
push_parent(ctx, push_box(ctx, "TWO BUTTONS TEST", {.DrawBorder}, .Vertical, semantic_size = {make_semantic_size(.PercentOfParent, 100), { .Fill, 256}}));
button(ctx, "Row 1");
button(ctx, "Row 2");
button(ctx, label1);
button(ctx, label2);
button(ctx, "Row 5");
button(ctx, "Row 6");
{
push_parent(ctx, push_box(ctx, "two_button_container_inner", {.DrawBorder}, semantic_size = {make_semantic_size(.Fill, 0), { .Fill, 64}}));
defer pop_parent(ctx);
push_box(ctx, "1", {.DrawText, .DrawBackground, .DrawBorder}, semantic_size = {make_semantic_size(.Fill, 100), { .FitText, 256}})
push_box(ctx, "2", {.DrawText, .DrawBackground, .DrawBorder}, semantic_size = {make_semantic_size(.Fill, 100), { .FitText, 256}})
{
push_parent(ctx, push_box(ctx, "two_button_container_inner_inner", {.DrawBorder}, .Vertical, semantic_size = {make_semantic_size(.Fill, 50), { .ChildrenSum, 256}}));
defer pop_parent(ctx);
button(ctx, "this is a test button");
button(ctx, "me in the middle");
button(ctx, "look at me, I'm a test button too");
}
push_box(ctx, "End", {.DrawBorder, .DrawBackground, .DrawText}, .Horizontal, semantic_size = {make_semantic_size(.Fill, 0), { .FitText, 0}})
}
button(ctx, "Help me I'm falling");
pop_parent(ctx);
} }