Skip to main content

graphics/
lvgl.rs

1use core::ffi::c_char;
2
3pub use lvgl_rust_sys::*;
4
5use crate::Point;
6
7pub const LV_SIZE_CONTENT: i32 = (LV_COORD_MAX | LV_COORD_TYPE_SPEC) as i32;
8
9pub const LV_STATE_DEFAULT: u32 = 0;
10pub const LV_STATE_CHECKED: u32 = 1 << 2;
11pub const LV_STATE_PRESSED: u32 = 1 << 7;
12
13pub const LV_PART_MAIN: u32 = 0;
14pub const LV_PART_INDICATOR: u32 = 0x020000;
15pub const LV_PART_KNOB: u32 = 0x030000;
16pub const LV_PART_ITEMS: u32 = 0x050000;
17
18pub const LV_OPA_TRANSP: u8 = 0;
19pub const LV_OPA_0: u8 = 0;
20pub const LV_OPA_50: u8 = 127;
21pub const LV_OPA_COVER: u8 = 255;
22
23/// Set the padding of an object on all sides
24///
25/// # Arguments
26///
27/// * `Object` - The object to set the padding of.
28/// * `Padding` - The padding to set.
29/// * `Selector` - The selector to set the padding for.
30///
31/// # Safety
32///
33/// This function is unsafe because it may dereference raw pointers (e.g. `Object`).
34pub unsafe fn lv_obj_set_style_pad_all(
35    object: *mut lv_obj_t,
36    padding: i32,
37    selector: lv_style_selector_t,
38) {
39    unsafe {
40        lv_obj_set_style_pad_top(object, padding, selector);
41        lv_obj_set_style_pad_bottom(object, padding, selector);
42        lv_obj_set_style_pad_left(object, padding, selector);
43        lv_obj_set_style_pad_right(object, padding, selector);
44    }
45}
46
47/// Set the padding of an object on the top side
48///
49/// # Arguments
50///
51/// * `Object` - The object to set the padding of.
52/// * `Padding` - The padding to set.
53/// * `Selector` - The selector to set the padding for.
54///
55/// # Safety
56///
57/// This function is unsafe because it may dereference raw pointers (e.g. `Object`).
58///
59pub unsafe fn lv_obj_move_foreground(object: *mut lv_obj_t) {
60    unsafe {
61        lv_obj_move_to_index(object, -1);
62    }
63}
64
65/// Get the size of an object as a Point
66///
67/// # Arguments
68/// * `Object` - The object to get the size of.
69///
70///  # Safety
71/// This function is unsafe because it may dereference raw pointers (e.g. `Object`).
72///
73pub unsafe fn lv_obj_get_size(object: *mut lv_obj_t) -> Point {
74    unsafe {
75        let width = lv_obj_get_width(object) as i16;
76        let height = lv_obj_get_height(object) as i16;
77
78        Point::new(width, height)
79    }
80}
81
82/// Add a tab to a tabview and adjust the tab button size
83///
84/// # Arguments
85///
86/// * `tabview` - The tabview to add the tab to.
87/// * `name` - The name of the tab.
88///
89/// # Safety
90///
91/// This function is unsafe because it may dereference raw pointers (e.g. `tabview`).
92pub unsafe fn lv_tabview_add_tab(tabview: *mut lv_obj_t, name: *const c_char) -> *mut lv_obj_t {
93    unsafe {
94        let page = lvgl_rust_sys::lv_tabview_add_tab(tabview, name);
95
96        let bar = lv_tabview_get_tab_bar(tabview);
97
98        lv_obj_set_size(bar, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
99
100        // get latest tab button
101        let tab_count = lv_obj_get_child_count(bar);
102        let button = lv_obj_get_child(bar, (tab_count - 1) as _);
103
104        // don't make it grow
105        lv_obj_set_flex_grow(button, 0);
106        lv_obj_set_size(button, LV_SIZE_CONTENT, LV_SIZE_CONTENT);
107
108        page
109    }
110}
111
112unsafe extern "C" fn radio_event_handler(event: *mut lv_event_t) {
113    unsafe {
114        let code = lvgl_rust_sys::lv_event_get_code(event);
115        let target = lvgl_rust_sys::lv_event_get_target(event) as *mut lv_obj_t;
116        let user_data = lvgl_rust_sys::lv_event_get_user_data(event) as *mut lv_obj_t;
117
118        if code == lv_event_code_t_LV_EVENT_CLICKED {
119            let parent = user_data as *mut lv_obj_t;
120            let child_count = lvgl_rust_sys::lv_obj_get_child_count(parent);
121
122            for i in 0..child_count {
123                let child = lvgl_rust_sys::lv_obj_get_child(parent, i as _);
124                if child != target {
125                    lvgl_rust_sys::lv_obj_remove_state(child, LV_STATE_CHECKED as _);
126                }
127            }
128
129            lvgl_rust_sys::lv_obj_add_state(target, LV_STATE_CHECKED as _);
130        }
131    }
132}
133
134/// Create a radio button (a checkbox that behaves like a radio button)
135///
136/// # Arguments
137///
138/// * `parent` - The parent object of the radio button.
139///
140/// # Safety
141/// This function is unsafe because it may dereference raw pointers (e.g. `parent`).
142pub unsafe fn lv_radiobox_create(parent: *mut lv_obj_t) -> *mut lv_obj_t {
143    unsafe {
144        let checkbox = lvgl_rust_sys::lv_checkbox_create(parent);
145
146        lvgl_rust_sys::lv_obj_add_event_cb(
147            checkbox,
148            Some(radio_event_handler),
149            lvgl_rust_sys::lv_event_code_t_LV_EVENT_CLICKED,
150            parent as _,
151        );
152
153        checkbox
154    }
155}