Skip to main content

dear_imgui_rs/widget/popup/
context.rs

1use crate::{MouseButton, sys};
2
3use super::PopupContextFlags;
4use super::flags::validate_popup_context_flags;
5
6/// Single mouse button used by popup context helpers.
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
8pub enum PopupContextMouseButton {
9    /// Open on left mouse release.
10    Left,
11    /// Open on right mouse release.
12    #[default]
13    Right,
14    /// Open on middle mouse release.
15    Middle,
16}
17
18impl PopupContextMouseButton {
19    #[inline]
20    const fn raw(self) -> i32 {
21        match self {
22            Self::Left => sys::ImGuiPopupFlags_MouseButtonLeft as i32,
23            Self::Right => sys::ImGuiPopupFlags_MouseButtonRight as i32,
24            Self::Middle => sys::ImGuiPopupFlags_MouseButtonMiddle as i32,
25        }
26    }
27}
28
29impl From<MouseButton> for PopupContextMouseButton {
30    fn from(button: MouseButton) -> Self {
31        match button {
32            MouseButton::Left => Self::Left,
33            MouseButton::Right => Self::Right,
34            MouseButton::Middle => Self::Middle,
35            MouseButton::Extra1 | MouseButton::Extra2 => {
36                panic!(
37                    "Dear ImGui popup context helpers only support left, right, and middle buttons"
38                )
39            }
40        }
41    }
42}
43
44/// Complete popup options assembled from independent flags and optional
45/// single mouse button.
46#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
47pub struct PopupContextOptions {
48    pub flags: PopupContextFlags,
49    pub mouse_button: PopupContextMouseButton,
50}
51
52impl PopupContextOptions {
53    pub const fn new() -> Self {
54        Self {
55            flags: PopupContextFlags::NONE,
56            mouse_button: PopupContextMouseButton::Right,
57        }
58    }
59
60    pub fn flags(mut self, flags: PopupContextFlags) -> Self {
61        self.flags = flags;
62        self
63    }
64
65    pub fn mouse_button(mut self, button: impl Into<PopupContextMouseButton>) -> Self {
66        self.mouse_button = button.into();
67        self
68    }
69
70    pub fn bits(self) -> i32 {
71        self.raw()
72    }
73
74    #[inline]
75    pub(crate) fn raw(self) -> i32 {
76        self.flags.raw() | self.mouse_button.raw()
77    }
78
79    #[inline]
80    pub(super) fn validate(self, caller: &str) {
81        validate_popup_context_flags(caller, self.flags);
82        assert!(
83            self.flags.bits() & (sys::ImGuiPopupFlags_MouseButtonMask_ as i32) == 0,
84            "{caller} received non-independent PopupContextFlags mouse-button bits"
85        );
86    }
87}
88
89impl Default for PopupContextOptions {
90    fn default() -> Self {
91        Self::new()
92    }
93}
94
95impl From<PopupContextFlags> for PopupContextOptions {
96    fn from(flags: PopupContextFlags) -> Self {
97        Self::new().flags(flags)
98    }
99}
100
101impl From<PopupContextMouseButton> for PopupContextOptions {
102    fn from(button: PopupContextMouseButton) -> Self {
103        Self::new().mouse_button(button)
104    }
105}
106
107impl From<MouseButton> for PopupContextOptions {
108    fn from(button: MouseButton) -> Self {
109        Self::new().mouse_button(button)
110    }
111}