diff --git a/examples/arc.rs b/examples/arc.rs index f250f18..37e6469 100644 --- a/examples/arc.rs +++ b/examples/arc.rs @@ -1,11 +1,12 @@ +use cstr_core::CString; use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::*; use embedded_graphics_simulator::{ OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window, }; use lvgl::style::Style; -use lvgl::widgets::{Arc, ArcPart, Label, LabelAlign}; -use lvgl::{self, Align, Color, DisplayDriver, Part, State, UI}; +use lvgl::widgets::{Arc, Label, LabelAlign}; +use lvgl::{self, Align, Color, Part, State, UI}; use lvgl::{LvError, Widget}; use lvgl_sys; use std::sync::{mpsc, Arc as StdArc, Mutex}; @@ -13,7 +14,7 @@ use std::thread::sleep; use std::time::Duration; fn main() -> Result<(), LvError> { - let mut display: SimulatorDisplay = SimulatorDisplay::new(Size::new( + let display: SimulatorDisplay = SimulatorDisplay::new(Size::new( lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_VER_RES_MAX, )); @@ -24,8 +25,7 @@ fn main() -> Result<(), LvError> { let mut ui = UI::init()?; // Implement and register your display: - let display_driver = DisplayDriver::new(&mut display); - ui.disp_drv_register(display_driver); + ui.disp_drv_register(display)?; // Create screen and widgets let mut screen = ui.scr_act()?; @@ -43,7 +43,7 @@ fn main() -> Result<(), LvError> { arc.set_end_angle(135)?; let mut loading_lbl = Label::new(&mut screen)?; - loading_lbl.set_text("Loading...")?; + loading_lbl.set_text(CString::new("Loading...").unwrap().as_c_str())?; loading_lbl.set_align(&mut arc, Align::OutTopMid, 0, -10)?; loading_lbl.set_label_align(LabelAlign::Center)?; @@ -78,11 +78,13 @@ fn main() -> Result<(), LvError> { arc.set_end_angle(angle + 135)?; i += 1; - sleep(Duration::from_millis(10)); + sleep(Duration::from_millis(50)); - threaded_ui.lock().unwrap().task_handler(); - - window.update(&display); + let mut ui = threaded_ui.lock().unwrap(); + ui.task_handler(); + if let Some(disp) = ui.get_display_ref() { + window.update(disp); + } for event in window.events() { match event { diff --git a/examples/gauge.rs b/examples/gauge.rs index 3902298..ccb50ef 100644 --- a/examples/gauge.rs +++ b/examples/gauge.rs @@ -4,15 +4,15 @@ use embedded_graphics_simulator::{ OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window, }; use lvgl::style::{Opacity, Style}; -use lvgl::widgets::{Gauge, GaugePart}; -use lvgl::{self, Align, Color, DisplayDriver, LvError, Part, State, Widget, UI}; +use lvgl::widgets::Gauge; +use lvgl::{self, Align, Color, LvError, Part, State, Widget, UI}; use lvgl_sys; use std::sync::{mpsc, Arc, Mutex}; use std::thread::sleep; use std::time::Duration; fn main() -> Result<(), LvError> { - let mut display: SimulatorDisplay = SimulatorDisplay::new(Size::new( + let display: SimulatorDisplay = SimulatorDisplay::new(Size::new( lvgl_sys::LV_HOR_RES_MAX, lvgl_sys::LV_VER_RES_MAX, )); @@ -23,8 +23,7 @@ fn main() -> Result<(), LvError> { let mut ui = UI::init()?; // Implement and register your display: - let display_driver = DisplayDriver::new(&mut display); - ui.disp_drv_register(display_driver); + ui.disp_drv_register(display)?; // Create screen and widgets let mut screen = ui.scr_act()?; @@ -75,9 +74,12 @@ fn main() -> Result<(), LvError> { let mut i = 0; 'running: loop { - threaded_ui.lock().unwrap().task_handler(); + let mut ui = threaded_ui.lock().unwrap(); + ui.task_handler(); + if let Some(disp) = ui.get_display_ref() { + window.update(disp); + } - window.update(&display); for event in window.events() { match event { SimulatorEvent::MouseButtonUp { diff --git a/lvgl/src/ui.rs b/lvgl/src/ui.rs index f05d049..cb89bf1 100644 --- a/lvgl/src/ui.rs +++ b/lvgl/src/ui.rs @@ -1,6 +1,6 @@ +use crate::mem::Box; use crate::{Color, Event, LvError, LvResult, Obj, Widget}; use core::marker::PhantomData; -use core::mem; use core::mem::{ManuallyDrop, MaybeUninit}; use core::ptr; use core::ptr::NonNull; @@ -18,8 +18,6 @@ const REFRESH_BUFFER_LEN: usize = 2; // Declare a buffer for the refresh rate const BUF_SIZE: usize = lvgl_sys::LV_HOR_RES_MAX as usize * REFRESH_BUFFER_LEN; -type RefreshBuffer = [lvgl_sys::lv_color_t; BUF_SIZE]; - pub struct UI where T: DrawTarget, @@ -66,30 +64,19 @@ where unsafe { // Create a display buffer for LittlevGL - // Never initialized in Rust side (don't call `assume_init`, this is C managed memory)! - let disp_buf = lvgl_sys::lv_mem_alloc( - mem::size_of::() as lvgl_sys::size_t - ) as *mut lvgl_sys::lv_disp_buf_t; // Initialize the display buffer - let buffer_size = mem::size_of::(); - let buf1 = lvgl_sys::lv_mem_alloc(buffer_size as lvgl_sys::size_t); - if buf1.is_null() { - lvgl_sys::lv_mem_free(disp_buf as *mut cty::c_void); - return Err(LvError::LvOOMemory); - } - let buf2 = lvgl_sys::lv_mem_alloc(buffer_size as lvgl_sys::size_t); - if buf2.is_null() { - lvgl_sys::lv_mem_free(disp_buf as *mut cty::c_void); - lvgl_sys::lv_mem_free(buf1); - return Err(LvError::LvOOMemory); - } + let refresh_buffer1 = [Color::from_rgb((0, 0, 0)).raw; BUF_SIZE]; + let refresh_buffer2 = [Color::from_rgb((0, 0, 0)).raw; BUF_SIZE]; + + let mut disp_buf = MaybeUninit::::uninit(); lvgl_sys::lv_disp_buf_init( - disp_buf, - buf1, - buf2, + disp_buf.as_mut_ptr(), + Box::into_raw(Box::new(refresh_buffer1)?) as *mut cty::c_void, + Box::into_raw(Box::new(refresh_buffer2)?) as *mut cty::c_void, lvgl_sys::LV_HOR_RES_MAX * REFRESH_BUFFER_LEN as u32, ); + let disp_buf = Box::new(disp_buf.assume_init())?; // Basic initialization of the display driver let mut disp_drv = MaybeUninit::::uninit(); @@ -97,7 +84,7 @@ where // Since this is C managed memory, we don't want to drop it using Rust, thus `ManuallyDrop` wrapping. let mut disp_drv = ManuallyDrop::new(disp_drv.assume_init()); // Assign the buffer to the display - disp_drv.buffer = disp_buf; + disp_drv.buffer = Box::into_raw(disp_buf); // Set your driver function disp_drv.flush_cb = Some(display_callback_wrapper::); // TODO: DrawHandler type here