on xenial help sign in
Behavioural changes for indicators - Part 1
bc65d02Nick Dedekind
Panel/IndicatorItem.qml+5
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
20+import "../Components"
20
21
21Item {
22Item {
22 id: indicatorItem
23 id: indicatorItem
@@ -27,6 +28,7 @@ Item {
27 property var indicatorProperties: undefined
28 property var indicatorProperties: undefined
28
29
29 opacity: dimmed ? 0.4 : 1
30 opacity: dimmed ? 0.4 : 1
31+ Behavior on opacity { StandardAnimation {} }
30
32
31 // only visible when non-empty
33 // only visible when non-empty
32 visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
34 visible: loader.item != undefined && loader.status == Loader.Ready ? loader.item.enabled : false
@@ -53,5 +55,8 @@ Item {
53 width: parent.width
55 width: parent.width
54 anchors.top: parent.bottom
56 anchors.top: parent.bottom
55 visible: highlighted
57 visible: highlighted
58+
59+ opacity: highlighted ? 1 : 0
60+ Behavior on opacity { StandardAnimation {} }
56 }
61 }
57}
62}
Panel/IndicatorRow.qml+34−48
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import "../Components"
19
20
20Item {
21Item {
21 id: indicatorRow
22 id: indicatorRow
@@ -25,21 +26,18 @@ Item {
25 property alias row: row
26 property alias row: row
26 property QtObject indicatorsModel: null
27 property QtObject indicatorsModel: null
27
28
28− Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic} }
29−
30 width: units.gu(40)
29 width: units.gu(40)
31 height: units.gu(3)
30 height: units.gu(3)
32
31
33− Component.onCompleted: setDefaultItem()
34−
35 function setDefaultItem() {
32 function setDefaultItem() {
36 // The leftmost indicator
33 // The leftmost indicator
37− var defaultItemIndex = 0
34+ setCurrentItem(0);
38− setItem(defaultItemIndex)
39 }
35 }
40
36
41− function setItem(index) {
37+ function setCurrentItem(index) {
38+ if (currentItemIndex !== index) {
42− currentItem = rowRepeater.itemAt(index)
39+ currentItem = rowRepeater.itemAt(index);
40+ }
43 }
41 }
44
42
45 Row {
43 Row {
@@ -54,51 +52,39 @@ Item {
54 objectName: "rowRepeater"
52 objectName: "rowRepeater"
55 model: indicatorsModel ? indicatorsModel : undefined
53 model: indicatorsModel ? indicatorsModel : undefined
56
54
57− IndicatorItem {
55+ Item {
58− id: indicatorItem
56+ id: itemWrapper
57+ height: indicatorRow.height
58+ width: childrenRect.width
59
59
60− property int ownIndex: index
60+ property int ownIndex: index
61+ property alias highlighted: indicatorItem.highlighted
62+ property alias dimmed: indicatorItem.dimmed
61
63
64+ IndicatorItem {
65+ id: indicatorItem
66+ height: parent.height
67+
68+ highlighted: indicatorRow.state != "initial" ? itemWrapper.ownIndex == indicatorRow.currentItemIndex : false
69+ dimmed: indicatorRow.state != "initial" ? itemWrapper.ownIndex != indicatorRow.currentItemIndex : false
70+
62− widgetSource: model.widgetSource
71+ widgetSource: model.widgetSource
72+ indicatorProperties : model.indicatorProperties
73+ }
63
74
64− indicatorProperties : model.indicatorProperties
75+ opacity: {
65− highlighted: indicatorRow.state == "reveal" || indicatorRow.state == "locked" || indicatorRow.state == "commit" ? ownIndex == indicatorRow.currentItemIndex : false
66− dimmed: { //See FIXME in Indicators regarding the "states" change
67− if (indicatorRow.state == "initial" || indicatorRow.state == "") {
68− return false;
69− } else if (indicatorRow.state == "hint") {
70− return true
71− } else {
72− return ownIndex != indicatorRow.currentItemIndex
73− }
74− }
75− height: indicatorRow.height
76− y: {
77− //FIXME: all indicators will be initial for now.
78− if (!highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
76+ if (!indicatorItem.highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")) {
79− return -indicatorRow.height
77+ return 0.0;
80− } else {
78+ } else {
81− return 0
82− }
83− }
84− Behavior on y {
85− NumberAnimation{
86− duration: {
87− if (index == 0) {
88− return 250
79+ return 1.0;
89− } else if (index == 1) {
90− return 150
91− } else if (index == 2) {
92− return 550
93− } else if (index == 3) {
94− return 400
95− } else {
96− return 100 + Math.random() * 200
97− }
98− }
99− easing.type: Easing.OutCubic
100 }
80 }
101 }
81 }
82+ Behavior on opacity {
83+ StandardAnimation {
84+ // flow away from current index
85+ duration: (rowRepeater.count - Math.abs(indicatorRow.currentItemIndex - index)) * (500/rowRepeater.count)
86+ }
87+ }
102 }
88 }
103 }
89 }
104 }
90 }
Panel/Indicators.qml+89−102
@@ -25,16 +25,15 @@ import "../Components/Math.js" as MathLocal
25Showable {
25Showable {
26 id: indicators
26 id: indicators
27
27
28− property int referenceOpenedHeight: units.gu(71)
28+ property real openedHeight: units.gu(71)
29− property real openedHeight: pinnedMode ? referenceOpenedHeight - panelHeight
30− : referenceOpenedHeight
31 property int panelHeight: units.gu(3)
29 property int panelHeight: units.gu(3)
32 property bool pinnedMode: true //should be set true if indicators menu can cover whole screen
30 property bool pinnedMode: true //should be set true if indicators menu can cover whole screen
33
31
34 property int hintValue
32 property int hintValue
35− readonly property int lockThreshold: referenceOpenedHeight / 2
33+ readonly property int lockThreshold: openedHeight / 2
36 property bool fullyOpened: height == openedHeight
34 property bool fullyOpened: height == openedHeight
37 property bool partiallyOpened: height > panelHeight && !fullyOpened
35 property bool partiallyOpened: height > panelHeight && !fullyOpened
36+ property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
38
37
39 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
38 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
40 // use its own values. Need to ask design about this.
39 // use its own values. Need to ask design about this.
@@ -43,6 +42,13 @@ Showable {
43 duration: 350
42 duration: 350
44 to: openedHeight
43 to: openedHeight
45 easing.type: Easing.OutCubic
44 easing.type: Easing.OutCubic
45+
46+ // Re-size if we've changed the openHeight while shown.
47+ onToChanged: {
48+ if (indicators.shown) {
49+ indicators.show();
50+ }
51+ }
46 }
52 }
47
53
48 hideAnimation: StandardAnimation {
54 hideAnimation: StandardAnimation {
@@ -56,28 +62,30 @@ Showable {
56
62
57 onHeightChanged: {
63 onHeightChanged: {
58 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
64 // need to use handle.get_height(). As the handle height depends on indicators.height changes (but this is called first!)
59− var contentProgress = indicators.height - handle.get_height();
65+ var revealProgress = indicators.height - panelHeight
60 if (!showAnimation.running && !hideAnimation.running) {
66 if (!showAnimation.running && !hideAnimation.running) {
67+ if (revealProgress == 0) {
61− if (contentProgress <= hintValue && indicators.state == "reveal") {
68+ indicators.state = "initial";
69+ } else if (revealProgress <= hintValue) {
62 indicators.state = "hint";
70 indicators.state = "hint";
63− } else if (contentProgress > hintValue && contentProgress < lockThreshold) {
71+ } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
64 indicators.state = "reveal";
72 indicators.state = "reveal";
65− } else if (contentProgress >= lockThreshold && lockThreshold > 0) {
73+ } else if (revealProgress >= lockThreshold && lockThreshold > 0) {
66 indicators.state = "locked";
74 indicators.state = "locked";
67 }
75 }
68 }
76 }
69
77
70− if (contentProgress == 0) {
78+ if (revealProgress == 0) {
71 menuContent.releaseContent();
79 menuContent.releaseContent();
72 }
80 }
73 }
81 }
74
82
75 function calculateCurrentItem(xValue, useBuffer) {
83 function calculateCurrentItem(xValue, useBuffer) {
76− var rowCoordinates
84+ var rowCoordinates;
77− var itemCoordinates
85+ var itemCoordinates;
78− var currentItem
86+ var currentItem;
79− var distanceFromRightEdge
87+ var distanceFromRightEdge;
80− var bufferExceeded = false
88+ var bufferExceeded = false;
81
89
82 if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return;
90 if (indicators.state == "commit" || indicators.state == "locked" || showAnimation.running || hideAnimation.running) return;
83
91
@@ -90,6 +98,14 @@ Showable {
90 MathLocal.clamp((indicators.height - handle.height - hintValue) /
98 MathLocal.clamp((indicators.height - handle.height - hintValue) /
91 (lockThreshold - hintValue), 0, 1);
99 (lockThreshold - hintValue), 0, 1);
92
100
101+ /*
102+ Vertical velocity check. Don't change the indicator if we're moving too quickly.
103+ */
104+ var verticalSpeed = Math.abs(yVelocityCalculator.calculate());
105+ if (verticalSpeed >= 0.05 && indicatorRow.currentItem!=null) {
106+ return;
107+ }
108+
93 /*
109 /*
94 Percentage of an indicator icon's width the user's press can stray horizontally from the
110 Percentage of an indicator icon's width the user's press can stray horizontally from the
95 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
111 focused icon before we change focus to another icon. E.g. a value of 0.5 means you must
@@ -110,7 +126,7 @@ Showable {
110 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
126 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
111 if (currentItem && currentItem != indicatorRow.currentItem ) {
127 if (currentItem && currentItem != indicatorRow.currentItem ) {
112 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
128 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
113− distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width)
129+ distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
114 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
130 if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
115 bufferExceeded = true;
131 bufferExceeded = true;
116 } else {
132 } else {
@@ -123,6 +139,8 @@ Showable {
123 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
139 if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
124 indicatorRow.currentItem = currentItem;
140 indicatorRow.currentItem = currentItem;
125 }
141 }
142+ } else if (!currentItem) {
143+ indicatorRow.setDefaultItem();
126 }
144 }
127 }
145 }
128
146
@@ -155,13 +173,20 @@ Showable {
155 left: parent.left
173 left: parent.left
156 right: parent.right
174 right: parent.right
157 top: indicatorRow.bottom
175 top: indicatorRow.bottom
158− bottom: parent.bottom
176+ bottom: handle.top
159 }
177 }
160 indicatorsModel: indicatorsModel
178 indicatorsModel: indicatorsModel
161 clip: !indicators.fullyOpened
179 clip: !indicators.fullyOpened
162
180
163− onMenuSelected: {
181+ Connections {
164− indicatorRow.setItem(index)
182+ target: indicatorRow
183+ onCurrentItemIndexChanged: menuContent.updateCurrentMenu();
184+ }
185+
186+ function updateCurrentMenu() {
187+ if (currentMenuIndex != indicatorRow.currentItemIndex) {
188+ currentMenuIndex = indicatorRow.currentItemIndex;
189+ }
165 }
190 }
166
191
167 //small shadow gradient at bottom of menu
192 //small shadow gradient at bottom of menu
@@ -188,7 +213,7 @@ Showable {
188 anchors {
213 anchors {
189 left: parent.left
214 left: parent.left
190 right: parent.right
215 right: parent.right
191− top: menuContent.bottom
216+ bottom: parent.bottom
192 }
217 }
193 height: get_height()
218 height: get_height()
194 clip: height < handleImage.height
219 clip: height < handleImage.height
@@ -212,33 +237,14 @@ Showable {
212 }
237 }
213 }
238 }
214
239
215− PanelSeparatorLine {
216− id: indicatorsSeparatorLine
217− visible: true
218− anchors {
219− top: handle.bottom
220− left: indicators.left
221− right: indicators.right
222− }
223− }
224−
225− BorderImage {
226− id: dropShadow
227− anchors {
228− top: indicators.top
229− bottom: indicatorsSeparatorLine.bottom
230− left: indicators.left
231− right: indicators.right
232− margins: -units.gu(1)
233− }
234− visible: indicators.height > panelHeight
235− source: "graphics/rectangular_dropshadow.sci"
236− }
237−
238 PanelBackground {
240 PanelBackground {
239 anchors.fill: indicatorRow
241 anchors.fill: indicatorRow
240 }
242 }
241
243
244+ IndicatorsDataModel {
245+ id: indicatorsModel
246+ }
247+
242 IndicatorRow {
248 IndicatorRow {
243 id: indicatorRow
249 id: indicatorRow
244 objectName: "indicatorRow"
250 objectName: "indicatorRow"
@@ -250,58 +256,45 @@ Showable {
250 indicatorsModel: indicatorsModel
256 indicatorsModel: indicatorsModel
251 state: indicators.state
257 state: indicators.state
252
258
253− onCurrentItemIndexChanged: menuContent.currentIndex = currentItemIndex
254−
255− }
256−
257− IndicatorsDataModel {
258− id: indicatorsModel
259− }
260−
261− Connections {
259+ Connections {
262− target: hideAnimation
260+ target: menuContent
263− onRunningChanged: {
261+ onCurrentMenuIndexChanged: {
264− if (hideAnimation.running) {
262+ indicatorRow.setCurrentItem(menuContent.currentMenuIndex);
265− indicators.state = "initial"
266− } else {
267− if (state == "initial") {
268− indicatorRow.setDefaultItem();
269− menuContent.releaseContent();
270− }
271 }
263 }
272 }
264 }
273 }
265 }
266+
274 Connections {
267 Connections {
275 target: showAnimation
268 target: showAnimation
276 onRunningChanged: {
269 onRunningChanged: {
277 if (showAnimation.running) {
270 if (showAnimation.running) {
278− indicators.calculateCurrentItem(dragHandle.touchX, false);
279 indicators.state = "commit";
271 indicators.state = "commit";
280 }
272 }
281 }
273 }
282 }
274 }
283
275
284 Connections {
276 Connections {
285− target: dragHandle
277+ target: hideAnimation
286− onTouchXChanged: {
278+ onRunningChanged: {
287− var buffer = dragHandle.dragging ? true : false;
279+ if (hideAnimation.running) {
288− indicators.calculateCurrentItem(dragHandle.touchX, buffer);
280+ indicators.state = "initial";
281+ indicatorRow.currentItem = null;
282+ }
289 }
283 }
290 }
284 }
291
285
292− // We start with pinned states. (default pinnedMode: true)
286+ property var activeDragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle.dragging ? hideDragHandle : null
293− states: pinnedModeStates
287+ // connections to the active drag handle
294− // because of dynamic assignment of states, we need to assign state after completion.
288+ Connections {
295− Component.onCompleted: state = "initial"
289+ target: activeDragHandle
296−
290+ onTouchXChanged: {
297− // changing states will reset state to "".
291+ indicators.calculateCurrentItem(activeDragHandle.touchX, true);
298− onPinnedModeChanged: {
292+ }
299− var last_state = state;
293+ onTouchSceneYChanged: {
300− states = (pinnedMode) ? pinnedModeStates : offScreenModeStates;
294+ yVelocityCalculator.trackedPosition = activeDragHandle.touchSceneY;
301− state = last_state;
295+ }
302 }
296 }
303
297
304− property var dragHandle: showDragHandle.dragging ? showDragHandle : hideDragHandle
305 DragHandle {
298 DragHandle {
306 id: showDragHandle
299 id: showDragHandle
307 anchors.bottom: parent.bottom
300 anchors.bottom: parent.bottom
@@ -315,7 +308,7 @@ Showable {
315 hintDisplacement: pinnedMode ? indicators.hintValue : 0
308 hintDisplacement: pinnedMode ? indicators.hintValue : 0
316 autoCompleteDragThreshold: maxTotalDragDistance / 2
309 autoCompleteDragThreshold: maxTotalDragDistance / 2
317 stretch: true
310 stretch: true
318− maxTotalDragDistance: openedHeight - handle.height
311+ maxTotalDragDistance: openedHeight - panelHeight
319 distanceThreshold: pinnedMode ? 0 : units.gu(3)
312 distanceThreshold: pinnedMode ? 0 : units.gu(3)
320
313
321 onStatusChanged: {
314 onStatusChanged: {
@@ -327,28 +320,40 @@ Showable {
327 DragHandle {
320 DragHandle {
328 id: hideDragHandle
321 id: hideDragHandle
329 anchors.fill: handle
322 anchors.fill: handle
330− height: panelHeight
331 direction: Direction.Upwards
323 direction: Direction.Upwards
332 enabled: indicators.shown
324 enabled: indicators.shown
333− hintDisplacement: units.gu(2)
325+ hintDisplacement: indicators.hintValue
334 autoCompleteDragThreshold: maxTotalDragDistance / 6
326 autoCompleteDragThreshold: maxTotalDragDistance / 6
335 stretch: true
327 stretch: true
336− maxTotalDragDistance: referenceOpenedHeight - 2*panelHeight
328+ maxTotalDragDistance: openedHeight - panelHeight
337 distanceThreshold: 0
329 distanceThreshold: 0
338 }
330 }
339
331
340− property list<State> offScreenModeStates: [
332+ AxisVelocityCalculator {
333+ id: yVelocityCalculator
334+ }
335+
336+ states: [
341 State {
337 State {
342 name: "initial"
338 name: "initial"
343 },
339 },
344 State {
340 State {
345 name: "hint"
341 name: "hint"
342+ PropertyChanges {
346− PropertyChanges { target: indicatorRow; y: panelHeight }
343+ target: indicatorRow;
344+ y: pinnedMode ? 0 : panelHeight
345+ }
346+ StateChangeScript {
347+ script: {
348+ if (activeDragHandle) {
349+ calculateCurrentItem(activeDragHandle.touchX, false);
350+ }
351+ }
352+ }
347 },
353 },
348 State {
354 State {
349 name: "reveal"
355 name: "reveal"
350 extend: "hint"
356 extend: "hint"
351− StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
352 },
357 },
353 State {
358 State {
354 name: "locked"
359 name: "locked"
@@ -359,25 +364,7 @@ Showable {
359 extend: "hint"
364 extend: "hint"
360 }
365 }
361 ]
366 ]
362−
363− property list<State> pinnedModeStates: [
364− State {
365− name: "initial"
367+ state: "initial"
366− },
367− State {
368− name: "hint"
369− },
370− State {
371− name: "reveal"
372− StateChangeScript { script: calculateCurrentItem(dragHandle.touchX, false); }
373− },
374− State {
375− name: "locked"
376− },
377− State {
378− name: "commit"
379− }
380− ]
381
368
382 transitions: [
369 transitions: [
383 Transition {
370 Transition {
Panel/MenuContent.qml+2−2
@@ -24,7 +24,7 @@ Rectangle {
24
24
25 property QtObject indicatorsModel: null
25 property QtObject indicatorsModel: null
26 property bool __contentActive: false
26 property bool __contentActive: false
27− property alias currentIndex : menus.currentIndex
27+ property alias currentMenuIndex : menus.currentIndex
28 property color backgroundColor: "#221e1c" // FIXME not in palette yet
28 property color backgroundColor: "#221e1c" // FIXME not in palette yet
29 property int contentReleaseInterval: 20000
29 property int contentReleaseInterval: 20000
30
30
@@ -146,7 +146,7 @@ Rectangle {
146 Indicators.MenuContentActivator {
146 Indicators.MenuContentActivator {
147 id: menuActivator
147 id: menuActivator
148 running: content.__contentActive
148 running: content.__contentActive
149− baseIndex: content.currentIndex
149+ baseIndex: content.currentMenuIndex
150 count: indicatorsModel.count
150 count: indicatorsModel.count
151 }
151 }
152}
152}
Panel/Panel.qml+28−9
@@ -39,11 +39,8 @@ Item {
39 }
39 }
40 height: __panelMinusSeparatorLineHeight
40 height: __panelMinusSeparatorLineHeight
41 y: 0
41 y: 0
42− onYChanged: indicatorsMenu.y = y;
43
42
44− Behavior on y {
43+ Behavior on y { StandardAnimation {} }
45− NumberAnimation { duration: 200 }
46− }
47 }
44 }
48
45
49 PanelSeparatorLine {
46 PanelSeparatorLine {
@@ -78,18 +75,40 @@ Item {
78 id: indicatorsMenu
75 id: indicatorsMenu
79
76
80 anchors.right: parent.right
77 anchors.right: parent.right
81− y: 0
78+ y: panelBackground.y
82 width: root.indicatorsMenuWidth
79 width: root.indicatorsMenuWidth
83 shown: false
80 shown: false
84 hintValue: __panelMinusSeparatorLineHeight * 3
81 hintValue: __panelMinusSeparatorLineHeight * 3
85 panelHeight: __panelMinusSeparatorLineHeight
82 panelHeight: __panelMinusSeparatorLineHeight
86− referenceOpenedHeight: parent.height
83+ openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
87−
88 pinnedMode: !fullscreenMode
84 pinnedMode: !fullscreenMode
89
85
90 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
86 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
91 }
87 }
92
88
89+ PanelSeparatorLine {
90+ id: indicatorsSeparatorLine
91+ visible: true
92+ anchors {
93+ left: indicatorsMenu.left
94+ right: indicatorsMenu.right
95+ }
96+ y: indicatorsMenu.visualBottom
97+ }
98+
99+ BorderImage {
100+ id: dropShadow
101+ anchors {
102+ top: indicators.top
103+ bottom: indicatorsSeparatorLine.bottom
104+ left: indicators.left
105+ right: indicators.right
106+ margins: -units.gu(1)
107+ }
108+ visible: indicatorsMenu.height > indicatorsMenu.panelHeight
109+ source: "graphics/rectangular_dropshadow.sci"
110+ }
111+
93 SearchIndicator {
112 SearchIndicator {
94 id: search
113 id: search
95 objectName: "search"
114 objectName: "search"
@@ -98,14 +117,14 @@ Item {
98 state: {
117 state: {
99 if (parent.width < indicatorsMenu.width + width) {
118 if (parent.width < indicatorsMenu.width + width) {
100 if (indicatorsMenu.state != "initial") {
119 if (indicatorsMenu.state != "initial") {
101− return "hiddenUp";
120+ return "hidden";
102 }
121 }
103 }
122 }
104 if (root.searchVisible) {
123 if (root.searchVisible) {
105 return "visible";
124 return "visible";
106 }
125 }
107
126
108− return "hiddenUp";
127+ return "hidden";
109 }
128 }
110
129
111 width: units.gu(13)
130 width: units.gu(13)
Panel/SearchIndicator.qml+3−5
@@ -16,6 +16,7 @@
16
16
17import QtQuick 2.0
17import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19+import "../Components"
19
20
20Item {
21Item {
21 id: search
22 id: search
@@ -40,8 +41,7 @@ Item {
40 width: parent.width
41 width: parent.width
41 height: parent.height
42 height: parent.height
42
43
43− Behavior on opacity {NumberAnimation {}}
44+ Behavior on opacity { StandardAnimation {} }
44− Behavior on y {NumberAnimation {duration: 300; easing.type: Easing.OutCubic}}
45
45
46 Image {
46 Image {
47 id: icon
47 id: icon
@@ -67,15 +67,13 @@ Item {
67 name: "visible"
67 name: "visible"
68 PropertyChanges {
68 PropertyChanges {
69 target: container
69 target: container
70− y: 0
71 opacity: 1
70 opacity: 1
72 }
71 }
73 },
72 },
74 State {
73 State {
75− name: "hiddenUp"
74+ name: "hidden"
76 PropertyChanges {
75 PropertyChanges {
77 target: container
76 target: container
78− y: -height
79 opacity: 0
77 opacity: 0
80 }
78 }
81 }
79 }
tests/qmltests/Panel/tst_IndicatorItem.qml+10−16
@@ -34,34 +34,28 @@ Rectangle {
34 UT.UnityTestCase {
34 UT.UnityTestCase {
35 name: "IndicatorItem"
35 name: "IndicatorItem"
36
36
37− function init_test() {
38− }
39−
40 function test_dimmed() {
37 function test_dimmed() {
41− init_test()
42−
43− indicatorItem.dimmed = true
38+ indicatorItem.dimmed = false;
44− compare(indicatorItem.opacity > 0, true, "IndicatorItem opacity should not be 0")
39+ tryCompareFunction(function(){return indicatorItem.opacity}, 1.0);
40+ indicatorItem.dimmed = true;
45− compare(indicatorItem.opacity < 1, true, "IndicatorItem opacity should not be 1")
41+ tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true);
46 }
42 }
47
43
48 function test_highlight() {
44 function test_highlight() {
49− var itemHighlight = findChild(indicatorItem, "highlight")
45+ var itemHighlight = findChild(indicatorItem, "highlight");
50− verify(itemHighlight != undefined)
46+ verify(itemHighlight != undefined);
51
47
52 indicatorItem.highlighted = true;
48 indicatorItem.highlighted = true;
53− compare(itemHighlight.visible, true, "Indicator should be highlighted")
49+ compare(itemHighlight.visible, true, "Indicator should be highlighted");
54
50
55 indicatorItem.highlighted = false;
51 indicatorItem.highlighted = false;
56− compare(itemHighlight.visible, false, "Indicator should not be highlighted")
52+ compare(itemHighlight.visible, false, "Indicator should not be highlighted");
57 }
53 }
58
54
59 function test_empty() {
55 function test_empty() {
60− init_test()
61−
62− compare(indicatorItem.visible, false, "IndicatorItem should not be visible.")
56+ compare(indicatorItem.visible, false, "IndicatorItem should not be visible.");
63 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
57 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
64− tryCompare(indicatorItem, "visible", true)
58+ tryCompare(indicatorItem, "visible", true);
65 }
59 }
66 }
60 }
67}
61}
tests/qmltests/Panel/tst_IndicatorRow.qml+21−21
@@ -61,13 +61,13 @@ Item {
61
61
62 function test_set_current_item() {
62 function test_set_current_item() {
63 init_test();
63 init_test();
64− indicatorRow.setItem(0);
64+ indicatorRow.setCurrentItem(0);
65 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu1", "Incorrect item at position 0");
65 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu1", "Incorrect item at position 0");
66
66
67− indicatorRow.setItem(1);
67+ indicatorRow.setCurrentItem(1);
68 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu2", "Incorrect item at position 1");
68 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu2", "Incorrect item at position 1");
69
69
70− indicatorRow.setItem(2);
70+ indicatorRow.setCurrentItem(2);
71 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu3", "Incorrect item at position 2");
71 compare(indicatorRow.indicatorsModel.get(indicatorRow.currentItemIndex).title, "Menu3", "Incorrect item at position 2");
72 }
72 }
73 }
73 }
@@ -83,13 +83,13 @@ Item {
83 function test_current_item_commit() {
83 function test_current_item_commit() {
84 init_test();
84 init_test();
85
85
86− indicatorRow.setItem(1);
86+ indicatorRow.setCurrentItem(1);
87 indicatorRow.state = "commit";
87 indicatorRow.state = "commit";
88− tryCompare(get_indicator_item_at(0), "y", -indicatorRow.height);
88+ tryCompare(get_indicator_item_at(0), "opacity", 0.0);
89− tryCompare(get_indicator_item_at(1), "y", 0);
89+ tryCompare(get_indicator_item_at(1), "opacity", 1.0);
90− tryCompare(get_indicator_item_at(2), "y", -indicatorRow.height);
90+ tryCompare(get_indicator_item_at(2), "opacity", 0.0);
91− tryCompare(get_indicator_item_at(3), "y", -indicatorRow.height);
91+ tryCompare(get_indicator_item_at(3), "opacity", 0.0);
92− tryCompare(get_indicator_item_at(4), "y", -indicatorRow.height);
92+ tryCompare(get_indicator_item_at(4), "opacity", 0.0);
93
93
94 }
94 }
95 }
95 }
@@ -106,7 +106,7 @@ Item {
106 init_test();
106 init_test();
107
107
108 indicatorRow.state = "initial";
108 indicatorRow.state = "initial";
109− indicatorRow.setItem(0);
109+ indicatorRow.setCurrentItem(0);
110
110
111 compare(indicatorRow.currentItem.highlighted, false, "Indicator should not highlight when in initial state");
111 compare(indicatorRow.currentItem.highlighted, false, "Indicator should not highlight when in initial state");
112 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in initial state");
112 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in initial state");
@@ -119,9 +119,9 @@ Item {
119 init_test();
119 init_test();
120
120
121 indicatorRow.state = "hint";
121 indicatorRow.state = "hint";
122− indicatorRow.setItem(0);
122+ indicatorRow.setCurrentItem(0);
123
123
124− compare(indicatorRow.currentItem.highlighted, false, "Indicator should not highlight when in hint state");
124+ compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in hint state");
125 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in hint state");
125 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in hint state");
126 compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in hint state");
126 compare(get_indicator_item_at(2).highlighted, false, "Other indicators should not highlight when in hint state");
127 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in hint state");
127 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in hint state");
@@ -132,7 +132,7 @@ Item {
132 init_test();
132 init_test();
133
133
134 indicatorRow.state = "reveal";
134 indicatorRow.state = "reveal";
135− indicatorRow.setItem(0);
135+ indicatorRow.setCurrentItem(0);
136
136
137 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in reveal state");
137 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in reveal state");
138 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
138 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
@@ -145,7 +145,7 @@ Item {
145 init_test();
145 init_test();
146
146
147 indicatorRow.state = "commit";
147 indicatorRow.state = "commit";
148− indicatorRow.setItem(0);
148+ indicatorRow.setCurrentItem(0);
149
149
150 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in commit state");
150 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in commit state");
151 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
151 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in commit state");
@@ -158,7 +158,7 @@ Item {
158 init_test();
158 init_test();
159
159
160 indicatorRow.state = "locked";
160 indicatorRow.state = "locked";
161− indicatorRow.setItem(0);
161+ indicatorRow.setCurrentItem(0);
162
162
163 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in locked state");
163 compare(indicatorRow.currentItem.highlighted, true, "Indicator should highlight when in locked state");
164 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in locked state");
164 compare(get_indicator_item_at(1).highlighted, false, "Other indicators should not highlight when in locked state");
@@ -180,7 +180,7 @@ Item {
180 init_test();
180 init_test();
181
181
182 indicatorRow.state = "initial";
182 indicatorRow.state = "initial";
183− indicatorRow.setItem(0);
183+ indicatorRow.setCurrentItem(0);
184
184
185 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in intiial state");
185 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in intiial state");
186 compare(get_indicator_item_at(1).dimmed, false, "Other indicators should not dim when in initial state");
186 compare(get_indicator_item_at(1).dimmed, false, "Other indicators should not dim when in initial state");
@@ -193,9 +193,9 @@ Item {
193 init_test();
193 init_test();
194
194
195 indicatorRow.state = "hint";
195 indicatorRow.state = "hint";
196− indicatorRow.setItem(0);
196+ indicatorRow.setCurrentItem(0);
197
197
198− compare(get_indicator_item_at(0).dimmed, true, "Current indicator should dim when in hint state");
198+ compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in hint state");
199 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in hint state");
199 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in hint state");
200 compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in hint state");
200 compare(get_indicator_item_at(2).dimmed, true, "Other indicators should dim when in hint state");
201 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in hint state");
201 compare(get_indicator_item_at(3).dimmed, true, "Other indicators should dim when in hint state");
@@ -206,7 +206,7 @@ Item {
206 init_test();
206 init_test();
207
207
208 indicatorRow.state = "reveal";
208 indicatorRow.state = "reveal";
209− indicatorRow.setItem(0);
209+ indicatorRow.setCurrentItem(0);
210
210
211 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in reveal state");
211 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in reveal state");
212 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in reveal state");
212 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in reveal state");
@@ -219,7 +219,7 @@ Item {
219 init_test();
219 init_test();
220
220
221 indicatorRow.state = "commit";
221 indicatorRow.state = "commit";
222− indicatorRow.setItem(0);
222+ indicatorRow.setCurrentItem(0);
223
223
224 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in commit state");
224 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in commit state");
225 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in commit state");
225 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in commit state");
@@ -232,7 +232,7 @@ Item {
232 init_test();
232 init_test();
233
233
234 indicatorRow.state = "locked";
234 indicatorRow.state = "locked";
235− indicatorRow.setItem(0);
235+ indicatorRow.setCurrentItem(0);
236
236
237 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in locked state");
237 compare(get_indicator_item_at(0).dimmed, false, "Current indicator should not dim when in locked state");
238 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in locked state");
238 compare(get_indicator_item_at(1).dimmed, true, "Other indicators should dim when in locked state");
tests/qmltests/Panel/tst_MenuContent.qml+4−4
@@ -77,15 +77,15 @@ Item {
77
77
78 function activate_next_content()
78 function activate_next_content()
79 {
79 {
80− if (menuContent.currentIndex == -1)
80+ if (menuContent.currentMenuIndex == -1)
81 activate_content(0);
81 activate_content(0);
82 else
82 else
83− activate_content((menuContent.currentIndex + 1) % indicatorsModel.count)
83+ activate_content((menuContent.currentMenuIndex + 1) % indicatorsModel.count)
84 }
84 }
85
85
86 function activate_content(index)
86 function activate_content(index)
87 {
87 {
88− menuContent.currentIndex = index
88+ menuContent.currentMenuIndex = index
89 }
89 }
90
90
91 function get_test_menu_objecName(index) {
91 function get_test_menu_objecName(index) {
@@ -197,7 +197,7 @@ Item {
197
197
198 for (var i = 0; i < 100; i++) {
198 for (var i = 0; i < 100; i++) {
199 activate_content(i % menu_count);
199 activate_content(i % menu_count);
200− compare(menuContent.currentIndex, i%menu_count);
200+ compare(menuContent.currentMenuIndex, i%menu_count);
201 }
201 }
202 wait(100);
202 wait(100);
203 }
203 }
tests/qmltests/Panel/tst_Panel.qml+83−43
@@ -30,11 +30,11 @@ Item {
30 width: units.gu(40)
30 width: units.gu(40)
31 height: units.gu(80)
31 height: units.gu(80)
32
32
33− property bool search_clicked: false
33+ property bool searchClicked: false
34
34
35 Connections {
35 Connections {
36 target: panel
36 target: panel
37− onSearchClicked: search_clicked = true
37+ onSearchClicked: searchClicked = true
38 }
38 }
39
39
40 Panel {
40 Panel {
@@ -54,27 +54,26 @@ Item {
54
54
55
55
56 function init() {
56 function init() {
57− search_clicked = false;
57+ searchClicked = false;
58 panel.indicators.hide();
58 panel.indicators.hide();
59 tryCompare(panel.indicators.hideAnimation, "running", false);
59 tryCompare(panel.indicators.hideAnimation, "running", false);
60 tryCompare(panel.indicators, "state", "initial");
60 tryCompare(panel.indicators, "state", "initial");
61 }
61 }
62
62
63 function get_indicator_item(index) {
63 function get_indicator_item(index) {
64− var row_repeater = findChild(panel.indicators, "rowRepeater");
64+ var rowRepeater = findChild(panel.indicators, "rowRepeater");
65− verify(row_repeater != undefined);
65+ verify(rowRepeater != undefined);
66− return row_repeater.itemAt(index);
66+ return rowRepeater.itemAt(index);
67 }
67 }
68
68
69 function get_indicator_item_position(index) {
69 function get_indicator_item_position(index) {
70+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
71+ verify(indicatorRow != undefined);
70
72
71− var indicator_row = findChild(panel.indicators, "indicatorRow");
72− verify(indicator_row != undefined);
73−
74− var indicator_item = get_indicator_item(index);
73+ var indicatorItem = get_indicator_item(index);
75− verify(indicator_item != undefined);
74+ verify(indicatorItem != undefined);
76
75
77− return panel.mapFromItem(indicator_item, indicator_item.width/2, indicator_item.height/2);
76+ return panel.mapFromItem(indicatorItem, indicatorItem.width/2, indicatorItem.height/2);
78 }
77 }
79
78
80 // Pressing on the indicator panel should activate the indicator hints
79 // Pressing on the indicator panel should activate the indicator hints
@@ -85,9 +84,9 @@ Item {
85 // (switches between normal and fullscreen modes are animated)
84 // (switches between normal and fullscreen modes are animated)
86 tryCompare(panel.indicators, "y", 0);
85 tryCompare(panel.indicators, "y", 0);
87
86
88− var indicator_item_coord = get_indicator_item_position(0);
87+ var indicatorItemCoord = get_indicator_item_position(0);
89
88
90− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
89+ touchPress(panel, indicatorItemCoord.x, panel.panelHeight / 2);
91
90
92 // hint animation should be run, meaning that indicators will move downwards
91 // hint animation should be run, meaning that indicators will move downwards
93 // by hintValue pixels without any drag taking place
92 // by hintValue pixels without any drag taking place
@@ -96,7 +95,7 @@ Item {
96 tryCompare(panel.indicators, "partiallyOpened", true);
95 tryCompare(panel.indicators, "partiallyOpened", true);
97 tryCompare(panel.indicators, "fullyOpened", false);
96 tryCompare(panel.indicators, "fullyOpened", false);
98
97
99− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
98+ touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
100 }
99 }
101
100
102 // Pressing on the top edge of the screen should have no effect if the panel
101 // Pressing on the top edge of the screen should have no effect if the panel
@@ -107,9 +106,9 @@ Item {
107 // (switches between normal and fullscreen modes are animated)
106 // (switches between normal and fullscreen modes are animated)
108 tryCompare(panel.indicators, "y", -panel.panelHeight);
107 tryCompare(panel.indicators, "y", -panel.panelHeight);
109
108
110− var indicator_item_coord = get_indicator_item_position(0);
109+ var indicatorItemCoord = get_indicator_item_position(0);
111
110
112− touchPress(panel, indicator_item_coord.x, panel.panelHeight / 2);
111+ touchPress(panel, indicatorItemCoord.x, panel.panelHeight / 2);
113
112
114 // Give some time for a hint animation to change things, if any
113 // Give some time for a hint animation to change things, if any
115 wait(500);
114 wait(500);
@@ -126,7 +125,7 @@ Item {
126 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
125 compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
127 " opened when panel is pressed in fullscreenmode");
126 " opened when panel is pressed in fullscreenmode");
128
127
129− touchRelease(panel, indicator_item_coord.x, panel.panelHeight/2);
128+ touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
130 }
129 }
131
130
132 function test_drag_show_data() { return get_window_data(); }
131 function test_drag_show_data() { return get_window_data(); }
@@ -137,14 +136,14 @@ Item {
137 function test_drag_show(data) {
136 function test_drag_show(data) {
138 panel.fullscreenMode = data.fullscreenFlag;
137 panel.fullscreenMode = data.fullscreenFlag;
139
138
140− var indicator_row = findChild(panel.indicators, "indicatorRow");
139+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
141− verify(indicator_row != undefined);
140+ verify(indicatorRow != undefined);
142
141
143− var row_repeater = findChild(panel.indicators, "rowRepeater");
142+ var rowRepeater = findChild(panel.indicators, "rowRepeater");
144− verify(indicator_row != undefined);
143+ verify(indicatorRow != undefined);
145
144
146− var menu_content = findChild(panel.indicators, "menuContent");
145+ var menuContent = findChild(panel.indicators, "menuContent");
147− verify(indicator_row != undefined);
146+ verify(indicatorRow != undefined);
148
147
149 // Wait for the indicators to get into position.
148 // Wait for the indicators to get into position.
150 // (switches between normal and fullscreen modes are animated)
149 // (switches between normal and fullscreen modes are animated)
@@ -155,20 +154,20 @@ Item {
155 }
154 }
156
155
157 // do this for each indicator item
156 // do this for each indicator item
158− for (var i = 0; i < row_repeater.count; i++) {
157+ for (var i = 0; i < rowRepeater.count; i++) {
159
158
160− var indicator_item = get_indicator_item(i);
159+ var indicatorItem = get_indicator_item(i);
161− verify(indicator_item != undefined);
160+ verify(indicatorItem != undefined);
162
161
163− var indicator_item_coord = get_indicator_item_position(i);
162+ var indicatorItemCoord = get_indicator_item_position(i);
164
163
165 touchPress(panel,
164 touchPress(panel,
166− indicator_item_coord.x, panel.panelHeight / 2);
165+ indicatorItemCoord.x, panel.panelHeight / 2);
167
166
168 // 1) Drag the mouse down
167 // 1) Drag the mouse down
169 touchFlick(panel,
168 touchFlick(panel,
170− indicator_item_coord.x, panel.panelHeight / 2,
169+ indicatorItemCoord.x, panel.panelHeight / 2,
171− indicator_item_coord.x, panel.height * 0.8,
170+ indicatorItemCoord.x, panel.height * 0.8,
172 false /* beginTouch */, false /* endTouch */);
171 false /* beginTouch */, false /* endTouch */);
173
172
174 // Indicators height should follow the drag, and therefore increase accordingly.
173 // Indicators height should follow the drag, and therefore increase accordingly.
@@ -177,13 +176,13 @@ Item {
177 function() {return panel.indicators.height >= panel.height * 0.5},
176 function() {return panel.indicators.height >= panel.height * 0.5},
178 true);
177 true);
179
178
180− touchRelease(panel, indicator_item_coord.x, panel.height * 0.8);
179+ touchRelease(panel, indicatorItemCoord.x, panel.height * 0.8);
181
180
182− compare(indicator_row.currentItem, indicator_item,
181+ compare(indicatorRow.currentItem, indicatorItem,
183 "Incorrect item activated at position " + i);
182 "Incorrect item activated at position " + i);
184− compare(menu_content.currentIndex, i, "Menu conetent should be enabled for item at position " + i);
183+ compare(menuContent.currentMenuIndex, i, "Menu conetent should be enabled for item at position " + i);
185
184
186− // init for next indicator_item
185+ // init for next indicatorItem
187 init();
186 init();
188 }
187 }
189 }
188 }
@@ -192,12 +191,12 @@ Item {
192 panel.fullscreenMode = false;
191 panel.fullscreenMode = false;
193 panel.searchVisible = true;
192 panel.searchVisible = true;
194
193
195− var search_indicator = findChild(panel, "search");
194+ var searchIndicator = findChild(panel, "search");
196− verify(search_indicator != undefined);
195+ verify(searchIndicator != undefined);
197
196
198− tap(search_indicator, 1, 1);
197+ tap(searchIndicator, 1, 1);
199
198
200− compare(search_clicked, true,
199+ compare(searchClicked, true,
201 "Tapping search indicator while it was enabled did not emit searchClicked signal");
200 "Tapping search indicator while it was enabled did not emit searchClicked signal");
202 }
201 }
203
202
@@ -205,13 +204,54 @@ Item {
205 panel.fullscreenMode = false;
204 panel.fullscreenMode = false;
206 panel.searchVisible = false;
205 panel.searchVisible = false;
207
206
208− var search_indicator = findChild(panel, "search");
207+ var searchIndicator = findChild(panel, "search");
209− verify(search_indicator != undefined);
208+ verify(searchIndicator != undefined);
210
209
211− tap(search_indicator, 1, 1);
210+ tap(searchIndicator, 1, 1);
212
211
213− compare(search_clicked, false,
212+ compare(searchClicked, false,
214 "Tapping search indicator while it was not visible emitted searchClicked signal");
213 "Tapping search indicator while it was not visible emitted searchClicked signal");
215 }
214 }
215+
216+ // Test the vertical velocity check when flicking the indicators open at an angle.
217+ // If the vertical velocity is above a specific point, we shouldnt change active indicators
218+ // if the x position changes
219+ function test_vertical_velocity_detector() {
220+ panel.fullscreenMode = false;
221+ panel.searchVisible = false;
222+
223+ var indicatorRow = findChild(panel.indicators, "indicatorRow");
224+ verify(indicatorRow != undefined);
225+
226+ var rowRepeater = findChild(panel.indicators, "rowRepeater");
227+ verify(indicatorRow != undefined);
228+
229+ // Get the first indicator
230+ var indicatorItemFirst = get_indicator_item(0);
231+ verify(indicatorItemFirst != undefined);
232+
233+ var indicatorItemCoordFirst = get_indicator_item_position(0);
234+ var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.count - 1);
235+
236+ touchPress(panel,
237+ indicatorItemCoordFirst.x, panel.panelHeight / 2);
238+
239+ // 1) Drag the mouse down to hint a bit
240+ touchFlick(panel,
241+ indicatorItemCoordFirst.x, panel.panelHeight / 2,
242+ indicatorItemCoordFirst.x, panel.panelHeight * 2,
243+ false /* beginTouch */, false /* endTouch */);
244+
245+ tryCompare(indicatorRow, "currentItem", indicatorItemFirst)
246+
247+ // 1) Flick mouse down to bottom
248+ touchFlick(panel,
249+ indicatorItemCoordFirst.x, panel.panelHeight * 2,
250+ indicatorItemCoordNext.x, panel.height,
251+ false /* beginTouch */, true /* endTouch */,
252+ units.gu(10) /* speed */, 30 /* iterations */); // more samples needed for accurate velocity
253+
254+ compare(indicatorRow.currentItem, indicatorItemFirst, "First indicator should still be the current item");
255+ }
216 }
256 }
217}
257}
tests/qmltests/Panel/tst_SearchIndicator.qml+8−10
@@ -41,24 +41,22 @@ Item {
41 when: windowShown
41 when: windowShown
42
42
43 function test_clickedSignal() {
43 function test_clickedSignal() {
44− clickedSpy.clear()
44+ clickedSpy.clear();
45 mouseClick(searchIndicator,
45 mouseClick(searchIndicator,
46 searchIndicator.width / 2, searchIndicator.height / 2);
46 searchIndicator.width / 2, searchIndicator.height / 2);
47− compare(clickedSpy.count, 1)
47+ compare(clickedSpy.count, 1);
48 }
48 }
49
49
50 function test_hideUp() {
50 function test_hideUp() {
51− var container = findChild(searchIndicator, "container")
51+ var container = findChild(searchIndicator, "container");
52− searchIndicator.state = "hiddenUp"
52+ searchIndicator.state = "hidden";
53− tryCompare(container, "opacity", 0)
53+ tryCompare(container, "opacity", 0);
54− tryCompare(container, "y", -container.height)
55 }
54 }
56
55
57 function test_show() {
56 function test_show() {
58− var container = findChild(searchIndicator, "container")
57+ var container = findChild(searchIndicator, "container");
59− searchIndicator.state = "visible"
58+ searchIndicator.state = "visible";
60− tryCompare(container, "opacity", 1)
59+ tryCompare(container, "opacity", 1);
61− tryCompare(container, "y", 0)
62 }
60 }
63 }
61 }
64}
62}
tests/utils/modules/Unity/Test/UnityTestCase.qml+22−18
@@ -32,32 +32,34 @@ TestCase {
32 // Qt uses in QQuickViewTestUtil::flick
32 // Qt uses in QQuickViewTestUtil::flick
33 // speed is in pixels/second
33 // speed is in pixels/second
34 function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse,
34 function mouseFlick(item, x, y, toX, toY, pressMouse, releaseMouse,
35− speed) {
35+ speed, iterations) {
36 pressMouse = ((pressMouse != null) ? pressMouse : true); // Default to true for pressMouse if not present
36 pressMouse = ((pressMouse != null) ? pressMouse : true); // Default to true for pressMouse if not present
37 releaseMouse = ((releaseMouse != null) ? releaseMouse : true); // Default to true for releaseMouse if not present
37 releaseMouse = ((releaseMouse != null) ? releaseMouse : true); // Default to true for releaseMouse if not present
38
38
39 // set a default speed if not specified
39 // set a default speed if not specified
40 speed = (speed != null) ? speed : units.gu(10);
40 speed = (speed != null) ? speed : units.gu(10);
41
41
42+ // set a default iterations if not specified
43+ iterations = (iterations !== undefined) ? iterations : 5
44+
42 var distance = Math.sqrt(Math.pow(toX - x, 2) + Math.pow(toY - y, 2))
45 var distance = Math.sqrt(Math.pow(toX - x, 2) + Math.pow(toY - y, 2))
43 var totalTime = (distance / speed) * 1000 /* converting speed to pixels/ms */
46 var totalTime = (distance / speed) * 1000 /* converting speed to pixels/ms */
44
47
45− var nIterations = 5
46− var timeStep = totalTime / nIterations
48+ var timeStep = totalTime / iterations
47− var diffX = (toX - x) / nIterations
49+ var diffX = (toX - x) / iterations
48− var diffY = (toY - y) / nIterations
50+ var diffY = (toY - y) / iterations
49 if (pressMouse) {
51 if (pressMouse) {
50 fakeDateTime.currentTimeMs += timeStep
52 fakeDateTime.currentTimeMs += timeStep
51 mousePress(item, x, y)
53 mousePress(item, x, y)
52 }
54 }
53− for (var i = 0; i < nIterations; ++i) {
55+ for (var i = 0; i < iterations; ++i) {
54 fakeDateTime.currentTimeMs += timeStep
56 fakeDateTime.currentTimeMs += timeStep
55− if (i === nIterations - 1) {
57+ if (i === iterations - 1) {
56 // Avoid any rounding errors by making the last move be at precisely
58 // Avoid any rounding errors by making the last move be at precisely
57 // the point specified
59 // the point specified
58− mouseMove(item, toX, toY, nIterations / speed)
60+ mouseMove(item, toX, toY, iterations / speed)
59 } else {
61 } else {
60− mouseMove(item, x + (i + 1) * diffX, y + (i + 1) * diffY, nIterations / speed)
62+ mouseMove(item, x + (i + 1) * diffX, y + (i + 1) * diffY, iterations / speed)
61 }
63 }
62 }
64 }
63 if (releaseMouse) {
65 if (releaseMouse) {
@@ -186,7 +188,7 @@ TestCase {
186 }
188 }
187
189
188 // speed is in pixels/second
190 // speed is in pixels/second
189− function touchFlick(item, x, y, toX, toY, beginTouch, endTouch, speed) {
191+ function touchFlick(item, x, y, toX, toY, beginTouch, endTouch, speed, iterations) {
190
192
191 // Default to true for beginTouch if not present
193 // Default to true for beginTouch if not present
192 beginTouch = (beginTouch !== undefined) ? beginTouch : true
194 beginTouch = (beginTouch !== undefined) ? beginTouch : true
@@ -197,13 +199,15 @@ TestCase {
197 // Set a default speed if not specified
199 // Set a default speed if not specified
198 speed = (speed !== undefined) ? speed : units.gu(10)
200 speed = (speed !== undefined) ? speed : units.gu(10)
199
201
202+ // Set a default iterations if not specified
203+ var iterations = (iterations !== undefined) ? iterations : 5
204+
200 var distance = Math.sqrt(Math.pow(toX - x, 2) + Math.pow(toY - y, 2))
205 var distance = Math.sqrt(Math.pow(toX - x, 2) + Math.pow(toY - y, 2))
201 var totalTime = (distance / speed) * 1000 /* converting speed to pixels/ms */
206 var totalTime = (distance / speed) * 1000 /* converting speed to pixels/ms */
202
207
203− var nIterations = 5
204− var timeStep = totalTime / nIterations
208+ var timeStep = totalTime / iterations
205− var diffX = (toX - x) / nIterations
209+ var diffX = (toX - x) / iterations
206− var diffY = (toY - y) / nIterations
210+ var diffY = (toY - y) / iterations
207 if (beginTouch) {
211 if (beginTouch) {
208 fakeDateTime.currentTimeMs += timeStep
212 fakeDateTime.currentTimeMs += timeStep
209
213
@@ -211,17 +215,17 @@ TestCase {
211 event.press(0 /* touchId */, x, y)
215 event.press(0 /* touchId */, x, y)
212 event.commit()
216 event.commit()
213 }
217 }
214− for (var i = 0; i < nIterations; ++i) {
218+ for (var i = 0; i < iterations; ++i) {
215 fakeDateTime.currentTimeMs += timeStep
219 fakeDateTime.currentTimeMs += timeStep
216− if (i === nIterations - 1) {
220+ if (i === iterations - 1) {
217 // Avoid any rounding errors by making the last move be at precisely
221 // Avoid any rounding errors by making the last move be at precisely
218 // the point specified
222 // the point specified
219− wait(nIterations / speed)
223+ wait(iterations / speed)
220 var event = touchEvent()
224 var event = touchEvent()
221 event.move(0 /* touchId */, toX, toY)
225 event.move(0 /* touchId */, toX, toY)
222 event.commit()
226 event.commit()
223 } else {
227 } else {
224− wait(nIterations / speed)
228+ wait(iterations / speed)
225 var event = touchEvent()
229 var event = touchEvent()
226 event.move(0 /* touchId */, x + (i + 1) * diffX, y + (i + 1) * diffY)
230 event.move(0 /* touchId */, x + (i + 1) * diffX, y + (i + 1) * diffY)
227 event.commit()
231 event.commit()