diff options
Diffstat (limited to 'qt-mobile/qml/mobilecomponents/IconGrid.qml')
-rw-r--r-- | qt-mobile/qml/mobilecomponents/IconGrid.qml | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/qt-mobile/qml/mobilecomponents/IconGrid.qml b/qt-mobile/qml/mobilecomponents/IconGrid.qml new file mode 100644 index 000000000..f3f8f1c09 --- /dev/null +++ b/qt-mobile/qml/mobilecomponents/IconGrid.qml @@ -0,0 +1,239 @@ +/* + Copyright 2010 Marco Martin <notmart@gmail.com> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +import QtQuick 2.1 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.mobilecomponents 0.2 +import org.kde.plasma.mobilecomponents.private 0.2 + +Item { + id: main + + property Component delegate + property QtObject model + + property int pageSize: Math.floor(iconView.width/main.delegateWidth)*Math.floor(iconView.height/main.delegateHeight) + property int delegateWidth: Units.iconSizes.huge + Units.gridUnit*2 + property int delegateHeight: Units.iconSizes.huge + Units.gridUnit*2 + property alias currentPage: iconView.currentIndex + property int pagesCount: Math.ceil(model.count/pageSize) + property int count: model.count + property alias contentX: iconView.contentX + clip: true + + function positionViewAtIndex(index) + { + iconView.positionViewAtIndex(index / pageSize, ListView.Beginning) + } + + Timer { + id: resizeTimer + running: true + interval: 100 + onTriggered: { + main.pageSize = Math.floor(iconView.width/main.delegateWidth)*Math.floor(iconView.height/main.delegateHeight) + if (iconView.currentItem) { + iconView.currentItem.width = iconView.width + iconView.currentItem.height = iconView.height + } + } + } + + ListView { + id: iconView + objectName: "iconView" + pressDelay: 200 + cacheBuffer: 100 + highlightMoveDuration: 250 + anchors.fill: parent + onWidthChanged: resizeTimer.restart() + onHeightChanged: resizeTimer.restart() + + model: main.model ? Math.ceil(main.model.count/main.pageSize) : 0 + highlightRangeMode: ListView.StrictlyEnforceRange + orientation: ListView.Horizontal + snapMode: ListView.SnapOneItem + boundsBehavior: Flickable.DragOverBounds + + signal clicked(string url) + + delegate: Component { + Item { + id: delegatePage + //Explicitly *not* bind the properties for performance reasons + Component.onCompleted: { + width = iconView.width + height = iconView.height + //iconView.cacheBuffer = iconView.width + } + + Flow { + id: iconFlow + width: iconRepeater.suggestedWidth + + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + bottom: parent.bottom + } + property int orientation: ListView.Horizontal + + PagedProxyModel { + id: pagedProxyModel + sourceModel: main.model + currentPage: model.index + pageSize: main.pageSize + } + Repeater { + id: iconRepeater + model: pagedProxyModel + property int columns: Math.min(count, Math.floor(delegatePage.width/main.delegateWidth)) + property int suggestedWidth: main.delegateWidth*columns + //property int suggestedHeight: main.delegateHeight*Math.floor(count/columns) + + delegate: main.delegate + } + } + } + } + } + + + Loader { + id: scrollArea + visible: main.model && Math.ceil(main.model.count/main.pageSize) > 1 + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + } + height: Math.max( 16, iconView.height - Math.floor(iconView.height/delegateHeight)*delegateHeight) + + property int pageCount: main.model ? Math.ceil(main.model.count/main.pageSize) : 0 + + sourceComponent: pageCount > 1 ? ((pageCount * 20 > width) ? scrollDotComponent : dotsRow) : undefined + function setViewIndex(index) + { + //animate only if near + if (Math.abs(iconView.currentIndex - index) > 1) { + iconView.positionViewAtIndex(index, ListView.Beginning) + } else { + iconView.currentIndex = index + } + } + Component { + id: scrollDotComponent + MouseArea { + anchors.fill: parent + property int pendingIndex: 0 + Rectangle { + id: barRectangle + color: Theme.textColor + opacity: 2.05 + height: 4 + radius: 2 + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + leftMargin: (parent.width/pageCount/2) + rightMargin: (parent.width/pageCount/2) + } + } + Rectangle { + color: Theme.textColor + height: 8 + width: height + radius: 4 + anchors.verticalCenter: parent.verticalCenter + x: parent.width/(pageCount/(iconView.currentIndex+1)) - (parent.width/pageCount/2) - 4 + Behavior on x { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + function setViewIndexFromMouse(x) + { + pendingIndex = Math.min(pageCount, + Math.round(pageCount / (barRectangle.width / Math.max(x - barRectangle.x, 1)))) + viewPositionTimer.restart() + } + onPressed: setViewIndexFromMouse(mouse.x) + onPositionChanged: setViewIndexFromMouse(mouse.x) + + Timer { + id: viewPositionTimer + interval: 200 + onTriggered: setViewIndex(pendingIndex) + } + } + } + Component { + id: dotsRow + + Item { + Row { + anchors.centerIn: parent + spacing: 20 + + Repeater { + model: scrollArea.pageCount + + + Rectangle { + width: 6 + height: 6 + scale: iconView.currentIndex == index ? 1.5 : 1 + radius: 5 + smooth: true + opacity: iconView.currentIndex == index ? 0.8: 0.4 + color: Theme.textColor + + Behavior on scale { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + + MouseArea { + anchors { + fill: parent + margins: -10 + } + + onClicked: { + setViewIndex(index) + } + } + } + } + } + } + } + } +} |