Files
IQ.Pilot/iqpilot/tools/cabana/ui/widgets/tabbar.cc
2026-09-02 16:46:45 -05:00

93 lines
2.9 KiB
C++

#include "tools/cabana/ui/widgets/tabbar.h"
#include <algorithm>
#include <utility>
#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);
}