livid/traits/
widget_ext.rs

1use crate::{
2    enums::*,
3    traits::{GroupExt, WidgetBase},
4};
5use wasm_bindgen::JsCast;
6use wasm_bindgen::UnwrapThrowExt;
7
8/// Defines the methods implemented by all widgets
9pub trait WidgetExt: WidgetBase {
10    /// Set the callback for the widget
11    fn add_callback<F: 'static + FnMut(&Self)>(&self, event: Event, mut cb: F)
12    where
13        Self: Sized,
14    {
15        self.inner().add_callback(event, move |w| unsafe {
16            cb(&Self::from_widget(w));
17        });
18    }
19    fn set_id(&self, id: &str) {
20        self.inner().set_id(id);
21    }
22    fn with_id(self, id: &str) -> Self
23    where
24        Self: Sized,
25    {
26        self.set_id(id);
27        self
28    }
29    fn set_class(&self, class: &str) {
30        self.inner().set_class_name(class);
31    }
32    fn with_class(self, class: &str) -> Self
33    where
34        Self: Sized,
35    {
36        self.set_class(class);
37        self
38    }
39    fn class(&self) -> String {
40        self.inner().class_name()
41    }
42    /// Sets the widget's label
43    fn set_label(&self, title: &str) {
44        self.inner().set_text_content(Some(title))
45    }
46    fn with_label(self, title: &str) -> Self
47    where
48        Self: Sized,
49    {
50        self.set_label(title);
51        self
52    }
53    /// Set to position x, y
54    fn set_pos(&self, x: i32, y: i32) {
55        let inner = self.inner();
56        inner.set_style(Style::Left, &x.to_string());
57        inner.set_style(Style::Top, &y.to_string());
58    }
59    /// Set to dimensions width and height
60    fn set_size(&self, width: i32, height: i32) {
61        let inner = self.inner();
62        inner.set_style(Style::Width, &width.to_string());
63        inner.set_style(Style::Height, &height.to_string());
64    }
65    /// set the size on construction
66    fn with_size(self, w: i32, h: i32) -> Self
67    where
68        Self: Sized,
69    {
70        self.set_size(w, h);
71        self
72    }
73    /// Redraws a widget, necessary for resizing and changing positions
74    fn redraw(&self) {
75        self.hide();
76        self.show();
77    }
78    /// Shows the widget
79    fn show(&self) {
80        self.inner().set_style(Style::Display, "block");
81    }
82    /// Hides the widget
83    fn hide(&self) {
84        self.inner().set_style(Style::Display, "none");
85    }
86    /// Returns the x coordinate of the widget
87    fn x(&self) -> i32 {
88        self.inner().style(Style::Left).parse().unwrap_throw()
89    }
90    /// Returns the y coordinate of the widget
91    fn y(&self) -> i32 {
92        self.inner().style(Style::Top).parse().unwrap_throw()
93    }
94    /// Returns the width of the widget
95    fn w(&self) -> i32 {
96        self.inner().client_width()
97    }
98    /// Returns the height of the widget
99    fn h(&self) -> i32 {
100        self.inner().client_height()
101    }
102    /// Returns the label of the widget
103    fn label(&self) -> Option<String> {
104        self.inner().text_content()
105    }
106    /// Returns the widget color
107    fn color(&self) -> Color {
108        Color::from_hex_str(&self.inner().style(Style::BackgroundColor)).unwrap_throw()
109    }
110    /// Sets the widget's color
111    fn set_color(&self, color: Color) {
112        self.inner()
113            .set_style(Style::BackgroundColor, &color.to_str())
114    }
115    /// Sets the widget's color
116    fn set_label_color(&self, color: Color) {
117        self.inner().set_style(Style::Color, &color.to_str())
118    }
119    /// Returns the widget's label color
120    fn label_color(&self) -> Color {
121        Color::from_hex_str(&self.inner().style(Style::Color)).unwrap_throw()
122    }
123    fn set_label_size(&self, size: u8) {
124        self.inner().set_style(Style::FontSize, &size.to_string());
125    }
126    fn label_size(&self) -> u8 {
127        self.inner().style(Style::FontSize).parse().unwrap_throw()
128    }
129    fn set_label_font(&self, font: &str) {
130        self.inner().set_style(Style::Font, font);
131    }
132    fn label_font(&self) -> String {
133        self.inner().style(Style::Font)
134    }
135    /// do callback
136    fn do_callback(&self, event: Event) {
137        let c = self.inner();
138        let elem: &web_sys::EventTarget = c.dyn_ref().unwrap_throw();
139        elem.dispatch_event(&web_sys::Event::new(&event.to_str()).unwrap_throw())
140            .unwrap_throw();
141    }
142    fn set_margin(&self, size: i32) {
143        self.inner().set_style(Style::Margin, &size.to_string());
144    }
145    fn margin(&self) -> i32 {
146        self.inner().style(Style::Margin).parse().unwrap_throw()
147    }
148    fn set_padding(&self, size: i32) {
149        self.inner().set_style(Style::Padding, &size.to_string());
150    }
151    fn padding(&self) -> i32 {
152        self.inner().style(Style::Padding).parse().unwrap_throw()
153    }
154    fn set_frame(&self, frame: FrameType) {
155        match frame {
156            FrameType::FlatBox => {
157                self.inner().set_style(Style::Border, "none");
158                self.inner().set_style(Style::BorderRadius, "0px");
159            }
160            FrameType::RFlatBox => {
161                self.inner().set_style(Style::Border, "none");
162                self.inner().set_style(Style::BorderRadius, "8px");
163            }
164            FrameType::RoundBox => {
165                self.inner().set_style(Style::Border, "none");
166                self.inner().set_style(Style::BorderRadius, "50%");
167            }
168            FrameType::FlatFrame => {
169                self.inner().set_style(Style::BorderRadius, "0px");
170            }
171            FrameType::RFlatFrame => {
172                self.inner().set_style(Style::BorderRadius, "8px");
173            }
174            FrameType::RoundFrame => {
175                self.inner().set_style(Style::BorderRadius, "50%");
176            }
177        }
178    }
179    fn parent(&self) -> Option<Box<dyn GroupExt>> {
180        if let Some(parent) = self.inner().parent_element() {
181            Some(Box::new(unsafe {
182                crate::group::Group::from_widget(&crate::widget::Widget::from_elem(parent))
183            }))
184        } else {
185            None
186        }
187    }
188}