Warning, /pim/merkuro/src/calendar/qml/Controls/DateControls/TimePicker.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2021 Claudio Cambra <claudio.cambra@gmail.com>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 import QtQuick 2.15
0005 import QtQuick.Controls 2.15 as QQC2
0006 import QtQuick.Layouts 1.15
0007 import org.kde.kirigami 2.15 as Kirigami
0008 
0009 Item {
0010     id: timePicker
0011 
0012     signal done()
0013     signal timeChanged(int hours, int minutes, int seconds)
0014     signal minuteMultiplesAboutToChange(int minuteMultiples)
0015 
0016     anchors.fill: parent
0017 
0018     property int hours
0019     property int minutes
0020     property int seconds
0021 
0022     property int minuteMultiples: 5
0023     property bool secondsPicker: false
0024 
0025     onMinutesChanged: {
0026         if (minutes % minuteMultiples !== 0) {
0027             minuteMultiplesAboutToChange(minuteMultiples);
0028             minuteMultiples = 1;
0029         }
0030     }
0031 
0032     function wheelHandler(parent, wheel) {
0033         if(parent.currentIndex == parent.count - 1) {
0034             wheel.angleDelta.y < 0 ? parent.currentIndex = 0 : parent.currentIndex -= 1;
0035         } else if(parent.currentIndex == 0) {
0036             wheel.angleDelta.y < 0 ? parent.currentIndex += 1 : parent.currentIndex = parent.count - 1;
0037         } else {
0038             wheel.angleDelta.y < 0 ? parent.currentIndex += 1 : parent.currentIndex -= 1;
0039         }
0040     }
0041 
0042     ColumnLayout {
0043         anchors.fill: parent
0044         spacing: 0
0045 
0046         RowLayout {
0047             Layout.fillWidth: true
0048             Layout.margins: Kirigami.Units.largeSpacing
0049             QQC2.Label {
0050                 text: i18n("Min. Interval:")
0051             }
0052             QQC2.SpinBox {
0053                 Layout.fillWidth: true
0054                 from: 1
0055                 value: minuteMultiples
0056                 onValueChanged: {
0057                     minuteMultiplesAboutToChange(minuteMultiples);
0058                     minuteMultiples = value;
0059                 }
0060             }
0061         }
0062 
0063         Item {
0064             Layout.fillWidth: true
0065             Layout.fillHeight: true
0066             GridLayout {
0067                 id: tumblerLayout
0068                 anchors.fill: parent
0069                 columns: timePicker.secondsPicker ? 5 : 3
0070                 rows: 3
0071 
0072                 QQC2.ToolButton {
0073                     Layout.fillWidth: true
0074                     Layout.row: 1
0075                     Layout.column: 0
0076                     icon.name: "go-up"
0077                     enabled: hourView.currentIndex != 0
0078                     onClicked: hourView.currentIndex -= 1
0079                     autoRepeat: true
0080                 }
0081                 QQC2.ToolButton {
0082                     Layout.fillWidth: true
0083                     Layout.row: 1
0084                     Layout.column: 2
0085                     icon.name: "go-up"
0086                     enabled: minuteView.currentIndex != 0
0087                     onClicked: minuteView.currentIndex -= 1
0088                     autoRepeat: true
0089                 }
0090                 QQC2.ToolButton {
0091                     Layout.fillWidth: true
0092                     Layout.row: 1
0093                     Layout.column: 4
0094                     icon.name: "go-up"
0095                     enabled: secondsView.currentIndex != 0
0096                     onClicked: secondsView.currentIndex -= 1
0097                     visible: timePicker.secondsPicker
0098                     autoRepeat: true
0099                 }
0100 
0101                 QQC2.Tumbler {
0102                     id: hourView
0103                     wrap: true
0104 
0105                     model: 24
0106                     currentIndex: timePicker.hours
0107                     onCurrentIndexChanged: timePicker.hours = currentIndex
0108 
0109                     delegate: Kirigami.Heading {
0110                         property int thisIndex: index
0111 
0112                         horizontalAlignment: Text.AlignHCenter
0113                         verticalAlignment: Text.AlignVCenter
0114                         opacity: hourView.currentIndex == thisIndex ? 1 : 0.7
0115                         font.bold: hourView.currentIndex == thisIndex
0116                         text: modelData < 10 ? String(modelData).padStart(2, "0") : modelData
0117 
0118                         MouseArea {
0119                             anchors.fill: parent
0120                             onClicked: hourView.currentIndex = parent.thisIndex
0121                         }
0122                     }
0123 
0124                     Layout.fillWidth: true
0125                     Layout.fillHeight: true
0126                     Layout.row: 2
0127                     Layout.column: 0
0128 
0129                     MouseArea {
0130                         anchors.fill: parent
0131                         onWheel: timePicker.wheelHandler(parent, wheel)
0132                     }
0133                 }
0134 
0135                 Kirigami.Heading {
0136                     horizontalAlignment: Text.AlignHCenter
0137                     verticalAlignment: Text.AlignVCenter
0138                     text: ":"
0139                     Layout.row: 2
0140                     Layout.column: 1
0141                 }
0142 
0143                 QQC2.Tumbler {
0144                     id: minuteView
0145 
0146                     property int selectedIndex: 0
0147 
0148                     wrap: true
0149 
0150                     currentIndex: timePicker.minutes
0151                     onCurrentIndexChanged: timePicker.minutes = currentIndex * timePicker.minuteMultiples
0152 
0153                     model: 60 / timePicker.minuteMultiples // So we can adjust the minute intervals selectable by the user (model goes up to 59)
0154                     onModelChanged: currentIndex = selectedIndex / timePicker.minuteMultiples
0155 
0156                     delegate: Kirigami.Heading {
0157                         property int thisIndex: index
0158                         property int minuteToDisplay: modelData * timePicker.minuteMultiples
0159 
0160                         horizontalAlignment: Text.AlignHCenter
0161                         verticalAlignment: Text.AlignVCenter
0162                         opacity: minuteView.currentIndex == thisIndex ? 1 : 0.7
0163                         font.bold: minuteView.currentIndex == thisIndex
0164                         text: minuteToDisplay < 10 ? String(minuteToDisplay).padStart(2, "0") : minuteToDisplay
0165 
0166                         MouseArea {
0167                             anchors.fill: parent
0168                             onClicked: minuteView.currentIndex = parent.thisIndex
0169                         }
0170                     }
0171 
0172                     Layout.fillWidth: true
0173                     Layout.fillHeight: true
0174 
0175                     // We don't want our selected time to get reset when we update minuteMultiples, on which the model depends
0176                     Connections { // Gets called before model regen
0177                         target: timePicker
0178 
0179                         function onMinuteMultiplesAboutToChange() {
0180                             minuteView.selectedIndex = minuteView.currentIndex * timePicker.minuteMultiples;
0181                         }
0182 
0183                         function onMinutesChanged() {
0184                             minuteView.currentIndex = minutes / timePicker.minuteMultiples;
0185                         }
0186                     }
0187 
0188                     MouseArea {
0189                         anchors.fill: parent
0190                         onWheel: timePicker.wheelHandler(parent, wheel)
0191                     }
0192                 }
0193 
0194                 Kirigami.Heading {
0195                     horizontalAlignment: Text.AlignHCenter
0196                     verticalAlignment: Text.AlignVCenter
0197                     visible: timePicker.secondsPicker
0198                     font.bold: true
0199                     text: ":"
0200                     Layout.row: 2
0201                     Layout.column: 3
0202                 }
0203 
0204                 QQC2.Tumbler {
0205                     id: secondsView
0206                     Layout.fillWidth: true
0207                     Layout.fillHeight: true
0208                     Layout.row: 2
0209                     Layout.column: 4
0210                     visible: timePicker.secondsPicker
0211                     model: 60
0212 
0213                     currentIndex: timePicker.seconds
0214                     onCurrentIndexChanged: timePicker.seconds = currentIndex
0215 
0216                     delegate: Kirigami.Heading {
0217                         property int thisIndex: index
0218 
0219                         horizontalAlignment: Text.AlignHCenter
0220                         verticalAlignment: Text.AlignVCenter
0221                         opacity: secondsView.currentIndex == thisIndex ? 1 : 0.7
0222                         font.bold: secondsView.currentIndex == thisIndex
0223                         text: modelData < 10 ? String(modelData).padStart(2, "0") : modelData
0224 
0225                         MouseArea {
0226                             anchors.fill: parent
0227                             onClicked: secondsView.currentIndex = parent.thisIndex
0228                         }
0229                     }
0230 
0231                     MouseArea {
0232                         anchors.fill: parent
0233                         onWheel: timePicker.wheelHandler(parent, wheel)
0234                     }
0235                 }
0236 
0237                 QQC2.ToolButton {
0238                     Layout.fillWidth: true
0239                     Layout.row: 3
0240                     Layout.column: 0
0241                     icon.name: "go-down"
0242                     enabled: hourView.currentIndex < hourView.count - 1
0243                     onClicked: hourView.currentIndex += 1
0244                     autoRepeat: true
0245                 }
0246                 QQC2.ToolButton {
0247                     Layout.fillWidth: true
0248                     Layout.row: 3
0249                     Layout.column: 2
0250                     icon.name: "go-down"
0251                     enabled: minuteView.currentIndex < minuteView.count - 1
0252                     onClicked: minuteView.currentIndex += 1
0253                     autoRepeat: true
0254                 }
0255                 QQC2.ToolButton {
0256                     Layout.fillWidth: true
0257                     Layout.row: 3
0258                     Layout.column: 4
0259                     icon.name: "go-down"
0260                     enabled: secondsView.currentIndex < secondsView.count - 1
0261                     onClicked: secondsView.currentIndex += 1
0262                     visible: timePicker.secondsPicker
0263                     autoRepeat: true
0264                 }
0265             }
0266 
0267             Rectangle {
0268                 anchors.left: parent.left
0269                 anchors.right: parent.right
0270                 anchors.verticalCenter: tumblerLayout.verticalCenter
0271                 height: hourView.currentItem.implicitHeight
0272                 z: -1
0273 
0274                 color: Kirigami.Theme.alternateBackgroundColor
0275 
0276                 border.width: 1
0277                 border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.2)
0278             }
0279         }
0280     }
0281 }
0282