2020-05-29 22:25:27 +00:00
|
|
|
use alloc::boxed::Box;
|
2020-04-18 17:20:38 +00:00
|
|
|
use core::mem;
|
2020-04-12 10:19:28 +00:00
|
|
|
use core::ptr;
|
2020-05-29 22:25:27 +00:00
|
|
|
use cstr_core::CString;
|
|
|
|
use embedded_graphics::pixelcolor::{Rgb565, Rgb888};
|
2020-04-12 11:57:17 +00:00
|
|
|
use lvgl_sys;
|
2020-04-12 10:19:28 +00:00
|
|
|
|
2020-04-13 18:52:06 +00:00
|
|
|
pub trait NativeObject {
|
2020-04-12 10:19:28 +00:00
|
|
|
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t>;
|
|
|
|
}
|
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
pub struct ObjectX {
|
2020-04-12 10:19:28 +00:00
|
|
|
raw: ptr::NonNull<lvgl_sys::lv_obj_t>,
|
|
|
|
}
|
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
impl ObjectX {
|
|
|
|
pub(crate) fn from_raw(raw: ptr::NonNull<lvgl_sys::lv_obj_t>) -> Self {
|
|
|
|
Self { raw }
|
2020-04-12 10:19:28 +00:00
|
|
|
}
|
2020-04-13 14:15:50 +00:00
|
|
|
}
|
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
impl NativeObject for ObjectX {
|
2020-04-13 14:15:50 +00:00
|
|
|
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t> {
|
|
|
|
unsafe { ptr::NonNull::new_unchecked(self.raw.as_ptr()) }
|
|
|
|
}
|
|
|
|
}
|
2020-04-12 23:49:23 +00:00
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
pub trait Object: NativeObject {
|
2020-04-13 14:15:50 +00:00
|
|
|
fn set_pos(&mut self, x: i16, y: i16) {
|
2020-04-12 23:49:23 +00:00
|
|
|
unsafe {
|
|
|
|
lvgl_sys::lv_obj_set_pos(
|
|
|
|
self.raw().as_mut(),
|
|
|
|
x as lvgl_sys::lv_coord_t,
|
|
|
|
y as lvgl_sys::lv_coord_t,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-13 14:15:50 +00:00
|
|
|
fn set_size(&mut self, w: i16, h: i16) {
|
2020-04-12 23:49:23 +00:00
|
|
|
unsafe {
|
|
|
|
lvgl_sys::lv_obj_set_size(
|
|
|
|
self.raw().as_mut(),
|
|
|
|
w as lvgl_sys::lv_coord_t,
|
|
|
|
h as lvgl_sys::lv_coord_t,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-13 14:15:50 +00:00
|
|
|
fn set_width(&mut self, w: u32) {
|
2020-04-12 23:49:23 +00:00
|
|
|
unsafe {
|
2020-04-13 14:15:50 +00:00
|
|
|
lvgl_sys::lv_obj_set_width(self.raw().as_mut(), w as lvgl_sys::lv_coord_t);
|
2020-04-12 23:49:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-13 14:15:50 +00:00
|
|
|
fn set_height(&mut self, h: u32) {
|
2020-04-12 23:49:23 +00:00
|
|
|
unsafe {
|
2020-04-13 14:15:50 +00:00
|
|
|
lvgl_sys::lv_obj_set_height(self.raw().as_mut(), h as lvgl_sys::lv_coord_t);
|
2020-04-12 23:49:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
fn set_align<C>(&mut self, base: &mut C, align: Align, x_mod: i32, y_mod: i32)
|
|
|
|
where
|
|
|
|
C: NativeObject,
|
|
|
|
{
|
2020-04-13 14:15:50 +00:00
|
|
|
let align = match align {
|
2020-04-13 18:52:06 +00:00
|
|
|
Align::Center => lvgl_sys::LV_ALIGN_CENTER,
|
|
|
|
Align::InTopLeft => lvgl_sys::LV_ALIGN_IN_TOP_LEFT,
|
|
|
|
Align::InTopMid => lvgl_sys::LV_ALIGN_IN_TOP_MID,
|
|
|
|
Align::InTopRight => lvgl_sys::LV_ALIGN_IN_TOP_RIGHT,
|
|
|
|
Align::InBottomLeft => lvgl_sys::LV_ALIGN_IN_BOTTOM_LEFT,
|
|
|
|
Align::InBottomMid => lvgl_sys::LV_ALIGN_IN_BOTTOM_MID,
|
|
|
|
Align::InBottomRight => lvgl_sys::LV_ALIGN_IN_BOTTOM_RIGHT,
|
|
|
|
Align::InLeftMid => lvgl_sys::LV_ALIGN_IN_LEFT_MID,
|
|
|
|
Align::InRightMid => lvgl_sys::LV_ALIGN_IN_RIGHT_MID,
|
|
|
|
Align::OutTopLeft => lvgl_sys::LV_ALIGN_OUT_TOP_LEFT,
|
|
|
|
Align::OutTopMid => lvgl_sys::LV_ALIGN_OUT_TOP_MID,
|
|
|
|
Align::OutTopRight => lvgl_sys::LV_ALIGN_OUT_TOP_RIGHT,
|
|
|
|
Align::OutBottomLeft => lvgl_sys::LV_ALIGN_OUT_BOTTOM_LEFT,
|
|
|
|
Align::OutBottomMid => lvgl_sys::LV_ALIGN_OUT_BOTTOM_MID,
|
|
|
|
Align::OutBottomRight => lvgl_sys::LV_ALIGN_OUT_BOTTOM_RIGHT,
|
|
|
|
Align::OutLeftTop => lvgl_sys::LV_ALIGN_OUT_LEFT_TOP,
|
|
|
|
Align::OutLeftMid => lvgl_sys::LV_ALIGN_OUT_LEFT_MID,
|
|
|
|
Align::OutLeftBottom => lvgl_sys::LV_ALIGN_OUT_LEFT_BOTTOM,
|
|
|
|
Align::OutRightTop => lvgl_sys::LV_ALIGN_OUT_RIGHT_TOP,
|
|
|
|
Align::OutRightMid => lvgl_sys::LV_ALIGN_OUT_RIGHT_MID,
|
|
|
|
Align::OutRightBottom => lvgl_sys::LV_ALIGN_OUT_RIGHT_BOTTOM,
|
2020-04-12 23:49:23 +00:00
|
|
|
} as lvgl_sys::lv_align_t;
|
|
|
|
unsafe {
|
|
|
|
lvgl_sys::lv_obj_align(
|
|
|
|
self.raw().as_mut(),
|
|
|
|
base.raw().as_mut(),
|
|
|
|
align,
|
|
|
|
x_mod as lvgl_sys::lv_coord_t,
|
2020-04-13 14:15:50 +00:00
|
|
|
y_mod as lvgl_sys::lv_coord_t,
|
2020-04-12 23:49:23 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2020-04-13 18:52:06 +00:00
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
fn set_style(&mut self, style: Style);
|
2020-04-18 17:20:38 +00:00
|
|
|
}
|
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
impl Object for ObjectX {
|
|
|
|
fn set_style(&mut self, style: Style) {
|
2020-04-18 17:20:38 +00:00
|
|
|
unsafe {
|
2020-05-29 22:25:27 +00:00
|
|
|
let boxed = Box::new(style.raw);
|
|
|
|
lvgl_sys::lv_obj_set_style(self.raw().as_mut(), Box::into_raw(boxed));
|
2020-04-18 17:20:38 +00:00
|
|
|
};
|
|
|
|
}
|
2020-04-12 10:19:28 +00:00
|
|
|
}
|
|
|
|
|
2020-04-13 14:42:05 +00:00
|
|
|
macro_rules! define_object {
|
|
|
|
($item:ident) => {
|
2020-05-29 22:25:27 +00:00
|
|
|
pub struct $item {
|
2020-05-31 07:12:37 +00:00
|
|
|
core: $crate::support::ObjectX,
|
2020-04-13 14:42:05 +00:00
|
|
|
}
|
|
|
|
|
2020-05-31 07:12:37 +00:00
|
|
|
impl $crate::support::NativeObject for $item {
|
|
|
|
fn raw(&self) -> core::ptr::NonNull<lvgl_sys::lv_obj_t> {
|
2020-04-13 14:42:05 +00:00
|
|
|
self.core.raw()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-31 07:12:37 +00:00
|
|
|
impl $crate::support::Object for $item {
|
|
|
|
fn set_style(&mut self, style: $crate::support::Style) {
|
2020-04-13 18:52:06 +00:00
|
|
|
unsafe {
|
2020-05-31 07:12:37 +00:00
|
|
|
let boxed = alloc::boxed::Box::new(style.raw);
|
|
|
|
lvgl_sys::lv_obj_set_style(
|
|
|
|
self.raw().as_mut(),
|
|
|
|
alloc::boxed::Box::into_raw(boxed),
|
|
|
|
);
|
2020-04-13 18:52:06 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2020-04-18 17:20:38 +00:00
|
|
|
};
|
2020-04-13 14:42:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
define_object!(Button);
|
2020-04-12 10:19:28 +00:00
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
impl Button {
|
2020-04-18 17:20:38 +00:00
|
|
|
pub fn new<C>(parent: &mut C) -> Self
|
|
|
|
where
|
|
|
|
C: NativeObject,
|
|
|
|
{
|
2020-04-12 10:19:28 +00:00
|
|
|
let raw = unsafe {
|
|
|
|
let ptr = lvgl_sys::lv_btn_create(parent.raw().as_mut(), ptr::null_mut());
|
|
|
|
ptr::NonNull::new_unchecked(ptr)
|
|
|
|
};
|
2020-05-29 22:25:27 +00:00
|
|
|
let core = ObjectX::from_raw(raw);
|
2020-04-12 10:19:28 +00:00
|
|
|
Self { core }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-12 23:49:23 +00:00
|
|
|
pub enum LabelAlign {
|
|
|
|
Left,
|
|
|
|
Center,
|
|
|
|
Right,
|
|
|
|
Auto,
|
|
|
|
}
|
|
|
|
|
2020-04-13 14:42:05 +00:00
|
|
|
define_object!(Label);
|
2020-04-12 10:19:28 +00:00
|
|
|
|
2020-05-29 22:25:27 +00:00
|
|
|
impl Label {
|
2020-04-18 17:20:38 +00:00
|
|
|
pub fn new<C>(parent: &mut C) -> Self
|
|
|
|
where
|
|
|
|
C: NativeObject,
|
|
|
|
{
|
2020-04-12 10:19:28 +00:00
|
|
|
let raw = unsafe {
|
|
|
|
let ptr = lvgl_sys::lv_label_create(parent.raw().as_mut(), ptr::null_mut());
|
|
|
|
ptr::NonNull::new_unchecked(ptr)
|
|
|
|
};
|
2020-05-29 22:25:27 +00:00
|
|
|
let core = ObjectX::from_raw(raw);
|
2020-04-12 10:19:28 +00:00
|
|
|
Self { core }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_text(&mut self, text: &str) {
|
2020-05-29 22:25:27 +00:00
|
|
|
let text = CString::new(text).unwrap();
|
2020-04-12 10:19:28 +00:00
|
|
|
unsafe {
|
2020-05-29 22:25:27 +00:00
|
|
|
lvgl_sys::lv_label_set_text(self.core.raw().as_mut(), text.as_ptr());
|
2020-04-12 10:19:28 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-12 23:49:23 +00:00
|
|
|
|
2020-04-13 18:52:06 +00:00
|
|
|
pub fn set_label_align(&mut self, align: LabelAlign) {
|
2020-04-12 23:49:23 +00:00
|
|
|
let align = match align {
|
|
|
|
LabelAlign::Left => lvgl_sys::LV_LABEL_ALIGN_LEFT,
|
|
|
|
LabelAlign::Center => lvgl_sys::LV_LABEL_ALIGN_CENTER,
|
|
|
|
LabelAlign::Right => lvgl_sys::LV_LABEL_ALIGN_RIGHT,
|
|
|
|
LabelAlign::Auto => lvgl_sys::LV_LABEL_ALIGN_AUTO,
|
|
|
|
} as lvgl_sys::lv_label_align_t;
|
|
|
|
unsafe {
|
2020-04-13 14:15:50 +00:00
|
|
|
lvgl_sys::lv_label_set_align(self.core.raw().as_mut(), align);
|
2020-04-12 23:49:23 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-14 19:33:34 +00:00
|
|
|
|
|
|
|
pub fn set_recolor(&mut self, recolor: bool) {
|
|
|
|
unsafe {
|
|
|
|
lvgl_sys::lv_label_set_recolor(self.core.raw().as_mut(), recolor);
|
|
|
|
}
|
|
|
|
}
|
2020-04-12 10:19:28 +00:00
|
|
|
}
|
2020-04-13 18:52:06 +00:00
|
|
|
|
|
|
|
pub enum Themes {
|
|
|
|
Pretty,
|
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
pub struct Style {
|
2020-05-31 07:12:37 +00:00
|
|
|
pub(crate) raw: lvgl_sys::lv_style_t,
|
2020-04-13 18:52:06 +00:00
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
impl Style {
|
|
|
|
pub fn new() -> Self {
|
|
|
|
let raw = unsafe {
|
|
|
|
let mut native_style = mem::MaybeUninit::<lvgl_sys::lv_style_t>::uninit();
|
|
|
|
lvgl_sys::lv_style_copy(native_style.as_mut_ptr(), &lvgl_sys::lv_style_pretty);
|
|
|
|
native_style.assume_init()
|
|
|
|
};
|
|
|
|
Self { raw }
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Object's main background color.
|
|
|
|
pub fn set_body_main_color(&mut self, color: Color) {
|
|
|
|
self.raw.body.main_color = color.raw;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Second color. If not equal to `set_body_main_color` a gradient will be drawn for the background.
|
|
|
|
pub fn set_body_grad_color(&mut self, color: Color) {
|
|
|
|
self.raw.body.grad_color = color.raw;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Text color.
|
|
|
|
pub fn set_text_color(&mut self, color: Color) {
|
|
|
|
self.raw.text.color = color.raw;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Font used for displaying the text.
|
|
|
|
pub fn set_text_font(&mut self, font: &lvgl_sys::lv_font_t) {
|
|
|
|
self.raw.text.font = font;
|
|
|
|
}
|
2020-05-30 14:31:01 +00:00
|
|
|
|
|
|
|
/// Body radius for rounded corners.
|
|
|
|
pub fn set_body_radius(&mut self, radius: i16) {
|
|
|
|
self.raw.body.radius = radius;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Border color.
|
|
|
|
pub fn set_body_border_color(&mut self, color: Color) {
|
|
|
|
self.raw.body.border.color = color.raw;
|
|
|
|
}
|
2020-04-13 18:52:06 +00:00
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
impl Clone for Style {
|
2020-04-15 07:50:25 +00:00
|
|
|
fn clone(&self) -> Self {
|
2020-04-18 17:20:38 +00:00
|
|
|
let mut native_style = mem::MaybeUninit::<lvgl_sys::lv_style_t>::uninit();
|
|
|
|
unsafe {
|
|
|
|
lvgl_sys::lv_style_copy(
|
|
|
|
native_style.as_mut_ptr(),
|
|
|
|
&self.raw as *const lvgl_sys::lv_style_t,
|
|
|
|
);
|
|
|
|
Self {
|
|
|
|
raw: native_style.assume_init(),
|
2020-04-15 07:50:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct Color {
|
|
|
|
raw: lvgl_sys::lv_color_t,
|
2020-04-15 07:50:25 +00:00
|
|
|
}
|
|
|
|
|
2020-04-18 17:20:38 +00:00
|
|
|
impl Color {
|
|
|
|
pub fn from_rgb((r, g, b): (u8, u8, u8)) -> Self {
|
2020-04-21 08:52:21 +00:00
|
|
|
let raw = unsafe { lvgl_sys::_LV_COLOR_MAKE(r, g, b) };
|
2020-04-18 17:20:38 +00:00
|
|
|
Self { raw }
|
2020-04-15 07:50:25 +00:00
|
|
|
}
|
2020-05-29 22:25:27 +00:00
|
|
|
|
|
|
|
pub fn from_raw(raw: lvgl_sys::lv_color_t) -> Self {
|
|
|
|
Self { raw }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Color> for Rgb888 {
|
|
|
|
fn from(color: Color) -> Self {
|
|
|
|
unsafe {
|
|
|
|
Rgb888::new(
|
|
|
|
lvgl_sys::_LV_COLOR_GET_R(color.raw) as u8,
|
|
|
|
lvgl_sys::_LV_COLOR_GET_G(color.raw) as u8,
|
|
|
|
lvgl_sys::_LV_COLOR_GET_B(color.raw) as u8,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<Color> for Rgb565 {
|
|
|
|
fn from(color: Color) -> Self {
|
|
|
|
unsafe {
|
|
|
|
Rgb565::new(
|
|
|
|
lvgl_sys::_LV_COLOR_GET_R(color.raw) as u8,
|
|
|
|
lvgl_sys::_LV_COLOR_GET_G(color.raw) as u8,
|
|
|
|
lvgl_sys::_LV_COLOR_GET_B(color.raw) as u8,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
2020-04-15 07:50:25 +00:00
|
|
|
}
|
|
|
|
|
2020-04-14 19:33:34 +00:00
|
|
|
pub enum Align {
|
|
|
|
Center,
|
|
|
|
InTopLeft,
|
|
|
|
InTopMid,
|
|
|
|
InTopRight,
|
|
|
|
InBottomLeft,
|
|
|
|
InBottomMid,
|
|
|
|
InBottomRight,
|
|
|
|
InLeftMid,
|
|
|
|
InRightMid,
|
|
|
|
OutTopLeft,
|
|
|
|
OutTopMid,
|
|
|
|
OutTopRight,
|
|
|
|
OutBottomLeft,
|
|
|
|
OutBottomMid,
|
|
|
|
OutBottomRight,
|
|
|
|
OutLeftTop,
|
|
|
|
OutLeftMid,
|
|
|
|
OutLeftBottom,
|
|
|
|
OutRightTop,
|
|
|
|
OutRightMid,
|
|
|
|
OutRightBottom,
|
|
|
|
}
|