iced_winit/application/
drag_resize.rs
1use winit::window::{CursorIcon, ResizeDirection};
2
3#[cfg(any(
4 all(
5 unix,
6 not(target_vendor = "apple"),
7 not(target_os = "android"),
8 not(target_os = "emscripten"),
9 ),
10 target_os = "windows",
11))]
12const DRAG_RESIZE_SUPPORTED: bool = true;
13
14#[cfg(not(any(
15 all(
16 unix,
17 not(target_vendor = "apple"),
18 not(target_os = "android"),
19 not(target_os = "emscripten"),
20 ),
21 target_os = "windows",
22)))]
23const DRAG_RESIZE_SUPPORTED: bool = false;
24
25pub fn event_func(
27 window: &dyn winit::window::Window,
28 border_size: f64,
29) -> Option<
30 Box<
31 dyn FnMut(
32 &dyn winit::window::Window,
33 &winit::event::WindowEvent,
34 ) -> bool,
35 >,
36> {
37 if DRAG_RESIZE_SUPPORTED {
38 let mut cursor_prev_resize_direction = None;
40
41 Some(Box::new(
42 move |window: &dyn winit::window::Window,
43 window_event: &winit::event::WindowEvent|
44 -> bool {
45 match window_event {
47 winit::event::WindowEvent::CursorMoved {
48 position, ..
49 } => {
50 if !window.is_decorated() {
51 let location = cursor_resize_direction(
52 window.surface_size(),
53 *position,
54 border_size,
55 );
56 if location != cursor_prev_resize_direction {
57 window.set_cursor(
58 resize_direction_cursor_icon(location)
59 .into(),
60 );
61 cursor_prev_resize_direction = location;
62 return true;
63 }
64 }
65 }
66 winit::event::WindowEvent::MouseInput {
67 state: winit::event::ElementState::Pressed,
68 button: winit::event::MouseButton::Left,
69 ..
70 } => {
71 if let Some(direction) = cursor_prev_resize_direction {
72 let _res = window.drag_resize_window(direction);
73 return true;
74 }
75 }
76 _ => (),
77 }
78
79 false
80 },
81 ))
82 } else {
83 None
84 }
85}
86
87fn resize_direction_cursor_icon(
89 resize_direction: Option<ResizeDirection>,
90) -> CursorIcon {
91 match resize_direction {
92 Some(resize_direction) => match resize_direction {
93 ResizeDirection::East => CursorIcon::EResize,
94 ResizeDirection::North => CursorIcon::NResize,
95 ResizeDirection::NorthEast => CursorIcon::NeResize,
96 ResizeDirection::NorthWest => CursorIcon::NwResize,
97 ResizeDirection::South => CursorIcon::SResize,
98 ResizeDirection::SouthEast => CursorIcon::SeResize,
99 ResizeDirection::SouthWest => CursorIcon::SwResize,
100 ResizeDirection::West => CursorIcon::WResize,
101 },
102 None => CursorIcon::Default,
103 }
104}
105
106#[allow(clippy::similar_names)]
108fn cursor_resize_direction(
109 win_size: winit::dpi::PhysicalSize<u32>,
110 position: winit::dpi::PhysicalPosition<f64>,
111 border_size: f64,
112) -> Option<ResizeDirection> {
113 enum XDirection {
114 West,
115 East,
116 Default,
117 }
118
119 enum YDirection {
120 North,
121 South,
122 Default,
123 }
124
125 let xdir = if position.x < border_size {
126 XDirection::West
127 } else if position.x > (win_size.width as f64 - border_size) {
128 XDirection::East
129 } else {
130 XDirection::Default
131 };
132
133 let ydir = if position.y < border_size {
134 YDirection::North
135 } else if position.y > (win_size.height as f64 - border_size) {
136 YDirection::South
137 } else {
138 YDirection::Default
139 };
140
141 Some(match xdir {
142 XDirection::West => match ydir {
143 YDirection::North => ResizeDirection::NorthWest,
144 YDirection::South => ResizeDirection::SouthWest,
145 YDirection::Default => ResizeDirection::West,
146 },
147
148 XDirection::East => match ydir {
149 YDirection::North => ResizeDirection::NorthEast,
150 YDirection::South => ResizeDirection::SouthEast,
151 YDirection::Default => ResizeDirection::East,
152 },
153
154 XDirection::Default => match ydir {
155 YDirection::North => ResizeDirection::North,
156 YDirection::South => ResizeDirection::South,
157 YDirection::Default => return None,
158 },
159 })
160}