lvgl / lv_binding_rust

LVGL bindings for Rust. A powerful and easy-to-use embedded GUI with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash).
MIT License
638 stars 64 forks source link

Make possible to define styles as CSS #1

Open rafaelcaricio opened 4 years ago

rafaelcaricio commented 4 years ago

Would be nice to be able to define styles in CSS format. That makes it easy to prototype and convert to LittlevGL Rust implementation.

Besides the possibility of creating styles like in C code:

let mut style = Style:new(Themes::Plain);
style.body.border.width = 1;
style.body.border.color   = Color::from_hex3(0x46B);
style.body.padding.left = 0;
style.body.padding.right = 0;
style.body.radius = 10;

We would like to be also able to use CSS:

let mut style = css_style!(Themes::Plain, {
  border-width: 1px;
  border-color: #46B;
  padding-left: 0;
  padding-right: 0;
  border-radius: 10px;
});

Both examples here would be equivalent Rust code after compilation.

embeddedt commented 4 years ago

I had been thinking of making a compiler that would convert CSS to LittlevGL 7 styles. How does Rust integrate with CSS? Perhaps we can combine our efforts.

rafaelcaricio commented 4 years ago

Hey! I'm thrilled to hear about your interest in lvgl-rs. :smiley_cat:

I think the compiler you're mentioning is a great idea. It will definitely make it easier to write Lvgl styles. This is similar in theory to the idea I describe in this issue, but in Rust it would work differently. Rust doesn't integrate with CSS. I want to write a Rust macro that accepts content looking like CSS and which, at compile time, will convert the pseudo-CSS content to actual Rust code calling the public methods in the lvgl::Style object. Rust macros are really powerful, so one can do this type of thing.

I think we could work together on enabling your compiler to generate the Rust macro or generate the final lvgl-rs compatible code. The user would choose the final format for the Rust code. This would be useful for some users since macro processing impacts Rust compile time, so people may want to generate the final Rust code in some cases.

Additionally, I would love to share the knowledge of the transformations like which CSS property means what in Lvgl.

embeddedt commented 4 years ago

I fiddled with it for a few hours today and got a rudimentary proof-of-concept working. I also uploaded my code here.

At the moment, it can take a CSS file with classname selectors and translate it to a C file containing LVGL lv_style function calls. (Styles in LVGL 7 are no longer used as structs but rather opaque handles which you manipulate through functions.)

It seems to me that your Rust macro could translate the pseudo-CSS to a real CSS file which then gets run through my compiler. My compiler could then output lvgl-rs compatible function calls. The syntax you proposed above looks almost identical to pure CSS so it should be a matter of dumping that into a file (if that's possible).

rafaelcaricio commented 4 years ago

Wow, nice! I will have a look at your code.

I don't know how familiar you are with Rust language, but Rust macros are preprocessed internally by the Rust compiler. So it is not a very good idea to save the pseudo-CSS into a file and call an external tool for preprocessing. I think it was not clear in my previous comment and I'm sorry about that. What I meant is for your compiler to generate either of these (based on a user option):

  1. lvgl-rs compatible Style stuct creation and method calls;
  2. calls to the lvgl-rs's macro css_style!.

I know the second option might sound redundant, but I thought users could learn that the css_style! macro of lvgl-rs is a way to have the CSS source definitions as a part of their codebase. That makes option no. 2 relevant.

Those two options are different public APIs that lvgl-rs will expose for creating styles. Of course, the macro is not implemented yet. So your compiler, for now, would only generate the first option.

I would be happy to help by sending a PR to add those options to your compiler. Plus I can be the main point of contact/maintainer of those two options related to lvgl-rs support in your compiler.

embeddedt commented 4 years ago

Sounds good to me. I'm not particularly familiar with how Rust works (more of a C and JS person) so do whatever you think is best. :slightly_smiling_face:

rafaelcaricio commented 4 years ago

Cool, I will make sure lvgl-rs is using LVGL 7 #10 before sending a PR to your compiler. Need to take care of this first. 💅 I just saw the lv_style has a completely different API now. 😬