graphics/
logo.rs

1use crate::{Color, Error, Point, Result, lvgl};
2
3pub struct Logo {
4    pub object: *mut lvgl::lv_obj_t,
5}
6
7impl Logo {
8    pub const BASE_SIZE: Point = Point::new(32, 32);
9    pub const BASE_PART_SIZE: Point = Point::new(10, 21);
10
11    pub fn get_factor(size: Point) -> u8 {
12        let factor_x = size.get_x() / Self::BASE_SIZE.get_x();
13        let factor_y = size.get_y() / Self::BASE_SIZE.get_y();
14
15        factor_x.min(factor_y) as u8
16    }
17
18    /// Create a new Logo object
19    ///
20    /// # Arguments
21    /// * `Parent` - The parent object to create the logo on.
22    /// * `Factor` - The scaling factor for the logo size.
23    /// * `Color` - The color of the logo parts.
24    ///
25    /// # Safety
26    /// This function is unsafe because it may dereference raw pointers (e.g.
27    pub unsafe fn new(parent: *mut lvgl::lv_obj_t, factor: u8, color: Color) -> Result<Self> {
28        unsafe {
29            let object = lvgl::lv_button_create(parent);
30
31            if object.is_null() {
32                return Err(Error::FailedToCreateObject);
33            }
34
35            let size = Self::BASE_SIZE.scale(factor as f64);
36
37            lvgl::lv_obj_set_size(object, size.x.into(), size.y.into());
38            lvgl::lv_obj_set_style_bg_opa(object, lvgl::LV_OPA_0 as u8, lvgl::LV_STATE_DEFAULT);
39            lvgl::lv_obj_set_style_pad_all(object, 0, lvgl::LV_STATE_DEFAULT);
40            lvgl::lv_obj_set_style_radius(object, 0, lvgl::LV_STATE_DEFAULT);
41            lvgl::lv_obj_set_style_border_width(object, 0, lvgl::LV_STATE_DEFAULT);
42
43            Self::new_part(object, lvgl::lv_align_t_LV_ALIGN_TOP_LEFT, factor, color)?;
44            Self::new_part(object, lvgl::lv_align_t_LV_ALIGN_BOTTOM_LEFT, factor, color)?;
45            Self::new_part(
46                object,
47                lvgl::lv_align_t_LV_ALIGN_BOTTOM_RIGHT,
48                factor,
49                color,
50            )?;
51            Self::new_part(object, lvgl::lv_align_t_LV_ALIGN_TOP_RIGHT, factor, color)?;
52
53            Ok(Self { object })
54        }
55    }
56
57    pub fn get_inner_object(&self) -> *mut lvgl::lv_obj_t {
58        self.object
59    }
60
61    fn new_part(
62        parent: *mut lvgl::lv_obj_t,
63        alignment: lvgl::lv_align_t,
64        factor: u8,
65        color: Color,
66    ) -> Result<*mut lvgl::lv_obj_t> {
67        let size = Self::BASE_PART_SIZE.scale(factor as f64);
68
69        unsafe {
70            let part = lvgl::lv_button_create(parent);
71
72            if part.is_null() {
73                return Err(Error::FailedToCreateObject);
74            }
75
76            lvgl::lv_obj_set_style_bg_color(part, color.into_lvgl_color(), lvgl::LV_STATE_DEFAULT);
77            lvgl::lv_obj_set_style_bg_color(part, lvgl::lv_color_white(), lvgl::LV_STATE_PRESSED);
78
79            lvgl::lv_obj_set_align(part, alignment);
80
81            match alignment {
82                lvgl::lv_align_t_LV_ALIGN_TOP_LEFT | lvgl::lv_align_t_LV_ALIGN_BOTTOM_RIGHT => {
83                    lvgl::lv_obj_set_size(part, size.x.into(), size.y.into());
84                }
85                lvgl::lv_align_t_LV_ALIGN_BOTTOM_LEFT | lvgl::lv_align_t_LV_ALIGN_TOP_RIGHT => {
86                    lvgl::lv_obj_set_size(part, size.y.into(), size.x.into());
87                }
88                _ => {}
89            }
90
91            lvgl::lv_obj_set_style_pad_all(part, 0, lvgl::LV_STATE_DEFAULT);
92            lvgl::lv_obj_set_style_radius(part, 0, lvgl::LV_STATE_DEFAULT);
93            lvgl::lv_obj_set_style_border_width(part, 0, lvgl::LV_STATE_DEFAULT);
94            lvgl::lv_obj_add_flag(part, lvgl::lv_obj_flag_t_LV_OBJ_FLAG_EVENT_BUBBLE);
95
96            Ok(part)
97        }
98    }
99}
100
101impl Drop for Logo {
102    fn drop(&mut self) {
103        unsafe {
104            lvgl::lv_obj_delete(self.object);
105        }
106    }
107}