Details
-
Suggestion
-
Resolution: Unresolved
-
P2: Important
-
None
Description
Behavior is a property interceptor: when some code (C++ or JS) tries to set a property on a QML-owned object, a property interceptor can change the value that ultimately gets set. But this mechanism is not very general so far: Behavior is limited to applying an animation, in practice.
I'm thinking from a functional-programming perspective: I expect that an interceptor could be a function that takes a proposed value and outputs a new value.
ScriptAction is designed for applying arbitrary side-effects while a SequentialAnimation is running, but it's not an animation itself.
So this combination doesn't work, but it would be useful if it did:
SomeItem {
Behavior on scale {
ScriptAction {
script: (proposedScale) => {
...
return newScale
}
}
}
}
Or maybe we need some other mechanism that would have a similar effect.
Yes, it could perhaps be dangerous...
The reason it comes up for me is PinchHandler tries to directly set the scale property of its target item; but if that item has other means of scaling itself, by increasing its internal resolution, we want to adjust the scale property accordingly. If the item is a Map, and after setting scale > 1.5 we adjust its zoom level to show more detail, what should the scale property be set to now? It should be less than 1, because now the map is twice as big, but we only need it to be 1.5 times as big as it was. But PinchHandler doesn't know better: it will keep trying to set the scale continuously upward from there as long as the user keeps spreading his fingers. I'm not sure yet if PinchHandler should have an API of its own for this, and what it should look like; it's hard to avoid having some sort of JS formula, because the relationship between scale and zoom may not be strictly logarithmic (because https://wiki.openstreetmap.org/wiki/Zoom_levels are not doubling at every step). But some other scripting solution that allows arbitrary mapping of proposed scale to actual scale could make it possible (albeit writing the formula may take some head-scratching).
The same pattern recurs with any item that can change its own resolution: an Image that is using an SVG or PDF file as a source, etc. (The easy way out is to just wait until the pinch is done, before changing the resolution. Then for the next pinch, the scale starts over, at 1.0 or at some other post-zoom scale factor.)
Applying it to the rotation property also needs some thought. Perhaps this would be a good way to enforce "detents": PinchHandler would normally let you rotate an item arbitrarily, but what if you want to make it rotate only by 15° increments? (for that matter, what if you want the snapping to be animated too?) Or the x and y properties: PinchHandler or DragHandler could allow translating an item, but it can snap to other items or to a grid. Do we need a new kind of property interceptor, something like BoundaryRule but with repeating boundaries? or should it be scriptable in JS?
If you apply scripted interceptors to all 4 properties that PinchHandler knows how to set (x, y, scale and rotation), what happens? What if the formulas have some dependencies? But even if there is a trap hiding there, it's not necessarily a reason not to try this idea.
Attachments
Issue Links
- relates to
-
QTBUG-68108 QtLocation: start using Pointer Handlers and get rid of the C++ gesture recognition logic
- Closed
-
QTBUG-108635 enable PinchHandler to control ease of starting rotation
- Reported
-
QTBUG-76379 PinchHandler should have a way to reset
- Closed