slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
17.56k stars 604 forks source link

Allow two-way binding syntax for callbacks inside used elements #6373

Open Enyium opened 1 month ago

Enyium commented 1 month ago

Consider this SlintPad demo (see comments):

import { Button, VerticalBox } from "std-widgets.slint";

component Foo {
    in property <bool> has-lower: true;

    in property <string> upper-text <=> upper.text;
    in property <string> lower-text;

    callback clicked-upper <=> upper.clicked;
    callback clicked-lower;

    VerticalBox {
        alignment: start;

        upper := Button {}

        if has-lower : Button {
            // This works:
            text <=> root.lower-text;

            // Why shouldn't this also work, if the two-way-binding
            // syntax is okay for callbacks when declaring them,
            // and for properties inside used elements?
            //clicked <=> root.clicked-lower;

            // You currently have to use this syntax. This would
            // require you to pass the whole parameter list:
            clicked => { root.clicked-lower(); }
        }
    }
}

export component Demo {
    Foo {
        upper-text: "0";
        lower-text: "0";

        clicked-upper => {
            self.upper-text = self.upper-text.to-float() + 1;
        }

        clicked-lower => {
            self.lower-text = self.lower-text.to-float() + 1;
        }
    }
}
ogoffart commented 1 month ago

True, we could transform it into a simple call there, instead of making this an error https://github.com/slint-ui/slint/blob/b2016239d182278d5af5e2aecf62d70ff7659460/internal/compiler/object_tree.rs#L1675