#include "tools/cabana/ui/widgets/tabbar.h" #include #include #include "tools/cabana/ui/widgets/scrollabletabbar.h" int TabBar::addTab(const std::string &text) { tabs_.push_back({text, 0, next_id_++}); int index = count() - 1; if (current_index_ == -1) { current_index_ = index; select_current_ = true; currentChanged(index); } return index; } void TabBar::setCurrentIndex(int index) { if (index == current_index_ || index < -1 || index >= count()) return; current_index_ = index; select_current_ = true; currentChanged(index); } int TabBar::tabAt(const ImVec2 &pos) const { for (int i = 0; i < count(); ++i) { if (tabs_[i].rect.Contains(pos)) return i; } return -1; } void TabBar::removeTab(int index) { tabs_.erase(tabs_.begin() + index); if (index == current_index_) { current_index_ = count() ? std::min(index, count() - 1) : -1; select_current_ = true; currentChanged(current_index_); } else if (index < current_index_) { --current_index_; } } void TabBar::moveTab(int from, int to) { if (from == to || from < 0 || from >= count() || to < 0 || to >= count()) return; const int current_id = current_index_ >= 0 ? tabs_[current_index_].id : -1; Tab tab = std::move(tabs_[from]); tabs_.erase(tabs_.begin() + from); tabs_.insert(tabs_.begin() + to, std::move(tab)); for (int i = 0; i < count(); ++i) { if (tabs_[i].id == current_id) current_index_ = i; } select_current_ = true; } void TabBar::draw() { if (auto_hide_ && count() < 2) return; ImGui::PushID(this); if (!(scroll_buttons_ ? beginScrollableTabBar("##tabbar", ImGuiTabBarFlags_NoTooltip) : ImGui::BeginTabBar("##tabbar", ImGuiTabBarFlags_NoTooltip))) { ImGui::PopID(); return; } ImGuiStyle &style = ImGui::GetStyle(); const float close_button_min_width = tabs_closable_ ? std::exchange(style.TabCloseButtonMinWidthUnselected, -1.0f) : 0.0f; const bool select_current = std::exchange(select_current_, false); int close_index = -1; for (int i = 0; i < count(); ++i) { bool open = true; const std::string label = tabs_[i].text + "###tab" + std::to_string(tabs_[i].id); const ImGuiTabItemFlags flags = (select_current && i == current_index_) ? ImGuiTabItemFlags_SetSelected : 0; if (ImGui::BeginTabItem(label.c_str(), tabs_closable_ ? &open : nullptr, flags)) { if (!select_current && i != current_index_) { current_index_ = i; currentChanged(i); } ImGui::EndTabItem(); } tabs_[i].rect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); if (!tabs_[i].tooltip.empty()) ImGui::SetItemTooltip("%s", tabs_[i].tooltip.c_str()); tabContextMenu(i); if (!open) close_index = i; } if (tabs_closable_) style.TabCloseButtonMinWidthUnselected = close_button_min_width; scroll_buttons_ ? endScrollableTabBar() : ImGui::EndTabBar(); ImGui::PopID(); if (close_index >= 0) tabCloseRequested(close_index); }