fltk_float/
button.rs

1use std::cmp::max;
2use std::ops::{Deref, DerefMut};
3
4use fltk::enums::FrameType;
5use fltk::menu::MenuButton;
6use fltk::prelude::*;
7
8use super::{LayoutElement, LayoutWidgetWrapper, Size};
9
10pub struct ButtonElement<B: ButtonExt + Clone> {
11    widget: B,
12}
13
14impl<B: ButtonExt + Clone> LayoutWidgetWrapper<B> for ButtonElement<B> {
15    fn wrap(widget: B) -> Self {
16        Self { widget }
17    }
18}
19
20impl<B: ButtonExt + Clone> LayoutElement for ButtonElement<B> {
21    fn min_size(&self) -> Size {
22        button_min_size(&self.widget, self.widget.down_frame())
23    }
24
25    fn layout(&self, x: i32, y: i32, width: i32, height: i32) {
26        self.widget.clone().resize(x, y, width, height)
27    }
28}
29
30impl<B: ButtonExt + Clone> Deref for ButtonElement<B> {
31    type Target = B;
32    fn deref(&self) -> &Self::Target {
33        &self.widget
34    }
35}
36
37impl<B: ButtonExt + Clone> DerefMut for ButtonElement<B> {
38    fn deref_mut(&mut self) -> &mut Self::Target {
39        &mut self.widget
40    }
41}
42
43pub struct MenuButtonElement {
44    widget: MenuButton,
45}
46
47impl LayoutWidgetWrapper<MenuButton> for MenuButtonElement {
48    fn wrap(widget: MenuButton) -> Self {
49        Self { widget }
50    }
51}
52
53impl LayoutElement for MenuButtonElement {
54    fn min_size(&self) -> Size {
55        button_min_size(&self.widget, self.widget.down_frame())
56    }
57
58    fn layout(&self, x: i32, y: i32, width: i32, height: i32) {
59        self.widget.clone().resize(x, y, width, height)
60    }
61}
62
63fn button_min_size<B: WidgetExt>(button: &B, down_frame: FrameType) -> Size {
64    let (label_width, label_height) = button.measure_label();
65    let up_frame = button.frame();
66    let frame_dx = max(up_frame.dx(), down_frame.dx());
67    let frame_dy = max(up_frame.dy(), down_frame.dy());
68    let frame_dw = max(up_frame.dw(), down_frame.dw());
69    let frame_dh = max(up_frame.dh(), down_frame.dh());
70    let frame_width = frame_dx + frame_dw;
71    let frame_height = frame_dy + frame_dh;
72
73    Size {
74        width: label_width + frame_width + label_height,
75        height: label_height + 2 * frame_height,
76    }
77}
78
79pub struct FramelessButtonElement<B: ButtonExt + Clone> {
80    widget: B,
81}
82
83impl<B: ButtonExt + Clone> LayoutWidgetWrapper<B> for FramelessButtonElement<B> {
84    fn wrap(widget: B) -> Self {
85        Self { widget }
86    }
87}
88
89impl<B: ButtonExt + Clone> LayoutElement for FramelessButtonElement<B> {
90    fn min_size(&self) -> Size {
91        let (label_width, label_height) = self.widget.measure_label();
92        let up_frame = self.widget.frame();
93        let down_frame = self.widget.down_frame();
94        let frame_dx = max(up_frame.dx(), down_frame.dx());
95        let frame_dy = max(up_frame.dy(), down_frame.dy());
96        let frame_dw = max(up_frame.dw(), down_frame.dw());
97        let frame_dh = max(up_frame.dh(), down_frame.dh());
98        let frame_width = frame_dx + frame_dw;
99        let frame_height = frame_dy + frame_dh;
100
101        Size {
102            width: label_width + frame_width + label_height,
103            height: label_height + frame_height,
104        }
105    }
106
107    fn layout(&self, x: i32, y: i32, width: i32, height: i32) {
108        self.widget.clone().resize(x, y, width, height)
109    }
110}
111
112impl<B: ButtonExt + Clone> Deref for FramelessButtonElement<B> {
113    type Target = B;
114    fn deref(&self) -> &Self::Target {
115        &self.widget
116    }
117}
118
119impl<B: ButtonExt + Clone> DerefMut for FramelessButtonElement<B> {
120    fn deref_mut(&mut self) -> &mut Self::Target {
121        &mut self.widget
122    }
123}