Generate code for most of the widgets #20
12 changed files with 94 additions and 70 deletions
|
@ -17,6 +17,7 @@ name = "lvgl_codegen"
|
|||
regex = "1.3.9"
|
||||
quote = "1.0.7"
|
||||
If a specific commit of the
If a specific commit of the `clang-rs` repo is needed, it's possible to do something like:
```text
clang = { git = "https://github.com/KyleMayes/clang-rs.git", rev = "<commit hash>" }
```
I needed to actually write some tweaks to the code. 😕 Maybe a PR to upstream would be the way to go here. I needed to actually write some tweaks to the code. 😕 Maybe a PR to upstream would be the way to go here.
|
||||
lazy_static = "1.4.0"
|
||||
clang = { path = "../../clang-rs" }
|
||||
itertools = "0.9.0"
|
||||
proc-macro2 = "1.0.18"
|
||||
Remove this, not used. Remove this, not used.
For context, I tried to use this library. But it cannot parse C99 standard. So I went back to For context, I tried to use this library. But it cannot parse C99 standard. So I went back to `clang-rs`. If we can find a good C99 parser we could simplify a lot all this code generation work.
|
||||
Inflector = "0.11.4"
|
||||
|
|
|
@ -48,7 +48,13 @@ impl Rusty for LvWidget {
|
|||
|
||||
fn code(&self, _parent: &Self::Parent) -> WrapperResult<TokenStream> {
|
||||
let widget_name = format_ident!("{}", to_pascal_case(self.name.as_str()));
|
||||
let methods: Vec<TokenStream> = self.methods.iter().flat_map(|m| m.code(self)).collect();
|
||||
let methods: Vec<TokenStream> = self
|
||||
.methods
|
||||
.iter()
|
||||
.take(1)
|
||||
.into_iter()
|
||||
.flat_map(|m| m.code(self))
|
||||
.collect();
|
||||
Ok(quote! {
|
||||
define_object!(#widget_name);
|
||||
|
||||
|
|
|
@ -21,4 +21,4 @@ cty = "0.2.1"
|
|||
|
||||
[build-dependencies]
|
||||
cc = "1.0.50"
|
||||
bindgen = "0.53.2"
|
||||
bindgen = "0.54.0"
|
||||
|
|
|
@ -16,3 +16,8 @@ cty = "0.2.1"
|
|||
embedded-graphics = "0.6.2"
|
||||
cstr_core = { version = "0.2.0", default-features = false, features = ["alloc"] }
|
||||
bitflags = "1.2.1"
|
||||
|
||||
[build-dependencies]
|
||||
lvgl-codegen = { path = "../lvgl-codegen" }
|
||||
quote = "1.0.7"
|
||||
proc-macro2 = "1.0.18"
|
||||
|
|
48
lvgl/build.rs
Normal file
48
lvgl/build.rs
Normal file
|
@ -0,0 +1,48 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::{env, fs, path};
|
||||
|
||||
fn main() {
|
||||
let project_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
|
||||
.canonicalize()
|
||||
.unwrap();
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let gen_code = out_path.join("bindings.rs");
|
||||
|
||||
let code = invoke_command("../target/debug/lvgl-codegen", &[""], &project_dir);
|
||||
fs::write(&gen_code, code).unwrap();
|
||||
|
||||
// // Format generated code
|
||||
// let _ = invoke_command(
|
||||
// "cargo",
|
||||
// &["fmt", "-p", gen_code.to_str().unwrap()],
|
||||
// &project_dir,
|
||||
// );
|
||||
}
|
||||
|
||||
fn invoke_command<C, I, S, D>(command: C, args: I, cur_dir: D) -> String
|
||||
where
|
||||
C: AsRef<OsStr>,
|
||||
I: IntoIterator<Item = S>,
|
||||
S: AsRef<OsStr>,
|
||||
D: AsRef<path::Path>,
|
||||
{
|
||||
Command::new(command)
|
||||
.current_dir(cur_dir)
|
||||
.args(args)
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|output| {
|
||||
if output.status.success() {
|
||||
Some(String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
} else {
|
||||
panic!(
|
||||
"{}",
|
||||
String::from_utf8_lossy(&output.stderr).trim().to_string()
|
||||
);
|
||||
}
|
||||
})
|
||||
.unwrap()
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#![feature(try_trait)]
|
||||
#![no_std]
|
||||
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
#[macro_use]
|
||||
extern crate bitflags;
|
||||
|
|
|
@ -118,36 +118,26 @@ impl Default for Obj {
|
|||
}
|
||||
|
||||
macro_rules! define_object {
|
||||
($item:ident, $create_fn:ident) => {
|
||||
define_object!($item, $create_fn, event = (), part = $crate::Part);
|
||||
($item:ident) => {
|
||||
define_object!($item, event = (), part = $crate::Part);
|
||||
};
|
||||
($item:ident, $create_fn:ident, event = $event_type:ty) => {
|
||||
define_object!($item, $create_fn, event = $event_type, part = $crate::Part);
|
||||
($item:ident, event = $event_type:ty) => {
|
||||
define_object!($item, event = $event_type, part = $crate::Part);
|
||||
};
|
||||
($item:ident, $create_fn:ident, part = $part_type:ty) => {
|
||||
define_object!($item, $create_fn, event = (), part = $part_type);
|
||||
($item:ident, part = $part_type:ty) => {
|
||||
define_object!($item, event = (), part = $part_type);
|
||||
};
|
||||
($item:ident, $create_fn:ident, part = $part_type:ty, event = $event_type:ty) => {
|
||||
define_object!($item, $create_fn, event = $event_type, part = $part_type);
|
||||
($item:ident, part = $part_type:ty, event = $event_type:ty) => {
|
||||
define_object!($item, event = $event_type, part = $part_type);
|
||||
};
|
||||
($item:ident, $create_fn:ident, event = $event_type:ty, part = $part_type:ty) => {
|
||||
($item:ident, event = $event_type:ty, part = $part_type:ty) => {
|
||||
pub struct $item {
|
||||
core: $crate::Obj,
|
||||
}
|
||||
|
||||
impl $item {
|
||||
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(ptr)?;
|
||||
let core = <$crate::Obj as $crate::Widget>::from_raw(raw);
|
||||
Ok(Self { core })
|
||||
}
|
||||
}
|
||||
unsafe impl Send for $item {}
|
||||
|
||||
impl $item {
|
||||
pub fn on_event<F>(&mut self, f: F) -> $crate::LvResult<()>
|
||||
where
|
||||
F: FnMut(Self, $crate::support::Event<<Self as $crate::Widget>::SpecialEvent>),
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::widgets::Arc;
|
||||
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.
|
||||
|
@ -19,10 +18,10 @@ impl Arc {
|
|||
|
||||
/// 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) -> LvResult<()> {
|
||||
pub fn set_end_angle(&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_end_angle(self.core.raw()?.as_mut(), angle)
|
||||
},
|
||||
ArcPart::Indicator => unsafe {
|
||||
lvgl_sys::lv_arc_set_end_angle(self.core.raw()?.as_mut(), angle)
|
||||
|
@ -41,19 +40,18 @@ impl Arc {
|
|||
}
|
||||
|
||||
/// The different parts, of an arc object.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum ArcPart {
|
||||
/// The background of the arc.
|
||||
Background,
|
||||
Background = lvgl_sys::LV_ARC_PART_BG as u8,
|
||||
/// The indicator of the arc.
|
||||
/// This is what moves/changes, depending on the arc's value.
|
||||
Indicator,
|
||||
Indicator = lvgl_sys::LV_ARC_PART_INDIC as u8,
|
||||
}
|
||||
|
||||
impl From<ArcPart> for u8 {
|
||||
fn from(component: ArcPart) -> Self {
|
||||
match component {
|
||||
ArcPart::Background => lvgl_sys::LV_ARC_PART_BG as u8,
|
||||
ArcPart::Indicator => lvgl_sys::LV_ARC_PART_INDIC as u8,
|
||||
}
|
||||
fn from(part: ArcPart) -> Self {
|
||||
part as u8
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::support::Animation;
|
||||
use crate::widgets::Bar;
|
||||
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) -> LvResult<()> {
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
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) -> LvResult<()> {
|
||||
unsafe {
|
||||
lvgl_sys::lv_gauge_set_value(self.core.raw()?.as_mut(), needle_id, value);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub enum GaugePart {
|
||||
Main,
|
||||
Major,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::widgets::Label;
|
||||
use crate::{LvResult, NativeObject};
|
||||
use cstr_core::CString;
|
||||
|
||||
define_object!(Label, lv_label_create);
|
||||
|
||||
impl Label {
|
||||
pub fn set_text(&mut self, text: &str) -> LvResult<()> {
|
||||
let text = CString::new(text).unwrap();
|
||||
|
@ -13,29 +12,18 @@ impl Label {
|
|||
}
|
||||
|
||||
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,
|
||||
LabelAlign::Right => lvgl_sys::LV_LABEL_ALIGN_RIGHT,
|
||||
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);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
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_align(self.core.raw()?.as_mut(), align as u8);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum LabelAlign {
|
||||
Left,
|
||||
Center,
|
||||
Right,
|
||||
Auto,
|
||||
Left = lvgl_sys::LV_LABEL_ALIGN_LEFT as u8,
|
||||
Center = lvgl_sys::LV_LABEL_ALIGN_CENTER as u8,
|
||||
Right = lvgl_sys::LV_LABEL_ALIGN_RIGHT as u8,
|
||||
Auto = lvgl_sys::LV_LABEL_ALIGN_AUTO as u8,
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
mod arc;
|
||||
mod bar;
|
||||
mod btn;
|
||||
mod gauge;
|
||||
mod label;
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
pub use arc::*;
|
||||
pub use bar::*;
|
||||
pub use btn::*;
|
||||
pub use gauge::*;
|
||||
pub use label::*;
|
||||
|
|
Loading…
Reference in a new issue
Ok, I need to commit this to my own repo. The original
clang-rs
is not up to date withclang-sys
that is used byrust-bindgen
.