Skip to main content

clutter/auto/
canvas.rs

1use crate::Content;
2use glib::{
3    object::{Cast, IsA},
4    signal::{connect_raw, SignalHandlerId},
5    translate::*,
6    StaticType, Value,
7};
8use std::boxed::Box as Box_;
9use std::{fmt, mem::transmute};
10
11glib_wrapper! {
12    pub struct Canvas(Object<ffi::ClutterCanvas, ffi::ClutterCanvasClass, CanvasClass>) @implements Content;
13
14    match fn {
15        get_type => || ffi::clutter_canvas_get_type(),
16    }
17}
18
19impl Canvas {
20    /// Creates a new instance of `Canvas`.
21    ///
22    /// You should call `CanvasExt::set_size` to set the size of the canvas.
23    ///
24    /// You should call `Content::invalidate` every time you wish to
25    /// draw the contents of the canvas.
26    ///
27    /// # Returns
28    ///
29    /// The newly allocated instance of
30    ///  `Canvas`. Use `gobject::ObjectExt::unref` when done.
31    pub fn new() -> Option<Content> {
32        unsafe { from_glib_full(ffi::clutter_canvas_new()) }
33    }
34}
35
36// impl Default for Canvas {
37//     fn default() -> Self {
38//         Self::new()
39//     }
40// }
41
42pub const NONE_CANVAS: Option<&Canvas> = None;
43
44/// Trait containing all `Canvas` methods.
45///
46/// # Implementors
47///
48/// [`Canvas`](struct.Canvas.html)
49pub trait CanvasExt: 'static {
50    /// Retrieves the scaling factor of `self`, as set using
51    /// `CanvasExt::set_scale_factor`.
52    ///
53    /// # Returns
54    ///
55    /// the scaling factor, or -1 if the `self`
56    ///  uses the default from `Settings`
57    fn get_scale_factor(&self) -> i32;
58
59    /// Sets the scaling factor for the Cairo surface used by `self`.
60    ///
61    /// This function should rarely be used.
62    ///
63    /// The default scaling factor of a `Canvas` content uses the
64    /// `Settings:window-scaling-factor` property, which is set by
65    /// the windowing system. By using this function it is possible to
66    /// override that setting.
67    ///
68    /// Changing the scale factor will invalidate the `self`.
69    /// ## `scale`
70    /// the scale factor, or -1 for the default
71    fn set_scale_factor(&self, scale: i32);
72
73    /// Sets the size of the `self`, and invalidates the content.
74    ///
75    /// This function will cause the `self` to be invalidated only
76    /// if the size of the canvas surface has changed.
77    ///
78    /// If you want to invalidate the contents of the `self` when setting
79    /// the size, you can use the return value of the function to conditionally
80    /// call `Content::invalidate`:
81    ///
82    ///
83    /// ```text
84    ///   if (!clutter_canvas_set_size (canvas, width, height))
85    ///     clutter_content_invalidate (CLUTTER_CONTENT (canvas));
86    /// ```
87    /// ## `width`
88    /// the width of the canvas, in pixels
89    /// ## `height`
90    /// the height of the canvas, in pixels
91    ///
92    /// # Returns
93    ///
94    /// this function returns `true` if the size change
95    ///  caused a content invalidation, and `false` otherwise
96    fn set_size(&self, width: i32, height: i32) -> bool;
97
98    /// The height of the canvas.
99    fn get_property_height(&self) -> i32;
100
101    /// The height of the canvas.
102    fn set_property_height(&self, height: i32);
103
104    /// Whether the `Canvas:scale-factor` property is set.
105    ///
106    /// If the `Canvas:scale-factor-set` property is `false`
107    /// then `Canvas` will use the `Settings:window-scaling-factor`
108    /// property.
109    fn get_property_scale_factor_set(&self) -> bool;
110
111    /// The width of the canvas.
112    fn get_property_width(&self) -> i32;
113
114    /// The width of the canvas.
115    fn set_property_width(&self, width: i32);
116
117    /// The `Canvas::draw` signal is emitted each time a canvas is
118    /// invalidated.
119    ///
120    /// It is safe to connect multiple handlers to this signal: each
121    /// handler invocation will be automatically protected by `cairo_save`
122    /// and `cairo_restore` pairs.
123    /// ## `cr`
124    /// the Cairo context used to draw
125    /// ## `width`
126    /// the width of the `canvas`
127    /// ## `height`
128    /// the height of the `canvas`
129    ///
130    /// # Returns
131    ///
132    /// `true` if the signal emission should stop, and
133    ///  `false` otherwise
134    fn connect_draw<F: Fn(&Self, &cairo::Context, i32, i32) -> bool + 'static>(
135        &self,
136        f: F,
137    ) -> SignalHandlerId;
138
139    fn connect_property_height_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
140
141    fn connect_property_scale_factor_notify<F: Fn(&Self) + 'static>(&self, f: F)
142        -> SignalHandlerId;
143
144    fn connect_property_scale_factor_set_notify<F: Fn(&Self) + 'static>(
145        &self,
146        f: F,
147    ) -> SignalHandlerId;
148
149    fn connect_property_width_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId;
150}
151
152impl<O: IsA<Canvas>> CanvasExt for O {
153    fn get_scale_factor(&self) -> i32 {
154        unsafe { ffi::clutter_canvas_get_scale_factor(self.as_ref().to_glib_none().0) }
155    }
156
157    fn set_scale_factor(&self, scale: i32) {
158        unsafe {
159            ffi::clutter_canvas_set_scale_factor(self.as_ref().to_glib_none().0, scale);
160        }
161    }
162
163    fn set_size(&self, width: i32, height: i32) -> bool {
164        unsafe {
165            from_glib(ffi::clutter_canvas_set_size(
166                self.as_ref().to_glib_none().0,
167                width,
168                height,
169            ))
170        }
171    }
172
173    fn get_property_height(&self) -> i32 {
174        unsafe {
175            let mut value = Value::from_type(<i32 as StaticType>::static_type());
176            gobject_sys::g_object_get_property(
177                self.to_glib_none().0 as *mut gobject_sys::GObject,
178                b"height\0".as_ptr() as *const _,
179                value.to_glib_none_mut().0,
180            );
181            value
182                .get()
183                .expect("Return Value for property `height` getter")
184                .unwrap()
185        }
186    }
187
188    fn set_property_height(&self, height: i32) {
189        unsafe {
190            gobject_sys::g_object_set_property(
191                self.to_glib_none().0 as *mut gobject_sys::GObject,
192                b"height\0".as_ptr() as *const _,
193                Value::from(&height).to_glib_none().0,
194            );
195        }
196    }
197
198    fn get_property_scale_factor_set(&self) -> bool {
199        unsafe {
200            let mut value = Value::from_type(<bool as StaticType>::static_type());
201            gobject_sys::g_object_get_property(
202                self.to_glib_none().0 as *mut gobject_sys::GObject,
203                b"scale-factor-set\0".as_ptr() as *const _,
204                value.to_glib_none_mut().0,
205            );
206            value
207                .get()
208                .expect("Return Value for property `scale-factor-set` getter")
209                .unwrap()
210        }
211    }
212
213    fn get_property_width(&self) -> i32 {
214        unsafe {
215            let mut value = Value::from_type(<i32 as StaticType>::static_type());
216            gobject_sys::g_object_get_property(
217                self.to_glib_none().0 as *mut gobject_sys::GObject,
218                b"width\0".as_ptr() as *const _,
219                value.to_glib_none_mut().0,
220            );
221            value
222                .get()
223                .expect("Return Value for property `width` getter")
224                .unwrap()
225        }
226    }
227
228    fn set_property_width(&self, width: i32) {
229        unsafe {
230            gobject_sys::g_object_set_property(
231                self.to_glib_none().0 as *mut gobject_sys::GObject,
232                b"width\0".as_ptr() as *const _,
233                Value::from(&width).to_glib_none().0,
234            );
235        }
236    }
237
238    fn connect_draw<F: Fn(&Self, &cairo::Context, i32, i32) -> bool + 'static>(
239        &self,
240        f: F,
241    ) -> SignalHandlerId {
242        unsafe extern "C" fn draw_trampoline<
243            P,
244            F: Fn(&P, &cairo::Context, i32, i32) -> bool + 'static,
245        >(
246            this: *mut ffi::ClutterCanvas,
247            cr: *mut cairo_sys::cairo_t,
248            width: libc::c_int,
249            height: libc::c_int,
250            f: glib_sys::gpointer,
251        ) -> glib_sys::gboolean
252        where
253            P: IsA<Canvas>,
254        {
255            let f: &F = &*(f as *const F);
256            f(
257                &Canvas::from_glib_borrow(this).unsafe_cast_ref(),
258                &from_glib_borrow(cr),
259                width,
260                height,
261            )
262            .to_glib()
263        }
264        unsafe {
265            let f: Box_<F> = Box_::new(f);
266            connect_raw(
267                self.as_ptr() as *mut _,
268                b"draw\0".as_ptr() as *const _,
269                Some(transmute::<_, unsafe extern "C" fn()>(
270                    draw_trampoline::<Self, F> as *const (),
271                )),
272                Box_::into_raw(f),
273            )
274        }
275    }
276
277    fn connect_property_height_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
278        unsafe extern "C" fn notify_height_trampoline<P, F: Fn(&P) + 'static>(
279            this: *mut ffi::ClutterCanvas,
280            _param_spec: glib_sys::gpointer,
281            f: glib_sys::gpointer,
282        ) where
283            P: IsA<Canvas>,
284        {
285            let f: &F = &*(f as *const F);
286            f(&Canvas::from_glib_borrow(this).unsafe_cast_ref())
287        }
288        unsafe {
289            let f: Box_<F> = Box_::new(f);
290            connect_raw(
291                self.as_ptr() as *mut _,
292                b"notify::height\0".as_ptr() as *const _,
293                Some(transmute::<_, unsafe extern "C" fn()>(
294                    notify_height_trampoline::<Self, F> as *const (),
295                )),
296                Box_::into_raw(f),
297            )
298        }
299    }
300
301    fn connect_property_scale_factor_notify<F: Fn(&Self) + 'static>(
302        &self,
303        f: F,
304    ) -> SignalHandlerId {
305        unsafe extern "C" fn notify_scale_factor_trampoline<P, F: Fn(&P) + 'static>(
306            this: *mut ffi::ClutterCanvas,
307            _param_spec: glib_sys::gpointer,
308            f: glib_sys::gpointer,
309        ) where
310            P: IsA<Canvas>,
311        {
312            let f: &F = &*(f as *const F);
313            f(&Canvas::from_glib_borrow(this).unsafe_cast_ref())
314        }
315        unsafe {
316            let f: Box_<F> = Box_::new(f);
317            connect_raw(
318                self.as_ptr() as *mut _,
319                b"notify::scale-factor\0".as_ptr() as *const _,
320                Some(transmute::<_, unsafe extern "C" fn()>(
321                    notify_scale_factor_trampoline::<Self, F> as *const (),
322                )),
323                Box_::into_raw(f),
324            )
325        }
326    }
327
328    fn connect_property_scale_factor_set_notify<F: Fn(&Self) + 'static>(
329        &self,
330        f: F,
331    ) -> SignalHandlerId {
332        unsafe extern "C" fn notify_scale_factor_set_trampoline<P, F: Fn(&P) + 'static>(
333            this: *mut ffi::ClutterCanvas,
334            _param_spec: glib_sys::gpointer,
335            f: glib_sys::gpointer,
336        ) where
337            P: IsA<Canvas>,
338        {
339            let f: &F = &*(f as *const F);
340            f(&Canvas::from_glib_borrow(this).unsafe_cast_ref())
341        }
342        unsafe {
343            let f: Box_<F> = Box_::new(f);
344            connect_raw(
345                self.as_ptr() as *mut _,
346                b"notify::scale-factor-set\0".as_ptr() as *const _,
347                Some(transmute::<_, unsafe extern "C" fn()>(
348                    notify_scale_factor_set_trampoline::<Self, F> as *const (),
349                )),
350                Box_::into_raw(f),
351            )
352        }
353    }
354
355    fn connect_property_width_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
356        unsafe extern "C" fn notify_width_trampoline<P, F: Fn(&P) + 'static>(
357            this: *mut ffi::ClutterCanvas,
358            _param_spec: glib_sys::gpointer,
359            f: glib_sys::gpointer,
360        ) where
361            P: IsA<Canvas>,
362        {
363            let f: &F = &*(f as *const F);
364            f(&Canvas::from_glib_borrow(this).unsafe_cast_ref())
365        }
366        unsafe {
367            let f: Box_<F> = Box_::new(f);
368            connect_raw(
369                self.as_ptr() as *mut _,
370                b"notify::width\0".as_ptr() as *const _,
371                Some(transmute::<_, unsafe extern "C" fn()>(
372                    notify_width_trampoline::<Self, F> as *const (),
373                )),
374                Box_::into_raw(f),
375            )
376        }
377    }
378}
379
380impl fmt::Display for Canvas {
381    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
382        write!(f, "Canvas")
383    }
384}