native_windows_gui2/controls/
plotters.rs1use super::{ControlBase, ControlHandle};
2use crate::NwgError;
3use crate::win32::base_helper::check_hwnd;
4use crate::win32::window_helper as wh;
5use winapi::um::winuser::{WS_CHILD, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, WS_VISIBLE};
6
7pub use crate::win32::plotters_d2d::{PlottersBackend, PlottersError};
8use plotters::coord::Shift;
9use plotters::prelude::DrawingArea;
10use std::ops::Deref;
11
12const NOT_BOUND: &'static str = "Plotters control is not yet bound to a winapi object";
13const BAD_HANDLE: &'static str = "INTERNAL ERROR: Plotters control handle is not HWND!";
14
15pub struct PlottersDrawingArea<'a> {
22 inner: &'a Plotters,
23 area: DrawingArea<&'a PlottersBackend, Shift>,
24}
25
26impl<'a> PlottersDrawingArea<'a> {
27 pub fn new(inner: &'a Plotters) -> Result<PlottersDrawingArea<'a>, PlottersError> {
28 let backend = inner.d2d_backend.as_ref().unwrap();
29
30 backend.rebuild(inner.handle.hwnd().unwrap())?;
31 backend.begin_draw();
32 backend.clear();
33
34 let area = PlottersDrawingArea {
35 inner: inner,
36 area: backend.into(),
37 };
38
39 Ok(area)
40 }
41}
42
43impl<'a> Deref for PlottersDrawingArea<'a> {
44 type Target = DrawingArea<&'a PlottersBackend, Shift>;
45
46 fn deref(&self) -> &Self::Target {
47 &self.area
48 }
49}
50
51impl<'a> Drop for PlottersDrawingArea<'a> {
52 fn drop(&mut self) {
53 self.inner.d2d_backend.as_ref().unwrap().end_draw();
54 }
55}
56
57#[derive(Default)]
62pub struct Plotters {
63 pub handle: ControlHandle,
64 d2d_backend: Option<PlottersBackend>,
65}
66
67impl Plotters {
68 pub fn builder() -> PlottersBuilder {
69 PlottersBuilder {
70 size: (500, 500),
71 position: (0, 0),
72 ex_flags: 0,
73 parent: None,
74 }
75 }
76
77 pub fn draw<'a>(&'a self) -> Result<PlottersDrawingArea<'a>, PlottersError> {
80 check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
81 PlottersDrawingArea::new(self)
82 }
83
84 pub fn focus(&self) -> bool {
86 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
87 wh::get_focus(handle)
88 }
89
90 pub fn set_focus(&self) {
92 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
93
94 wh::set_focus(handle);
95 }
96
97 pub fn enabled(&self) -> bool {
99 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
100 wh::get_window_enabled(handle)
101 }
102
103 pub fn set_enabled(&self, v: bool) {
105 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
106 wh::set_window_enabled(handle, v)
107 }
108
109 pub fn visible(&self) -> bool {
112 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
113 wh::get_window_visibility(handle)
114 }
115
116 pub fn set_visible(&self, v: bool) {
118 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
119 wh::set_window_visibility(handle, v)
120 }
121
122 pub fn size(&self) -> (u32, u32) {
124 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
125 wh::get_window_size(handle)
126 }
127
128 pub fn physical_size(&self) -> (u32, u32) {
130 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
131 wh::get_window_physical_size(handle)
132 }
133
134 pub fn set_size(&self, x: u32, y: u32) {
136 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
137 wh::set_window_size(handle, x, y, true)
138 }
139
140 pub fn position(&self) -> (i32, i32) {
142 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
143 wh::get_window_position(handle)
144 }
145
146 pub fn set_position(&self, x: i32, y: i32) {
148 let handle = check_hwnd(&self.handle, NOT_BOUND, BAD_HANDLE);
149 wh::set_window_position(handle, x, y)
150 }
151
152 pub fn class_name(&self) -> &'static str {
154 "NWG_EXTERN_CANVAS"
155 }
156
157 pub fn flags(&self) -> u32 {
159 WS_CHILD | WS_VISIBLE
160 }
161
162 pub fn forced_flags(&self) -> u32 {
164 WS_CLIPCHILDREN | WS_CLIPSIBLINGS
165 }
166}
167
168impl PartialEq for Plotters {
169 fn eq(&self, other: &Self) -> bool {
170 self.handle == other.handle
171 }
172}
173
174pub struct PlottersBuilder {
175 parent: Option<ControlHandle>,
176 size: (i32, i32),
177 position: (i32, i32),
178 ex_flags: u32,
179}
180
181impl PlottersBuilder {
182 pub fn ex_flags(mut self, flags: u32) -> PlottersBuilder {
183 self.ex_flags = flags;
184 self
185 }
186
187 pub fn size(mut self, size: (i32, i32)) -> PlottersBuilder {
188 self.size = size;
189 self
190 }
191
192 pub fn position(mut self, pos: (i32, i32)) -> PlottersBuilder {
193 self.position = pos;
194 self
195 }
196
197 pub fn parent<C: Into<ControlHandle>>(mut self, p: C) -> PlottersBuilder {
198 self.parent = Some(p.into());
199 self
200 }
201
202 pub fn build(self, out: &mut Plotters) -> Result<(), NwgError> {
203 *out = Default::default();
204
205 out.handle = ControlBase::build_hwnd()
206 .class_name(out.class_name())
207 .forced_flags(out.forced_flags())
208 .flags(out.flags())
209 .ex_flags(self.ex_flags)
210 .size(self.size)
211 .position(self.position)
212 .text("")
213 .parent(self.parent)
214 .build()?;
215
216 let handle = out.handle.hwnd().unwrap();
217 match PlottersBackend::init(handle) {
218 Ok(b) => {
219 out.d2d_backend = Some(b);
220 Ok(())
221 }
222 Err(e) => {
223 *out = Default::default();
224 Err(NwgError::from(e))
225 }
226 }
227 }
228}