Merge lp:~zsombi/ubuntu-ui-toolkit/dialer-component into lp:ubuntu-ui-toolkit
- dialer-component
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 759 |
Merged at revision: | 764 |
Proposed branch: | lp:~zsombi/ubuntu-ui-toolkit/dialer-component |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
964 lines (+899/-0) 10 files modified
components.api (+25/-0) examples/ubuntu-ui-toolkit-gallery/Pickers.qml (+77/-0) modules/Ubuntu/Components/Pickers/Dialer.qml (+178/-0) modules/Ubuntu/Components/Pickers/DialerHand.qml (+222/-0) modules/Ubuntu/Components/Pickers/DialerHandGroup.qml (+29/-0) modules/Ubuntu/Components/Pickers/qmldir (+2/-0) modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.qml (+63/-0) modules/Ubuntu/Components/Themes/Ambiance/DialerStyle.qml (+126/-0) modules/Ubuntu/Components/Themes/Ambiance/qmldir (+2/-0) tests/unit_x11/tst_components/tst_dialer.qml (+175/-0) |
To merge this branch: | bzr merge lp:~zsombi/ubuntu-ui-toolkit/dialer-component |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Cris Dywan | Approve | ||
Review via email: mp+185213@code.launchpad.net |
Commit message
Dialer + DialerHand components required for TimePicker.
Description of the change
Zsombor Egri (zsombi) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:753
http://
Executed test runs:
FAILURE: http://
UNSTABLE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:754
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
UNSTABLE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:754
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:755
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:756
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:758
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 759. By Zsombor Egri
-
comment fixed
Cris Dywan (kalikiana) wrote : | # |
For the record: it's apparently expected that the Dialer always comes in Gradient theming.
I was unsure about the behavior of the overlay at first, with separate visibility and rotation, but more API can be added later if it makes sense, and this is more flexible.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:759
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'components.api' |
2 | --- components.api 2013-09-24 06:22:16 +0000 |
3 | +++ components.api 2013-09-24 14:39:42 +0000 |
4 | @@ -486,6 +486,31 @@ |
5 | property variant values |
6 | property int selectedIndex |
7 | property bool expanded |
8 | +modules/Ubuntu/Components/Pickers/Dialer.qml |
9 | +StyledItem |
10 | + property real minimumValue |
11 | + property real maximumValue |
12 | + property real size |
13 | + property real handSpace |
14 | + readonly property Item centerItem |
15 | + property list<var> centerContent |
16 | + readonly property list<DialerHands> hands |
17 | + signal handUpdated(var hand) |
18 | +modules/Ubuntu/Components/Pickers/DialerHand.qml |
19 | +StyledItem |
20 | + property real value |
21 | + property DialerHandGroup hand |
22 | + readonly property Dialer dialer |
23 | + default property list<QtObject> overlay |
24 | + readonly property int index |
25 | + property internal __grabber |
26 | +modules/Ubuntu/Components/Pickers/DialerHandGroup.qml |
27 | +QtObject |
28 | + property real width |
29 | + property real height |
30 | + property bool draggable |
31 | + property bool visible |
32 | + property bool toCenterItem |
33 | modules/Ubuntu/Components/Pickers/Picker.qml |
34 | StyledItem |
35 | property bool circular |
36 | |
37 | === modified file 'examples/ubuntu-ui-toolkit-gallery/Pickers.qml' |
38 | --- examples/ubuntu-ui-toolkit-gallery/Pickers.qml 2013-09-11 09:29:14 +0000 |
39 | +++ examples/ubuntu-ui-toolkit-gallery/Pickers.qml 2013-09-24 14:39:42 +0000 |
40 | @@ -93,4 +93,81 @@ |
41 | } |
42 | } |
43 | } |
44 | + |
45 | + TemplateSection { |
46 | + className: "Dialer" |
47 | + documentation: "qml-ubuntu-components-pickers0-dialer.html" |
48 | + |
49 | + TemplateRow { |
50 | + title: i18n.tr("Clock") |
51 | + Dialer { |
52 | + size: units.gu(20) |
53 | + handSpace: units.gu(4) |
54 | + minimumValue: 0 |
55 | + maximumValue: 60 |
56 | + |
57 | + DialerHand { |
58 | + id: hour |
59 | + hand.toCenterItem: true |
60 | + value: new Date().getHours() * 5 |
61 | + } |
62 | + DialerHand { |
63 | + id: minute |
64 | + value: new Date().getMinutes() |
65 | + } |
66 | + |
67 | + DialerHand { |
68 | + id: second |
69 | + value: new Date().getSeconds() |
70 | + } |
71 | + |
72 | + centerContent: [ |
73 | + Label { |
74 | + id: hourLabel |
75 | + anchors.centerIn: parent |
76 | + } |
77 | + ] |
78 | + |
79 | + onHandUpdated: { |
80 | + hourLabel.text = Math.round(hour.value / 5) + ":" |
81 | + + Math.round(minute.value) + ":" |
82 | + + Math.round(second.value); |
83 | + } |
84 | + } |
85 | + } |
86 | + TemplateRow { |
87 | + title: i18n.tr("Overlay") |
88 | + Dialer { |
89 | + size: units.gu(20) |
90 | + handSpace: units.gu(4) |
91 | + |
92 | + DialerHand { |
93 | + id: selector |
94 | + hand.visible: false |
95 | + value: 311 |
96 | + Rectangle { |
97 | + anchors.centerIn: parent |
98 | + width: height |
99 | + height: units.gu(3) |
100 | + radius: width / 2 |
101 | + color: Theme.palette.normal.background |
102 | + antialiasing: true |
103 | + Label { |
104 | + text: Math.round(selector.value) |
105 | + anchors.centerIn: parent |
106 | + } |
107 | + } |
108 | + } |
109 | + |
110 | + centerContent: [ |
111 | + Label { |
112 | + id: handText |
113 | + anchors.centerIn: parent |
114 | + } |
115 | + ] |
116 | + |
117 | + onHandUpdated: handText.text = Math.round(hand.value); |
118 | + } |
119 | + } |
120 | + } |
121 | } |
122 | |
123 | === added file 'modules/Ubuntu/Components/Pickers/Dialer.qml' |
124 | --- modules/Ubuntu/Components/Pickers/Dialer.qml 1970-01-01 00:00:00 +0000 |
125 | +++ modules/Ubuntu/Components/Pickers/Dialer.qml 2013-09-24 14:39:42 +0000 |
126 | @@ -0,0 +1,178 @@ |
127 | +/* |
128 | + * Copyright 2013 Canonical Ltd. |
129 | + * |
130 | + * This program is free software; you can redistribute it and/or modify |
131 | + * it under the terms of the GNU Lesser General Public License as published by |
132 | + * the Free Software Foundation; version 3. |
133 | + * |
134 | + * This program is distributed in the hope that it will be useful, |
135 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
136 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
137 | + * GNU Lesser General Public License for more details. |
138 | + * |
139 | + * You should have received a copy of the GNU Lesser General Public License |
140 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
141 | + */ |
142 | + |
143 | +import QtQuick 2.0 |
144 | +import "../" 0.1 |
145 | + |
146 | +/*! |
147 | + \qmltype Dialer |
148 | + \inqmlmodule Ubuntu.Components.Pickers 0.1 |
149 | + \ingroup ubuntu-pickers |
150 | + \brief Dialer is a phone dialer style picker component. |
151 | + |
152 | + The Dialer component is dedicated for value selection where the value is |
153 | + compound of several sections, i.e. hour, minute and second, or integral and |
154 | + decimal values. Each section is defined by a DialerHand, which shares the |
155 | + same range as the dialer is having. Dialer hand visuals are placed on the |
156 | + same dialer disk, however this can be altered by setting different values |
157 | + to DialerHand propertries. |
158 | + |
159 | + The following example shows how to create a dialer component to select a |
160 | + value between 0 and 50. |
161 | + |
162 | + \qml |
163 | + import QtQuick 2.0 |
164 | + import Ubuntu.Components.Pickers 0.1 |
165 | + |
166 | + Dialer { |
167 | + size: units.gu(20) |
168 | + minimumValue: 0 |
169 | + maximumValue: 50 |
170 | + |
171 | + DialerHand { |
172 | + id: mainHand |
173 | + onValueChanged: console.log(value) |
174 | + } |
175 | + } |
176 | + \endqml |
177 | + |
178 | + \sa DialerHand |
179 | + */ |
180 | + |
181 | +StyledItem { |
182 | + |
183 | + /*! |
184 | + \qmlproperty real minimumValue: 0 |
185 | + \qmlproperty real maximumValue: 360 |
186 | + |
187 | + These properties define the value range the dialer hand values can take. |
188 | + The default values are 0 and 360. |
189 | + */ |
190 | + property real minimumValue: 0.0 |
191 | + |
192 | + /*! \internal - documented in previous block*/ |
193 | + property real maximumValue: 360.0 |
194 | + |
195 | + /*! |
196 | + The property holds the size of the dialer. The component should be sized |
197 | + using this property instead of using width and/or height properties. Sizing |
198 | + with this property it is made sure that the component will scale evenly. |
199 | + */ |
200 | + property real size: units.gu(32) |
201 | + |
202 | + /*! |
203 | + The property holds the height reserved for the dialer hands, being the distance |
204 | + between the outer and the inner dialer disks. This value cannot be higher than |
205 | + the half of the dialer \l size. |
206 | + */ |
207 | + property real handSpace: units.gu(6.5) |
208 | + |
209 | + /*! |
210 | + \qmlproperty Item centerItem |
211 | + The property holds the component from the center of the Dialer. Items wanted |
212 | + to be placed into the center of the Dialer must be reparented to this component, |
213 | + or listed in the \l centerContent property. |
214 | + |
215 | + Beside that, the property helps anchoring the center disk content to the |
216 | + item. |
217 | + \qml |
218 | + Dialer { |
219 | + DialerHand { |
220 | + id: hand |
221 | + Label { |
222 | + parent: hand.centerItem |
223 | + // [...] |
224 | + } |
225 | + } |
226 | + // [...] |
227 | + } |
228 | + \endqml |
229 | + */ |
230 | + readonly property alias centerItem: centerHolder |
231 | + |
232 | + /*! |
233 | + \qmlproperty list<var> centerContent |
234 | + The property holds the list of items to be placed inside of the center disk. |
235 | + Items placed inside the center disk can either be listed in this property or |
236 | + reparented to \l centerItem property. |
237 | + \qml |
238 | + Dialer { |
239 | + DialerHand { |
240 | + id: hand |
241 | + centerContent: [ |
242 | + Label { |
243 | + // [...] |
244 | + } |
245 | + // [...] |
246 | + ] |
247 | + } |
248 | + // [...] |
249 | + } |
250 | + \endqml |
251 | + */ |
252 | + property alias centerContent: centerHolder.data |
253 | + |
254 | + /*! |
255 | + \qmlproperty list<DialerHands> hands |
256 | + \readonly |
257 | + The property holds the list of DialerHands added to Dialer. This may be the |
258 | + same as the children, however will contain only DialerHand objects. |
259 | + */ |
260 | + readonly property alias hands: internal.hands |
261 | + |
262 | + /*! |
263 | + \qmlmethod void handUpdated(DialerHand hand) |
264 | + The signal is emited when the hand value is updated. |
265 | + */ |
266 | + signal handUpdated(var hand) |
267 | + |
268 | + id: dialer |
269 | + implicitWidth: size |
270 | + implicitHeight: size |
271 | + |
272 | + style: Theme.createStyleComponent("DialerStyle.qml", dialer) |
273 | + |
274 | + Item { |
275 | + id: internal |
276 | + // internal property holding only the list of DialerHand components |
277 | + // workaround for readonly public property |
278 | + property var hands: [] |
279 | + |
280 | + height: size - handSpace * 2 |
281 | + width: size - handSpace * 2 |
282 | + anchors.centerIn: parent |
283 | + Item { |
284 | + id: centerHolder |
285 | + anchors.fill: parent |
286 | + z: 1 |
287 | + } |
288 | + } |
289 | + |
290 | + /*! \internal */ |
291 | + onChildrenChanged: { |
292 | + // apply dialer presets if the hand sizes were not set |
293 | + // check dialers only |
294 | + var idx = 0; |
295 | + var stack = []; |
296 | + for (var i in children) { |
297 | + if (children[i].hasOwnProperty("hand")) { |
298 | + children[i].__grabber.index = idx++; |
299 | + stack.push(children[i]); |
300 | + } |
301 | + internal.hands = stack; |
302 | + } |
303 | + } |
304 | +} |
305 | |
306 | === added file 'modules/Ubuntu/Components/Pickers/DialerHand.qml' |
307 | --- modules/Ubuntu/Components/Pickers/DialerHand.qml 1970-01-01 00:00:00 +0000 |
308 | +++ modules/Ubuntu/Components/Pickers/DialerHand.qml 2013-09-24 14:39:42 +0000 |
309 | @@ -0,0 +1,222 @@ |
310 | +/* |
311 | + * Copyright 2013 Canonical Ltd. |
312 | + * |
313 | + * This program is free software; you can redistribute it and/or modify |
314 | + * it under the terms of the GNU Lesser General Public License as published by |
315 | + * the Free Software Foundation; version 3. |
316 | + * |
317 | + * This program is distributed in the hope that it will be useful, |
318 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
319 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
320 | + * GNU Lesser General Public License for more details. |
321 | + * |
322 | + * You should have received a copy of the GNU Lesser General Public License |
323 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
324 | + */ |
325 | + |
326 | +import QtQuick 2.0 |
327 | +import "../" 0.1 |
328 | + |
329 | +/*! |
330 | + \qmltype DialerHand |
331 | + \inqmlmodule Ubuntu.Components.Pickers 0.1 |
332 | + \ingroup ubuntu-pickers |
333 | + \brief DialerHand represents a value selector on a Dialer. |
334 | + |
335 | + DialerHand components have meaning only if those are placed inside Dialer |
336 | + components. The dialer hand presents a value selection from the given dialer's |
337 | + minimum and maximum values. |
338 | + |
339 | + By default all hands are placed on the dialer's hand space, on the outer dialer |
340 | + disk. By default all hands have teh same size, 0.5GU width and height same as |
341 | + the handSpace specified in \l Dialer, however themes can specify preset values |
342 | + for each hand. |
343 | + |
344 | + Hands can also be placed onto the inner disk by setting \a hand.toCenterItem |
345 | + property to true. |
346 | + |
347 | + \qml |
348 | + Dialer { |
349 | + DialerHand { |
350 | + // this dialer hand will take the space as defined by the theme. |
351 | + } |
352 | + DialerHand { |
353 | + hand.height: units.gu(3) |
354 | + // this hand will have its width as defined by the theme |
355 | + // but height as 3 GU |
356 | + } |
357 | + } |
358 | + \endqml |
359 | + |
360 | + Items declared as children will be placed over the hands. These items will not |
361 | + be rotated togehther with the hand, these will always be shown horizontally. |
362 | + The hand can be hidden by setting false to \a hand.visible property, but that |
363 | + does not hide the overlay content. |
364 | + |
365 | + The following example demonstrates how to create a hidden dialer hand having |
366 | + an overlay component on the hand. |
367 | + \qml |
368 | + Dialer { |
369 | + DialerHand { |
370 | + id: selector |
371 | + hand.visible: false |
372 | + Rectangle { |
373 | + anchors.centerIn: parent |
374 | + width: height |
375 | + height: units.gu(3) |
376 | + radius: width / 2 |
377 | + color: Theme.palette.normal.background |
378 | + antialiasing: true |
379 | + Label { |
380 | + text: Math.round(selector.value) |
381 | + anchors.centerIn: parent |
382 | + } |
383 | + } |
384 | + } |
385 | + } |
386 | + \endqml |
387 | + */ |
388 | +StyledItem { |
389 | + id: dialerHand |
390 | + |
391 | + /*! |
392 | + The property holds the selected value the dialer hand points to. |
393 | + */ |
394 | + property real value |
395 | + |
396 | + /*! |
397 | + \qmlproperty real hand.width |
398 | + \qmlproperty real hand.height |
399 | + \qmlproperty bool hand.draggable |
400 | + \qmlproperty bool hand.toCenterItem |
401 | + \qmlproperty bool hand.visible |
402 | + |
403 | + The \b hand.width and \b hand.height properties define the size of the hand. |
404 | + The height of the hand must be in the [0..dialer.handSpace] range in order |
405 | + to have the hand displayed in the hand area, however there is no restriction |
406 | + applied on the size of the dialer hand. If no value is set, the width and |
407 | + height will be defined by the style. |
408 | + |
409 | + \b draggable property specifies whether the hand is draggable or not. When set to not draggable, |
410 | + the hand is used only to indicate the given value. The default value is true. |
411 | + |
412 | + \b toCenterItem property specifies whether the hand should be placed on the hand space (on the outer disk |
413 | + - false) or onto the center disk (inner disk - true). The default value is false, meaning the hand will be placed onto the hand space disk. |
414 | + |
415 | + \b visible property specifies whether to show the hand marker or not. The default value is true. |
416 | + */ |
417 | + property DialerHandGroup hand: DialerHandGroup { |
418 | + width: __styleInstance.handPreset(index, "width") |
419 | + height: __styleInstance.handPreset(index, "height") |
420 | + draggable: __styleInstance.handPreset(index, "draggable") |
421 | + visible: __styleInstance.handPreset(index, "visible") |
422 | + toCenterItem: __styleInstance.handPreset(index, "toCenterItem") |
423 | + } |
424 | + |
425 | + /*! |
426 | + The property holds the dialer instance the hand is assigned to. This is a |
427 | + helper property to enable access to the dialer component hosting the hand. |
428 | + */ |
429 | + readonly property Dialer dialer: parent |
430 | + |
431 | + /*! |
432 | + \qmlproperty list<QtObject> overlay |
433 | + \default |
434 | + The property holds the items that can be added on top of the hand. Note that |
435 | + these items will not be rotated together with the hand pointer and pointer |
436 | + visibility does not affect the overlay items visibility. |
437 | + */ |
438 | + default property alias overlay: contentItem.data |
439 | + |
440 | + /*! |
441 | + \qmlproperty int index |
442 | + \readonly |
443 | + The property holds the index of the hand. Note that this is not the child |
444 | + index of the dialer children, this represents the index of the DialerHand |
445 | + component added to the \l dialer. |
446 | + */ |
447 | + readonly property alias index: grabber.index |
448 | + |
449 | + z: __styleInstance.handPreset(index, "z") |
450 | + anchors.centerIn: parent |
451 | + width: parent.width |
452 | + height: parent.height |
453 | + style: Theme.createStyleComponent("DialerHandStyle.qml", dialerHand) |
454 | + |
455 | + /*! \internal */ |
456 | + onParentChanged: { |
457 | + if (dialer && !dialer.hasOwnProperty("handSpace")) { |
458 | + console.log("WARNING: DialerHand can be a child of Dialer only."); |
459 | + } |
460 | + } |
461 | + |
462 | + /*! \internal */ |
463 | + onValueChanged: grabber.updateHand(); |
464 | + /*! \internal */ |
465 | + Component.onCompleted: grabber.updateHand(); |
466 | + |
467 | + /*! \internal */ |
468 | + property alias __grabber: grabber |
469 | + Item { |
470 | + id: grabber |
471 | + property int index: -1 |
472 | + parent: __styleInstance.handPointer |
473 | + width: units.gu(4) |
474 | + height: parent.height |
475 | + anchors { |
476 | + top: parent.top |
477 | + horizontalCenter: parent.horizontalCenter |
478 | + } |
479 | + Item { |
480 | + id: contentItem |
481 | + anchors.fill: parent |
482 | + rotation: 360 - __styleInstance.rotation |
483 | + } |
484 | + |
485 | + function updateHand() { |
486 | + if (!dialer || !__styleInstance) return; |
487 | + __styleInstance.rotation = |
488 | + MathUtils.projectValue(value, |
489 | + dialer.minimumValue, dialer.maximumValue, |
490 | + 0.0, 360.0); |
491 | + dialer.handUpdated(dialerHand); |
492 | + } |
493 | + |
494 | + MouseArea{ |
495 | + anchors.fill: parent; |
496 | + preventStealing: true; |
497 | + enabled: dialerHand.hand.draggable; |
498 | + property real centerX : dialerHand.width / 2 |
499 | + property real centerY : dialerHand.height / 2 |
500 | + property bool internalChange: false |
501 | + |
502 | + onPositionChanged: { |
503 | + if (internalChange) return; |
504 | + internalChange = true; |
505 | + var point = mapToItem (dialerHand, mouse.x, mouse.y); |
506 | + var diffX = (point.x - centerX); |
507 | + var diffY = -1 * (point.y - centerY); |
508 | + var rad = Math.atan (diffY / diffX); |
509 | + var deg = (rad * 180 / Math.PI); |
510 | + |
511 | + if (diffX > 0 && diffY > 0) { |
512 | + __styleInstance.rotation = 90 - Math.abs (deg); |
513 | + } |
514 | + else if (diffX > 0 && diffY < 0) { |
515 | + __styleInstance.rotation = 90 + Math.abs (deg); |
516 | + } |
517 | + else if (diffX < 0 && diffY > 0) { |
518 | + __styleInstance.rotation = 270 + Math.abs (deg); |
519 | + } |
520 | + else if (diffX < 0 && diffY < 0) { |
521 | + __styleInstance.rotation = 270 - Math.abs (deg); |
522 | + } |
523 | + |
524 | + dialerHand.value = MathUtils.projectValue(__styleInstance.rotation, |
525 | + 0.0, 360.0, |
526 | + dialer.minimumValue, dialer.maximumValue); |
527 | + internalChange = false; |
528 | + } |
529 | + } |
530 | + } |
531 | +} |
532 | |
533 | === added file 'modules/Ubuntu/Components/Pickers/DialerHandGroup.qml' |
534 | --- modules/Ubuntu/Components/Pickers/DialerHandGroup.qml 1970-01-01 00:00:00 +0000 |
535 | +++ modules/Ubuntu/Components/Pickers/DialerHandGroup.qml 2013-09-24 14:39:42 +0000 |
536 | @@ -0,0 +1,29 @@ |
537 | +/* |
538 | + * Copyright 2013 Canonical Ltd. |
539 | + * |
540 | + * This program is free software; you can redistribute it and/or modify |
541 | + * it under the terms of the GNU Lesser General Public License as published by |
542 | + * the Free Software Foundation; version 3. |
543 | + * |
544 | + * This program is distributed in the hope that it will be useful, |
545 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
546 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
547 | + * GNU Lesser General Public License for more details. |
548 | + * |
549 | + * You should have received a copy of the GNU Lesser General Public License |
550 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
551 | + */ |
552 | +import QtQuick 2.0 |
553 | +import "../" 0.1 |
554 | + |
555 | +/*! |
556 | + \internal |
557 | + Component serving as group property for DialerHhand.hand property. |
558 | + */ |
559 | +QtObject { |
560 | + property real width: units.gu(0.5) |
561 | + property real height: parent.dialer.handSize |
562 | + property bool draggable: true |
563 | + property bool visible: true |
564 | + property bool toCenterItem: false |
565 | +} |
566 | |
567 | === modified file 'modules/Ubuntu/Components/Pickers/qmldir' |
568 | --- modules/Ubuntu/Components/Pickers/qmldir 2013-09-09 09:06:41 +0000 |
569 | +++ modules/Ubuntu/Components/Pickers/qmldir 2013-09-24 14:39:42 +0000 |
570 | @@ -1,3 +1,5 @@ |
571 | module Ubuntu.Components.Pickers |
572 | Picker 0.1 Picker.qml |
573 | PickerDelegate 0.1 PickerDelegate.qml |
574 | +Dialer 0.1 Dialer.qml |
575 | +DialerHand 0.1 DialerHand.qml |
576 | |
577 | === added file 'modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.qml' |
578 | --- modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.qml 1970-01-01 00:00:00 +0000 |
579 | +++ modules/Ubuntu/Components/Themes/Ambiance/DialerHandStyle.qml 2013-09-24 14:39:42 +0000 |
580 | @@ -0,0 +1,63 @@ |
581 | +/* |
582 | + * Copyright 2013 Canonical Ltd. |
583 | + * |
584 | + * This program is free software; you can redistribute it and/or modify |
585 | + * it under the terms of the GNU Lesser General Public License as published by |
586 | + * the Free Software Foundation; version 3. |
587 | + * |
588 | + * This program is distributed in the hope that it will be useful, |
589 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
590 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
591 | + * GNU Lesser General Public License for more details. |
592 | + * |
593 | + * You should have received a copy of the GNU Lesser General Public License |
594 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
595 | + */ |
596 | + |
597 | +import QtQuick 2.0 |
598 | +import Ubuntu.Components 0.1 |
599 | + |
600 | +Item { |
601 | + // style API |
602 | + property alias handPointer: pointer |
603 | + |
604 | + function handPreset(index, property) { |
605 | + switch (property) { |
606 | + case "width" : |
607 | + return (index === 0) ? units.gu(0.8) : units.gu(0.5); |
608 | + case "height": |
609 | + return (index === 0) ? dialer.handSpace /2 : |
610 | + (index === 2) ? dialer.handSpace + units.gu(1.5) : |
611 | + dialer.handSpace - units.gu(1.5); |
612 | + case "z": |
613 | + return (index === 2) ? -1 : 0; |
614 | + case "visible": |
615 | + case "draggable": |
616 | + return true; |
617 | + case "toCenterItem": |
618 | + return false; |
619 | + default: |
620 | + return undefined; |
621 | + } |
622 | + } |
623 | + |
624 | + // style |
625 | + anchors.fill: parent |
626 | + transformOrigin: Item.Center |
627 | + |
628 | + Rectangle { |
629 | + id: pointer |
630 | + x: (parent.width - width) / 2 |
631 | + y: styledItem.dialer.handSpace - (styledItem.hand.toCenterItem ? 0 : styledItem.hand.height) |
632 | + width: styledItem.hand.width |
633 | + height: styledItem.hand.height |
634 | + radius: units.gu(1) |
635 | + color: styledItem.hand.visible ? Theme.palette.normal.baseText : "#00000000" |
636 | + antialiasing: true |
637 | + } |
638 | + |
639 | + Behavior on rotation { |
640 | + enabled: !styledItem.hand.draggable |
641 | + RotationAnimation { direction: RotationAnimation.Shortest } |
642 | + } |
643 | +} |
644 | |
645 | === added file 'modules/Ubuntu/Components/Themes/Ambiance/DialerStyle.qml' |
646 | --- modules/Ubuntu/Components/Themes/Ambiance/DialerStyle.qml 1970-01-01 00:00:00 +0000 |
647 | +++ modules/Ubuntu/Components/Themes/Ambiance/DialerStyle.qml 2013-09-24 14:39:42 +0000 |
648 | @@ -0,0 +1,126 @@ |
649 | +/* |
650 | + * Copyright 2013 Canonical Ltd. |
651 | + * |
652 | + * This program is free software; you can redistribute it and/or modify |
653 | + * it under the terms of the GNU Lesser General Public License as published by |
654 | + * the Free Software Foundation; version 3. |
655 | + * |
656 | + * This program is distributed in the hope that it will be useful, |
657 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
658 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
659 | + * GNU Lesser General Public License for more details. |
660 | + * |
661 | + * You should have received a copy of the GNU Lesser General Public License |
662 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
663 | + */ |
664 | + |
665 | +import QtQuick 2.0 |
666 | +import Ubuntu.Components 0.1 |
667 | +import QtGraphicalEffects 1.0 |
668 | + |
669 | +// FIXME: Replace this once UbuntuShape support for gradients and shading has landed |
670 | +Rectangle { |
671 | + anchors.fill: parent |
672 | + radius: width / 2 |
673 | + antialiasing: true |
674 | + |
675 | + property real offset : units.gu(0.2) |
676 | + |
677 | + gradient: Gradient { |
678 | + GradientStop { position: 0.0; color: "#512F48" } |
679 | + GradientStop { position: 0.25; color: "#583048" } |
680 | + GradientStop { position: 0.5; color: "#653449" } |
681 | + GradientStop { position: 0.75; color: "#6D384A" } |
682 | + GradientStop { position: 1.0; color: "#753B4A" } |
683 | + } |
684 | + // draws the outter shadow/highlight |
685 | + Rectangle { |
686 | + id: sourceOutter |
687 | + anchors { fill: parent; margins: -offset } |
688 | + radius: (width / 2) |
689 | + antialiasing: true |
690 | + gradient: Gradient { |
691 | + GradientStop { position: 0.0; color: "black" } |
692 | + GradientStop { position: 0.5; color: "transparent" } |
693 | + GradientStop { position: 1.0; color: "white" } |
694 | + } |
695 | + } |
696 | + |
697 | + // mask for outer 3D effect |
698 | + Rectangle { |
699 | + id: maskOutter |
700 | + anchors.fill: sourceOutter |
701 | + color: "transparent" |
702 | + radius: (width / 2) |
703 | + antialiasing: true |
704 | + border { width: offset; color: "black" } |
705 | + } |
706 | + |
707 | + // outter effect |
708 | + OpacityMask { |
709 | + anchors.fill: sourceOutter |
710 | + opacity: 0.65 |
711 | + source: ShaderEffectSource { |
712 | + sourceItem: sourceOutter |
713 | + hideSource: true |
714 | + } |
715 | + maskSource: ShaderEffectSource { |
716 | + sourceItem: maskOutter |
717 | + hideSource: true |
718 | + } |
719 | + } |
720 | + |
721 | + // center item |
722 | + // FIXME: Replace this once UbuntuShape support for gradients and shading has landed |
723 | + Rectangle { |
724 | + parent: styledItem.centerItem.parent |
725 | + anchors.fill: parent |
726 | + radius: width / 2; |
727 | + antialiasing: true; |
728 | + |
729 | + gradient: Gradient { |
730 | + GradientStop { position: 0.0; color: "#7A4C68" } |
731 | + GradientStop { position: 0.25; color: "#804563" } |
732 | + GradientStop { position: 0.5; color: "#864660" } |
733 | + GradientStop { position: 0.75; color: "#86465E" } |
734 | + GradientStop { position: 1.0; color: "#964E66" } |
735 | + } |
736 | + |
737 | + // draws the inner highlight / shadow |
738 | + Rectangle { |
739 | + id: sourceInner; |
740 | + anchors { fill: parent; margins: -offset } |
741 | + radius: (width / 2) |
742 | + antialiasing: true |
743 | + gradient: Gradient { |
744 | + GradientStop { position: 0.0; color: "white" } |
745 | + GradientStop { position: 0.5; color: "transparent" } |
746 | + GradientStop { position: 1.0; color: "black" } |
747 | + } |
748 | + } |
749 | + |
750 | + // mask for inner 3D effect |
751 | + Rectangle { |
752 | + id: maskInner |
753 | + color: "transparent" |
754 | + anchors.fill: sourceInner |
755 | + radius: (width / 2) |
756 | + antialiasing: true |
757 | + border { width: offset; color: "black" } |
758 | + } |
759 | + |
760 | + // inner effect |
761 | + OpacityMask { |
762 | + opacity: 0.65 |
763 | + anchors.fill: sourceInner |
764 | + source: ShaderEffectSource { |
765 | + sourceItem: sourceInner |
766 | + hideSource: true |
767 | + } |
768 | + maskSource: ShaderEffectSource { |
769 | + sourceItem: maskInner |
770 | + hideSource: true |
771 | + } |
772 | + } |
773 | + } |
774 | +} |
775 | |
776 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/qmldir' |
777 | --- modules/Ubuntu/Components/Themes/Ambiance/qmldir 2013-09-06 13:38:06 +0000 |
778 | +++ modules/Ubuntu/Components/Themes/Ambiance/qmldir 2013-09-24 14:39:42 +0000 |
779 | @@ -22,3 +22,5 @@ |
780 | internal BubbleShape BubbleShape.qml |
781 | PickerStyle 0.1 PickerStyle.qml |
782 | PickerDelegateStyle 0.1 PickerDelegateStyle.qml |
783 | +DialerStyle 0.1 DialerStyle.qml |
784 | +DialerHandStyle 0.1 DialerHandStyle.qml |
785 | |
786 | === added file 'tests/unit_x11/tst_components/tst_dialer.qml' |
787 | --- tests/unit_x11/tst_components/tst_dialer.qml 1970-01-01 00:00:00 +0000 |
788 | +++ tests/unit_x11/tst_components/tst_dialer.qml 2013-09-24 14:39:42 +0000 |
789 | @@ -0,0 +1,175 @@ |
790 | +/* |
791 | + * Copyright 2012 Canonical Ltd. |
792 | + * |
793 | + * This program is free software; you can redistribute it and/or modify |
794 | + * it under the terms of the GNU Lesser General Public License as published by |
795 | + * the Free Software Foundation; version 3. |
796 | + * |
797 | + * This program is distributed in the hope that it will be useful, |
798 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
799 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
800 | + * GNU Lesser General Public License for more details. |
801 | + * |
802 | + * You should have received a copy of the GNU Lesser General Public License |
803 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
804 | + */ |
805 | + |
806 | +import QtQuick 2.0 |
807 | +import QtTest 1.0 |
808 | +import Ubuntu.Test 0.1 |
809 | +import Ubuntu.Components 0.1 |
810 | +import Ubuntu.Components.Pickers 0.1 |
811 | + |
812 | +Item { |
813 | + id: root |
814 | + width: 200 |
815 | + height: 200 |
816 | + |
817 | + Dialer { |
818 | + id: noHands |
819 | + } |
820 | + Dialer { |
821 | + id: oneHand |
822 | + DialerHand { |
823 | + id: hand |
824 | + } |
825 | + } |
826 | + Dialer { |
827 | + DialerHand { |
828 | + id: overlayHand |
829 | + Label { |
830 | + id: overlayItem |
831 | + text: overlayHand.value |
832 | + } |
833 | + } |
834 | + } |
835 | + |
836 | + SignalSpy { |
837 | + id: spy |
838 | + } |
839 | + |
840 | + TestCase { |
841 | + id: testCase |
842 | + name: "DialerAPI" |
843 | + when: windowShown |
844 | + |
845 | + function test_0_Dialer_minimumValue() { |
846 | + compare(noHands.minimumValue, 0.0, "noHands.minimumValue"); |
847 | + compare(oneHand.minimumValue, 0.0, "oneHand.minimumValue"); |
848 | + } |
849 | + |
850 | + function test_0_Dialer_maximumValue() { |
851 | + compare(noHands.maximumValue, 360.0, "noHands.maximumValue"); |
852 | + compare(oneHand.maximumValue, 360.0, "oneHand.maximumValue"); |
853 | + } |
854 | + |
855 | + function test_0_Dialer_size() { |
856 | + compare(noHands.size, units.gu(32), "noHands.size"); |
857 | + compare(oneHand.size, units.gu(32), "oneHand.size"); |
858 | + } |
859 | + |
860 | + function test_0_Dialer_handSpace() { |
861 | + compare(noHands.handSpace, units.gu(6.5), "noHands.handSpace"); |
862 | + compare(oneHand.handSpace, units.gu(6.5), "oneHand.handSpace"); |
863 | + } |
864 | + |
865 | + function test_0_Dialer_centerItem() { |
866 | + verify(noHands.centerItem !== undefined, "noHands.centerItem"); |
867 | + verify(oneHand.centerItem !== undefined, "oneHand.centerItem"); |
868 | + } |
869 | + |
870 | + function test_0_Dialer_centerContent() { |
871 | + verify(noHands.centerContent !== undefined, "noHands.centerContent"); |
872 | + verify(oneHand.centerContent !== undefined, "oneHand.centerContent"); |
873 | + } |
874 | + |
875 | + function test_0_Dialer_hands() { |
876 | + verify(noHands.hands !== undefined, "hoHands.hands is defined"); |
877 | + compare(noHands.hands.length, 0, "noHands.hands.length"); |
878 | + compare(oneHand.hands.length, 1, "noHands.hands.length"); |
879 | + compare(oneHand.hands[0], hand, "noHands.hands[0] == hand"); |
880 | + } |
881 | + |
882 | + function test_0_DialerHand_value() { |
883 | + compare(hand.value, 0.0, "hand.value"); |
884 | + } |
885 | + |
886 | + function test_0_DialerHand_hand_height() { |
887 | + verify(hand.hand.height !== 0.0, "hand.hand.height"); |
888 | + } |
889 | + |
890 | + function test_0_DialerHand_hand_width() { |
891 | + verify(hand.hand.width !== 0.0, "hand.hand.width"); |
892 | + } |
893 | + |
894 | + function test_0_DialerHand_hand_draggable() { |
895 | + compare(hand.hand.draggable, true, "hand.hand.draggable"); |
896 | + } |
897 | + |
898 | + function test_0_DialerHand_hand_visible() { |
899 | + compare(hand.hand.visible, true, "hand.hand.visible"); |
900 | + } |
901 | + |
902 | + function test_0_DialerHand_hand_toCenterItem() { |
903 | + compare(hand.hand.toCenterItem, false, "hand.hand.toCenterItem"); |
904 | + } |
905 | + |
906 | + function test_0_DialerHand_index() { |
907 | + compare(hand.index, 0, "hand.index"); |
908 | + } |
909 | + |
910 | + function test_0_DialerHand_dialer() { |
911 | + compare(hand.dialer, oneHand, "hand.dialer"); |
912 | + } |
913 | + |
914 | + function test_0_DialerHand_overlay() { |
915 | + verify(hand.overlay !== undefined, "hand.overlay"); |
916 | + } |
917 | + |
918 | + function test_DialerHand_valueChange() { |
919 | + spy.clear(); |
920 | + spy.signalName = "onHandUpdated"; |
921 | + spy.target = oneHand; |
922 | + hand.value = 100; |
923 | + compare(hand.value, 100, "hand.value changed"); |
924 | + tryCompare(spy, "count", 1); |
925 | + } |
926 | + |
927 | + function test_DialerHand_hand_toCenterItem_Change() { |
928 | + hand.hand.toCenterItem = true; |
929 | + compare(hand.hand.toCenterItem, true, "hand.hand.toCenterItem changed"); |
930 | + } |
931 | + |
932 | + function test_DialerHand_hand_draggable_Change() { |
933 | + hand.hand.draggable = false; |
934 | + compare(hand.hand.draggable, false, "hand.hand.draggable changed"); |
935 | + } |
936 | + |
937 | + function test_DialerHand_handSizeChange() { |
938 | + var prevHeight = hand.hand.height; |
939 | + hand.hand.height = units.gu(10); |
940 | + verify(hand.hand.height !== prevHeight, "hand.hand.height"); |
941 | + compare(hand.hand.height, units.gu(10), "hand.hand.height changed"); |
942 | + |
943 | + var prevWidth = hand.hand.width; |
944 | + hand.hand.width = units.gu(10); |
945 | + verify(hand.hand.width !== prevWidth, "hand.hand.width"); |
946 | + compare(hand.hand.width, units.gu(10), "hand.hand.width changed"); |
947 | + } |
948 | + |
949 | + function test_OverlayHand_visible() { |
950 | + overlayHand.hand.visible = false; |
951 | + compare(overlayItem.visible, true, "overLayItem.visible"); |
952 | + } |
953 | + |
954 | + function test_OverlayHand_rotation() { |
955 | + overlayHand.value = 50; |
956 | + compare(overlayItem.rotation, 0.0, "overLayItem.rotation"); |
957 | + } |
958 | + |
959 | + function test_OverlayHand_valueChange() { |
960 | + overlayHand.value = 70; |
961 | + compare(overlayItem.text, "70", "overLayItem.text"); |
962 | + } |
963 | + } |
964 | +} |
API docs in https:/ /docs.google. com/a/canonical .com/document/ d/1MLhXE8WM7xUW 2hiuLLgwuXT066Y -v8qQSRlfIdkT5F g/edit#