-
Notifications
You must be signed in to change notification settings - Fork 600
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
Have callback emitted when a property changes #112
Comments
We have concern that this will not help keeping the language pure. |
We discussed this further a bit today and one way to address the laziness would be to treat each handler as if it were tracking a "gui" related property. So a "change handler" would result in the implementation using
|
In the mean time, as a workaround/hack, it is possible to put callback using the fact that property are re-evaluated when their dependency changes
In that example, background is going to be re-evaluated when dirty by the rendering code. and it is going to be dirty if the has-hover property is changed. So the (This is just a workaround/hack until such mechanism are implemented) |
Will this also work with global properties ? |
We decided to go with the following syntax:
The concern is still that this feature is opening a can of worm because some user would tend to use change handler instead of using binding. This is bad because it makes the design tool and tooling more complex. We decided that we will execute change handler in the next event loop iteration. When the property is marked as dirty, it is added to a queue and is evaluated in the next change handler. In particular, this will force the evaluation of the property at component creation no matter if the propery is queried by other mean (even if the component is hidden). This kind of disable the lazyness. Another point is the loop detection. Should the compiler detect loops? This can get quite difficult as it involves multiple components: component Inner {
in property <int> c;
out property <int> b: c;
}
component Foo {
out property <int> a: inner.b;
property <int> xxx;
changed a => {
func();
}
function func() {
xxx = inner.b; // Ok even if a depends on b
xxx = z; // ok even if z depends on a
inner.c = 42; // NOT OK: Loop: because a depends on c, and c is modified (so changes a)
}
property <int> z: a;
inner := Inner {}
} Another example:
And finally: component Foo {
b0 := LineEdit {
// Ok, no loop so far
changed text => { b1.text = text; }
}
b1 := LineEdit {
// but this would be a loop
// changed text => { b0.text = text; }
}
} This last example is something that may actually be wanted, to synchronize two propery, possibly with some code in the middle. It is kind of alright if, like in this case, the property converge, but if the binding was So since it is really hard to detect loops in the compiler, we might actually not do it and resort to runtime detection: if the evaluation of a debug handler mark the property dirty again, we would stop. but the problem is that if it causes another change handler to mark another property dirty which then mark the same property again we don't know that easily so that's also not trivial to detect and in the end we would still have a runtime infinite loop :-( |
One of the reason we want change handler is to keep some property in sync when it is not possible to have a proper two way binding. component SpinBox {
property <int> value;
// ...
LineEdit {
// this doesn't work because that's not the same type
// text <=> root.value;
// this breaks the binding as soon as text is edited or set.
text: root.value;
// works one way
edited => { value = text.to-float(); }
// this binding would actually solve the problem (but written at the root, not here)
changed value => { text = value; }
// but what about other possibilities such as
text <=> root.value {
=> text.to-float();
<= root.value;
}
}
} This is similar to #814 |
Hmm, maybe there was a misunderstanding. IMO we should not call change handlers at component creation time, only at the next event loop iteration. Can you elaborate what you mean? |
I have the next use case for changed handlers. The native |
It would be also great to have a possibility to check if an animation is finished like an callback. |
Would be quite nice to have this natively supported by Slint. One specific use case for this I ran into the other day would be implementing something akin to QtQuick's |
There is an experimental implementation of change callbacks.
It will most likely still not be active in 1.7, but you can already give it a try with the env variable, and feedback welcome. |
My take on loop handling:
|
Do we want a signal when a property changes.
If we do, what would be the syntax.
Some suggestions:
Can there be multiple event handler? (signal can only have one event handler currently)
When is the signal emitted? (properties are lazy right now, and they can be dirty without changing)
The text was updated successfully, but these errors were encountered: