Docking Example using QtQuick

One of Qt’s features that impressed me early on was use of docking elements. These allowed the user to rearrange the UI to their own liking, expand widgets into windows of their own and brought great flexibility in general.
In QtQuick this functionality is missing, but can be easily added. I made a short example how to implement a dockable container that can be detached into a window of its own. This can be useful especially in larger applications where the user needs to keep an eye on several things going on at the same time.

Demo of the Docking Example

While the implementation is far from being production ready I would like to show two tricks in particular that solve common problems.

The Dockable container is defined within its own qml file. The content however has to be defined outside of this file, where the container is being used. For this I am using a technique discussed in this Stackoverflow post in detail.
In the Dockable item a default property is set that places the content inside a placeholder container:

// The Dockable item, shortened to the relevant parts
Item {
    id: root
    default property alias contents: placeholder.data

    [...]

    Item {
       id: placeholder
        anchors {
            top: toolBar.bottom;
            left: parent.left;
            right: parent.right;
            bottom: parent.bottom
        }
    }
}

Using this a Dockable item can be declared like this:

Dockable {
    title: qsTr("Dockable A")
    anchors { left: parent.left; right: parent.right}
    contents: Label {
        anchors.centerIn: parent
        text: "A"
        font.pointSize: 48
    }
}

The second technique involves states to make the code more elegant and readable by grouping changes that belong together in one place. In this example the Dockable item has two states called docked and undocked. The state definitions contain all the neccessary changes that have to be made to move the content to a window, show the window and hide the contents original container:

states: [
    State {
        name: "undocked"
        PropertyChanges { target: root; height: 0 }
        PropertyChanges { target: window; visible: true }
        ParentChange { target: content; parent: undockedContainer }
    },
    State {
        name: "docked"
        PropertyChanges { target: root; height: implicitHeight }
        PropertyChanges { target: window; visible: false }
        ParentChange { target: content; parent: root }
    }
]

The full example is on GitHub an can be found here:
https://github.com/wbt729/quickdock