diff --git a/src/window_draw_list.rs b/src/window_draw_list.rs index f61ad42..abc6a53 100644 --- a/src/window_draw_list.rs +++ b/src/window_draw_list.rs @@ -45,14 +45,6 @@ impl From<(f32, f32, f32)> for ImColor { fn from(v: (f32, f32, f32)) -> Self { [v.0, v.1, v.2, 1.0].into() } } -/// All types from which ImGui's custom draw API can be used implement this -/// trait. This trait is internal to this library and implemented by -/// `WindowDrawList` and `ChannelsSplit`. -pub trait DrawAPI { - /// Get draw_list object - fn draw_list(&self) -> *mut ImDrawList; -} - /// Object implementing the custom draw API. /// /// Called from [`Ui::get_window_draw_list`]. No more than one instance of this @@ -63,10 +55,6 @@ pub struct WindowDrawList<'ui> { _phantom: PhantomData<&'ui Ui<'ui>>, } -impl<'ui> DrawAPI for WindowDrawList<'ui> { - fn draw_list(&self) -> *mut ImDrawList { self.draw_list } -} - static mut WINDOW_DRAW_LIST_LOADED: bool = false; impl<'ui> Drop for WindowDrawList<'ui> { @@ -126,10 +114,6 @@ pub struct ChannelsSplit<'ui> { channels_count: u32, } -impl<'ui> DrawAPI for ChannelsSplit<'ui> { - fn draw_list(&self) -> *mut ImDrawList { self.draw_list.draw_list } -} - impl<'ui> ChannelsSplit<'ui> { /// Change current channel. /// @@ -141,170 +125,153 @@ impl<'ui> ChannelsSplit<'ui> { channel_index, self.channels_count ); - unsafe { sys::ImDrawList_ChannelsSetCurrent(self.draw_list(), channel_index as i32) }; + unsafe { + sys::ImDrawList_ChannelsSetCurrent(self.draw_list.draw_list, channel_index as i32) + }; } } -macro_rules! impl_draw_list_methods { - ($T: ident) => { - impl<'ui> $T<'ui> - where - $T<'ui>: DrawAPI, - { - /// Returns a line from point `p1` to `p2` with color `c`. - pub fn add_line(&self, p1: P1, p2: P2, c: C) -> Line<'ui, $T> - where - P1: Into, - P2: Into, - C: Into, - { - Line::new(self, p1, p2, c) - } +/// Drawing functions +impl<'ui> WindowDrawList<'ui> { + /// Returns a line from point `p1` to `p2` with color `c`. + pub fn add_line(&'ui self, p1: P1, p2: P2, c: C) -> Line<'ui> + where + P1: Into, + P2: Into, + C: Into, + { + Line::new(self, p1, p2, c) + } - /// Returns a rectangle whose upper-left corner is at point `p1` - /// and lower-right corner is at point `p2`, with color `c`. - pub fn add_rect(&self, p1: P1, p2: P2, c: C) -> Rect<'ui, $T> - where - P1: Into, - P2: Into, - C: Into, - { - Rect::new(self, p1, p2, c) - } + /// Returns a rectangle whose upper-left corner is at point `p1` + /// and lower-right corner is at point `p2`, with color `c`. + pub fn add_rect(&'ui self, p1: P1, p2: P2, c: C) -> Rect<'ui> + where + P1: Into, + P2: Into, + C: Into, + { + Rect::new(self, p1, p2, c) + } - /// Draw a rectangle whose upper-left corner is at point `p1` - /// and lower-right corner is at point `p2`. - /// The remains parameters are the respective color of the corners - /// in the counter-clockwise starting from the upper-left corner - /// first. - pub fn add_rect_filled_multicolor( - &self, - p1: P1, - p2: P2, - col_upr_left: C1, - col_upr_right: C2, - col_bot_right: C3, - col_bot_left: C4, - ) where - P1: Into, - P2: Into, - C1: Into, - C2: Into, - C3: Into, - C4: Into, - { - unsafe { - sys::ImDrawList_AddRectFilledMultiColor( - self.draw_list(), - p1.into(), - p2.into(), - col_upr_left.into().into(), - col_upr_right.into().into(), - col_bot_right.into().into(), - col_bot_left.into().into(), - ); - } - } - - /// Returns a triangle with the given 3 vertices `p1`, `p2` and `p3` - /// and color `c`. - pub fn add_triangle( - &self, - p1: P1, - p2: P2, - p3: P3, - c: C, - ) -> Triangle<'ui, $T> - where - P1: Into, - P2: Into, - P3: Into, - C: Into, - { - Triangle::new(self, p1, p2, p3, c) - } - - /// Returns a circle with the given `center`, `radius` and `color`. - pub fn add_circle(&self, center: P, radius: f32, color: C) -> Circle<'ui, $T> - where - P: Into, - C: Into, - { - Circle::new(self, center, radius, color) - } - - /// Returns a Bezier curve stretching from `pos0` to `pos1`, whose - /// curvature is defined by `cp0` and `cp1`. - pub fn add_bezier_curve( - &self, - pos0: P1, - cp0: P2, - cp1: P3, - pos1: P4, - color: C, - ) -> BezierCurve<'ui, $T> - where - P1: Into, - P2: Into, - P3: Into, - P4: Into, - C: Into, - { - BezierCurve::new(self, pos0, cp0, cp1, pos1, color) - } - - /// Push a clipping rectangle on the stack, run `f` and pop it. - /// - /// Clip all drawings done within the closure `f` in the given - /// rectangle. - pub fn with_clip_rect(&self, min: P1, max: P2, f: F) - where - P1: Into, - P2: Into, - F: FnOnce(), - { - unsafe { - sys::ImDrawList_PushClipRect(self.draw_list(), min.into(), max.into(), false) - } - f(); - unsafe { sys::ImDrawList_PopClipRect(self.draw_list()) } - } - - /// Push a clipping rectangle on the stack, run `f` and pop it. - /// - /// Clip all drawings done within the closure `f` in the given - /// rectangle. Intersect with all clipping rectangle previously on - /// the stack. - pub fn with_clip_rect_intersect(&self, min: P1, max: P2, f: F) - where - P1: Into, - P2: Into, - F: FnOnce(), - { - unsafe { - sys::ImDrawList_PushClipRect(self.draw_list(), min.into(), max.into(), true) - } - f(); - unsafe { sys::ImDrawList_PopClipRect(self.draw_list()) } - } + /// Draw a rectangle whose upper-left corner is at point `p1` + /// and lower-right corner is at point `p2`. + /// The remains parameters are the respective color of the corners + /// in the counter-clockwise starting from the upper-left corner + /// first. + pub fn add_rect_filled_multicolor( + &self, + p1: P1, + p2: P2, + col_upr_left: C1, + col_upr_right: C2, + col_bot_right: C3, + col_bot_left: C4, + ) where + P1: Into, + P2: Into, + C1: Into, + C2: Into, + C3: Into, + C4: Into, + { + unsafe { + sys::ImDrawList_AddRectFilledMultiColor( + self.draw_list, + p1.into(), + p2.into(), + col_upr_left.into().into(), + col_upr_right.into().into(), + col_bot_right.into().into(), + col_bot_left.into().into(), + ); } - }; + } + + /// Returns a triangle with the given 3 vertices `p1`, `p2` and `p3` + /// and color `c`. + pub fn add_triangle(&'ui self, p1: P1, p2: P2, p3: P3, c: C) -> Triangle<'ui> + where + P1: Into, + P2: Into, + P3: Into, + C: Into, + { + Triangle::new(self, p1, p2, p3, c) + } + + /// Returns a circle with the given `center`, `radius` and `color`. + pub fn add_circle(&'ui self, center: P, radius: f32, color: C) -> Circle<'ui> + where + P: Into, + C: Into, + { + Circle::new(self, center, radius, color) + } + + /// Returns a Bezier curve stretching from `pos0` to `pos1`, whose + /// curvature is defined by `cp0` and `cp1`. + pub fn add_bezier_curve( + &'ui self, + pos0: P1, + cp0: P2, + cp1: P3, + pos1: P4, + color: C, + ) -> BezierCurve<'ui> + where + P1: Into, + P2: Into, + P3: Into, + P4: Into, + C: Into, + { + BezierCurve::new(self, pos0, cp0, cp1, pos1, color) + } + + /// Push a clipping rectangle on the stack, run `f` and pop it. + /// + /// Clip all drawings done within the closure `f` in the given + /// rectangle. + pub fn with_clip_rect(&self, min: P1, max: P2, f: F) + where + P1: Into, + P2: Into, + F: FnOnce(), + { + unsafe { sys::ImDrawList_PushClipRect(self.draw_list, min.into(), max.into(), false) } + f(); + unsafe { sys::ImDrawList_PopClipRect(self.draw_list) } + } + + /// Push a clipping rectangle on the stack, run `f` and pop it. + /// + /// Clip all drawings done within the closure `f` in the given + /// rectangle. Intersect with all clipping rectangle previously on + /// the stack. + pub fn with_clip_rect_intersect(&self, min: P1, max: P2, f: F) + where + P1: Into, + P2: Into, + F: FnOnce(), + { + unsafe { sys::ImDrawList_PushClipRect(self.draw_list, min.into(), max.into(), true) } + f(); + unsafe { sys::ImDrawList_PopClipRect(self.draw_list) } + } } -impl_draw_list_methods!(WindowDrawList); -impl_draw_list_methods!(ChannelsSplit); - /// Represents a line about to be drawn -pub struct Line<'ui, D: 'ui> { +pub struct Line<'ui> { p1: ImVec2, p2: ImVec2, color: ImColor, thickness: f32, - draw_list: &'ui D, + draw_list: &'ui WindowDrawList<'ui>, } -impl<'ui, D: DrawAPI> Line<'ui, D> { - fn new(draw_list: &'ui D, p1: P1, p2: P2, c: C) -> Self +impl<'ui> Line<'ui> { + fn new(draw_list: &'ui WindowDrawList, p1: P1, p2: P2, c: C) -> Self where P1: Into, P2: Into, @@ -329,7 +296,7 @@ impl<'ui, D: DrawAPI> Line<'ui, D> { pub fn build(self) { unsafe { sys::ImDrawList_AddLine( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.p1, self.p2, self.color.into(), @@ -340,7 +307,7 @@ impl<'ui, D: DrawAPI> Line<'ui, D> { } /// Represents a rectangle about to be drawn -pub struct Rect<'ui, D: 'ui> { +pub struct Rect<'ui> { p1: ImVec2, p2: ImVec2, color: ImColor, @@ -348,11 +315,11 @@ pub struct Rect<'ui, D: 'ui> { flags: ImDrawCornerFlags, thickness: f32, filled: bool, - draw_list: &'ui D, + draw_list: &'ui WindowDrawList<'ui>, } -impl<'ui, D: DrawAPI> Rect<'ui, D> { - fn new(draw_list: &'ui D, p1: P1, p2: P2, c: C) -> Self +impl<'ui> Rect<'ui> { + fn new(draw_list: &'ui WindowDrawList, p1: P1, p2: P2, c: C) -> Self where P1: Into, P2: Into, @@ -418,7 +385,7 @@ impl<'ui, D: DrawAPI> Rect<'ui, D> { if self.filled { unsafe { sys::ImDrawList_AddRectFilled( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.p1, self.p2, self.color.into(), @@ -429,7 +396,7 @@ impl<'ui, D: DrawAPI> Rect<'ui, D> { } else { unsafe { sys::ImDrawList_AddRect( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.p1, self.p2, self.color.into(), @@ -443,18 +410,18 @@ impl<'ui, D: DrawAPI> Rect<'ui, D> { } /// Represents a triangle about to be drawn on the window -pub struct Triangle<'ui, D: 'ui> { +pub struct Triangle<'ui> { p1: ImVec2, p2: ImVec2, p3: ImVec2, color: ImColor, thickness: f32, filled: bool, - draw_list: &'ui D, + draw_list: &'ui WindowDrawList<'ui>, } -impl<'ui, D: DrawAPI> Triangle<'ui, D> { - fn new(draw_list: &'ui D, p1: P1, p2: P2, p3: P3, c: C) -> Self +impl<'ui> Triangle<'ui> { + fn new(draw_list: &'ui WindowDrawList, p1: P1, p2: P2, p3: P3, c: C) -> Self where P1: Into, P2: Into, @@ -489,7 +456,7 @@ impl<'ui, D: DrawAPI> Triangle<'ui, D> { if self.filled { unsafe { sys::ImDrawList_AddTriangleFilled( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.p1, self.p2, self.p3, @@ -499,7 +466,7 @@ impl<'ui, D: DrawAPI> Triangle<'ui, D> { } else { unsafe { sys::ImDrawList_AddTriangle( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.p1, self.p2, self.p3, @@ -512,18 +479,18 @@ impl<'ui, D: DrawAPI> Triangle<'ui, D> { } /// Represents a circle about to be drawn -pub struct Circle<'ui, D: 'ui> { +pub struct Circle<'ui> { center: ImVec2, radius: f32, color: ImColor, num_segments: u32, thickness: f32, filled: bool, - draw_list: &'ui D, + draw_list: &'ui WindowDrawList<'ui>, } -impl<'ui, D: DrawAPI> Circle<'ui, D> { - pub fn new(draw_list: &'ui D, center: P, radius: f32, color: C) -> Self +impl<'ui> Circle<'ui> { + pub fn new(draw_list: &'ui WindowDrawList, center: P, radius: f32, color: C) -> Self where P: Into, C: Into, @@ -563,7 +530,7 @@ impl<'ui, D: DrawAPI> Circle<'ui, D> { if self.filled { unsafe { sys::ImDrawList_AddCircleFilled( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.center, self.radius, self.color.into(), @@ -573,7 +540,7 @@ impl<'ui, D: DrawAPI> Circle<'ui, D> { } else { unsafe { sys::ImDrawList_AddCircle( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.center, self.radius, self.color.into(), @@ -586,7 +553,7 @@ impl<'ui, D: DrawAPI> Circle<'ui, D> { } /// Represents a Bezier curve about to be drawn -pub struct BezierCurve<'ui, D: 'ui> { +pub struct BezierCurve<'ui> { pos0: ImVec2, cp0: ImVec2, pos1: ImVec2, @@ -595,11 +562,18 @@ pub struct BezierCurve<'ui, D: 'ui> { thickness: f32, /// If num_segments is not set, the bezier curve is auto-tessalated. num_segments: Option, - draw_list: &'ui D, + draw_list: &'ui WindowDrawList<'ui>, } -impl<'ui, D: DrawAPI> BezierCurve<'ui, D> { - fn new(draw_list: &'ui D, pos0: P1, cp0: P2, cp1: P3, pos1: P4, c: C) -> Self +impl<'ui> BezierCurve<'ui> { + fn new( + draw_list: &'ui WindowDrawList, + pos0: P1, + cp0: P2, + cp1: P3, + pos1: P4, + c: C, + ) -> Self where P1: Into, P2: Into, @@ -636,7 +610,7 @@ impl<'ui, D: DrawAPI> BezierCurve<'ui, D> { pub fn build(self) { unsafe { sys::ImDrawList_AddBezierCurve( - self.draw_list.draw_list(), + self.draw_list.draw_list, self.pos0, self.cp0, self.cp1,