Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 171d86a

Browse files
nsfthomcc
authored andcommitted
Refactor WindowDrawList into DrawListMut and fix #413.
- Rename WindowDrawList -> DrawListMut. It's not about window draw lists, but about background/foreground draw lists as well. The naming was not an easy choice, but seems like in rust it's a common convention to add a Mut suffix for mutable entities. Imgui-rs already has DrawList and it acts as an immutable reference type for rendering implementations to consume. Hence the name DrawListMut, which becomes a mutable reference to draw list with methods to modify it. - Add Ui::get_foreground_draw_list(). Same as Ui::get_background_draw_list() but for foreground. - Add draw_list example which shows the use of all three draw lists (window, bg, fg).
1 parent 81e21f5 commit 171d86a

File tree

3 files changed

+139
-38
lines changed

3 files changed

+139
-38
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use imgui::*;
2+
3+
mod support;
4+
5+
// rect is [x, y, w, h]
6+
fn draw_text_centered(
7+
ui: &Ui,
8+
draw_list: &DrawListMut,
9+
rect: [f32; 4],
10+
text: &ImStr,
11+
color: [f32; 3],
12+
) {
13+
let text_size = ui.calc_text_size(text, false, 0.0);
14+
let cx = (rect[2] - text_size[0]) / 2.0;
15+
let cy = (rect[3] - text_size[1]) / 2.0;
16+
draw_list.add_text([rect[0] + cx, rect[1] + cy], color, text);
17+
}
18+
19+
fn main() {
20+
let system = support::init(file!());
21+
system.main_loop(move |_, ui| {
22+
{
23+
let bg_draw_list = ui.get_background_draw_list();
24+
bg_draw_list
25+
.add_circle([150.0, 150.0], 150.0, [1.0, 0.0, 0.0])
26+
.thickness(4.0)
27+
.build();
28+
draw_text_centered(
29+
ui,
30+
&bg_draw_list,
31+
[0.0, 0.0, 300.0, 300.0],
32+
im_str!("background draw list"),
33+
[0.0, 0.0, 0.0],
34+
);
35+
}
36+
37+
{
38+
let [w, h] = ui.io().display_size;
39+
let fg_draw_list = ui.get_foreground_draw_list();
40+
fg_draw_list
41+
.add_circle([w - 150.0, h - 150.0], 150.0, [1.0, 0.0, 0.0])
42+
.thickness(4.0)
43+
.build();
44+
draw_text_centered(
45+
ui,
46+
&fg_draw_list,
47+
[w - 300.0, h - 300.0, 300.0, 300.0],
48+
im_str!("foreground draw list"),
49+
[1.0, 0.0, 0.0],
50+
);
51+
}
52+
53+
Window::new(im_str!("Draw list"))
54+
.size([300.0, 110.0], Condition::FirstUseEver)
55+
.scroll_bar(false)
56+
.build(ui, || {
57+
ui.button(im_str!("random button"), [0.0, 0.0]);
58+
let draw_list = ui.get_window_draw_list();
59+
let o = ui.cursor_screen_pos();
60+
let ws = ui.content_region_avail();
61+
draw_list
62+
.add_circle([o[0] + 10.0, o[1] + 10.0], 5.0, [1.0, 0.0, 0.0])
63+
.thickness(4.0)
64+
.build();
65+
draw_list
66+
.add_circle([o[0] + ws[0] - 10.0, o[1] + 10.0], 5.0, [0.0, 1.0, 0.0])
67+
.thickness(4.0)
68+
.build();
69+
draw_list
70+
.add_circle(
71+
[o[0] + ws[0] - 10.0, o[1] + ws[1] - 10.0],
72+
5.0,
73+
[0.0, 0.0, 1.0],
74+
)
75+
.thickness(4.0)
76+
.build();
77+
draw_list
78+
.add_circle([o[0] + 10.0, o[1] + ws[1] - 10.0], 5.0, [1.0, 1.0, 0.0])
79+
.thickness(4.0)
80+
.build();
81+
draw_text_centered(
82+
ui,
83+
&draw_list,
84+
[o[0], o[1], ws[0], ws[1]],
85+
im_str!("window draw list"),
86+
[1.0, 1.0, 1.0],
87+
);
88+
});
89+
});
90+
}

imgui/src/window_draw_list.rs renamed to imgui/src/draw_list.rs

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,25 @@ impl From<(f32, f32, f32)> for ImColor {
5353

5454
/// Object implementing the custom draw API.
5555
///
56-
/// Called from [`Ui::get_window_draw_list`]. No more than one instance of this
57-
/// structure can live in a program at the same time.
56+
/// Called from [`Ui::get_window_draw_list`], [`Ui::get_background_draw_list`] or [`Ui::get_foreground_draw_list`].
57+
/// No more than one instance of this structure can live in a program at the same time.
5858
/// The program will panic on creating a second instance.
59-
pub struct WindowDrawList<'ui> {
59+
pub struct DrawListMut<'ui> {
6060
draw_list: *mut ImDrawList,
6161
_phantom: PhantomData<&'ui Ui<'ui>>,
6262
}
6363

