Generate code for most of the widgets #20

Merged
rafaelcaricio merged 11 commits from generate-code into master 2020-06-13 18:31:25 +00:00
12 changed files with 94 additions and 70 deletions
Showing only changes of commit 9b68e734eb - Show all commits

View file

@ -17,6 +17,7 @@ name = "lvgl_codegen"
regex = "1.3.9"
quote = "1.0.7"
rafaelcaricio commented 2020-06-12 18:47:44 +00:00 (Migrated from github.com)
Review

Ok, I need to commit this to my own repo. The original clang-rs is not up to date with clang-sys that is used by rust-bindgen.

Ok, I need to commit this to my own repo. The original `clang-rs` is not up to date with `clang-sys` that is used by `rust-bindgen`.
jakubclark commented 2020-06-12 22:46:33 +00:00 (Migrated from github.com)
Review

If a specific commit of the clang-rs repo is needed, it's possible to do something like:

clang = { git = "https://github.com/KyleMayes/clang-rs.git", rev = "<commit hash>" }
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>" } ```
rafaelcaricio commented 2020-06-13 06:03:46 +00:00 (Migrated from github.com)
Review

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"
rafaelcaricio commented 2020-06-12 18:48:08 +00:00 (Migrated from github.com)
Review

Remove this, not used.

Remove this, not used.
rafaelcaricio commented 2020-06-12 18:49:11 +00:00 (Migrated from github.com)
Review

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.

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"

View file

@ -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);

View file

@ -21,4 +21,4 @@ cty = "0.2.1"
[build-dependencies]
cc = "1.0.50"
bindgen = "0.53.2"
bindgen = "0.54.0"

View file

@ -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
View 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()
}

View file

@ -1,6 +1,7 @@
#![feature(try_trait)]
#![no_std]
#[macro_use]
extern crate alloc;
#[macro_use]
extern crate bitflags;

View file

@ -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>),

View file

@ -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
}
}

View file

@ -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<()> {

View file

@ -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,

View file

@ -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,
}

View file

@ -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::*;