Bar widget (#12)
* Implement simple bar widget * Make it easier to create new examples * Add bar example * Add README to examples * Remove unnecessary imports
This commit is contained in:
parent
81d924e854
commit
2fae95bdfb
15 changed files with 169 additions and 25 deletions
|
@ -2,5 +2,5 @@
|
|||
members = [
|
||||
"lvgl",
|
||||
"lvgl-sys",
|
||||
"examples/demo",
|
||||
"examples"
|
||||
]
|
||||
|
|
|
@ -54,4 +54,10 @@ That is required, so we can safely provide Rust pointers through FFI. For that r
|
|||
|
||||
## Running the demo
|
||||
|
||||
[This project contains an example that can run in a desktop simulator.](./examples/demo)
|
||||
[This project contains examples that can run in a desktop simulator.](./examples)
|
||||
|
||||
To run the `demo` example:
|
||||
|
||||
```shell
|
||||
$ DEP_LV_CONFIG_PATH=`pwd`/examples/include cargo run --example demo
|
||||
```
|
||||
|
|
20
examples/Cargo.toml
Normal file
20
examples/Cargo.toml
Normal file
|
@ -0,0 +1,20 @@
|
|||
[package]
|
||||
name = "demo"
|
||||
version = "0.1.0"
|
||||
authors = ["Rafael Caricio <crates@caric.io>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dev-dependencies]
|
||||
lvgl = { path = "../lvgl" }
|
||||
lvgl-sys = { path = "../lvgl-sys" }
|
||||
embedded-graphics = "0.6"
|
||||
embedded-graphics-simulator = "0.2.0"
|
||||
|
||||
[[example]]
|
||||
name = "demo"
|
||||
path = "demo.rs"
|
||||
|
||||
[[example]]
|
||||
name = "bar"
|
||||
path = "bar.rs"
|
8
examples/README.md
Normal file
8
examples/README.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
## Examples of how to use various `lvgl-rs` widgets/components
|
||||
|
||||
All examples can be executed using:
|
||||
```shell
|
||||
cargo run --example <name>
|
||||
```
|
||||
|
||||
The `DEP_LV_CONFIG_PATH` environment variable is necessary, as explained in the [README](../README.md).
|
82
examples/bar.rs
Normal file
82
examples/bar.rs
Normal file
|
@ -0,0 +1,82 @@
|
|||
use embedded_graphics::pixelcolor::Rgb565;
|
||||
use embedded_graphics::prelude::*;
|
||||
use embedded_graphics_simulator::{
|
||||
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
|
||||
};
|
||||
use lvgl::{self, widgets::Bar, Align, Color, DisplayDriver, Object, Style, UI};
|
||||
use lvgl_sys;
|
||||
use std::sync::{mpsc, Arc, Mutex};
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let mut display: SimulatorDisplay<Rgb565> = SimulatorDisplay::new(Size::new(
|
||||
lvgl_sys::LV_HOR_RES_MAX,
|
||||
lvgl_sys::LV_VER_RES_MAX,
|
||||
));
|
||||
|
||||
let output_settings = OutputSettingsBuilder::new().scale(2).build();
|
||||
let mut window = Window::new("Bar Example", &output_settings);
|
||||
|
||||
let mut ui = UI::init().unwrap();
|
||||
|
||||
// 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_style = Style::new();
|
||||
screen_style.set_body_main_color(Color::from_rgb((0, 0, 0)));
|
||||
screen_style.set_body_grad_color(Color::from_rgb((0, 0, 0)));
|
||||
screen.set_style(screen_style);
|
||||
|
||||
// Create the bar object
|
||||
let mut bar = Bar::new(&mut screen);
|
||||
bar.set_size(50, 175);
|
||||
bar.set_align(&mut screen, Align::Center, 0, 0);
|
||||
bar.set_range(0, 100);
|
||||
bar.set_value(0);
|
||||
|
||||
let threaded_ui = Arc::new(Mutex::new(ui));
|
||||
|
||||
let (stop_ch, read_ch) = mpsc::channel();
|
||||
let closure_ui = threaded_ui.clone();
|
||||
let tick_thr = std::thread::spawn(move || loop {
|
||||
let period = Duration::from_millis(5);
|
||||
closure_ui.lock().unwrap().tick_inc(period);
|
||||
|
||||
sleep(period);
|
||||
if read_ch.try_recv().is_ok() {
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
let mut i = 0;
|
||||
'running: loop {
|
||||
if i > 100 {
|
||||
i = 0;
|
||||
}
|
||||
bar.set_value(i);
|
||||
i += 1;
|
||||
|
||||
sleep(Duration::from_millis(25));
|
||||
|
||||
threaded_ui.lock().unwrap().task_handler();
|
||||
|
||||
window.update(&display);
|
||||
|
||||
for event in window.events() {
|
||||
match event {
|
||||
SimulatorEvent::Quit => break 'running,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stop_ch.send(true).unwrap();
|
||||
tick_thr.join().unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
From base of the repository, install LVGL git submodule.
|
||||
|
||||
```
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
Run this demo:
|
||||
|
||||
```
|
||||
cd examples/demo/
|
||||
DEP_LV_CONFIG_PATH=./include cargo run
|
||||
```
|
|
@ -2,11 +2,12 @@
|
|||
|
||||
extern crate alloc;
|
||||
|
||||
mod global;
|
||||
mod display;
|
||||
mod global;
|
||||
#[macro_use]
|
||||
mod support;
|
||||
mod widgets;
|
||||
pub mod widgets;
|
||||
|
||||
pub use global::{UI, LvError};
|
||||
pub use display::DisplayDriver;
|
||||
pub use global::{LvError, UI};
|
||||
pub use support::*;
|
||||
|
|
|
@ -111,20 +111,23 @@ impl Object for ObjectX {
|
|||
macro_rules! define_object {
|
||||
($item:ident) => {
|
||||
pub struct $item {
|
||||
core: ObjectX,
|
||||
core: $crate::support::ObjectX,
|
||||
}
|
||||
|
||||
impl NativeObject for $item {
|
||||
fn raw(&self) -> ptr::NonNull<lvgl_sys::lv_obj_t> {
|
||||
impl $crate::support::NativeObject for $item {
|
||||
fn raw(&self) -> core::ptr::NonNull<lvgl_sys::lv_obj_t> {
|
||||
self.core.raw()
|
||||
}
|
||||
}
|
||||
|
||||
impl Object for $item {
|
||||
fn set_style(&mut self, style: Style) {
|
||||
impl $crate::support::Object for $item {
|
||||
fn set_style(&mut self, style: $crate::support::Style) {
|
||||
unsafe {
|
||||
let boxed = Box::new(style.raw);
|
||||
lvgl_sys::lv_obj_set_style(self.raw().as_mut(), Box::into_raw(boxed));
|
||||
let boxed = alloc::boxed::Box::new(style.raw);
|
||||
lvgl_sys::lv_obj_set_style(
|
||||
self.raw().as_mut(),
|
||||
alloc::boxed::Box::into_raw(boxed),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +203,7 @@ pub enum Themes {
|
|||
}
|
||||
|
||||
pub struct Style {
|
||||
raw: lvgl_sys::lv_style_t,
|
||||
pub(crate) raw: lvgl_sys::lv_style_t,
|
||||
}
|
||||
|
||||
impl Style {
|
||||
|
|
33
lvgl/src/widgets/bar.rs
Normal file
33
lvgl/src/widgets/bar.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
use crate::support::{NativeObject, ObjectX};
|
||||
use core::ptr;
|
||||
use lvgl_sys;
|
||||
|
||||
define_object!(Bar);
|
||||
|
||||
impl Bar {
|
||||
pub fn new<C>(parent: &mut C) -> Self
|
||||
where
|
||||
C: NativeObject,
|
||||
{
|
||||
let raw = unsafe {
|
||||
let ptr = lvgl_sys::lv_bar_create(parent.raw().as_mut(), ptr::null_mut());
|
||||
ptr::NonNull::new_unchecked(ptr)
|
||||
};
|
||||
let core = ObjectX::from_raw(raw);
|
||||
Self { core }
|
||||
}
|
||||
|
||||
/// Set minimum and the maximum values of the bar
|
||||
pub fn set_range(&mut self, min: i16, max: i16) {
|
||||
unsafe {
|
||||
lvgl_sys::lv_bar_set_range(self.core.raw().as_mut(), min, max);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the value of the bar
|
||||
pub fn set_value(&mut self, value: i16) {
|
||||
unsafe {
|
||||
lvgl_sys::lv_bar_set_value(self.core.raw().as_mut(), value, 0);
|
||||
}
|
||||
}
|
||||
}
|
3
lvgl/src/widgets/mod.rs
Normal file
3
lvgl/src/widgets/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod bar;
|
||||
|
||||
pub use self::bar::Bar;
|
Loading…
Reference in a new issue