dioxus_use_window/hooks/use_window/
mod.rs

1use super::*;
2
3pub mod data;
4mod display;
5
6/// Window size effect handler
7pub struct UseWindow {
8    data: Rc<RefCell<WindowSizeData>>,
9    listen_window_resize: Option<EventListener>,
10    listen_fullscreen: Option<EventListener>,
11}
12
13impl UseWindowBuilder {
14    /// hooks for window's size with config
15    ///
16    /// # Arguments
17    ///
18    /// returns: [`UseWindowSize`]
19    ///
20    /// # Examples
21    ///
22    /// ```
23    /// use dioxus::prelude::*;
24    /// use dioxus_use_window::{UseWindowBuilder};
25    ///
26    /// fn App(cx: Scope) -> Element {
27    ///     let hook = UseWindowBuilder::default().use_window(&cx);
28    ///
29    ///     cx.render(rsx!(
30    ///         h1 { "Window size: {hook}" }
31    ///     ))
32    /// }
33    /// ```
34    pub fn use_window<'a>(&self, cx: &'a ScopeState) -> &'a mut UseWindow {
35        let hook = self.use_window_hook(cx);
36        cx.use_hook(|| hook)
37    }
38    #[inline]
39    pub(crate) fn use_window_hook(&self, cx: &ScopeState) -> UseWindow {
40        UseWindow::new(cx, self).unwrap_or_else(|| UseWindow::new_ssr(cx, self))
41    }
42}
43
44impl UseWindow {
45    fn new(cx: &ScopeState, config: &UseWindowBuilder) -> Option<Self> {
46        let data = WindowSizeData::new(window(), (config.missing_x as _, config.missing_y as _));
47        let window = window()?;
48        let listen_window_resize = Self::on_window_resize(cx, &window, &data);
49        let listen_fullscreen = Self::on_fullscreen_change(cx, &window, &data);
50        Some(Self { data, listen_window_resize: Some(listen_window_resize), listen_fullscreen: Some(listen_fullscreen) })
51    }
52    fn new_ssr(_: &ScopeState, config: &UseWindowBuilder) -> Self {
53        info!("Window Resize Listener Initializing failed, using ssr mode now.");
54        let data = WindowSizeData::new(None, (config.missing_x as _, config.missing_y as _));
55        Self { data, listen_window_resize: None, listen_fullscreen: None }
56    }
57    fn on_window_resize(cx: &ScopeState, window: &Window, _: &Rc<RefCell<WindowSizeData>>) -> EventListener {
58        #[cfg(debug_assertions)]
59        {
60            info!("Windows Resize Listener Initialized at {}!", cx.scope_id().0);
61        }
62        let regenerate = cx.schedule_update();
63        EventListener::new(window, "resize", move |_| {
64            regenerate();
65        })
66    }
67    fn on_fullscreen_change(cx: &ScopeState, window: &Window, _: &Rc<RefCell<WindowSizeData>>) -> EventListener {
68        #[cfg(debug_assertions)]
69        {
70            info!("Full Screen Listener Initialized at {}!", cx.scope_id().0);
71        }
72        let regenerate = cx.schedule_update();
73        EventListener::new(window, "fullscreenchange", move |_| {
74            regenerate();
75        })
76    }
77    #[inline]
78    pub(crate) fn data_ref(&self) -> Ref<WindowSizeData> {
79        self.data.borrow()
80    }
81}
82
83impl UseWindow {
84    /// get height of current window
85    ///
86    /// **read-only**
87    #[inline]
88    pub fn size(&self) -> (usize, usize) {
89        (self.width(), self.height())
90    }
91    /// get height of current window
92    ///
93    /// **read-only**
94    #[inline]
95    pub fn width(&self) -> usize {
96        self.data.borrow().inner_width() as usize
97    }
98    /// get height of current window
99    ///
100    /// **read-only**
101    #[inline]
102    pub fn height(&self) -> usize {
103        self.data.borrow().inner_height() as usize
104    }
105    /// get aspect radio of current window
106    #[inline]
107    pub fn aspect_radio(&self) -> f64 {
108        self.data.borrow().inner_aspect_radio()
109    }
110    /// get layout of current window
111    #[inline]
112    pub fn layout<T>(&self) -> T
113    where
114        T: From<usize>,
115    {
116        let w = self.data.borrow().inner_width() as usize;
117        T::from(w)
118    }
119}
120
121// noinspection RsSelfConvention
122impl UseWindow {
123    /// using as [`WindowWidth`]
124    #[inline]
125    pub fn as_width(self) -> UseWindowWidth {
126        UseWindowWidth::new(self)
127    }
128    /// using as [`WindowHeight`]
129    #[inline]
130    pub fn as_height(self) -> UseWindowHeight {
131        UseWindowHeight::new(self)
132    }
133    /// using as [`WindowLayout`]
134    #[inline]
135    pub fn as_layout<T>(self) -> UseWindowLayout<T> {
136        UseWindowLayout::new(self)
137    }
138}