Generate all widgets
This commit is contained in:
parent
d970deaa9d
commit
de9b6512a7
7 changed files with 73 additions and 58 deletions
|
@ -4,7 +4,7 @@ use embedded_graphics_simulator::{
|
||||||
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
|
OutputSettingsBuilder, SimulatorDisplay, SimulatorEvent, Window,
|
||||||
};
|
};
|
||||||
use lvgl::style::Style;
|
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::{self, Align, Color, DisplayDriver, Event, LvError, Part, State, Widget, UI};
|
||||||
use lvgl_sys;
|
use lvgl_sys;
|
||||||
use std::sync::{mpsc, Arc, Mutex};
|
use std::sync::{mpsc, Arc, Mutex};
|
||||||
|
|
|
@ -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 inflector::cases::pascalcase::to_pascal_case;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::{Ident, TokenStream};
|
||||||
use quote::format_ident;
|
use quote::format_ident;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -47,14 +47,13 @@ impl Rusty for LvWidget {
|
||||||
type Parent = ();
|
type Parent = ();
|
||||||
|
|
||||||
fn code(&self, _parent: &Self::Parent) -> WrapperResult<TokenStream> {
|
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 widget_name = format_ident!("{}", to_pascal_case(self.name.as_str()));
|
||||||
let methods: Vec<TokenStream> = self
|
let methods: Vec<TokenStream> = self.methods.iter().flat_map(|m| m.code(self)).collect();
|
||||||
.methods
|
|
||||||
.iter()
|
|
||||||
.take(1)
|
|
||||||
.into_iter()
|
|
||||||
.flat_map(|m| m.code(self))
|
|
||||||
.collect();
|
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
define_object!(#widget_name);
|
define_object!(#widget_name);
|
||||||
|
|
||||||
|
@ -76,6 +75,14 @@ impl LvFunc {
|
||||||
pub fn new(name: String, args: Vec<LvArg>, ret: Option<LvType>) -> Self {
|
pub fn new(name: String, args: Vec<LvArg>, ret: Option<LvType>) -> Self {
|
||||||
Self { name, args, ret }
|
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 {
|
impl Rusty for LvFunc {
|
||||||
|
@ -108,6 +115,10 @@ impl Rusty for LvFunc {
|
||||||
for arg in self.args.iter().skip(1) {
|
for arg in self.args.iter().skip(1) {
|
||||||
arg.code(self)?;
|
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
|
let args_decl = self
|
||||||
.args
|
.args
|
||||||
|
@ -144,7 +155,7 @@ impl Rusty for LvFunc {
|
||||||
let next_arg = if i == 0 {
|
let next_arg = if i == 0 {
|
||||||
quote!(self.core.raw()?.as_mut())
|
quote!(self.core.raw()?.as_mut())
|
||||||
} else {
|
} else {
|
||||||
let var = format_ident!("{}", arg.name.as_str());
|
let var = arg.get_name_ident();
|
||||||
quote!(#var)
|
quote!(#var)
|
||||||
};
|
};
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
|
@ -160,7 +171,7 @@ impl Rusty for LvFunc {
|
||||||
|
|
||||||
// TODO: Handle methods that return types
|
// TODO: Handle methods that return types
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
pub fn #func_name(#args_decl) -> LvResult<()> {
|
pub fn #func_name(#args_decl) -> crate::LvResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
lvgl_sys::#original_func_name(#args_call);
|
lvgl_sys::#original_func_name(#args_call);
|
||||||
}
|
}
|
||||||
|
@ -201,6 +212,10 @@ impl LvArg {
|
||||||
Self { name, typ }
|
Self { name, typ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_name_ident(&self) -> Ident {
|
||||||
|
format_ident!("r#{}", self.name)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_type(&self) -> &LvType {
|
pub fn get_type(&self) -> &LvType {
|
||||||
&self.typ
|
&self.typ
|
||||||
}
|
}
|
||||||
|
@ -210,7 +225,7 @@ impl Rusty for LvArg {
|
||||||
type Parent = LvFunc;
|
type Parent = LvFunc;
|
||||||
|
|
||||||
fn code(&self, _parent: &Self::Parent) -> WrapperResult<TokenStream> {
|
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)?;
|
let typ = self.typ.code(self)?;
|
||||||
Ok(quote! {
|
Ok(quote! {
|
||||||
#name: #typ
|
#name: #typ
|
||||||
|
@ -287,6 +302,7 @@ impl CodeGen {
|
||||||
for widget_name in &widget_names {
|
for widget_name in &widget_names {
|
||||||
if f.name
|
if f.name
|
||||||
.starts_with(format!("{}{}", LIB_PREFIX, widget_name).as_str())
|
.starts_with(format!("{}{}", LIB_PREFIX, widget_name).as_str())
|
||||||
|
&& f.is_method()
|
||||||
{
|
{
|
||||||
ws.entry(widget_name.clone())
|
ws.entry(widget_name.clone())
|
||||||
.or_insert_with(|| LvWidget {
|
.or_insert_with(|| LvWidget {
|
||||||
|
@ -335,6 +351,7 @@ impl CodeGen {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|e| e.get_kind() == EntityKind::FunctionDecl)
|
.filter(|e| e.get_kind() == EntityKind::FunctionDecl)
|
||||||
.filter(|e| e.get_name().is_some())
|
.filter(|e| e.get_name().is_some())
|
||||||
|
.filter(|e| e.get_linkage().unwrap() != Linkage::Internal)
|
||||||
.map(|e| e.into())
|
.map(|e| e.into())
|
||||||
.filter(|e: &LvFunc| e.name.starts_with(LIB_PREFIX))
|
.filter(|e: &LvFunc| e.name.starts_with(LIB_PREFIX))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
use std::ffi::OsStr;
|
use std::env;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::{env, fs, path};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
let widgets_rs_path = manifest_dir.join("src/widgets/generated.rs");
|
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`");
|
println!("Generating `src/widgets/generated.rs`");
|
||||||
let status = Command::new(manifest_dir.join("../target/debug/lvgl-codegen"))
|
let status = Command::new(codegen_bin)
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|_| {
|
||||||
panic!(
|
panic!(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::Color;
|
use crate::Color;
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
use core::mem::MaybeUninit;
|
use core::mem::MaybeUninit;
|
||||||
use core::ptr;
|
|
||||||
use embedded_graphics::prelude::*;
|
use embedded_graphics::prelude::*;
|
||||||
use embedded_graphics::{drawable, DrawTarget};
|
use embedded_graphics::{drawable, DrawTarget};
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,41 @@
|
||||||
use crate::widgets::Arc;
|
use crate::widgets::Arc;
|
||||||
use crate::{LvResult, NativeObject};
|
|
||||||
|
|
||||||
impl Arc {
|
impl Arc {
|
||||||
/// Set the start angle, for the given arc part.
|
// /// Set the start angle, for the given arc part.
|
||||||
/// 0 degrees for the right, 90 degrees for the bottom, etc.
|
// /// 0 degrees for the right, 90 degrees for the bottom, etc.
|
||||||
pub fn set_start_angle(&mut self, angle: u16, part: ArcPart) -> LvResult<()> {
|
// pub fn set_start_angle(&mut self, angle: u16, part: ArcPart) -> LvResult<()> {
|
||||||
match part {
|
// match part {
|
||||||
ArcPart::Background => unsafe {
|
// ArcPart::Background => unsafe {
|
||||||
lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw()?.as_mut(), angle)
|
// lvgl_sys::lv_arc_set_bg_start_angle(self.core.raw()?.as_mut(), angle)
|
||||||
},
|
// },
|
||||||
ArcPart::Indicator => unsafe {
|
// ArcPart::Indicator => unsafe {
|
||||||
lvgl_sys::lv_arc_set_start_angle(self.core.raw()?.as_mut(), angle)
|
// lvgl_sys::lv_arc_set_start_angle(self.core.raw()?.as_mut(), angle)
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Set the end angle, for the given arc part.
|
// /// Set the end angle, for the given arc part.
|
||||||
/// 0 degrees for the right, 90 degrees for the bottom, etc.
|
// /// 0 degrees for the right, 90 degrees for the bottom, etc.
|
||||||
pub fn set_end_angle(&self, angle: u16, part: ArcPart) -> LvResult<()> {
|
// pub fn set_end_angle(&self, angle: u16, part: ArcPart) -> LvResult<()> {
|
||||||
match part {
|
// match part {
|
||||||
ArcPart::Background => unsafe {
|
// ArcPart::Background => unsafe {
|
||||||
lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw()?.as_mut(), angle)
|
// lvgl_sys::lv_arc_set_bg_end_angle(self.core.raw()?.as_mut(), angle)
|
||||||
},
|
// },
|
||||||
ArcPart::Indicator => unsafe {
|
// ArcPart::Indicator => unsafe {
|
||||||
lvgl_sys::lv_arc_set_end_angle(self.core.raw()?.as_mut(), angle)
|
// lvgl_sys::lv_arc_set_end_angle(self.core.raw()?.as_mut(), angle)
|
||||||
},
|
// },
|
||||||
}
|
// }
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
/// Rotate the arc, `angle` degrees clockwise.
|
// /// Rotate the arc, `angle` degrees clockwise.
|
||||||
pub fn set_rotation(&mut self, angle: u16) -> LvResult<()> {
|
// pub fn set_rotation(&mut self, angle: u16) -> LvResult<()> {
|
||||||
unsafe {
|
// unsafe {
|
||||||
lvgl_sys::lv_arc_set_rotation(self.core.raw()?.as_mut(), angle);
|
// lvgl_sys::lv_arc_set_rotation(self.core.raw()?.as_mut(), angle);
|
||||||
}
|
// }
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The different parts, of an arc object.
|
/// The different parts, of an arc object.
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use crate::{LvResult, NativeObject};
|
|
||||||
|
|
||||||
pub enum GaugePart {
|
pub enum GaugePart {
|
||||||
Main,
|
Main,
|
||||||
Major,
|
Major,
|
||||||
|
|
|
@ -5,7 +5,7 @@ mod label;
|
||||||
|
|
||||||
include!("generated.rs");
|
include!("generated.rs");
|
||||||
|
|
||||||
use crate::Widget;
|
use crate::{NativeObject, Widget};
|
||||||
pub use arc::*;
|
pub use arc::*;
|
||||||
pub use bar::*;
|
pub use bar::*;
|
||||||
pub use gauge::*;
|
pub use gauge::*;
|
||||||
|
|
Loading…
Reference in a new issue