Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSL thoughts #10

Open
UkoeHB opened this issue Nov 5, 2023 · 0 comments
Open

DSL thoughts #10

UkoeHB opened this issue Nov 5, 2023 · 0 comments

Comments

@UkoeHB
Copy link
Contributor

UkoeHB commented Nov 5, 2023

I have been thinking a bit about a DSL syntax for bevy_lunex. This syntax could easily be translated to pure-rust without too much additional verbosity, but I wanted to see if I could figure out a nice DSL.

Here is an example:

#[derive(LnxStyle)]
struct PlainTextStyle
{
    font      : &'static str,
    font_size : usize,
    color     : Color,
}

/// Deriving `LnxParams` transforms the text fields into lnx 'param methods' (see the example).
#[derive(LnxParams, Default)]
struct PlainTextParams
{
    justify: Justification,
    width: Option<f32>,
    height: Option<f32>,
    depth: f32,
}

impl Into<TextParams> for PlainTextParams
{
    fn into(self) -> TextParams
    {
        let params = match self.justify
        {
            Justification::Center => TextParams::center(),
            _ => unimplemented!()
        }
        params.set_width(self.width);
        params.set_height(self.height);
        params.depth(depth);
    }
}


#[lnx_prefab]
fn plain_text(lnx: &mut LnxContext, text: &str, params: PlainTextParams)
{
    let style = lnx.get_style::<PlainTextStyle>().unwrap();
    let text_style = TextStyle {
            font      : lnx.asset_server().load(style.font),
            font_size : style.font_size,
            color     : style.color,
        };

    let text_params: TextParams = params
        .into()
        .with_style(&text_style);
    lnx.commands().spawn(TextElementBundle::new(lnx.widget().clone(), text_params, text)); 
}

#[LnxStyleBundle]
struct BaseStyle
{
    plain: PlainTextStyle,
}

impl Default for BaseStyle
{
    //define the style
}

#[LnxStyleBundle]
struct DisplayStyle
{
    plain: PlainTextStyle,
}

impl Default for PlainTextStyle
{
    //define the style
}

let ui =
lnx!{
    // import rust bindings or lnx scripts
    use ui::prefabs::{plain_text, PlainTextParams};
    use ui::prefabs::text_params::Center;

    // registers style handles that can be referenced in the widget tree
    // - style bundles are default-initialize, unpacked, and stored in Arcs; copies are minimized in the widget tree
    styles[
        base_style: BaseStyle
        display_style: DisplayStyle
    ]

    // [r] creates a relative widget and implicitly sets it in the lnx context widget stack
    // - when entering a {} block, a new empty widget stack entry is added, then popped when leaving the block
    // - when a new widget is created within a block, the previous entry in the stack is over-written (but the other widget
    //   handle remains valid until leaving the block where it is created)
    [r] root: rx(0, 100) ry(0, 100)
    {
        // sets the current style in the lnx context style stack
        // - all previous styles in the stack will be hidden
        [style] set(base_style)

        // this nameless widget is implicitly a child of `root`
        [r] _: rx(20, 80), ry(42.5, 57.5)
        {
            // layers `display_style` on top of the previous style in the style stack
            // - the parent style will be used whenever the child style cannot satisfy a prefab's requirements
            [style] add(display_style)

            // style and parent widget are implicitly passed to the prefab
            // - we use 'param methods' to define parameters in the prefab
            // - if there is a param method name conflict, you must resolve the conflict with the names of the 
            //   target structs
            [inject] plain_text("Hello, World!", justify(Center), height(100), PlainTextParams::width(100))
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant