-
-
Notifications
You must be signed in to change notification settings - Fork 685
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
Implement ValueSource #3012
Comments
An alternative would be to leave widget properties essentially as they are, but give a value source the ability to link to and modify any arbitrary attribute of any object, or at least of any widget. Something along the lines of a_source.link_to(a_widget, "attribute_name") Or perhaps more like link(a_source, a_widget, "attribute_name") Would probably be most ergonomic to give widget a convenience method that then calls the above, like a_widget.link_source("attribute_name", a_source) However it's phrased, the source would keep a list of things it's connected to, and update them whenever it's changed. |
The root of the issue is the source of truth. In other source-based widgets (tree, table), the source is the source of truth, and the widget renders that source of truth. Change the source and the widget is informed of the need to re-render. If there are multiple widgets using that source, they're all notified. However, in other widgets (TextInput is a good example), the widget's value is the source of truth. That's problematic for a source-based implementation, because you can't tie a second widget to the first widget's internal state (or, if you do, you risk notification cascades - changing one widget changes the source, which is an event that changes the second widget which is an event that changes the source, and so on). The other key difference is that Toga currently differentiates between the "value" of a widget (i.e., the data actually being displayed) and all other properties of the widget. As I understand it, Invent doesn't make this distinction - all properties of the widget are essentially treated as being "source controlled". So, as an example, the "enabled" status of a widget is a property that could be controlled by the source of another widget. A switch widget could be used literally to control the enabled status of a text input with nothing more than "plugging the wires together", as it were. The risk with these sorts of changes is that you end up with the possibility of diverged state - where the physical state of the widget doesn't reflect the value that the source thinks the widget has. This should be resolvable; we just need to be careful to get the details right. And most of the details will be exactly the same - the main difference is that any Ironically, Toga has been down this path in the past - one of the big changes in the 0.3 release was moving to "widget as source of truth" for most widget; with a handful of widgets (like NumberInput) retaining some core-side representation of value because of issues with round-tripping values in the backend. |
Invent currently avoids this because JavaScript events are not fired on programmatic changes. But Toga consistently fires events on programmatic changes on all platforms, with the backend generating the event itself if the native layer doesn't already do so.
I'm not sure what you mean by this: how is the "value" property different from the others?
Since the native widget always exists but the ValueSource is optional, I'd prefer to keep the native widget as the source of truth for its own properties if we can, with the ValueSource being a layer on top. In that case, the "self-notification" could be prevented by making the ValueSource take no action if set to its existing value. A couple of other notes:
|
One of my (not terribly common) fond memories of using QML in Qt was the ability to set the value of basically anything as dynamic. Like something as simple as Anyway, I doubt Toga could feasibly do anything quite so magical (especially not that example, since I don't think actual, calculated sizes are even exposed), but my point in this case is that the ability to modify the received value when the source updates is useful, and if there were a way to supply a callable when setting up a binding, one could supply something like |
Agreed - I suspect we may need to add something like a "notification source" to the notification mechanism, with notifications not being reflected back to the widget that created them.
I mean in the sense of things like places where I guess you could argue that distinction is mostly in my head, and that this is really a manifestation of "not using ValueSource everywhere it could be".
I agree that this would minimise the number of changes required; my concern is that it will be prone to "Widget has a different value to the source"-style bugs, because the "source of truth" becomes a concept, rather than literally the only place you can get the value. I guess we can protect against this with testing, but it still makes me nervous.
I think I can see what you're describing here; from a functionality perspective, it concerns me a little, as it seems like the sort of thing that could be easy to misunderstand/misconfigure. From an external API perspective, it won't necessarily be obvious that because you've added a source, custom event handlers will no longer work (or vice versa). This is possibly ratholing on the implementation, but I suspect that in order to manage this, we'll need to put the tools in place so that every property is implicitly a source under the hood; that will also mean that we can rely on a source existing for every data value, so we should be in a position to tie user-defined event handling and data-source handling into the same wrapper.
Agreed - I suspect "value" will need to have some basic typed variants that also do validation. |
ValueSource itself is already implemented, documented and tested, but there's no way to link it to any other component.
This would be required to support the Invent datastore. There's a sketch of how that might work here:
Any implementation of this feature is likely to involve replacing all the widget
@properties
with a custom class. Such a class could also be used to store metadata for an interactive GUI builder, such as:Related:
The text was updated successfully, but these errors were encountered: