WindowDrawList: Wrap add_rect method

This patch uses bitflags to set the whether the corners are rounded.
Hence the `ImDrawCornerFlags` struct is defined, but only used
internally.

Externally, the valule of the flags can be changed with methods on the
`Rect` structure such as `round_top_right` or `round_bot_left`.

This patch wraps both ImDrawList_AddRectFilled and ImDrawList_AddRect.
ImDrawList_AddRectFilled is seen as a particular case of `add_rect`
where `filled` is set to `true`.
This commit is contained in:
Malik Olivier Boussejra 2018-03-29 22:42:53 +09:00
parent db97041936
commit 05b382e317
2 changed files with 137 additions and 3 deletions

View File

@ -325,6 +325,26 @@ bitflags!(
}
);
bitflags!(
/// Flags for indictating which corner of a rectangle should be rounded
#[repr(C)]
pub struct ImDrawCornerFlags: c_int {
const TopLeft = 1 << 0;
const TopRight = 1 << 1;
const BotRight = 1 << 2;
const BotLeft = 1 << 3;
const Top = ImDrawCornerFlags::TopLeft.bits
| ImDrawCornerFlags::TopRight.bits;
const Bot = ImDrawCornerFlags::BotLeft.bits
| ImDrawCornerFlags::BotRight.bits;
const Left = ImDrawCornerFlags::TopLeft.bits
| ImDrawCornerFlags::BotLeft.bits;
const Right = ImDrawCornerFlags::TopRight.bits
| ImDrawCornerFlags::BotRight.bits;
const All = 0xF;
}
);
pub type ImGuiTextEditCallback = Option<
extern "C" fn(data: *mut ImGuiTextEditCallbackData) -> c_int,
>;
@ -1840,7 +1860,7 @@ extern "C" {
b: ImVec2,
col: ImU32,
rounding: c_float,
rounding_corners_flags: c_int,
rounding_corners_flags: ImDrawCornerFlags,
thickness: c_float,
);
pub fn ImDrawList_AddRectFilled(
@ -1849,7 +1869,7 @@ extern "C" {
b: ImVec2,
col: ImU32,
rounding: c_float,
rounding_corners_flags: c_int,
rounding_corners_flags: ImDrawCornerFlags,
);
pub fn ImDrawList_AddRectFilledMultiColor(
list: *mut ImDrawList,

View File

@ -1,5 +1,5 @@
use sys;
use sys::{ImDrawList, ImU32};
use sys::{ImDrawCornerFlags, ImDrawList, ImU32};
use super::{ImVec2, ImVec4, Ui};
@ -126,6 +126,17 @@ macro_rules! impl_draw_list_methods {
{
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<P1, P2, C>(&self, p1: P1, p2: P2, c: C) -> Rect<'ui, $T>
where
P1: Into<ImVec2>,
P2: Into<ImVec2>,
C: Into<ImColor>,
{
Rect::new(self, p1, p2, c)
}
}
};
}
@ -177,3 +188,106 @@ impl<'ui, D: DrawAPI<'ui>> Line<'ui, D> {
}
}
}
/// Represents a rectangle about to be drawn
pub struct Rect<'ui, D: 'ui> {
p1: ImVec2,
p2: ImVec2,
color: ImColor,
rounding: f32,
flags: ImDrawCornerFlags,
thickness: f32,
filled: bool,
draw_list: &'ui D,
}
impl<'ui, D: DrawAPI<'ui>> Rect<'ui, D> {
fn new<P1, P2, C>(draw_list: &'ui D, p1: P1, p2: P2, c: C) -> Self
where
P1: Into<ImVec2>,
P2: Into<ImVec2>,
C: Into<ImColor>,
{
Self {
p1: p1.into(),
p2: p2.into(),
color: c.into(),
rounding: 0.0,
flags: ImDrawCornerFlags::All,
thickness: 1.0,
filled: false,
draw_list,
}
}
/// Set rectangle's corner rounding (default to 0.0: no rounding).
/// By default all corners are rounded if this value is set.
pub fn rounding(mut self, rounding: f32) -> Self {
self.rounding = rounding;
self
}
/// Set flag to indicate if rectangle's top-left corner will be rounded.
pub fn round_top_left(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::TopLeft, value);
self
}
/// Set flag to indicate if rectangle's top-right corner will be rounded.
pub fn round_top_right(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::TopRight, value);
self
}
/// Set flag to indicate if rectangle's bottom-left corner will be rounded.
pub fn round_bot_left(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::BotLeft, value);
self
}
/// Set flag to indicate if rectangle's bottom-right corner will be rounded.
pub fn round_bot_right(mut self, value: bool) -> Self {
self.flags.set(ImDrawCornerFlags::BotRight, value);
self
}
/// Set rectangle's thickness (default to 1.0 pixel).
pub fn thickness(mut self, thickness: f32) -> Self {
self.thickness = thickness;
self
}
/// Set to `true` to make a filled rectangle (default to `false`).
pub fn filled(mut self, filled: bool) -> Self {
self.filled = filled;
self
}
/// Draw the rectangle on the window.
pub fn build(self) {
if self.filled {
unsafe {
sys::ImDrawList_AddRectFilled(
self.draw_list.draw_list(),
self.p1,
self.p2,
self.color.into(),
self.rounding,
self.flags,
);
}
} else {
unsafe {
sys::ImDrawList_AddRect(
self.draw_list.draw_list(),
self.p1,
self.p2,
self.color.into(),
self.rounding,
self.flags,
self.thickness,
);
}
}
}
}