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.72k stars 615 forks source link

`Timer` element doesn't apply assignments in `init` #6376

Open Enyium opened 2 months ago

Enyium commented 2 months ago

Consider this SlintPad demo (see its rendered output):

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

export component Demo {
    timer := Timer {
        interval: 1s;

        triggered => {
            t.text = t.text.to-float() + 1;
        }
    }

    init => {
        timer.interval = 2s;
        timer.running = false;
    }

    VerticalBox {
        alignment: start;

        Text {
            text: "Timer shouldn't run,\nand interval should be\nlonger than 1s:";
        }

        t := Text {
            text: "0";
        }

        Button {
            text: "Lengthen";

            clicked => {
                timer.interval = 5s;
            }
        }

        Text {
            text: "Running as read: \{timer.running ? "true" : "false"}";
        }

        Text {
            text: "Interval as read: \{timer.interval / 1s}s";
        }
    }
}
ogoffart commented 2 months ago

I haven't investigated this bug yet, but i have the feeling this is because we assign property and call init callback in the wrong order.

renatofilho commented 1 month ago

The Slint docs says we should not assign properties on Init Function. Don’t use this callback to initialize properties, because this violates the declarative principle. I would like to know if that is a different case for this bug?

tronical commented 1 month ago

I tried the link and this is what I see:

(Mobile Safari)

IMG_0620

What am I missing?

renatofilho commented 1 month ago
Timer shouldn't run,\nand interval should be\nlonger than 1s:

since he set the timer.running = false; on Init function he expects the timer not be running. t.text should not be changing.

tronical commented 1 month ago

Got it - thanks :)

tronical commented 1 month ago

When the frames are rendered, the timer properties evaluate to the correct value. The timer is still running though, which leads me to believe that the issue is with the change callbacks that aren’t triggered, and thus the timer keeps on running and is never stopped.

Enyium commented 1 month ago

Don’t use this callback to initialize properties, because this violates the declarative principle.

"because this violates the declarative principle" is something completely different than "Don't expect this to work." There may be edge cases where it's needed or useful.