diff --git a/src/ui/gitree_ui.cpp b/src/ui/gitree_ui.cpp index 788ad36..a9108c5 100644 --- a/src/ui/gitree_ui.cpp +++ b/src/ui/gitree_ui.cpp @@ -209,6 +209,13 @@ bool sidebar_collapse_row(const char* id, const std::string& label, bool default return open; } +bool sidebar_section_is_open(const char* id) { + ImGui::PushID(id); + const bool open = ImGui::GetStateStorage()->GetBool(ImGui::GetID("collapse_state"), true); + ImGui::PopID(); + return open; +} + bool sidebar_section_header(const char* label, int count, const char* add_tooltip, const char* add_notice) { const ImVec2 header_min = ImGui::GetCursorScreenPos(); const float header_width = ImGui::GetContentRegionAvail().x; @@ -277,11 +284,11 @@ void sidebar_item_context(const std::string& item, SidebarItemKind kind) { } void section(const char* label, const std::vector& items, const char* item_icon, - const char* add_tooltip, const char* add_notice, SidebarItemKind kind, size_t section_index) { + const char* add_tooltip, const char* add_notice, SidebarItemKind kind, size_t section_index, + float body_height) { const bool open = sidebar_section_header(label, static_cast(items.size()), add_tooltip, add_notice); if (open) { - ImGui::BeginChild((std::string(label) + "##body").c_str(), - {-1, ui(g_user_data->sidebarSectionHeight(section_index))}); + ImGui::BeginChild((std::string(label) + "##body").c_str(), {-1, std::max(ui(1.0f), body_height)}); for (const auto& item : items) { ImGui::Selectable((std::string(" ") + item_icon + " " + item).c_str()); sidebar_item_context(item, kind); @@ -347,11 +354,10 @@ void draw_branch_nodes(const BranchNode& parent, const char* branch_icon, const void branch_section(const char* label, const std::vector& branches, const char* branch_icon, const char* group_icon, const char* add_tooltip, const char* add_notice, bool remote, - size_t section_index) { + size_t section_index, float body_height) { const bool open = sidebar_section_header(label, static_cast(branches.size()), add_tooltip, add_notice); if (open) { - ImGui::BeginChild((std::string(label) + "##body").c_str(), - {-1, ui(g_user_data->sidebarSectionHeight(section_index))}); + ImGui::BeginChild((std::string(label) + "##body").c_str(), {-1, std::max(ui(1.0f), body_height)}); BranchNode root; for (const auto& branch : branches) { if (g_filter[0] && branch.find(g_filter.data()) == std::string::npos) continue; @@ -367,7 +373,8 @@ void branch_section(const char* label, const std::vector& branches, } void draw_sidebar(float width) { - ImGui::BeginChild("sidebar", {width, -ui(28.0f)}, ImGuiChildFlags_Borders); + ImGui::BeginChild("sidebar", {width, -ui(28.0f)}, ImGuiChildFlags_Borders, + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse); if (ImGui::Button(ICON_FA_LIST " List", {ui(98), ui(30)})) {} ImGui::SameLine(); if (ImGui::Button(ICON_FA_LAYER_GROUP " Workspace", {ui(102), ui(30)})) {} @@ -375,14 +382,41 @@ void draw_sidebar(float width) { ImGui::SetNextItemWidth(-1); ImGui::InputTextWithHint("##filter", ICON_FA_MAGNIFYING_GLASS " Search branches...", g_filter.data(), g_filter.size()); ImGui::Spacing(); + + constexpr const char* section_ids[] = { + ICON_FA_HOUSE " LOCAL", + ICON_FA_CLOUD " REMOTE", + ICON_FA_DIAGRAM_PROJECT " WORKTREES", + ICON_FA_CUBES " SUBMODULES", + }; + std::array section_open{}; + float desired_height = 0.0f; + int open_count = 0; + for (size_t index = 0; index < section_open.size(); ++index) { + section_open[index] = sidebar_section_is_open(section_ids[index]); + if (!section_open[index]) continue; + desired_height += g_user_data->sidebarSectionHeight(index); + ++open_count; + } + const float header_space = (ImGui::GetTextLineHeightWithSpacing() + ui(5.0f)) * section_open.size(); + const float splitter_space = ui(12.0f) * open_count; + const float body_space = std::max(0.0f, ImGui::GetContentRegionAvail().y - header_space - splitter_space); + std::array section_heights{}; + if (desired_height > 0.0f) { + for (size_t index = 0; index < section_heights.size(); ++index) { + if (section_open[index]) + section_heights[index] = body_space * g_user_data->sidebarSectionHeight(index) / desired_height; + } + } + branch_section(ICON_FA_HOUSE " LOCAL", repo().local_branches, ICON_FA_CODE_BRANCH, ICON_FA_FOLDER, - "Create local branch", "Branch creation is not wired yet", false, 0); + "Create local branch", "Branch creation is not wired yet", false, 0, section_heights[0]); branch_section(ICON_FA_CLOUD " REMOTE", repo().remote_branches, ICON_FA_CODE_BRANCH, ICON_FA_GLOBE, - "Add remote", "Remote creation is not wired yet", true, 1); + "Add remote", "Remote creation is not wired yet", true, 1, section_heights[1]); section(ICON_FA_DIAGRAM_PROJECT " WORKTREES", repo().worktrees, ICON_FA_COMPUTER, - "Add worktree", "Worktree creation is not wired yet", SidebarItemKind::worktree, 2); + "Add worktree", "Worktree creation is not wired yet", SidebarItemKind::worktree, 2, section_heights[2]); section(ICON_FA_CUBES " SUBMODULES", repo().submodules, ICON_FA_CUBES, - "Add submodule", "Submodule creation is not wired yet", SidebarItemKind::submodule, 3); + "Add submodule", "Submodule creation is not wired yet", SidebarItemKind::submodule, 3, section_heights[3]); ImGui::EndChild(); }