fix(sidebar): keep section resize local to neighbors
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user