i changed the code a bit and ended up with this:
import QtQuick 2.5
Rectangle {
id: timePicker
color: "#fff"
clip: true
property int numberOfItems: 7
property string fontFamily
// property var time: ({hour: 0, minute: 0})
property int hour:0
property int minute:0
property int space: 10
Rectangle {
width: parent.width
height: 1
y: (parent.height - listViewHour.delegateHeight) / 2
color: "#D0D0D0"
}
Rectangle {
width: parent.width
height: 1
y: (parent.height - listViewHour.delegateHeight) / 2 + listViewHour.delegateHeight
color: "#D0D0D0"
}
ListView {
id: listViewHour
x: (parent.width>>2) - (space>>1)
width: parent.width>>2
y: -parent.height * 0.5
height: parent.height * 2
property int delegateHeight: height / numberOfItems
model: 24
spacing: 1
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: (height - delegateHeight) / 2
preferredHighlightEnd: (height + delegateHeight) / 2
delegate: Item {
id: contentItem
width: listViewHour.width
height: listViewHour.delegateHeight
Rectangle {
anchors.fill: parent
color: "#3333ee33"
visible: false
}
Text {
id: innerText
property int hour: index
text: leadingZero(hour)
// anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter
anchors.right:parent.right
font.pixelSize: listViewHour.delegateHeight * 0.8
font.family: fontFamily
color: contentItem.ListView.isCurrentItem ? "black" : "#999"
transform: [
Rotation {
origin.x: innerText.width / 2
origin.y: innerText.height / 2
axis { x: 1; y: 0; z: 0 }
angle: {
var middle = contentItem.ListView.view.contentY - contentItem.y + contentItem.ListView.view.height / 2
var calculated = (middle - contentItem.height / 2) / contentItem.height * 40
if (calculated < -90)
return -90
else if (calculated > 90)
return 90
else
return calculated
}
},
Scale {
origin.x: innerText.width
origin.y: innerText.height / 2
xScale: {
// scaled 1 in middle position -> 0 when reaching edges
var scaled = (contentItem.y - contentItem.ListView.view.contentY + contentItem.height * 0.5) / contentItem.ListView.view.height * 2
if (scaled > 1) scaled = 2 - scaled
return Math.max(0, scaled)
}
yScale: xScale
},
Translate {
y: {
var scaled = (contentItem.y - contentItem.ListView.view.contentY + contentItem.height * 0.5) / contentItem.ListView.view.height * 2
scaled = Math.max(0, scaled)
scaled = 1 - scaled
return scaled * scaled * scaled * contentItem.height * 3
}
}
]
}
}
Component.onCompleted: {
// Scrolls to middle of list
// positionViewAtIndex(model * 0.5 - (listView.numberOfItems > 2 ? 1 : 0), ListView.SnapPosition)
}
onMovementEnded: {
hour = currentIndex
console.debug("TIME IS:", hour + ":" + minute)
// timePicker.time = {hour: hour, minute: minute}
}
}
//-- :
Rectangle {
anchors.centerIn: parent
anchors.verticalCenterOffset: -14
width:8
height:8
color:"black"
radius: 4
}
Rectangle {
anchors.centerIn: parent
anchors.verticalCenterOffset: 6
width:8
height:8
color:"black"
radius: 4
}
//-- minutes
ListView {
id: listViewMinute
x: (parent.width>>1) + (space>>1)
width: parent.width>>2
y: -parent.height * 0.5
height: parent.height * 2
property int delegateHeight: height / numberOfItems
model: (65/5)
spacing: 1
highlightRangeMode: ListView.StrictlyEnforceRange
preferredHighlightBegin: (height - delegateHeight) / 2
preferredHighlightEnd: (height + delegateHeight) / 2
delegate: Item {
id: contentItem2
width: listViewMinute.width
height: listViewMinute.delegateHeight
Rectangle {
anchors.fill: parent
color: "#3333ee33"
visible: false
}
Text {
id: innerText2
property int minute: (index*5) % 60
text: leadingZero(minute)
// anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
font.pixelSize: listViewMinute.delegateHeight * 0.8
font.family: fontFamily
color: contentItem2.ListView.isCurrentItem ? "black" : "#999"
transform: [
Rotation {
origin.x: innerText2.width / 2
origin.y: innerText2.height / 2
axis { x: 1; y: 0; z: 0 }
angle: {
var middle = contentItem2.ListView.view.contentY - contentItem2.y + contentItem2.ListView.view.height / 2
var calculated = (middle - contentItem2.height / 2) / contentItem2.height * 40
if (calculated < -90)
return -90
else if (calculated > 90)
return 90
else
return calculated
}
},
Scale {
origin.x:0
origin.y: innerText2.height / 2
xScale: {
// scaled 1 in middle position -> 0 when reaching edges
var scaled = (contentItem2.y - contentItem2.ListView.view.contentY + contentItem2.height * 0.5) / contentItem2.ListView.view.height * 2
if (scaled > 1) scaled = 2 - scaled
return Math.max(0, scaled)
}
yScale: xScale
},
Translate {
y: {
var scaled = (contentItem2.y - contentItem2.ListView.view.contentY + contentItem2.height * 0.5) / contentItem2.ListView.view.height * 2
scaled = Math.max(0, scaled)
scaled = 1 - scaled
return scaled * scaled * scaled * contentItem2.height * 3
}
}
]
}
}
Component.onCompleted: {
// Scrolls to middle of list
// positionViewAtIndex(model * 0.5 - (listView.numberOfItems > 2 ? 1 : 0), ListView.SnapPosition)
}
onMovementEnded: {
minute = (currentIndex * 5) % 60
console.debug("TIME IS:", hour + ":" + minute)
// timePicker.time = {hour: hour, minute: minute}
}
}
function setTime(newTime) {
// listViewHour.positionViewAtIndex(newTime && newTime.hour * 4 + newTime.minute / 15 || 0, ListView.Center)
timePicker.time = newTime
}
function leadingZero(number) {
return ('00' + number).slice(-2)
}
}