refactor(toolbar): match labeled Git action layout

This commit is contained in:
2026-06-18 18:42:50 -05:00
parent da475f2608
commit 09011a6a4f

View File

@@ -468,14 +468,47 @@ void draw_details() {
ImGui::EndChild(); ImGui::EndChild();
} }
bool toolbar_action(const char* id, const char* icon, const char* tooltip) { bool toolbar_action(const char* id, const char* label, const char* icon, const char* tooltip,
bool enabled = true, bool dropdown = false, float logical_width = 58.0f) {
ImGui::PushID(id); ImGui::PushID(id);
const bool clicked = ImGui::Button(icon, {ui(36), ui(36)}); if (!enabled) ImGui::BeginDisabled();
const bool clicked = ImGui::InvisibleButton("##action", {ui(logical_width), ui(58.0f)});
const ImVec2 minimum = ImGui::GetItemRectMin();
const ImVec2 maximum = ImGui::GetItemRectMax();
ImDrawList* draw = ImGui::GetWindowDrawList();
if (enabled && ImGui::IsItemHovered())
draw->AddRectFilled(minimum, maximum, IM_COL32(55, 62, 74, 180), ui(3.0f));
const ImU32 text_color = enabled ? IM_COL32(215, 220, 229, 255) : IM_COL32(105, 111, 122, 255);
const ImVec2 label_size = ImGui::CalcTextSize(label);
const ImVec2 icon_size = ImGui::CalcTextSize(icon);
draw->AddText({minimum.x + (maximum.x - minimum.x - label_size.x) * 0.5f, minimum.y + ui(3.0f)},
text_color, label);
const float icon_x = minimum.x + (maximum.x - minimum.x - icon_size.x) * 0.5f - (dropdown ? ui(4.0f) : 0.0f);
draw->AddText({icon_x, minimum.y + ui(27.0f)}, text_color, icon);
if (dropdown)
draw->AddText({icon_x + icon_size.x + ui(8.0f), minimum.y + ui(25.0f)}, text_color, ICON_FA_CARET_DOWN);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) { if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
ImGui::BeginTooltip(); ImGui::BeginTooltip();
ImGui::TextUnformatted(tooltip); ImGui::TextUnformatted(tooltip);
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
if (!enabled) ImGui::EndDisabled();
ImGui::PopID();
return clicked;
}
bool toolbar_selector(const char* id, const char* label, const std::string& value,
float logical_width, bool trailing_arrow = false) {
ImGui::PushID(id);
const bool clicked = ImGui::InvisibleButton("##selector", {ui(logical_width), ui(58.0f)});
const ImVec2 minimum = ImGui::GetItemRectMin();
const ImVec2 maximum = ImGui::GetItemRectMax();
ImDrawList* draw = ImGui::GetWindowDrawList();
if (ImGui::IsItemHovered()) draw->AddRectFilled(minimum, maximum, IM_COL32(55, 62, 74, 150), ui(3.0f));
draw->AddText({minimum.x + ui(8), minimum.y + ui(3)}, IM_COL32(155, 164, 178, 255), label);
draw->AddText({minimum.x + ui(8), minimum.y + ui(27)}, IM_COL32(236, 239, 244, 255), value.c_str());
draw->AddText({maximum.x - ui(18), minimum.y + ui(27)}, IM_COL32(148, 156, 168, 255),
trailing_arrow ? ICON_FA_ANGLE_RIGHT : ICON_FA_CARET_DOWN);
ImGui::PopID(); ImGui::PopID();
return clicked; return clicked;
} }
@@ -695,36 +728,54 @@ void draw_app() {
return; return;
} }
ImGui::BeginChild("repo_toolbar", {-1, ui(56)}, ImGuiChildFlags_Borders); ImGui::BeginChild("repo_toolbar", {-1, ui(64)}, ImGuiChildFlags_Borders);
ImGui::TextDisabled("repository"); ImGui::SetCursorPos({ui(5), ui(2)});
ImGui::SameLine(ui(145)); ImGui::TextDisabled("branch"); if (toolbar_selector("repository", "repository", repo().name, 120.0f))
ImGui::SetCursorPosY(ui(26)); g_notice = "Use repository tabs to switch repositories";
ImGui::Text("%s", repo().name.c_str()); ImGui::SameLine(0, ui(3));
ImGui::SameLine(ui(145)); ImGui::SetCursorPosY(ui(28));
ImGui::SetNextItemWidth(ui(180)); ImGui::TextDisabled(ICON_FA_ANGLE_RIGHT);
if (ImGui::BeginCombo("##branch", repo().branch.c_str())) { ImGui::SameLine(0, ui(3));
for (const auto& branch : repo().local_branches) ImGui::Selectable(branch.c_str(), branch == repo().branch); ImGui::SetCursorPosY(ui(2));
ImGui::EndCombo(); if (toolbar_selector("branch", "branch", repo().branch, 120.0f)) ImGui::OpenPopup("branch_selector");
if (ImGui::BeginPopup("branch_selector")) {
for (const auto& branch : repo().local_branches) {
if (ImGui::MenuItem(branch.c_str(), nullptr, branch == repo().branch) && branch != repo().branch)
g_git_manager->checkoutBranch(repo(), branch, g_notice);
}
ImGui::EndPopup();
} }
constexpr int action_count = 6;
const float action_size = ui(36.0f);
const float action_spacing = ui(7.0f);
const float action_group_width = action_size * action_count + action_spacing * (action_count - 1);
const float centered_x = (ImGui::GetWindowWidth() - action_group_width) * 0.5f;
ImGui::SetCursorPos({std::max(ui(350.0f), centered_x), ui(10.0f)});
if (toolbar_action("pull", ICON_FA_DOWNLOAD, "Pull from remote")) g_notice = "Pull is not wired yet"; const float action_spacing = ui(3.0f);
const float action_group_width = ui(507.0f);
const float centered_x = (ImGui::GetWindowWidth() - action_group_width) * 0.5f;
ImGui::SetCursorPos({std::max(ui(300.0f), centered_x), ui(2.0f)});
if (toolbar_action("undo", "Undo", ICON_FA_ROTATE_LEFT, "Undo last Git action", true, false, 54))
g_notice = "Undo is not wired yet";
ImGui::SameLine(0, action_spacing); ImGui::SameLine(0, action_spacing);
if (toolbar_action("push", ICON_FA_UPLOAD, "Push to remote")) g_notice = "Push is not wired yet"; toolbar_action("redo", "Redo", ICON_FA_ROTATE_RIGHT, "Redo last Git action", false, false, 54);
ImGui::SameLine(0, action_spacing); ImGui::SameLine(0, action_spacing);
if (toolbar_action("branch", ICON_FA_CODE_BRANCH, "Create branch")) g_notice = "Branch creation is not wired yet"; if (toolbar_action("pull", "Pull", ICON_FA_DOWNLOAD, "Pull from remote", true, true, 58))
g_notice = "Pull is not wired yet";
ImGui::SameLine(0, action_spacing); ImGui::SameLine(0, action_spacing);
if (toolbar_action("stash", ICON_FA_BOX_ARCHIVE, "Stash changes")) g_notice = "Stash is not wired yet"; if (toolbar_action("push", "Push", ICON_FA_UPLOAD, "Push to remote", true, false, 58))
g_notice = "Push is not wired yet";
ImGui::SameLine(0, action_spacing); ImGui::SameLine(0, action_spacing);
if (toolbar_action("pop", ICON_FA_BOX_OPEN, "Pop latest stash")) g_notice = "Stash pop is not wired yet"; if (toolbar_action("branch_action", "Branch", ICON_FA_CODE_BRANCH, "Create branch", true, false, 64))
g_notice = "Branch creation is not wired yet";
ImGui::SameLine(0, action_spacing); ImGui::SameLine(0, action_spacing);
if (toolbar_action("refresh", ICON_FA_ROTATE, "Refresh repository")) toolbar_action("stash", "Stash", ICON_FA_BOX_ARCHIVE, "Stash changes", false, false, 58);
g_git_manager->reload(repo(), g_notice); ImGui::SameLine(0, action_spacing);
toolbar_action("pop", "Pop", ICON_FA_BOX_OPEN, "Pop latest stash", false, false, 54);
ImGui::SameLine(0, ui(5));
const ImVec2 divider = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddLine({divider.x, divider.y}, {divider.x, divider.y + ui(58)},
IM_COL32(82, 89, 103, 255), ui(1));
ImGui::Dummy({ui(5), ui(58)});
ImGui::SameLine(0, ui(5));
if (toolbar_action("terminal", "Terminal", ICON_FA_TERMINAL, "Open repository terminal", true, false, 76))
g_notice = "Terminal is not wired yet";
ImGui::EndChild(); ImGui::EndChild();
draw_sidebar(ui(g_sidebar_width)); draw_sidebar(ui(g_sidebar_width));