use crate::sys;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
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_retain(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_retain(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_retain(bits))
}
}