use crate::sys;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub mod button;
pub mod color;
pub mod combo;
pub mod drag;
pub mod image;
pub mod input;
pub mod list_box;
pub mod menu;
pub mod misc;
pub mod multi_select;
pub mod plot;
pub mod popup;
pub mod progress;
pub mod selectable;
pub mod slider;
pub mod tab;
pub mod table;
pub mod text;
pub mod tooltip;
pub mod tree;
pub use popup::PopupFlags;
pub use table::{TableBgTarget, TableBuilder, TableColumnSetup};
pub use self::button::*;
pub use self::color::*;
pub use self::combo::*;
pub use self::drag::*;
pub use self::image::*;
pub use self::input::*;
pub use self::list_box::*;
pub use self::menu::*;
pub use self::misc::*;
pub use self::multi_select::*;
pub use self::plot::*;
pub use self::popup::*;
pub use self::progress::*;
pub use self::selectable::*;
pub use self::slider::*;
pub use self::tab::*;
pub use self::table::*;
pub use self::tooltip::*;
pub use self::tree::*;
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TreeNodeFlags: i32 {
const NONE = 0;
const SELECTED = sys::ImGuiTreeNodeFlags_Selected as i32;
const FRAMED = sys::ImGuiTreeNodeFlags_Framed as i32;
const ALLOW_ITEM_OVERLAP = sys::ImGuiTreeNodeFlags_AllowOverlap as i32;
const ALLOW_OVERLAP = sys::ImGuiTreeNodeFlags_AllowOverlap as i32;
const NO_TREE_PUSH_ON_OPEN = sys::ImGuiTreeNodeFlags_NoTreePushOnOpen as i32;
const NO_AUTO_OPEN_ON_LOG = sys::ImGuiTreeNodeFlags_NoAutoOpenOnLog as i32;
const DEFAULT_OPEN = sys::ImGuiTreeNodeFlags_DefaultOpen as i32;
const OPEN_ON_DOUBLE_CLICK = sys::ImGuiTreeNodeFlags_OpenOnDoubleClick as i32;
const OPEN_ON_ARROW = sys::ImGuiTreeNodeFlags_OpenOnArrow as i32;
const LEAF = sys::ImGuiTreeNodeFlags_Leaf as i32;
const BULLET = sys::ImGuiTreeNodeFlags_Bullet as i32;
const FRAME_PADDING = sys::ImGuiTreeNodeFlags_FramePadding as i32;
const SPAN_AVAIL_WIDTH = sys::ImGuiTreeNodeFlags_SpanAvailWidth as i32;
const SPAN_FULL_WIDTH = sys::ImGuiTreeNodeFlags_SpanFullWidth as i32;
const SPAN_LABEL_WIDTH = sys::ImGuiTreeNodeFlags_SpanLabelWidth as i32;
const LABEL_SPAN_ALL_COLUMNS = sys::ImGuiTreeNodeFlags_LabelSpanAllColumns as i32;
const NAV_LEFT_JUMPS_BACK_HERE = sys::ImGuiTreeNodeFlags_NavLeftJumpsToParent as i32;
const COLLAPSING_HEADER =
Self::FRAMED.bits() | Self::NO_TREE_PUSH_ON_OPEN.bits() | Self::NO_AUTO_OPEN_ON_LOG.bits();
const DRAW_LINES_NONE = sys::ImGuiTreeNodeFlags_DrawLinesNone as i32;
const DRAW_LINES_FULL = sys::ImGuiTreeNodeFlags_DrawLinesFull as i32;
const DRAW_LINES_TO_NODES = sys::ImGuiTreeNodeFlags_DrawLinesToNodes as i32;
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ComboBoxFlags: i32 {
const NONE = 0;
const POPUP_ALIGN_LEFT = sys::ImGuiComboFlags_PopupAlignLeft as i32;
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ComboBoxHeight {
Small,
Regular,
Large,
Largest,
}
impl ComboBoxHeight {
#[inline]
const fn raw(self) -> i32 {
match self {
Self::Small => sys::ImGuiComboFlags_HeightSmall as i32,
Self::Regular => sys::ImGuiComboFlags_HeightRegular as i32,
Self::Large => sys::ImGuiComboFlags_HeightLarge as i32,
Self::Largest => sys::ImGuiComboFlags_HeightLargest as i32,
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum ComboBoxPreviewMode {
#[default]
Preview,
PreviewNoArrowButton,
PreviewFit,
PreviewFitNoArrowButton,
NoPreview,
}
impl ComboBoxPreviewMode {
#[inline]
const fn raw(self) -> i32 {
match self {
Self::Preview => 0,
Self::PreviewNoArrowButton => sys::ImGuiComboFlags_NoArrowButton as i32,
Self::PreviewFit => sys::ImGuiComboFlags_WidthFitPreview as i32,
Self::PreviewFitNoArrowButton => {
sys::ImGuiComboFlags_WidthFitPreview as i32
| sys::ImGuiComboFlags_NoArrowButton as i32
}
Self::NoPreview => sys::ImGuiComboFlags_NoPreview as i32,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct ComboBoxOptions {
pub flags: ComboBoxFlags,
pub height: Option<ComboBoxHeight>,
pub preview_mode: ComboBoxPreviewMode,
}
impl Default for ComboBoxOptions {
fn default() -> Self {
Self::new()
}
}
impl ComboBoxOptions {
pub const fn new() -> Self {
Self {
flags: ComboBoxFlags::NONE,
height: None,
preview_mode: ComboBoxPreviewMode::Preview,
}
}
pub fn flags(mut self, flags: ComboBoxFlags) -> Self {
self.flags = flags;
self
}
pub fn height(mut self, height: ComboBoxHeight) -> Self {
self.height = Some(height);
self
}
pub fn preview_mode(mut self, mode: ComboBoxPreviewMode) -> Self {
self.preview_mode = mode;
self
}
pub fn bits(self) -> i32 {
self.raw()
}
#[inline]
pub(crate) fn raw(self) -> i32 {
self.flags.bits() | self.height.map_or(0, ComboBoxHeight::raw) | self.preview_mode.raw()
}
#[inline]
pub(crate) fn validate(self, caller: &str) {
let unsupported_flags = self.flags.bits() & !ComboBoxFlags::all().bits();
assert!(
unsupported_flags == 0,
"{caller} received non-independent ImGuiComboFlags bits: 0x{unsupported_flags:X}"
);
let bits = self.raw();
let height_mask = sys::ImGuiComboFlags_HeightMask_ as i32;
let no_arrow_button = sys::ImGuiComboFlags_NoArrowButton as i32;
let no_preview = sys::ImGuiComboFlags_NoPreview as i32;
let width_fit_preview = sys::ImGuiComboFlags_WidthFitPreview as i32;
let supported = ComboBoxFlags::all().bits() | height_mask | combo_preview_mask();
let unsupported = bits & !supported;
assert!(
unsupported == 0,
"{caller} received unsupported ImGuiComboFlags bits: 0x{unsupported:X}"
);
assert!(
bits & (no_arrow_button | no_preview) != (no_arrow_button | no_preview),
"{caller} cannot combine NO_ARROW_BUTTON with NO_PREVIEW"
);
assert!(
bits & width_fit_preview == 0 || bits & no_preview == 0,
"{caller} cannot combine WIDTH_FIT_PREVIEW with NO_PREVIEW"
);
assert!(
(bits & height_mask).count_ones() <= 1,
"{caller} accepts at most one combo height policy"
);
}
}
#[inline]
const fn combo_preview_mask() -> i32 {
(sys::ImGuiComboFlags_NoArrowButton
| sys::ImGuiComboFlags_NoPreview
| sys::ImGuiComboFlags_WidthFitPreview) as i32
}
impl From<ComboBoxFlags> for ComboBoxOptions {
fn from(flags: ComboBoxFlags) -> Self {
Self::new().flags(flags)
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TableFlags: i32 {
const NONE = 0;
const RESIZABLE = sys::ImGuiTableFlags_Resizable as i32;
const REORDERABLE = sys::ImGuiTableFlags_Reorderable as i32;
const HIDEABLE = sys::ImGuiTableFlags_Hideable as i32;
const SORTABLE = sys::ImGuiTableFlags_Sortable as i32;
const NO_SAVED_SETTINGS = sys::ImGuiTableFlags_NoSavedSettings as i32;
const CONTEXT_MENU_IN_BODY = sys::ImGuiTableFlags_ContextMenuInBody as i32;
const ROW_BG = sys::ImGuiTableFlags_RowBg as i32;
const BORDERS_INNER_H = sys::ImGuiTableFlags_BordersInnerH as i32;
const BORDERS_OUTER_H = sys::ImGuiTableFlags_BordersOuterH as i32;
const BORDERS_INNER_V = sys::ImGuiTableFlags_BordersInnerV as i32;
const BORDERS_OUTER_V = sys::ImGuiTableFlags_BordersOuterV as i32;
const BORDERS_H = Self::BORDERS_INNER_H.bits() | Self::BORDERS_OUTER_H.bits();
const BORDERS_V = Self::BORDERS_INNER_V.bits() | Self::BORDERS_OUTER_V.bits();
const BORDERS_INNER = Self::BORDERS_INNER_V.bits() | Self::BORDERS_INNER_H.bits();
const BORDERS_OUTER = Self::BORDERS_OUTER_V.bits() | Self::BORDERS_OUTER_H.bits();
const BORDERS = Self::BORDERS_INNER.bits() | Self::BORDERS_OUTER.bits();
const NO_BORDERS_IN_BODY = sys::ImGuiTableFlags_NoBordersInBody as i32;
const NO_BORDERS_IN_BODY_UNTIL_RESIZE = sys::ImGuiTableFlags_NoBordersInBodyUntilResize as i32;
const NO_HOST_EXTEND_X = sys::ImGuiTableFlags_NoHostExtendX as i32;
const NO_HOST_EXTEND_Y = sys::ImGuiTableFlags_NoHostExtendY as i32;
const NO_KEEP_COLUMNS_VISIBLE = sys::ImGuiTableFlags_NoKeepColumnsVisible as i32;
const PRECISE_WIDTHS = sys::ImGuiTableFlags_PreciseWidths as i32;
const NO_CLIP = sys::ImGuiTableFlags_NoClip as i32;
const PAD_OUTER_X = sys::ImGuiTableFlags_PadOuterX as i32;
const NO_PAD_OUTER_X = sys::ImGuiTableFlags_NoPadOuterX as i32;
const NO_PAD_INNER_X = sys::ImGuiTableFlags_NoPadInnerX as i32;
const SCROLL_X = sys::ImGuiTableFlags_ScrollX as i32;
const SCROLL_Y = sys::ImGuiTableFlags_ScrollY as i32;
const SORT_MULTI = sys::ImGuiTableFlags_SortMulti as i32;
const SORT_TRISTATE = sys::ImGuiTableFlags_SortTristate as i32;
const HIGHLIGHT_HOVERED_COLUMN = sys::ImGuiTableFlags_HighlightHoveredColumn as i32;
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TableSizingPolicy {
FixedFit,
FixedSame,
StretchProp,
StretchSame,
}
impl TableSizingPolicy {
#[inline]
const fn raw(self) -> i32 {
match self {
Self::FixedFit => sys::ImGuiTableFlags_SizingFixedFit as i32,
Self::FixedSame => sys::ImGuiTableFlags_SizingFixedSame as i32,
Self::StretchProp => sys::ImGuiTableFlags_SizingStretchProp as i32,
Self::StretchSame => sys::ImGuiTableFlags_SizingStretchSame as i32,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TableOptions {
pub flags: TableFlags,
pub sizing_policy: Option<TableSizingPolicy>,
}
impl Default for TableOptions {
fn default() -> Self {
Self::new()
}
}
impl TableOptions {
pub const fn new() -> Self {
Self {
flags: TableFlags::NONE,
sizing_policy: None,
}
}
pub fn flags(mut self, flags: TableFlags) -> Self {
self.flags = flags;
self
}
pub fn sizing_policy(mut self, policy: TableSizingPolicy) -> Self {
self.sizing_policy = Some(policy);
self
}
pub fn bits(self) -> i32 {
self.raw()
}
#[inline]
pub(crate) fn raw(self) -> i32 {
self.flags.bits() | self.sizing_policy.map_or(0, TableSizingPolicy::raw)
}
#[inline]
pub(crate) fn validate(self, caller: &str) {
let unsupported_flags = self.flags.bits() & !TableFlags::all().bits();
assert!(
unsupported_flags == 0,
"{caller} received non-independent ImGuiTableFlags bits: 0x{unsupported_flags:X}"
);
let bits = self.raw();
let sizing_mask = sys::ImGuiTableFlags_SizingMask_ as i32;
let supported = TableFlags::all().bits() | sizing_mask;
let unsupported = bits & !supported;
assert!(
unsupported == 0,
"{caller} received unsupported ImGuiTableFlags bits: 0x{unsupported:X}"
);
let sizing_policy = bits & sizing_mask;
assert!(
is_valid_table_sizing_policy(sizing_policy),
"{caller} received invalid table sizing policy bits: 0x{sizing_policy:X}"
);
}
}
#[inline]
const fn is_valid_table_sizing_policy(bits: i32) -> bool {
bits == 0
|| bits == TableSizingPolicy::FixedFit.raw()
|| bits == TableSizingPolicy::FixedSame.raw()
|| bits == TableSizingPolicy::StretchProp.raw()
|| bits == TableSizingPolicy::StretchSame.raw()
}
impl From<TableFlags> for TableOptions {
fn from(flags: TableFlags) -> Self {
Self::new().flags(flags)
}
}
#[cfg(feature = "serde")]
impl Serialize for TableFlags {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_i32(self.bits())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for TableFlags {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let bits = i32::deserialize(deserializer)?;
Ok(TableFlags::from_bits_truncate(bits))
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TableColumnFlags: i32 {
const NONE = 0;
const DISABLED = sys::ImGuiTableColumnFlags_Disabled as i32;
const DEFAULT_HIDE = sys::ImGuiTableColumnFlags_DefaultHide as i32;
const DEFAULT_SORT = sys::ImGuiTableColumnFlags_DefaultSort as i32;
const NO_RESIZE = sys::ImGuiTableColumnFlags_NoResize as i32;
const NO_REORDER = sys::ImGuiTableColumnFlags_NoReorder as i32;
const NO_HIDE = sys::ImGuiTableColumnFlags_NoHide as i32;
const NO_CLIP = sys::ImGuiTableColumnFlags_NoClip as i32;
const NO_SORT = sys::ImGuiTableColumnFlags_NoSort as i32;
const NO_SORT_ASCENDING = sys::ImGuiTableColumnFlags_NoSortAscending as i32;
const NO_SORT_DESCENDING = sys::ImGuiTableColumnFlags_NoSortDescending as i32;
const NO_HEADER_LABEL = sys::ImGuiTableColumnFlags_NoHeaderLabel as i32;
const NO_HEADER_WIDTH = sys::ImGuiTableColumnFlags_NoHeaderWidth as i32;
const PREFER_SORT_ASCENDING = sys::ImGuiTableColumnFlags_PreferSortAscending as i32;
const PREFER_SORT_DESCENDING = sys::ImGuiTableColumnFlags_PreferSortDescending as i32;
const ANGLED_HEADER = sys::ImGuiTableColumnFlags_AngledHeader as i32;
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TableColumnWidth {
Fixed(f32),
Stretch(f32),
}
impl TableColumnWidth {
pub const fn fixed(width: f32) -> Self {
Self::Fixed(width)
}
pub const fn stretch(weight: f32) -> Self {
Self::Stretch(weight)
}
#[inline]
pub(crate) const fn raw_flags(self) -> i32 {
match self {
Self::Fixed(_) => sys::ImGuiTableColumnFlags_WidthFixed as i32,
Self::Stretch(_) => sys::ImGuiTableColumnFlags_WidthStretch as i32,
}
}
#[inline]
pub(crate) const fn value(self) -> f32 {
match self {
Self::Fixed(value) | Self::Stretch(value) => value,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TableColumnIndent {
Enable,
Disable,
}
impl TableColumnIndent {
#[inline]
pub const fn bits(self) -> i32 {
self.raw_flags()
}
#[inline]
pub(crate) const fn raw_flags(self) -> i32 {
match self {
Self::Enable => sys::ImGuiTableColumnFlags_IndentEnable as i32,
Self::Disable => sys::ImGuiTableColumnFlags_IndentDisable as i32,
}
}
}
bitflags::bitflags! {
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct TableColumnStateFlags: i32 {
const NONE = 0;
const DISABLED = sys::ImGuiTableColumnFlags_Disabled as i32;
const DEFAULT_HIDE = sys::ImGuiTableColumnFlags_DefaultHide as i32;
const DEFAULT_SORT = sys::ImGuiTableColumnFlags_DefaultSort as i32;
const WIDTH_FIXED = sys::ImGuiTableColumnFlags_WidthFixed as i32;
const WIDTH_STRETCH = sys::ImGuiTableColumnFlags_WidthStretch as i32;
const NO_RESIZE = sys::ImGuiTableColumnFlags_NoResize as i32;
const NO_REORDER = sys::ImGuiTableColumnFlags_NoReorder as i32;
const NO_HIDE = sys::ImGuiTableColumnFlags_NoHide as i32;
const NO_CLIP = sys::ImGuiTableColumnFlags_NoClip as i32;
const NO_SORT = sys::ImGuiTableColumnFlags_NoSort as i32;
const NO_SORT_ASCENDING = sys::ImGuiTableColumnFlags_NoSortAscending as i32;
const NO_SORT_DESCENDING = sys::ImGuiTableColumnFlags_NoSortDescending as i32;
const NO_HEADER_LABEL = sys::ImGuiTableColumnFlags_NoHeaderLabel as i32;
const NO_HEADER_WIDTH = sys::ImGuiTableColumnFlags_NoHeaderWidth as i32;
const PREFER_SORT_ASCENDING = sys::ImGuiTableColumnFlags_PreferSortAscending as i32;
const PREFER_SORT_DESCENDING = sys::ImGuiTableColumnFlags_PreferSortDescending as i32;
const INDENT_ENABLE = sys::ImGuiTableColumnFlags_IndentEnable as i32;
const INDENT_DISABLE = sys::ImGuiTableColumnFlags_IndentDisable as i32;
const ANGLED_HEADER = sys::ImGuiTableColumnFlags_AngledHeader as i32;
const IS_ENABLED = sys::ImGuiTableColumnFlags_IsEnabled as i32;
const IS_VISIBLE = sys::ImGuiTableColumnFlags_IsVisible as i32;
const IS_SORTED = sys::ImGuiTableColumnFlags_IsSorted as i32;
const IS_HOVERED = sys::ImGuiTableColumnFlags_IsHovered as i32;
}
}
impl From<TableColumnFlags> for TableColumnStateFlags {
fn from(flags: TableColumnFlags) -> Self {
Self::from_bits_retain(flags.bits())
}
}
impl TableColumnFlags {
#[inline]
pub(crate) fn validate_for_setup(
self,
caller: &str,
width: Option<TableColumnWidth>,
indent: Option<TableColumnIndent>,
) {
let unsupported_flags = self.bits() & !TableColumnFlags::all().bits();
assert!(
unsupported_flags == 0,
"{caller} received non-independent ImGuiTableColumnFlags bits: 0x{unsupported_flags:X}"
);
let bits = self.bits()
| width.map_or(0, TableColumnWidth::raw_flags)
| indent.map_or(0, TableColumnIndent::raw_flags);
let width_mask = sys::ImGuiTableColumnFlags_WidthMask_ as i32;
let indent_mask = sys::ImGuiTableColumnFlags_IndentMask_ as i32;
let supported = TableColumnFlags::all().bits() | width_mask | indent_mask;
let unsupported = bits & !supported;
assert!(
unsupported == 0,
"{caller} received unsupported ImGuiTableColumnFlags bits: 0x{unsupported:X}"
);
assert!(
(bits & width_mask).count_ones() <= 1,
"{caller} accepts at most one table column width policy"
);
assert!(
(bits & indent_mask).count_ones() <= 1,
"{caller} accepts at most one table column indent policy"
);
}
}
#[cfg(feature = "serde")]
impl Serialize for TableColumnFlags {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_i32(self.bits())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for TableColumnFlags {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let bits = i32::deserialize(deserializer)?;
Ok(TableColumnFlags::from_bits_truncate(bits))
}
}
#[cfg(feature = "serde")]
impl Serialize for TableColumnStateFlags {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_i32(self.bits())
}
}
#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for TableColumnStateFlags {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let bits = i32::deserialize(deserializer)?;
Ok(TableColumnStateFlags::from_bits_truncate(bits))
}
}