diff options
Diffstat (limited to 'qt-mobile/qml/mobilecomponents/OverlayDrawer.qml')
-rw-r--r-- | qt-mobile/qml/mobilecomponents/OverlayDrawer.qml | 414 |
1 files changed, 234 insertions, 180 deletions
diff --git a/qt-mobile/qml/mobilecomponents/OverlayDrawer.qml b/qt-mobile/qml/mobilecomponents/OverlayDrawer.qml index c6e9d4b36..061a9f490 100644 --- a/qt-mobile/qml/mobilecomponents/OverlayDrawer.qml +++ b/qt-mobile/qml/mobilecomponents/OverlayDrawer.qml @@ -37,11 +37,11 @@ Description: Properties: bool opened: If true the drawer is open showing the contents of the "drawer" - component. + component. Item page: It's the default property. it's the main content of the drawer page, - the part that is always shown + the part that is always shown Item contentItem: It's the part that can be pulled in and out, will act as a sidebar. @@ -53,30 +53,63 @@ AbstractDrawer { default property alias page: mainPage.data property Item contentItem - property alias opened: browserFrame.open + property alias opened: mainFlickable.open property int edge: Qt.LeftEdge property real position: 0 - - onContentItemChanged: contentItem.parent = drawerPage onPositionChanged: { - if (!enabled) { - return; - } - if (root.edge == Qt.LeftEdge) { - browserFrame.x = -browserFrame.width + position * browserFrame.width; - } else { - browserFrame.x = root.width - (position * browserFrame.width); + if (!mainFlickable.flicking && !mainFlickable.dragging && !mainAnim.running) { + switch (root.edge) { + case Qt.RightEdge: + mainFlickable.contentX = drawerPage.width * position; + break; + case Qt.LeftEdge: + mainFlickable.contentX = drawerPage.width * (1-position); + break; + case Qt.BottomEdge: + mainFlickable.contentY = drawerPage.height * position; + break; + } } } + onContentItemChanged: { + contentItem.parent = drawerPage + contentItem.anchors.fill = drawerPage + } + + function open () { - mouseEventListener.startBrowserFrameX = browserFrame.x; - browserFrame.state = "Dragging"; - browserFrame.state = "Open"; + mainAnim.to = 0; + switch (root.edge) { + case Qt.RightEdge: + mainAnim.to = drawerPage.width; + break; + case Qt.BottomEdge: + mainAnim.to = drawerPage.height; + break; + case Qt.LeftEdge: + case Qt.TopEdge: + default: + mainAnim.to = 0; + break; + } + mainAnim.running = true; + mainFlickable.open = true; } function close () { - mouseEventListener.startBrowserFrameX = browserFrame.x; - browserFrame.state = "Dragging"; - browserFrame.state = "Closed"; + switch (root.edge) { + case Qt.RightEdge: + case Qt.BottomEdge: + mainAnim.to = 0; + break; + case Qt.LeftEdge: + mainAnim.to = drawerPage.width; + break; + case Qt.TopEdge: + mainAnim.to = drawerPage.height; + break; + } + mainAnim.running = true; + mainFlickable.open = false; } Item { @@ -88,236 +121,257 @@ AbstractDrawer { Rectangle { anchors.fill: parent color: "black" - opacity: 0.6 * (root.edge == Qt.LeftEdge - ? ((browserFrame.x + browserFrame.width) / browserFrame.width) - : (1 - browserFrame.x / root.width)) + opacity: 0.6 * mainFlickable.internalPosition + } + + + NumberAnimation { + id: mainAnim + target: mainFlickable + properties: (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) ? "contentX" : "contentY" + duration: Units.longDuration + easing.type: Easing.InOutQuad } MouseArea { + id: edgeMouse anchors { right: root.edge == Qt.LeftEdge ? undefined : parent.right - left: root.edge == Qt.LeftEdge ? parent.left : undefined - top: parent.top - bottom: parent.bottom + left: root.edge == Qt.RightEdge ? undefined : parent.left + top: root.edge == Qt.BottomEdge ? undefined : parent.top + bottom: root.edge == Qt.TopEdge ? undefined : parent.bottom } z: 99 - width: Units.smallSpacing - onPressed: mouseEventListener.managePressed(mouse) - onPositionChanged: mouseEventListener.positionChanged(mouse) - onReleased: mouseEventListener.released(mouse) - } - MouseArea { - id: mouseEventListener - anchors.fill: parent - drag.filterChildren: true - property int startBrowserFrameX + width: Units.smallSpacing * 2 + height: Units.smallSpacing * 2 property int startMouseX property real oldMouseX + property int startMouseY + property real oldMouseY property bool startDragging: false - property string startState - enabled: browserFrame.state != "Closed" - onPressed: managePressed(mouse) - function managePressed(mouse) { + onPressed: { if (drawerPage.children.length == 0) { mouse.accepted = false; return; } + speedSampler.restart(); mouse.accepted = true; - startBrowserFrameX = browserFrame.x; oldMouseX = startMouseX = mouse.x; + oldMouseY = startMouseY = mouse.y; startDragging = false; - startState = browserFrame.state; - browserFrame.state = "Dragging"; - browserFrame.x = startBrowserFrameX; } onPositionChanged: { - if (drawerPage.children.length == 0) { + if (!root.contentItem) { mouse.accepted = false; return; } - if (mouse.x < Units.gridUnit || - Math.abs(mouse.x - startMouseX) > root.width / 5) { + if (Math.abs(mouse.x - startMouseX) > root.width / 5 || + Math.abs(mouse.y - startMouseY) > root.height / 5) { startDragging = true; } if (startDragging) { - browserFrame.x = root.edge == Qt.LeftEdge - ? Math.min(0, browserFrame.x + mouse.x - oldMouseX) - : Math.max(root.width - browserFrame.width, browserFrame.x + mouse.x - oldMouseX); + switch (root.edge) { + case Qt.RightEdge: + mainFlickable.contentX = Math.min(mainItem.width - root.width, mainFlickable.contentX + oldMouseX - mouse.x); + break; + case Qt.LeftEdge: + mainFlickable.contentX = Math.max(0, mainFlickable.contentX + oldMouseX - mouse.x); + break; + case Qt.BottomEdge: + mainFlickable.contentY = Math.min(mainItem.height - root.height, mainFlickable.contentY + oldMouseY - mouse.y); + break; + case Qt.TopEdge: + mainFlickable.contentY = Math.max(0, mainFlickable.contentY + oldMouseY - mouse.y); + break; + } } oldMouseX = mouse.x; + oldMouseY = mouse.y; } - onReleased: { - if (drawerPage.children.length == 0) { - mouse.accepted = false; - return; - } - - if (root.edge == Qt.LeftEdge) { - if (mouse.x < Units.gridUnit) { - browserFrame.state = "Closed"; - } else if (browserFrame.x - startBrowserFrameX > browserFrame.width / 3) { - browserFrame.state = "Open"; - } else if (startBrowserFrameX - browserFrame.x > browserFrame.width / 3) { - browserFrame.state = "Closed"; + speedSampler.running = false; + if (speedSampler.speed != 0) { + if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) { + mainFlickable.flick(speedSampler.speed, 0); } else { - browserFrame.state = startState + mainFlickable.flick(0, speedSampler.speed); } - } else { - if (mouse.x > width - Units.gridUnit) { - browserFrame.state = "Closed"; - } else if (browserFrame.x - startBrowserFrameX > browserFrame.width / 3) { - browserFrame.state = "Closed"; - } else if (startBrowserFrameX - browserFrame.x > browserFrame.width / 3) { - browserFrame.state = "Open"; + if (mainFlickable.internalPosition > 0.5) { + root.open(); } else { - browserFrame.state = startState; + root.close(); } } } - onCanceled: { - if (oldMouseX > width - Units.gridUnit) { - browserFrame.state = "Closed"; - } else if (Math.abs(browserFrame.x - startBrowserFrameX) > browserFrame.width / 3) { - browserFrame.state = startState == "Open" ? "Closed" : "Open"; + } + + Timer { + id: speedSampler + interval: 100 + repeat: true + property real speed + property real oldContentX + property real oldContentY + onTriggered: { + if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) { + speed = (mainFlickable.contentX - oldContentX) * 10; + oldContentX = mainFlickable.contentX; } else { - browserFrame.state = "Open"; - } - } - onClicked: { - if (Math.abs(startMouseX - mouse.x) > Units.gridUnit) { - return; - } - if ((root.edge == Qt.LeftEdge && mouse.x > browserFrame.width) || - (root.edge != Qt.LeftEdge && mouse.x < browserFrame.x)) { - browserFrame.state = startState == "Open" ? "Closed" : "Open"; - root.clicked(); + speed = (mainFlickable.contentY - oldContentY) * 10; + oldContentY = mainFlickable.contentY; } } - Rectangle { - id: browserFrame - z: 100 - color: Theme.viewBackgroundColor - anchors { - top: parent.top - bottom: parent.bottom - } - - width: { - if (drawerPage.children.length > 0 && drawerPage.children[0].implicitWidth > 0) { - return Math.min( parent.width - Units.gridUnit, drawerPage.children[0].implicitWidth) + onRunningChanged: { + if (running) { + speed = 0; + oldContentX = mainFlickable.contentX; + oldContentY = mainFlickable.contentY; + } else { + if (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) { + speed = (oldContentX - mainFlickable.contentX) * 10; } else { - return parent.width - Units.gridUnit * 3 + speed = (oldContentY - mainFlickable.contentY) * 10; } } + } + } - onXChanged: { - root.position = root.edge == Qt.LeftEdge ? 1 + browserFrame.x/browserFrame.width : (root.width - browserFrame.x)/browserFrame.width; + MouseArea { + id: mainMouseArea + anchors.fill: parent + drag.filterChildren: true + onClicked: { + if ((root.edge == Qt.LeftEdge && mouse.x < drawerPage.width) || + (root.edge == Qt.RightEdge && mouse.x > drawerPage.x) || + (root.edge == Qt.TopEdge && mouse.y < drawerPage.height) || + (root.edge == Qt.BottomEdge && mouse.y > drawerPage.y)) { + return; } + root.clicked(); + root.close(); + } + enabled: (root.edge == Qt.LeftEdge && !mainFlickable.atXEnd) || + (root.edge == Qt.RightEdge && !mainFlickable.atXBeginning) || + (root.edge == Qt.TopEdge && !mainFlickable.atYEnd) || + (root.edge == Qt.BottomEdge && !mainFlickable.atYBeginning) || + mainFlickable.moving - state: "Closed" - onStateChanged: open = (state != "Closed") - property bool open: false - onOpenChanged: { - if (browserFrame.state == "Dragging" || drawerPage.children.length == 0) { - return; - } + Flickable { + id: mainFlickable + property bool open + anchors.fill: parent + onOpenChanged: { if (open) { - browserFrame.state = "Open"; + root.open(); } else { - browserFrame.state = "Closed"; + root.close(); } } - - LinearGradient { - width: Units.gridUnit/2 - anchors { - right: root.edge == Qt.LeftEdge ? undefined : parent.left - left: root.edge == Qt.LeftEdge ? parent.right : undefined - top: parent.top - bottom: parent.bottom + enabled: parent.enabled + flickableDirection: root.edge == Qt.LeftEdge || root.edge == Qt.RightEdge ? Flickable.HorizontalFlick : Flickable.VerticalFlick + contentWidth: mainItem.width + contentHeight: mainItem.height + boundsBehavior: Flickable.StopAtBounds + property real internalPosition: { + switch (root.edge) { + case Qt.RightEdge: + return mainFlickable.contentX/drawerPage.width; + case Qt.LeftEdge: + return 1 - (mainFlickable.contentX/drawerPage.width); + case Qt.BottomEdge: + return mainFlickable.contentY/drawerPage.height; + case Qt.TopEdge: + return 1 - (mainFlickable.contentY/drawerPage.height); } - opacity: root.position == 0 ? 0 : 1 - start: Qt.point(0, 0) - end: Qt.point(Units.gridUnit/2, 0) - gradient: Gradient { - GradientStop { - position: 0.0 - color: root.edge == Qt.LeftEdge ? Qt.rgba(0, 0, 0, 0.3) : "transparent" - } - GradientStop { - position: root.edge == Qt.LeftEdge ? 0.3 : 0.7 - color: Qt.rgba(0, 0, 0, 0.15) - } - GradientStop { - position: 1.0 - color: root.edge == Qt.LeftEdge ? "transparent" : Qt.rgba(0, 0, 0, 0.3) - } - } - Behavior on opacity { - NumberAnimation { - duration: Units.longDuration - easing.type: Easing.InOutQuad + } + onInternalPositionChanged: { + root.position = internalPosition; + } + + onFlickingChanged: { + if (!flicking) { + if (internalPosition > 0.5) { + root.open(); + } else { + root.close(); } } } - - - MouseArea { - id: drawerPage - anchors { - fill: parent - //leftMargin: Units.gridUnit + onMovingChanged: { + if (!moving) { + flickingChanged(); } - clip: true - onChildrenChanged: drawerPage.children[0].anchors.fill = drawerPage } - states: [ - State { - name: "Open" - PropertyChanges { - target: browserFrame - x: root.edge == Qt.LeftEdge ? 0 : root.width - browserFrame.width + Item { + id: mainItem + width: root.width + ((root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) ? drawerPage.width : 0) + height: root.height + ((root.edge == Qt.TopEdge || root.edge == Qt.BottomEdge) ? drawerPage.height : 0) + onWidthChanged: { + if (root.edge == Qt.LeftEdge) { + mainFlickable.contentX = drawerPage.width; } - }, - State { - name: "Dragging" - //workaround for a quirkiness of the state machine - //if no x binding gets defined in this state x will be set to whatever last x it had last time it was in this state - PropertyChanges { - target: browserFrame - x: mouseEventListener.startBrowserFrameX + } + onHeightChanged: { + if (root.edge == Qt.TopEdge) { + mainFlickable.contentY = drawerPage.Height; } - }, - State { - name: "Closed" - PropertyChanges { - target: browserFrame - x: root.edge == Qt.LeftEdge ? -browserFrame.width : root.width + } + + Rectangle { + id: drawerPage + anchors { + left: root.edge != Qt.RightEdge ? parent.left : undefined + right: root.edge != Qt.LeftEdge ? parent.right : undefined + top: root.edge != Qt.BottomEdge ? parent.top : undefined + bottom: root.edge != Qt.TopEdge ? parent.bottom : undefined } + color: Theme.viewBackgroundColor + clip: true + width: root.contentItem ? Math.min(root.contentItem.implicitWidth, root.width - Units.gridUnit * 2) : 0 + height: root.contentItem ? Math.min(root.contentItem.implicitHeight, root.height - Units.gridUnit * 2) : 0 } - ] + LinearGradient { + width: Units.gridUnit/2 + height: Units.gridUnit/2 + anchors { + right: root.edge == Qt.RightEdge ? drawerPage.left : (root.edge == Qt.LeftEdge ? undefined : parent.right) + left: root.edge == Qt.LeftEdge ? drawerPage.right : (root.edge == Qt.RightEdge ? undefined : parent.left) + top: root.edge == Qt.TopEdge ? drawerPage.bottom : (root.edge == Qt.BottomEdge ? undefined : parent.top) + bottom: root.edge == Qt.BottomEdge ? drawerPage.top : (root.edge == Qt.TopEdge ? undefined : parent.bottom) + } - transitions: [ - Transition { - //Exclude Dragging - to: "Open,Closed" - NumberAnimation { - id: transitionAnim - properties: "x" - duration: Units.longDuration - easing.type: Easing.InOutQuad + opacity: root.position == 0 ? 0 : 1 + start: Qt.point(0, 0) + end: (root.edge == Qt.RightEdge || root.edge == Qt.LeftEdge) ? Qt.point(Units.gridUnit/2, 0) : Qt.point(0, Units.gridUnit/2) + gradient: Gradient { + GradientStop { + position: 0.0 + color: root.edge == Qt.LeftEdge ? Qt.rgba(0, 0, 0, 0.3) : "transparent" + } + GradientStop { + position: root.edge == Qt.LeftEdge ? 0.3 : 0.7 + color: Qt.rgba(0, 0, 0, 0.15) + } + GradientStop { + position: 1.0 + color: root.edge == Qt.LeftEdge ? "transparent" : Qt.rgba(0, 0, 0, 0.3) + } + } + Behavior on opacity { + NumberAnimation { + duration: Units.longDuration + easing.type: Easing.InOutQuad + } } } - ] + } } } } - |