Let users deal with Errors
This commit is contained in:
parent
80d976ac1f
commit
36bae837f8
11 changed files with 132 additions and 108 deletions
|
@ -5,14 +5,14 @@ use embedded_graphics_simulator::{
|
|||
};
|
||||
use lvgl::style::Style;
|
||||
use lvgl::widgets::{Arc, ArcPart, Label, LabelAlign};
|
||||
use lvgl::Widget;
|
||||
use lvgl::{self, Align, Color, DisplayDriver, Event, Part, State, UI};
|
||||
use lvgl::{self, Align, Color, DisplayDriver, Part, State, UI};
|
||||
use lvgl::{LvError, Widget};
|
||||
use lvgl_sys;
|
||||
use std::sync::{mpsc, Arc as StdArc, Mutex};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
fn main() -> Result<(), LvError> {
|
||||
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(
|
||||
lvgl_sys::LV_HOR_RES_MAX,
|
||||
lvgl_sys::LV_VER_RES_MAX,
|
||||
|
@ -21,35 +21,35 @@ fn main() -> Result<(), String> {
|
|||
let output_settings = OutputSettingsBuilder::new().scale(2).build();
|
||||
let mut window = Window::new("Arc Example", &output_settings);
|
||||
|
||||
let mut ui = UI::init().unwrap();
|
||||
let mut ui = UI::init()?;
|
||||
|
||||
// Implement and register your display:
|
||||
let display_driver = DisplayDriver::new(&mut display);
|
||||
ui.disp_drv_register(display_driver);
|
||||
|
||||
// Create screen and widgets
|
||||
let mut screen = ui.scr_act();
|
||||
let mut screen = ui.scr_act()?;
|
||||
|
||||
let mut screen_style = Style::default();
|
||||
screen_style.set_bg_color(State::DEFAULT, Color::from_rgb((255, 255, 255)));
|
||||
screen_style.set_radius(State::DEFAULT, 0);
|
||||
screen.add_style(Part::Main, screen_style);
|
||||
screen.add_style(Part::Main, screen_style)?;
|
||||
|
||||
// Create the arc object
|
||||
let mut arc = Arc::new(&mut screen);
|
||||
arc.set_size(150, 150);
|
||||
arc.set_align(&mut screen, Align::Center, 0, 10);
|
||||
arc.set_start_angle(135, ArcPart::Indicator);
|
||||
arc.set_end_angle(135, ArcPart::Indicator);
|
||||
let mut arc = Arc::new(&mut screen)?;
|
||||
arc.set_size(150, 150)?;
|
||||
arc.set_align(&mut screen, Align::Center, 0, 10)?;
|
||||
arc.set_start_angle(135, ArcPart::Indicator)?;
|
||||
arc.set_end_angle(135, ArcPart::Indicator)?;
|
||||
|
||||
let mut loading_lbl = Label::new(&mut screen);
|
||||
loading_lbl.set_text("Loading...");
|
||||
loading_lbl.set_align(&mut arc, Align::OutTopMid, 0, -10);
|
||||
loading_lbl.set_label_align(LabelAlign::Center);
|
||||
let mut loading_lbl = Label::new(&mut screen)?;
|
||||
loading_lbl.set_text("Loading...")?;
|
||||
loading_lbl.set_align(&mut arc, Align::OutTopMid, 0, -10)?;
|
||||
loading_lbl.set_label_align(LabelAlign::Center)?;
|
||||
|
||||
let mut loading_style = Style::default();
|
||||
loading_style.set_text_color(State::DEFAULT, Color::from_rgb((0, 0, 0)));
|
||||
loading_lbl.add_style(Part::Main, loading_style);
|
||||
loading_lbl.add_style(Part::Main, loading_style)?;
|
||||
|
||||
let threaded_ui = StdArc::new(Mutex::new(ui));
|
||||
|
||||
|
@ -73,13 +73,9 @@ fn main() -> Result<(), String> {
|
|||
if i > 270 {
|
||||
forward = if forward { false } else { true };
|
||||
i = 1;
|
||||
threaded_ui
|
||||
.lock()
|
||||
.unwrap()
|
||||
.event_send(&mut loading_lbl, Event::Clicked)
|
||||
}
|
||||
angle = if forward { angle + 1 } else { angle - 1 };
|
||||
arc.set_end_angle(angle + 135, ArcPart::Indicator);
|
||||
arc.set_end_angle(angle + 135, ArcPart::Indicator)?;
|
||||
i += 1;
|
||||
|
||||
sleep(Duration::from_millis(10));
|
||||
|
|
|
@ -20,6 +20,7 @@ impl DisplayDriver {
|
|||
let mut display_buffer = MaybeUninit::<lvgl_sys::lv_disp_buf_t>::uninit();
|
||||
|
||||
// Declare a buffer for the refresh rate
|
||||
// TODO: Make this an external configuration
|
||||
const REFRESH_BUFFER_LEN: usize = 2;
|
||||
let refresh_buffer1 = Box::new(
|
||||
MaybeUninit::<
|
||||
|
@ -94,6 +95,7 @@ unsafe extern "C" fn display_callback_wrapper<T, C>(
|
|||
// have an standard unwinding mechanism to rely upon.
|
||||
let display_driver = *disp_drv;
|
||||
// Rust code closure reference
|
||||
if !display_driver.user_data.is_null() {
|
||||
let device = &mut *(display_driver.user_data as *mut T);
|
||||
let x1 = (*area).x1;
|
||||
let x2 = (*area).x2;
|
||||
|
@ -101,6 +103,7 @@ unsafe extern "C" fn display_callback_wrapper<T, C>(
|
|||
let y2 = (*area).y2;
|
||||
// TODO: Can we do anything when there is a error while flushing?
|
||||
let _ = display_flush(device, (x1, x2), (y1, y2), color_p);
|
||||
}
|
||||
// Indicate to LittlevGL that we are ready with the flushing
|
||||
lvgl_sys::lv_disp_flush_ready(disp_drv);
|
||||
}
|
||||
|
@ -136,6 +139,5 @@ where
|
|||
})
|
||||
.flatten();
|
||||
|
||||
// TODO: Maybe find a way to use `draw_image` method on the device instance.
|
||||
Ok(display.draw_iter(pixels)?)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{DisplayDriver, Event, Obj, Widget};
|
||||
use crate::{DisplayDriver, Event, LvError, LvResult, Obj, Widget};
|
||||
use alloc::boxed::Box;
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr;
|
||||
|
@ -9,12 +9,6 @@ use core::time::Duration;
|
|||
// There can only be a single reference to LittlevGL library.
|
||||
static LVGL_IN_USE: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
|
||||
pub enum LvError {
|
||||
Uninitialized,
|
||||
AlreadyInUse,
|
||||
}
|
||||
|
||||
pub struct UI {
|
||||
// LittlevGL is not thread-safe by default.
|
||||
_not_sync: PhantomData<*mut ()>,
|
||||
|
@ -24,7 +18,7 @@ pub struct UI {
|
|||
unsafe impl Send for UI {}
|
||||
|
||||
impl UI {
|
||||
pub fn init() -> Result<Self, LvError> {
|
||||
pub fn init() -> LvResult<Self> {
|
||||
if !LVGL_IN_USE.compare_and_swap(false, true, Ordering::SeqCst) {
|
||||
unsafe {
|
||||
lvgl_sys::lv_init();
|
||||
|
@ -47,20 +41,21 @@ impl UI {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn scr_act(&self) -> Obj {
|
||||
pub fn scr_act(&self) -> LvResult<Obj> {
|
||||
unsafe {
|
||||
let screen = lvgl_sys::lv_disp_get_scr_act(ptr::null_mut());
|
||||
Obj::from_raw(NonNull::new_unchecked(screen))
|
||||
Ok(Obj::from_raw(NonNull::new(screen)?))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event_send<T>(&mut self, obj: &mut T, event: Event<T::SpecialEvent>)
|
||||
pub fn event_send<T>(&mut self, obj: &mut T, event: Event<T::SpecialEvent>) -> LvResult<()>
|
||||
where
|
||||
T: Widget,
|
||||
{
|
||||
unsafe {
|
||||
lvgl_sys::lv_event_send(obj.raw().as_mut(), event.into(), ptr::null_mut());
|
||||
lvgl_sys::lv_event_send(obj.raw()?.as_mut(), event.into(), ptr::null_mut());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn tick_inc(&mut self, tick_period: Duration) {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(try_trait)]
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
@ -12,6 +13,6 @@ mod lv_core;
|
|||
pub mod widgets;
|
||||
|
||||
pub use display::DisplayDriver;
|
||||
pub use global::{LvError, UI};
|
||||
pub use global::UI;
|
||||
pub use lv_core::*;
|
||||
pub use support::*;
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
use crate::lv_core::style::Style;
|
||||
use crate::Align;
|
||||
use crate::{Align, LvError, LvResult};
|
||||
use alloc::boxed::Box;
|
||||
use core::ptr;
|
||||
|
||||
const PANIC_MESSAGE: &str = "Value was dropped by LittlevGL";
|
||||
|
||||
/// Represents a native LittlevGL object
|
||||
pub trait NativeObject {
|
||||
/// Provide common way to access to the underlying native object pointer.
|
||||
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t>;
|
||||
fn raw(&self) -> LvResult<ptr::NonNull<lvgl_sys::lv_obj_t>>;
|
||||
}
|
||||
|
||||
/// Generic LVGL object.
|
||||
|
@ -21,8 +19,12 @@ pub struct Obj {
|
|||
}
|
||||
|
||||
impl NativeObject for Obj {
|
||||
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t> {
|
||||
ptr::NonNull::new(self.raw).expect(PANIC_MESSAGE)
|
||||
fn raw(&self) -> LvResult<ptr::NonNull<lvgl_sys::lv_obj_t>> {
|
||||
if let Some(non_null_ptr) = ptr::NonNull::new(self.raw) {
|
||||
Ok(non_null_ptr)
|
||||
} else {
|
||||
Err(LvError::InvalidReference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,57 +40,63 @@ pub trait Widget: NativeObject {
|
|||
///
|
||||
unsafe fn from_raw(raw_pointer: ptr::NonNull<lvgl_sys::lv_obj_t>) -> Self;
|
||||
|
||||
fn add_style(&mut self, part: Self::Part, style: Style) {
|
||||
fn add_style(&mut self, part: Self::Part, style: Style) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_add_style(self.raw().as_mut(), part.into(), Box::into_raw(style.raw));
|
||||
lvgl_sys::lv_obj_add_style(self.raw()?.as_mut(), part.into(), Box::into_raw(style.raw));
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_pos(&mut self, x: i16, y: i16) {
|
||||
fn set_pos(&mut self, x: i16, y: i16) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_set_pos(
|
||||
self.raw().as_mut(),
|
||||
self.raw()?.as_mut(),
|
||||
x as lvgl_sys::lv_coord_t,
|
||||
y as lvgl_sys::lv_coord_t,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_size(&mut self, w: i16, h: i16) {
|
||||
fn set_size(&mut self, w: i16, h: i16) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_set_size(
|
||||
self.raw().as_mut(),
|
||||
self.raw()?.as_mut(),
|
||||
w as lvgl_sys::lv_coord_t,
|
||||
h as lvgl_sys::lv_coord_t,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_width(&mut self, w: u32) {
|
||||
fn set_width(&mut self, w: u32) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_set_width(self.raw().as_mut(), w as lvgl_sys::lv_coord_t);
|
||||
lvgl_sys::lv_obj_set_width(self.raw()?.as_mut(), w as lvgl_sys::lv_coord_t);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_height(&mut self, h: u32) {
|
||||
fn set_height(&mut self, h: u32) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_set_height(self.raw().as_mut(), h as lvgl_sys::lv_coord_t);
|
||||
lvgl_sys::lv_obj_set_height(self.raw()?.as_mut(), h as lvgl_sys::lv_coord_t);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_align<C>(&mut self, base: &mut C, align: Align, x_mod: i32, y_mod: i32)
|
||||
fn set_align<C>(&mut self, base: &mut C, align: Align, x_mod: i32, y_mod: i32) -> LvResult<()>
|
||||
where
|
||||
C: NativeObject,
|
||||
{
|
||||
unsafe {
|
||||
lvgl_sys::lv_obj_align(
|
||||
self.raw().as_mut(),
|
||||
base.raw().as_mut(),
|
||||
self.raw()?.as_mut(),
|
||||
base.raw()?.as_mut(),
|
||||
align.into(),
|
||||
x_mod as lvgl_sys::lv_coord_t,
|
||||
y_mod as lvgl_sys::lv_coord_t,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,25 +136,25 @@ macro_rules! define_object {
|
|||
}
|
||||
|
||||
impl $item {
|
||||
pub fn new<C>(parent: &mut C) -> Self
|
||||
pub fn new<C>(parent: &mut C) -> $crate::LvResult<Self>
|
||||
where
|
||||
C: $crate::NativeObject,
|
||||
{
|
||||
unsafe {
|
||||
let ptr = lvgl_sys::$create_fn(parent.raw().as_mut(), core::ptr::null_mut());
|
||||
let raw = core::ptr::NonNull::new_unchecked(ptr);
|
||||
let ptr = lvgl_sys::$create_fn(parent.raw()?.as_mut(), core::ptr::null_mut());
|
||||
let raw = core::ptr::NonNull::new(ptr)?;
|
||||
let core = <$crate::Obj as $crate::Widget>::from_raw(raw);
|
||||
Self { core }
|
||||
Ok(Self { core })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_event<F>(&mut self, f: F)
|
||||
pub fn on_event<F>(&mut self, f: F) -> $crate::LvResult<()>
|
||||
where
|
||||
F: FnMut(Self, $crate::support::Event<<Self as $crate::Widget>::SpecialEvent>),
|
||||
{
|
||||
use $crate::NativeObject;
|
||||
unsafe {
|
||||
let mut raw = self.raw();
|
||||
let mut raw = self.raw()?;
|
||||
let obj = raw.as_mut();
|
||||
let user_closure = alloc::boxed::Box::new(f);
|
||||
obj.user_data = alloc::boxed::Box::into_raw(user_closure) as *mut cty::c_void;
|
||||
|
@ -155,11 +163,12 @@ macro_rules! define_object {
|
|||
lvgl_sys::lv_event_cb_t::Some($crate::support::event_callback::<Self, F>),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::NativeObject for $item {
|
||||
fn raw(&self) -> core::ptr::NonNull<lvgl_sys::lv_obj_t> {
|
||||
fn raw(&self) -> $crate::LvResult<core::ptr::NonNull<lvgl_sys::lv_obj_t>> {
|
||||
self.core.raw()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Color, State};
|
||||
use crate::{Color, LvResult, State};
|
||||
use alloc::boxed::Box;
|
||||
use core::mem;
|
||||
use cstr_core::CString;
|
||||
|
@ -12,22 +12,9 @@ pub struct Style {
|
|||
}
|
||||
|
||||
impl Style {
|
||||
pub fn set_value_str(&mut self, state: State, value: &str) {
|
||||
pub fn set_value_str(&mut self, state: State, value: &str) -> LvResult<()> {
|
||||
let native_state: u32 = state.get_bits();
|
||||
let string = CString::new(value).unwrap();
|
||||
unsafe {
|
||||
lvgl_sys::_lv_style_set_ptr(
|
||||
self.raw.as_mut(),
|
||||
(lvgl_sys::LV_STYLE_VALUE_STR
|
||||
| (native_state << lvgl_sys::LV_STYLE_STATE_POS as u32)) as u16,
|
||||
string.into_raw() as *mut cty::c_void,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_font(&mut self, state: State, value: &str) {
|
||||
let native_state: u32 = state.get_bits();
|
||||
let string = CString::new(value).unwrap();
|
||||
let string = CString::new(value)?;
|
||||
unsafe {
|
||||
lvgl_sys::_lv_style_set_ptr(
|
||||
self.raw.as_mut(),
|
||||
|
@ -36,6 +23,7 @@ impl Style {
|
|||
string.into_raw() as *mut cty::c_void,
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,32 @@
|
|||
use crate::Widget;
|
||||
use bitflags::_core::option::NoneError;
|
||||
use core::convert::{TryFrom, TryInto};
|
||||
use core::ptr::NonNull;
|
||||
use cstr_core::NulError;
|
||||
use embedded_graphics::pixelcolor::{Rgb565, Rgb888};
|
||||
|
||||
pub type LvResult<T> = Result<T, LvError>;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
|
||||
pub enum LvError {
|
||||
InvalidReference,
|
||||
Uninitialized,
|
||||
InvalidNulByteString,
|
||||
AlreadyInUse,
|
||||
}
|
||||
|
||||
impl From<NoneError> for LvError {
|
||||
fn from(_: NoneError) -> Self {
|
||||
LvError::InvalidReference
|
||||
}
|
||||
}
|
||||
|
||||
impl From<NulError> for LvError {
|
||||
fn from(_: NulError) -> Self {
|
||||
LvError::InvalidNulByteString
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Color {
|
||||
pub(crate) raw: lvgl_sys::lv_color_t,
|
||||
|
|
|
@ -1,39 +1,42 @@
|
|||
use crate::NativeObject;
|
||||
use crate::{LvResult, NativeObject};
|
||||
|
||||
define_object!(Arc, lv_arc_create, part = ArcPart);
|
||||
|
||||
impl Arc {
|
||||
/// Set the start angle, for the given arc part.
|
||||
/// 0 degrees for the right, 90 degrees for the bottom, etc.
|
||||
pub fn set_start_angle(&mut self, angle: u16, part: ArcPart) {
|
||||
pub fn set_start_angle(&mut self, angle: u16, part: ArcPart) -> LvResult<()> {
|
||||
match part {
|
||||
ArcPart::Background => unsafe {
|
||||
lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw().as_mut(), angle)
|
||||
lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw()?.as_mut(), angle)
|
||||
},
|
||||
ArcPart::Indicator => unsafe {
|
||||
lvgl_sys::lv_arc_set_start_angle(self.core.raw().as_mut(), angle)
|
||||
lvgl_sys::lv_arc_set_start_angle(self.core.raw()?.as_mut(), angle)
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the end angle, for the given arc part.
|
||||
/// 0 degrees for the right, 90 degrees for the bottom, etc.
|
||||
pub fn set_end_angle(&mut self, angle: u16, part: ArcPart) {
|
||||
pub fn set_end_angle(&mut self, angle: u16, part: ArcPart) -> LvResult<()> {
|
||||
match part {
|
||||
ArcPart::Background => unsafe {
|
||||
lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw().as_mut(), angle)
|
||||
lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw()?.as_mut(), angle)
|
||||
},
|
||||
ArcPart::Indicator => unsafe {
|
||||
lvgl_sys::lv_arc_set_end_angle(self.core.raw().as_mut(), angle)
|
||||
lvgl_sys::lv_arc_set_end_angle(self.core.raw()?.as_mut(), angle)
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Rotate the arc, `angle` degrees clockwise.
|
||||
pub fn set_rotation(&mut self, angle: u16) {
|
||||
pub fn set_rotation(&mut self, angle: u16) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_arc_set_rotation(self.core.raw().as_mut(), angle);
|
||||
lvgl_sys::lv_arc_set_rotation(self.core.raw()?.as_mut(), angle);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
use crate::support::Animation;
|
||||
use crate::NativeObject;
|
||||
use crate::{LvResult, NativeObject};
|
||||
|
||||
define_object!(Bar, lv_bar_create, part = BarPart);
|
||||
|
||||
impl Bar {
|
||||
/// Set minimum and the maximum values of the bar
|
||||
pub fn set_range(&mut self, min: i16, max: i16) {
|
||||
pub fn set_range(&mut self, min: i16, max: i16) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_bar_set_range(self.core.raw().as_mut(), min, max);
|
||||
lvgl_sys::lv_bar_set_range(self.core.raw()?.as_mut(), min, max);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set a new value on the bar
|
||||
pub fn set_value(&mut self, value: i16, anim: Animation) {
|
||||
pub fn set_value(&mut self, value: i16, anim: Animation) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_bar_set_value(self.core.raw().as_mut(), value, anim.into());
|
||||
lvgl_sys::lv_bar_set_value(self.core.raw()?.as_mut(), value, anim.into());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
use crate::NativeObject;
|
||||
use crate::{LvResult, NativeObject};
|
||||
|
||||
define_object!(Gauge, lv_gauge_create, part = GaugePart);
|
||||
|
||||
impl Gauge {
|
||||
/// Set a new value on the gauge
|
||||
pub fn set_value(&mut self, needle_id: u8, value: i32) {
|
||||
pub fn set_value(&mut self, needle_id: u8, value: i32) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_gauge_set_value(self.core.raw().as_mut(), needle_id, value);
|
||||
lvgl_sys::lv_gauge_set_value(self.core.raw()?.as_mut(), needle_id, value);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
use crate::NativeObject;
|
||||
use crate::{LvResult, NativeObject};
|
||||
use cstr_core::CString;
|
||||
|
||||
define_object!(Label, lv_label_create);
|
||||
|
||||
impl Label {
|
||||
pub fn set_text(&mut self, text: &str) {
|
||||
pub fn set_text(&mut self, text: &str) -> LvResult<()> {
|
||||
let text = CString::new(text).unwrap();
|
||||
unsafe {
|
||||
lvgl_sys::lv_label_set_text(self.core.raw().as_mut(), text.as_ptr());
|
||||
lvgl_sys::lv_label_set_text(self.core.raw()?.as_mut(), text.as_ptr());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_label_align(&mut self, align: LabelAlign) {
|
||||
pub fn set_label_align(&mut self, align: LabelAlign) -> LvResult<()> {
|
||||
let align = match align {
|
||||
LabelAlign::Left => lvgl_sys::LV_LABEL_ALIGN_LEFT,
|
||||
LabelAlign::Center => lvgl_sys::LV_LABEL_ALIGN_CENTER,
|
||||
|
@ -19,14 +20,16 @@ impl Label {
|
|||
LabelAlign::Auto => lvgl_sys::LV_LABEL_ALIGN_AUTO,
|
||||
} as lvgl_sys::lv_label_align_t;
|
||||
unsafe {
|
||||
lvgl_sys::lv_label_set_align(self.core.raw().as_mut(), align);
|
||||
lvgl_sys::lv_label_set_align(self.core.raw()?.as_mut(), align);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_recolor(&mut self, recolor: bool) {
|
||||
pub fn set_recolor(&mut self, recolor: bool) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_label_set_recolor(self.core.raw().as_mut(), recolor);
|
||||
lvgl_sys::lv_label_set_recolor(self.core.raw()?.as_mut(), recolor);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue