Kirigami-addons

TimePicker.qml
1// SPDX-FileCopyrightText: 2021 Han Young <hanyoung@protonmail.com>
2// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
3// SPDX-License-Identifier: LGPL-2.1-or-later
4
5import QtQuick 2.15
6import QtQuick.Controls 2.15
7import org.kde.kirigami 2.20 as Kirigami
8import QtQuick.Layouts 1.15
9import org.kde.kirigamiaddons.dateandtime 1.0
10
11/**
12 * A large time picker
13 * Represented as a clock provides a very visual way for a user
14 * to set and visulise a time being chosen
15 */
16RowLayout {
17 id: root
18
19 /**
20 * This property holds the current hours selected. This is a number between 0 and 23.
21 */
22 property int hours
24 /**
25 * This property holds the current minutes selected. This is a number between 0 and 59.
26 */
27 property int minutes
28
29 property bool _pm: false
30
31 property bool _init: false
32
33 readonly property bool _isAmPm: Qt.locale().timeFormat().includes("AP")
34
35 implicitHeight: Kirigami.Units.gridUnit * 5
36 implicitWidth: Kirigami.Units.gridUnit * 10
37
38 Component.onCompleted: {
39 hoursTumbler.currentIndex = (_isAmPm && hours > 12 ? hours - 12 : hours);
40 minutesTumbler.currentIndex = minutes;
41 if (_isAmPm) {
42 root._pm = hours > 12 ? 1 : 0;
43 amPmTumbler.currentIndex = _pm;
44 }
45
46 // Avoid initialisation bug where thumbler are by default initialised
47 // to currentIndex 0
48 _init = true;
49 }
50
51 function formatText(count, modelData) {
52 var data = count === 12 && modelData === 0 ? 12 : modelData;
53 return data.toString().length < 2 ? "0" + data : data;
54 }
55
56 FontMetrics {
57 id: fontMetrics
58 }
59
60 Component {
61 id: delegateComponent
62 Label {
63 id: delegate
64
65 text: formatText(Tumbler.tumbler.count, modelData)
66 opacity: 1.0 - Math.abs(Tumbler.displacement) / (Tumbler.tumbler.visibleItemCount / 2)
67 horizontalAlignment: Text.AlignHCenter
68 verticalAlignment: Text.AlignVCenter
69 font.pixelSize: fontMetrics.font.pixelSize * 1.25
70 Accessible.ignored: true
71
72 Rectangle {
73 anchors.fill: parent
74 color: 'transparent'
75 radius: Kirigami.Units.mediumSpacing
76 border {
77 width: delegate === Tumbler.tumbler.currentItem ? 1 : 0
78 color: Kirigami.Theme.highlightColor
79 }
80 }
81 }
82 }
83
84 Item {
85 Layout.fillWidth: true
86 }
87
88 Tumbler {
89 id: hoursTumbler
90 Layout.preferredHeight: Kirigami.Units.gridUnit * 10
91 model: _isAmPm ? 12 : 24
92 delegate: delegateComponent
93 visibleItemCount: 5
94 onCurrentIndexChanged: if (_init) {
95 hours = currentIndex + (_isAmPm && _pm ? 12 : 0)
96 }
97 Accessible.name: if (!_isAmPm) {
98 i18ndc("kirigami-addons6", "time in hour in 24h format", "%1 hours", root.hours)
99 } else if (_isAmPm && _pm) {
100 i18ndc("kirigami-addons6", "time in hour (PM)", "%1 PM", currentIndex + 12)
101 } else {
102 i18ndc("kirigami-addons6", "time in hour (AM)", "%1 AM", currentIndex)
103 }
104 Accessible.role: Accessible.Dial
105 Accessible.onDecreaseAction: hoursTumbler.currentIndex = (hoursTumbler.currentIndex + hoursTumbler.model - 1) % hoursTumbler.model
106 Accessible.onIncreaseAction: hoursTumbler.currentIndex = (hoursTumbler.currentIndex + 1) % hoursTumbler.model
107 focus: true
108 }
109
110 Label {
111 Layout.alignment: Qt.AlignCenter
112 text: i18ndc("kirigami-addons6", "Time separator", ":")
113 font.pointSize: Kirigami.Theme.defaultFont.pointSize * 1.3
114 Accessible.ignored: true
115 }
116
117 Tumbler {
118 id: minutesTumbler
119 Layout.preferredHeight: Kirigami.Units.gridUnit * 10
120 model: 60
121 delegate: delegateComponent
122 visibleItemCount: 5
123 onCurrentIndexChanged: if (_init) {
124 minutes = currentIndex;
125 }
126
127 Accessible.name: i18ndc("kirigami-addons6", "number of minutes", "%1 minutes", root.minutes)
128 Accessible.role: Accessible.Dial
129 Accessible.onDecreaseAction: minutesTumbler.currentIndex = (minutesTumbler.currentIndex + 59) % 60
130 Accessible.onIncreaseAction: minutesTumbler.currentIndex = (minutesTumbler.currentIndex + 1) % 60
131 }
132
133 Tumbler {
134 id: amPmTumbler
135 visible: _isAmPm
136 Layout.preferredHeight: Kirigami.Units.gridUnit * 10
137 model: [Qt.locale().amText, Qt.locale().pmText]
138 Accessible.name: currentItem.text
139 Accessible.role: Accessible.CheckBox
140 Accessible.ignored: !_isAmPm
141 Accessible.onPressAction: amPmTumbler.currentIndex = (amPmTumbler.currentIndex + 1) % 2
142 Accessible.onToggleAction: amPmTumbler.currentIndex = (amPmTumbler.currentIndex + 1) % 2
143 delegate: delegateComponent
144 visibleItemCount: 5
145 onCurrentIndexChanged: if (_isAmPm && _init) {
146 _pm = currentIndex;
147 hours = (hours + 12) % 24;
148 }
149 }
150
151 Item {
152 Layout.fillWidth: true
153 }
154}
QString i18ndc(const char *domain, const char *context, const char *text, const TYPE &arg...)
AlignHCenter
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:16:11 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.