fix(sidebar): scroll section bodies independently

This commit is contained in:
2026-06-18 19:00:29 -05:00
parent de002ef156
commit 660e047cdb

View File

@@ -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<std::string>& 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<int>(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<std::string>& 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<int>(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<std::string>& 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<bool, 4> 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<float, 4> 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();
}