nice_plug_egui/
resizable_window.rs1use egui::emath::GuiRounding;
4use egui::{CentralPanel, Id, Rect, Response, Sense, Ui, Vec2, pos2};
5use egui::{InnerResponse, UiBuilder};
6
7use crate::EguiState;
8
9pub struct ResizableWindow {
12 id: Id,
13 min_size: Vec2,
14}
15
16impl ResizableWindow {
17 pub fn new(id_source: impl std::hash::Hash) -> Self {
18 Self {
19 id: Id::new(id_source),
20 min_size: Vec2::splat(16.0),
21 }
22 }
23
24 #[inline]
26 pub fn min_size(mut self, min_size: impl Into<Vec2>) -> Self {
27 self.min_size = min_size.into();
28 self
29 }
30
31 pub fn show<R>(
32 self,
33 ui: &mut Ui,
34 egui_state: &EguiState,
35 add_contents: impl FnOnce(&mut Ui) -> R,
36 ) -> InnerResponse<R> {
37 CentralPanel::default().show_inside(ui, move |ui| {
38 let ui_rect = ui.clip_rect();
39 let mut content_ui =
40 ui.new_child(UiBuilder::new().max_rect(ui_rect).layout(*ui.layout()));
41
42 let ret = add_contents(&mut content_ui);
43
44 let corner_size = Vec2::splat(ui.visuals().resize_corner_size);
45 let corner_rect = Rect::from_min_size(ui_rect.max - corner_size, corner_size);
46
47 let corner_response = ui.interact(corner_rect, self.id.with("corner"), Sense::drag());
48
49 if let Some(pointer_pos) = corner_response.interact_pointer_pos() {
50 let desired_size = (pointer_pos - ui_rect.min + 0.5 * corner_response.rect.size())
51 .max(self.min_size);
52
53 if corner_response.dragged() {
54 egui_state.set_requested_size((
55 desired_size.x.round() as u32,
56 desired_size.y.round() as u32,
57 ));
58 }
59 }
60
61 paint_resize_corner(&content_ui, &corner_response);
62
63 ret
64 })
65 }
66}
67
68pub fn paint_resize_corner(ui: &Ui, response: &Response) {
69 let stroke = ui.style().interact(response).fg_stroke;
70
71 let painter = ui.painter();
72 let rect = response.rect.translate(-Vec2::splat(2.0)); let cp = rect.max.round_to_pixels(painter.pixels_per_point());
74
75 let mut w = 2.0;
76
77 while w <= rect.width() && w <= rect.height() {
78 painter.line_segment([pos2(cp.x - w, cp.y), pos2(cp.x, cp.y - w)], stroke);
79 w += 4.0;
80 }
81}