64-
static WINDOW_DRAW_LIST_LOADED: std::sync::atomic::AtomicBool =
65-
std::sync::atomic::AtomicBool::new(false);
64+
static DRAW_LIST_LOADED: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false);
6665

67-
impl<'ui> Drop for WindowDrawList<'ui> {
66+
impl<'ui> Drop for DrawListMut<'ui> {
6867
fn drop(&mut self) {
69-
WINDOW_DRAW_LIST_LOADED.store(false, std::sync::atomic::Ordering::Release);
68+
DRAW_LIST_LOADED.store(false, std::sync::atomic::Ordering::Release);
7069
}
7170
}
7271

73-
impl<'ui> WindowDrawList<'ui> {
74-
pub(crate) fn new(_: &Ui<'ui>) -> Self {
75-
let already_loaded = WINDOW_DRAW_LIST_LOADED
72+
impl<'ui> DrawListMut<'ui> {
73+
fn lock_draw_list() {
74+
let already_loaded = DRAW_LIST_LOADED
7675
.compare_exchange(
7776
false,
7877
true,
@@ -81,21 +80,34 @@ impl<'ui> WindowDrawList<'ui> {
8180
)
8281
.is_err();
8382
if already_loaded {
84-
panic!("WindowDrawList is already loaded! You can only load one instance of it!")
83+
panic!("DrawListMut is already loaded! You can only load one instance of it!")
8584
}
85+
}
86+
87+
pub(crate) fn window(_: &Ui<'ui>) -> Self {
88+
Self::lock_draw_list();
8689
Self {
8790
draw_list: unsafe { sys::igGetWindowDrawList() },
8891
_phantom: PhantomData,
8992
}
9093
}
9194

92-
pub(crate) fn background(self) -> Self {
95+
pub(crate) fn background(_: &Ui<'ui>) -> Self {
96+
Self::lock_draw_list();
9397
Self {
9498
draw_list: unsafe { sys::igGetBackgroundDrawList() },
9599
_phantom: PhantomData,
96100
}
97101
}
98102

103+
pub(crate) fn foreground(_: &Ui<'ui>) -> Self {
104+
Self::lock_draw_list();
105+
Self {
106+
draw_list: unsafe { sys::igGetForegroundDrawList() },
107+
_phantom: PhantomData,
108+
}
109+
}
110+
99111
/// Split into *channels_count* drawing channels.
100112
/// At the end of the closure, the channels are merged. The objects
101113
/// are then drawn in the increasing order of their channel number, and not
@@ -127,9 +139,9 @@ impl<'ui> WindowDrawList<'ui> {
127139

128140
/// Represent the drawing interface within a call to [`channels_split`].
129141
///
130-
/// [`channels_split`]: WindowDrawList::channels_split
142+
/// [`channels_split`]: DrawListMut::channels_split
131143
pub struct ChannelsSplit<'ui> {
132-
draw_list: &'ui WindowDrawList<'ui>,
144+
draw_list: &'ui DrawListMut<'ui>,
133145
channels_count: u32,
134146
}
135147

@@ -151,7 +163,7 @@ impl<'ui> ChannelsSplit<'ui> {
151163
}
152164

153165
/// Drawing functions
154-
impl<'ui> WindowDrawList<'ui> {
166+
impl<'ui> DrawListMut<'ui> {
155167
/// Returns a line from point `p1` to `p2` with color `c`.
156168
pub fn add_line<C>(&'ui self, p1: [f32; 2], p2: [f32; 2], c: C) -> Line<'ui>
157169
where
@@ -291,11 +303,11 @@ pub struct Line<'ui> {
291303
p2: [f32; 2],
292304
color: ImColor,
293305
thickness: f32,
294-
draw_list: &'ui WindowDrawList<'ui>,
306+
draw_list: &'ui DrawListMut<'ui>,
295307
}
296308

297309
impl<'ui> Line<'ui> {
298-
fn new<C>(draw_list: &'ui WindowDrawList, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
310+
fn new<C>(draw_list: &'ui DrawListMut, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
299311
where
300312
C: Into<ImColor>,
301313
{
@@ -338,11 +350,11 @@ pub struct Rect<'ui> {
338350
flags: ImDrawCornerFlags,
339351
thickness: f32,
340352
filled: bool,
341-
draw_list: &'ui WindowDrawList<'ui>,
353+
draw_list: &'ui DrawListMut<'ui>,
342354
}
343355

344356
impl<'ui> Rect<'ui> {
345-
fn new<C>(draw_list: &'ui WindowDrawList, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
357+
fn new<C>(draw_list: &'ui DrawListMut, p1: [f32; 2], p2: [f32; 2], c: C) -> Self
346358
where
347359
C: Into<ImColor>,
348360
{
@@ -439,17 +451,11 @@ pub struct Triangle<'ui> {
439451
color: ImColor,
440452
thickness: f32,
441453
filled: bool,
442-
draw_list: &'ui WindowDrawList<'ui>,
454+
draw_list: &'ui DrawListMut<'ui>,
443455
}
444456

445457
impl<'ui> Triangle<'ui> {
446-
fn new<C>(
447-
draw_list: &'ui WindowDrawList,
448-
p1: [f32; 2],
449-
p2: [f32; 2],
450-
p3: [f32; 2],
451-
c: C,
452-
) -> Self
458+
fn new<C>(draw_list: &'ui DrawListMut, p1: [f32; 2], p2: [f32; 2], p3: [f32; 2], c: C) -> Self
453459
where
454460
C: Into<ImColor>,
455461
{
@@ -512,11 +518,11 @@ pub struct Circle<'ui> {
512518
num_segments: u32,
513519
thickness: f32,
514520
filled: bool,
515-
draw_list: &'ui WindowDrawList<'ui>,
521+
draw_list: &'ui DrawListMut<'ui>,
516522
}
517523

518524
impl<'ui> Circle<'ui> {
519-
pub fn new<C>(draw_list: &'ui WindowDrawList, center: [f32; 2], radius: f32, color: C) -> Self
525+
pub fn new<C>(draw_list: &'ui DrawListMut, center: [f32; 2], radius: f32, color: C) -> Self
520526
where
521527
C: Into<ImColor>,
522528
{
@@ -588,12 +594,12 @@ pub struct BezierCurve<'ui> {
588594
thickness: f32,
589595
/// If num_segments is not set, the bezier curve is auto-tessalated.
590596
num_segments: Option<u32>,
591-
draw_list: &'ui WindowDrawList<'ui>,
597+
draw_list: &'ui DrawListMut<'ui>,
592598
}
593599

594600
impl<'ui> BezierCurve<'ui> {
595601
fn new<C>(
596-
draw_list: &'ui WindowDrawList,
602+
draw_list: &'ui DrawListMut,
597603
pos0: [f32; 2],
598604
cp0: [f32; 2],
599605
cp1: [f32; 2],

imgui/src/lib.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::thread;
1010

1111
pub use self::clipboard::*;
1212
pub use self::context::*;
13+
pub use self::draw_list::{ChannelsSplit, DrawListMut, ImColor};
1314
pub use self::fonts::atlas::*;
1415
pub use self::fonts::font::*;
1516
pub use self::fonts::glyph::*;
@@ -46,12 +47,12 @@ pub use self::widget::tab::*;
4647
pub use self::widget::tree::*;
4748
pub use self::window::child_window::*;
4849
pub use self::window::*;
49-
pub use self::window_draw_list::{ChannelsSplit, ImColor, WindowDrawList};
5050
use internal::RawCast;
5151

5252
mod clipboard;
5353
mod columns;
5454
mod context;
55+
mod draw_list;
5556
mod fonts;
5657
mod input;
5758
mod input_widget;
@@ -72,7 +73,6 @@ mod test;
7273
mod utils;
7374
mod widget;
7475
mod window;
75-
mod window_draw_list;
7676

7777
/// Returns the underlying Dear ImGui library version
7878
pub fn dear_imgui_version() -> &'static str {
@@ -470,7 +470,7 @@ impl<'ui> Ui<'ui> {
470470
/// }
471471
/// ```
472472
///
473-
/// This function will panic if several instances of [`WindowDrawList`]
473+
/// This function will panic if several instances of [`DrawListMut`]
474474
/// coexist. Before a new instance is got, a previous instance should be
475475
/// dropped.
476476
///
@@ -485,13 +485,18 @@ impl<'ui> Ui<'ui> {
485485
/// }
486486
/// ```
487487
#[must_use]
488-
pub fn get_window_draw_list(&'ui self) -> WindowDrawList<'ui> {
489-
WindowDrawList::new(self)
488+
pub fn get_window_draw_list(&'ui self) -> DrawListMut<'ui> {
489+
DrawListMut::window(self)
490490
}
491491

492492
#[must_use]
493-
pub fn get_background_draw_list(&'ui self) -> WindowDrawList<'ui> {
494-
WindowDrawList::new(self).background()
493+
pub fn get_background_draw_list(&'ui self) -> DrawListMut<'ui> {
494+
DrawListMut::background(self)
495+
}
496+
497+
#[must_use]
498+
pub fn get_foreground_draw_list(&'ui self) -> DrawListMut<'ui> {
499+
DrawListMut::foreground(self)
495500
}
496501
}
497502

0 commit comments

Comments
 (0)