mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	- Fixes interactivity in context drawer. - These are mostly cleanups that have been done pre-merge of these components. This now is the state of master in plasma-mobile. - makes navigation a bit more intuitive Signed-off-by: Sebastian Kügler <sebas@kde.org>
		
			
				
	
	
		
			238 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			QML
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
	
		
			8.6 KiB
		
	
	
	
		
			QML
		
	
	
	
	
	
/*
 | 
						|
    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: Units.gridUnit * 8
 | 
						|
        highlightMoveDuration: Units.shortDuration
 | 
						|
        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
 | 
						|
                    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: Units.shortDuration
 | 
						|
                            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: units.gridUnit
 | 
						|
 | 
						|
                    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: units.shortDuration
 | 
						|
                                    easing.type: Easing.InOutQuad
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                            Behavior on opacity {
 | 
						|
                                NumberAnimation {
 | 
						|
                                    duration: units.shortDuration
 | 
						|
                                    easing.type: Easing.InOutQuad
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
 | 
						|
                            MouseArea {
 | 
						|
                                anchors {
 | 
						|
                                    fill: parent
 | 
						|
                                    margins: Units.gridUnit / 2
 | 
						|
                                }
 | 
						|
 | 
						|
                                onClicked: {
 | 
						|
                                    setViewIndex(index)
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |