i_slint_backend_winit/
drag_resize_window.rs

1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4use winit::window::{CursorIcon, ResizeDirection};
5
6pub fn handle_cursor_move_for_resize(
7    window: &winit::window::Window,
8    position: winit::dpi::PhysicalPosition<f64>,
9    current_direction: Option<ResizeDirection>,
10    border_size: f64,
11) -> Option<ResizeDirection> {
12    if !window.is_decorated() && window.is_resizable() {
13        let location = get_resize_direction(window.inner_size(), position, border_size);
14
15        if current_direction != location {
16            window.set_cursor(resize_direction_cursor_icon(location));
17        }
18
19        return location;
20    }
21
22    None
23}
24
25pub fn handle_resize(window: &winit::window::Window, direction: Option<ResizeDirection>) {
26    if let Some(dir) = direction {
27        let _ = window.drag_resize_window(dir);
28    }
29}
30
31/// Get the cursor icon that corresponds to the resize direction.
32fn resize_direction_cursor_icon(resize_direction: Option<ResizeDirection>) -> CursorIcon {
33    match resize_direction {
34        Some(resize_direction) => match resize_direction {
35            ResizeDirection::East => CursorIcon::EResize,
36            ResizeDirection::North => CursorIcon::NResize,
37            ResizeDirection::NorthEast => CursorIcon::NeResize,
38            ResizeDirection::NorthWest => CursorIcon::NwResize,
39            ResizeDirection::South => CursorIcon::SResize,
40            ResizeDirection::SouthEast => CursorIcon::SeResize,
41            ResizeDirection::SouthWest => CursorIcon::SwResize,
42            ResizeDirection::West => CursorIcon::WResize,
43        },
44        None => CursorIcon::Default,
45    }
46}
47
48fn get_resize_direction(
49    win_size: winit::dpi::PhysicalSize<u32>,
50    position: winit::dpi::PhysicalPosition<f64>,
51    border_size: f64,
52) -> Option<ResizeDirection> {
53    enum X {
54        West,
55        East,
56        Default,
57    }
58
59    enum Y {
60        North,
61        South,
62        Default,
63    }
64
65    let xdir = if position.x < border_size {
66        X::West
67    } else if position.x > (win_size.width as f64 - border_size) {
68        X::East
69    } else {
70        X::Default
71    };
72
73    let ydir = if position.y < border_size {
74        Y::North
75    } else if position.y > (win_size.height as f64 - border_size) {
76        Y::South
77    } else {
78        Y::Default
79    };
80
81    Some(match (xdir, ydir) {
82        (X::West, Y::North) => ResizeDirection::NorthWest,
83        (X::West, Y::South) => ResizeDirection::SouthWest,
84        (X::West, Y::Default) => ResizeDirection::West,
85
86        (X::East, Y::North) => ResizeDirection::NorthEast,
87        (X::East, Y::South) => ResizeDirection::SouthEast,
88        (X::East, Y::Default) => ResizeDirection::East,
89
90        (X::Default, Y::North) => ResizeDirection::North,
91        (X::Default, Y::South) => ResizeDirection::South,
92        (X::Default, Y::Default) => return None,
93    })
94}