on xenial help sign in
Split panel
b2c7059Nick Dedekind
qml/Panel/ActiveCallHint.qml+2−17
@@ -23,27 +23,18 @@ import "../Components"
23Item {
23Item {
24 id: callHint
24 id: callHint
25
25
26− property bool active: true//callManager.hasCalls && ApplicationManager.focusedApplicationId !== "dialer-app"
26+ property bool active: callManager.hasCalls && ApplicationManager.focusedApplicationId !== "dialer-app"
27 readonly property QtObject contactWatcher: _contactWatcher
27 readonly property QtObject contactWatcher: _contactWatcher
28 property int alternateLabelInterval: 4000
28 property int alternateLabelInterval: 4000
29 property color color: Qt.rgba(0.1, 0.6, 0.1, 1.0)
29 property color color: Qt.rgba(0.1, 0.6, 0.1, 1.0)
30 property color colorFlash: Qt.lighter(color)
30 property color colorFlash: Qt.lighter(color)
31− readonly property alias mouseArea: __mouseArea
32
31
33 Component.onCompleted: {
32 Component.onCompleted: {
34 telepathyHelper.registerChannelObserver("unity8");
33 telepathyHelper.registerChannelObserver("unity8");
35 }
34 }
36
35
37 function activate() {
36 function activate() {
38− console.log("PLOP")
39−// ApplicationManager.requestFocusApplication("dialer-app");
37+ ApplicationManager.requestFocusApplication("dialer-app");
40− }
41−
42− Timer {
43− running: true
44− interval: 4000
45− repeat: true
46− onTriggered: active = !active
47 }
38 }
48
39
49 Rectangle {
40 Rectangle {
@@ -239,12 +230,6 @@ Item {
239 }
230 }
240 }
231 }
241
232
242− // eater
243− MouseArea {
244− id: __mouseArea
245− anchors.fill: parent
246− }
247−
248 Telephony.ContactWatcher {
233 Telephony.ContactWatcher {
249 id: _contactWatcher
234 id: _contactWatcher
250 objectName: "contactWatcher"
235 objectName: "contactWatcher"
qml/Panel/IndicatorRow.qml+1−1
@@ -36,7 +36,7 @@ Item {
36
36
37 function setDefaultItem() {
37 function setDefaultItem() {
38 // The leftmost indicator
38 // The leftmost indicator
39− setCurrentItem(0);
39+ setCurrentItemIndex(0);
40 }
40 }
41
41
42 function setCurrentItemIndex(index) {
42 function setCurrentItemIndex(index) {
qml/Panel/Indicators.qml+20−37
@@ -28,7 +28,6 @@ Showable {
28
28
29 property real openedHeight: units.gu(71)
29 property real openedHeight: units.gu(71)
30 property int panelHeight: units.gu(3)
30 property int panelHeight: units.gu(3)
31− property bool pinnedMode: true //should be set true if indicators menu can cover whole screen
32 property alias overFlowWidth: indicatorRow.overFlowWidth
31 property alias overFlowWidth: indicatorRow.overFlowWidth
33 property alias showAll: indicatorRow.showAll
32 property alias showAll: indicatorRow.showAll
34 // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...)
33 // TODO: This should be sourced by device type (eg "desktop", "tablet", "phone"...)
@@ -38,13 +37,13 @@ Showable {
38 readonly property int lockThreshold: openedHeight / 2
37 readonly property int lockThreshold: openedHeight / 2
39 property bool fullyOpened: height == openedHeight
38 property bool fullyOpened: height == openedHeight
40 property bool partiallyOpened: height > panelHeight && !fullyOpened
39 property bool partiallyOpened: height > panelHeight && !fullyOpened
41− property real visualBottom: Math.max(y+height, y+indicatorRow.y+indicatorRow.height)
42 property bool contentEnabled: true
40 property bool contentEnabled: true
43 property bool initalizeItem: true
41 property bool initalizeItem: true
44 readonly property alias content: menuContent
42 readonly property alias content: menuContent
45 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
43 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
46 property bool enableHint: true
44 property bool enableHint: true
47− property real hintAreaHeightOffset: 0
45+ property real showHintBottomMargin: 0
46+ property real showHintHeightOffset: 0
48
47
49 signal showTapped(point position)
48 signal showTapped(point position)
50
49
@@ -53,13 +52,6 @@ Showable {
53 showAnimation: StandardAnimation {
52 showAnimation: StandardAnimation {
54 property: "height"
53 property: "height"
55 to: openedHeight
54 to: openedHeight
56−
57− // Re-size if we've changed the openHeight while shown.
58− onToChanged: {
59− if (indicators.shown) {
60− height = openedHeight;
61− }
62− }
63 }
55 }
64
56
65 hideAnimation: StandardAnimation {
57 hideAnimation: StandardAnimation {
@@ -69,16 +61,24 @@ Showable {
69 easing.type: Easing.OutCubic
61 easing.type: Easing.OutCubic
70 }
62 }
71
63
64+ onOpenedHeightChanged: {
65+ if (showAnimation.running) {
66+ showAnimation.restart();
67+ } else if (indicators.shown) {
68+ height = openedHeight;
69+ }
70+ }
71+
72 height: panelHeight
72 height: panelHeight
73− onHeightChanged: updateRevealProgressState(indicators.height - panelHeight, true)
73+ onHeightChanged: updateRevealProgressState(indicators.height - panelHeight - showHintBottomMargin, true)
74
74
75 function updateRevealProgressState(revealProgress, enableRelease) {
75 function updateRevealProgressState(revealProgress, enableRelease) {
76 if (!showAnimation.running && !hideAnimation.running) {
76 if (!showAnimation.running && !hideAnimation.running) {
77 if (revealProgress === 0) {
77 if (revealProgress === 0) {
78 indicators.state = "initial";
78 indicators.state = "initial";
79− } else if (revealProgress > 0 && revealProgress <= hintValue) {
79+ } else if (enableHint && revealProgress > 0 && revealProgress <= hintValue) {
80 indicators.state = "hint";
80 indicators.state = "hint";
81− } else if (revealProgress > hintValue && revealProgress < lockThreshold) {
81+ } else if ((!enableHint || revealProgress > hintValue) && revealProgress < lockThreshold) {
82 indicators.state = "reveal";
82 indicators.state = "reveal";
83 } else if (revealProgress >= lockThreshold && lockThreshold > 0) {
83 } else if (revealProgress >= lockThreshold && lockThreshold > 0) {
84 indicators.state = "locked";
84 indicators.state = "locked";
@@ -173,17 +173,6 @@ Showable {
173 }
173 }
174 }
174 }
175
175
176− VerticalThinDivider {
177− anchors {
178− top: indicators.top
179− topMargin: panelHeight
180− bottom: handle.bottom
181− right: indicators.left
182− }
183− width: units.dp(2)
184− source: "graphics/VerticalDivider.png"
185− }
186−
187 VisibleIndicators {
176 VisibleIndicators {
188 id: visibleIndicators
177 id: visibleIndicators
189 }
178 }
@@ -247,10 +236,6 @@ Showable {
247 }
236 }
248 }
237 }
249
238
250− PanelBackground {
251− anchors.fill: indicatorRow
252− }
253−
254 IndicatorRow {
239 IndicatorRow {
255 id: indicatorRow
240 id: indicatorRow
256 objectName: "indicatorRow"
241 objectName: "indicatorRow"
@@ -358,17 +343,17 @@ Showable {
358 id: showDragHandle
343 id: showDragHandle
359 anchors.bottom: parent.bottom
344 anchors.bottom: parent.bottom
360 // go beyond parent so that it stays reachable, at the top of the screen.
345 // go beyond parent so that it stays reachable, at the top of the screen.
361− anchors.bottomMargin: pinnedMode ? 0 : -panelHeight
346+ anchors.bottomMargin: showHintBottomMargin
362 anchors.left: parent.left
347 anchors.left: parent.left
363 anchors.right: parent.right
348 anchors.right: parent.right
364− height: panelHeight + hintAreaHeightOffset
349+ height: panelHeight + showHintHeightOffset
365 direction: Direction.Downwards
350 direction: Direction.Downwards
366 enabled: !indicators.shown && indicators.available
351 enabled: !indicators.shown && indicators.available
367− hintDisplacement: enableHint && pinnedMode ? indicators.hintValue : 0
352+ hintDisplacement: enableHint ? indicators.hintValue : 0
368 autoCompleteDragThreshold: maxTotalDragDistance / 2
353 autoCompleteDragThreshold: maxTotalDragDistance / 2
369 stretch: true
354 stretch: true
370 maxTotalDragDistance: openedHeight - panelHeight
355 maxTotalDragDistance: openedHeight - panelHeight
371− distanceThreshold: pinnedMode ? 0 : units.gu(3)
356+ distanceThreshold: panelHeight
372
357
373 onStatusChanged: {
358 onStatusChanged: {
374 if (status === DirectionalDragArea.Recognized) {
359 if (status === DirectionalDragArea.Recognized) {
@@ -376,8 +361,9 @@ Showable {
376 }
361 }
377 }
362 }
378
363
379− onTapped: showTapped(Qt.point(x + touchX, y + touchY))
364+ onTapped: showTapped(Qt.point(touchSceneX, touchSceneY));
380 }
365 }
366+
381 DragHandle {
367 DragHandle {
382 id: hideDragHandle
368 id: hideDragHandle
383 anchors.fill: handle
369 anchors.fill: handle
@@ -400,10 +386,6 @@ Showable {
400 },
386 },
401 State {
387 State {
402 name: "hint"
388 name: "hint"
403− PropertyChanges {
404− target: indicatorRow;
405− y: pinnedMode ? 0 : panelHeight
406− }
407 StateChangeScript {
389 StateChangeScript {
408 script: {
390 script: {
409 if (d.activeDragHandle) {
391 if (d.activeDragHandle) {
@@ -436,5 +418,6 @@ Showable {
436 Component.onCompleted: initialise();
418 Component.onCompleted: initialise();
437 function initialise() {
419 function initialise() {
438 visibleIndicators.load(profile);
420 visibleIndicators.load(profile);
421+ indicatorRow.setDefaultItem();
439 }
422 }
440}
423}
qml/Panel/Panel.qml+171−135
@@ -18,11 +18,13 @@ import QtQuick 2.0
18import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
19import Unity.Application 0.1
19import Unity.Application 0.1
20import "../Components"
20import "../Components"
21+import "../Components/ListItems"
21
22
22Item {
23Item {
23 id: root
24 id: root
24− readonly property real panelHeight: indicatorArea.y + indicatorArea.indicatorHeight
25+ readonly property real panelHeight: nonIndicatorArea.y + nonIndicatorArea.height
25− property alias indicators: indicatorsMenu
26+ property alias indicators: __indicators
27+ property alias callHint: __callHint
26 property bool fullscreenMode: false
28 property bool fullscreenMode: false
27 property bool searchVisible: true
29 property bool searchVisible: true
28
30
@@ -33,7 +35,7 @@ Item {
33 hideTimer.interval = delay;
35 hideTimer.interval = delay;
34 hideTimer.start();
36 hideTimer.start();
35 } else {
37 } else {
36− indicatorsMenu.hide();
38+ indicators.hide();
37 }
39 }
38 }
40 }
39
41
@@ -41,124 +43,122 @@ Item {
41 id: hideTimer
43 id: hideTimer
42 running: false
44 running: false
43 onTriggered: {
45 onTriggered: {
44− indicatorsMenu.hide();
46+ indicators.hide();
45 }
47 }
46 }
48 }
47
49
48 Connections {
50 Connections {
49− target: indicatorsMenu
51+ target: indicators
50 onShownChanged: hideTimer.stop()
52 onShownChanged: hideTimer.stop()
51 }
53 }
52
54
53− PanelBackground {
55+ Rectangle {
54− id: callHintBackground
56+ id: darkenedArea
55− anchors.fill: callHint
57+ property real darkenedOpacity: 0.6
56− }
57−
58− ActiveCallHint {
59− id: callHint
60−
61 anchors {
58 anchors {
62 left: parent.left
59 left: parent.left
63 right: parent.right
60 right: parent.right
61+ top: nonIndicatorArea.bottom
62+ bottom: parent.bottom
64 }
63 }
65− height: units.gu(3)
64+ color: "black"
66− y: -height
65+ opacity: indicators.unitProgress * darkenedOpacity
67
66
68− states: [
67+ MouseArea {
69− State {
70− name: "active"
71− when: callHint.active
72− PropertyChanges { target: callHint; y: 0 }
73− PropertyChanges { target: search.mouseArea; anchors.topMargin: -callHint.height/3 }
74− }
75− ]
76− Behavior on y { StandardAnimation { id: callHintYAnimation } }
77−
78− mouseArea.onClicked: callHint.activate();
79−
80− Rectangle {
81− anchors.fill: callHint.mouseArea
68+ anchors.fill: parent
82− color: Qt.rgba(0,1,0,0.5)
69+ enabled: indicators.shown
70+ onClicked: if (indicators.fullyOpened) indicators.hide();
83 }
71 }
84 }
72 }
85
73
74+ PanelBackground {
75+ anchors.fill: nonIndicatorArea
76+ }
77+
86 Item {
78 Item {
87− id: indicatorArea
79+ id: nonIndicatorArea
88 objectName: "indicatorArea"
80 objectName: "indicatorArea"
89− z: 1
90−
91− readonly property real indicatorHeight: indicatorsMenu.panelHeight + leftSeparatorLine.height
92
81
93 anchors {
82 anchors {
83+ top: callHint.bottom
94 left: parent.left
84 left: parent.left
95 right: parent.right
85 right: parent.right
96 }
86 }
97− height: root.height - indicatorArea.y
87+ height: d.indicatorHeight
98−
99− Behavior on y {
100− enabled: !callHintYAnimation.running
101− StandardAnimation {}
102− }
103−
104− PanelBackground {
105− id: panelBackground
106− anchors {
107− top: parent.top
108− left: parent.left
109− right: parent.right
110− }
111− height: indicatorsMenu.panelHeight
112− }
113
88
114 PanelSeparatorLine {
89 PanelSeparatorLine {
115 id: leftSeparatorLine
90 id: leftSeparatorLine
116 anchors {
91 anchors {
117− top: panelBackground.bottom
92+ bottom: parent.bottom
118 left: parent.left
93 left: parent.left
119− right: indicatorsMenu.left
94+ right: parent.right
120 }
95 }
121− saturation: 1 - indicatorsMenu.unitProgress
96+ saturation: 1 - indicators.unitProgress
122 }
97 }
123
98
124− Rectangle {
99+ MouseArea {
125− id: darkenedArea
100+ id: nonIndicatorMouseArea
126− property real darkenedOpacity: 0.6
101+ enabled: callHint.active
127 anchors {
102 anchors {
103+ top: parent.top
128 left: parent.left
104 left: parent.left
129 right: parent.right
105 right: parent.right
130− top: leftSeparatorLine.bottom
131− bottom: parent.bottom
132 }
106 }
133− color: "black"
107+ height: indicators.panelHeight/2
134− opacity: indicatorsMenu.unitProgress * darkenedOpacity
108+ onClicked: callHint.activate();
109+ }
110+ }
135
111
112+ // eater
136− MouseArea {
113+ MouseArea {
137− anchors.fill: parent
114+ anchors.fill: callHint
138− enabled: indicatorsMenu.shown
115+ onClicked: callHint.activate()
139− onClicked: if (indicatorsMenu.fullyOpened) indicatorsMenu.hide();
140− }
116+ }
117+
118+ Item {
119+ id: indicatorArea
120+ objectName: "indicatorArea"
121+
122+ anchors {
123+ top: callHint.bottom
124+ right: parent.right
125+ bottom: parent.bottom
141 }
126 }
127+ width: indicators.width
142
128
143− MouseArea {
129+ Behavior on anchors.topMargin { StandardAnimation {} }
144− id: indicatorAreaClick
130+
145− enabled: callHint.active
131+ BorderImage {
132+ id: dropShadow
146 anchors {
133 anchors {
147− top: parent.top
134+ fill: indicators
148− left: search.right
135+ leftMargin: -units.gu(1)
149− right: indicatorsMenu.right
136+ bottomMargin: -units.gu(1)
150 }
137 }
151− height: indicatorsMenu.panelHeight/2
138+ visible: indicators.height > indicators.panelHeight
152− onClicked: callHint.activate();
139+ source: "graphics/rectangular_dropshadow.sci"
140+ }
141+
142+ VerticalThinDivider {
143+ id: indicatorDividor
144+ anchors {
145+ top: indicators.top
146+ bottom: indicators.bottom
147+ right: indicators.left
153
148
154− Rectangle {
149+ topMargin: nonIndicatorArea.anchors.topMargin + indicators.panelHeight
155− anchors.fill: indicatorAreaClick
156− color: Qt.rgba(0,1,0,0.5)
157 }
150 }
151+
152+ width: units.dp(2)
153+ source: "graphics/VerticalDivider.png"
154+ }
155+
156+ PanelBackground {
157+ anchors.fill: indicators
158 }
158 }
159
159
160 Indicators {
160 Indicators {
161− id: indicatorsMenu
161+ id: __indicators
162 objectName: "indicators"
162 objectName: "indicators"
163
163
164 anchors {
164 anchors {
@@ -169,92 +169,128 @@ Item {
169 width: (root.width > units.gu(60)) ? units.gu(40) : root.width
169 width: (root.width > units.gu(60)) ? units.gu(40) : root.width
170 shown: false
170 shown: false
171 panelHeight: units.gu(3)
171 panelHeight: units.gu(3)
172− openedHeight: parent.height
172+ openedHeight: root.height - (callHint.y + callHint.height)
173− pinnedMode: !fullscreenMode
174− enableHint: !callHint.active
175− overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
173+ overFlowWidth: search.state=="hidden" ? root.width : root.width - search.width
174+
175+ enableHint: !callHint.active && !fullscreenMode
176+ showHintBottomMargin: fullscreenMode ? -panelHeight : 0
176− hintAreaHeightOffset: callHint.active ? callHint.height : 0
177+ showHintHeightOffset: callHint.active ? callHint.height : 0
177
178
178 onShowTapped: {
179 onShowTapped: {
179− if (callHint.active && position.y < y + indicatorsMenu.panelHeight/2) {
180+ if (callHint.active) {
181+ var callHintScenePosition = callHint.mapToItem(null, callHint.x, callHint.y);
182+ var indicatorScenePosition = mapToItem(null, x, y);
183+
184+ // tapped on callHint
185+ if (position.y > callHintScenePosition.y && position.y <= callHintScenePosition.y + callHint.height) {
186+ callHint.activate();
187+ // tapped on top half of indicator
188+ } else if (!fullscreenMode && position.y > indicatorScenePosition.y && position.y < indicatorScenePosition.y + panelHeight/2) {
180− callHint.activate();
189+ callHint.activate();
190+ }
181 }
191 }
182 }
192 }
183−
184− Rectangle {
185− anchors.fill: indicatorsMenu
186− color: Qt.rgba(1,1,0,0.5)
187− }
188 }
193 }
189
194
190 PanelSeparatorLine {
195 PanelSeparatorLine {
191 id: indicatorsSeparatorLine
196 id: indicatorsSeparatorLine
192 visible: true
197 visible: true
193 anchors {
198 anchors {
194− left: indicatorsMenu.left
195− right: indicatorsMenu.right
196− }
197− y: indicatorsMenu.visualBottom
198− }
199−
200− BorderImage {
201− id: dropShadow
202− anchors {
203− top: indicators.top
199+ top: indicators.bottom
204− bottom: indicatorsSeparatorLine.bottom
200+ left: indicatorDividor.left
205− left: indicators.left
206 right: indicators.right
201 right: indicators.right
207− margins: -units.gu(1)
208 }
202 }
209− visible: indicatorsMenu.height > indicatorsMenu.panelHeight
210− source: "graphics/rectangular_dropshadow.sci"
211 }
203 }
204+ }
212
205
213− SearchIndicator {
206+ SearchIndicator {
214− id: search
207+ id: search
215− objectName: "search"
208+ objectName: "search"
216− enabled: root.searchVisible
209+ enabled: root.searchVisible
217
210
218− state: {
211+ state: {
219− if (parent.width < indicatorsMenu.width + width) {
212+ if (parent.width < indicators.width + width) {
220− if (indicatorsMenu.state != "initial") {
213+ if (indicators.state != "initial") {
221− return "hidden";
214+ return "hidden";
222− }
223 }
215 }
224− if (root.searchVisible && !indicatorsMenu.showAll) {
225− return "visible";
226− }
227− return "hidden";
228 }
216 }
229−
217+ if (root.searchVisible && !indicators.showAll) {
230− anchors {
218+ return "visible";
231− top: parent.top
232− left: parent.left
233 }
219 }
234− height: panelBackground.height
220+ return "hidden";
221+ }
235
222
236− mouseArea {
237− onClicked: root.searchClicked()
238− }
239− Rectangle {
240− anchors.fill: search.mouseArea
223+ anchors {
241− color: Qt.rgba(1,0,0,0.5)
224+ top: nonIndicatorArea.top
242− }
225+ bottom: nonIndicatorArea.bottom
226+ left: nonIndicatorArea.left
243 }
227 }
228+
229+ mouseArea {
230+ onClicked: root.searchClicked()
231+ }
232+ }
233+
234+ ActiveCallHint {
235+ id: __callHint
236+ anchors {
237+ left: parent.left
238+ right: parent.right
239+ }
240+ height: units.gu(3)
241+ y: -height
242+
243+ states: [
244+ State {
245+ name: "active"
246+ when: callHint.active
247+ PropertyChanges { target: callHint; y: 0 }
248+ PropertyChanges { target: search.mouseArea; anchors.topMargin: -callHint.height/3 }
249+ }
250+ ]
251+ Behavior on y { StandardAnimation {} }
252+ }
253+
254+ QtObject {
255+ id: d
256+ readonly property real indicatorHeight: indicators.panelHeight + leftSeparatorLine.height
244 }
257 }
245
258
246 states: [
259 states: [
247 State {
260 State {
248− name: "in" //fully opaque and visible at top edge of screen
261+ name: "onscreen" //fully opaque and visible at top edge of screen
249 when: !fullscreenMode
262 when: !fullscreenMode
250− PropertyChanges { target: indicatorArea; y: callHint.y + callHint.height }
251− PropertyChanges { target: callHint; z: 0 }
252 },
263 },
253 State {
264 State {
254− name: "out" //pushed off screen
265+ name: "offscreen" //pushed off screen
255 when: fullscreenMode
266 when: fullscreenMode
256− PropertyChanges { target: indicatorArea; y: callHint.y + callHint.height - indicatorHeight }
267+ PropertyChanges { target: nonIndicatorArea; anchors.topMargin: -d.indicatorHeight }
257− PropertyChanges { target: callHint; z: 2 }
268+ PropertyChanges { target: indicatorArea; anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 }
269+ }
270+ ]
271+
272+ transitions: [
273+ Transition {
274+ to: "onscreen"
275+ SequentialAnimation {
276+ ParallelAnimation {
277+ StandardAnimation { target: nonIndicatorArea; property: "anchors.topMargin" }
278+ StandardAnimation { target: indicatorArea; property: "anchors.topMargin" }
279+ }
280+ PropertyAction { target: search; property: "z"; value: 2 }
281+ PropertyAction { target: indicatorArea; property: "z"; value: 2 }
282+ }
283+ },
284+ Transition {
285+ to: "offscreen"
286+ SequentialAnimation {
287+ PropertyAction { target: search; property: "z"; value: 0 }
288+ PropertyAction { target: indicatorArea; property: "z"; value: 0 }
289+ ParallelAnimation {
290+ StandardAnimation { target: nonIndicatorArea; property: "anchors.topMargin" }
291+ StandardAnimation { target: indicatorArea; property: "anchors.topMargin" }
292+ }
293+ }
258 }
294 }
259 ]
295 ]
260}
296}
qml/Shell.qml−7
@@ -461,13 +461,6 @@ FocusScope {
461 panel.hideIndicatorMenu(delay);
461 panel.hideIndicatorMenu(delay);
462 }
462 }
463
463
464− Timer {
465− running: true
466− interval: 7000
467− repeat: true
468− onTriggered: {panel.fullscreenMode = !panel.fullscreenMode }
469− }
470−
471 Item {
464 Item {
472 id: overlay
465 id: overlay
473
466
tests/qmltests/Panel/tst_Indicators.qml+10−21
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20+import Ubuntu.Components 0.1 as UC
20import ".."
21import ".."
21import "../../../qml/Panel"
22import "../../../qml/Panel"
22import "../../../qml/Components"
23import "../../../qml/Components"
@@ -45,13 +46,12 @@ Item {
45 shown: false
46 shown: false
46 profile: "test1"
47 profile: "test1"
47
48
48− openedHeight: parent.height - click_me.height
49+ openedHeight: parent.height - button.height
49 }
50 }
50
51
51− // Just a rect for clicking to open the indicators.
52+ UC.Button {
52− Rectangle {
53+ id: button
53− id: click_me
54+ text: indicators.shown ? "Hide" : "Show"
54− color: "red"
55 anchors {
55 anchors {
56 bottom: shell.bottom
56 bottom: shell.bottom
57 left: parent.left
57 left: parent.left
@@ -59,22 +59,11 @@ Item {
59 }
59 }
60 height: 50
60 height: 50
61
61
62− Text {
63− text: "Click Me"
64− horizontalAlignment: Text.AlignHCenter
65− verticalAlignment: Text.AlignVCenter
66− anchors.fill: parent
67−
68− MouseArea {
69− anchors.fill: parent
70−
71− onClicked: {
62+ onClicked: {
72− if (!indicators.shown) {
63+ if (!indicators.shown) {
73− indicators.show();
64+ indicators.show();
74− } else {
65+ } else {
75− indicators.hide();
66+ indicators.hide();
76− }
77− }
78 }
67 }
79 }
68 }
80 }
69 }
tests/qmltests/Panel/tst_Panel.qml+120−30
@@ -17,6 +17,7 @@
17import QtQuick 2.0
17import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import Unity.Test 0.1 as UT
19import Unity.Test 0.1 as UT
20+import Ubuntu.Components 0.1 as UC
20import Ubuntu.Telephony 0.1 as Telephony
21import Ubuntu.Telephony 0.1 as Telephony
21import ".."
22import ".."
22import "../../../qml/Panel"
23import "../../../qml/Panel"
@@ -40,13 +41,81 @@ Item {
40
41
41 Panel {
42 Panel {
42 id: panel
43 id: panel
43− anchors.fill: parent
44+ anchors {
45+ left: parent.left
46+ right: parent.right
47+ }
48+ height: parent.height - row.height
44 fullscreenMode: false
49 fullscreenMode: false
45
50
46 indicators {
51 indicators {
47 profile: "test1"
52 profile: "test1"
48 panelHeight: units.gu(5)
53 panelHeight: units.gu(5)
49 }
54 }
55+ callHint {
56+ height: units.gu(4)
57+ }
58+
59+ onSearchClicked: console.log("Search Clicked")
60+
61+ property real panelAndSeparatorHeight: panel.indicators.panelHeight + units.dp(2)
62+ }
63+
64+
65+ Row {
66+ id: row
67+ anchors {
68+ bottom: shell.bottom
69+ left: parent.left
70+ right: parent.right
71+ }
72+ height: 50
73+
74+ UC.Button {
75+ text: panel.indicators.shown ? "Hide" : "Show"
76+ anchors {
77+ top: parent.top
78+ bottom: parent.bottom
79+ }
80+ width: parent.width/3
81+
82+ onClicked: {
83+ if (panel.indicators.shown) {
84+ panel.indicators.hide();
85+ } else {
86+ panel.indicators.show();
87+ }
88+ }
89+ }
90+
91+ UC.Button {
92+ text: panel.fullscreenMode ? "Maximize" : "FullScreen"
93+ anchors {
94+ top: parent.top
95+ bottom: parent.bottom
96+ }
97+ width: parent.width/3
98+
99+ onClicked: panel.fullscreenMode = !panel.fullscreenMode
100+ }
101+
102+ UC.Button {
103+ text: callManager.hasCalls ? "Called" : "No Calls"
104+ anchors {
105+ top: parent.top
106+ bottom: parent.bottom
107+ }
108+ width: parent.width/3
109+
110+ onClicked: {
111+ if (callManager.hasCalls) {
112+ callManager.foregroundCall = null;
113+ callManager.backgroundCall = null;
114+ } else {
115+ callManager.foregroundCall = phoneCall;
116+ }
117+ }
118+ }
50 }
119 }
51
120
52 Telephony.CallEntry {
121 Telephony.CallEntry {
@@ -60,12 +129,18 @@ Item {
60
129
61 function init() {
130 function init() {
62 panel.indicators.initialise();
131 panel.indicators.initialise();
132+ panel.fullscreenMode = false;
63
133
64 searchClicked = false;
134 searchClicked = false;
65 panel.indicators.hide();
135 panel.indicators.hide();
136+ // Wait for animation to complete
66 tryCompare(panel.indicators.hideAnimation, "running", false);
137 tryCompare(panel.indicators.hideAnimation, "running", false);
67− tryCompare(panel.indicators, "state", "initial");
68 callManager.foregroundCall = null;
138 callManager.foregroundCall = null;
139+
140+ // Wait for the indicators to get into position.
141+ // (switches between normal and fullscreen modes are animated)
142+ var indicatorArea = findChild(panel, "indicatorArea");
143+ tryCompare(indicatorArea, "y", 0);
69 }
144 }
70
145
71 function get_indicator_item(index) {
146 function get_indicator_item(index) {
@@ -88,27 +163,22 @@ Item {
88 // Pressing on the indicator panel should activate the indicator hints
163 // Pressing on the indicator panel should activate the indicator hints
89 // and expose a portion of the conent.
164 // and expose a portion of the conent.
90 function test_hint() {
165 function test_hint() {
91− panel.fullscreenMode = false;
92− // Wait for the indicators to get into position.
93− // (switches between normal and fullscreen modes are animated)
94− tryCompare(panel.indicators, "y", 0);
95−
96 var indicatorItemCoord = get_indicator_item_position(0);
166 var indicatorItemCoord = get_indicator_item_position(0);
97
167
98− touchPress(panel, indicatorItemCoord.x, panel.panelHeight / 2);
168+ touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2);
99
169
100 // hint animation should be run, meaning that indicators will move downwards
170 // hint animation should be run, meaning that indicators will move downwards
101 // by hintValue pixels without any drag taking place
171 // by hintValue pixels without any drag taking place
102− tryCompare(panel.indicators, "height",
172+ tryCompareFunction2(function() { return panel.indicators.height },
103− panel.indicators.panelHeight + panel.indicators.hintValue);
173+ function() { return panel.indicators.panelHeight + panel.indicators.hintValue });
104 tryCompare(panel.indicators, "partiallyOpened", true);
174 tryCompare(panel.indicators, "partiallyOpened", true);
105 tryCompare(panel.indicators, "fullyOpened", false);
175 tryCompare(panel.indicators, "fullyOpened", false);
106
176
107− touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
177+ touchRelease(panel, indicatorItemCoord.x, panel.indicators.panelHeight/2);
108 }
178 }
109
179
110 // Pressing on the top edge of the screen should have no effect if the panel
180 // Pressing on the top edge of the screen should have no effect if the panel
111− // is hidden (!pinned), which is the case when a fullscreen app is being shown
181+ // is hidden (fullscreen), which is the case when a fullscreen app is being shown
112 function test_noHintOnFullscreenMode() {
182 function test_noHintOnFullscreenMode() {
113 panel.fullscreenMode = true;
183 panel.fullscreenMode = true;
114 // Wait for the indicators to get into position.
184 // Wait for the indicators to get into position.
@@ -118,17 +188,38 @@ Item {
118
188
119 var indicatorItemCoord = get_indicator_item_position(0);
189 var indicatorItemCoord = get_indicator_item_position(0);
120
190
121− touchPress(panel, indicatorItemCoord.x, panel.panelHeight / 2);
191+ touchPress(panel, indicatorItemCoord.x, panel.indicators.panelHeight / 2);
192+
193+ // Give some time for a hint animation to change things, if any
194+ wait(500);
195+
196+ // no hint animation when fullscreen
197+ compare(panel.indicators.partiallyOpened, false,
198+ "Indicator should not be partially opened when panel is pressed in" +
199+ " fullscreenmode");
200+ compare(panel.indicators.fullyOpened, false, "Indicator should not be partially" +
201+ " opened when panel is pressed in fullscreenmode");
202+
203+ touchRelease(panel, indicatorItemCoord.x, panel.panelHeight/2);
204+ }
205+
206+ // Pressing on the top edge of the indicator should have no effect if the panel
207+ // has an active call
208+ function test_noHintOnActiveCall() {
209+ callManager.foregroundCall = phoneCall;
210+ // Wait for the indicators to get into position.
211+ // (switches between normal and fullscreen modes are animated)
212+ var indicatorArea = findChild(panel, "indicatorArea");
213+ tryCompare(indicatorArea, "y", panel.callHint.height);
214+
215+ var indicatorItemCoord = get_indicator_item_position(0);
216+
217+ touchPress(panel, indicatorItemCoord.x, panel.callHint.height + panel.indicators.panelHeight / 2);
122
218
123 // Give some time for a hint animation to change things, if any
219 // Give some time for a hint animation to change things, if any
124 wait(500);
220 wait(500);
125
221
126 // no hint animation when fullscreen
222 // no hint animation when fullscreen
127− compare(indicatorArea.y, -panel.panelHeight);
128− var indicatorRow = findChild(panel.indicators, "indicatorRow");
129− verify(indicatorRow !== null);
130− compare(indicatorRow.y, 0);
131− compare(panel.indicators.height, panel.indicators.panelHeight);
132 compare(panel.indicators.partiallyOpened, false,
223 compare(panel.indicators.partiallyOpened, false,
133 "Indicator should not be partially opened when panel is pressed in" +
224 "Indicator should not be partially opened when panel is pressed in" +
134 " fullscreenmode");
225 " fullscreenmode");
@@ -143,15 +234,15 @@ Item {
143 { tag: "pinned", fullscreenFlag: false, alreadyOpen: false, call: null,
234 { tag: "pinned", fullscreenFlag: false, alreadyOpen: false, call: null,
144 indicatorY: function() { return 0 } },
235 indicatorY: function() { return 0 } },
145 { tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false, call: null,
236 { tag: "fullscreen", fullscreenFlag: true, alreadyOpen: false, call: null,
146− indicatorY: function() {return -panel.panelHeight } },
237+ indicatorY: function() {return -panel.panelAndSeparatorHeight } },
147 { tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true, call: null,
238 { tag: "pinned-alreadyOpen", fullscreenFlag: false, alreadyOpen: true, call: null,
148 indicatorY: function() { return 0 } },
239 indicatorY: function() { return 0 } },
149 { tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true, call: null,
240 { tag: "fullscreen-alreadyOpen", fullscreenFlag: true, alreadyOpen: true, call: null,
150− indicatorY: function() {return -panel.panelHeight } },
241+ indicatorY: function() {return -panel.panelAndSeparatorHeight } },
151 { tag: "pinned-callActive", fullscreenFlag: false, alreadyOpen: false, call: phoneCall,
242 { tag: "pinned-callActive", fullscreenFlag: false, alreadyOpen: false, call: phoneCall,
152− indicatorY: function() { return units.gu(3) } },
243+ indicatorY: function() { return panel.callHint.height } },
153 { tag: "fullscreen-callActive", fullscreenFlag: true, alreadyOpen: false, call: phoneCall,
244 { tag: "fullscreen-callActive", fullscreenFlag: true, alreadyOpen: false, call: phoneCall,
154− indicatorY: function() {return units.gu(3) - (panel.panelHeight - units.gu(3)) } }
245+ indicatorY: function() { return panel.callHint.height - panel.panelAndSeparatorHeight } }
155 ];
246 ];
156 }
247 }
157
248
@@ -160,7 +251,6 @@ Item {
160 // expose more of the panel, binding it to the selected indicator and opening it's menu.
251 // expose more of the panel, binding it to the selected indicator and opening it's menu.
161 function test_drag_show(data) {
252 function test_drag_show(data) {
162 panel.fullscreenMode = data.fullscreenFlag;
253 panel.fullscreenMode = data.fullscreenFlag;
163−
164 callManager.foregroundCall = data.call;
254 callManager.foregroundCall = data.call;
165
255
166 if (data.alreadyOpen) {
256 if (data.alreadyOpen) {
@@ -179,7 +269,7 @@ Item {
179
269
180 // Wait for the indicators to get into position.
270 // Wait for the indicators to get into position.
181 // (switches between normal and fullscreen modes are animated)
271 // (switches between normal and fullscreen modes are animated)
182− tryCompare(indicatorArea, "y", data.indicatorY());
272+ tryCompareFunction2(function() { return indicatorArea.y } , data.indicatorY);
183
273
184 // do this for each indicator item
274 // do this for each indicator item
185 for (var i = 0; i < indicatorRow.row.count; i++) {
275 for (var i = 0; i < indicatorRow.row.count; i++) {
@@ -193,11 +283,11 @@ Item {
193 var indicatorItemCoord = get_indicator_item_position(i);
283 var indicatorItemCoord = get_indicator_item_position(i);
194
284
195 touchPress(panel,
285 touchPress(panel,
196− indicatorItemCoord.x, panel.panelHeight / 2);
286+ indicatorItemCoord.x, panel.indicators.panelHeight / 2);
197
287
198 // 1) Drag the mouse down
288 // 1) Drag the mouse down
199 touchFlick(panel,
289 touchFlick(panel,
200− indicatorItemCoord.x, panel.panelHeight / 2,
290+ indicatorItemCoord.x, panel.indicators.panelHeight / 2,
201 indicatorItemCoord.x, panel.height,
291 indicatorItemCoord.x, panel.height,
202 false /* beginTouch */, false /* endTouch */);
292 false /* beginTouch */, false /* endTouch */);
203
293
@@ -266,19 +356,19 @@ Item {
266 var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.row.count - 1);
356 var indicatorItemCoordNext = get_indicator_item_position(indicatorRow.row.count - 1);
267
357
268 touchPress(panel,
358 touchPress(panel,
269− indicatorItemCoordFirst.x, panel.panelHeight / 2);
359+ indicatorItemCoordFirst.x, panel.indicators.panelHeight / 2);
270
360
271 // 1) Drag the mouse down to hint a bit
361 // 1) Drag the mouse down to hint a bit
272 touchFlick(panel,
362 touchFlick(panel,
273− indicatorItemCoordFirst.x, panel.panelHeight / 2,
363+ indicatorItemCoordFirst.x, panel.indicators.panelHeight / 2,
274− indicatorItemCoordFirst.x, panel.panelHeight * 2,
364+ indicatorItemCoordFirst.x, panel.indicators.panelHeight * 2,
275 false /* beginTouch */, false /* endTouch */);
365 false /* beginTouch */, false /* endTouch */);
276
366
277 tryCompare(indicatorRow, "currentItem", indicatorItemFirst)
367 tryCompare(indicatorRow, "currentItem", indicatorItemFirst)
278
368
279 // 1) Flick mouse down to bottom
369 // 1) Flick mouse down to bottom
280 touchFlick(panel,
370 touchFlick(panel,
281− indicatorItemCoordFirst.x, panel.panelHeight * 2,
371+ indicatorItemCoordFirst.x, panel.indicators.panelHeight * 2,
282 indicatorItemCoordNext.x, panel.height,
372 indicatorItemCoordNext.x, panel.height,
283 false /* beginTouch */, true /* endTouch */,
373 false /* beginTouch */, true /* endTouch */,
284 units.gu(10) /* speed */, 30 /* iterations */); // more samples needed for accurate velocity
374 units.gu(10) /* speed */, 30 /* iterations */); // more samples needed for accurate velocity
tests/utils/modules/Unity/Test/UnityTestCase.qml+29
@@ -202,6 +202,35 @@ TestCase {
202 }
202 }
203 }
203 }
204
204
205+ // Keeps executing a given parameter-less function until it returns the given
206+ // expected result or the timemout is reached (in which case a test failure
207+ // is generated)
208+ function tryCompareFunction2(func, expectedResultFunc) {
209+ var timeSpent = 0
210+ var timeout = 5000
211+ var success = false
212+ var actualResult
213+ var expectedResult
214+ while (timeSpent < timeout && !success) {
215+ actualResult = func()
216+ expectedResult = expectedResultFunc()
217+ success = qtest_compareInternal(actualResult, expectedResult)
218+ if (success === false) {
219+ wait(50)
220+ timeSpent += 50
221+ }
222+ }
223+
224+ var act = qtest_results.stringify(actualResult)
225+ var exp = qtest_results.stringify(expectedResult)
226+ if (!qtest_results.compare(success,
227+ "function returned unexpected result",
228+ act, exp,
229+ util.callerFile(), util.callerLine())) {
230+ throw new Error("QtQuickTest::fail")
231+ }
232+ }
233+
205 function touchEvent() {
234 function touchEvent() {
206 return UT.Util.touchEvent()
235 return UT.Util.touchEvent()
207 }
236 }