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}