use imgui_sys; use std::marker::PhantomData; use std::ptr; use super::{ImGuiInputTextFlags, ImGuiInputTextFlags_AllowTabInput /* ImGuiInputTextFlags_CtrlEnterForNewLine, */, ImGuiInputTextFlags_AlwaysInsertMode, ImGuiInputTextFlags_AutoSelectAll, ImGuiInputTextFlags_CallbackAlways, ImGuiInputTextFlags_CallbackCharFilter, ImGuiInputTextFlags_CallbackCompletion, ImGuiInputTextFlags_CallbackHistory, ImGuiInputTextFlags_CharsDecimal, ImGuiInputTextFlags_CharsHexadecimal, ImGuiInputTextFlags_CharsNoBlank, ImGuiInputTextFlags_CharsUppercase, ImGuiInputTextFlags_EnterReturnsTrue, ImGuiInputTextFlags_NoHorizontalScroll, ImStr, ImString, Ui}; macro_rules! impl_text_flags { ($InputType:ident) => { #[inline] pub fn flags(mut self, flags: ImGuiInputTextFlags) -> Self { self.flags = flags; self } #[inline] pub fn chars_decimal(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CharsDecimal, value); self } #[inline] pub fn chars_hexadecimal(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CharsHexadecimal, value); self } #[inline] pub fn chars_uppercase(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CharsUppercase, value); self } #[inline] pub fn chars_noblank(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CharsNoBlank, value); self } #[inline] pub fn auto_select_all(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_AutoSelectAll, value); self } #[inline] pub fn enter_returns_true(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_EnterReturnsTrue, value); self } #[inline] pub fn callback_completion(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CallbackCompletion, value); self } #[inline] pub fn callback_history(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CallbackHistory, value); self } #[inline] pub fn callback_always(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CallbackAlways, value); self } #[inline] pub fn callback_char_filter(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_CallbackCharFilter, value); self } #[inline] pub fn allow_tab_input(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_AllowTabInput, value); self } #[inline] pub fn no_horizontal_scroll(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_NoHorizontalScroll, value); self } #[inline] pub fn always_insert_mode(mut self, value: bool) -> Self { self.flags.set(ImGuiInputTextFlags_AlwaysInsertMode, value); self } } } macro_rules! impl_step_params { ($InputType:ident, $Value:ty) => { #[inline] pub fn step(mut self, value: $Value) -> Self { self.step = value; self } #[inline] pub fn step_fast(mut self, value: $Value) -> Self { self.step_fast = value; self } } } macro_rules! impl_precision_params { ($InputType:ident) => { #[inline] pub fn decimal_precision(mut self, value: i32) -> Self { self.decimal_precision = value; self } } } #[must_use] pub struct InputText<'ui, 'p> { label: &'p ImStr, buf: &'p mut ImString, flags: ImGuiInputTextFlags, _phantom: PhantomData<&'ui Ui<'ui>>, } impl<'ui, 'p> InputText<'ui, 'p> { pub fn new(label: &'p ImStr, buf: &'p mut ImString) -> Self { InputText { label: label, buf: buf, flags: ImGuiInputTextFlags::empty(), _phantom: PhantomData, } } impl_text_flags!(InputText); // TODO: boxed closure...? // pub fn callback(self) -> Self { } pub fn build(self) -> bool { unsafe { imgui_sys::igInputText(self.label.as_ptr(), // TODO: this is evil. // Perhaps something else than &mut str is better self.buf.as_ptr() as *mut i8, self.buf.capacity() + 1, self.flags, None, ptr::null_mut()) } } } #[must_use] pub struct InputInt<'ui, 'p> { label: &'p ImStr, value: &'p mut i32, step: i32, step_fast: i32, flags: ImGuiInputTextFlags, _phantom: PhantomData<&'ui Ui<'ui>>, } impl<'ui, 'p> InputInt<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut i32) -> Self { InputInt { label: label, value: value, step: 1, step_fast: 100, flags: ImGuiInputTextFlags::empty(), _phantom: PhantomData, } } pub fn build(self) -> bool { unsafe { imgui_sys::igInputInt(self.label.as_ptr(), self.value as *mut i32, self.step, self.step_fast, self.flags) } } impl_step_params!(InputInt, i32); impl_text_flags!(InputInt); } #[must_use] pub struct InputFloat<'ui, 'p> { label: &'p ImStr, value: &'p mut f32, step: f32, step_fast: f32, decimal_precision: i32, flags: ImGuiInputTextFlags, _phantom: PhantomData<&'ui Ui<'ui>>, } impl<'ui, 'p> InputFloat<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut f32) -> Self { InputFloat { label: label, value: value, step: 0.0, step_fast: 0.0, decimal_precision: -1, flags: ImGuiInputTextFlags::empty(), _phantom: PhantomData, } } pub fn build(self) -> bool { unsafe { imgui_sys::igInputFloat(self.label.as_ptr(), self.value as *mut f32, self.step, self.step_fast, self.decimal_precision, self.flags) } } impl_step_params!(InputFloat, f32); impl_precision_params!(InputFloat); impl_text_flags!(InputFloat); } macro_rules! impl_input_floatn { ($InputFloatN:ident, $N:expr, $igInputFloatN:ident) => { #[must_use] pub struct $InputFloatN<'ui, 'p> { label: &'p ImStr, value: &'p mut [f32;$N], decimal_precision: i32, flags: ImGuiInputTextFlags, _phantom: PhantomData<&'ui Ui<'ui>> } impl<'ui, 'p> $InputFloatN<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut [f32;$N]) -> Self { $InputFloatN { label: label, value: value, decimal_precision: -1, flags: ImGuiInputTextFlags::empty(), _phantom: PhantomData } } pub fn build(self) -> bool { unsafe { imgui_sys::$igInputFloatN( self.label.as_ptr(), self.value.as_mut_ptr(), self.decimal_precision, self.flags) } } impl_precision_params!($InputFloatN); impl_text_flags!($InputFloatN); } } } impl_input_floatn!(InputFloat2, 2, igInputFloat2); impl_input_floatn!(InputFloat3, 3, igInputFloat3); impl_input_floatn!(InputFloat4, 4, igInputFloat4); macro_rules! impl_input_intn { ($InputIntN:ident, $N:expr, $igInputIntN:ident) => { #[must_use] pub struct $InputIntN<'ui, 'p> { label: &'p ImStr, value: &'p mut [i32;$N], flags: ImGuiInputTextFlags, _phantom: PhantomData<&'ui Ui<'ui>> } impl<'ui, 'p> $InputIntN<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut [i32;$N]) -> Self { $InputIntN { label: label, value: value, flags: ImGuiInputTextFlags::empty(), _phantom: PhantomData } } pub fn build(self) -> bool { unsafe { imgui_sys::$igInputIntN( self.label.as_ptr(), self.value.as_mut_ptr(), self.flags) } } impl_text_flags!($InputIntN); } } } impl_input_intn!(InputInt2, 2, igInputInt2); impl_input_intn!(InputInt3, 3, igInputInt3); impl_input_intn!(InputInt4, 4, igInputInt4); #[must_use] pub struct ColorEdit3<'ui, 'p> { label: &'p ImStr, value: &'p mut [f32; 3], _phantom: PhantomData<&'ui Ui<'ui>>, } impl<'ui, 'p> ColorEdit3<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut [f32; 3]) -> Self { ColorEdit3 { label: label, value: value, _phantom: PhantomData, } } pub fn build(self) -> bool { unsafe { imgui_sys::igColorEdit3(self.label.as_ptr(), self.value.as_mut_ptr()) } } } #[must_use] pub struct ColorEdit4<'ui, 'p> { label: &'p ImStr, value: &'p mut [f32; 4], show_alpha: bool, _phantom: PhantomData<&'ui Ui<'ui>>, } impl<'ui, 'p> ColorEdit4<'ui, 'p> { pub fn new(label: &'p ImStr, value: &'p mut [f32; 4]) -> Self { ColorEdit4 { label: label, value: value, show_alpha: true, _phantom: PhantomData, } } pub fn build(self) -> bool { unsafe { imgui_sys::igColorEdit4(self.label.as_ptr(), self.value.as_mut_ptr(), self.show_alpha) } } }