(The TLDR for this is https://bugreports.qt.io/browse/QTBUG-94168)

When working on pointer handlers a few years ago, I was mainly thinking of the 
primary use cases where the target property points to an Item to be 
manipulated, and when the handler is active, it changes the appropriate 
properties for you.  (I.e. you can just declare a DragHandler inside an Item, 
and it becomes draggable.  If you want to drag something else instead, you can 
set the target.)  But there are some use cases where the target is or should be 
null, and you use ordinary bindings to make the handler manipulate arbitrary 
numeric properties.  QTBUG-68941 was the first (if memory serves) to point out 
that it’s an API mistake to have the main "value property", like 
PinchHandler.scale, resetting to the default value (1) when the gesture ends: 
the result is whatever you bound it to will jump back; so you need conditional 
bindings, or imperative onValueChanged and/or onActiveChanged code blocks to 
work around that.  So we made PinchHandler.scale “persistent” or “accumulated” 
so that you can bind it directly to an Item’s scale, and the item will scale 
smoothly when you do a sequence of pinches.  And then I thought "But I suppose 
we need to do the same with rotation.” But didn’t do it.  A couple of years 
went by… and now we are afraid to repeat that sort of behavior change, for 
example in 6.2, for fear that too many users might be using those existing 
properties, and will see breakage when they port their Qt 5 apps to Qt 6.  I’m 
thinking of PinchHandler.rotation, PinchHandler.translation and 
DragHandler.translation (I wonder if I missed any more).

Also, DragHandler and PinchHandler have the centroid property.  The 
gesture-scoped translation should be the same as centroid.scenePosition - 
centroid.scenePressPosition I think.  Binding to centroid properties can be 
useful, but they also change abruptly between gestures.

Working with Qt Quick 3D reminded me of this problem.  I want to make pointer 
handlers work in 3D.  (Not start over again with all-new objects for event 
handling: maybe that’s been done enough times now.)  But a pointer handler’s 
target property is a QQuickItem*, so it cannot be a QQuick3DModel* (so far… but 
it’s still C++-private, so maybe we can still change it to QObject*, as long as 
it doesn’t affect the QML API for the 2D use cases; I didn’t try that yet).  I 
have patches that make it possible to declare the handler in the Model, and do 
event delivery so that it becomes interactive; but DragHandler cannot of its 
own accord know exactly how to drag a 3D model, because the units are 
different, and you probably want to drag on a 2D plane, which there is no API 
to define.  So it seems that the value properties like DragHandler.translation 
are going to be more important, because you will more likely need to make 
bindings to them:

     Model {
        source: "#Sphere"
        pickable: true
        materials: DefaultMaterial { diffuseColor: "beige" }
        x: dh.translation.x
        y: -dh.translation.y
        z: 400
        DragHandler { id: dh }
    }

The translation should “pick up where it left off” when you start dragging the 
second time, to make that work.  But currently it has the same problem as 
PinchHandler.scale did: it’s just the distance you have dragged within one drag 
gesture, and jumps back to 0,0 on release.  A workaround could be like this:

    DragHandler {
property point startDrag
onActiveChanged: {
   if (active)
startDrag = Qt.point(sphere.x, sphere.y)
}
onTranslationChanged: {
            // replace bindings with imperative code, yuck
    sphere.x = startDrag.x + translation.x
    sphere.y = startDrag.y - translation.y
}
    }

(It would be nice if DragHandler “just works”: declare it in a Model and it’s 
draggable.  But how?  We’d maybe need to teach DragHandler to use some sort of 
callback to transform pixel deltas to 3D deltas, where the callback is defined 
by some Qt Quick 3D API which we haven’t put any thought into yet; and then 
perhaps use QMetaProperty’s to set the position of the 3D object, because Qt 
Quick can’t link directly to Qt Quick 3D.  Using metaproperties is a good idea 
anyway, for another reason: so that property interceptors like Behavior and 
BoundaryRule will work.  (Every time a handler calls setSomething() on an Item 
directly, it means those cannot intercept it.)  I don’t know if we will succeed 
in making binding-free DragHandler possible in 3D or not; but making plain old 
bindings is simple enough, and ought to work.)

So I want to make translation persistent, but that’s likely to break someone 
else’s QML code.  I don’t know how widely-used that property is.

So now we are going towards the convention that there is activeTranslation and 
persistentTranslation, and the same for the other “value properties” like that, 
in pointer handlers.  That makes translation redundant, so it should be 
deprecated.  In order to avoid breaking some use cases unexpectedly, we will 
cause intentional trouble for more of the users (replacing deprecated 
properties), if we go ahead and repeat that pattern on the rest of the 
handlers.  It implies that even PinchHandler.scale should be deprecated, 
because we should call it persistentScale now.  But this is what we do in Qt: 
we always worry about backwards compatibility, and it’s often a hassle.  In the 
end I’d rather have the shorter property names, actually.  What do you think?

Should we stick to the rule that we always deprecate and replace, rather than 
taking a risk?

Any other ideas?

If only I’d thought of doing this a few months ago for 6.0, or 5.12 even…

Anyway https://codereview.qt-project.org/c/qt/qtdeclarative/+/352432 went in 
for 6.2 today.  Changing the other properties would be past the feature freeze 
now, so I guess it will be later.

A couple of grinding follow-up patches are 
https://codereview.qt-project.org/c/qt/qtdeclarative/+/352811 and 
https://codereview.qt-project.org/c/qt/qtdeclarative/+/352812

_______________________________________________
Development mailing list
[email protected]
https://lists.qt-project.org/listinfo/development

Reply via email to