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.55k stars 601 forks source link

unexprected index overwrite in for loop #4961

Closed HookedBehemoth closed 7 months ago

HookedBehemoth commented 7 months ago

Hey, I tried to create a simple clock in a slint component and a custom property with the name "index" got overwritten in my for loop. index is described as optional in the slint book and should require brackets. Defining it myself makes it so it's always overwritten and my assignment is ignored. Renaming the property to anything else makes my code work again. You can test the code below in slintpad https://slint.dev/releases/1.5.1/editor/


export component Clock inherits Rectangle {
    in property <length> size: 200px;
    preferred-height: 100px;
    preferred-width: 100px;
    width: size;
    height: size;

    Rectangle {
        width: size;
        height: size;
        background: white;
        border-width: 2px;
        border-color: black;
        border-radius: self.width / 2;
    }

    for number in 12: Text {
        property <length> size: 30px;
        property <float> index: number + 1;
        property <length> parent_center: parent.width / 2 - size / 2;
        property <length> radius: parent.width / 2 - size / 2;

        text: number + 1;
        color: black;
        font-size: size / 2;
        font-weight: 900;
        width: size;
        height: size;
        vertical-alignment: center;
        horizontal-alignment: center;
        x: radius * sin(360deg * (index / 12.0)) + parent_center;
        y: -radius * cos(360deg * (index / 12.0)) + parent_center;
    }
}```
ogoffart commented 7 months ago

Thanks for the bug report!

Indeed, the interpreter used by the preview and slintpad hardcode the "index" property in https://github.com/slint-ui/slint/blob/6563bf0981ca882e72ad7e217a53e7adf07fc805/internal/interpreter/dynamic_item_tree.rs#L115

This can even lead to more severe bugs. For example, this panics because at runtime, index is no longer a string as expected.

export component Demo {
    HorizontalLayout {
        for i in 12: Text {
            property <string> index: "hello";
            text: index; 
        }
    }
}
HookedBehemoth commented 7 months ago

Awesome! Thanks for the quick fix.