Merge pull request #536 from sanbox-irl/mint-support

Switch [f32; _] types in the public api to `mint` equivalents
This commit is contained in:
Jonathan Spira 2021-09-30 19:13:48 -04:00 committed by GitHub
commit 4d183cffa6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 876 additions and 311 deletions

View File

@ -544,8 +544,8 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
Drag::new("drag float").range(-1.0, 1.0).speed(0.001).build(ui, &mut state.f0);
ui.input_float3("input float3", &mut state.vec3f)
.build();
ColorEdit::new("color 1", &mut state.col1).build(ui);
ColorEdit::new("color 2", &mut state.col2).build(ui);
ColorEdit3::new("color 1", &mut state.col1).build(ui);
ColorEdit4::new("color 2", &mut state.col2).build(ui);
TreeNode::new("Multi-component Widgets").build(ui, || {
ui.input_float2("input float2", &mut state.vec2f)
@ -601,19 +601,19 @@ fn show_test_window(ui: &Ui, state: &mut State, opened: &mut bool) {
"Click on the colored square to open a color picker.
CTRL+click on individual component to input value.\n",
);
ColorEdit::new("MyColor##1", &mut s.color)
ColorEdit4::new("MyColor##1", &mut s.color)
.flags(misc_flags)
.alpha(false)
.build(ui);
ui.text("Color widget HSV with Alpha:");
ColorEdit::new("MyColor##2", &mut s.color)
ColorEdit4::new("MyColor##2", &mut s.color)
.flags(misc_flags)
.input_mode(ColorEditInputMode::HSV)
.build(ui);
ui.text("Color widget with Float Display:");
ColorEdit::new("MyColor##2f", &mut s.color)
ColorEdit4::new("MyColor##2f", &mut s.color)
.flags(misc_flags)
.format(ColorFormat::Float)
.build(ui);
@ -627,7 +627,7 @@ CTRL+click on individual component to input value.\n",
With the label(false) function you can pass a non-empty label which \
will only be used for the tooltip and picker popup.",
);
ColorEdit::new("MyColor##3", &mut s.color)
ColorEdit4::new("MyColor##3", &mut s.color)
.flags(misc_flags)
.inputs(false)
.label(false)
@ -642,13 +642,13 @@ CTRL+click on individual component to input value.\n",
ui.checkbox("With Ref Color", &mut s.ref_color);
if s.ref_color {
ui.same_line();
ColorEdit::new("##RefColor", &mut s.ref_color_v)
ColorEdit4::new("##RefColor", &mut s.ref_color_v)
.flags(misc_flags)
.inputs(false)
.build(ui);
}
}
let mut b = ColorPicker::new
let mut b = ColorPicker4::new
("MyColor##4", &mut s.color)
.flags(misc_flags)
.alpha(s.alpha)
@ -657,7 +657,7 @@ CTRL+click on individual component to input value.\n",
.display_rgb(true);
if s.ref_color {
b = b.reference_color(&s.ref_color_v)
b = b.reference_color(s.ref_color_v)
}
b.build(ui);
});
@ -806,7 +806,7 @@ CTRL+click on individual component to input value.\n",
let items = &["aaaa", "bbbb", "cccc", "dddd", "eeee"];
ui.combo_simple_string("Combo", &mut state.stacked_modals_item, items);
ColorEdit::new("color", &mut state.stacked_modals_color).build(ui);
ColorEdit4::new("color", &mut state.stacked_modals_color).build(ui);
if ui.button("Add another modal..") {
ui.open_popup("Stacked 2") ;
@ -976,7 +976,7 @@ fn show_example_app_custom_rendering(ui: &Ui, state: &mut CustomRenderingState,
.build(|| {
ui.text("Primitives");
// TODO: Add DragFloat to change value of sz
ColorEdit::new("Color", &mut state.col).build(ui);
ColorEdit3::new("Color", &mut state.col).build(ui);
let draw_list = ui.get_window_draw_list();
let p = ui.cursor_screen_pos();
let spacing = 8.0;

View File

@ -15,6 +15,7 @@ exclude = ["third-party/*.json", "third-party/*.lua", "third-party/imgui/*/"]
[dependencies]
chlorine = "1.0.7"
mint = "0.5.6"
[build-dependencies]
cc = "1.0"

View File

@ -71,6 +71,23 @@ impl From<ImVec2> for (f32, f32) {
}
}
impl From<mint::Vector2<f32>> for ImVec2 {
fn from(o: mint::Vector2<f32>) -> Self {
Self { x: o.x, y: o.y }
}
}
impl From<mint::Vector4<f32>> for ImVec4 {
fn from(o: mint::Vector4<f32>) -> Self {
Self {
x: o.x,
y: o.y,
z: o.z,
w: o.w,
}
}
}
impl ImVec4 {
#[inline]
pub const fn new(x: f32, y: f32, z: f32, w: f32) -> ImVec4 {

View File

@ -15,6 +15,7 @@ exclude = ["/resources"]
[dependencies]
bitflags = "1"
imgui-sys = { version = "0.8.1-alpha.0", path = "../imgui-sys" }
mint = "0.5.6"
parking_lot = "0.11"
[features]

View File

@ -1,3 +1,5 @@
use crate::math::MintVec4;
/// Wraps u32 that represents a packed RGBA color. Mostly used by types in the
/// low level custom drawing API, such as [`DrawListMut`](crate::DrawListMut).
///
@ -220,6 +222,12 @@ impl From<u32> for ImColor32 {
}
}
impl From<MintVec4> for ImColor32 {
fn from(v: MintVec4) -> Self {
Self::from_rgba_f32s(v.x, v.y, v.z, v.w)
}
}
impl From<[f32; 4]> for ImColor32 {
#[inline]
fn from(v: [f32; 4]) -> Self {

View File

@ -15,7 +15,7 @@
use bitflags::bitflags;
use crate::ImColor32;
use crate::{math::MintVec2, ImColor32};
use sys::ImDrawList;
use super::Ui;
@ -214,7 +214,12 @@ impl<'ui> ChannelsSplit<'ui> {
impl<'ui> DrawListMut<'ui> {
/// Returns a line from point `p1` to `p2` with color `c`.
#[doc(alias = "AddLine")]
pub fn add_line<C>(&'ui self, p1: [f32; 2], p2: [f32; 2], c: C) -> Line<'ui>
pub fn add_line<C>(
&'ui self,
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
c: C,
) -> Line<'ui>
where
C: Into<ImColor32>,
{
@ -224,7 +229,12 @@ impl<'ui> DrawListMut<'ui> {
/// Returns a rectangle whose upper-left corner is at point `p1`
/// and lower-right corner is at point `p2`, with color `c`.
#[doc(alias = "AddRectFilled", alias = "AddRect")]
pub fn add_rect<C>(&'ui self, p1: [f32; 2], p2: [f32; 2], c: C) -> Rect<'ui>
pub fn add_rect<C>(
&'ui self,
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
c: C,
) -> Rect<'ui>
where
C: Into<ImColor32>,
{
@ -239,8 +249,8 @@ impl<'ui> DrawListMut<'ui> {
#[doc(alias = "AddRectFilledMultiColor")]
pub fn add_rect_filled_multicolor<C1, C2, C3, C4>(
&self,
p1: [f32; 2],
p2: [f32; 2],
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
col_upr_left: C1,
col_upr_right: C2,
col_bot_right: C3,
@ -254,8 +264,8 @@ impl<'ui> DrawListMut<'ui> {
unsafe {
sys::ImDrawList_AddRectFilledMultiColor(
self.draw_list,
p1.into(),
p2.into(),
p1.into().into(),
p2.into().into(),
col_upr_left.into().into(),
col_upr_right.into().into(),
col_bot_right.into().into(),
@ -269,9 +279,9 @@ impl<'ui> DrawListMut<'ui> {
#[doc(alias = "AddTriangleFilled", alias = "AddTriangle")]
pub fn add_triangle<C>(
&'ui self,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
p3: impl Into<MintVec2>,
c: C,
) -> Triangle<'ui>
where
@ -282,7 +292,12 @@ impl<'ui> DrawListMut<'ui> {
/// Returns a circle with the given `center`, `radius` and `color`.
#[doc(alias = "AddCircleFilled", alias = "AddCircle")]
pub fn add_circle<C>(&'ui self, center: [f32; 2], radius: f32, color: C) -> Circle<'ui>
pub fn add_circle<C>(
&'ui self,
center: impl Into<MintVec2>,
radius: f32,
color: C,
) -> Circle<'ui>
where
C: Into<ImColor32>,
{
@ -291,35 +306,39 @@ impl<'ui> DrawListMut<'ui> {
/// Draw a text whose upper-left corner is at point `pos`.
#[doc(alias = "AddText")]
pub fn add_text<C, T>(&self, pos: [f32; 2], col: C, text: T)
where
C: Into<ImColor32>,
T: AsRef<str>,
{
pub fn add_text(
&self,
pos: impl Into<MintVec2>,
col: impl Into<ImColor32>,
text: impl AsRef<str>,
) {
use std::os::raw::c_char;
let text = text.as_ref();
unsafe {
let start = text.as_ptr() as *const c_char;
let end = (start as usize + text.len()) as *const c_char;
sys::ImDrawList_AddText_Vec2(self.draw_list, pos.into(), col.into().into(), start, end)
sys::ImDrawList_AddText_Vec2(
self.draw_list,
pos.into().into(),
col.into().into(),
start,
end,
)
}
}
/// Returns a Bezier curve stretching from `pos0` to `pos1`, whose
/// curvature is defined by `cp0` and `cp1`.
#[doc(alias = "AddBezier", alias = "AddBezierCubic")]
pub fn add_bezier_curve<C>(
pub fn add_bezier_curve(
&'ui self,
pos0: [f32; 2],
cp0: [f32; 2],
cp1: [f32; 2],
pos1: [f32; 2],
color: C,
) -> BezierCurve<'ui>
where
C: Into<ImColor32>,
{
pos0: impl Into<MintVec2>,
cp0: impl Into<MintVec2>,
cp1: impl Into<MintVec2>,
pos1: impl Into<MintVec2>,
color: impl Into<ImColor32>,
) -> BezierCurve<'ui> {
BezierCurve::new(self, pos0, cp0, cp1, pos1, color)
}
@ -328,11 +347,18 @@ impl<'ui> DrawListMut<'ui> {
/// Clip all drawings done within the closure `f` in the given
/// rectangle.
#[doc(alias = "PushClipRect", alias = "PopClipRect")]
pub fn with_clip_rect<F>(&self, min: [f32; 2], max: [f32; 2], f: F)
pub fn with_clip_rect<F>(&self, min: impl Into<MintVec2>, max: impl Into<MintVec2>, f: F)
where
F: FnOnce(),
{
unsafe { sys::ImDrawList_PushClipRect(self.draw_list, min.into(), max.into(), false) }
unsafe {
sys::ImDrawList_PushClipRect(
self.draw_list,
min.into().into(),
max.into().into(),
false,
)
}
f();
unsafe { sys::ImDrawList_PopClipRect(self.draw_list) }
}
@ -343,11 +369,17 @@ impl<'ui> DrawListMut<'ui> {
/// rectangle. Intersect with all clipping rectangle previously on
/// the stack.
#[doc(alias = "PushClipRect", alias = "PopClipRect")]
pub fn with_clip_rect_intersect<F>(&self, min: [f32; 2], max: [f32; 2], f: F)
where
pub fn with_clip_rect_intersect<F>(
&self,
min: impl Into<MintVec2>,
max: impl Into<MintVec2>,
f: F,
) where
F: FnOnce(),
{
unsafe { sys::ImDrawList_PushClipRect(self.draw_list, min.into(), max.into(), true) }
unsafe {
sys::ImDrawList_PushClipRect(self.draw_list, min.into().into(), max.into().into(), true)
}
f();
unsafe { sys::ImDrawList_PopClipRect(self.draw_list) }
}
@ -376,8 +408,8 @@ impl<'ui> DrawListMut<'ui> {
pub fn add_image(
&'ui self,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
p_min: impl Into<MintVec2>,
p_max: impl Into<MintVec2>,
) -> Image<'_> {
Image::new(self, texture_id, p_min, p_max)
}
@ -388,10 +420,10 @@ impl<'ui> DrawListMut<'ui> {
pub fn add_image_quad(
&'ui self,
texture_id: TextureId,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p4: [f32; 2],
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
p3: impl Into<MintVec2>,
p4: impl Into<MintVec2>,
) -> ImageQuad<'_> {
ImageQuad::new(self, texture_id, p1, p2, p3, p4)
}
@ -400,8 +432,8 @@ impl<'ui> DrawListMut<'ui> {
pub fn add_image_rounded(
&'ui self,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
p_min: impl Into<MintVec2>,
p_max: impl Into<MintVec2>,
rounding: f32,
) -> ImageRounded<'_> {
ImageRounded::new(self, texture_id, p_min, p_max, rounding)
@ -419,13 +451,18 @@ pub struct Line<'ui> {
}
impl<'ui> Line<'ui> {
fn new<C>(draw_list: &'ui DrawListMut<'_>, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
fn new<C>(
draw_list: &'ui DrawListMut<'_>,
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
c: C,
) -> Self
where
C: Into<ImColor32>,
{
Self {
p1,
p2,
p1: p1.into().into(),
p2: p2.into().into(),
color: c.into(),
thickness: 1.0,
draw_list,
@ -466,13 +503,18 @@ pub struct Rect<'ui> {
}
impl<'ui> Rect<'ui> {
fn new<C>(draw_list: &'ui DrawListMut<'_>, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
fn new<C>(
draw_list: &'ui DrawListMut<'_>,
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
c: C,
) -> Self
where
C: Into<ImColor32>,
{
Self {
p1,
p2,
p1: p1.into().into(),
p2: p2.into().into(),
color: c.into(),
rounding: 0.0,
flags: DrawFlags::ROUND_CORNERS_ALL,
@ -569,18 +611,18 @@ pub struct Triangle<'ui> {
impl<'ui> Triangle<'ui> {
fn new<C>(
draw_list: &'ui DrawListMut<'_>,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
p3: impl Into<MintVec2>,
c: C,
) -> Self
where
C: Into<ImColor32>,
{
Self {
p1,
p2,
p3,
p1: p1.into().into(),
p2: p2.into().into(),
p3: p3.into().into(),
color: c.into(),
thickness: 1.0,
filled: false,
@ -641,12 +683,17 @@ pub struct Circle<'ui> {
impl<'ui> Circle<'ui> {
/// Typically constructed by [`DrawListMut::add_circle`]
pub fn new<C>(draw_list: &'ui DrawListMut<'_>, center: [f32; 2], radius: f32, color: C) -> Self
pub fn new<C>(
draw_list: &'ui DrawListMut<'_>,
center: impl Into<MintVec2>,
radius: f32,
color: C,
) -> Self
where
C: Into<ImColor32>,
{
Self {
center,
center: center.into().into(),
radius,
color: color.into(),
num_segments: 0,
@ -720,20 +767,20 @@ impl<'ui> BezierCurve<'ui> {
/// Typically constructed by [`DrawListMut::add_bezier_curve`]
pub fn new<C>(
draw_list: &'ui DrawListMut<'_>,
pos0: [f32; 2],
cp0: [f32; 2],
cp1: [f32; 2],
pos1: [f32; 2],
pos0: impl Into<MintVec2>,
cp0: impl Into<MintVec2>,
cp1: impl Into<MintVec2>,
pos1: impl Into<MintVec2>,
c: C,
) -> Self
where
C: Into<ImColor32>,
{
Self {
pos0,
cp0,
cp1,
pos1,
pos0: pos0.into().into(),
cp0: cp0.into().into(),
cp1: cp1.into().into(),
pos1: pos1.into().into(),
color: c.into(),
thickness: 1.0,
num_segments: None,
@ -789,13 +836,13 @@ impl<'ui> Image<'ui> {
pub fn new(
draw_list: &'ui DrawListMut<'_>,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
p_min: impl Into<MintVec2>,
p_max: impl Into<MintVec2>,
) -> Self {
Self {
texture_id,
p_min,
p_max,
p_min: p_min.into().into(),
p_max: p_max.into().into(),
uv_min: [0.0, 0.0],
uv_max: [1.0, 1.0],
col: [1.0, 1.0, 1.0, 1.0].into(),
@ -804,13 +851,13 @@ impl<'ui> Image<'ui> {
}
/// Set uv_min (default `[0.0, 0.0]`)
pub fn uv_min(mut self, uv_min: [f32; 2]) -> Self {
self.uv_min = uv_min;
pub fn uv_min(mut self, uv_min: impl Into<MintVec2>) -> Self {
self.uv_min = uv_min.into().into();
self
}
/// Set uv_max (default `[1.0, 1.0]`)
pub fn uv_max(mut self, uv_max: [f32; 2]) -> Self {
self.uv_max = uv_max;
pub fn uv_max(mut self, uv_max: impl Into<MintVec2>) -> Self {
self.uv_max = uv_max.into().into();
self
}
@ -862,17 +909,17 @@ impl<'ui> ImageQuad<'ui> {
pub fn new(
draw_list: &'ui DrawListMut<'_>,
texture_id: TextureId,
p1: [f32; 2],
p2: [f32; 2],
p3: [f32; 2],
p4: [f32; 2],
p1: impl Into<MintVec2>,
p2: impl Into<MintVec2>,
p3: impl Into<MintVec2>,
p4: impl Into<MintVec2>,
) -> Self {
Self {
texture_id,
p1,
p2,
p3,
p4,
p1: p1.into().into(),
p2: p2.into().into(),
p3: p3.into().into(),
p4: p4.into().into(),
uv1: [0.0, 0.0],
uv2: [1.0, 0.0],
uv3: [1.0, 1.0],
@ -890,11 +937,17 @@ impl<'ui> ImageQuad<'ui> {
/// uv3: [1, 1],
/// uv4: [0, 1],
/// ```
pub fn uv(mut self, uv1: [f32; 2], uv2: [f32; 2], uv3: [f32; 2], uv4: [f32; 2]) -> Self {
self.uv1 = uv1;
self.uv2 = uv2;
self.uv3 = uv3;
self.uv4 = uv4;
pub fn uv(
mut self,
uv1: impl Into<MintVec2>,
uv2: impl Into<MintVec2>,
uv3: impl Into<MintVec2>,
uv4: impl Into<MintVec2>,
) -> Self {
self.uv1 = uv1.into().into();
self.uv2 = uv2.into().into();
self.uv3 = uv3.into().into();
self.uv4 = uv4.into().into();
self
}
@ -949,14 +1002,14 @@ impl<'ui> ImageRounded<'ui> {
pub fn new(
draw_list: &'ui DrawListMut<'_>,
texture_id: TextureId,
p_min: [f32; 2],
p_max: [f32; 2],
p_min: impl Into<MintVec2>,
p_max: impl Into<MintVec2>,
rounding: f32,
) -> Self {
Self {
texture_id,
p_min,
p_max,
p_min: p_min.into().into(),
p_max: p_max.into().into(),
uv_min: [0.0, 0.0],
uv_max: [1.0, 1.0],
col: [1.0, 1.0, 1.0, 1.0].into(),
@ -967,13 +1020,13 @@ impl<'ui> ImageRounded<'ui> {
}
/// Set uv_min (default `[0.0, 0.0]`)
pub fn uv_min(mut self, uv_min: [f32; 2]) -> Self {
self.uv_min = uv_min;
pub fn uv_min(mut self, uv_min: impl Into<MintVec2>) -> Self {
self.uv_min = uv_min.into().into();
self
}
/// Set uv_max (default `[1.0, 1.0]`)
pub fn uv_max(mut self, uv_max: [f32; 2]) -> Self {
self.uv_max = uv_max;
pub fn uv_max(mut self, uv_max: impl Into<MintVec2>) -> Self {
self.uv_max = uv_max.into().into();
self
}

View File

@ -1,5 +1,6 @@
use std::ptr;
use crate::math::MintVec2;
use crate::sys;
use crate::Ui;
@ -133,8 +134,12 @@ impl<'ui> Ui<'ui> {
///
/// Clipped by current clipping settings, but disregards other factors like focus, window
/// ordering, modal popup blocking.
pub fn is_mouse_hovering_rect(&self, r_min: [f32; 2], r_max: [f32; 2]) -> bool {
unsafe { sys::igIsMouseHoveringRect(r_min.into(), r_max.into(), true) }
pub fn is_mouse_hovering_rect(
&self,
r_min: impl Into<MintVec2>,
r_max: impl Into<MintVec2>,
) -> bool {
unsafe { sys::igIsMouseHoveringRect(r_min.into().into(), r_max.into().into(), true) }
}
/// Returns the mouse position backed up at the time of opening a popup
#[doc(alias = "GetMousePosOnOpeningCurrentPopup")]
@ -221,8 +226,8 @@ impl<'ui> Ui<'ui> {
unsafe { sys::igIsMousePosValid(ptr::null()) }
}
#[doc(alias = "IsMousePosValid")]
pub fn is_mouse_pos_valid(&self, mouse_pos: [f32; 2]) -> bool {
unsafe { sys::igIsMousePosValid(&mouse_pos.into()) }
pub fn is_mouse_pos_valid(&self, mouse_pos: impl Into<MintVec2>) -> bool {
unsafe { sys::igIsMousePosValid(&mouse_pos.into().into()) }
}
}

View File

@ -2,6 +2,7 @@ use bitflags::bitflags;
use std::ops::Range;
use std::os::raw::{c_char, c_int, c_void};
use crate::math::*;
use crate::sys;
use crate::Ui;
@ -360,12 +361,12 @@ impl<'ui, 'p, L: AsRef<str>> InputTextMultiline<'ui, 'p, L, PassthroughCallback>
/// your string.
/// 3. Truncations by ImGui appear to be done primarily by insertions of `\0` to the truncation point.
/// We will handle this for you and edit the string "properly" too, but this might show up in callbacks.
pub fn new(ui: &'ui Ui<'ui>, label: L, buf: &'p mut String, size: [f32; 2]) -> Self {
pub fn new(ui: &'ui Ui<'ui>, label: L, buf: &'p mut String, size: impl Into<MintVec2>) -> Self {
InputTextMultiline {
label,
buf,
flags: InputTextFlags::CALLBACK_RESIZE,
size,
size: size.into().into(),
callback_handler: PassthroughCallback,
ui,
}
@ -552,17 +553,22 @@ impl<'ui, 'p, L: AsRef<str>> InputFloat<'ui, 'p, L> {
}
macro_rules! impl_input_floatn {
($InputFloatN:ident, $N:expr, $igInputFloatN:ident) => {
($InputFloatN:ident, $MINT_TARGET:ty, $N:expr, $igInputFloatN:ident) => {
#[must_use]
pub struct $InputFloatN<'ui, 'p, L> {
pub struct $InputFloatN<'ui, 'p, L, T> {
label: L,
value: &'p mut [f32; $N],
value: &'p mut T,
flags: InputTextFlags,
ui: &'ui Ui<'ui>,
}
impl<'ui, 'p, L: AsRef<str>> $InputFloatN<'ui, 'p, L> {
pub fn new(ui: &'ui Ui<'ui>, label: L, value: &'p mut [f32; $N]) -> Self {
impl<'ui, 'p, L, T> $InputFloatN<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<$MINT_TARGET>,
$MINT_TARGET: Into<T> + Into<[f32; $N]>,
{
pub fn new(ui: &'ui Ui<'ui>, label: L, value: &'p mut T) -> Self {
$InputFloatN {
label,
value,
@ -572,14 +578,24 @@ macro_rules! impl_input_floatn {
}
pub fn build(self) -> bool {
unsafe {
let value: $MINT_TARGET = (*self.value).into();
let mut value: [f32; $N] = value.into();
let changed = unsafe {
sys::$igInputFloatN(
self.ui.scratch_txt(self.label),
self.value.as_mut_ptr(),
value.as_mut_ptr(),
b"%.3f\0".as_ptr() as *const _,
self.flags.bits() as i32,
)
};
if changed {
let value: $MINT_TARGET = value.into();
*self.value = value.into();
}
changed
}
impl_text_flags!($InputFloatN);
@ -587,22 +603,27 @@ macro_rules! impl_input_floatn {
};
}
impl_input_floatn!(InputFloat2, 2, igInputFloat2);
impl_input_floatn!(InputFloat3, 3, igInputFloat3);
impl_input_floatn!(InputFloat4, 4, igInputFloat4);
impl_input_floatn!(InputFloat2, MintVec2, 2, igInputFloat2);
impl_input_floatn!(InputFloat3, MintVec3, 3, igInputFloat3);
impl_input_floatn!(InputFloat4, MintVec4, 4, igInputFloat4);
macro_rules! impl_input_intn {
($InputIntN:ident, $N:expr, $igInputIntN:ident) => {
($InputIntN:ident, $MINT_TARGET:ident, $N:expr, $igInputIntN:ident) => {
#[must_use]
pub struct $InputIntN<'ui, 'p, L> {
pub struct $InputIntN<'ui, 'p, L, T> {
label: L,
value: &'p mut [i32; $N],
value: &'p mut T,
flags: InputTextFlags,
ui: &'ui Ui<'ui>,
}
impl<'ui, 'p, L: AsRef<str>> $InputIntN<'ui, 'p, L> {
pub fn new(ui: &'ui Ui<'ui>, label: L, value: &'p mut [i32; $N]) -> Self {
impl<'ui, 'p, L, T> $InputIntN<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<$MINT_TARGET>,
$MINT_TARGET: Into<T> + Into<[i32; $N]>,
{
pub fn new(ui: &'ui Ui<'ui>, label: L, value: &'p mut T) -> Self {
$InputIntN {
label,
value,
@ -612,13 +633,23 @@ macro_rules! impl_input_intn {
}
pub fn build(self) -> bool {
unsafe {
let value: $MINT_TARGET = (*self.value).into();
let mut value: [i32; $N] = value.into();
let changed = unsafe {
sys::$igInputIntN(
self.ui.scratch_txt(self.label),
self.value.as_mut_ptr(),
value.as_mut_ptr(),
self.flags.bits() as i32,
)
};
if changed {
let value: $MINT_TARGET = value.into();
*self.value = value.into();
}
changed
}
impl_text_flags!($InputIntN);
@ -626,9 +657,9 @@ macro_rules! impl_input_intn {
};
}
impl_input_intn!(InputInt2, 2, igInputInt2);
impl_input_intn!(InputInt3, 3, igInputInt3);
impl_input_intn!(InputInt4, 4, igInputInt4);
impl_input_intn!(InputInt2, MintIVec2, 2, igInputInt2);
impl_input_intn!(InputInt3, MintIVec3, 3, igInputInt3);
impl_input_intn!(InputInt4, MintIVec4, 4, igInputInt4);
bitflags!(
/// Callback flags for an `InputText` widget. These correspond to

View File

@ -1,3 +1,4 @@
use crate::math::MintVec2;
use crate::sys;
use crate::Ui;
@ -64,8 +65,8 @@ impl<'ui> Ui<'ui> {
///
/// Can be used to move the cursor on the window.
#[doc(alias = "Dummy")]
pub fn dummy(&self, size: [f32; 2]) {
unsafe { sys::igDummy(size.into()) }
pub fn dummy(&self, size: impl Into<MintVec2>) {
unsafe { sys::igDummy(size.into().into()) }
}
/// Moves content position to the right by `Style::indent_spacing`
@ -126,8 +127,8 @@ impl<'ui> Ui<'ui> {
///
/// This sets the point on which the next widget will be drawn.
#[doc(alias = "SetCursorPos")]
pub fn set_cursor_pos(&self, pos: [f32; 2]) {
unsafe { sys::igSetCursorPos(pos.into()) };
pub fn set_cursor_pos(&self, pos: impl Into<MintVec2>) {
unsafe { sys::igSetCursorPos(pos.into().into()) };
}
/// Returns the initial cursor position (in window coordinates)
#[doc(alias = "GetCursorStartPos")]
@ -147,8 +148,8 @@ impl<'ui> Ui<'ui> {
}
/// Sets the cursor position (in absolute screen coordinates)
#[doc(alias = "SetCursorScreenPos")]
pub fn set_cursor_screen_pos(&self, pos: [f32; 2]) {
unsafe { sys::igSetCursorScreenPos(pos.into()) }
pub fn set_cursor_screen_pos(&self, pos: impl Into<MintVec2>) {
unsafe { sys::igSetCursorScreenPos(pos.into().into()) }
}
/// Vertically aligns text baseline so that it will align properly to regularly frame items.
///

View File

@ -48,6 +48,7 @@ pub use self::widget::tree::*;
pub use self::window::child_window::*;
pub use self::window::*;
use internal::RawCast;
use math::*;
#[macro_use]
mod string;
@ -68,6 +69,7 @@ pub mod internal;
mod io;
mod layout;
mod list_clipper;
mod math;
mod plothistogram;
mod plotlines;
mod popups;
@ -387,27 +389,43 @@ impl<'ui> Ui<'ui> {
) -> InputFloat<'ui, 'p, L> {
InputFloat::new(self, label, value)
}
pub fn input_float2<'p, L: AsRef<str>>(
#[doc(alias = "InputFloat2")]
pub fn input_float2<'p, L, T>(
&'ui self,
label: L,
value: &'p mut [f32; 2],
) -> InputFloat2<'ui, 'p, L> {
value: &'p mut T,
) -> InputFloat2<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintVec2>,
MintVec2: Into<T> + Into<[f32; 2]>,
{
InputFloat2::new(self, label, value)
}
#[doc(alias = "InputFloat3")]
pub fn input_float3<'p, L: AsRef<str>>(
pub fn input_float3<'p, L, T>(
&'ui self,
label: L,
value: &'p mut [f32; 3],
) -> InputFloat3<'ui, 'p, L> {
value: &'p mut T,
) -> InputFloat3<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintVec3>,
MintVec3: Into<T> + Into<[f32; 3]>,
{
InputFloat3::new(self, label, value)
}
#[doc(alias = "InputFloat4")]
pub fn input_float4<'p, L: AsRef<str>>(
pub fn input_float4<'p, L, T>(
&'ui self,
label: L,
value: &'p mut [f32; 4],
) -> InputFloat4<'ui, 'p, L> {
value: &'p mut T,
) -> InputFloat4<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintVec4>,
MintVec4: Into<T> + Into<[f32; 4]>,
{
InputFloat4::new(self, label, value)
}
#[doc(alias = "InputInt")]
@ -419,27 +437,30 @@ impl<'ui> Ui<'ui> {
InputInt::new(self, label, value)
}
#[doc(alias = "InputInt2")]
pub fn input_int2<'p, L: AsRef<str>>(
&'ui self,
label: L,
value: &'p mut [i32; 2],
) -> InputInt2<'ui, 'p, L> {
pub fn input_int2<'p, L, T>(&'ui self, label: L, value: &'p mut T) -> InputInt2<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintIVec2>,
MintIVec2: Into<T> + Into<[i32; 2]>,
{
InputInt2::new(self, label, value)
}
#[doc(alias = "InputInt3")]
pub fn input_int3<'p, L: AsRef<str>>(
&'ui self,
label: L,
value: &'p mut [i32; 3],
) -> InputInt3<'ui, 'p, L> {
pub fn input_int3<'p, L, T>(&'ui self, label: L, value: &'p mut T) -> InputInt3<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintIVec3>,
MintIVec3: Into<T> + Into<[i32; 3]>,
{
InputInt3::new(self, label, value)
}
#[doc(alias = "InputInt4")]
pub fn input_int4<'p, L: AsRef<str>>(
&'ui self,
label: L,
value: &'p mut [i32; 4],
) -> InputInt4<'ui, 'p, L> {
pub fn input_int4<'p, L, T>(&'ui self, label: L, value: &'p mut T) -> InputInt4<'ui, 'p, L, T>
where
L: AsRef<str>,
T: Copy + Into<MintIVec4>,
MintIVec4: Into<T> + Into<[i32; 4]>,
{
InputInt4::new(self, label, value)
}
}

7
imgui/src/math.rs Normal file
View File

@ -0,0 +1,7 @@
pub(crate) type MintVec2 = mint::Vector2<f32>;
pub(crate) type MintVec3 = mint::Vector3<f32>;
pub(crate) type MintVec4 = mint::Vector4<f32>;
pub(crate) type MintIVec2 = mint::Vector2<i32>;
pub(crate) type MintIVec3 = mint::Vector3<i32>;
pub(crate) type MintIVec4 = mint::Vector4<i32>;

View File

@ -62,8 +62,8 @@ impl<'ui, 'p, Label: AsRef<str>, Overlay: AsRef<str>> PlotHistogram<'ui, 'p, Lab
self
}
pub fn graph_size(mut self, graph_size: [f32; 2]) -> Self {
self.graph_size = graph_size;
pub fn graph_size(mut self, graph_size: impl Into<crate::MintVec2>) -> Self {
self.graph_size = graph_size.into().into();
self
}

View File

@ -62,8 +62,8 @@ impl<'ui, 'p, Label: AsRef<str>, Overlay: AsRef<str>> PlotLines<'ui, 'p, Label,
self
}
pub fn graph_size(mut self, graph_size: [f32; 2]) -> Self {
self.graph_size = graph_size;
pub fn graph_size(mut self, graph_size: impl Into<crate::MintVec2>) -> Self {
self.graph_size = graph_size.into().into();
self
}

View File

@ -1,6 +1,7 @@
use std::slice;
use crate::internal::{RawCast, RawWrapper};
use crate::math::MintVec2;
use crate::render::renderer::TextureId;
use crate::sys;
@ -72,7 +73,7 @@ impl DrawData {
/// Can be used if your final output buffer is at a different scale than imgui-rs expects, or
/// if there is a difference between your window resolution and framebuffer resolution.
#[doc(alias = "ScaleClipRects")]
pub fn scale_clip_rects(&mut self, fb_scale: [f32; 2]) {
pub fn scale_clip_rects(&mut self, fb_scale: MintVec2) {
unsafe {
sys::ImDrawData_ScaleClipRects(self.raw_mut(), fb_scale.into());
}

View File

@ -5,6 +5,7 @@ use std::ptr;
use crate::context::Context;
use crate::fonts::atlas::FontId;
use crate::internal::RawCast;
use crate::math::MintVec4;
use crate::style::{StyleColor, StyleVar};
use crate::sys;
use crate::{Id, Ui};
@ -61,9 +62,9 @@ impl<'ui> Ui<'ui> {
pub fn push_style_color(
&self,
style_color: StyleColor,
color: [f32; 4],
color: impl Into<MintVec4>,
) -> ColorStackToken<'_> {
unsafe { sys::igPushStyleColor_Vec4(style_color as i32, color.into()) };
unsafe { sys::igPushStyleColor_Vec4(style_color as i32, color.into().into()) };
ColorStackToken::new(self)
}

View File

@ -2,8 +2,10 @@
use bitflags::bitflags;
use crate::input::mouse::MouseButton;
use crate::style::{Style, StyleColor};
use crate::math::MintVec2;
use crate::style::StyleColor;
use crate::sys;
use crate::Style;
use crate::Ui;
bitflags! {
@ -143,13 +145,17 @@ impl<'ui> Ui<'ui> {
impl<'ui> Ui<'ui> {
/// Returns `true` if the rectangle (of given size, starting from cursor position) is visible
#[doc(alias = "IsRectVisibleNil")]
pub fn is_cursor_rect_visible(&self, size: [f32; 2]) -> bool {
unsafe { sys::igIsRectVisible_Nil(size.into()) }
pub fn is_cursor_rect_visible(&self, size: impl Into<MintVec2>) -> bool {
unsafe { sys::igIsRectVisible_Nil(size.into().into()) }
}
/// Returns `true` if the rectangle (in screen coordinates) is visible
#[doc(alias = "IsRectVisibleNilVec2")]
pub fn is_rect_visible(&self, rect_min: [f32; 2], rect_max: [f32; 2]) -> bool {
unsafe { sys::igIsRectVisible_Vec2(rect_min.into(), rect_max.into()) }
pub fn is_rect_visible(
&self,
rect_min: impl Into<MintVec2>,
rect_max: impl Into<MintVec2>,
) -> bool {
unsafe { sys::igIsRectVisible_Vec2(rect_min.into().into(), rect_max.into().into()) }
}
/// Returns the global imgui-rs time.
///
@ -173,6 +179,7 @@ impl<'ui> Ui<'ui> {
pub fn style_color(&self, style_color: StyleColor) -> [f32; 4] {
self.ctx.style()[style_color]
}
/// Returns a shared reference to the current [`Style`].
///
/// ## Safety

View File

@ -1,41 +1,44 @@
use bitflags::bitflags;
use std::ptr;
use crate::math::MintVec2;
use crate::math::MintVec3;
use crate::math::MintVec4;
use crate::sys;
use crate::Ui;
/// Mutable reference to an editable color value.
#[derive(Debug)]
pub enum EditableColor<'a> {
/// Color value with three float components (e.g. RGB).
Float3(&'a mut [f32; 3]),
/// Color value with four float components (e.g. RGBA).
Float4(&'a mut [f32; 4]),
}
// /// Mutable reference to an editable color value.
// #[derive(Debug)]
// pub enum EditableColor<'a, T> {
// /// Color value with three float components (e.g. RGB).
// Float3(&'a mut T),
// /// Color value with four float components (e.g. RGBA).
// Float4(&'a mut T),
// }
impl<'a> EditableColor<'a> {
/// Returns an unsafe mutable pointer to the color slice's buffer.
fn as_mut_ptr(&mut self) -> *mut f32 {
match *self {
EditableColor::Float3(ref mut value) => value.as_mut_ptr(),
EditableColor::Float4(ref mut value) => value.as_mut_ptr(),
}
}
}
// impl<'a> EditableColor<'a> {
// /// Returns an unsafe mutable pointer to the color slice's buffer.
// fn as_mut_ptr(&mut self) -> *mut f32 {
// match *self {
// EditableColor::Float3(ref mut value) => value.as_mut_ptr(),
// EditableColor::Float4(ref mut value) => value.as_mut_ptr(),
// }
// }
// }
impl<'a> From<&'a mut [f32; 3]> for EditableColor<'a> {
#[inline]
fn from(value: &'a mut [f32; 3]) -> EditableColor<'a> {
EditableColor::Float3(value)
}
}
// impl<'a> From<&'a mut [f32; 3]> for EditableColor<'a> {
// #[inline]
// fn from(value: &'a mut [f32; 3]) -> EditableColor<'a> {
// EditableColor::Float3(value)
// }
// }
impl<'a> From<&'a mut [f32; 4]> for EditableColor<'a> {
#[inline]
fn from(value: &'a mut [f32; 4]) -> EditableColor<'a> {
EditableColor::Float4(value)
}
}
// impl<'a> From<&'a mut [f32; 4]> for EditableColor<'a> {
// #[inline]
// fn from(value: &'a mut [f32; 4]) -> EditableColor<'a> {
// EditableColor::Float4(value)
// }
// }
/// Color editor input mode.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -176,26 +179,31 @@ bitflags! {
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let ce = ColorEdit::new(im_str!("color_edit"), &mut color);
/// let ce = ColorEdit4::new("color_edit", &mut color);
/// if ce.build(&ui) {
/// println!("The color was changed");
/// }
/// ```
#[derive(Debug)]
#[must_use]
pub struct ColorEdit<'a, T: AsRef<str> + 'a> {
pub struct ColorEdit3<'a, T, C> {
label: T,
value: EditableColor<'a>,
value: &'a mut C,
flags: ColorEditFlags,
}
impl<'a, T: AsRef<str> + 'a> ColorEdit<'a, T> {
impl<'a, T, C> ColorEdit3<'a, T, C>
where
T: AsRef<str>,
C: Copy + Into<MintVec3>,
MintVec3: Into<C> + Into<[f32; 3]>,
{
/// Constructs a new color editor builder.
#[doc(alias = "ColorEdit3", alias = "ColorEdit4")]
pub fn new(label: T, value: impl Into<EditableColor<'a>>) -> ColorEdit<'a, T> {
ColorEdit {
#[doc(alias = "ColorEdit3")]
pub fn new(label: T, value: &'a mut C) -> Self {
ColorEdit3 {
label,
value: value.into(),
value,
flags: ColorEditFlags::empty(),
}
}
@ -319,26 +327,208 @@ impl<'a, T: AsRef<str> + 'a> ColorEdit<'a, T> {
///
/// Returns true if the color value was changed.
pub fn build(mut self, ui: &Ui<'_>) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ColorEditFlags::NO_ALPHA);
// if let EditableColor::Float3(_) = self.value {
self.flags.insert(ColorEditFlags::NO_ALPHA);
let as_vec3: MintVec3 = (*self.value).into();
let mut as_vec3: [f32; 3] = as_vec3.into();
let changed = unsafe {
sys::igColorEdit3(
ui.scratch_txt(self.label),
as_vec3.as_mut_ptr(),
self.flags.bits() as _,
)
};
// and go backwards...
if changed {
let as_vec3: MintVec3 = as_vec3.into();
*self.value = as_vec3.into();
}
match self.value {
EditableColor::Float3(value) => unsafe {
sys::igColorEdit3(
ui.scratch_txt(self.label),
value.as_mut_ptr(),
self.flags.bits() as _,
)
},
EditableColor::Float4(value) => unsafe {
sys::igColorEdit4(
ui.scratch_txt(self.label),
value.as_mut_ptr(),
self.flags.bits() as _,
)
},
changed
}
}
/// Builder for a color editor widget.
///
/// # Examples
///
/// ```no_run
/// # use imgui::*;
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let ce = ColorEdit4::new("color_edit", &mut color);
/// if ce.build(&ui) {
/// println!("The color was changed");
/// }
/// ```
#[derive(Debug)]
#[must_use]
pub struct ColorEdit4<'a, T, C> {
label: T,
value: &'a mut C,
flags: ColorEditFlags,
}
impl<'a, T, C> ColorEdit4<'a, T, C>
where
T: AsRef<str>,
C: Copy + Into<MintVec4>,
MintVec4: Into<C> + Into<[f32; 4]>,
{
/// Constructs a new color editor builder.
#[doc(alias = "ColorEdit4")]
pub fn new(label: T, value: &'a mut C) -> Self {
Self {
label,
value,
flags: ColorEditFlags::empty(),
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
/// Enables/disables the picker that appears when clicking on colored square.
#[inline]
pub fn picker(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_PICKER, !value);
self
}
/// Enables/disables toggling of the options menu when right-clicking on inputs or the small
/// preview.
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
/// Sets the preview style.
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW_HALF,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW,
preview == ColorPreview::Alpha,
);
self
}
/// (WIP) Currently only disables 0.0..1.0 limits in RGBA edition.
///
/// Note: you probably want to use ColorFormat::Float as well.
#[inline]
pub fn hdr(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::HDR, value);
self
}
/// Sets the data format for input and output data.
#[inline]
pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
self.flags.set(
ColorEditFlags::INPUT_RGB,
input_mode == ColorEditInputMode::RGB,
);
self.flags.set(
ColorEditFlags::INPUT_HSV,
input_mode == ColorEditInputMode::HSV,
);
self
}
/// Sets the color editor display mode.
#[inline]
pub fn display_mode(mut self, mode: ColorEditDisplayMode) -> Self {
self.flags.set(
ColorEditFlags::DISPLAY_RGB,
mode == ColorEditDisplayMode::RGB,
);
self.flags.set(
ColorEditFlags::DISPLAY_HSV,
mode == ColorEditDisplayMode::HSV,
);
self.flags.set(
ColorEditFlags::DISPLAY_HEX,
mode == ColorEditDisplayMode::HEX,
);
self
}
/// Sets the formatting style of color components.
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ColorEditFlags::UINT8, format == ColorFormat::U8);
self.flags
.set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
self
}
/// Builds the color editor.
///
/// Returns true if the color value was changed.
pub fn build(self, ui: &Ui<'_>) -> bool {
let as_vec4: MintVec4 = (*self.value).into();
let mut as_vec4: [f32; 4] = as_vec4.into();
let changed = unsafe {
sys::igColorEdit4(
ui.scratch_txt(self.label),
as_vec4.as_mut_ptr(),
self.flags.bits() as _,
)
};
// and go backwards...
if changed {
let as_vec4: MintVec4 = as_vec4.into();
*self.value = as_vec4.into();
}
changed
}
}
/// Builder for a color picker widget.
@ -350,27 +540,216 @@ impl<'a, T: AsRef<str> + 'a> ColorEdit<'a, T> {
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let cp = ColorPicker::new(im_str!("color_picker"), &mut color);
/// let cp = ColorPicker4::new("color_picker", &mut color);
/// if cp.build(&ui) {
/// println!("A color was picked");
/// }
/// ```
#[derive(Debug)]
#[must_use]
pub struct ColorPicker<'a, T: AsRef<str> + 'a> {
label: T,
value: EditableColor<'a>,
pub struct ColorPicker3<'a, Label, Color> {
label: Label,
value: &'a mut Color,
flags: ColorEditFlags,
ref_color: Option<&'a [f32; 4]>,
}
impl<'a, T: AsRef<str>> ColorPicker<'a, T> {
impl<'a, Label, Color> ColorPicker3<'a, Label, Color>
where
Label: AsRef<str>,
Color: Copy + Into<MintVec3>,
MintVec3: Into<Color> + Into<[f32; 3]>,
{
/// Constructs a new color picker builder.
#[doc(alias = "ColorButton")]
pub fn new(label: T, value: impl Into<EditableColor<'a>>) -> Self {
ColorPicker {
#[doc(alias = "ColorPicker3")]
pub fn new(label: Label, value: &'a mut Color) -> Self {
ColorPicker3 {
label,
value: value.into(),
value,
flags: ColorEditFlags::empty(),
}
}
/// Replaces all current settings with the given flags.
#[inline]
pub fn flags(mut self, flags: ColorEditFlags) -> Self {
self.flags = flags;
self
}
/// Enables/disables the use of the alpha component.
#[inline]
pub fn alpha(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_ALPHA, !value);
self
}
/// Enables/disables toggling of the options menu when right-clicking on inputs or the small
/// preview.
#[inline]
pub fn options(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_OPTIONS, !value);
self
}
/// Enables/disables the colored square preview next to the inputs.
#[inline]
pub fn small_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SMALL_PREVIEW, !value);
self
}
/// Enables/disables the input sliders/text widgets.
#[inline]
pub fn inputs(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_INPUTS, !value);
self
}
/// Enables/disables the tooltip that appears when hovering the preview.
#[inline]
pub fn tooltip(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_TOOLTIP, !value);
self
}
/// Enables/disables display of the inline text label (the label is in any case forwarded to
/// the tooltip and picker).
#[inline]
pub fn label(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_LABEL, !value);
self
}
/// Enables/disables the bigger color preview on the right side of the picker.
#[inline]
pub fn side_preview(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::NO_SIDE_PREVIEW, !value);
self
}
/// Enables/disables the vertical alpha bar/gradient in the color picker.
#[inline]
pub fn alpha_bar(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::ALPHA_BAR, value);
self
}
/// Sets the preview style.
#[inline]
pub fn preview(mut self, preview: ColorPreview) -> Self {
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW_HALF,
preview == ColorPreview::HalfAlpha,
);
self.flags.set(
ColorEditFlags::ALPHA_PREVIEW,
preview == ColorPreview::Alpha,
);
self
}
/// Sets the data format for input and output data.
#[inline]
pub fn input_mode(mut self, input_mode: ColorEditInputMode) -> Self {
self.flags.set(
ColorEditFlags::INPUT_RGB,
input_mode == ColorEditInputMode::RGB,
);
self.flags.set(
ColorEditFlags::INPUT_HSV,
input_mode == ColorEditInputMode::HSV,
);
self
}
/// Enables/disables displaying the value as RGB.
#[inline]
pub fn display_rgb(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_RGB, value);
self
}
/// Enables/disables displaying the value as HSV.
#[inline]
pub fn display_hsv(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HSV, value);
self
}
/// Enables/disables displaying the value as hex.
#[inline]
pub fn display_hex(mut self, value: bool) -> Self {
self.flags.set(ColorEditFlags::DISPLAY_HEX, value);
self
}
/// Sets the hue/saturation/value editor mode.
#[inline]
pub fn mode(mut self, mode: ColorPickerMode) -> Self {
self.flags.set(
ColorEditFlags::PICKER_HUE_BAR,
mode == ColorPickerMode::HueBar,
);
self.flags.set(
ColorEditFlags::PICKER_HUE_WHEEL,
mode == ColorPickerMode::HueWheel,
);
self
}
/// Sets the formatting style of color components.
#[inline]
pub fn format(mut self, format: ColorFormat) -> Self {
self.flags
.set(ColorEditFlags::UINT8, format == ColorFormat::U8);
self.flags
.set(ColorEditFlags::FLOAT, format == ColorFormat::Float);
self
}
/// Builds the color picker.
///
/// Returns true if the color value was changed.
pub fn build(mut self, ui: &Ui<'_>) -> bool {
self.flags.insert(ColorEditFlags::NO_ALPHA);
let mut value: [f32; 3] = (*self.value).into().into();
let changed = unsafe {
sys::igColorPicker3(
ui.scratch_txt(self.label),
value.as_mut_ptr(),
self.flags.bits() as _,
)
};
if changed {
let as_vec3: MintVec3 = value.into();
*self.value = as_vec3.into();
}
changed
}
}
// Builder for a color picker widget.
///
/// # Examples
///
/// ```no_run
/// # use imgui::*;
/// # let mut imgui = Context::create();
/// # let ui = imgui.frame();
/// # let mut color = [0.0, 0.0, 0.0, 1.0];
/// let cp = ColorPicker4::new("color_picker", &mut color);
/// if cp.build(&ui) {
/// println!("A color was picked");
/// }
/// ```
#[derive(Debug)]
#[must_use]
pub struct ColorPicker4<'a, Label, Color> {
label: Label,
value: &'a mut Color,
flags: ColorEditFlags,
ref_color: Option<[f32; 4]>,
}
impl<'a, Label, Color> ColorPicker4<'a, Label, Color>
where
Label: AsRef<str>,
Color: Copy + Into<MintVec4>,
MintVec4: Into<Color> + Into<[f32; 4]>,
{
/// Constructs a new color picker builder.
#[doc(alias = "ColorPicker4")]
pub fn new(label: Label, value: &'a mut Color) -> Self {
Self {
label,
value,
flags: ColorEditFlags::empty(),
ref_color: None,
}
@ -499,26 +878,35 @@ impl<'a, T: AsRef<str>> ColorPicker<'a, T> {
}
/// Sets the shown reference color.
#[inline]
pub fn reference_color(mut self, ref_color: &'a [f32; 4]) -> Self {
self.ref_color = Some(ref_color);
pub fn reference_color(mut self, ref_color: impl Into<MintVec4>) -> Self {
self.ref_color = Some(ref_color.into().into());
self
}
/// Builds the color picker.
///
/// Returns true if the color value was changed.
pub fn build(mut self, ui: &Ui<'_>) -> bool {
if let EditableColor::Float3(_) = self.value {
self.flags.insert(ColorEditFlags::NO_ALPHA);
}
self.flags.insert(ColorEditFlags::NO_ALPHA);
let mut value: [f32; 4] = (*self.value).into().into();
let ref_color = self.ref_color.map(|c| c.as_ptr()).unwrap_or(ptr::null());
unsafe {
let changed = unsafe {
sys::igColorPicker4(
ui.scratch_txt(self.label),
self.value.as_mut_ptr(),
value.as_mut_ptr(),
self.flags.bits() as _,
ref_color,
)
};
if changed {
let as_vec3: MintVec4 = value.into();
*self.value = as_vec3.into();
}
changed
}
}
@ -544,10 +932,10 @@ pub struct ColorButton<T> {
impl<T: AsRef<str>> ColorButton<T> {
/// Constructs a new color button builder.
pub fn new(desc_id: T, color: [f32; 4]) -> Self {
pub fn new(desc_id: T, color: impl Into<MintVec4>) -> Self {
ColorButton {
desc_id,
color,
color: color.into().into(),
flags: ColorEditFlags::empty(),
size: [0.0, 0.0],
}
@ -614,8 +1002,8 @@ impl<T: AsRef<str>> ColorButton<T> {
///
/// Use 0.0 for width and/or height to use the default size.
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
self.size = size.into().into();
self
}
/// Builds the color button.

View File

@ -1,5 +1,7 @@
use std::os::raw::c_void;
use crate::math::MintVec2;
use crate::math::MintVec4;
use crate::render::renderer::TextureId;
use crate::sys;
use crate::Ui;
@ -19,10 +21,10 @@ pub struct Image {
impl Image {
/// Creates a new image builder with the given texture and size
#[doc(alias = "Image")]
pub const fn new(texture_id: TextureId, size: [f32; 2]) -> Image {
pub fn new(texture_id: TextureId, size: impl Into<MintVec2>) -> Image {
Image {
texture_id,
size,
size: size.into().into(),
uv0: [0.0, 0.0],
uv1: [1.0, 1.0],
tint_col: [1.0, 1.0, 1.0, 1.0],
@ -30,28 +32,29 @@ impl Image {
}
}
/// Sets the image size
pub const fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
#[deprecated(note = "just set the size in the `new` constructor.")]
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
self.size = size.into().into();
self
}
/// Sets uv0 (default `[0.0, 0.0]`)
pub const fn uv0(mut self, uv0: [f32; 2]) -> Self {
self.uv0 = uv0;
pub fn uv0(mut self, uv0: impl Into<MintVec2>) -> Self {
self.uv0 = uv0.into().into();
self
}
/// Sets uv1 (default `[1.0, 1.0]`)
pub const fn uv1(mut self, uv1: [f32; 2]) -> Self {
self.uv1 = uv1;
pub fn uv1(mut self, uv1: impl Into<MintVec2>) -> Self {
self.uv1 = uv1.into().into();
self
}
/// Sets the tint color (default: no tint color)
pub const fn tint_col(mut self, tint_col: [f32; 4]) -> Self {
self.tint_col = tint_col;
pub fn tint_col(mut self, tint_col: impl Into<MintVec4>) -> Self {
self.tint_col = tint_col.into().into();
self
}
/// Sets the border color (default: no border)
pub const fn border_col(mut self, border_col: [f32; 4]) -> Self {
self.border_col = border_col;
pub fn border_col(mut self, border_col: impl Into<MintVec4>) -> Self {
self.border_col = border_col.into().into();
self
}
/// Builds the image
@ -85,10 +88,10 @@ pub struct ImageButton {
impl ImageButton {
/// Creates a new image button builder with the given texture and size
#[doc(alias = "ImageButton")]
pub fn new(texture_id: TextureId, size: [f32; 2]) -> ImageButton {
pub fn new(texture_id: TextureId, size: impl Into<MintVec2>) -> ImageButton {
ImageButton {
texture_id,
size,
size: size.into().into(),
uv0: [0.0, 0.0],
uv1: [1.0, 1.0],
frame_padding: -1,
@ -96,19 +99,21 @@ impl ImageButton {
tint_col: [1.0, 1.0, 1.0, 1.0],
}
}
/// Sets the image button size
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
#[deprecated(note = "just set the size in the `new` constructor.")]
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
self.size = size.into().into();
self
}
/// Sets uv0 (default `[0.0, 0.0]`)
pub fn uv0(mut self, uv0: [f32; 2]) -> Self {
self.uv0 = uv0;
pub fn uv0(mut self, uv0: impl Into<MintVec2>) -> Self {
self.uv0 = uv0.into().into();
self
}
/// Sets uv1 (default `[1.0, 1.0]`)
pub fn uv1(mut self, uv1: [f32; 2]) -> Self {
self.uv1 = uv1;
pub fn uv1(mut self, uv1: impl Into<MintVec2>) -> Self {
self.uv1 = uv1.into().into();
self
}
/// Sets the frame padding (default: uses frame padding from style).
@ -121,13 +126,13 @@ impl ImageButton {
self
}
/// Sets the background color (default: no background color)
pub fn background_col(mut self, bg_col: [f32; 4]) -> Self {
self.bg_col = bg_col;
pub fn background_col(mut self, bg_col: impl Into<MintVec4>) -> Self {
self.bg_col = bg_col.into().into();
self
}
/// Sets the tint color (default: no tint color)
pub fn tint_col(mut self, tint_col: [f32; 4]) -> Self {
self.tint_col = tint_col;
pub fn tint_col(mut self, tint_col: impl Into<MintVec4>) -> Self {
self.tint_col = tint_col.into().into();
self
}
/// Builds the image button

View File

@ -8,7 +8,7 @@ use crate::Ui;
#[must_use]
pub struct ListBox<T> {
label: T,
size: sys::ImVec2,
size: [f32; 2],
}
impl<T: AsRef<str>> ListBox<T> {
@ -17,7 +17,7 @@ impl<T: AsRef<str>> ListBox<T> {
pub fn new(label: T) -> ListBox<T> {
ListBox {
label,
size: sys::ImVec2::zero(),
size: [0.0, 0.0],
}
}
@ -28,8 +28,8 @@ impl<T: AsRef<str>> ListBox<T> {
///
/// Default: [0.0, 0.0], in which case the combobox calculates a sensible width and height
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = sys::ImVec2::new(size[0], size[1]);
pub fn size(mut self, size: impl Into<crate::math::MintVec2>) -> Self {
self.size = size.into().into();
self
}
/// Creates a list box and starts appending to it.
@ -40,7 +40,8 @@ impl<T: AsRef<str>> ListBox<T> {
/// Returns `None` if the list box is not open and no content should be rendered.
#[must_use]
pub fn begin<'ui>(self, ui: &Ui<'ui>) -> Option<ListBoxToken<'ui>> {
let should_render = unsafe { sys::igBeginListBox(ui.scratch_txt(self.label), self.size) };
let should_render =
unsafe { sys::igBeginListBox(ui.scratch_txt(self.label), self.size.into()) };
if should_render {
Some(ListBoxToken::new(ui))
} else {

View File

@ -1,6 +1,7 @@
use bitflags::bitflags;
use std::ops::{BitAnd, BitAndAssign, BitOrAssign, Not};
use crate::math::MintVec2;
use crate::sys;
use crate::{Direction, Ui};
@ -38,8 +39,8 @@ impl<'ui> Ui<'ui> {
/// Setting `size` as `[0.0, 0.0]` will size the button to the label's width in
/// the current style.
#[doc(alias = "Button")]
pub fn button_with_size(&self, label: impl AsRef<str>, size: [f32; 2]) -> bool {
unsafe { sys::igButton(self.scratch_txt(label), size.into()) }
pub fn button_with_size(&self, label: impl AsRef<str>, size: impl Into<MintVec2>) -> bool {
unsafe { sys::igButton(self.scratch_txt(label), size.into().into()) }
}
/// Renders a small clickable button that is easy to embed in text.
///
@ -52,8 +53,8 @@ impl<'ui> Ui<'ui> {
///
/// Returns true if this button was clicked.
#[doc(alias = "InvisibleButton")]
pub fn invisible_button(&self, id: impl AsRef<str>, size: [f32; 2]) -> bool {
unsafe { sys::igInvisibleButton(self.scratch_txt(id), size.into(), 0) }
pub fn invisible_button(&self, id: impl AsRef<str>, size: impl Into<MintVec2>) -> bool {
unsafe { sys::igInvisibleButton(self.scratch_txt(id), size.into().into(), 0) }
}
/// Renders a widget with button behaviour without the visual look.
///
@ -62,10 +63,16 @@ impl<'ui> Ui<'ui> {
pub fn invisible_button_flags(
&self,
id: impl AsRef<str>,
size: [f32; 2],
size: impl Into<MintVec2>,
flags: ButtonFlags,
) -> bool {
unsafe { sys::igInvisibleButton(self.scratch_txt(id), size.into(), flags.bits() as i32) }
unsafe {
sys::igInvisibleButton(
self.scratch_txt(id),
size.into().into(),
flags.bits() as i32,
)
}
}
/// Renders a square button with an arrow shape.
///

View File

@ -1,3 +1,4 @@
use crate::math::MintVec2;
use crate::sys;
// use crate::ImStr;
use crate::Ui;
@ -55,8 +56,8 @@ impl<T: AsRef<str>> ProgressBar<T> {
/// Negative values will automatically align to the end of the axis, zero will let the progress
/// bar choose a size, and positive values will use the given size.
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
self.size = size.into().into();
self
}

View File

@ -1,5 +1,6 @@
use bitflags::bitflags;
use crate::math::MintVec2;
use crate::sys;
use crate::Ui;
@ -100,8 +101,8 @@ impl<T: AsRef<str>> Selectable<T> {
/// - `> 0.0`: use given height
/// - `= 0.0`: use label height
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
pub fn size(mut self, size: impl Into<MintVec2>) -> Self {
self.size = size.into().into();
self
}
/// Builds the selectable.

View File

@ -2,6 +2,7 @@ use bitflags::bitflags;
use std::os::raw::c_void;
use crate::internal::DataTypeKind;
use crate::math::MintVec2;
use crate::sys;
use crate::Ui;
@ -161,10 +162,10 @@ where
/// It is safe, though up to C++ Dear ImGui, on how to handle when
/// `min > max`.
#[doc(alias = "VSliderScalar")]
pub fn new(label: Label, size: [f32; 2], min: Data, max: Data) -> Self {
pub fn new(label: Label, size: impl Into<MintVec2>, min: Data, max: Data) -> Self {
VerticalSlider {
label,
size,
size: size.into().into(),
min,
max,
display_format: None,

View File

@ -1,5 +1,6 @@
use std::os::raw::c_char;
use crate::math::MintVec4;
// use crate::string::ImStr;
use crate::style::StyleColor;
use crate::Ui;
@ -24,7 +25,7 @@ impl<'ui> Ui<'ui> {
}
}
/// Renders simple text using the given text color
pub fn text_colored<T: AsRef<str>>(&self, color: [f32; 4], text: T) {
pub fn text_colored<T: AsRef<str>>(&self, color: impl Into<MintVec4>, text: T) {
let style = self.push_style_color(StyleColor::Text, color);
self.text(text);
style.end();

View File

@ -1,5 +1,6 @@
use std::f32;
use crate::math::MintVec2;
use crate::sys;
use crate::window::WindowFlags;
use crate::Ui;
@ -47,8 +48,8 @@ impl<'ui, Label: AsRef<str>> ChildWindow<'ui, Label> {
/// - `= 0.0`: use remaining host window size
/// - `< 0.0`: use remaining host window size minus abs(size)
#[inline]
pub fn size(mut self, size: [f32; 2]) -> Self {
self.size = size;
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.
@ -57,8 +58,8 @@ impl<'ui, Label: AsRef<str>> ChildWindow<'ui, Label> {
/// 0.0 to leave the size automatic.
#[inline]
#[doc(alias = "SetNextWindowContentSize")]
pub fn content_size(mut self, size: [f32; 2]) -> Self {
self.content_size = size;
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

View File

@ -2,6 +2,7 @@ use bitflags::bitflags;
use std::f32;
use std::ptr;
use crate::math::MintVec2;
use crate::sys;
use crate::{Condition, Ui};
@ -165,13 +166,13 @@ pub struct Window<'ui, 'a, Label> {
name: Label,
opened: Option<&'a mut bool>,
flags: WindowFlags,
pos: [f32; 2],
pos: MintVec2,
pos_cond: Condition,
pos_pivot: [f32; 2],
size: [f32; 2],
pos_pivot: MintVec2,
size: MintVec2,
size_cond: Condition,
size_constraints: Option<([f32; 2], [f32; 2])>,
content_size: [f32; 2],
size_constraints: Option<(MintVec2, MintVec2)>,
content_size: MintVec2,
collapsed: bool,
collapsed_cond: Condition,
focused: bool,
@ -186,13 +187,13 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
name,
opened: None,
flags: WindowFlags::empty(),
pos: [0.0, 0.0],
pos: [0.0, 0.0].into(),
pos_cond: Condition::Never,
pos_pivot: [0.0, 0.0],
size: [0.0, 0.0],
pos_pivot: [0.0, 0.0].into(),
size: [0.0, 0.0].into(),
size_cond: Condition::Never,
size_constraints: None,
content_size: [0.0, 0.0],
content_size: [0.0, 0.0].into(),
collapsed: false,
collapsed_cond: Condition::Never,
focused: false,
@ -213,8 +214,8 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
}
/// Sets the window position, which is applied based on the given condition value
#[inline]
pub fn position(mut self, position: [f32; 2], condition: Condition) -> Self {
self.pos = position;
pub fn position(mut self, position: impl Into<MintVec2>, condition: Condition) -> Self {
self.pos = position.into();
self.pos_cond = condition;
self
}
@ -224,14 +225,14 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
/// For example, pass [0.5, 0.5] to center the window on the position.
/// Does nothing if window position is not also set with `position()`.
#[inline]
pub fn position_pivot(mut self, pivot: [f32; 2]) -> Self {
self.pos_pivot = pivot;
pub fn position_pivot(mut self, pivot: impl Into<MintVec2>) -> Self {
self.pos_pivot = pivot.into();
self
}
/// Sets the window size, which is applied based on the given condition value
#[inline]
pub fn size(mut self, size: [f32; 2], condition: Condition) -> Self {
self.size = size;
pub fn size(mut self, size: impl Into<MintVec2>, condition: Condition) -> Self {
self.size = size.into();
self.size_cond = condition;
self
}
@ -239,8 +240,12 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
///
/// Use -1.0, -1.0 on either X or Y axis to preserve current size.
#[inline]
pub fn size_constraints(mut self, size_min: [f32; 2], size_max: [f32; 2]) -> Self {
self.size_constraints = Some((size_min, size_max));
pub fn size_constraints(
mut self,
size_min: impl Into<MintVec2>,
size_max: impl Into<MintVec2>,
) -> Self {
self.size_constraints = Some((size_min.into(), size_max.into()));
self
}
/// Sets the window content size, which can be used to enforce scrollbars.
@ -248,8 +253,8 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
/// Does not include window decorations (title bar, menu bar, etc.). Set one of the values to
/// 0.0 to leave the size automatic.
#[inline]
pub fn content_size(mut self, size: [f32; 2]) -> Self {
self.content_size = size;
pub fn content_size(mut self, size: impl Into<MintVec2>) -> Self {
self.content_size = size.into();
self
}
/// Sets the window collapse state, which is applied based on the given condition value
@ -513,7 +518,7 @@ impl<'ui, 'a, Label: AsRef<str>> Window<'ui, 'a, Label> {
)
};
}
if self.content_size[0] != 0.0 || self.content_size[1] != 0.0 {
if self.content_size.x != 0.0 || self.content_size.y != 0.0 {
unsafe { sys::igSetNextWindowContentSize(self.content_size.into()) };
}
if self.collapsed_cond != Condition::Never {