refactor(sidebar): unify repository sections

This commit is contained in:
2026-06-18 20:07:58 -05:00
parent 54f91349c4
commit 17028fafdd

View File

@@ -60,7 +60,6 @@ bool g_focus_inline_branch = false;
enum class FileViewMode { path, tree };
FileViewMode g_file_view_mode = FileViewMode::path;
bool g_view_all_files = false;
bool g_sidebar_workspace_view = false;
bool g_request_branch_selector = false;
std::array<char, 128> g_commit_summary{};
std::array<char, 1024> g_commit_description{};
@@ -415,6 +414,7 @@ void section(const char* label, const std::vector<std::string>& items, const cha
ImGui::BeginChild((std::string(label) + "##body").c_str(), {-1, body_height});
const std::vector<std::string> snapshot = items;
for (const auto& item : snapshot) {
if (g_filter[0] && item.find(g_filter.data()) == std::string::npos) continue;
sidebar_item_row(item_icon, item, item);
sidebar_item_context(item, kind);
}
@@ -506,27 +506,12 @@ void draw_sidebar(float width) {
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(39 / 255.0f, 42 / 255.0f, 49 / 255.0f, 1.0f));
ImGui::BeginChild("sidebar", {width, -ui(28.0f)}, ImGuiChildFlags_None,
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
const float mode_button_width = (ImGui::GetContentRegionAvail().x - ImGui::GetStyle().ItemSpacing.x) * 0.5f;
const bool list_selected = !g_sidebar_workspace_view;
if (list_selected)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.15f, 0.25f, 0.40f, 1.0f));
if (ImGui::Button(ICON_FA_LIST " List", {mode_button_width, ui(30)})) g_sidebar_workspace_view = false;
if (list_selected) ImGui::PopStyleColor();
ImGui::SameLine();
const bool workspace_selected = g_sidebar_workspace_view;
if (workspace_selected)
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.15f, 0.25f, 0.40f, 1.0f));
if (ImGui::Button(ICON_FA_LAYER_GROUP " Workspace", {mode_button_width, ui(30)}))
g_sidebar_workspace_view = true;
if (workspace_selected) ImGui::PopStyleColor();
const int viewing_count = g_sidebar_workspace_view
? static_cast<int>(repo().worktrees.size() + repo().submodules.size())
: static_cast<int>(repo().local_branches.size() + repo().remote_branches.size());
const int viewing_count = static_cast<int>(repo().local_branches.size() + repo().remote_branches.size() +
repo().worktrees.size() + repo().submodules.size());
ImGui::TextDisabled(ICON_FA_EYE " VIEWING %d", viewing_count);
ImGui::SetNextItemWidth(-1);
ImGui::InputTextWithHint("##filter", g_sidebar_workspace_view
? ICON_FA_MAGNIFYING_GLASS " Search workspace..."
: ICON_FA_MAGNIFYING_GLASS " Search branches...", g_filter.data(), g_filter.size());
ImGui::InputTextWithHint("##filter", ICON_FA_MAGNIFYING_GLASS " Search sidebar...",
g_filter.data(), g_filter.size());
ImGui::Spacing();
ImGui::BeginChild("sidebar_sections", {-1, -1}, ImGuiChildFlags_None,
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
@@ -540,50 +525,54 @@ void draw_sidebar(float width) {
ICON_FA_CUBES " SUBMODULES",
};
std::array<bool, 4> section_open{};
std::vector<size_t> open_indices;
for (size_t index = 0; index < section_open.size(); ++index) {
if (g_sidebar_workspace_view ? index < 2 : index >= 2) {
section_open[index] = false;
continue;
}
section_open[index] = sidebar_section_is_open(section_ids[index]);
if (section_open[index]) open_indices.push_back(index);
}
const size_t first_index = g_sidebar_workspace_view ? 2 : 0;
const size_t last_index = first_index + 1;
const bool both_open = section_open[first_index] && section_open[last_index];
const float header_space = (ui(24.0f) + 1.0f) * 2.0f;
const float splitter_space = both_open ? ui(5.0f) : 0.0f;
const size_t last_open = open_indices.empty() ? section_open.size() : open_indices.back();
const float header_space = (ui(24.0f) + 1.0f) * static_cast<float>(section_open.size());
const float splitter_space = open_indices.size() > 1
? ui(5.0f) * static_cast<float>(open_indices.size() - 1)
: 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{};
if (both_open) {
const float minimum_body = std::min(ui(42.0f), body_space * 0.5f);
const float first_maximum = std::max(minimum_body, body_space - minimum_body);
section_heights[first_index] = std::clamp(
ui(g_user_data->sidebarSectionHeight(first_index)), minimum_body, first_maximum);
section_heights[last_index] = std::max(0.0f, body_space - section_heights[first_index]);
maximum_heights[first_index] = first_maximum / g_ui_scale;
} else if (section_open[first_index]) {
section_heights[first_index] = body_space;
} else if (section_open[last_index]) {
section_heights[last_index] = body_space;
if (!open_indices.empty()) {
const float minimum_body = std::min(ui(42.0f), body_space / static_cast<float>(open_indices.size()));
float remaining = body_space;
for (size_t position = 0; position + 1 < open_indices.size(); ++position) {
const size_t index = open_indices[position];
const size_t remaining_sections = open_indices.size() - position - 1;
const float maximum = std::max(minimum_body,
remaining - minimum_body * static_cast<float>(remaining_sections));
section_heights[index] = std::clamp(
ui(g_user_data->sidebarSectionHeight(index)), minimum_body, maximum);
remaining -= section_heights[index];
}
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;
}
}
if (!g_sidebar_workspace_view) {
branch_section(ICON_FA_HOUSE " LOCAL", repo().local_branches, ICON_FA_CODE_BRANCH, ICON_FA_FOLDER,
"Create local branch", "Create local branch", false, 0, section_heights[0], maximum_heights[0], both_open);
branch_section(ICON_FA_CLOUD " REMOTE", repo().remote_branches, ICON_FA_CODE_BRANCH, ICON_FA_GLOBE,
"Add remote", "Add remote", true, 1, section_heights[1], maximum_heights[1], false);
} else {
section(ICON_FA_DIAGRAM_PROJECT " WORKTREES", repo().worktrees, ICON_FA_COMPUTER,
"Add worktree", "Add worktree", SidebarItemKind::worktree, 2,
section_heights[2], maximum_heights[2], both_open);
}
if (g_sidebar_workspace_view) {
section(ICON_FA_CUBES " SUBMODULES", repo().submodules, ICON_FA_CUBES,
"Add submodule", "Add submodule", SidebarItemKind::submodule, 3,
section_heights[3], maximum_heights[3], false);
}
branch_section(ICON_FA_HOUSE " LOCAL", repo().local_branches, ICON_FA_CODE_BRANCH, ICON_FA_FOLDER,
"Create local branch", "Create local branch", false, 0, section_heights[0], maximum_heights[0],
section_open[0] && last_open != 0);
branch_section(ICON_FA_CLOUD " REMOTE", repo().remote_branches, ICON_FA_CODE_BRANCH, ICON_FA_GLOBE,
"Add remote", "Add remote", true, 1, section_heights[1], maximum_heights[1],
section_open[1] && last_open != 1);
section(ICON_FA_DIAGRAM_PROJECT " WORKTREES", repo().worktrees, ICON_FA_COMPUTER,
"Add worktree", "Add worktree", SidebarItemKind::worktree, 2,
section_heights[2], maximum_heights[2], section_open[2] && last_open != 2);
section(ICON_FA_CUBES " SUBMODULES", repo().submodules, ICON_FA_CUBES,
"Add submodule", "Add submodule", SidebarItemKind::submodule, 3,
section_heights[3], maximum_heights[3], false);
ImGui::PopStyleVar();
ImGui::EndChild();
ImGui::EndChild();