fltk/
printer.rs

1use crate::prelude::*;
2use crate::utils::FlString;
3use fltk_sys::printer::*;
4use std::ffi::CString;
5
6/**
7    Defines a printer object.
8    Example usage:
9    ```rust,no_run
10    use fltk::{prelude::*, *};
11    let mut but = button::Button::default();
12    but.set_callback(|widget| {
13        let mut printer = printer::Printer::default();
14        if printer.begin_job(1).is_ok() {
15            printer.begin_page().ok();
16            let (width, height) = printer.printable_rect();
17            draw::set_draw_color(enums::Color::Black);
18            draw::set_line_style(draw::LineStyle::Solid, 2);
19            draw::draw_rect(0, 0, width, height);
20            draw::set_font(enums::Font::Courier, 12);
21            printer.set_origin(width / 2, height / 2);
22            printer.print_widget(widget, -widget.w() / 2, -widget.h() / 2);
23            printer.end_page().ok();
24            printer.end_job();
25        }
26    });
27    ```
28*/
29pub struct Printer {
30    inner: *mut Fl_Printer,
31}
32
33impl Default for Printer {
34    fn default() -> Self {
35        unsafe {
36            let ptr = Fl_Printer_new();
37            assert!(!ptr.is_null());
38            Printer { inner: ptr }
39        }
40    }
41}
42
43impl Printer {
44    /// Begins a print job.
45    /// `pagecount` The total number of pages to be created. Use 0 if this number is unknown
46    /// Returns a tuple (frompage, topage) indicating the chosen pages by the user
47    /// # Errors
48    /// Errors on failure to print
49    pub fn begin_job(&mut self, pagecount: i32) -> Result<(Option<i32>, Option<i32>), FltkError> {
50        let mut frompage_ = 0;
51        let mut topage_ = 0;
52        unsafe {
53            if Fl_Printer_begin_job(
54                self.inner,
55                pagecount,
56                &mut frompage_,
57                &mut topage_,
58                std::ptr::null_mut(),
59            ) == 0
60            {
61                let from = if frompage_ == 0 {
62                    None
63                } else {
64                    Some(frompage_)
65                };
66                let to = if topage_ == 0 { None } else { Some(topage_) };
67                Ok((from, to))
68            } else {
69                Err(FltkError::Internal(FltkErrorKind::FailedToRun))
70            }
71        }
72    }
73
74    /// End the print page
75    /// # Errors
76    /// Errors on failure to end the page
77    pub fn end_page(&mut self) -> Result<(), FltkError> {
78        unsafe {
79            if Fl_Printer_end_page(self.inner) == 0 {
80                Ok(())
81            } else {
82                Err(FltkError::Internal(FltkErrorKind::FailedToRun))
83            }
84        }
85    }
86
87    /// Ends the print job
88    pub fn end_job(&mut self) {
89        unsafe { Fl_Printer_end_job(self.inner) }
90    }
91
92    /// Begins a print page
93    /// # Errors
94    /// Errors on failure to begin the page
95    pub fn begin_page(&mut self) -> Result<(), FltkError> {
96        unsafe {
97            if Fl_Printer_begin_page(self.inner) == 0 {
98                Ok(())
99            } else {
100                Err(FltkError::Internal(FltkErrorKind::FailedToRun))
101            }
102        }
103    }
104
105    /// Returns the width and height of the printable rect
106    pub fn printable_rect(&self) -> (i32, i32) {
107        unsafe {
108            let mut x = 0;
109            let mut y = 0;
110            Fl_Printer_printable_rect(self.inner, &mut x, &mut y);
111            (x, y)
112        }
113    }
114
115    /// Returns the coordinates of the printable margins.
116    /// (left, top, right, bottom)
117    pub fn margins(&self) -> (i32, i32, i32, i32) {
118        unsafe {
119            let mut left = 0;
120            let mut top = 0;
121            let mut right = 0;
122            let mut bottom = 0;
123            Fl_Printer_margins(self.inner, &mut left, &mut top, &mut right, &mut bottom);
124            (left, top, right, bottom)
125        }
126    }
127
128    /// Get the origin coordinates of the printable rect
129    pub fn origin(&self) -> (i32, i32) {
130        unsafe {
131            let mut x = 0;
132            let mut y = 0;
133            Fl_Printer_origin(self.inner, &mut x, &mut y);
134            (x, y)
135        }
136    }
137
138    /// Set the origin coordinates of the printable rect
139    pub fn set_origin(&mut self, x: i32, y: i32) {
140        unsafe { Fl_Printer_set_origin(self.inner, x, y) }
141    }
142
143    /// Scale the printable rect
144    pub fn scale(&mut self, scale_x: f32, scale_y: f32) {
145        unsafe { Fl_Printer_scale(self.inner, scale_x, scale_y) }
146    }
147
148    /// Rotate the printable rect
149    pub fn rotate(&mut self, angle: f32) {
150        unsafe { Fl_Printer_rotate(self.inner, angle) }
151    }
152
153    /// Translate the printable rect
154    pub fn translate(&mut self, x: i32, y: i32) {
155        unsafe { Fl_Printer_translate(self.inner, x, y) }
156    }
157
158    /// Untranslate the printable rect
159    pub fn untranslate(&mut self) {
160        unsafe { Fl_Printer_untranslate(self.inner) }
161    }
162
163    /// Check whether the printer is the current printer
164    pub fn is_current(&self) -> bool {
165        unsafe { Fl_Printer_is_current(self.inner as *mut _) != 0 }
166    }
167
168    /// Set the printer to be the current printer
169    pub fn set_current(&mut self) {
170        unsafe { Fl_Printer_set_current(self.inner) }
171    }
172
173    /// Print a widget
174    pub fn print_widget<W: WidgetExt>(&self, widget: &W, delta_x: i32, delta_y: i32) {
175        unsafe {
176            Fl_Printer_print_widget(
177                self.inner,
178                widget.as_widget_ptr() as *mut _,
179                delta_x,
180                delta_y,
181            );
182        }
183    }
184
185    /// Print a window
186    pub fn print_window<W: WindowExt>(&self, win: &W, x_offset: i32, y_offset: i32) {
187        unsafe {
188            Fl_Printer_print_window(
189                self.inner,
190                win.as_widget_ptr() as *mut _,
191                x_offset,
192                y_offset,
193            );
194        }
195    }
196
197    /// Set the dialog "Title"
198    pub fn set_dialog_title(msg: &'static str) {
199        let msg = CString::safe_new(msg);
200        unsafe { Fl_Printer_set_dialog_title(msg.into_raw() as _) }
201    }
202
203    /// Set the dialog "Printer"
204    pub fn set_dialog_printer(msg: &'static str) {
205        let msg = CString::safe_new(msg);
206        unsafe { Fl_Printer_set_dialog_printer(msg.into_raw() as _) }
207    }
208
209    /// Set dialog "Range"
210    pub fn set_dialog_range(msg: &'static str) {
211        let msg = CString::safe_new(msg);
212        unsafe { Fl_Printer_set_dialog_range(msg.into_raw() as _) }
213    }
214
215    /// Set dialog "Copies"
216    pub fn set_dialog_copies(msg: &'static str) {
217        let msg = CString::safe_new(msg);
218        unsafe { Fl_Printer_set_dialog_copies(msg.into_raw() as _) }
219    }
220
221    /// Set dialog "All"
222    pub fn set_dialog_all(msg: &'static str) {
223        let msg = CString::safe_new(msg);
224        unsafe { Fl_Printer_set_dialog_all(msg.into_raw() as _) }
225    }
226
227    /// Set dialog "Pages"
228    pub fn set_dialog_pages(msg: &'static str) {
229        let msg = CString::safe_new(msg);
230        unsafe { Fl_Printer_set_dialog_pages(msg.into_raw() as _) }
231    }
232
233    /// Set dialog "From"
234    pub fn set_dialog_from(msg: &'static str) {
235        let msg = CString::safe_new(msg);
236        unsafe { Fl_Printer_set_dialog_from(msg.into_raw() as _) }
237    }
238
239    /// Set dialog "To"
240    pub fn set_dialog_to(msg: &'static str) {
241        let msg = CString::safe_new(msg);
242        unsafe { Fl_Printer_set_dialog_to(msg.into_raw() as _) }
243    }
244
245    /// Set dialog "Properties"
246    pub fn set_dialog_properties(msg: &'static str) {
247        let msg = CString::safe_new(msg);
248        unsafe { Fl_Printer_set_dialog_properties(msg.into_raw() as _) }
249    }
250
251    /// Set dialog "Number of copies"
252    pub fn set_dialog_copy_number(msg: &'static str) {
253        let msg = CString::safe_new(msg);
254        unsafe { Fl_Printer_set_dialog_copyNo(msg.into_raw() as _) }
255    }
256
257    /// Set dialog "Print" button
258    pub fn set_dialog_print_button(msg: &'static str) {
259        let msg = CString::safe_new(msg);
260        unsafe { Fl_Printer_set_dialog_print_button(msg.into_raw() as _) }
261    }
262
263    /// Set dialog "Cancel" button
264    pub fn set_dialog_cancel_button(msg: &'static str) {
265        let msg = CString::safe_new(msg);
266        unsafe { Fl_Printer_set_dialog_cancel_button(msg.into_raw() as _) }
267    }
268
269    /// Set dialog "Print to file" button
270    pub fn set_dialog_print_to_file(msg: &'static str) {
271        let msg = CString::safe_new(msg);
272        unsafe { Fl_Printer_set_dialog_print_to_file(msg.into_raw() as _) }
273    }
274
275    /// Set property "Title"
276    pub fn set_property_title(msg: &'static str) {
277        let msg = CString::safe_new(msg);
278        unsafe { Fl_Printer_set_property_title(msg.into_raw() as _) }
279    }
280
281    /// Set property "Page Size"
282    pub fn set_property_pagesize(msg: &'static str) {
283        let msg = CString::safe_new(msg);
284        unsafe { Fl_Printer_set_property_pagesize(msg.into_raw() as _) }
285    }
286
287    /// Set property "Mode"
288    pub fn set_property_mode(msg: &'static str) {
289        let msg = CString::safe_new(msg);
290        unsafe { Fl_Printer_set_property_mode(msg.into_raw() as _) }
291    }
292
293    /// Set property "Use"
294    pub fn set_property_use(msg: &'static str) {
295        let msg = CString::safe_new(msg);
296        unsafe { Fl_Printer_set_property_use(msg.into_raw() as _) }
297    }
298
299    /// Set property "Save"
300    pub fn set_property_save(msg: &'static str) {
301        let msg = CString::safe_new(msg);
302        unsafe { Fl_Printer_set_property_save(msg.into_raw() as _) }
303    }
304
305    /// Set property "Cancel"
306    pub fn set_property_cancel(msg: &'static str) {
307        let msg = CString::safe_new(msg);
308        unsafe { Fl_Printer_set_property_cancel(msg.into_raw() as _) }
309    }
310}
311
312impl Drop for Printer {
313    fn drop(&mut self) {
314        unsafe { Fl_Printer_delete(self.inner) }
315    }
316}