Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-130517

PinchHandler unexpectedly resets target's rotation even if rotationAxis.enabled is false

    XMLWordPrintable

Details

    • macOS
    • 49fbf2f86 (dev), 6c9123f09 (6.8), 965cd1c1d (tqtc/lts-6.5)

    Description

      PinchHandler is used to control scale of image, just zooming in/out, no rotation.
      rotationAxis.enabled is explicitly set to false
      However, any pinch gesture resets rotation to 0.

      Sample code:

      import QtQuick
      import QtQuick.Controls.Basic
      import QtQuick.Dialogs
      import QtQuick.Layouts
      import Qt.labs.animation // for BoundaryRule
      
      Window {
          width: 640
          height: 480
          visible: true
      
          FileDialog {
              id: fileDialog
              fileMode: FileDialog.OpenFile
              nameFilters: ["Images (*.jpg *.jpeg *.png *.gif)"]
              onAccepted: image.source = currentFile
          }
      
          ColumnLayout {
              anchors {
                  fill: parent
                  margins: 20
              }
              spacing: 20
      
              RowLayout {
                  spacing: 20
                  Button {
                      text: "Select"
                      onClicked: fileDialog.open()
                  }
      
                  Button {
                      text: "rotate cw"
                      onClicked: image.rotation = ((image.rotation + 90) % 360)
                  }
      
                  Text {
                      text: image.rotation
                  }
              }
      
              Flickable {
                  id: flickable
      
                  Layout.fillHeight: true
                  Layout.fillWidth: true
      
                  clip: true
                  contentWidth: imageProxy.width
                  contentHeight: imageProxy.height
                  boundsBehavior: Flickable.StopAtBounds
                  interactive: image.isZoomed
      
                  function updateContent() {
                      contentX = (imageProxy.width - width) / 2;
                      contentY = (imageProxy.height - height) / 2;
                  }
      
                  Item {
                      id: imageProxy
                      width: Math.max(image.rotatedWidth * image.scale, flickable.width)
                      height: Math.max(image.rotatedHeight * image.scale, flickable.height)
      
                      onWidthChanged: flickable.updateContent()
                      onHeightChanged: flickable.updateContent()
      
                      PinchHandler {
                          id: pinchHandler
                          target: image
                          enabled: true
                          persistentScale: image.defaultScale
                          scaleAxis {
                              maximum: image.maximumScale
                              minimum: image.minimumScale
                          }
                          xAxis.enabled: false
                          yAxis.enabled: false
                          rotationAxis.enabled: false
                          // onScaleChanged: (delta) => image.scale = Math.max(image.minimumScale ,Math.min(image.maximumScale, (image.scale * delta)))
                      }
      
                      WheelHandler {
                          id: wheelHandler
                          target: image
                          property: 'scale'
                          enabled: true
                          acceptedModifiers: Qt.ControlModifier
                          acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
                          targetTransformAroundCursor: false
                      }
      
                      Image {
                          id: image
      
                          anchors.centerIn: parent
                          autoTransform: true
      
                          readonly property real rotatedWidth: (rotation % 180 === 0) ? width : height
                          readonly property real rotatedHeight: (rotation % 180 === 0) ? height : width
                          readonly property real defaultScale: Math.min((flickable.width - 144) / image.rotatedWidth,
                                                                         flickable.height / image.rotatedHeight, 1)
                          readonly property real minimumScale: Math.min(defaultScale, 1.0)
                          readonly property real maximumScale: Math.max(defaultScale, 1.0)
                          readonly property bool canBeZoomed: Math.abs(maximumScale - minimumScale) >= Number.EPSILON
                          readonly property bool isMinimumSize: Math.abs(scale - minimumScale) < Number.EPSILON
                          readonly property bool isMaximumSize: Math.abs(scale - maximumScale) < Number.EPSILON
                          readonly property bool isZoomed: canBeZoomed && !isMinimumSize
      
                          //scale: defaultScale // set implicitly via 'pinchHandler.persistentScale'
      
                          onDefaultScaleChanged: {
                              if (image.status === Image.Ready && !image.isZoomed) {
                                  image.scale = image.defaultScale
                              }
                          }
      
                          BoundaryRule on scale {
                              enabled: wheelHandler.active
                              minimum: image.minimumScale
                              maximum: image.maximumScale
                          }
      
                          TapHandler {
                              gesturePolicy: TapHandler.WithinBounds
                              onDoubleTapped: {
                                  image.scale = image.isZoomed ? image.minimumScale
                                                               : image.maximumScale
                              }
                          }
                      }
                  }
              }
          }
      }
      

      Checked on Mac only, but may be relevant for all platforms.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            srutledg Shawn Rutledge
            sergei.nevdakh Sergei Nevdakh
            Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes