mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
302 lines
9.2 KiB
Rust
302 lines
9.2 KiB
Rust
use std::f32;
|
|
|
|
use crate::math::MintVec2;
|
|
use crate::window::WindowFlags;
|
|
use crate::Ui;
|
|
use crate::{sys, Id};
|
|
|
|
/// Builder for a child window
|
|
#[derive(Copy, Clone, Debug)]
|
|
#[must_use]
|
|
pub struct ChildWindow<'ui> {
|
|
ui: &'ui Ui,
|
|
id: u32,
|
|
flags: WindowFlags,
|
|
size: [f32; 2],
|
|
content_size: [f32; 2],
|
|
focused: bool,
|
|
bg_alpha: f32,
|
|
border: bool,
|
|
}
|
|
|
|
impl<'ui> ChildWindow<'ui> {
|
|
/// Creates a new child window builder with the str.
|
|
#[doc(alias = "BeginChildID")]
|
|
#[deprecated(since = "0.9.0", note = "use ui.child_window(...) instead")]
|
|
pub fn new(ui: &'ui Ui, name: impl AsRef<str>) -> Self {
|
|
let id = ui.new_id_str(name);
|
|
Self::new_id(ui, id)
|
|
}
|
|
|
|
/// Creates a new child window builder with the given imgui id.
|
|
#[doc(alias = "BeginChildID")]
|
|
pub fn new_id(ui: &'ui Ui, id: Id) -> Self {
|
|
Self {
|
|
ui,
|
|
id: id.0,
|
|
flags: WindowFlags::empty(),
|
|
size: [0.0, 0.0],
|
|
content_size: [0.0, 0.0],
|
|
focused: false,
|
|
bg_alpha: f32::NAN,
|
|
border: false,
|
|
}
|
|
}
|
|
|
|
/// Replace current window flags with the given value
|
|
#[inline]
|
|
pub fn flags(mut self, flags: WindowFlags) -> Self {
|
|
self.flags = flags;
|
|
self
|
|
}
|
|
/// Sets the child window size.
|
|
///
|
|
/// For each independent axis of size:
|
|
///
|
|
/// - `> 0.0`: fixed size
|
|
/// - `= 0.0`: use remaining host window size
|
|
/// - `< 0.0`: use remaining host window size minus abs(size)
|
|
#[inline]
|
|
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
|
|
self.size = size.into().into();
|
|
self
|
|
}
|
|
/// Sets the window content size, which can be used to enforce scrollbars.
|
|
///
|
|
/// Does not include window decorations (title bar, menu bar, etc.). Set one of the values to
|
|
/// 0.0 to leave the size automatic.
|
|
#[inline]
|
|
#[doc(alias = "SetNextWindowContentSize")]
|
|
pub fn content_size(mut self, size: impl Into<MintVec2>) -> Self {
|
|
self.content_size = size.into().into();
|
|
self
|
|
}
|
|
/// Sets the window focused state, which can be used to bring the window to front
|
|
#[inline]
|
|
#[doc(alias = "SetNextWindwowFocus")]
|
|
pub fn focused(mut self, focused: bool) -> Self {
|
|
self.focused = focused;
|
|
self
|
|
}
|
|
/// Sets the background color alpha value.
|
|
///
|
|
/// See also `draw_background`
|
|
#[inline]
|
|
#[doc(alias = "SetNextWindowContentBgAlpha")]
|
|
pub fn bg_alpha(mut self, bg_alpha: f32) -> Self {
|
|
self.bg_alpha = bg_alpha;
|
|
self
|
|
}
|
|
/// Enables/disables the child window border.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn border(mut self, border: bool) -> Self {
|
|
self.border = border;
|
|
self
|
|
}
|
|
/// Enables/disables moving the window when child window is dragged.
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn movable(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_MOVE, !value);
|
|
self
|
|
}
|
|
/// Enables/disables scrollbars (scrolling is still possible with the mouse or
|
|
/// programmatically).
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn scroll_bar(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_SCROLLBAR, !value);
|
|
self
|
|
}
|
|
/// Enables/disables vertical scrolling with the mouse wheel.
|
|
///
|
|
/// Enabled by default.
|
|
/// When enabled, child windows forward the mouse wheel to the parent unless `NO_SCROLLBAR`
|
|
/// is also set.
|
|
#[inline]
|
|
pub fn scrollable(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_SCROLL_WITH_MOUSE, !value);
|
|
self
|
|
}
|
|
/// Enables/disables resizing the window to its content on every frame.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn always_auto_resize(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::ALWAYS_AUTO_RESIZE, value);
|
|
self
|
|
}
|
|
/// Enables/disables drawing of background color and outside border.
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn draw_background(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_BACKGROUND, !value);
|
|
self
|
|
}
|
|
/// Enables/disables catching mouse input.
|
|
///
|
|
/// Enabled by default.
|
|
/// Note: Hovering test will pass through when disabled
|
|
#[inline]
|
|
pub fn mouse_inputs(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_MOUSE_INPUTS, !value);
|
|
self
|
|
}
|
|
/// Enables/disables the menu bar.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn menu_bar(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::MENU_BAR, value);
|
|
self
|
|
}
|
|
/// Enables/disables the horizontal scrollbar.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn horizontal_scrollbar(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::HORIZONTAL_SCROLLBAR, value);
|
|
self
|
|
}
|
|
/// Enables/disables taking focus when transitioning from hidden to visible state.
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn focus_on_appearing(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_FOCUS_ON_APPEARING, !value);
|
|
self
|
|
}
|
|
/// Enables/disables bringing the window to front when taking focus (e.g. clicking it or
|
|
/// programmatically giving it focus).
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn bring_to_front_on_focus(mut self, value: bool) -> Self {
|
|
self.flags
|
|
.set(WindowFlags::NO_BRING_TO_FRONT_ON_FOCUS, !value);
|
|
self
|
|
}
|
|
/// When enabled, forces the vertical scrollbar to render regardless of the content size.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn always_vertical_scrollbar(mut self, value: bool) -> Self {
|
|
self.flags
|
|
.set(WindowFlags::ALWAYS_VERTICAL_SCROLLBAR, value);
|
|
self
|
|
}
|
|
/// When enabled, forces the horizontal scrollbar to render regardless of the content size.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn always_horizontal_scrollbar(mut self, value: bool) -> Self {
|
|
self.flags
|
|
.set(WindowFlags::ALWAYS_HORIZONTAL_SCROLLBAR, value);
|
|
self
|
|
}
|
|
/// When enabled, ensures child windows without border use `style.window_padding`.
|
|
///
|
|
/// Disabled by default.
|
|
#[inline]
|
|
pub fn always_use_window_padding(mut self, value: bool) -> Self {
|
|
self.flags
|
|
.set(WindowFlags::ALWAYS_USE_WINDOW_PADDING, value);
|
|
self
|
|
}
|
|
/// Enables/disables gamepad/keyboard navigation within the window.
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn nav_inputs(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_NAV_INPUTS, !value);
|
|
self
|
|
}
|
|
/// Enables/disables focusing toward this window with gamepad/keyboard navigation (e.g.
|
|
/// CTRL+TAB).
|
|
///
|
|
/// Enabled by default.
|
|
#[inline]
|
|
pub fn nav_focus(mut self, value: bool) -> Self {
|
|
self.flags.set(WindowFlags::NO_NAV_FOCUS, !value);
|
|
self
|
|
}
|
|
/// Disable gamepad/keyboard navigation and focusing.
|
|
///
|
|
/// Shorthand for
|
|
/// ```text
|
|
/// .nav_inputs(false)
|
|
/// .nav_focus(false)
|
|
/// ```
|
|
#[inline]
|
|
pub fn no_nav(mut self) -> Self {
|
|
self.flags |= WindowFlags::NO_NAV;
|
|
self
|
|
}
|
|
/// Don't handle input.
|
|
///
|
|
/// Shorthand for
|
|
/// ```text
|
|
/// .mouse_inputs(false)
|
|
/// .nav_inputs(false)
|
|
/// .nav_focus(false)
|
|
/// ```
|
|
#[inline]
|
|
pub fn no_inputs(mut self) -> Self {
|
|
self.flags |= WindowFlags::NO_INPUTS;
|
|
self
|
|
}
|
|
/// Creates a child window and starts append to it.
|
|
///
|
|
/// Returns `Some(ChildWindowToken)` if the window is visible. After content has been
|
|
/// rendered, the token must be ended by calling `.end()`.
|
|
///
|
|
/// Returns `None` if the window is not visible and no content should be rendered.
|
|
pub fn begin(self) -> Option<ChildWindowToken<'ui>> {
|
|
if self.content_size[0] != 0.0 || self.content_size[1] != 0.0 {
|
|
unsafe { sys::igSetNextWindowContentSize(self.content_size.into()) };
|
|
}
|
|
if self.focused {
|
|
unsafe { sys::igSetNextWindowFocus() };
|
|
}
|
|
if self.bg_alpha.is_finite() {
|
|
unsafe { sys::igSetNextWindowBgAlpha(self.bg_alpha) };
|
|
}
|
|
let should_render = unsafe {
|
|
sys::igBeginChild_ID(
|
|
self.id,
|
|
self.size.into(),
|
|
self.border,
|
|
self.flags.bits() as i32,
|
|
)
|
|
};
|
|
if should_render {
|
|
Some(ChildWindowToken::new(self.ui))
|
|
} else {
|
|
unsafe { sys::igEndChild() };
|
|
None
|
|
}
|
|
}
|
|
/// Creates a child window and runs a closure to construct the contents.
|
|
/// Returns the result of the closure, if it is called.
|
|
///
|
|
/// Note: the closure is not called if no window content is visible (e.g. window is collapsed
|
|
/// or fully clipped).
|
|
pub fn build<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
|
self.begin().map(|_window| f())
|
|
}
|
|
}
|
|
|
|
create_token!(
|
|
/// Tracks a child window that can be ended by calling `.end()`
|
|
/// or by dropping
|
|
pub struct ChildWindowToken<'ui>;
|
|
|
|
/// Ends a window
|
|
drop { sys::igEndChild() }
|
|
);
|