feat(sidebar): add section icons counts and actions

This commit is contained in:
2026-06-18 16:44:35 -05:00
parent 7b2e0f133d
commit c67dd465ca

View File

@@ -368,14 +368,35 @@ void load_fonts(float scale) {
apply_style(scale);
}
void section(const char* label, const std::vector<std::string>& items) {
bool sidebar_section_header(const char* label, int count, const char* add_tooltip, const char* add_notice) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.60f, 0.67f, 0.76f, 1.0f));
bool open = ImGui::TreeNodeEx(label, ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth);
ImGui::SameLine(ImGui::GetContentRegionAvail().x - 18.0f);
ImGui::TextDisabled("%d", static_cast<int>(items.size()));
const bool open = ImGui::TreeNodeEx(label, ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_AllowOverlap);
ImGui::PopStyleColor();
ImGui::SameLine();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - ui(62.0f));
ImGui::TextDisabled("%d", count);
ImGui::SameLine(0, ui(7.0f));
ImGui::PushID(label);
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.43f, 0.90f, 0.51f, 1.0f));
ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0.25f, 0.72f, 0.35f, 1.0f));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {ui(5.0f), ui(1.0f)});
if (ImGui::SmallButton(ICON_FA_PLUS "##add")) g_notice = add_notice;
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) ImGui::SetTooltip("%s", add_tooltip);
ImGui::PopStyleVar();
ImGui::PopStyleColor(2);
ImGui::PopID();
return open;
}
void section(const char* label, const std::vector<std::string>& items, const char* item_icon,
const char* add_tooltip, const char* add_notice) {
const bool open = sidebar_section_header(label, static_cast<int>(items.size()), add_tooltip, add_notice);
if (open) {
for (const auto& item : items) ImGui::Selectable((" " + item).c_str());
for (const auto& item : items) {
ImGui::Selectable((std::string(" ") + item_icon + " " + item).c_str());
}
ImGui::TreePop();
}
ImGui::Separator();
@@ -401,7 +422,7 @@ void add_branch_node(BranchNode& root, const std::string& branch) {
node->full_name = branch;
}
void draw_branch_nodes(const BranchNode& parent, const std::string& id_path = {}) {
void draw_branch_nodes(const BranchNode& parent, const char* branch_icon, const std::string& id_path = {}) {
for (const auto& [name, node] : parent.children) {
const std::string id = id_path + "/" + name;
if (!node.children.empty()) {
@@ -409,29 +430,26 @@ void draw_branch_nodes(const BranchNode& parent, const std::string& id_path = {}
const bool open = ImGui::TreeNodeEx(label.c_str(), ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_SpanAvailWidth);
if (open) {
if (node.branch) ImGui::Selectable((std::string(ICON_FA_CODE_BRANCH) + " " + name + "##branch" + id).c_str());
draw_branch_nodes(node, id);
if (node.branch) ImGui::Selectable((std::string(branch_icon) + " " + name + "##branch" + id).c_str());
draw_branch_nodes(node, branch_icon, id);
ImGui::TreePop();
}
} else {
ImGui::Selectable((std::string(ICON_FA_CODE_BRANCH) + " " + name + "##" + id).c_str());
ImGui::Selectable((std::string(branch_icon) + " " + name + "##" + id).c_str());
}
}
}
void branch_section(const char* label, const std::vector<std::string>& branches) {
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.60f, 0.67f, 0.76f, 1.0f));
const bool open = ImGui::TreeNodeEx(label, ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_SpanAvailWidth);
ImGui::SameLine(ImGui::GetContentRegionAvail().x - ui(18.0f));
ImGui::TextDisabled("%d", static_cast<int>(branches.size()));
ImGui::PopStyleColor();
void branch_section(const char* label, const std::vector<std::string>& branches, const char* branch_icon,
const char* add_tooltip, const char* add_notice) {
const bool open = sidebar_section_header(label, static_cast<int>(branches.size()), add_tooltip, add_notice);
if (open) {
BranchNode root;
for (const auto& branch : branches) {
if (g_filter[0] && branch.find(g_filter.data()) == std::string::npos) continue;
add_branch_node(root, branch);
}
draw_branch_nodes(root, label);
draw_branch_nodes(root, branch_icon, label);
ImGui::TreePop();
}
ImGui::Separator();
@@ -446,10 +464,14 @@ 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();
branch_section(ICON_FA_HOUSE " LOCAL", repo().local_branches);
branch_section(ICON_FA_CLOUD " REMOTE", repo().remote_branches);
section(ICON_FA_DIAGRAM_PROJECT " WORKTREES", repo().worktrees);
section(ICON_FA_CUBES " SUBMODULES", repo().submodules);
branch_section(ICON_FA_HOUSE " LOCAL", repo().local_branches, ICON_FA_CODE_BRANCH,
"Create local branch", "Branch creation is not wired yet");
branch_section(ICON_FA_CLOUD " REMOTE", repo().remote_branches, ICON_FA_CLOUD,
"Add remote", "Remote creation is not wired yet");
section(ICON_FA_DIAGRAM_PROJECT " WORKTREES", repo().worktrees, ICON_FA_COMPUTER,
"Add worktree", "Worktree creation is not wired yet");
section(ICON_FA_CUBES " SUBMODULES", repo().submodules, ICON_FA_CUBES,
"Add submodule", "Submodule creation is not wired yet");
ImGui::EndChild();
}