on xenial help sign in
Added ActiveCallHint
c71e684Nick Dedekind
qml/Panel/ActiveCallHint.qmlnew file+143
@@ -0,0 +1,143 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
3+ *
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import Ubuntu.Telephony 0.1 as Telephony
19+import Ubuntu.Components 0.1
20+import Unity.Application 0.1
21+import "../Components"
22+
23+Rectangle {
24+ id: callHint
25+
26+ readonly property bool active: callManager.hasCalls && ApplicationManager.focusedApplicationId !== "dialer-app"
27+
28+ Component.onCompleted: {
29+ telepathyHelper.registerChannelObserver("unity8");
30+ }
31+
32+ color: Qt.rgba(0,0.8,0,1)
33+ clip: true
34+
35+ MouseArea {
36+ anchors.fill: parent
37+ onClicked: {
38+ ApplicationManager.requestFocusApplication("dialer-app");
39+ }
40+ }
41+
42+ Column {
43+ id: column
44+
45+ anchors {
46+ left: parent.left
47+ leftMargin:units.gu(1)
48+ right: time.left
49+ }
50+ y: 0
51+ Behavior on y { StandardAnimation { duration: 400 } }
52+
53+ Label {
54+ id: label1
55+ anchors {
56+ left: parent.left
57+ right: parent.right
58+ }
59+ height: callHint.height
60+ verticalAlignment: Text.AlignVCenter
61+
62+ text: {
63+ if (!d.activeCall) {
64+ return "";
65+ } else if (d.activeCall.isConference) {
66+ return i18n.tr("Conference");
67+ } else {
68+ return contactWatcher.alias !== "" ? contactWatcher.alias : contactWatcher.phoneNumber;
69+ }
70+ }
71+ }
72+
73+ Label {
74+ id: label2
75+ anchors {
76+ left: parent.left
77+ right: parent.right
78+ }
79+ height: callHint.height
80+ verticalAlignment: Text.AlignVCenter
81+ text: i18n.tr("Tap to return to call...");
82+ }
83+ }
84+
85+ Label {
86+ id: time
87+ anchors {
88+ right: parent.right
89+ rightMargin:units.gu(1)
90+ top: parent.top
91+ }
92+ height: parent.height
93+ verticalAlignment: Text.AlignVCenter
94+ text: {
95+ if (!d.activeCall) {
96+ return "0:00";
97+ }
98+ var m = Math.round(d.activeCall.elapsedTime/60);
99+ var ss = d.activeCall.elapsedTime % 60;
100+ if (ss >= 10) {
101+ return m + ":" + ss;
102+ } else {
103+ return m + ":0" + ss;
104+ }
105+ }
106+ }
107+
108+ Telephony.ContactWatcher {
109+ id: contactWatcher
110+ phoneNumber: d.activeCall ? d.activeCall.phoneNumber : ""
111+ }
112+
113+ Timer {
114+ running: callHint.active
115+ interval: 4000
116+ repeat: true
117+
118+ property int iteration: 0
119+
120+ onRunningChanged: iteration = 0; // bit longer for the first one.
121+
122+ onTriggered: {
123+ // every 4 seconds.
124+ if (iteration % 2 == 0) {
125+ column.y = -label1.height;
126+ } else {
127+ column.y = 0;
128+ }
129+ iteration++;
130+ }
131+ }
132+
133+ QtObject {
134+ id: d
135+
136+ property QtObject activeCall: {
137+ if (callManager.foregroundCall) {
138+ return callManager.foregroundCall;
139+ }
140+ return callManager.backgroundCall;
141+ }
142+ }
143+}
qml/Panel/Indicators.qml+1−3
@@ -48,14 +48,12 @@ Showable {
48 // use its own values. Need to ask design about this.
48 // use its own values. Need to ask design about this.
49 showAnimation: StandardAnimation {
49 showAnimation: StandardAnimation {
50 property: "height"
50 property: "height"
51− duration: 350
52 to: openedHeight
51 to: openedHeight
53− easing.type: Easing.OutCubic
54
52
55 // Re-size if we've changed the openHeight while shown.
53 // Re-size if we've changed the openHeight while shown.
56 onToChanged: {
54 onToChanged: {
57 if (indicators.shown) {
55 if (indicators.shown) {
58− indicators.show();
56+ height = openedHeight;
59 }
57 }
60 }
58 }
61 }
59 }
qml/Panel/Panel.qml+109−84
@@ -20,14 +20,12 @@ import "../Components"
20
20
21Item {
21Item {
22 id: root
22 id: root
23− readonly property real panelHeight: units.gu(3) + units.dp(2)
23+ readonly property real panelHeight: callHint.active ? callHint.height + lowerPanelHeight : lowerPanelHeight
24− property real indicatorsMenuWidth: (shell.width > units.gu(60)) ? units.gu(40) : shell.width
24+ property real indicatorsMenuWidth: (width > units.gu(60)) ? units.gu(40) : width
25 property alias indicators: indicatorsMenu
25 property alias indicators: indicatorsMenu
26 property bool fullscreenMode: false
26 property bool fullscreenMode: false
27 property bool searchVisible: true
27 property bool searchVisible: true
28−
29− readonly property real separatorLineHeight: leftSeparatorLine.height
28+ readonly property real lowerPanelHeight: indicatorsMenu.panelHeight + leftSeparatorLine.height
30− readonly property real __panelMinusSeparatorLineHeight: panelHeight - separatorLineHeight
31
29
32 signal searchClicked
30 signal searchClicked
33
31
@@ -53,120 +51,147 @@ Item {
53 onShownChanged: hideTimer.stop()
51 onShownChanged: hideTimer.stop()
54 }
52 }
55
53
56− PanelBackground {
54+ ActiveCallHint {
57− id: panelBackground
55+ id: callHint
56+
58 anchors {
57 anchors {
59 left: parent.left
58 left: parent.left
60 right: parent.right
59 right: parent.right
61 }
60 }
62− height: __panelMinusSeparatorLineHeight
61+ height: units.gu(3)
63− y: 0
64
62
65− Behavior on y { StandardAnimation { duration: UbuntuAnimation.FastDuration } }
63+ y: active ? 0 : -height
66− }
64+ z: 1
67
65
68− PanelSeparatorLine {
66+ Behavior on y { StandardAnimation {} }
69− id: leftSeparatorLine
70− anchors {
71− top: panelBackground.bottom
72− left: parent.left
73− right: indicatorsMenu.left
74− }
75− saturation: 1 - indicatorsMenu.unitProgress
76 }
67 }
77
68
78− Rectangle {
69+ Item {
79− id: darkenedArea
70+ id: lowerPanel
80− property real darkenedOpacity: 0.6
71+
81 anchors {
72 anchors {
82 left: parent.left
73 left: parent.left
83 right: parent.right
74 right: parent.right
84− top: panelBackground.bottom
85− bottom: parent.bottom
86 }
75 }
87− color: "black"
76+ height: root.height - lowerPanel.y
88− opacity: indicatorsMenu.unitProgress * darkenedOpacity
77+ z: 0
89− MouseArea {
78+
79+ PanelBackground {
80+ id: panelBackground
90− anchors.fill: parent
81+ anchors {
91− enabled: indicatorsMenu.shown
82+ top: parent.top
92− onClicked: if (indicatorsMenu.fullyOpened) indicatorsMenu.hide();
83+ left: parent.left
84+ right: parent.right
85+ }
86+ height: indicatorsMenu.panelHeight
93 }
87 }
94− }
95
88
96− Indicators {
89+ PanelSeparatorLine {
97− id: indicatorsMenu
90+ id: leftSeparatorLine
98− objectName: "indicators"
99−
100− anchors.right: parent.right
91+ anchors {
101− y: panelBackground.y
92+ top: panelBackground.bottom
102− width: root.indicatorsMenuWidth
93+ left: parent.left
103− shown: false
94+ right: indicatorsMenu.left
104− panelHeight: __panelMinusSeparatorLineHeight
95+ }
105− openedHeight: parent.height + (pinnedMode ? 0 : root.panelHeight)
106− pinnedMode: !fullscreenMode
107− overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
108− }
109−
110− PanelSeparatorLine {
111− id: indicatorsSeparatorLine
112− visible: true
113− anchors {
114− left: indicatorsMenu.left
96+ saturation: 1 - indicatorsMenu.unitProgress
115− right: indicatorsMenu.right
116 }
97 }
117− y: indicatorsMenu.visualBottom
118− }
119
98
120− BorderImage {
99+ Rectangle {
121− id: dropShadow
100+ id: darkenedArea
101+ property real darkenedOpacity: 0.6
122− anchors {
102+ anchors {
123− top: indicators.top
103+ left: parent.left
104+ right: parent.right
105+ top: panelBackground.bottom
124− bottom: indicatorsSeparatorLine.bottom
106+ bottom: parent.bottom
125− left: indicators.left
107+ }
126− right: indicators.right
108+ color: "black"
127− margins: -units.gu(1)
109+ opacity: indicatorsMenu.unitProgress * darkenedOpacity
110+ MouseArea {
111+ anchors.fill: parent
112+ enabled: indicatorsMenu.shown
113+ onClicked: if (indicatorsMenu.fullyOpened) indicatorsMenu.hide();
114+ }
128 }
115 }
129− visible: indicatorsMenu.height > indicatorsMenu.panelHeight
130− source: "graphics/rectangular_dropshadow.sci"
131− }
132
116
133− SearchIndicator {
117+ Indicators {
134− id: search
118+ id: indicatorsMenu
135− objectName: "search"
119+ objectName: "indicators"
136− enabled: root.searchVisible
137
120
138− state: {
121+ anchors {
139− if (parent.width < indicatorsMenu.width + width) {
122+ top: parent.top
140− if (indicatorsMenu.state != "initial") {
123+ right: parent.right
141− return "hidden";
142− }
143− }
144− if (root.searchVisible && !indicatorsMenu.showAll) {
145− return "visible";
146 }
124 }
147
125
148− return "hidden";
126+ width: root.indicatorsMenuWidth
127+ shown: false
128+ panelHeight: units.gu(3)
129+ openedHeight: parent.height
130+ pinnedMode: !fullscreenMode
131+ overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
149 }
132 }
150
133
151− height: __panelMinusSeparatorLineHeight
134+ PanelSeparatorLine {
135+ id: indicatorsSeparatorLine
136+ visible: true
152− anchors {
137+ anchors {
153− top: panelBackground.top
138+ left: indicatorsMenu.left
154− left: panelBackground.left
139+ right: indicatorsMenu.right
140+ }
141+ y: indicatorsMenu.visualBottom
155 }
142 }
156
143
144+ BorderImage {
145+ id: dropShadow
146+ anchors {
147+ top: indicators.top
148+ bottom: indicatorsSeparatorLine.bottom
149+ left: indicators.left
150+ right: indicators.right
151+ margins: -units.gu(1)
152+ }
153+ visible: indicatorsMenu.height > indicatorsMenu.panelHeight
154+ source: "graphics/rectangular_dropshadow.sci"
155+ }
156+
157+ SearchIndicator {
158+ id: search
159+ objectName: "search"
160+ enabled: root.searchVisible
161+
162+ state: {
163+ if (parent.width < indicatorsMenu.width + width) {
164+ if (indicatorsMenu.state != "initial") {
165+ return "hidden";
166+ }
167+ }
168+ if (root.searchVisible && !indicatorsMenu.showAll) {
169+ return "visible";
170+ }
171+
172+ return "hidden";
173+ }
174+
175+ anchors {
176+ top: panelBackground.top
177+ left: panelBackground.left
178+ }
179+ height: panelBackground.height
180+
157− onClicked: root.searchClicked()
181+ onClicked: root.searchClicked()
182+ }
158 }
183 }
159
184
160 states: [
185 states: [
161 State {
186 State {
162 name: "in" //fully opaque and visible at top edge of screen
187 name: "in" //fully opaque and visible at top edge of screen
163 when: !fullscreenMode
188 when: !fullscreenMode
164− PropertyChanges { target: panelBackground; y: 0 }
189+ PropertyChanges { target: lowerPanel; y: callHint.y + callHint.height }
165 },
190 },
166 State {
191 State {
167 name: "out" //pushed off screen
192 name: "out" //pushed off screen
168 when: fullscreenMode
193 when: fullscreenMode
169− PropertyChanges { target: panelBackground; y: -panelHeight }
194+ PropertyChanges { target: lowerPanel; y: callHint.y + callHint.height - lowerPanelHeight }
170 }
195 }
171 ]
196 ]
172}
197}
qml/Shell.qml+20−12
@@ -151,10 +151,10 @@ FocusScope {
151 shown: disappearingAnimationProgress !== 1.0
151 shown: disappearingAnimationProgress !== 1.0
152 enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
152 enabled: disappearingAnimationProgress === 0.0 && edgeDemo.dashEnabled
153
153
154− anchors {
154+ y: panel.panelHeight
155− fill: parent
155+ width: parent.width
156− topMargin: panel.panelHeight
156+ height: parent.height - panel.panelHeight
157− }
157+ Behavior on y { StandardAnimation {} }
158
158
159 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
159 contentScale: 1.0 - 0.2 * disappearingAnimationProgress
160 opacity: 1.0 - disappearingAnimationProgress
160 opacity: 1.0 - disappearingAnimationProgress
@@ -317,10 +317,13 @@ FocusScope {
317 enabled: true
317 enabled: true
318 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
318 showAnimation: StandardAnimation { property: "opacity"; to: 1 }
319 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
319 hideAnimation: StandardAnimation { property: "opacity"; to: 0 }
320+
320 y: panel.panelHeight
321 y: panel.panelHeight
321 x: required ? 0 : - width
322 x: required ? 0 : - width
322 width: parent.width
323 width: parent.width
323 height: parent.height - panel.panelHeight
324 height: parent.height - panel.panelHeight
325+ Behavior on y { StandardAnimation {} }
326+
324 background: shell.background
327 background: shell.background
325 pinLength: 4
328 pinLength: 4
326
329
@@ -375,6 +378,8 @@ FocusScope {
375 y: panel.panelHeight
378 y: panel.panelHeight
376 width: parent.width
379 width: parent.width
377 height: parent.height - panel.panelHeight
380 height: parent.height - panel.panelHeight
381+ Behavior on y { StandardAnimation {} }
382+ Behavior on height { StandardAnimation {} }
378
383
379 dragHandleWidth: shell.edgeSize
384 dragHandleWidth: shell.edgeSize
380
385
@@ -574,12 +579,12 @@ FocusScope {
574 model: NotificationBackend.Model
579 model: NotificationBackend.Model
575 margin: units.gu(1)
580 margin: units.gu(1)
576
581
577− anchors {
582+ y: panel.panelHeight
578− top: parent.top
583+ width: parent.width
579− right: parent.right
580− bottom: parent.bottom
581− topMargin: panel.panelHeight
584+ height: parent.height - panel.panelHeight
582− }
585+ Behavior on y { StandardAnimation {} }
586+ Behavior on height { StandardAnimation {} }
587+
583 states: [
588 states: [
584 State {
589 State {
585 name: "narrow"
590 name: "narrow"
@@ -632,8 +637,11 @@ FocusScope {
632 }
637 }
633
638
634 OSKController {
639 OSKController {
635− anchors.topMargin: panel.panelHeight
640+ y: panel.panelHeight
636− anchors.fill: parent // as needs to know the geometry of the shell
641+ width: parent.width
642+ height: parent.height - panel.panelHeight
643+ Behavior on y { StandardAnimation {} }
644+ Behavior on height { StandardAnimation {} }
637 }
645 }
638
646
639 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
647 //FIXME: This should be handled in the input stack, keyboard shouldnt propagate
tests/qmltests/Panel/tst_Panel.qml+1
@@ -40,6 +40,7 @@ Item {
40 Panel {
40 Panel {
41 id: panel
41 id: panel
42 anchors.fill: parent
42 anchors.fill: parent
43+ fullscreenMode: true
43
44
44 indicators {
45 indicators {
45 profile: "test1"
46 profile: "test1"