fix(sidebar): keep section resize local to neighbors

This commit is contained in:
2026-06-18 23:40:50 -05:00
parent 755092933f
commit 2c7cabb0f9

View File

@@ -667,17 +667,19 @@ bool sidebar_section_header(const char* label, int count, const char* add_toolti
return open;
}
void sidebar_section_splitter(const char* id, size_t section_index, float maximum_height) {
void sidebar_section_splitter(const char* id, size_t section_index, float current_height,
float next_height, float minimum_height, size_t next_section_index, bool persist_next_height) {
ImGui::PushID(id);
ImGui::InvisibleButton("##vertical_resize", {-1, ui(5.0f)});
const bool active = ImGui::IsItemActive();
const bool hovered = ImGui::IsItemHovered();
if (active || hovered) ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS);
if (active) {
const float minimum_height = std::min(42.0f, maximum_height);
const float height = std::clamp(g_user_data->sidebarSectionHeight(section_index) +
ImGui::GetIO().MouseDelta.y / g_ui_scale, minimum_height, maximum_height);
const float total_height = current_height + next_height;
const float height = std::clamp(current_height + ImGui::GetIO().MouseDelta.y / g_ui_scale,
minimum_height, std::max(minimum_height, total_height - minimum_height));
g_user_data->setSidebarSectionHeight(section_index, height);
if (persist_next_height) g_user_data->setSidebarSectionHeight(next_section_index, total_height - height);
}
if (ImGui::IsItemDeactivated()) g_user_data->save();
const ImVec2 minimum = ImGui::GetItemRectMin();
@@ -709,7 +711,8 @@ 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,
float body_height, float maximum_height, bool resizable) {
float body_height, float next_height, float minimum_height, size_t next_section_index,
bool persist_next_height, bool resizable) {
const bool open = sidebar_section_header(label, static_cast<int>(items.size()), add_tooltip, add_notice);
if (open && body_height >= ui(1.0f)) {
if (g_reset_repository_view) ImGui::SetNextWindowScroll({0.0f, 0.0f});
@@ -747,7 +750,9 @@ void section(const char* label, const std::vector<std::string>& items, const cha
}
ImGui::Unindent(ui(sidebar_child_indent));
ImGui::EndChild();
if (resizable) sidebar_section_splitter(label, section_index, maximum_height);
if (resizable)
sidebar_section_splitter(label, section_index, body_height / g_ui_scale, next_height, minimum_height,
next_section_index, persist_next_height);
} else {
ImGui::Separator();
}
@@ -843,7 +848,8 @@ 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, float body_height, float maximum_height, bool resizable) {
size_t section_index, float body_height, float next_height, float minimum_height, size_t next_section_index,
bool persist_next_height, bool resizable) {
const bool open = sidebar_section_header(label, static_cast<int>(branches.size()), add_tooltip, add_notice);
if (open && body_height >= ui(1.0f)) {
if (g_reset_repository_view) ImGui::SetNextWindowScroll({0.0f, 0.0f});
@@ -857,7 +863,9 @@ void branch_section(const char* label, const std::vector<std::string>& branches,
draw_branch_nodes(root, branch_icon, group_icon, remote, label);
ImGui::Unindent(ui(sidebar_child_indent));
ImGui::EndChild();
if (resizable) sidebar_section_splitter(label, section_index, maximum_height);
if (resizable)
sidebar_section_splitter(label, section_index, body_height / g_ui_scale, next_height, minimum_height,
next_section_index, persist_next_height);
} else {
ImGui::Separator();
}
@@ -982,9 +990,12 @@ void draw_sidebar(float width) {
: 0.0f;
const float body_space = std::max(0.0f, ImGui::GetContentRegionAvail().y - header_space - splitter_space);
std::array<float, 4> section_heights{};
std::array<float, 4> maximum_heights{};
std::array<size_t, 4> next_open_indices{};
next_open_indices.fill(section_open.size());
float minimum_height = 0.0f;
if (!open_indices.empty()) {
const float minimum_body = std::min(ui(42.0f), body_space / static_cast<float>(open_indices.size()));
minimum_height = minimum_body / g_ui_scale;
float remaining = body_space;
for (size_t position = 0; position + 1 < open_indices.size(); ++position) {
const size_t index = open_indices[position];
@@ -994,30 +1005,27 @@ void draw_sidebar(float width) {
section_heights[index] = std::clamp(
ui(g_user_data->sidebarSectionHeight(index)), minimum_body, maximum);
remaining -= section_heights[index];
next_open_indices[index] = open_indices[position + 1];
}
section_heights[last_open] = std::max(0.0f, remaining);
for (size_t position = 0; position + 1 < open_indices.size(); ++position) {
const size_t index = open_indices[position];
float other_heights = 0.0f;
for (size_t other_position = 0; other_position + 1 < open_indices.size(); ++other_position)
if (other_position != position) other_heights += section_heights[open_indices[other_position]];
maximum_heights[index] = std::max(minimum_body,
body_space - other_heights - minimum_body) / g_ui_scale;
}
}
branch_section(ICON_TB_DESKTOP " LOCAL", repo().local_branches, ICON_TB_CODE_BRANCH, ICON_TB_FOLDER,
"Create local branch", "Create local branch", false, 0, section_heights[0], maximum_heights[0],
section_open[0] && last_open != 0);
"Create local branch", "Create local branch", false, 0, section_heights[0],
next_open_indices[0] < section_open.size() ? section_heights[next_open_indices[0]] / g_ui_scale : 0.0f,
minimum_height, next_open_indices[0], next_open_indices[0] != last_open, section_open[0] && last_open != 0);
branch_section(ICON_TB_CLOUD " REMOTE", repo().remote_branches, ICON_TB_CODE_BRANCH, ICON_TB_GLOBE,
"Add remote", "Add remote", true, 1, section_heights[1], maximum_heights[1],
section_open[1] && last_open != 1);
"Add remote", "Add remote", true, 1, section_heights[1],
next_open_indices[1] < section_open.size() ? section_heights[next_open_indices[1]] / g_ui_scale : 0.0f,
minimum_height, next_open_indices[1], next_open_indices[1] != last_open, section_open[1] && last_open != 1);
section(ICON_TB_TREE " WORKTREES", repo().worktrees, ICON_TB_COMPUTER,
"Add worktree", "Add worktree", SidebarItemKind::worktree, 2,
section_heights[2], maximum_heights[2], section_open[2] && last_open != 2);
section_heights[2],
next_open_indices[2] < section_open.size() ? section_heights[next_open_indices[2]] / g_ui_scale : 0.0f,
minimum_height, next_open_indices[2], next_open_indices[2] != last_open, section_open[2] && last_open != 2);
section(ICON_TB_LAYERS_LINKED " SUBMODULES", repo().submodules, ICON_TB_LAYERS_LINKED,
"Add submodule", "Add submodule", SidebarItemKind::submodule, 3,
section_heights[3], maximum_heights[3], false);
section_heights[3], 0.0f, minimum_height, section_open.size(), false, false);
ImGui::PopStyleVar();
ImGui::EndChild();
ImGui::EndChild();