dear_imgui_rs/widget/combo/
options.rs1use crate::sys;
2
3bitflags::bitflags! {
4 #[repr(transparent)]
9 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10 pub struct ComboBoxFlags: i32 {
11 const NONE = 0;
13 const POPUP_ALIGN_LEFT = sys::ImGuiComboFlags_PopupAlignLeft as i32;
15 }
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
20pub enum ComboBoxHeight {
21 Small,
23 Regular,
25 Large,
27 Largest,
29}
30
31impl ComboBoxHeight {
32 #[inline]
33 const fn raw(self) -> i32 {
34 match self {
35 Self::Small => sys::ImGuiComboFlags_HeightSmall as i32,
36 Self::Regular => sys::ImGuiComboFlags_HeightRegular as i32,
37 Self::Large => sys::ImGuiComboFlags_HeightLarge as i32,
38 Self::Largest => sys::ImGuiComboFlags_HeightLargest as i32,
39 }
40 }
41}
42
43#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
45pub enum ComboBoxPreviewMode {
46 #[default]
48 Preview,
49 PreviewNoArrowButton,
51 PreviewFit,
53 PreviewFitNoArrowButton,
55 NoPreview,
57}
58
59impl ComboBoxPreviewMode {
60 #[inline]
61 const fn raw(self) -> i32 {
62 match self {
63 Self::Preview => 0,
64 Self::PreviewNoArrowButton => sys::ImGuiComboFlags_NoArrowButton as i32,
65 Self::PreviewFit => sys::ImGuiComboFlags_WidthFitPreview as i32,
66 Self::PreviewFitNoArrowButton => {
67 sys::ImGuiComboFlags_WidthFitPreview as i32
68 | sys::ImGuiComboFlags_NoArrowButton as i32
69 }
70 Self::NoPreview => sys::ImGuiComboFlags_NoPreview as i32,
71 }
72 }
73}
74
75#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
78pub struct ComboBoxOptions {
79 pub flags: ComboBoxFlags,
80 pub height: Option<ComboBoxHeight>,
81 pub preview_mode: ComboBoxPreviewMode,
82}
83
84impl Default for ComboBoxOptions {
85 fn default() -> Self {
86 Self::new()
87 }
88}
89
90impl ComboBoxOptions {
91 pub const fn new() -> Self {
92 Self {
93 flags: ComboBoxFlags::NONE,
94 height: None,
95 preview_mode: ComboBoxPreviewMode::Preview,
96 }
97 }
98
99 pub fn flags(mut self, flags: ComboBoxFlags) -> Self {
100 self.flags = flags;
101 self
102 }
103
104 pub fn height(mut self, height: ComboBoxHeight) -> Self {
105 self.height = Some(height);
106 self
107 }
108
109 pub fn preview_mode(mut self, mode: ComboBoxPreviewMode) -> Self {
110 self.preview_mode = mode;
111 self
112 }
113
114 pub fn bits(self) -> i32 {
115 self.raw()
116 }
117
118 #[inline]
119 pub(crate) fn raw(self) -> i32 {
120 self.flags.bits() | self.height.map_or(0, ComboBoxHeight::raw) | self.preview_mode.raw()
121 }
122
123 #[inline]
124 pub(crate) fn validate(self, caller: &str) {
125 let unsupported_flags = self.flags.bits() & !ComboBoxFlags::all().bits();
126 assert!(
127 unsupported_flags == 0,
128 "{caller} received non-independent ImGuiComboFlags bits: 0x{unsupported_flags:X}"
129 );
130 let bits = self.raw();
131 let height_mask = sys::ImGuiComboFlags_HeightMask_ as i32;
132 let no_arrow_button = sys::ImGuiComboFlags_NoArrowButton as i32;
133 let no_preview = sys::ImGuiComboFlags_NoPreview as i32;
134 let width_fit_preview = sys::ImGuiComboFlags_WidthFitPreview as i32;
135 let supported = ComboBoxFlags::all().bits() | height_mask | combo_preview_mask();
136 let unsupported = bits & !supported;
137 assert!(
138 unsupported == 0,
139 "{caller} received unsupported ImGuiComboFlags bits: 0x{unsupported:X}"
140 );
141 assert!(
142 bits & (no_arrow_button | no_preview) != (no_arrow_button | no_preview),
143 "{caller} cannot combine NO_ARROW_BUTTON with NO_PREVIEW"
144 );
145 assert!(
146 bits & width_fit_preview == 0 || bits & no_preview == 0,
147 "{caller} cannot combine WIDTH_FIT_PREVIEW with NO_PREVIEW"
148 );
149 assert!(
150 (bits & height_mask).count_ones() <= 1,
151 "{caller} accepts at most one combo height policy"
152 );
153 }
154}
155
156#[inline]
157const fn combo_preview_mask() -> i32 {
158 (sys::ImGuiComboFlags_NoArrowButton
159 | sys::ImGuiComboFlags_NoPreview
160 | sys::ImGuiComboFlags_WidthFitPreview) as i32
161}
162
163impl From<ComboBoxFlags> for ComboBoxOptions {
164 fn from(flags: ComboBoxFlags) -> Self {
165 Self::new().flags(flags)
166 }
167}