use crate::imgui::string::ImStr;
use crate::imgui::Ui;
use bitflags::bitflags;
use std::ptr;
bitflags! {
#[repr(transparent)]
pub struct TabBarFlags: u32 {
const REORDERABLE = crate::imgui_sys::ImGuiTabBarFlags_Reorderable;
const AUTO_SELECT_NEW_TABS = crate::imgui_sys::ImGuiTabBarFlags_AutoSelectNewTabs;
const TAB_LIST_POPUP_BUTTON = crate::imgui_sys::ImGuiTabBarFlags_TabListPopupButton;
const NO_CLOSE_WITH_MIDDLE_MOUSE_BUTTON = crate::imgui_sys::ImGuiTabBarFlags_NoCloseWithMiddleMouseButton;
const NO_TAB_LIST_SCROLLING_BUTTONS = crate::imgui_sys::ImGuiTabBarFlags_NoTabListScrollingButtons;
const NO_TOOLTIP = crate::imgui_sys::ImGuiTabBarFlags_NoTooltip;
const FITTING_POLICY_RESIZE_DOWN = crate::imgui_sys::ImGuiTabBarFlags_FittingPolicyResizeDown;
const FITTING_POLICY_SCROLL = crate::imgui_sys::ImGuiTabBarFlags_FittingPolicyScroll;
const FITTING_POLICY_MASK = crate::imgui_sys::ImGuiTabBarFlags_FittingPolicyMask_;
const FITTING_POLICY_DEFAULT = crate::imgui_sys::ImGuiTabBarFlags_FittingPolicyDefault_;
}
}
bitflags! {
#[repr(transparent)]
pub struct TabItemFlags: u32 {
const UNSAVED_DOCUMENT = crate::imgui_sys::ImGuiTabItemFlags_UnsavedDocument;
const SET_SELECTED = crate::imgui_sys::ImGuiTabItemFlags_SetSelected;
const NO_CLOSE_WITH_MIDDLE_MOUSE_BUTTON = crate::imgui_sys::ImGuiTabItemFlags_NoCloseWithMiddleMouseButton;
const NO_PUSH_ID = crate::imgui_sys::ImGuiTabItemFlags_NoPushId;
const NO_TOOLTIP = crate::imgui_sys::ImGuiTabItemFlags_NoTooltip;
const NO_REORDER = crate::imgui_sys::ImGuiTabItemFlags_NoReorder;
const LEADING = crate::imgui_sys::ImGuiTabItemFlags_Leading;
const TRAILING = crate::imgui_sys::ImGuiTabItemFlags_Trailing;
}
}
pub struct TabBar<'a> {
id: &'a ImStr,
flags: TabBarFlags,
}
impl<'a> TabBar<'a> {
#[inline]
#[doc(alias = "BeginTabBar")]
pub const fn new(id: &'a ImStr) -> Self {
Self {
id,
flags: TabBarFlags::empty(),
}
}
#[inline]
pub fn reorderable(mut self, value: bool) -> Self {
self.flags.set(TabBarFlags::REORDERABLE, value);
self
}
#[inline]
pub fn flags(mut self, flags: TabBarFlags) -> Self {
self.flags = flags;
self
}
#[must_use]
pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option<TabBarToken<'ui>> {
let should_render =
unsafe { crate::imgui_sys::igBeginTabBar(self.id.as_ptr(), self.flags.bits() as i32) };
if should_render {
Some(TabBarToken::new(ui))
} else {
unsafe { crate::imgui_sys::igEndTabBar() };
None
}
}
pub fn build<T, F: FnOnce() -> T>(self, ui: &Ui<'_>, f: F) -> Option<T> {
self.begin(ui).map(|_tab| f())
}
}
create_token!(
pub struct TabBarToken<'ui>;
drop { crate::imgui_sys::igEndTabBar() }
);
pub struct TabItem<'a> {
name: &'a ImStr,
opened: Option<&'a mut bool>,
flags: TabItemFlags,
}
impl<'a> TabItem<'a> {
#[doc(alias = "BeginTabItem")]
pub fn new(name: &'a ImStr) -> Self {
Self {
name,
opened: None,
flags: TabItemFlags::empty(),
}
}
#[inline]
pub fn opened(mut self, opened: &'a mut bool) -> Self {
self.opened = Some(opened);
self
}
#[inline]
pub fn flags(mut self, flags: TabItemFlags) -> Self {
self.flags = flags;
self
}
#[must_use]
pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option<TabItemToken<'ui>> {
let should_render = unsafe {
crate::imgui_sys::igBeginTabItem(
self.name.as_ptr(),
self.opened
.map(|x| x as *mut bool)
.unwrap_or(ptr::null_mut()),
self.flags.bits() as i32,
)
};
if should_render {
Some(TabItemToken::new(ui))
} else {
None
}
}
pub fn build<T, F: FnOnce() -> T>(self, ui: &Ui<'_>, f: F) -> Option<T> {
self.begin(ui).map(|_tab| f())
}
}
create_token!(
pub struct TabItemToken<'ui>;
drop { crate::imgui_sys::igEndTabItem() }
);