1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
use super::*;
use log::debug;
use wasm_bindgen::JsValue;

impl Default for WindowSize {
    fn default() -> Self {
        // used for ssr
        Self { x: MISSING_W, y: MISSING_H, listener: None }
    }
}

impl WindowSize {
    /// builder of [`WindowSize`]
    pub fn new(cx: &ScopeState, x: f64, y: f64) -> Option<Self> {
        #[cfg(debug_assertions)]
        {
            debug!("Windows Resize Listener");
        }
        let window = window()?;
        let regenerate = cx.schedule_update();
        let mut hook = WindowSize { x, y, listener: None };
        let listener = EventListener::new(&window, "resize", move |_| {
            if let Some(size) = Self::get_size() {
                hook.x = size.0;
                hook.y = size.1;
                regenerate();
                #[cfg(debug_assertions)]
                {
                    debug!("Windows Resize Event: {:?}", size);
                }
            }
        });
        hook.listener = Some(listener);
        Some(hook)
    }
    /// get size of the current window, return `None` if window not found
    pub fn get_size() -> Option<(f64, f64)> {
        let window = window()?;
        let x = window.inner_width().ok()?.as_f64()?;
        let y = window.inner_height().ok()?.as_f64()?;
        Some((x, y))
    }
    /// set width of the current window, return `None` if failed to run
    pub fn set_window_width(input: usize) -> Option<()> {
        window()?.set_inner_width(&JsValue::from(input)).ok()
    }
    /// set height of the current window, return `None` if failed to run
    pub fn set_window_height(input: usize) -> Option<()> {
        window()?.set_inner_width(&JsValue::from(input)).ok()
    }
}

impl WindowSize {
    /// get width of current window
    #[inline]
    pub fn width(&self) -> usize {
        self.x as _
    }
    /// get height of current window
    #[inline]
    pub fn height(&self) -> usize {
        self.x as _
    }
    /// get layout of current window
    #[inline]
    pub fn layout<T>(&self) -> T
    where
        T: From<usize>,
    {
        self.width().into()
    }
    /// get aspect radio of current window
    #[inline]
    pub fn aspect_radio(&self) -> f64 {
        self.x / self.y
    }
    /// using as [`WindowWidth`]
    #[inline]
    pub fn as_width(self) -> WindowWidth {
        WindowWidth { inner: self }
    }
    /// using as [`WindowHeight`]
    #[inline]
    pub fn as_height(self) -> WindowHeight {
        WindowHeight { inner: self }
    }
    /// using as [`WindowLayout`]
    #[inline]
    pub fn as_layout<T>(self) -> WindowLayout<T> {
        WindowLayout { inner: self, bound: Default::default() }
    }
}

impl<T> WindowLayout<T>
where
    T: From<usize>,
{
    /// get layout of current window
    pub fn get(&self) -> T {
        self.inner.layout()
        // T::from(self.inner.x as usize)
    }
}

impl WindowWidth {
    /// get width of current window
    #[inline]
    pub fn get(&self) -> usize {
        self.inner.width()
    }
    /// set width of current window, return `false` if failed to run
    pub fn set(&self, width: usize) -> bool {
        WindowSize::set_window_width(width).is_some()
    }
    /// get layout of current window, return `false` if failed to run
    #[inline]
    pub fn layout<T>(&self) -> T
    where
        T: From<usize>,
    {
        self.inner.layout()
    }
}

impl WindowHeight {
    /// get height of current window
    #[inline]
    pub fn get(&self) -> usize {
        self.inner.height()
    }
    /// set height of current window, return `false` if failed to run
    #[inline]
    pub fn set(&self, height: usize) -> bool {
        WindowSize::set_window_height(height).is_some()
    }
}