Skip to main content

gdk4/
toplevel_size.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::ffi::c_void;
4
5use crate::{ffi, prelude::*};
6use glib::translate::*;
7
8/// Contains information that is useful to compute the size of a toplevel.
9#[repr(transparent)]
10#[doc(alias = "GdkToplevelSize")]
11pub struct ToplevelSize(pub(crate) std::ptr::NonNull<ffi::GdkToplevelSize>);
12
13impl StaticType for ToplevelSize {
14    fn static_type() -> glib::Type {
15        unsafe { from_glib(ffi::gdk_toplevel_size_get_type()) }
16    }
17}
18
19impl ToplevelSize {
20    /// Retrieves the bounds the toplevel is placed within.
21    ///
22    /// The bounds represent the largest size a toplevel may have while still being
23    /// able to fit within some type of boundary. Depending on the backend, this may
24    /// be equivalent to the dimensions of the work area or the monitor on which the
25    /// window is being presented on, or something else that limits the way a
26    /// toplevel can be presented.
27    ///
28    /// # Returns
29    ///
30    ///
31    /// ## `bounds_width`
32    /// return location for width
33    ///
34    /// ## `bounds_height`
35    /// return location for height
36    #[doc(alias = "gdk_toplevel_size_get_bounds")]
37    #[doc(alias = "get_bounds")]
38    pub fn bounds(&self) -> (i32, i32) {
39        unsafe {
40            let mut bounds_width = std::mem::MaybeUninit::uninit();
41            let mut bounds_height = std::mem::MaybeUninit::uninit();
42
43            ffi::gdk_toplevel_size_get_bounds(
44                self.0.as_ptr(),
45                bounds_width.as_mut_ptr(),
46                bounds_height.as_mut_ptr(),
47            );
48            (bounds_width.assume_init(), bounds_height.assume_init())
49        }
50    }
51
52    /// Sets the minimum size of the toplevel.
53    ///
54    /// The minimum size corresponds to the limitations the toplevel can be shrunk
55    /// to, without resulting in incorrect painting. A user of a [`Toplevel`][crate::Toplevel] should
56    /// calculate these given both the existing size, and the bounds retrieved from
57    /// the [`ToplevelSize`][crate::ToplevelSize] object.
58    ///
59    /// The minimum size should be within the bounds (see
60    /// [`bounds()`][Self::bounds()]).
61    /// ## `min_width`
62    /// the minimum width
63    /// ## `min_height`
64    /// the minimum height
65    #[doc(alias = "gdk_toplevel_size_set_min_size")]
66    pub fn set_min_size(&mut self, min_width: i32, min_height: i32) {
67        unsafe {
68            ffi::gdk_toplevel_size_set_min_size(self.0.as_mut(), min_width, min_height);
69        }
70    }
71
72    /// Sets the shadows size of the toplevel.
73    ///
74    /// The shadow width corresponds to the part of the computed surface size
75    /// that would consist of the shadow margin surrounding the window, would
76    /// there be any.
77    ///
78    /// Shadow width should only be set if
79    /// `Gtk::Display::supports_shadow_width()` is [`true`].
80    /// ## `left`
81    /// width of the left part of the shadow
82    /// ## `right`
83    /// width of the right part of the shadow
84    /// ## `top`
85    /// height of the top part of the shadow
86    /// ## `bottom`
87    /// height of the bottom part of the shadow
88    #[doc(alias = "gdk_toplevel_size_set_shadow_width")]
89    pub fn set_shadow_width(&mut self, left: i32, right: i32, top: i32, bottom: i32) {
90        unsafe {
91            ffi::gdk_toplevel_size_set_shadow_width(self.0.as_mut(), left, right, top, bottom);
92        }
93    }
94
95    /// Sets the size the toplevel prefers to be resized to.
96    ///
97    /// The size should be within the bounds (see
98    /// [`bounds()`][Self::bounds()]). The set size should
99    /// be considered as a hint, and should not be assumed to be
100    /// respected by the windowing system, or backend.
101    /// ## `width`
102    /// the width
103    /// ## `height`
104    /// the height
105    #[doc(alias = "gdk_toplevel_size_set_size")]
106    pub fn set_size(&mut self, width: i32, height: i32) {
107        unsafe {
108            ffi::gdk_toplevel_size_set_size(self.0.as_mut(), width, height);
109        }
110    }
111}
112
113impl std::fmt::Debug for ToplevelSize {
114    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
115        f.debug_struct("ToplevelSize")
116            .field("bounds", &self.bounds())
117            .finish()
118    }
119}
120
121unsafe impl<'a> glib::value::FromValue<'a> for ToplevelSize {
122    type Checker = glib::value::GenericValueTypeChecker<Self>;
123
124    #[inline]
125    unsafe fn from_value(value: &'a glib::Value) -> Self {
126        unsafe {
127            let ptr = glib::gobject_ffi::g_value_get_pointer(value.to_glib_none().0);
128            debug_assert!(
129                !ptr.is_null(),
130                "ToplevelSize in glib::Value is a NULL pointer"
131            );
132            ToplevelSize(std::ptr::NonNull::new_unchecked(
133                ptr as *mut ffi::_GdkToplevelSize,
134            ))
135        }
136    }
137}
138
139impl ToValue for ToplevelSize {
140    #[inline]
141    fn to_value(&self) -> glib::Value {
142        unsafe {
143            let mut v = glib::Value::from_type(Self::static_type());
144            glib::gobject_ffi::g_value_set_pointer(
145                v.to_glib_none_mut().0,
146                self.0.as_ptr() as *mut c_void,
147            );
148            v
149        }
150    }
151
152    #[inline]
153    fn value_type(&self) -> glib::Type {
154        Self::static_type()
155    }
156}