diff --git a/liblua54.a b/liblua54.a new file mode 100755 index 0000000..b9f953e Binary files /dev/null and b/liblua54.a differ diff --git a/plugins/lua/view.lua b/plugins/lua/view.lua index 3e94bb8..a10e735 100644 --- a/plugins/lua/view.lua +++ b/plugins/lua/view.lua @@ -13,6 +13,7 @@ local CodeViews = {} local MovingTab = nil local MovingTabDest = nil +local MovingTabInBetween = false local LastMouseX = 0 local LastMouseY = 0 @@ -73,11 +74,15 @@ function add_buffer_to_code_view(code_view_index, file_path, buffer_index) CodeViews[code_view_index].current_tab = file_path end -function ui_sidebar(ctx) - SideBarSmoothedWidth = lerp(SideBarSmoothedWidth, SideBarWidth, 0.3) +function ui_sidemenu(ctx) + if SideBarClosed then + SideBarSmoothedWidth = lerp(SideBarSmoothedWidth, 0, 0.3) + else + SideBarSmoothedWidth = lerp(SideBarSmoothedWidth, SideBarWidth, 0.3) + end - 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) + side_menu, _ = UI.push_box(ctx, "side menu", {"Scrollable"}, UI.Vertical, UI.Exact(SideBarSmoothedWidth), UI.Fill) + UI.push_parent(ctx, side_menu) 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_rect(ctx, "padded top open files", false, false, UI.Horizontal, UI.Exact(8), UI.Fill) @@ -109,7 +114,7 @@ function ui_sidebar(ctx) end UI.pop_parent(ctx) end - UI.spacer(ctx, "below tabs spacer") + UI.spacer(ctx, "below buffers spacer") UI.pop_parent(ctx) end @@ -129,10 +134,12 @@ function ui_code_view(ctx, code_view_index) if is_tab_dest then if tab_dest_interaction.hovering then MovingTabDest = code_view_index + elseif MovingTabDest == code_view_index then + MovingTabDest = nil end end - UI.push_parent(ctx, UI.push_rect(ctx, "tabs", false, false, UI.Horizontal, UI.Fill, UI.ChildrenSum)) + UI.push_parent(ctx, UI.push_box(ctx, "tabs", {}, UI.Horizontal, UI.Fill, UI.ChildrenSum)) for k,v in pairs(code_view.tabs) do show_border = k ~= code_view.current_tab background = show_border @@ -163,10 +170,17 @@ function ui_code_view(ctx, code_view_index) UI.pop_parent(ctx) elseif MovingTab ~= nil and MovingTab["code_view_index"] == code_view_index and MovingTab["tab"] == k then if MovingTabDest ~= nil then - add_buffer_to_code_view(MovingTabDest, k, v["buffer_index"]) - remove_buffer_from_code_view(code_view_index, k) + if MovingTabInBetween then + remove_buffer_from_code_view(code_view_index, k) - MovingTabDest = nil + table.insert(CodeViews, MovingTabDest+1, nil) + add_buffer_to_code_view(MovingTabDest+1, k, v["buffer_index"]) + else + add_buffer_to_code_view(MovingTabDest, k, v["buffer_index"]) + remove_buffer_from_code_view(code_view_index, k) + + MovingTabDest = nil + end end MovingTab = nil @@ -197,22 +211,34 @@ function render_ui_window(ctx) numFrames = 7 CurrentPreviewBufferIndex = current_buffer_index - if not SidebarClosed or SideBarSmoothedWidth > 2 then - ui_sidebar(ctx) + if not SideBarClosed or SideBarSmoothedWidth > 2 then + ui_sidemenu(ctx) end - if UI.advanced_button(ctx, "side bar grab handle", {"DrawBorder", "Hoverable"}, UI.Exact(16), UI.Fill).dragging then + + side_bar_interaction = UI.advanced_button(ctx, "side menu grab handle", {"DrawBorder", "Hoverable", "Clickable"}, UI.Exact(16), UI.Fill) + if side_bar_interaction.clicked then + if SideBarClosed then + SideBarClosed = false + + if SideBarWidth < 32 then + SideBarWidth = 128 + end + else + SideBarClosed = true + end + end + if side_bar_interaction.dragging then SideBarWidth = x-8 if SideBarWidth < 32 then - SidebarClosed = true + SideBarClosed = true SideBarWidth = 0 elseif SideBarWidth > 128 then - SidebarClosed = false + SideBarClosed = false end - -- TODO: use some math.max function - if not SidebarClosed and SideBarWidth < 128 then - SideBarWidth = 128 + if not SideBarClosed then + SideBarWidth = math.max(SideBarWidth, 128) end end @@ -220,12 +246,18 @@ function render_ui_window(ctx) 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) + interaction = UI.advanced_button(ctx, k.."code view grab handle", {"DrawBorder", "Hoverable", "Clickable"}, 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 + elseif MovingTab ~= nil and interaction.hovering then + MovingTabInBetween = true + MovingTabDest = k + elseif MovingTabDest == k and MovingTabInBetween then + MovingTabInBetween = false + MovingTabDest = nil end else v.width = UI.Fill diff --git a/src/main.odin b/src/main.odin index 10034fa..fa424cf 100644 --- a/src/main.odin +++ b/src/main.odin @@ -1266,6 +1266,16 @@ main :: proc() { lua.setfield(L, -2, "y"); } lua.setfield(L, -2, "box_pos"); + + lua.newtable(L); + { + lua.pushinteger(L, lua.Integer(interaction.box_size.x)); + lua.setfield(L, -2, "x"); + + lua.pushinteger(L, lua.Integer(interaction.box_size.y)); + lua.setfield(L, -2, "y"); + } + lua.setfield(L, -2, "box_size"); } } @@ -1409,6 +1419,31 @@ main :: proc() { return 1; } }, + 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, interaction := ui.push_box(ui_ctx, strings.clone(string(label), context.temp_allocator), flags, axis, { semantic_width, semantic_height }); + lua.pushlightuserdata(L, box); + push_lua_box_interaction(L, interaction) + return 2; + } + + return i32(lua.ERRRUN); + } + }, lua.L_Reg { "push_rect", proc "c" (L: ^lua.State) -> i32 { @@ -1603,11 +1638,11 @@ main :: proc() { lua.setfield(L, -2, "Horizontal"); lua.pushinteger(L, lua.Integer(ui.Axis.Vertical)); lua.setfield(L, -2, "Vertical"); - lua.pushinteger(L, lua.Integer(ui.SemanticSizeKind.Fill)); + push_lua_semantic_size_table(L, { ui.SemanticSizeKind.Fill, 0 }); lua.setfield(L, -2, "Fill"); - lua.pushinteger(L, lua.Integer(ui.SemanticSizeKind.ChildrenSum)); + push_lua_semantic_size_table(L, { ui.SemanticSizeKind.ChildrenSum, 0 }); lua.setfield(L, -2, "ChildrenSum"); - lua.pushinteger(L, lua.Integer(ui.SemanticSizeKind.FitText)); + push_lua_semantic_size_table(L, { ui.SemanticSizeKind.FitText, 0 }); lua.setfield(L, -2, "FitText"); lua.L_setfuncs(L, raw_data(&ui_lib), 0); diff --git a/src/ui/imm.odin b/src/ui/imm.odin index 4153b99..3eaf9ca 100644 --- a/src/ui/imm.odin +++ b/src/ui/imm.odin @@ -233,12 +233,16 @@ push_box :: proc(ctx: ^Context, label: string, flags: bit_set[Flag], axis: Axis push_parent :: proc(ctx: ^Context, box: ^Box) { ctx.current_parent = box; + + push_clip(ctx, box.computed_pos, box.computed_size, !(.Floating in box.flags)); } pop_parent :: proc(ctx: ^Context) { if ctx.current_parent.parent != nil { ctx.current_parent = ctx.current_parent.parent; } + + pop_clip(ctx); } test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction { @@ -251,11 +255,17 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction { 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 { - 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; - } else if box.parent == nil { + if len(ctx.clips) > 0 { + clip := ctx.clips[len(ctx.clips)-1]; + + if ctx.mouse_x >= clip.pos.x && ctx.mouse_x <= clip.pos.x + clip.size.x && + ctx.mouse_y >= clip.pos.y && ctx.mouse_y <= clip.pos.y + clip.size.y + { + hovering = true; + } else { + hovering = false; + } + } else { hovering = true; } } @@ -274,12 +284,19 @@ test_box :: proc(ctx: ^Context, box: ^Box) -> Interaction { box.active = 0; } + // TODO: change this to use the scroll wheel input + if .Scrollable in box.flags && box.active > 1 && ctx.mouse_left_down { + box.scroll_offset -= ctx.mouse_y - ctx.last_mouse_y; + + box.scroll_offset = math.min(0, box.scroll_offset); + } + if box.hot > 0 || box.active > 0 { box.last_interacted_index = ctx.current_interaction_index; } return Interaction { - hovering = hovering || box.active > 0, - clicked = hovering && mouse_is_released && box.active > 0, + hovering = .Hoverable in box.flags && (hovering || box.active > 0), + clicked = .Clickable in box.flags && (hovering && mouse_is_released && box.active > 0), dragging = box.active > 1, box_pos = box.computed_pos, @@ -367,7 +384,8 @@ compute_layout :: proc(ctx: ^Context, canvas_size: [2]int, font_width: int, font axis := Axis.Horizontal; if box.parent != nil && !(.Floating in box.flags) { axis = box.parent.axis; - box.computed_pos = box.parent.computed_pos - { 0, box.parent.scroll_offset }; + box.computed_pos = box.parent.computed_pos; + box.computed_pos[axis] += box.parent.scroll_offset; } if .Floating in box.flags {