diff options
Diffstat (limited to 'prototype_2016/third_party/qml-material/src/components')
14 files changed, 0 insertions, 2151 deletions
diff --git a/prototype_2016/third_party/qml-material/src/components/ActionButton.qml b/prototype_2016/third_party/qml-material/src/components/ActionButton.qml deleted file mode 100644 index c286663..0000000 --- a/prototype_2016/third_party/qml-material/src/components/ActionButton.qml +++ /dev/null | |||
@@ -1,130 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import QtQuick.Controls 1.3 as Controls | ||
13 | import QtQuick.Controls.Styles 1.3 as ControlStyles | ||
14 | import Material 0.3 | ||
15 | import QtGraphicalEffects 1.0 | ||
16 | |||
17 | /*! | ||
18 | \qmltype ActionButton | ||
19 | \inqmlmodule Material | ||
20 | |||
21 | \brief A floating action button. | ||
22 | |||
23 | An ActionButton is a floating action button that provides a primary action | ||
24 | on the current page. | ||
25 | */ | ||
26 | Controls.Button { | ||
27 | id: button | ||
28 | |||
29 | visible: action ? action.visible : true | ||
30 | |||
31 | /*! | ||
32 | The color of the action button. By default, this is the accent color of your | ||
33 | app as defined by \l Theme::accentColor. | ||
34 | */ | ||
35 | property color backgroundColor: Theme.accentColor | ||
36 | |||
37 | /*! | ||
38 | \internal | ||
39 | The elevation of the icon. This will be higher for a white background color. | ||
40 | */ | ||
41 | property int elevation: backgroundColor == "white" ? 0 : 1 | ||
42 | |||
43 | /*! | ||
44 | The color of the icon displayed on the action button. By default, this is | ||
45 | automatically selected based on the \l backgroundColor. | ||
46 | */ | ||
47 | property color iconColor: Theme.lightDark(button.backgroundColor, | ||
48 | Theme.light.iconColor, | ||
49 | Theme.dark.iconColor) | ||
50 | |||
51 | /*! | ||
52 | The name of the icon to display in the action button, selected from the Material | ||
53 | Design icon collection by Google. | ||
54 | */ | ||
55 | property string iconName: action ? action.iconName : "" | ||
56 | |||
57 | /*! | ||
58 | Floating action buttons come in two sizes: | ||
59 | |||
60 | \list | ||
61 | \li \b {Default size} - for most use cases | ||
62 | \li \b {Mini size} - only used to create visual continuity with other screen elements | ||
63 | \endlist | ||
64 | */ | ||
65 | property bool isMiniSize: false | ||
66 | |||
67 | style: ControlStyles.ButtonStyle { | ||
68 | padding { | ||
69 | left: 0 | ||
70 | right: 0 | ||
71 | top: 0 | ||
72 | bottom: 0 | ||
73 | } | ||
74 | |||
75 | background: Item { | ||
76 | RectangularGlow { | ||
77 | |||
78 | anchors.centerIn: parent | ||
79 | anchors.verticalCenterOffset: elevation == 1 ? 1.5 * Units.dp | ||
80 | : 1 * Units.dp | ||
81 | |||
82 | width: parent.width | ||
83 | height: parent.height | ||
84 | |||
85 | glowRadius: elevation == 1 ? 0.75 * Units.dp : 0.3 * Units.dp | ||
86 | opacity: elevation == 1 ? 0.6 : 0.3 | ||
87 | spread: elevation == 1 ? 0.7 : 0.85 | ||
88 | color: "black" | ||
89 | cornerRadius: height/2 | ||
90 | } | ||
91 | |||
92 | View { | ||
93 | anchors.fill: parent | ||
94 | radius: width/2 | ||
95 | |||
96 | backgroundColor: button.backgroundColor | ||
97 | |||
98 | tintColor: control.pressed || | ||
99 | (control.focus && !button.elevation) || | ||
100 | (control.hovered && !button.elevation) ? | ||
101 | Qt.rgba(0,0,0, control.pressed ? 0.1 : 0.05) : "transparent" | ||
102 | |||
103 | Ink { | ||
104 | id: mouseArea | ||
105 | anchors.fill: parent | ||
106 | Connections { | ||
107 | target: control.__behavior | ||
108 | onPressed: mouseArea.onPressed(mouse) | ||
109 | onCanceled: mouseArea.onCanceled() | ||
110 | onReleased: mouseArea.onReleased(mouse) | ||
111 | } | ||
112 | |||
113 | circular: true | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | label: Item { | ||
118 | implicitHeight: isMiniSize ? 40 * Units.dp : 56 * Units.dp | ||
119 | implicitWidth: implicitHeight | ||
120 | Icon { | ||
121 | id: icon | ||
122 | |||
123 | anchors.centerIn: parent | ||
124 | name: control.iconName | ||
125 | color: button.iconColor | ||
126 | size: 24 * Units.dp | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/Card.qml b/prototype_2016/third_party/qml-material/src/components/Card.qml deleted file mode 100644 index e778027..0000000 --- a/prototype_2016/third_party/qml-material/src/components/Card.qml +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import Material 0.3 | ||
13 | |||
14 | /*! | ||
15 | \qmltype Card | ||
16 | \inqmlmodule Material | ||
17 | |||
18 | \brief A card is a piece of paper with unique related data that serves as an entry point | ||
19 | to more detailed information. | ||
20 | */ | ||
21 | View { | ||
22 | width: 300 * Units.dp | ||
23 | height: 250 * Units.dp | ||
24 | elevation: flat ? 0 : 1 | ||
25 | |||
26 | property bool flat: false | ||
27 | |||
28 | border.color: flat ? Qt.rgba(0,0,0,0.2) : "transparent" | ||
29 | radius: fullWidth || fullHeight ? 0 : 2 * Units.dp | ||
30 | |||
31 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/DatePicker.qml b/prototype_2016/third_party/qml-material/src/components/DatePicker.qml deleted file mode 100644 index 02b87ab..0000000 --- a/prototype_2016/third_party/qml-material/src/components/DatePicker.qml +++ /dev/null | |||
@@ -1,496 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015 Jordan Neidlinger <JNeidlinger@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import QtQuick.Layouts 1.1 | ||
13 | import QtQuick.Controls 1.3 as Controls | ||
14 | import QtQuick.Controls.Styles.Material 0.1 as MaterialStyle | ||
15 | import QtQuick.Controls.Styles 1.3 | ||
16 | import QtQuick.Controls.Private 1.0 | ||
17 | import Material 0.3 | ||
18 | |||
19 | /*! | ||
20 | \qmltype DatePicker | ||
21 | \inqmlmodule Material | ||
22 | |||
23 | \brief Date Picker provides a simple way to select a valid, formatted date | ||
24 | */ | ||
25 | Controls.Calendar { | ||
26 | |||
27 | /*! | ||
28 | Set to \c true if the picker should lay itself in landscape mode | ||
29 | */ | ||
30 | property bool isLandscape: false | ||
31 | property int dayAreaBottomMargin : 0 | ||
32 | |||
33 | style: CalendarStyle { | ||
34 | gridVisible: false | ||
35 | |||
36 | property int calendarWidth: isLandscape ? 500 * Units.dp : 340 * Units.dp | ||
37 | property int calendarHeight: isLandscape ? 280 * Units.dp : 440 * Units.dp | ||
38 | |||
39 | background: Rectangle { | ||
40 | color: "white" | ||
41 | implicitWidth: calendarWidth | ||
42 | implicitHeight: calendarHeight | ||
43 | } | ||
44 | |||
45 | navigationBar: Rectangle { | ||
46 | height: isLandscape ? calendarHeight + 64 * Units.dp : 96 * Units.dp | ||
47 | width: isLandscape ? calendarWidth / 3 : undefined | ||
48 | color: Theme.accentColor | ||
49 | |||
50 | ColumnLayout { | ||
51 | anchors.verticalCenter: isLandscape ? undefined : parent.verticalCenter | ||
52 | anchors.left: parent.left | ||
53 | anchors.leftMargin: isLandscape ? 16 * Units.dp : 24 * Units.dp | ||
54 | anchors.top: isLandscape ? parent.top : undefined | ||
55 | anchors.topMargin: isLandscape ? 16 * Units.dp : undefined | ||
56 | anchors.right: parent.right | ||
57 | anchors.rightMargin: 36 * Units.dp | ||
58 | spacing: 0 | ||
59 | |||
60 | Label { | ||
61 | font.weight: Font.DemiBold | ||
62 | style: "body2" | ||
63 | color: Qt.rgba(1, 1, 1, 0.7) | ||
64 | text: control.selectedDate.toLocaleString(control.__locale, "yyyy") | ||
65 | } | ||
66 | |||
67 | Label { | ||
68 | id: dayTitle | ||
69 | font.weight: Font.DemiBold | ||
70 | font.pixelSize: 36 * Units.dp | ||
71 | Layout.fillWidth: true | ||
72 | lineHeight: 0.9 | ||
73 | wrapMode: Text.Wrap | ||
74 | color: Theme.dark.textColor | ||
75 | text: control.selectedDate.toLocaleString(control.__locale, "ddd, MMM dd") | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | dayOfWeekDelegate: Rectangle { | ||
81 | color: "transparent" | ||
82 | implicitHeight: 30 * Units.dp | ||
83 | Label { | ||
84 | text: control.__locale.dayName(styleData.dayOfWeek, Locale.NarrowFormat).substring(0, 1) | ||
85 | color: Theme.light.subTextColor | ||
86 | anchors.centerIn: parent | ||
87 | } | ||
88 | } | ||
89 | |||
90 | dayDelegate: Item { | ||
91 | visible: styleData.visibleMonth | ||
92 | |||
93 | Rectangle { | ||
94 | anchors.centerIn: parent | ||
95 | width: 1 * Math.min(parent.width, parent.height) | ||
96 | height: width | ||
97 | |||
98 | color: styleData.selected ? Theme.accentColor : "transparent" | ||
99 | radius: height/2 | ||
100 | } | ||
101 | |||
102 | Label { | ||
103 | text: styleData.date.getDate() | ||
104 | anchors.centerIn: parent | ||
105 | color: styleData.selected | ||
106 | ? "white" : styleData.today | ||
107 | ? Theme.accentColor : "black" | ||
108 | } | ||
109 | } | ||
110 | |||
111 | panel: Item { | ||
112 | id: panelItem | ||
113 | |||
114 | implicitWidth: backgroundLoader.implicitWidth | ||
115 | implicitHeight: backgroundLoader.implicitHeight | ||
116 | |||
117 | property alias navigationBarItem: navigationBarLoader.item | ||
118 | |||
119 | property alias dayOfWeekHeaderRow: dayOfWeekHeaderRow | ||
120 | |||
121 | readonly property int weeksToShow: 6 | ||
122 | readonly property int rows: weeksToShow | ||
123 | readonly property int columns: CalendarUtils.daysInAWeek | ||
124 | |||
125 | // The combined available width and height to be shared amongst each cell. | ||
126 | readonly property real availableWidth: viewContainer.width | ||
127 | readonly property real availableHeight: viewContainer.height | ||
128 | |||
129 | property int hoveredCellIndex: -1 | ||
130 | property int pressedCellIndex: -1 | ||
131 | property int pressCellIndex: -1 | ||
132 | |||
133 | Rectangle { | ||
134 | anchors.fill: parent | ||
135 | color: "transparent" | ||
136 | border.color: gridColor | ||
137 | visible: control.frameVisible | ||
138 | } | ||
139 | |||
140 | Item { | ||
141 | id: container | ||
142 | anchors.fill: parent | ||
143 | anchors.margins: control.frameVisible ? 1 : 0 | ||
144 | |||
145 | Loader { | ||
146 | id: backgroundLoader | ||
147 | anchors.fill: parent | ||
148 | sourceComponent: background | ||
149 | } | ||
150 | |||
151 | Loader { | ||
152 | id: navigationBarLoader | ||
153 | anchors.left: parent.left | ||
154 | anchors.right: isLandscape ? undefined: parent.right | ||
155 | anchors.top: parent.top | ||
156 | anchors.bottom: isLandscape ? parent.bottom : undefined | ||
157 | sourceComponent: navigationBar | ||
158 | active: control.navigationBarVisible | ||
159 | |||
160 | property QtObject styleData: QtObject { | ||
161 | readonly property string title: control.__locale.standaloneMonthName(control.visibleMonth) | ||
162 | + new Date(control.visibleYear, control.visibleMonth, 1).toLocaleDateString(control.__locale, " yyyy") | ||
163 | } | ||
164 | } | ||
165 | |||
166 | Rectangle { | ||
167 | id: dayOfWeekHeaderRow | ||
168 | anchors.top: control.isLandscape ? parent.top : navigationBarLoader.bottom | ||
169 | anchors.left: control.isLandscape ? navigationBarLoader.right : parent.left | ||
170 | anchors.right: parent.right | ||
171 | width: control.isLandscape ? parent.width / 2 : undefined | ||
172 | height: control.isLandscape ? 72 * Units.dp : 80 * Units.dp | ||
173 | color: "transparent" | ||
174 | |||
175 | IconButton { | ||
176 | iconName: "navigation/chevron_left" | ||
177 | id: previousMonth | ||
178 | anchors.top: parent.top | ||
179 | anchors.topMargin: control.isLandscape ? 12 * Units.dp : 16 * Units.dp | ||
180 | anchors.left: parent.left | ||
181 | anchors.leftMargin: 16 * Units.dp | ||
182 | onClicked: control.showPreviousMonth() | ||
183 | } | ||
184 | |||
185 | IconButton { | ||
186 | iconName: "navigation/chevron_right" | ||
187 | id: nextMonth | ||
188 | anchors.top: parent.top | ||
189 | anchors.topMargin: control.isLandscape ? 12 * Units.dp : 16 * Units.dp | ||
190 | anchors.right: parent.right | ||
191 | anchors.rightMargin: 16 * Units.dp | ||
192 | onClicked: control.showNextMonth() | ||
193 | } | ||
194 | |||
195 | Label { | ||
196 | id: monthHeader | ||
197 | anchors.verticalCenter: previousMonth.verticalCenter | ||
198 | anchors.verticalCenterOffset: -1 * Units.dp | ||
199 | anchors.horizontalCenter: parent.horizontalCenter | ||
200 | font.weight: Font.Black | ||
201 | style: "subheading" | ||
202 | text: control.__locale.standaloneMonthName(control.visibleMonth) + " " + control.visibleYear | ||
203 | } | ||
204 | |||
205 | Row { | ||
206 | id: calenderHeader | ||
207 | anchors.bottom: parent.bottom | ||
208 | anchors.left: parent.left | ||
209 | anchors.leftMargin: (control.weekNumbersVisible ? weekNumbersItem.width : 0) + 8 * Units.dp | ||
210 | anchors.right: parent.right | ||
211 | anchors.rightMargin: 8 * Units.dp | ||
212 | |||
213 | spacing: gridVisible ? __gridLineWidth : 0 | ||
214 | |||
215 | Repeater { | ||
216 | id: repeater | ||
217 | model: CalendarHeaderModel { | ||
218 | locale: control.__locale | ||
219 | } | ||
220 | Loader { | ||
221 | id: dayOfWeekDelegateLoader | ||
222 | sourceComponent: dayOfWeekDelegate | ||
223 | width: __cellRectAt(index).width | ||
224 | |||
225 | readonly property int __index: index | ||
226 | readonly property var __dayOfWeek: dayOfWeek | ||
227 | |||
228 | property QtObject styleData: QtObject { | ||
229 | readonly property alias index: dayOfWeekDelegateLoader.__index | ||
230 | readonly property alias dayOfWeek: dayOfWeekDelegateLoader.__dayOfWeek | ||
231 | } | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | Rectangle { | ||
237 | id: topGridLine | ||
238 | color: __horizontalSeparatorColor | ||
239 | width: control.isLandscape ? parent.width * (2/3) : parent.width | ||
240 | height: __gridLineWidth | ||
241 | visible: gridVisible | ||
242 | anchors.top: dayOfWeekHeaderRow.bottom | ||
243 | anchors.right: control.isLandscape ? parent.right : undefined | ||
244 | } | ||
245 | |||
246 | Row { | ||
247 | id: gridRow | ||
248 | width: weekNumbersItem.width + (control.isLandscape ? (viewContainer.width * (2/3)) : viewContainer.width) - 16 * Units.dp | ||
249 | height: viewContainer.height - dayAreaBottomMargin | ||
250 | anchors.top: topGridLine.bottom | ||
251 | anchors.left: control.isLandscape ? topGridLine.left : parent.left | ||
252 | anchors.leftMargin: 8 * Units.dp | ||
253 | |||
254 | Column { | ||
255 | id: weekNumbersItem | ||
256 | visible: control.weekNumbersVisible | ||
257 | height: viewContainer.height - dayAreaBottomMargin | ||
258 | spacing: gridVisible ? __gridLineWidth : 0 | ||
259 | Repeater { | ||
260 | id: weekNumberRepeater | ||
261 | model: panelItem.weeksToShow | ||
262 | |||
263 | Loader { | ||
264 | id: weekNumberDelegateLoader | ||
265 | height: __cellRectAt(index * panelItem.columns).height | ||
266 | sourceComponent: weekNumberDelegate | ||
267 | |||
268 | readonly property int __index: index | ||
269 | property int __weekNumber: control.__model.weekNumberAt(index) | ||
270 | |||
271 | Connections { | ||
272 | target: control | ||
273 | onVisibleMonthChanged: __weekNumber = control.__model.weekNumberAt(index) | ||
274 | onVisibleYearChanged: __weekNumber = control.__model.weekNumberAt(index) | ||
275 | } | ||
276 | |||
277 | Connections { | ||
278 | target: control.__model | ||
279 | onCountChanged: __weekNumber = control.__model.weekNumberAt(index) | ||
280 | } | ||
281 | |||
282 | property QtObject styleData: QtObject { | ||
283 | readonly property alias index: weekNumberDelegateLoader.__index | ||
284 | readonly property int weekNumber: weekNumberDelegateLoader.__weekNumber | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | Rectangle { | ||
291 | id: separator | ||
292 | anchors.topMargin: - dayOfWeekHeaderRow.height - 1 | ||
293 | anchors.top: weekNumbersItem.top | ||
294 | anchors.bottom: weekNumbersItem.bottom | ||
295 | |||
296 | width: __gridLineWidth | ||
297 | color: __verticalSeparatorColor | ||
298 | visible: control.weekNumbersVisible | ||
299 | } | ||
300 | |||
301 | // Contains the grid lines and the grid itself. | ||
302 | Item { | ||
303 | id: viewContainer | ||
304 | width: (control.isLandscape ? container.width * (2/3) : container.width) - (control.weekNumbersVisible ? weekNumbersItem.width + separator.width : 0) - 16 * Units.dp | ||
305 | height: container.height - (control.isLandscape ? 0 : navigationBarLoader.height) - dayOfWeekHeaderRow.height - topGridLine.height - dayAreaBottomMargin | ||
306 | |||
307 | Repeater { | ||
308 | id: verticalGridLineRepeater | ||
309 | model: panelItem.columns - 1 | ||
310 | delegate: Rectangle { | ||
311 | x: __cellRectAt(index + 1).x - __gridLineWidth | ||
312 | y: 0 | ||
313 | width: __gridLineWidth | ||
314 | height: viewContainer.height | ||
315 | color: gridColor | ||
316 | visible: gridVisible | ||
317 | } | ||
318 | } | ||
319 | |||
320 | Repeater { | ||
321 | id: horizontalGridLineRepeater | ||
322 | model: panelItem.rows - 1 | ||
323 | delegate: Rectangle { | ||
324 | x: 0 | ||
325 | y: __cellRectAt((index + 1) * panelItem.columns).y - __gridLineWidth | ||
326 | width: viewContainer.width | ||
327 | height: __gridLineWidth | ||
328 | color: gridColor | ||
329 | visible: gridVisible | ||
330 | } | ||
331 | } | ||
332 | |||
333 | MouseArea { | ||
334 | id: mouseArea | ||
335 | anchors.fill: parent | ||
336 | |||
337 | hoverEnabled: true | ||
338 | |||
339 | function cellIndexAt(mouseX, mouseY) { | ||
340 | var viewContainerPos = viewContainer.mapFromItem(mouseArea, mouseX, mouseY); | ||
341 | var child = viewContainer.childAt(viewContainerPos.x, viewContainerPos.y); | ||
342 | // In the tests, the mouseArea sometimes gets picked instead of the cells, | ||
343 | // probably because stuff is still loading. To be safe, we check for that here. | ||
344 | return child && child !== mouseArea ? child.__index : -1; | ||
345 | } | ||
346 | |||
347 | onEntered: { | ||
348 | hoveredCellIndex = cellIndexAt(mouseX, mouseY); | ||
349 | if (hoveredCellIndex === undefined) { | ||
350 | hoveredCellIndex = cellIndexAt(mouseX, mouseY); | ||
351 | } | ||
352 | |||
353 | var date = view.model.dateAt(hoveredCellIndex); | ||
354 | if (__isValidDate(date)) { | ||
355 | control.hovered(date); | ||
356 | } | ||
357 | } | ||
358 | |||
359 | onExited: { | ||
360 | hoveredCellIndex = -1; | ||
361 | } | ||
362 | |||
363 | onPositionChanged: { | ||
364 | var indexOfCell = cellIndexAt(mouse.x, mouse.y); | ||
365 | var previousHoveredCellIndex = hoveredCellIndex; | ||
366 | hoveredCellIndex = indexOfCell; | ||
367 | if (indexOfCell !== -1) { | ||
368 | var date = view.model.dateAt(indexOfCell); | ||
369 | if (__isValidDate(date)) { | ||
370 | if (hoveredCellIndex !== previousHoveredCellIndex) | ||
371 | control.hovered(date); | ||
372 | |||
373 | // The date must be different for the pressed signal to be emitted. | ||
374 | if (pressed && date.getTime() !== control.selectedDate.getTime()) { | ||
375 | control.pressed(date); | ||
376 | |||
377 | // You can't select dates in a different month while dragging. | ||
378 | if (date.getMonth() === control.selectedDate.getMonth()) { | ||
379 | control.selectedDate = date; | ||
380 | pressedCellIndex = indexOfCell; | ||
381 | } | ||
382 | } | ||
383 | } | ||
384 | } | ||
385 | } | ||
386 | |||
387 | onPressed: { | ||
388 | pressCellIndex = cellIndexAt(mouse.x, mouse.y); | ||
389 | if (pressCellIndex !== -1) { | ||
390 | var date = view.model.dateAt(pressCellIndex); | ||
391 | pressedCellIndex = pressCellIndex; | ||
392 | if (__isValidDate(date) && (date.getMonth() === control.visibleMonth && date.getFullYear() === control.visibleYear)) { | ||
393 | control.selectedDate = date; | ||
394 | control.pressed(date); | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | |||
399 | onReleased: { | ||
400 | var indexOfCell = cellIndexAt(mouse.x, mouse.y); | ||
401 | if (indexOfCell !== -1) { | ||
402 | // The cell index might be valid, but the date has to be too. We could let the | ||
403 | // selected date validation take care of this, but then the selected date would | ||
404 | // change to the earliest day if a day before the minimum date is clicked, for example. | ||
405 | var date = view.model.dateAt(indexOfCell); | ||
406 | if (__isValidDate(date)) { | ||
407 | control.released(date); | ||
408 | } | ||
409 | } | ||
410 | pressedCellIndex = -1; | ||
411 | } | ||
412 | |||
413 | onClicked: { | ||
414 | var indexOfCell = cellIndexAt(mouse.x, mouse.y); | ||
415 | if (indexOfCell !== -1 && indexOfCell === pressCellIndex) { | ||
416 | var date = view.model.dateAt(indexOfCell); | ||
417 | if (__isValidDate(date)) | ||
418 | control.clicked(date); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | onDoubleClicked: { | ||
423 | var indexOfCell = cellIndexAt(mouse.x, mouse.y); | ||
424 | if (indexOfCell !== -1) { | ||
425 | var date = view.model.dateAt(indexOfCell); | ||
426 | if (__isValidDate(date)) | ||
427 | control.doubleClicked(date); | ||
428 | } | ||
429 | } | ||
430 | |||
431 | onPressAndHold: { | ||
432 | var indexOfCell = cellIndexAt(mouse.x, mouse.y); | ||
433 | if (indexOfCell !== -1 && indexOfCell === pressCellIndex) { | ||
434 | var date = view.model.dateAt(indexOfCell); | ||
435 | if (__isValidDate(date)) | ||
436 | control.pressAndHold(date); | ||
437 | } | ||
438 | } | ||
439 | } | ||
440 | |||
441 | Connections { | ||
442 | target: control | ||
443 | onSelectedDateChanged: view.selectedDateChanged() | ||
444 | } | ||
445 | |||
446 | Repeater { | ||
447 | id: view | ||
448 | |||
449 | property int currentIndex: -1 | ||
450 | |||
451 | model: control.__model | ||
452 | |||
453 | Component.onCompleted: selectedDateChanged() | ||
454 | |||
455 | function selectedDateChanged() { | ||
456 | if (model !== undefined && model.locale !== undefined) { | ||
457 | currentIndex = model.indexAt(control.selectedDate); | ||
458 | } | ||
459 | } | ||
460 | |||
461 | delegate: Loader { | ||
462 | id: delegateLoader | ||
463 | |||
464 | x: __cellRectAt(index).x | ||
465 | y: __cellRectAt(index).y | ||
466 | width: __cellRectAt(index).width | ||
467 | height: __cellRectAt(index).height | ||
468 | sourceComponent: dayDelegate | ||
469 | |||
470 | readonly property int __index: index | ||
471 | readonly property date __date: date | ||
472 | // We rely on the fact that an invalid QDate will be converted to a Date | ||
473 | // whose year is -4713, which is always an invalid date since our | ||
474 | // earliest minimum date is the year 1. | ||
475 | readonly property bool valid: __isValidDate(date) | ||
476 | |||
477 | property QtObject styleData: QtObject { | ||
478 | readonly property alias index: delegateLoader.__index | ||
479 | readonly property bool selected: control.selectedDate.getTime() === date.getTime() | ||
480 | readonly property alias date: delegateLoader.__date | ||
481 | readonly property bool valid: delegateLoader.valid | ||
482 | // TODO: this will not be correct if the app is running when a new day begins. | ||
483 | readonly property bool today: date.getTime() === new Date().setHours(0, 0, 0, 0) | ||
484 | readonly property bool visibleMonth: date.getMonth() === control.visibleMonth | ||
485 | readonly property bool hovered: panelItem.hoveredCellIndex == index | ||
486 | readonly property bool pressed: panelItem.pressedCellIndex == index | ||
487 | // todo: pressed property here, clicked and doubleClicked in the control itself | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | } | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/IconButton.qml b/prototype_2016/third_party/qml-material/src/components/IconButton.qml deleted file mode 100644 index 2c6d27d..0000000 --- a/prototype_2016/third_party/qml-material/src/components/IconButton.qml +++ /dev/null | |||
@@ -1,78 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import Material 0.3 | ||
13 | import Material.Extras 0.1 | ||
14 | |||
15 | /*! | ||
16 | \qmltype IconButton | ||
17 | \inqmlmodule Material | ||
18 | |||
19 | \brief Icon buttons are appropriate for app bars, toolbars, action buttons or toggles. | ||
20 | */ | ||
21 | Item { | ||
22 | id: iconButton | ||
23 | |||
24 | property Action action | ||
25 | property string iconName | ||
26 | property string iconSource: action ? action.iconSource : "icon://" + iconName | ||
27 | property bool hoverAnimation: action ? action.hoverAnimation : false | ||
28 | property alias color: icon.color | ||
29 | property alias size: icon.size | ||
30 | |||
31 | signal clicked | ||
32 | |||
33 | width: icon.width | ||
34 | height: icon.height | ||
35 | enabled: action ? action.enabled : true | ||
36 | opacity: enabled ? 1 : 0.6 | ||
37 | |||
38 | onClicked: { | ||
39 | if (action) action.triggered(icon) | ||
40 | } | ||
41 | |||
42 | Ink { | ||
43 | id: ink | ||
44 | |||
45 | anchors.centerIn: parent | ||
46 | enabled: iconButton.enabled | ||
47 | centered: true | ||
48 | circular: true | ||
49 | |||
50 | width: parent.width + 20 * Units.dp | ||
51 | height: parent.height + 20 * Units.dp | ||
52 | |||
53 | z: 0 | ||
54 | |||
55 | onClicked: { | ||
56 | iconButton.clicked() | ||
57 | } | ||
58 | } | ||
59 | |||
60 | Icon { | ||
61 | id: icon | ||
62 | |||
63 | anchors.centerIn: parent | ||
64 | |||
65 | source: iconButton.iconSource | ||
66 | rotation: iconButton.hoverAnimation ? ink.containsMouse ? 90 : 0 | ||
67 | : 0 | ||
68 | |||
69 | Behavior on rotation { | ||
70 | NumberAnimation { duration: 200 } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | Tooltip { | ||
75 | text: action ? action.name : "" | ||
76 | mouseArea: ink | ||
77 | } | ||
78 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/OverlayLayer.qml b/prototype_2016/third_party/qml-material/src/components/OverlayLayer.qml deleted file mode 100644 index 47c032b..0000000 --- a/prototype_2016/third_party/qml-material/src/components/OverlayLayer.qml +++ /dev/null | |||
@@ -1,71 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | |||
13 | /*! | ||
14 | \qmltype OverlayLayer | ||
15 | \inqmlmodule Material | ||
16 | |||
17 | \brief Provides a layer to display popups and other overlay components. | ||
18 | */ | ||
19 | Rectangle { | ||
20 | id: overlayLayer | ||
21 | objectName: "overlayLayer" | ||
22 | |||
23 | anchors.fill: parent | ||
24 | |||
25 | property Item currentOverlay | ||
26 | color: "transparent" | ||
27 | |||
28 | onEnabledChanged: { | ||
29 | if (!enabled && overlayLayer.currentOverlay != null) | ||
30 | overlayLayer.currentOverlay.close() | ||
31 | } | ||
32 | |||
33 | onWidthChanged: closeIfNecessary() | ||
34 | onHeightChanged: closeIfNecessary() | ||
35 | |||
36 | states: State { | ||
37 | name: "ShowState" | ||
38 | when: overlayLayer.currentOverlay != null | ||
39 | |||
40 | PropertyChanges { | ||
41 | target: overlayLayer | ||
42 | color: currentOverlay.overlayColor | ||
43 | } | ||
44 | } | ||
45 | |||
46 | transitions: Transition { | ||
47 | ColorAnimation { | ||
48 | duration: 300 | ||
49 | easing.type: Easing.InOutQuad | ||
50 | } | ||
51 | } | ||
52 | |||
53 | function closeIfNecessary() { | ||
54 | if (overlayLayer.currentOverlay != null && overlayLayer.currentOverlay.closeOnResize) | ||
55 | overlayLayer.currentOverlay.close() | ||
56 | } | ||
57 | |||
58 | MouseArea { | ||
59 | anchors.fill: parent | ||
60 | enabled: overlayLayer.currentOverlay != null && | ||
61 | overlayLayer.currentOverlay.globalMouseAreaEnabled | ||
62 | hoverEnabled: enabled | ||
63 | |||
64 | onWheel: wheel.accepted = true | ||
65 | |||
66 | onClicked: { | ||
67 | if (overlayLayer.currentOverlay.dismissOnTap) | ||
68 | overlayLayer.currentOverlay.close() | ||
69 | } | ||
70 | } | ||
71 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/OverlayView.qml b/prototype_2016/third_party/qml-material/src/components/OverlayView.qml deleted file mode 100644 index f2f5fbe..0000000 --- a/prototype_2016/third_party/qml-material/src/components/OverlayView.qml +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import Material 0.3 | ||
13 | import Material.Extras 0.1 | ||
14 | |||
15 | /*! | ||
16 | \qmltype OverlayView | ||
17 | \inqmlmodule Material | ||
18 | |||
19 | \brief A view that pops out of the content to display as an overlay. | ||
20 | */ | ||
21 | PopupBase { | ||
22 | id: overlay | ||
23 | |||
24 | overlayLayer: "dialogOverlayLayer" | ||
25 | overlayColor: Qt.rgba(0, 0, 0, 0.3) | ||
26 | |||
27 | visible: transitionOpacity > 0 | ||
28 | state: showing ? "visible" : "hidden" | ||
29 | |||
30 | x: (parent.width - width)/2 | ||
31 | y: (parent.height - height)/2 | ||
32 | |||
33 | property alias transitionOpacity: shadow.opacity | ||
34 | |||
35 | states: [ | ||
36 | State { | ||
37 | name: "hidden" | ||
38 | |||
39 | PropertyChanges { | ||
40 | target: overlay | ||
41 | x: sourceView ? sourceView.mapToItem(overlay.parent, 0, 0).x : 0 | ||
42 | y: sourceView ? sourceView.mapToItem(overlay.parent, 0, 0).y : 0 | ||
43 | width: sourceView ? sourceView.width : 0 | ||
44 | height: sourceView ? sourceView.height : 0 | ||
45 | } | ||
46 | } | ||
47 | ] | ||
48 | |||
49 | transitions: Transition { | ||
50 | from: "*"; to: "*" | ||
51 | |||
52 | NumberAnimation { | ||
53 | target: overlay | ||
54 | properties: "x,y,width,height" | ||
55 | duration: 300; easing.type: Easing.InOutQuad | ||
56 | } | ||
57 | } | ||
58 | |||
59 | property Item sourceView | ||
60 | |||
61 | function open(sourceView) { | ||
62 | overlay.sourceView = sourceView; | ||
63 | |||
64 | parent = Utils.findRootChild(overlay, overlayLayer) | ||
65 | showing = true | ||
66 | forceActiveFocus() | ||
67 | parent.currentOverlay = overlay | ||
68 | |||
69 | opened() | ||
70 | } | ||
71 | |||
72 | function close() { | ||
73 | showing = false | ||
74 | parent.currentOverlay = null | ||
75 | sourceView = null | ||
76 | } | ||
77 | |||
78 | View { | ||
79 | id: shadow | ||
80 | |||
81 | anchors.fill: parent | ||
82 | opacity: showing ? 1 : 0 | ||
83 | elevation: 5 | ||
84 | |||
85 | Behavior on opacity { | ||
86 | NumberAnimation { | ||
87 | duration: 300; easing.type: Easing.InOutQuad | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/ProgressCircle.qml b/prototype_2016/third_party/qml-material/src/components/ProgressCircle.qml deleted file mode 100644 index 71cd7b5..0000000 --- a/prototype_2016/third_party/qml-material/src/components/ProgressCircle.qml +++ /dev/null | |||
@@ -1,226 +0,0 @@ | |||
1 | /***** THIS FILE CANNOT BE RELICENSED UNDER THE MPL YET *****/ | ||
2 | |||
3 | /* | ||
4 | * QML Material - An application framework implementing Material Design. | ||
5 | * Copyright (C) 2015 Jordan Neidlinger <JNeidlinger@gmail.com> | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation, either version 2.1 of the | ||
10 | * License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | import QtQuick 2.4 | ||
21 | import QtQuick.Window 2.2 | ||
22 | import QtQuick.Controls 1.3 as Controls | ||
23 | import QtQuick.Controls.Styles 1.3 as Styles | ||
24 | import Material 0.3 | ||
25 | |||
26 | /*! | ||
27 | \qmltype ProgressCircle | ||
28 | \inqmlmodule Material | ||
29 | |||
30 | \brief Visual circular indicator of progress in some operation. | ||
31 | */ | ||
32 | Controls.ProgressBar { | ||
33 | id: progressBar | ||
34 | |||
35 | /*! | ||
36 | The color for the progress circle. By default this is | ||
37 | the primary color defined in \l Theme::primaryColor | ||
38 | */ | ||
39 | property color color: Theme.primaryColor | ||
40 | |||
41 | /*! | ||
42 | The thickness of the progress circle's stroke, | ||
43 | 3 dp by default | ||
44 | */ | ||
45 | property real dashThickness: 3 * Units.dp | ||
46 | |||
47 | width: 32 * Units.dp | ||
48 | height: 32 * Units.dp | ||
49 | |||
50 | indeterminate: true | ||
51 | |||
52 | style: Styles.ProgressBarStyle { | ||
53 | id: progressBarStyle | ||
54 | |||
55 | progress: Item { | ||
56 | anchors.fill: parent | ||
57 | |||
58 | Canvas { | ||
59 | id: canvas | ||
60 | |||
61 | property int ratio: Screen.devicePixelRatio | ||
62 | |||
63 | width: parent.width * ratio | ||
64 | height: parent.height * ratio | ||
65 | anchors.centerIn: parent | ||
66 | |||
67 | scale: 1/ratio | ||
68 | |||
69 | onWidthChanged: requestPaint() | ||
70 | onHeightChanged: requestPaint() | ||
71 | |||
72 | renderStrategy: Canvas.Threaded | ||
73 | antialiasing: true | ||
74 | onPaint: drawSpinner(); | ||
75 | |||
76 | opacity: visible ? 1.0 : 0 | ||
77 | |||
78 | Behavior on opacity { | ||
79 | PropertyAnimation { | ||
80 | duration: 800 | ||
81 | } | ||
82 | } | ||
83 | |||
84 | Connections { | ||
85 | target: control | ||
86 | onColorChanged: canvas.requestPaint() | ||
87 | onValueChanged: canvas.requestPaint() | ||
88 | onDashThicknessChanged: canvas.requestPaint() | ||
89 | onIndeterminateChanged: | ||
90 | { | ||
91 | if(control.indeterminate) | ||
92 | { | ||
93 | internal.arcEndPoint = 0 | ||
94 | internal.arcStartPoint = 0 | ||
95 | internal.rotate = 0 | ||
96 | } | ||
97 | |||
98 | canvas.requestPaint(); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | QtObject { | ||
103 | id: internal | ||
104 | |||
105 | property real arcEndPoint: 0 | ||
106 | onArcEndPointChanged: canvas.requestPaint(); | ||
107 | |||
108 | property real arcStartPoint: 0 | ||
109 | onArcStartPointChanged: canvas.requestPaint(); | ||
110 | |||
111 | property real rotate: 0 | ||
112 | onRotateChanged: canvas.requestPaint(); | ||
113 | |||
114 | property real longDash: 3 * Math.PI / 2 | ||
115 | property real shortDash: 19 * Math.PI / 10 | ||
116 | } | ||
117 | |||
118 | NumberAnimation { | ||
119 | target: internal | ||
120 | properties: "rotate" | ||
121 | from: 0 | ||
122 | to: 2 * Math.PI | ||
123 | loops: Animation.Infinite | ||
124 | running: control.indeterminate && canvas.visible | ||
125 | easing.type: Easing.Linear | ||
126 | duration: 3000 | ||
127 | } | ||
128 | |||
129 | SequentialAnimation { | ||
130 | running: control.indeterminate && canvas.visible | ||
131 | loops: Animation.Infinite | ||
132 | |||
133 | ParallelAnimation { | ||
134 | NumberAnimation { | ||
135 | target: internal | ||
136 | properties: "arcEndPoint" | ||
137 | from: 0 | ||
138 | to: internal.longDash | ||
139 | easing.type: Easing.InOutCubic | ||
140 | duration: 800 | ||
141 | } | ||
142 | |||
143 | NumberAnimation { | ||
144 | target: internal | ||
145 | properties: "arcStartPoint" | ||
146 | from: internal.shortDash | ||
147 | to: 2 * Math.PI - 0.001 | ||
148 | easing.type: Easing.InOutCubic | ||
149 | duration: 800 | ||
150 | } | ||
151 | } | ||
152 | |||
153 | ParallelAnimation { | ||
154 | NumberAnimation { | ||
155 | target: internal | ||
156 | properties: "arcEndPoint" | ||
157 | from: internal.longDash | ||
158 | to: 2 * Math.PI - 0.001 | ||
159 | easing.type: Easing.InOutCubic | ||
160 | duration: 800 | ||
161 | } | ||
162 | |||
163 | NumberAnimation { | ||
164 | target: internal | ||
165 | properties: "arcStartPoint" | ||
166 | from: 0 | ||
167 | to: internal.shortDash | ||
168 | easing.type: Easing.InOutCubic | ||
169 | duration: 800 | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | |||
174 | function drawSpinner() { | ||
175 | var ctx = canvas.getContext("2d"); | ||
176 | ctx.reset(); | ||
177 | ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
178 | ctx.strokeStyle = control.color | ||
179 | ctx.lineWidth = control.dashThickness * canvas.ratio | ||
180 | ctx.lineCap = "butt"; | ||
181 | |||
182 | ctx.translate(canvas.width / 2, canvas.height / 2); | ||
183 | ctx.rotate(control.indeterminate ? internal.rotate : currentProgress * (3 * Math.PI / 2)); | ||
184 | |||
185 | ctx.arc(0, 0, Math.max(0, Math.min(canvas.width, canvas.height) / 2 - ctx.lineWidth), | ||
186 | control.indeterminate ? internal.arcStartPoint : 0, | ||
187 | control.indeterminate ? internal.arcEndPoint : currentProgress * (2 * Math.PI), | ||
188 | false); | ||
189 | |||
190 | ctx.stroke(); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | |||
195 | property Component panel: Item{ | ||
196 | implicitWidth: backgroundLoader.implicitWidth | ||
197 | implicitHeight: backgroundLoader.implicitHeight | ||
198 | |||
199 | Item { | ||
200 | width: parent.width | ||
201 | height: parent.height | ||
202 | transformOrigin: Item.TopLeft | ||
203 | |||
204 | Rectangle { | ||
205 | id: backgroundLoader | ||
206 | implicitWidth: control.width | ||
207 | implicitHeight: control.height | ||
208 | color: "transparent" | ||
209 | } | ||
210 | |||
211 | Loader { | ||
212 | sourceComponent: progressBarStyle.progress | ||
213 | anchors.topMargin: padding.top | ||
214 | anchors.leftMargin: padding.left | ||
215 | anchors.rightMargin: padding.right | ||
216 | anchors.bottomMargin: padding.bottom | ||
217 | |||
218 | anchors.top: parent.top | ||
219 | anchors.left: parent.left | ||
220 | anchors.bottom: parent.bottom | ||
221 | width: parent.width - padding.left - padding.right | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/Scrollbar.qml b/prototype_2016/third_party/qml-material/src/components/Scrollbar.qml deleted file mode 100644 index 4c3de83..0000000 --- a/prototype_2016/third_party/qml-material/src/components/Scrollbar.qml +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | |||
13 | /*! | ||
14 | \qmltype Scrollbar | ||
15 | \inqmlmodule Material | ||
16 | |||
17 | \brief Scrollbars show scrolling progress for listviews and flickables. | ||
18 | */ | ||
19 | Item { | ||
20 | id: root | ||
21 | |||
22 | property Flickable flickableItem | ||
23 | property int orientation: Qt.Vertical | ||
24 | property int thickness: 5 | ||
25 | property bool moving: flickableItem.moving | ||
26 | |||
27 | width: thickness | ||
28 | height: thickness | ||
29 | clip: true | ||
30 | smooth: true | ||
31 | visible: orientation === Qt.Vertical ? flickableItem.contentHeight > flickableItem.height | ||
32 | : flickableItem.contentWidth > flickableItem.width | ||
33 | |||
34 | anchors { | ||
35 | top: orientation === Qt.Vertical ? flickableItem.top : undefined | ||
36 | bottom: flickableItem.bottom | ||
37 | left: orientation === Qt.Horizontal ? flickableItem.left : undefined | ||
38 | right: flickableItem.right | ||
39 | margins: 2 | ||
40 | } | ||
41 | |||
42 | Component.onCompleted: hideAnimation.start() | ||
43 | |||
44 | onMovingChanged: { | ||
45 | if (moving) { | ||
46 | hideAnimation.stop() | ||
47 | showAnimation.start() | ||
48 | } else { | ||
49 | hideAnimation.start() | ||
50 | showAnimation.stop() | ||
51 | } | ||
52 | } | ||
53 | |||
54 | NumberAnimation { | ||
55 | id: showAnimation | ||
56 | target: scrollBar; | ||
57 | property: "opacity"; | ||
58 | to: 0.3; | ||
59 | duration: 200; | ||
60 | easing.type: Easing.InOutQuad | ||
61 | } | ||
62 | |||
63 | SequentialAnimation { | ||
64 | id: hideAnimation | ||
65 | |||
66 | NumberAnimation { duration: 500 } | ||
67 | NumberAnimation { | ||
68 | target: scrollBar; | ||
69 | property: "opacity"; | ||
70 | to: 0; | ||
71 | duration: 500; | ||
72 | easing.type: Easing.InOutQuad | ||
73 | } | ||
74 | } | ||
75 | |||
76 | onOrientationChanged: { | ||
77 | if (orientation == Qt.Vertical) { | ||
78 | width = thickness | ||
79 | } else { | ||
80 | height = thickness | ||
81 | } | ||
82 | } | ||
83 | |||
84 | Rectangle { | ||
85 | id: scrollBar | ||
86 | property int length: orientation == Qt.Vertical ? root.height | ||
87 | : root.width; | ||
88 | property int targetLength: orientation == Qt.Vertical ? flickableItem.height | ||
89 | : flickableItem.width; | ||
90 | property int contentStart: orientation == Qt.Vertical ? flickableItem.contentY | ||
91 | : flickableItem.contentX; | ||
92 | property int contentLength: orientation == Qt.Vertical ? flickableItem.contentHeight | ||
93 | : flickableItem.contentWidth; | ||
94 | property int start: Math.max(0, length * contentStart/contentLength); | ||
95 | property int end: Math.min(length, | ||
96 | length * (contentStart + targetLength)/contentLength) | ||
97 | |||
98 | color: "black"//theme.foreground | ||
99 | opacity: 0.3 | ||
100 | radius: thickness/2 | ||
101 | width: Math.max(orientation == Qt.Horizontal ? end - start : 0, thickness) | ||
102 | height: Math.max(orientation == Qt.Vertical ? end - start : 0, thickness) | ||
103 | x: orientation == Qt.Horizontal ? start : 0 | ||
104 | y: orientation == Qt.Vertical ? start : 0 | ||
105 | } | ||
106 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/Snackbar.qml b/prototype_2016/third_party/qml-material/src/components/Snackbar.qml deleted file mode 100644 index 834a8b7..0000000 --- a/prototype_2016/third_party/qml-material/src/components/Snackbar.qml +++ /dev/null | |||
@@ -1,124 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * 2014 Bogdan Cuza <bogdan.cuza@hotmail.com> | ||
6 | * | ||
7 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
8 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
9 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
10 | */ | ||
11 | |||
12 | import QtQuick 2.4 | ||
13 | import QtQuick.Layouts 1.1 | ||
14 | import Material 0.3 | ||
15 | |||
16 | /*! | ||
17 | \qmltype Snackbar | ||
18 | \inqmlmodule Material | ||
19 | |||
20 | \brief Snackbars provide lightweight feedback about an operation | ||
21 | */ | ||
22 | View { | ||
23 | id: snackbar | ||
24 | |||
25 | property string buttonText | ||
26 | property color buttonColor: Theme.accentColor | ||
27 | property string text | ||
28 | property bool opened | ||
29 | property int duration: 2000 | ||
30 | property bool fullWidth: Device.type === Device.phone || Device.type === Device.phablet | ||
31 | |||
32 | signal clicked | ||
33 | |||
34 | function open(text) { | ||
35 | snackbar.text = text | ||
36 | opened = true; | ||
37 | timer.restart(); | ||
38 | } | ||
39 | |||
40 | anchors { | ||
41 | left: fullWidth ? parent.left : undefined | ||
42 | right: fullWidth ? parent.right : undefined | ||
43 | bottom: parent.bottom | ||
44 | bottomMargin: opened ? 0 : -snackbar.height | ||
45 | horizontalCenter: fullWidth ? undefined : parent.horizontalCenter | ||
46 | |||
47 | Behavior on bottomMargin { | ||
48 | NumberAnimation { duration: 300 } | ||
49 | } | ||
50 | } | ||
51 | radius: fullWidth ? 0 : 2 * Units.dp | ||
52 | backgroundColor: "#323232" | ||
53 | height: snackLayout.height | ||
54 | width: fullWidth ? undefined : snackLayout.width | ||
55 | opacity: opened ? 1 : 0 | ||
56 | |||
57 | Timer { | ||
58 | id: timer | ||
59 | |||
60 | interval: snackbar.duration | ||
61 | |||
62 | onTriggered: { | ||
63 | if (!running) { | ||
64 | snackbar.opened = false; | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | RowLayout { | ||
70 | id: snackLayout | ||
71 | |||
72 | anchors { | ||
73 | verticalCenter: parent.verticalCenter | ||
74 | left: snackbar.fullWidth ? parent.left : undefined | ||
75 | right: snackbar.fullWidth ? parent.right : undefined | ||
76 | } | ||
77 | |||
78 | spacing: 0 | ||
79 | |||
80 | Item { | ||
81 | width: 24 * Units.dp | ||
82 | } | ||
83 | |||
84 | Label { | ||
85 | id: snackText | ||
86 | Layout.fillWidth: true | ||
87 | Layout.minimumWidth: snackbar.fullWidth ? -1 : 216 * Units.dp - snackButton.width | ||
88 | Layout.maximumWidth: snackbar.fullWidth ? -1 : | ||
89 | Math.min(496 * Units.dp - snackButton.width - middleSpacer.width - 48 * Units.dp, | ||
90 | snackbar.parent.width - snackButton.width - middleSpacer.width - 48 * Units.dp) | ||
91 | |||
92 | Layout.preferredHeight: lineCount == 2 ? 80 * Units.dp : 48 * Units.dp | ||
93 | verticalAlignment: Text.AlignVCenter | ||
94 | maximumLineCount: 2 | ||
95 | wrapMode: Text.Wrap | ||
96 | elide: Text.ElideRight | ||
97 | text: snackbar.text | ||
98 | color: "white" | ||
99 | } | ||
100 | |||
101 | Item { | ||
102 | id: middleSpacer | ||
103 | width: snackbar.buttonText == "" ? 0 : snackbar.fullWidth ? 24 * Units.dp : 48 * Units.dp | ||
104 | } | ||
105 | |||
106 | Button { | ||
107 | id: snackButton | ||
108 | textColor: snackbar.buttonColor | ||
109 | visible: snackbar.buttonText != "" | ||
110 | text: snackbar.buttonText | ||
111 | context: "snackbar" | ||
112 | width: visible ? implicitWidth : 0 | ||
113 | onClicked: snackbar.clicked() | ||
114 | } | ||
115 | |||
116 | Item { | ||
117 | width: 24 * Units.dp | ||
118 | } | ||
119 | } | ||
120 | |||
121 | Behavior on opacity { | ||
122 | NumberAnimation { duration: 300 } | ||
123 | } | ||
124 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/ThinDivider.qml b/prototype_2016/third_party/qml-material/src/components/ThinDivider.qml deleted file mode 100644 index 8770960..0000000 --- a/prototype_2016/third_party/qml-material/src/components/ThinDivider.qml +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2014-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
5 | * | ||
6 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
7 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
8 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
9 | */ | ||
10 | |||
11 | import QtQuick 2.4 | ||
12 | import Material 0.3 | ||
13 | |||
14 | /*! | ||
15 | \qmltype ThinDivider | ||
16 | \inqmlmodule Material | ||
17 | |||
18 | \brief A 1dp high divider for use in lists and other columns of content. | ||
19 | */ | ||
20 | Rectangle { | ||
21 | anchors { | ||
22 | left: parent.left | ||
23 | right: parent.right | ||
24 | } | ||
25 | |||
26 | property bool darkBackground | ||
27 | |||
28 | color: darkBackground ? Theme.dark.hintColor : Theme.light.hintColor | ||
29 | height: 1 | ||
30 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/TimePicker.qml b/prototype_2016/third_party/qml-material/src/components/TimePicker.qml deleted file mode 100644 index 6f84275..0000000 --- a/prototype_2016/third_party/qml-material/src/components/TimePicker.qml +++ /dev/null | |||
@@ -1,579 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015 Steve Coffey <scoffey@barracuda.com> | ||
5 | * 2015 Jordan Neidlinger <JNeidlinger@gmail.com> | ||
6 | * 2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
7 | * | ||
8 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
9 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
10 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
11 | */ | ||
12 | |||
13 | import QtQuick 2.4 | ||
14 | import Material 0.3 | ||
15 | import Material.Extras 0.1 | ||
16 | import QtQuick.Controls 1.3 as QuickControls | ||
17 | import QtQuick.Controls.Styles 1.3 | ||
18 | |||
19 | FocusScope { | ||
20 | id: timePicker | ||
21 | |||
22 | width: 300 * Units.dp | ||
23 | height: content.height | ||
24 | |||
25 | /*! | ||
26 | Set to \c true if selection is 24 hour based. Defaults to false | ||
27 | */ | ||
28 | property bool prefer24Hour: false | ||
29 | |||
30 | /*! | ||
31 | The visual padding around the clock element | ||
32 | */ | ||
33 | property real clockPadding: 24 * Units.dp | ||
34 | |||
35 | /*! | ||
36 | Set to \c true if the time picker should first show the hours. Defaults to true | ||
37 | */ | ||
38 | property bool isHours: true | ||
39 | |||
40 | /*! | ||
41 | Sets the bottom margin for the time picker | ||
42 | */ | ||
43 | property int bottomMargin: 0 | ||
44 | |||
45 | Keys.onUpPressed: { | ||
46 | var date = internal.timePicked | ||
47 | |||
48 | if(isHours) | ||
49 | date.setHours(internal.timePicked.getHours() + 1) | ||
50 | else | ||
51 | date.setMinutes(internal.timePicked.getMinutes() + 1) | ||
52 | |||
53 | internal.timePicked = date | ||
54 | } | ||
55 | |||
56 | Keys.onDownPressed: { | ||
57 | var date = internal.timePicked | ||
58 | |||
59 | if(isHours) | ||
60 | date.setHours(internal.timePicked.getHours() - 1) | ||
61 | else | ||
62 | date.setMinutes(internal.timePicked.getMinutes() - 1) | ||
63 | |||
64 | internal.timePicked = date | ||
65 | } | ||
66 | |||
67 | Keys.onLeftPressed: { | ||
68 | if(!isHours) | ||
69 | setIsHours(true) | ||
70 | } | ||
71 | |||
72 | Keys.onRightPressed: { | ||
73 | if(isHours) | ||
74 | setIsHours(false) | ||
75 | } | ||
76 | |||
77 | property string __digitsPressed | ||
78 | |||
79 | Keys.onDigit0Pressed: setDigitsPressed(0) | ||
80 | Keys.onDigit1Pressed: setDigitsPressed(1) | ||
81 | Keys.onDigit2Pressed: setDigitsPressed(2) | ||
82 | Keys.onDigit3Pressed: setDigitsPressed(3) | ||
83 | Keys.onDigit4Pressed: setDigitsPressed(4) | ||
84 | Keys.onDigit5Pressed: setDigitsPressed(5) | ||
85 | Keys.onDigit6Pressed: setDigitsPressed(6) | ||
86 | Keys.onDigit7Pressed: setDigitsPressed(7) | ||
87 | Keys.onDigit8Pressed: setDigitsPressed(8) | ||
88 | Keys.onDigit9Pressed: setDigitsPressed(9) | ||
89 | |||
90 | QtObject { | ||
91 | id: internal | ||
92 | property bool resetFlag: false | ||
93 | property date timePicked | ||
94 | property bool completed: false | ||
95 | |||
96 | onTimePickedChanged: { | ||
97 | if(completed) { | ||
98 | var hours = timePicked.getHours() | ||
99 | if(hours > 11 && !prefer24Hour){ | ||
100 | hours -= 12 | ||
101 | amPmPicker.isAm = false | ||
102 | } else { | ||
103 | amPmPicker.isAm = true | ||
104 | } | ||
105 | |||
106 | hoursPathView.currentIndex = hours | ||
107 | |||
108 | var minutes = internal.timePicked.getMinutes() | ||
109 | minutesPathView.currentIndex = minutes | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | |||
114 | Component.onCompleted: { | ||
115 | internal.completed = true | ||
116 | internal.timePicked = new Date(Date.now()) | ||
117 | forceActiveFocus() | ||
118 | } | ||
119 | |||
120 | Column { | ||
121 | id:content | ||
122 | height: childrenRect.height + bottomMargin | ||
123 | width: parent.width | ||
124 | |||
125 | Rectangle { | ||
126 | id: headerView | ||
127 | width: parent.width | ||
128 | height: 88 * Units.dp | ||
129 | color: Theme.accentColor | ||
130 | |||
131 | Row { | ||
132 | id: timeContainer | ||
133 | anchors.centerIn: parent | ||
134 | height: 48 * Units.dp | ||
135 | |||
136 | Label { | ||
137 | id:hoursLabel | ||
138 | style: "display3" | ||
139 | color: isHours ? "white" : "#99ffffff" | ||
140 | text: internal.timePicked.getHours() | ||
141 | anchors.verticalCenter: parent.verticalCenter | ||
142 | |||
143 | MouseArea { | ||
144 | anchors.fill: parent | ||
145 | onClicked: { | ||
146 | if(!isHours){ | ||
147 | setIsHours(true) | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | |||
153 | Label { | ||
154 | style: "display3" | ||
155 | color: "white" | ||
156 | text:":" | ||
157 | anchors.verticalCenter: parent.verticalCenter | ||
158 | } | ||
159 | |||
160 | Label { | ||
161 | id: minutesLabel | ||
162 | style: "display3" | ||
163 | color: !isHours ? "white" : "#99ffffff" | ||
164 | text: internal.timePicked.getMinutes() < 10 ? "0" + internal.timePicked.getMinutes() : internal.timePicked.getMinutes() | ||
165 | anchors.verticalCenter: parent.verticalCenter | ||
166 | |||
167 | MouseArea { | ||
168 | anchors.fill: parent | ||
169 | onClicked: { | ||
170 | if(isHours){ | ||
171 | setIsHours(false) | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | Column { | ||
179 | id: amPmPicker | ||
180 | visible: !prefer24Hour | ||
181 | |||
182 | property bool isAm: true | ||
183 | |||
184 | anchors { | ||
185 | bottom: timeContainer.bottom | ||
186 | left: timeContainer.right | ||
187 | leftMargin: 12 * Units.dp | ||
188 | } | ||
189 | |||
190 | spacing: 4 * Units.dp | ||
191 | |||
192 | Label { | ||
193 | style: "subheading" | ||
194 | font.weight: Font.DemiBold | ||
195 | color: amPmPicker.isAm ? "white" : "#99ffffff" | ||
196 | text: "AM" | ||
197 | |||
198 | MouseArea { | ||
199 | anchors.fill: parent | ||
200 | onClicked: amPmPicker.isAm = true | ||
201 | } | ||
202 | } | ||
203 | |||
204 | Label { | ||
205 | style: "subheading" | ||
206 | font.weight: Font.DemiBold | ||
207 | color: !amPmPicker.isAm ? "white" : "#99ffffff" | ||
208 | text: "PM" | ||
209 | |||
210 | MouseArea { | ||
211 | anchors.fill: parent | ||
212 | onClicked: amPmPicker.isAm = false | ||
213 | } | ||
214 | } | ||
215 | } | ||
216 | } | ||
217 | |||
218 | Rectangle { | ||
219 | id: picker | ||
220 | width: parent.width | ||
221 | height: width | ||
222 | color: "white" | ||
223 | |||
224 | Rectangle { | ||
225 | id: circle | ||
226 | color: "#eee" | ||
227 | anchors.centerIn: parent | ||
228 | width: parent.width * 0.9 | ||
229 | height: width | ||
230 | radius: width / 2 | ||
231 | |||
232 | Rectangle { | ||
233 | id: centerPoint | ||
234 | anchors.centerIn: parent | ||
235 | color: Theme.accentColor | ||
236 | width: 8 * Units.dp | ||
237 | height: 8 * Units.dp | ||
238 | radius: width / 2 | ||
239 | } | ||
240 | |||
241 | Rectangle { | ||
242 | id: pointer | ||
243 | color: Theme.accentColor | ||
244 | width: 2 * Units.dp | ||
245 | height: circle.height / 2 - clockPadding | ||
246 | y: clockPadding | ||
247 | anchors.horizontalCenter: parent.horizontalCenter | ||
248 | antialiasing: true | ||
249 | transformOrigin: Item.Bottom | ||
250 | |||
251 | Connections { | ||
252 | target: hoursPathView | ||
253 | onCurrentIndexChanged: { | ||
254 | if(isHours) | ||
255 | pointer.setAngle() | ||
256 | } | ||
257 | } | ||
258 | |||
259 | Connections { | ||
260 | target: minutesPathView | ||
261 | onCurrentIndexChanged: { | ||
262 | if(!isHours) | ||
263 | pointer.setAngle() | ||
264 | } | ||
265 | } | ||
266 | |||
267 | Connections { | ||
268 | target: timePicker | ||
269 | onIsHoursChanged: pointer.setAngle() | ||
270 | } | ||
271 | |||
272 | function setAngle() | ||
273 | { | ||
274 | var idx = isHours ? hoursPathView.currentIndex : minutesPathView.currentIndex | ||
275 | var angle | ||
276 | if(isHours) | ||
277 | angle = (360 / ((prefer24Hour) ? 24 : 12)) * idx | ||
278 | else | ||
279 | angle = 360 / 60 * idx | ||
280 | |||
281 | if(Math.abs(pointer.rotation - angle) == 180) | ||
282 | pointerRotation.direction = RotationAnimation.Clockwise | ||
283 | else | ||
284 | pointerRotation.direction = RotationAnimation.Shortest | ||
285 | |||
286 | pointer.rotation = angle | ||
287 | } | ||
288 | |||
289 | Behavior on rotation { | ||
290 | RotationAnimation { | ||
291 | id: pointerRotation | ||
292 | duration: 200 | ||
293 | direction: RotationAnimation.Shortest | ||
294 | } | ||
295 | } | ||
296 | } | ||
297 | |||
298 | Component { | ||
299 | id: pathViewHighlight | ||
300 | Rectangle { | ||
301 | id: highlight | ||
302 | width: 40 * Units.dp | ||
303 | height: 40 * Units.dp | ||
304 | color: Theme.accentColor | ||
305 | radius: width / 2 | ||
306 | } | ||
307 | } | ||
308 | |||
309 | Component { | ||
310 | id: pathViewItem | ||
311 | Rectangle { | ||
312 | id: rectangle | ||
313 | width: !isHours && modelData % 5 == 0 ? 12 * Units.dp : isHours ? 30 * Units.dp : 8 * Units.dp | ||
314 | height: !isHours && modelData % 5 == 0 ? 12 * Units.dp : isHours ? 30 * Units.dp : 8 * Units.dp | ||
315 | color: "transparent" | ||
316 | |||
317 | property bool isSelected: false | ||
318 | |||
319 | Label { | ||
320 | anchors.centerIn: parent | ||
321 | text:{ | ||
322 | var model = isHours ? hoursPathView.model : minutesPathView.model | ||
323 | return model.data < 10 && !isHours ? "0" + modelData : modelData | ||
324 | } | ||
325 | visible: modelData >= 0 && (isHours ? true : modelData % 5 == 0) | ||
326 | style: "subheading" | ||
327 | } | ||
328 | |||
329 | Connections { | ||
330 | target: parentMouseArea | ||
331 | |||
332 | onClicked: { | ||
333 | checkClick(false) | ||
334 | } | ||
335 | |||
336 | onPositionChanged: { | ||
337 | checkClick(true) | ||
338 | } | ||
339 | |||
340 | function checkClick(isPress) | ||
341 | { | ||
342 | if((isPress ? parentMouseArea.leftButtonPressed : true) && rectangle.visible) { | ||
343 | var thisPosition = rectangle.mapToItem(null, 0, 0, width, height) | ||
344 | |||
345 | if(parentMouseArea.globalX > thisPosition.x && | ||
346 | parentMouseArea.globalY > thisPosition.y && | ||
347 | parentMouseArea.globalX < (thisPosition.x + width) && | ||
348 | parentMouseArea.globalY < (thisPosition.y + height)) { | ||
349 | |||
350 | if(!rectangle.isSelected) { | ||
351 | rectangle.isSelected = true | ||
352 | |||
353 | var newDate = new Date(internal.timePicked) // Grab a new date from existing | ||
354 | |||
355 | var time = parseInt(modelData) | ||
356 | if(isHours) { | ||
357 | if(!prefer24Hour && !amPmPicker.isAm && time < 12) { | ||
358 | time += 12 | ||
359 | } | ||
360 | else if(!prefer24Hour && amPmPicker.isAm && time === 12) { | ||
361 | time = 0 | ||
362 | } | ||
363 | |||
364 | newDate.setHours(time) | ||
365 | } else { | ||
366 | newDate.setMinutes(time) | ||
367 | } | ||
368 | |||
369 | internal.timePicked = newDate | ||
370 | } | ||
371 | } | ||
372 | else { | ||
373 | rectangle.isSelected = false | ||
374 | } | ||
375 | } | ||
376 | } | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | |||
381 | MouseArea { | ||
382 | property bool leftButtonPressed | ||
383 | property int globalX | ||
384 | property int globalY | ||
385 | id: parentMouseArea | ||
386 | anchors.fill: circle | ||
387 | hoverEnabled: true | ||
388 | |||
389 | onClicked: { | ||
390 | globalX = parentMouseArea.mapToItem(null, mouse.x, mouse.y).x | ||
391 | globalY = parentMouseArea.mapToItem(null, mouse.x, mouse.y).y | ||
392 | } | ||
393 | |||
394 | onPositionChanged: { | ||
395 | if(containsPress) | ||
396 | { | ||
397 | leftButtonPressed = true | ||
398 | globalX = parentMouseArea.mapToItem(null, mouse.x, mouse.y).x | ||
399 | globalY = parentMouseArea.mapToItem(null, mouse.x, mouse.y).y | ||
400 | } | ||
401 | else | ||
402 | { | ||
403 | leftButtonPressed = false | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
408 | |||
409 | PathView { | ||
410 | id: hoursPathView | ||
411 | anchors.fill: parent | ||
412 | visible: isHours | ||
413 | model: { | ||
414 | var limit = prefer24Hour ? 24 : 12 | ||
415 | var zeroBased = prefer24Hour | ||
416 | return getTimeList(limit, zeroBased) | ||
417 | } | ||
418 | highlightRangeMode: PathView.NoHighlightRange | ||
419 | highlightMoveDuration: 200 | ||
420 | |||
421 | onCurrentIndexChanged: { | ||
422 | var newText = currentIndex | ||
423 | if(currentIndex == 0 && !prefer24Hour) | ||
424 | newText = 12 | ||
425 | hoursLabel.text = newText | ||
426 | } | ||
427 | |||
428 | delegate: pathViewItem | ||
429 | |||
430 | interactive: false | ||
431 | highlight: pathViewHighlight | ||
432 | |||
433 | path: Path { | ||
434 | startX: circle.width / 2 | ||
435 | startY: clockPadding | ||
436 | |||
437 | PathArc { | ||
438 | x: circle.width / 2 | ||
439 | y: circle.height - clockPadding | ||
440 | radiusX: circle.width / 2 - clockPadding | ||
441 | radiusY: circle.width / 2 - clockPadding | ||
442 | useLargeArc: false | ||
443 | } | ||
444 | |||
445 | PathArc { | ||
446 | x: circle.width / 2 | ||
447 | y: clockPadding | ||
448 | radiusX: circle.width / 2 - clockPadding | ||
449 | radiusY: circle.width / 2 - clockPadding | ||
450 | useLargeArc: false | ||
451 | } | ||
452 | } | ||
453 | } | ||
454 | |||
455 | PathView { | ||
456 | id: minutesPathView | ||
457 | anchors.fill: parent | ||
458 | visible: !isHours | ||
459 | model: { | ||
460 | return getTimeList(60, true) | ||
461 | } | ||
462 | highlightRangeMode: PathView.NoHighlightRange | ||
463 | highlightMoveDuration: 200 | ||
464 | delegate: pathViewItem | ||
465 | highlight: pathViewHighlight | ||
466 | interactive: false | ||
467 | |||
468 | path: Path { | ||
469 | startX: circle.width / 2 | ||
470 | startY: clockPadding | ||
471 | |||
472 | PathArc { | ||
473 | x: circle.width / 2 | ||
474 | y: circle.height - clockPadding | ||
475 | radiusX: circle.width / 2 - clockPadding | ||
476 | radiusY: circle.width / 2 - clockPadding | ||
477 | useLargeArc: false | ||
478 | } | ||
479 | |||
480 | PathArc { | ||
481 | x: circle.width / 2 | ||
482 | y: clockPadding | ||
483 | radiusX: circle.width / 2 - clockPadding | ||
484 | radiusY: circle.width / 2 - clockPadding | ||
485 | useLargeArc: false | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | } | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | Switches contexts | ||
495 | |||
496 | If previously we hadn't set hours, and we're now switching contexts, disable the auto switch to minutes | ||
497 | */ | ||
498 | function setIsHours(_isHours) { | ||
499 | if(_isHours == isHours) | ||
500 | return | ||
501 | |||
502 | if(!internal.resetFlag) | ||
503 | internal.resetFlag = true | ||
504 | |||
505 | var prevRotation = pointerRotation.duration | ||
506 | pointerRotation.duration = 0 | ||
507 | isHours = _isHours | ||
508 | pointerRotation.duration = prevRotation | ||
509 | } | ||
510 | |||
511 | function getCurrentTime() { | ||
512 | var date = new Date(internal.timePicked) | ||
513 | if(amPmPicker.isAm && date.getHours() > 11) | ||
514 | date.setHours(date.getHours() - 12) | ||
515 | else if(!amPmPicker.isAm && date.getHours() < 11) | ||
516 | date.setHours(date.getHours() + 12) | ||
517 | |||
518 | return date | ||
519 | } | ||
520 | |||
521 | /*! | ||
522 | \internal | ||
523 | Resets the view after closing | ||
524 | */ | ||
525 | function reset() { | ||
526 | isHours = true | ||
527 | internal.resetFlag = false | ||
528 | amPmPicker.isAm = true | ||
529 | internal.timePicked = new Date(Date.now()) | ||
530 | } | ||
531 | |||
532 | /*! | ||
533 | \internal | ||
534 | Provides list of ints for pathview based on the context and user prefs | ||
535 | */ | ||
536 | function getTimeList(limit, isZeroBased) { | ||
537 | var items = [] | ||
538 | if(!isZeroBased) { | ||
539 | items[0] = limit | ||
540 | } | ||
541 | |||
542 | var start = isZeroBased ? 0 : 1 | ||
543 | |||
544 | var jump = limit > 24 ? 1 : 1 | ||
545 | for(var i = start; i < limit; i += jump) { | ||
546 | items[i / jump] = i | ||
547 | } | ||
548 | return items | ||
549 | } | ||
550 | |||
551 | /*! | ||
552 | \internal | ||
553 | */ | ||
554 | function setDigitsPressed(minute) | ||
555 | { | ||
556 | if(__digitsPressed.length > 1) { | ||
557 | __digitsPressed = "" | ||
558 | __digitsPressed = minute | ||
559 | } | ||
560 | else { | ||
561 | __digitsPressed += minute | ||
562 | } | ||
563 | |||
564 | var date = internal.timePicked | ||
565 | var value = parseInt(__digitsPressed) | ||
566 | |||
567 | if((isHours && value > 23) || (!isHours && value > 59)) { | ||
568 | __digitsPressed = "" | ||
569 | return | ||
570 | } | ||
571 | |||
572 | if(isHours) | ||
573 | date.setHours(value) | ||
574 | else | ||
575 | date.setMinutes(value) | ||
576 | |||
577 | internal.timePicked = date | ||
578 | } | ||
579 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/Tooltip.qml b/prototype_2016/third_party/qml-material/src/components/Tooltip.qml deleted file mode 100644 index 8ea259f..0000000 --- a/prototype_2016/third_party/qml-material/src/components/Tooltip.qml +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * QML Material - An application framework implementing Material Design. | ||
3 | * | ||
4 | * Copyright (C) 2015 Jordan Neidlinger <jneidlinger@gmail.com> | ||
5 | * 2015-2016 Michael Spencer <sonrisesoftware@gmail.com> | ||
6 | * | ||
7 | * This Source Code Form is subject to the terms of the Mozilla Public | ||
8 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||
9 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
10 | */ | ||
11 | |||
12 | import QtQuick 2.4 | ||
13 | import Material 0.3 | ||
14 | import Material.Extras 0.1 | ||
15 | |||
16 | /*! | ||
17 | \qmltype Tooltip | ||
18 | \inqmlmodule Material | ||
19 | |||
20 | \brief A tooltip is a label that appears on hover and explains a non-text UI element. | ||
21 | |||
22 | To display a tooltip for your view, simply create an instance of Tooltip, | ||
23 | set the text property to your tooltip text, and then set the mouseArea property | ||
24 | to your MouseArea or Ink that will trigger the tooltip. If you use a MouseArea, | ||
25 | make sure hoverEnabled is set to true. | ||
26 | |||
27 | See the Material Design guidelines for more details: | ||
28 | http://www.google.com/design/spec/components/tooltips.html | ||
29 | */ | ||
30 | Popover { | ||
31 | id: dropdown | ||
32 | |||
33 | property alias text: tooltipLabel.text | ||
34 | |||
35 | property MouseArea mouseArea | ||
36 | |||
37 | overlayLayer: "tooltipOverlayLayer" | ||
38 | globalMouseAreaEnabled: false | ||
39 | |||
40 | width: tooltipLabel.paintedWidth + 32 * Units.dp | ||
41 | implicitHeight: Device.isMobile ? 44 * Units.dp : 40 * Units.dp | ||
42 | |||
43 | backgroundColor: Qt.rgba(0.2, 0.2, 0.2, 0.9) | ||
44 | |||
45 | Timer { | ||
46 | id: timer | ||
47 | |||
48 | interval: 1000 | ||
49 | onTriggered: open(mouseArea, 0, 4 * Units.dp) | ||
50 | } | ||
51 | |||
52 | Connections { | ||
53 | target: mouseArea | ||
54 | |||
55 | onReleased: { | ||
56 | if(showing) | ||
57 | close() | ||
58 | } | ||
59 | |||
60 | onPressAndHold: { | ||
61 | if(text !== "" && !showing) | ||
62 | open(mouseArea, 0, 4 * Units.dp) | ||
63 | } | ||
64 | |||
65 | onEntered: { | ||
66 | if(text !== "" && !showing) | ||
67 | timer.start() | ||
68 | } | ||
69 | |||
70 | onExited: { | ||
71 | timer.stop() | ||
72 | |||
73 | if(showing) | ||
74 | close() | ||
75 | } | ||
76 | } | ||
77 | |||
78 | Label { | ||
79 | id: tooltipLabel | ||
80 | style: "tooltip" | ||
81 | color: Theme.dark.textColor | ||
82 | anchors.centerIn: parent | ||
83 | } | ||
84 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/Wave.qml b/prototype_2016/third_party/qml-material/src/components/Wave.qml deleted file mode 100644 index 3a0afb4..0000000 --- a/prototype_2016/third_party/qml-material/src/components/Wave.qml +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | /***** THIS FILE CANNOT BE RELICENSED UNDER THE MPL YET *****/ | ||
2 | |||
3 | /* | ||
4 | * QML Material - An application framework implementing Material Design. | ||
5 | * Copyright (C) 2014 Bogdan Cuza <bogdan.cuza@hotmail.com> | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation, either version 2.1 of the | ||
10 | * License, or (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | import QtQuick 2.4 | ||
22 | |||
23 | /*! | ||
24 | \qmltype Wave | ||
25 | \inqmlmodule Material | ||
26 | |||
27 | \brief Provides a wave animation for transitioning between views of content. | ||
28 | */ | ||
29 | Rectangle { | ||
30 | id: wave | ||
31 | |||
32 | property bool opened | ||
33 | property real size | ||
34 | property real initialX | ||
35 | property real initialY | ||
36 | property real abstractWidth: parent.width | ||
37 | property real abstractHeight: parent.height | ||
38 | property real diameter: 2*Math.sqrt(Math.pow(Math.max(initialX, abstractWidth - initialX), 2) + Math.pow(Math.max(initialY, abstractHeight - initialY), 2)) | ||
39 | |||
40 | signal finished(bool opened) | ||
41 | |||
42 | function open(x, y) { | ||
43 | wave.initialX = x; | ||
44 | wave.initialY = y; | ||
45 | wave.opened = true; | ||
46 | } | ||
47 | |||
48 | function close(x, y) { | ||
49 | wave.initialX = x; | ||
50 | wave.initialY = y; | ||
51 | wave.opened = false; | ||
52 | } | ||
53 | |||
54 | width: size | ||
55 | height: size | ||
56 | radius: size/2 | ||
57 | x: initialX - size/2 | ||
58 | y: initialY - size/2 | ||
59 | |||
60 | states: State { | ||
61 | name: "opened" | ||
62 | when: wave.opened | ||
63 | |||
64 | PropertyChanges { | ||
65 | target: wave | ||
66 | size: wave.diameter | ||
67 | } | ||
68 | } | ||
69 | |||
70 | transitions: Transition { | ||
71 | from: "" | ||
72 | to: "opened" | ||
73 | reversible: true | ||
74 | |||
75 | SequentialAnimation { | ||
76 | NumberAnimation { | ||
77 | property: "size" | ||
78 | easing.type: Easing.OutCubic | ||
79 | } | ||
80 | ScriptAction { | ||
81 | script: wave.finished(wave.opened) | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | } | ||
diff --git a/prototype_2016/third_party/qml-material/src/components/components.qrc b/prototype_2016/third_party/qml-material/src/components/components.qrc deleted file mode 100644 index 8d22f1e..0000000 --- a/prototype_2016/third_party/qml-material/src/components/components.qrc +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | <!DOCTYPE RCC> | ||
2 | <RCC version="1.0"> | ||
3 | |||
4 | <qresource prefix="/Material"> | ||
5 | <file>ActionButton.qml</file> | ||
6 | <file>Card.qml</file> | ||
7 | <file>DatePicker.qml</file> | ||
8 | <file>IconButton.qml</file> | ||
9 | <file>OverlayLayer.qml</file> | ||
10 | <file>OverlayView.qml</file> | ||
11 | <file>ProgressCircle.qml</file> | ||
12 | <file>Scrollbar.qml</file> | ||
13 | <file>Snackbar.qml</file> | ||
14 | <file>ThinDivider.qml</file> | ||
15 | <file>TimePicker.qml</file> | ||
16 | <file>Tooltip.qml</file> | ||
17 | <file>Wave.qml</file> | ||
18 | </qresource> | ||
19 | |||
20 | </RCC> | ||