Generate all widgets

This commit is contained in:
Rafael Caricio 2020-06-12 18:20:02 +02:00 committed by Rafael Carício
parent d970deaa9d
commit de9b6512a7
7 changed files with 73 additions and 58 deletions

View file

@ -4,7 +4,7 @@ use embedded_graphics_simulator::{
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
};
use lvgl::style::Style;
use lvgl::widgets::{Btn, Label};
use lvgl::widgets::{Btn, Label, Msgbox, Spinbox};
use lvgl::{self, Align, Color, DisplayDriver, Event, LvError, Part, State, Widget, UI};
use lvgl_sys;
use std::sync::{mpsc, Arc, Mutex};

View file

@ -1,7 +1,7 @@
use clang::{Clang, Entity, EntityKind, Index, Type};
use clang::{Availability, Clang, Entity, EntityKind, Index, Linkage, Type};
use inflector::cases::pascalcase::to_pascal_case;
use lazy_static::lazy_static;
use proc_macro2::TokenStream;
use proc_macro2::{Ident, TokenStream};
use quote::format_ident;
use quote::quote;
use regex::Regex;
@ -47,14 +47,13 @@ impl Rusty for LvWidget {
type Parent = ();
fn code(&self, _parent: &Self::Parent) -> WrapperResult<TokenStream> {
// We don't generate for the generic Obj
if self.name.eq("obj") {
return Err(WrapperError::Skip);
}
let widget_name = format_ident!("{}", to_pascal_case(self.name.as_str()));
let methods: Vec<TokenStream> = self
.methods
.iter()
.take(1)
.into_iter()
.flat_map(|m| m.code(self))
.collect();
let methods: Vec<TokenStream> = self.methods.iter().flat_map(|m| m.code(self)).collect();
Ok(quote! {
define_object!(#widget_name);
@ -76,6 +75,14 @@ impl LvFunc {
pub fn new(name: String, args: Vec<LvArg>, ret: Option<LvType>) -> Self {
Self { name, args, ret }
}
pub fn is_method(&self) -> bool {
if self.args.len() > 0 {
let first_arg = &self.args[0];
return first_arg.typ.typ.contains("lv_obj_t");
}
false
}
}
impl Rusty for LvFunc {
@ -108,6 +115,10 @@ impl Rusty for LvFunc {
for arg in self.args.iter().skip(1) {
arg.code(self)?;
}
// We don't deal with methods that return types yet
if self.ret.is_some() {
return Err(WrapperError::Skip);
}
let args_decl = self
.args
@ -144,7 +155,7 @@ impl Rusty for LvFunc {
let next_arg = if i == 0 {
quote!(self.core.raw()?.as_mut())
} else {
let var = format_ident!("{}", arg.name.as_str());
let var = arg.get_name_ident();
quote!(#var)
};
if args.is_empty() {
@ -160,7 +171,7 @@ impl Rusty for LvFunc {
// TODO: Handle methods that return types
Ok(quote! {
pub fn #func_name(#args_decl) -> LvResult<()> {
pub fn #func_name(#args_decl) -> crate::LvResult<()> {
unsafe {
lvgl_sys::#original_func_name(#args_call);
}
@ -201,6 +212,10 @@ impl LvArg {
Self { name, typ }
}
pub fn get_name_ident(&self) -> Ident {
format_ident!("r#{}", self.name)
}
pub fn get_type(&self) -> &LvType {
&self.typ
}
@ -210,7 +225,7 @@ impl Rusty for LvArg {
type Parent = LvFunc;
fn code(&self, _parent: &Self::Parent) -> WrapperResult<TokenStream> {
let name = format_ident!("{}", self.name.as_str());
let name = self.get_name_ident();
let typ = self.typ.code(self)?;
Ok(quote! {
#name: #typ
@ -287,6 +302,7 @@ impl CodeGen {
for widget_name in &widget_names {
if f.name
.starts_with(format!("{}{}", LIB_PREFIX, widget_name).as_str())
&& f.is_method()
{
ws.entry(widget_name.clone())
.or_insert_with(|| LvWidget {
@ -335,6 +351,7 @@ impl CodeGen {
.into_iter()
.filter(|e| e.get_kind() == EntityKind::FunctionDecl)
.filter(|e| e.get_name().is_some())
.filter(|e| e.get_linkage().unwrap() != Linkage::Internal)
.map(|e| e.into())
.filter(|e: &LvFunc| e.name.starts_with(LIB_PREFIX))
.collect::<Vec<_>>();

View file

@ -1,15 +1,17 @@
use std::ffi::OsStr;
use std::path::{Path, PathBuf};
use std::env;
use std::path::Path;
use std::process::Command;
use std::{env, fs, path};
fn main() {
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
let widgets_rs_path = manifest_dir.join("src/widgets/generated.rs");
let codegen_bin = manifest_dir.join("../target/debug/lvgl-codegen");
if !widgets_rs_path.exists() {
println!("rerun-if-changed={}", codegen_bin.to_string_lossy());
if env::var("LVGL_FORCE_CODEGEN").is_ok() || !widgets_rs_path.exists() {
println!("Generating `src/widgets/generated.rs`");
let status = Command::new(manifest_dir.join("../target/debug/lvgl-codegen"))
let status = Command::new(codegen_bin)
.spawn()
.unwrap_or_else(|_| {
panic!(

View file

@ -1,7 +1,6 @@
use crate::Color;
use alloc::boxed::Box;
use core::mem::MaybeUninit;
use core::ptr;
use embedded_graphics::prelude::*;
use embedded_graphics::{drawable, DrawTarget};

View file

@ -1,42 +1,41 @@
use crate::widgets::Arc;
use crate::{LvResult, NativeObject};
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) -> LvResult<()> {
match part {
ArcPart::Background => unsafe {
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)
},
}
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(&self, angle: u16, part: ArcPart) -> LvResult<()> {
match part {
ArcPart::Background => unsafe {
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)
},
}
Ok(())
}
/// Rotate the arc, `angle` degrees clockwise.
pub fn set_rotation(&mut self, angle: u16) -> LvResult<()> {
unsafe {
lvgl_sys::lv_arc_set_rotation(self.core.raw()?.as_mut(), angle);
}
Ok(())
}
// /// 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) -> LvResult<()> {
// match part {
// ArcPart::Background => unsafe {
// 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)
// },
// }
// 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(&self, angle: u16, part: ArcPart) -> LvResult<()> {
// match part {
// ArcPart::Background => unsafe {
// 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)
// },
// }
// Ok(())
// }
//
// /// Rotate the arc, `angle` degrees clockwise.
// pub fn set_rotation(&mut self, angle: u16) -> LvResult<()> {
// unsafe {
// lvgl_sys::lv_arc_set_rotation(self.core.raw()?.as_mut(), angle);
// }
// Ok(())
// }
}
/// The different parts, of an arc object.

View file

@ -1,5 +1,3 @@
use crate::{LvResult, NativeObject};
pub enum GaugePart {
Main,
Major,

View file

@ -5,7 +5,7 @@ mod label;
include!("generated.rs");
use crate::Widget;
use crate::{NativeObject, Widget};
pub use arc::*;
pub use bar::*;
pub use gauge::*;