From 37adc371e8ef49931c78d6e1030fbb0f23734c44 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 13 Jul 2019 01:24:08 +0300 Subject: [PATCH] Add most missing utility functions --- CHANGELOG.markdown | 1 + src/legacy.rs | 58 ++++---------------- src/lib.rs | 65 +++------------------- src/utils.rs | 132 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 104 deletions(-) create mode 100644 src/utils.rs diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 2c97afd..934176b 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -6,6 +6,7 @@ - Window scrolling API - Full support for the column API +- Almost all small utility functions from upstream API ### Changed diff --git a/src/legacy.rs b/src/legacy.rs index e67e106..d9cc395 100644 --- a/src/legacy.rs +++ b/src/legacy.rs @@ -5,7 +5,7 @@ use std::os::raw::c_int; use crate::string::ImStr; use crate::widget::color_editors::*; use crate::widget::progress_bar::ProgressBar; -use crate::window::{Window, WindowFlags}; +use crate::window::{Window, WindowFlags, WindowFocusedFlags}; use crate::{Id, Ui}; #[deprecated(since = "0.2.0", note = "use ColorEditFlags instead")] @@ -105,50 +105,6 @@ bitflags!( } ); -bitflags!( - /// Flags for window focus checks - #[repr(C)] - pub struct ImGuiFocusedFlags: c_int { - /// Return true if any children of the window is focused - const ChildWindows = 1; - /// Test from root window (top most parent of the current hierarchy) - const RootWindow = 1 << 1; - /// Return true if any window is focused - const AnyWindow = 1 << 2; - - const RootAndChildWindows = - ImGuiFocusedFlags::RootWindow.bits | ImGuiFocusedFlags::ChildWindows.bits; - } -); - -bitflags!( - /// Flags for hover checks - #[repr(C)] - pub struct ImGuiHoveredFlags: c_int { - /// Window hover checks only: Return true if any children of the window is hovered - const ChildWindows = 1; - /// Window hover checks only: Test from root window (top most parent of the current hierarchy) - const RootWindow = 1 << 1; - /// Window hover checks only: Return true if any window is hovered - const AnyWindow = 1 << 2; - /// Return true even if a popup window is normally blocking access to this item/window - const AllowWhenBlockedByPopup = 1 << 3; - /// Return true even if an active item is blocking access to this item/window. Useful for - /// Drag and Drop patterns. - const AllowWhenBlockedByActiveItem = 1 << 5; - /// Return true even if the position is overlapped by another window - const AllowWhenOverlapped = 1 << 6; - /// Return true even if the item is disabled - const AllowWhenDisabled = 1 << 7; - - const RectOnly = ImGuiHoveredFlags::AllowWhenBlockedByPopup.bits - | ImGuiHoveredFlags::AllowWhenBlockedByActiveItem.bits - | ImGuiHoveredFlags::AllowWhenOverlapped.bits; - const RootAndChildWindows = ImGuiFocusedFlags::RootWindow.bits - | ImGuiFocusedFlags::ChildWindows.bits; - } -); - bitflags!( /// Flags for text inputs #[repr(C)] @@ -291,14 +247,14 @@ impl<'ui> Ui<'ui> { note = "use Ui::is_window_focused(WindowFlags::RootWindow) instead" )] pub fn is_root_window_focused(&self) -> bool { - unsafe { sys::igIsWindowFocused(ImGuiFocusedFlags::RootWindow.bits()) } + unsafe { sys::igIsWindowFocused(WindowFocusedFlags::ROOT_WINDOW.bits() as i32) } } #[deprecated( since = "0.2.0", note = "use Ui::is_window_focused(WindowFlags::ChildWindows) instead" )] pub fn is_child_window_focused(&self) -> bool { - unsafe { sys::igIsWindowFocused(ImGuiFocusedFlags::ChildWindows.bits()) } + unsafe { sys::igIsWindowFocused(WindowFocusedFlags::CHILD_WINDOWS.bits() as i32) } } } @@ -382,3 +338,11 @@ impl<'ui> Ui<'ui> { f(); } } + +impl<'ui> Ui<'ui> { + #[deprecated(since = "0.2.0", note = "use Ui::item_rect_size instead")] + pub fn get_item_rect_size(&self) -> [f32; 2] { + let size = unsafe { sys::igGetItemRectSize_nonUDT2() }; + size.into() + } +} diff --git a/src/lib.rs b/src/lib.rs index 9cd9be5..d37472f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,7 @@ pub use self::stacks::*; pub use self::string::*; pub use self::style::*; pub use self::trees::{CollapsingHeader, TreeNode}; +pub use self::utils::*; pub use self::widget::color_editors::*; pub use self::widget::progress_bar::*; pub use self::window::child_window::*; @@ -73,6 +74,7 @@ mod style; #[cfg(test)] mod test; mod trees; +mod utils; mod widget; mod window; mod window_draw_list; @@ -91,9 +93,15 @@ fn test_version() { } impl Context { + /// Returns the global imgui-rs time. + /// + /// Incremented by Io::delta_time every frame. pub fn time(&self) -> f64 { unsafe { sys::igGetTime() } } + /// Returns the global imgui-rs frame count. + /// + /// Incremented by 1 every frame. pub fn frame_count(&self) -> i32 { unsafe { sys::igGetFrameCount() } } @@ -130,19 +138,6 @@ impl<'ui> Ui<'ui> { pub fn clone_style(&self) -> Style { *self.ctx.style() } - /// Returns a single style color from the user interface style. - /// - /// Use this function if you need to access the colors, but don't want to clone the entire - /// style object. - pub fn style_color(&self, style_color: StyleColor) -> [f32; 4] { - self.ctx.style()[style_color] - } - pub fn time(&self) -> f64 { - unsafe { sys::igGetTime() } - } - pub fn frame_count(&self) -> i32 { - unsafe { sys::igGetFrameCount() } - } /// Renders the frame and returns a reference to the resulting draw data pub fn render(self) -> &'ui DrawData { unsafe { @@ -668,50 +663,6 @@ impl<'ui> Ui<'ui> { } } -impl<'ui> Ui<'ui> { - /// Get previously drawn item's size - pub fn get_item_rect_size(&self) -> [f32; 2] { - let size = unsafe { sys::igGetItemRectSize_nonUDT2() }; - size.into() - } -} - -/// # Utilities -impl<'ui> Ui<'ui> { - /// Returns `true` if the last item is being hovered by the mouse. - /// - /// # Examples - /// - /// ``` - /// # use imgui::*; - /// fn user_interface(ui: &Ui) { - /// ui.text("Hover over me"); - /// let is_hover_over_me_text_hovered = ui.is_item_hovered(); - /// } - /// # fn main() { - /// # } - /// ``` - pub fn is_item_hovered(&self) -> bool { - unsafe { sys::igIsItemHovered(ImGuiHoveredFlags::empty().bits()) } - } - - pub fn is_item_hovered_with_flags(&self, flags: ImGuiHoveredFlags) -> bool { - unsafe { sys::igIsItemHovered(flags.bits()) } - } - - /// Returns `true` if the last item is being active. - pub fn is_item_active(&self) -> bool { - unsafe { sys::igIsItemActive() } - } - - /// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. - pub fn set_item_allow_overlap(&self) { - unsafe { - sys::igSetItemAllowOverlap(); - } - } -} - /// # Draw list for custom drawing impl<'ui> Ui<'ui> { /// Get access to drawing API diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..a82dd0b --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,132 @@ +use bitflags::bitflags; + +use crate::input::mouse::MouseButton; +use crate::style::StyleColor; +use crate::sys; +use crate::Ui; + +bitflags! { + /// Item hover check option flags + #[repr(transparent)] + pub struct ItemHoveredFlags: u32 { + /// Return true even if a popup window is blocking access to this item + const ALLOW_WHEN_BLOCKED_BY_POPUP = sys::ImGuiHoveredFlags_AllowWhenBlockedByPopup; + /// Return true even if an active item is blocking access to this item + const ALLOW_WHEN_BLOCKED_BY_ACTIVE_ITEM = sys::ImGuiHoveredFlags_AllowWhenBlockedByActiveItem; + /// Return true even if the position is overlapped by another window + const ALLOW_WHEN_OVERLAPPED = sys::ImGuiHoveredFlags_AllowWhenOverlapped; + /// Return true even if the item is disabled + const ALLOW_WHEN_DISABLED = sys::ImGuiHoveredFlags_AllowWhenDisabled; + const RECT_ONLY = sys::ImGuiHoveredFlags_RectOnly; + } +} + +/// # Item/widget utilities +impl<'ui> Ui<'ui> { + /// Returns `true` if the last item is hovered + pub fn is_item_hovered(&self) -> bool { + unsafe { sys::igIsItemHovered(0) } + } + /// Returns `true` if the last item is hovered based on the given flags + pub fn is_item_hovered_with_flags(&self, flags: ItemHoveredFlags) -> bool { + unsafe { sys::igIsItemHovered(flags.bits() as i32) } + } + /// Returns `true` if the last item is active + pub fn is_item_active(&self) -> bool { + unsafe { sys::igIsItemActive() } + } + /// Returns `true` if the last item is focused for keyboard/gamepad navigation + pub fn is_item_focused(&self) -> bool { + unsafe { sys::igIsItemFocused() } + } + /// Returns `true` if the last item is being clicked + pub fn is_item_clicked(&self, button: MouseButton) -> bool { + unsafe { sys::igIsItemClicked(button as i32) } + } + /// Returns `true` if the last item is visible + pub fn is_item_visible(&self) -> bool { + unsafe { sys::igIsItemVisible() } + } + /// Returns `true` if the last item modified its underlying value this frame or was pressed + pub fn is_item_edited(&self) -> bool { + unsafe { sys::igIsItemEdited() } + } + /// Returns `true` if the last item was just made active + pub fn is_item_activated(&self) -> bool { + unsafe { sys::igIsItemActivated() } + } + /// Returns `true` if the last item was just made inactive + pub fn is_item_deactivated(&self) -> bool { + unsafe { sys::igIsItemDeactivated() } + } + /// Returns `true` if the last item was just made inactive and made a value change when it was + /// active + pub fn is_item_deactivated_after_edit(&self) -> bool { + unsafe { sys::igIsItemDeactivatedAfterEdit() } + } + /// Returns `true` if any item is hovered + pub fn is_any_item_hovered(&self) -> bool { + unsafe { sys::igIsAnyItemHovered() } + } + /// Returns `true` if any item is active + pub fn is_any_item_active(&self) -> bool { + unsafe { sys::igIsAnyItemActive() } + } + /// Returns `true` if any item is focused + pub fn is_any_item_focused(&self) -> bool { + unsafe { sys::igIsAnyItemFocused() } + } + /// Returns the upper-left bounding rectangle of the last item (in screen coordinates) + pub fn item_rect_min(&self) -> [f32; 2] { + unsafe { sys::igGetItemRectMin_nonUDT2().into() } + } + /// Returns the lower-right bounding rectangle of the last item (in screen coordinates) + pub fn item_rect_max(&self) -> [f32; 2] { + unsafe { sys::igGetItemRectMax_nonUDT2().into() } + } + /// Returns the size of the last item + pub fn item_rect_size(&self) -> [f32; 2] { + unsafe { sys::igGetItemRectSize_nonUDT2().into() } + } + /// Allows the last item to be overlapped by a subsequent item. + /// + /// Both may be activated during the same frame before the later one takes priority. + pub fn set_item_allow_overlap(&self) { + unsafe { sys::igSetItemAllowOverlap() }; + } + /// Makes the last item the default focused item of the window + pub fn set_item_default_focus(&self) { + unsafe { sys::igSetItemDefaultFocus() }; + } +} + +/// # Miscellaneous utilities +impl<'ui> Ui<'ui> { + /// Returns `true` if the rectangle (of given size, starting from cursor position) is visible + pub fn is_cursor_rect_visible(&self, size: [f32; 2]) -> bool { + unsafe { sys::igIsRectVisible(size.into()) } + } + /// Returns `true` if the rectangle (in screen coordinates) is visible + pub fn is_rect_visible(&self, rect_min: [f32; 2], rect_max: [f32; 2]) -> bool { + unsafe { sys::igIsRectVisibleVec2(rect_min.into(), rect_max.into()) } + } + /// Returns the global imgui-rs time. + /// + /// Incremented by Io::delta_time every frame. + pub fn time(&self) -> f64 { + unsafe { sys::igGetTime() } + } + /// Returns the global imgui-rs frame count. + /// + /// Incremented by 1 every frame. + pub fn frame_count(&self) -> i32 { + unsafe { sys::igGetFrameCount() } + } + /// Returns a single style color from the user interface style. + /// + /// Use this function if you need to access the colors, but don't want to clone the entire + /// style object. + pub fn style_color(&self, style_color: StyleColor) -> [f32; 4] { + self.ctx.style()[style_color] + } +}