use std::mem;
use std::os::raw::{c_char, c_void};
use std::ptr;
use std::thread;
use crate::imgui::context::Context;
use crate::imgui::fonts::atlas::FontId;
use crate::imgui::internal::RawCast;
use crate::imgui::style::{StyleColor, StyleVar};
use crate::imgui::{Id, Ui};
impl<'ui> Ui<'ui> {
#[doc(alias = "PushFont")]
pub fn push_font(&self, id: FontId) -> FontStackToken<'_> {
let fonts = self.fonts();
let font = fonts
.get_font(id)
.expect("Font atlas did not contain the given font");
unsafe { crate::imgui_sys::igPushFont(font.raw() as *const _ as *mut _) };
FontStackToken::new(self)
}
#[doc(alias = "PushStyleColorVec4")]
pub fn push_style_color(&self, style_color: StyleColor, color: [f32; 4]) -> ColorStackToken {
unsafe { crate::imgui_sys::igPushStyleColorVec4(style_color as i32, color.into()) };
ColorStackToken::new(self)
}
#[deprecated = "deprecated in 0.7.0. Use `push_style_color` multiple times for similar effect."]
pub fn push_style_colors<'a, I>(&self, style_colors: I) -> MultiColorStackToken
where
I: IntoIterator<Item = &'a (StyleColor, [f32; 4])>,
{
let mut count = 0;
for &(style_color, color) in style_colors {
unsafe { crate::imgui_sys::igPushStyleColorVec4(style_color as i32, color.into()) };
count += 1;
}
MultiColorStackToken {
count,
ctx: self.ctx,
}
}
#[doc(alias = "PushStyleVar")]
pub fn push_style_var(&self, style_var: StyleVar) -> StyleStackToken {
unsafe { push_style_var(style_var) };
StyleStackToken::new(self)
}
#[deprecated = "deprecated in 0.7.0. Use `push_style_var` multiple times for similar effect."]
pub fn push_style_vars<'a, I>(&self, style_vars: I) -> MultiStyleStackToken
where
I: IntoIterator<Item = &'a StyleVar>,
{
let mut count = 0;
for &style_var in style_vars {
unsafe { push_style_var(style_var) };
count += 1;
}
MultiStyleStackToken {
count,
ctx: self.ctx,
}
}
}
create_token!(
pub struct FontStackToken<'ui>;
drop { crate::imgui_sys::igPopFont() }
);
impl FontStackToken<'_> {
pub fn pop(self) {
self.end()
}
}
create_token!(
pub struct ColorStackToken<'ui>;
drop { crate::imgui_sys::igPopStyleColor(1) }
);
impl ColorStackToken<'_> {
pub fn pop(self) {
self.end()
}
}
#[must_use]
pub struct MultiColorStackToken {
count: usize,
ctx: *const Context,
}
impl MultiColorStackToken {
#[doc(alias = "PopStyleColor")]
pub fn pop(mut self, _: &Ui) {
self.ctx = ptr::null();
unsafe { crate::imgui_sys::igPopStyleColor(self.count as i32) };
}
}
impl Drop for MultiColorStackToken {
fn drop(&mut self) {
if !self.ctx.is_null() && !thread::panicking() {
panic!("A ColorStackToken was leaked. Did you call .pop()?");
}
}
}
create_token!(
pub struct StyleStackToken<'ui>;
drop { crate::imgui_sys::igPopStyleVar(1) }
);
impl StyleStackToken<'_> {
pub fn pop(self) {
self.end()
}
}
#[must_use]
pub struct MultiStyleStackToken {
count: usize,
ctx: *const Context,
}
impl MultiStyleStackToken {
#[doc(alias = "PopStyleVar")]
pub fn pop(mut self, _: &Ui) {
self.ctx = ptr::null();
unsafe { crate::imgui_sys::igPopStyleVar(self.count as i32) };
}
}
impl Drop for MultiStyleStackToken {
fn drop(&mut self) {
if !self.ctx.is_null() && !thread::panicking() {
panic!("A StyleStackToken was leaked. Did you call .pop()?");
}
}
}
#[inline]
unsafe fn push_style_var(style_var: StyleVar) {
use crate::imgui::style::StyleVar::*;
use crate::imgui::sys::{igPushStyleVarFloat, igPushStyleVarVec2};
match style_var {
Alpha(v) => igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_Alpha as i32, v),
WindowPadding(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_WindowPadding as i32,
v.into(),
),
WindowRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_WindowRounding as i32, v)
}
WindowBorderSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_WindowBorderSize as i32, v)
}
WindowMinSize(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_WindowMinSize as i32,
v.into(),
),
WindowTitleAlign(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_WindowTitleAlign as i32,
v.into(),
),
ChildRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_ChildRounding as i32, v)
}
ChildBorderSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_ChildBorderSize as i32, v)
}
PopupRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_PopupRounding as i32, v)
}
PopupBorderSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_PopupBorderSize as i32, v)
}
FramePadding(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_FramePadding as i32,
v.into(),
),
FrameRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_FrameRounding as i32, v)
}
FrameBorderSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_FrameBorderSize as i32, v)
}
ItemSpacing(v) => {
igPushStyleVarVec2(crate::imgui_sys::ImGuiStyleVar_ItemSpacing as i32, v.into())
}
ItemInnerSpacing(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_ItemInnerSpacing as i32,
v.into(),
),
IndentSpacing(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_IndentSpacing as i32, v)
}
ScrollbarSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_ScrollbarSize as i32, v)
}
ScrollbarRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_ScrollbarRounding as i32, v)
}
GrabMinSize(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_GrabMinSize as i32, v)
}
GrabRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_GrabRounding as i32, v)
}
TabRounding(v) => {
igPushStyleVarFloat(crate::imgui_sys::ImGuiStyleVar_TabRounding as i32, v)
}
ButtonTextAlign(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_ButtonTextAlign as i32,
v.into(),
),
SelectableTextAlign(v) => igPushStyleVarVec2(
crate::imgui_sys::ImGuiStyleVar_SelectableTextAlign as i32,
v.into(),
),
}
}
impl<'ui> Ui<'ui> {
#[doc(alias = "PushItemWith")]
pub fn push_item_width(&self, item_width: f32) -> ItemWidthStackToken {
unsafe { crate::imgui_sys::igPushItemWidth(item_width) };
ItemWidthStackToken { _ctx: self.ctx }
}
#[doc(alias = "SetNextItemWidth")]
pub fn set_next_item_width(&self, item_width: f32) {
unsafe { crate::imgui_sys::igSetNextItemWidth(item_width) };
}
#[doc(alias = "CalcItemWidth")]
pub fn calc_item_width(&self) -> f32 {
unsafe { crate::imgui_sys::igCalcItemWidth() }
}
#[doc(alias = "PushTextWrapPos")]
pub fn push_text_wrap_pos(&self) -> TextWrapPosStackToken {
self.push_text_wrap_pos_with_pos(0.0)
}
#[doc(alias = "PushTextWrapPos")]
pub fn push_text_wrap_pos_with_pos(&self, wrap_pos_x: f32) -> TextWrapPosStackToken {
unsafe { crate::imgui_sys::igPushTextWrapPos(wrap_pos_x) };
TextWrapPosStackToken { _ctx: self.ctx }
}
#[doc(alias = "PushItemFlag")]
pub fn push_item_flag(&self, item_flag: ItemFlag) -> ItemFlagsStackToken {
use self::ItemFlag::*;
match item_flag {
AllowKeyboardFocus(v) => unsafe { crate::imgui_sys::igPushAllowKeyboardFocus(v) },
ButtonRepeat(v) => unsafe { crate::imgui_sys::igPushButtonRepeat(v) },
}
ItemFlagsStackToken {
discriminant: mem::discriminant(&item_flag),
_ctx: self.ctx,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ItemFlag {
AllowKeyboardFocus(bool),
ButtonRepeat(bool),
}
pub struct ItemWidthStackToken {
_ctx: *const Context,
}
impl ItemWidthStackToken {
#[doc(alias = "PopItemWidth")]
pub fn pop(mut self, _: &Ui) {
self._ctx = ptr::null();
unsafe { crate::imgui_sys::igPopItemWidth() };
}
}
pub struct TextWrapPosStackToken {
_ctx: *const Context,
}
impl TextWrapPosStackToken {
#[doc(alias = "PopTextWrapPos")]
pub fn pop(mut self, _: &Ui) {
self._ctx = ptr::null();
unsafe { crate::imgui_sys::igPopTextWrapPos() };
}
}
pub struct ItemFlagsStackToken {
discriminant: mem::Discriminant<ItemFlag>,
_ctx: *const Context,
}
impl ItemFlagsStackToken {
#[doc(alias = "PopAllowKeyboardFocus", alias = "PopButtonRepeat")]
pub fn pop(mut self, _: &Ui) {
self._ctx = ptr::null();
const ALLOW_KEYBOARD_FOCUS: ItemFlag = ItemFlag::AllowKeyboardFocus(true);
const BUTTON_REPEAT: ItemFlag = ItemFlag::ButtonRepeat(true);
if self.discriminant == mem::discriminant(&ALLOW_KEYBOARD_FOCUS) {
unsafe { crate::imgui_sys::igPopAllowKeyboardFocus() };
} else if self.discriminant == mem::discriminant(&BUTTON_REPEAT) {
unsafe { crate::imgui_sys::igPopButtonRepeat() };
} else {
unreachable!();
}
}
}
create_token!(
pub struct IdStackToken<'ui>;
drop { crate::imgui_sys::igPopID() }
);
impl IdStackToken<'_> {
pub fn pop(self) {
self.end()
}
}
impl<'ui> Ui<'ui> {
#[doc(alias = "PushId")]
pub fn push_id<'a, I: Into<Id<'a>>>(&self, id: I) -> IdStackToken<'ui> {
let id = id.into();
unsafe {
match id {
Id::Int(i) => crate::imgui_sys::igPushIDInt(i),
Id::Str(s) => {
let start = s.as_ptr() as *const c_char;
let end = start.add(s.len());
crate::imgui_sys::igPushIDStrStr(start, end)
}
Id::Ptr(p) => crate::imgui_sys::igPushIDPtr(p as *const c_void),
}
}
IdStackToken::new(self)
}
}