on xenial help sign in
single line active call hint
cdc76fdNick Dedekind
qml/Panel/ActiveCallHint.qml+73−132
@@ -25,9 +25,10 @@ Item {
25
25
26 property bool active: callManager.callIndicatorVisible
26 property bool active: callManager.callIndicatorVisible
27 readonly property QtObject contactWatcher: _contactWatcher
27 readonly property QtObject contactWatcher: _contactWatcher
28− property int alternateLabelInterval: 4000
28+ property int alternateLabelInterval: 6000
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+ implicitWidth: row.x + row.width
31
32
32 Component.onCompleted: {
33 Component.onCompleted: {
33 telepathyHelper.registerChannelObserver("unity8");
34 telepathyHelper.registerChannelObserver("unity8");
@@ -37,59 +38,14 @@ Item {
37 ApplicationManager.requestFocusApplication("dialer-app");
38 ApplicationManager.requestFocusApplication("dialer-app");
38 }
39 }
39
40
40− Rectangle {
41− id: background
42− anchors.fill: parent
43− color: callHint.color
44−
45− states: [
46− State {
47− name: "fade-down"
48− },
49− State {
50− name: "fade-up"
51− PropertyChanges { target: background; color: callHint.colorFlash }
52− }
53− ]
54− state: "fade-down"
55−
56− transitions: [
57− Transition {
58− to: "fade-up";
59− ColorAnimation { duration: 260; easing.type: Easing.InQuart }
60− },
61− Transition {
62− to: "fade-down";
63− ColorAnimation { duration: 150; easing.type: Easing.OutQuad }
64− }
65− ]
66−
67− Timer {
68− running: callHint.active && color != colorFlash
69− interval: background.state == "fade-down" ? 3000 : 400
70− repeat: true
71− onTriggered: {
72− if (background.state == "fade-down") {
73− background.state = "fade-up";
74− } else {
75− background.state = "fade-down";
76− }
77− }
78− }
79− }
80−
81 Component {
41 Component {
82− id: contactColumnRow
42+ id: contactColumn
83
43
84 Column {
44 Column {
85 id: column
45 id: column
86 objectName: "contactColumn"
46 objectName: "contactColumn"
87
47
88− anchors {
89− left: parent.left
48+ anchors.left: parent.left
90− right: parent.right
91− }
92− height: childrenRect.height
93
49
94 Component.onCompleted: {
50 Component.onCompleted: {
95 if (index === 0) {
51 if (index === 0) {
@@ -100,15 +56,16 @@ Item {
100 }
56 }
101
57
102 Label {
58 Label {
103− id: contactLabel
59+ height: callHint.height
104− objectName: "contactLabel"
60+ verticalAlignment: Text.AlignVCenter
61+ text: i18n.tr("Tap to return to call...");
62+ }
105
63
106− anchors {
64+ Label {
107− left: parent.left
65+ objectName: "contactLabel"
108− right: parent.right
109− }
110 height: callHint.height
66 height: callHint.height
111 verticalAlignment: Text.AlignVCenter
67 verticalAlignment: Text.AlignVCenter
68+ width: Math.max(contentWidth, 1)
112
69
113 text: {
70 text: {
114 if (!d.activeCall) {
71 if (!d.activeCall) {
@@ -120,76 +77,84 @@ Item {
120 }
77 }
121 }
78 }
122 }
79 }
123−
124− Label {
125− id: returnLabel
126−
127− anchors {
128− left: parent.left
129− right: parent.right
130− }
131− height: callHint.height
132− verticalAlignment: Text.AlignVCenter
133− text: i18n.tr("Tap to return to call...");
134− }
135 }
80 }
136 }
81 }
137
82
138− PathView {
83+ Row {
139− id: labelPathView
84+ id: row
140− objectName: "labelPathView"
141−
142 anchors {
85 anchors {
143 top: parent.top
86 top: parent.top
87+ bottom: parent.bottom
144 left: parent.left
88 left: parent.left
145− leftMargin:units.gu(1)
89+ leftMargin: units.gu(1)
146− right: time.left
147 }
90 }
148− height: columnHeight > callHint.height ? callHint.height : columnHeight
91+ spacing: units.gu(1)
149− clip: true
92+
150−
93+ Label {
151− property Column column1
94+ id: time
152− property Column column2
95+ objectName: "timeLabel"
153− property int columnHeight: column1 ? column1.height : 0
96+
154−
97+ anchors {
155− delegate: contactColumnRow
98+ top: parent.top
156− model: 2
99+ bottom: parent.bottom
157− offset: 0
100+ }
158− interactive: false
101+ verticalAlignment: Text.AlignVCenter
159−
102+ horizontalAlignment: Text.AlignRight
160− path: Path {
103+ text: {
161− startY: -labelPathView.columnHeight / 2
104+ var m = Math.round(d.callTime/60);
162− PathLine {
105+ var ss = d.callTime % 60;
163− y: labelPathView.columnHeight * 1.5
106+ if (ss >= 10) {
107+ return m + ":" + ss;
108+ } else {
109+ return m + ":0" + ss;
110+ }
164 }
111 }
165 }
112 }
166
113
114+ PathView {
115+ id: labelPathView
116+ objectName: "labelPathView"
117+
118+ anchors {
119+ top: parent.top
120+ bottom: parent.bottom
121+ }
122+ width: column1 && column2 ? Math.max(column1.width, column1.width) : 0
123+ clip: true
124+
125+ property Column column1
126+ property Column column2
127+ property int columnHeight: column1 ? column1.height : 0
128+
129+ delegate: contactColumn
130+ model: 2
167− Behavior on offset {
131+ offset: 0
168− id: offsetBehaviour
132+ interactive: false
169− SmoothedAnimation {
133+
170− id: offsetAnimation
134+ path: Path {
171− // ensure we go faster than the label switch
135+ startY: -labelPathView.columnHeight / 2
172− duration: alternateLabelInterval / 2
136+ PathLine {
173− velocity: 0.75
137+ y: labelPathView.columnHeight * 1.5
174− easing.type: Easing.InOutQuad
138+ }
175 }
139 }
176− }
177− }
178
140
179− // Fade in text
141+ Behavior on offset {
180− Rectangle {
142+ id: offsetBehaviour
181− anchors.fill: parent
143+ SmoothedAnimation {
182− gradient: Gradient {
144+ id: offsetAnimation
183− GradientStop { position: 0.0; color: background.color }
145+ // ensure we go faster than the label switch
184− GradientStop { position: 0.25; color: Qt.rgba(background.color.r, background.color.g, background.color.b, 0.0) }
146+ duration: alternateLabelTimer.interval / 2
185− GradientStop { position: 0.75; color: Qt.rgba(background.color.r, background.color.g, background.color.b, 0.0) }
147+ velocity: 0.75
186− GradientStop { position: 1.0; color: background.color }
148+ easing.type: Easing.InOutQuad
149+ }
150+ }
187 }
151 }
188 }
152 }
189
153
190 Timer {
154 Timer {
155+ id: alternateLabelTimer
191 running: callHint.active
156 running: callHint.active
192− interval: alternateLabelInterval
157+ interval: labelPathView.offset % 1.0 !== 0 ? alternateLabelInterval : alternateLabelInterval/4
193 repeat: true
158 repeat: true
194
159
195 onRunningChanged: {
160 onRunningChanged: {
@@ -205,31 +170,6 @@ Item {
205 }
170 }
206 }
171 }
207
172
208− Label {
209− id: time
210− objectName: "timeLabel"
211−
212− anchors {
213− right: parent.right
214− rightMargin:units.gu(1)
215− top: parent.top
216− }
217− height: parent.height
218− verticalAlignment: Text.AlignVCenter
219− text: {
220− if (!d.activeCall) {
221− return "0:00";
222− }
223− var m = Math.round(d.activeCall.elapsedTime/60);
224− var ss = d.activeCall.elapsedTime % 60;
225− if (ss >= 10) {
226− return m + ":" + ss;
227− } else {
228− return m + ":0" + ss;
229− }
230− }
231− }
232−
233 Telephony.ContactWatcher {
173 Telephony.ContactWatcher {
234 id: _contactWatcher
174 id: _contactWatcher
235 objectName: "contactWatcher"
175 objectName: "contactWatcher"
@@ -245,5 +185,6 @@ Item {
245 }
185 }
246 return callManager.backgroundCall;
186 return callManager.backgroundCall;
247 }
187 }
188+ property int callTime: activeCall ? activeCall.elapsedTime : 0
248 }
189 }
249}
190}
qml/Panel/Indicators.qml+1−2
@@ -43,7 +43,6 @@ Showable {
43 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
43 property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
44 property bool enableHint: true
44 property bool enableHint: true
45 property real showHintBottomMargin: 0
45 property real showHintBottomMargin: 0
46− property real showHintHeightOffset: 0
47
46
48 signal showTapped(point position)
47 signal showTapped(point position)
49
48
@@ -346,7 +345,7 @@ Showable {
346 anchors.bottomMargin: showHintBottomMargin
345 anchors.bottomMargin: showHintBottomMargin
347 anchors.left: parent.left
346 anchors.left: parent.left
348 anchors.right: parent.right
347 anchors.right: parent.right
349− height: panelHeight + showHintHeightOffset
348+ height: panelHeight
350 direction: Direction.Downwards
349 direction: Direction.Downwards
351 enabled: !indicators.shown && indicators.available
350 enabled: !indicators.shown && indicators.available
352 hintDisplacement: enableHint ? indicators.hintValue : 0
351 hintDisplacement: enableHint ? indicators.hintValue : 0
qml/Panel/Panel.qml+75−141
@@ -22,7 +22,7 @@ import "../Components/ListItems"
22
22
23Item {
23Item {
24 id: root
24 id: root
25− readonly property real panelHeight: nonIndicatorArea.y + nonIndicatorArea.height
25+ readonly property real panelHeight: indicatorArea.y + d.indicatorHeight
26 property alias indicators: __indicators
26 property alias indicators: __indicators
27 property alias callHint: __callHint
27 property alias callHint: __callHint
28 property bool fullscreenMode: false
28 property bool fullscreenMode: false
@@ -56,9 +56,10 @@ Item {
56 id: darkenedArea
56 id: darkenedArea
57 property real darkenedOpacity: 0.6
57 property real darkenedOpacity: 0.6
58 anchors {
58 anchors {
59+ top: parent.top
60+ topMargin: panelHeight
59 left: parent.left
61 left: parent.left
60 right: parent.right
62 right: parent.right
61− top: nonIndicatorArea.bottom
62 bottom: parent.bottom
63 bottom: parent.bottom
63 }
64 }
64 color: "black"
65 color: "black"
@@ -71,60 +72,11 @@ Item {
71 }
72 }
72 }
73 }
73
74
74− PanelBackground {
75− anchors.fill: nonIndicatorArea
76− }
77−
78− Item {
79− id: nonIndicatorArea
80− objectName: "indicatorArea"
81−
82− anchors {
83− top: callHint.bottom
84− left: parent.left
85− right: parent.right
86− }
87− height: d.indicatorHeight
88−
89− PanelSeparatorLine {
90− id: leftSeparatorLine
91− anchors {
92− bottom: parent.bottom
93− left: parent.left
94− right: parent.right
95− }
96− saturation: 1 - indicators.unitProgress
97− }
98−
99− MouseArea {
100− id: nonIndicatorMouseArea
101− enabled: callHint.active
102− anchors {
103− top: parent.top
104− left: parent.left
105− right: parent.right
106− }
107− height: indicators.panelHeight/2
108− onClicked: callHint.activate();
109− }
110− }
111−
112− // eater
113− MouseArea {
114− anchors.fill: callHint
115− onClicked: callHint.activate()
116− }
117−
118 Item {
75 Item {
119 id: indicatorArea
76 id: indicatorArea
120 objectName: "indicatorArea"
77 objectName: "indicatorArea"
121
78
122− anchors {
79+ anchors.fill: parent
123− top: callHint.bottom
124− right: parent.right
125− bottom: parent.bottom
126− }
127− width: indicators.width
128
80
129 Behavior on anchors.topMargin { StandardAnimation {} }
81 Behavior on anchors.topMargin { StandardAnimation {} }
130
82
@@ -146,15 +98,34 @@ Item {
146 bottom: indicators.bottom
98 bottom: indicators.bottom
147 right: indicators.left
99 right: indicators.left
148
100
149− topMargin: nonIndicatorArea.anchors.topMargin + indicators.panelHeight
101+ topMargin: indicatorArea.anchors.topMargin + indicators.panelHeight
150 }
102 }
151
103
152 width: units.dp(2)
104 width: units.dp(2)
153 source: "graphics/VerticalDivider.png"
105 source: "graphics/VerticalDivider.png"
154 }
106 }
155
107
156− PanelBackground {
108+ Rectangle {
109+ id: indicatorAreaBackground
110+ color: callHint.visible ? "green" : "black"
111+ anchors {
112+ top: parent.top
113+ left: parent.left
114+ right: parent.right
115+ }
116+ height: indicators.panelHeight
117+
118+ Behavior on color { ColorAnimation { duration: UbuntuAnimation.FastDuration } }
119+ }
120+
121+ PanelSeparatorLine {
122+ id: nonIndicatorAreaSeparatorLine
157− anchors.fill: indicators
123+ anchors {
124+ top: indicatorAreaBackground.bottom
125+ left: parent.left
126+ right: indicators.left
127+ }
128+ saturation: 1 - indicators.unitProgress
158 }
129 }
159
130
160 Indicators {
131 Indicators {
@@ -169,91 +140,80 @@ Item {
169 width: (root.width > units.gu(60)) ? units.gu(40) : root.width
140 width: (root.width > units.gu(60)) ? units.gu(40) : root.width
170 shown: false
141 shown: false
171 panelHeight: units.gu(3)
142 panelHeight: units.gu(3)
172− openedHeight: root.height - (callHint.y + callHint.height)
143+ openedHeight: root.height
144+ overFlowWidth: {
145+ if (callHint.visible) {
146+ return Math.max(root.width - (callHint.width + units.gu(2)), 0)
147+ }
173− overFlowWidth: search.state=="hidden" ? root.width : root.width - search.width
148+ return search.state=="hidden" ? root.width : root.width - search.width
149+ }
174
150
175 enableHint: !callHint.active && !fullscreenMode
151 enableHint: !callHint.active && !fullscreenMode
176 showHintBottomMargin: fullscreenMode ? -panelHeight : 0
152 showHintBottomMargin: fullscreenMode ? -panelHeight : 0
177− showHintHeightOffset: callHint.active ? callHint.height : 0
178
153
179 onShowTapped: {
154 onShowTapped: {
180 if (callHint.active) {
155 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
156+ callHint.activate();
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) {
189− callHint.activate();
190− }
191 }
157 }
192 }
158 }
193 }
159 }
194
160
195− PanelSeparatorLine {
196− id: indicatorsSeparatorLine
197− visible: true
198− anchors {
199− top: indicators.bottom
200− left: indicatorDividor.left
201− right: indicators.right
202− }
203− }
204− }
205−
206− SearchIndicator {
161+ SearchIndicator {
207− id: search
162+ id: search
208− objectName: "search"
163+ objectName: "search"
209− enabled: root.searchVisible
164+ enabled: root.searchVisible
210
165
211− state: {
166+ state: {
167+ if (callHint.visible) {
168+ return "hidden"
169+ }
212− if (parent.width < indicators.width + width) {
170+ if (parent.width < indicators.width + width) {
213− if (indicators.state != "initial") {
171+ if (indicators.state != "initial") {
172+ return "hidden";
173+ }
174+ }
175+ if (root.searchVisible && !indicators.showAll) {
214− return "hidden";
176+ return "visible";
215 }
177 }
178+ return "hidden";
216 }
179 }
217− if (root.searchVisible && !indicators.showAll) {
180+ anchors {
218− return "visible";
181+ top: parent.top
182+ left: parent.left
219 }
183 }
220− return "hidden";
184+ height: indicators.panelHeight
221− }
222
185
223− anchors {
186+ mouseArea {
224− top: nonIndicatorArea.top
187+ onClicked: root.searchClicked()
225− bottom: nonIndicatorArea.bottom
188+ }
226− left: nonIndicatorArea.left
227 }
189 }
228
190
229− mouseArea {
191+ ActiveCallHint {
230− onClicked: root.searchClicked()
192+ id: __callHint
193+ anchors {
194+ top: parent.top
195+ left: parent.left
231− }
196+ }
232− }
197+ height: indicators.panelHeight
198+ visible: active && indicators.state == "initial"
233
199
234− ActiveCallHint {
200+ Component.onCompleted: console.log("callHint " + width)
235− id: __callHint
236− anchors {
237− left: parent.left
238− right: parent.right
239 }
201 }
240− height: units.gu(3)
241− y: -height
242
202
243− states: [
203+ PanelSeparatorLine {
244− State {
204+ id: indicatorsSeparatorLine
245− name: "active"
205+ visible: true
246− when: callHint.active
206+ anchors {
247− PropertyChanges { target: callHint; y: 0 }
207+ top: indicators.bottom
248− PropertyChanges { target: search.mouseArea; anchors.topMargin: -callHint.height/3 }
208+ left: indicatorDividor.left
209+ right: indicators.right
249 }
210 }
250− ]
211+ }
251− Behavior on y { StandardAnimation {} }
252 }
212 }
253
213
254 QtObject {
214 QtObject {
255 id: d
215 id: d
256− readonly property real indicatorHeight: indicators.panelHeight + leftSeparatorLine.height
216+ readonly property real indicatorHeight: indicators.panelHeight + indicatorsSeparatorLine.height
257 }
217 }
258
218
259 states: [
219 states: [
@@ -264,33 +224,7 @@ Item {
264 State {
224 State {
265 name: "offscreen" //pushed off screen
225 name: "offscreen" //pushed off screen
266 when: fullscreenMode
226 when: fullscreenMode
267− PropertyChanges { target: nonIndicatorArea; anchors.topMargin: -d.indicatorHeight }
268 PropertyChanges { target: indicatorArea; anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 }
227 PropertyChanges { target: indicatorArea; anchors.topMargin: indicators.state === "initial" ? -d.indicatorHeight : 0 }
269 }
228 }
270 ]
229 ]
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− }
294− }
295− ]
296}
230}