TheWaterProgrammer
TheWaterProgrammer

Reputation: 8219

How to block a QML item from getting panned out or its parent's boundaries

I have the following code which allows panning of an image on an application window

Code:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

ApplicationWindow {
    id: app
    visible: true
    title: qsTr("Test panning an Image")

    width: 700
    height: 700

    Image {
        id: my_image_item
        source: "http://doc.qt.io/qt-5/images/declarative-qtlogo.png"
        MouseArea{
            anchors.fill: parent
            drag.target: my_image_item
            drag.axis: Drag.XAndYAxis
        }
    }
}

Objective:
I want to block the image from getting dragged/panned outside its parent.

Basically I do not want to allow my_image_item to be moved out to a position where :

Primary Question:
How can I limit the movement of my_image_item only within the edges of its parent while user is dragging my_image_item?

Secondary question: (if answered then great):
The item that limits my_image_item's movement needs to be strictly its parent? Or it could be another item which is not its parent as well ? (at least one that shares a common QML parent)

Upvotes: 4

Views: 1490

Answers (3)

VojtaStruhar
VojtaStruhar

Reputation: 651

the solution was posted by the author himself, but I thought I would try to explain it a little bit.

drag.minimum and drag.maximum take a number as a value, that is why accepted answer (that uses parent anchors) will not work. Limiting movement to parent is then indeed like this:

drag.minimumY: 0
drag.minimumX: 0
drag.maximumY: parent.height
drag.maximumX: parent.width

But this counts with the fact the dragged element is placed on x: 0; y: 0 like it is by default. If you place is somewhere else, replace the zeroes by its initial coordinates.


As for the secondary question - you see you are limiting the drag amount itself, it is not strictly bound to any single component. You are saying that the component can be dragged this much in these directions.

If you are going to limit dragging to completely unrelated component, be careful about the minimum, maximum drag amounts and about initial placement of your dragged element.

Upvotes: 1

Paltoquet
Paltoquet

Reputation: 1234

Did you try to use drag.maximumX/drag.minimumX

http://doc.qt.io/qt-5/qml-qtquick-mousearea.html#drag.minimumX-prop

Image {
        id: my_image_item
        source: "http://doc.qt.io/qt-5/images/declarative-qtlogo.png"
        MouseArea{
            anchors.fill: parent
            drag.target: my_image_item
            drag.axis: Drag.XAndYAxis
            drag.minimumX: my_image_item.x
            drag.maximumX: my_image_item.right // my_image_item.x + width ???
            drag.minimumY: my_image_item.y
            drag.maximumY: my_image_item.bottom // my_image_item.y + height ???
        }
    }

Upvotes: 6

TheWaterProgrammer
TheWaterProgrammer

Reputation: 8219

I got the answer to my question from Qt docs itself.

Adding the following additionally to MouseArea's drag properties limits its movement to within its parent's boundaries.

Solution:

drag.minimumX: 0
drag.maximumX: app.width - my_image_item.width
drag.minimumY: 0
drag.maximumY: app.height - my_image_item.height

Gives me exactly the behaviour I wanted to simulate in the 4 bullet points listed in the question.

Following is how the final test app looks like:

Full code:

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2

ApplicationWindow {
    id: app
    visible: true
    title: qsTr("Test panning an Image")

    width: 700
    height: 700

    Image {
        id: my_image_item
        source: "http://doc.qt.io/qt-5/images/declarative-qtlogo.png"
        MouseArea{
            anchors.fill: parent
            drag.target: my_image_item
            drag.axis: Drag.XAndYAxis

            drag.minimumX: 0
            drag.maximumX: app.width - my_image_item.width
            drag.minimumY: 0
            drag.maximumY: app.height - my_image_item.height
        }
    }
}

I am still in process of figuring out the answer to my additional secondary question

Upvotes: 3

Related Questions