on xenial help sign in
Use PathView for label cycling
cad0962Nick Dedekind
qml/Panel/ActiveCallHint.qml+128−49
@@ -24,6 +24,8 @@ Rectangle {
24 id: callHint
24 id: callHint
25
25
26 readonly property bool active: callManager.hasCalls && ApplicationManager.focusedApplicationId !== "dialer-app"
26 readonly property bool active: callManager.hasCalls && ApplicationManager.focusedApplicationId !== "dialer-app"
27+ readonly property QtObject contactWatcher: _contactWatcher
28+ property int alternateLabelInterval: 4000
27
29
28 Component.onCompleted: {
30 Component.onCompleted: {
29 telepathyHelper.registerChannelObserver("unity8");
31 telepathyHelper.registerChannelObserver("unity8");
@@ -39,51 +41,147 @@ Rectangle {
39 }
41 }
40 }
42 }
41
43
42− Column {
44+ Component {
43− id: column
45+ id: contactColumnRow
44
46
45− anchors {
47+ Column {
46− left: parent.left
48+ id: column
47− leftMargin:units.gu(1)
49+ objectName: "contactColumn"
48− right: time.left
49− }
50− y: 0
51− Behavior on y { StandardAnimation { duration: 400 } }
52
50
53− Label {
54− id: label1
55 anchors {
51 anchors {
56 left: parent.left
52 left: parent.left
57 right: parent.right
53 right: parent.right
58 }
54 }
59− height: callHint.height
55+ height: childrenRect.height
60− verticalAlignment: Text.AlignVCenter
56+
61−
57+ Component.onCompleted: {
62− text: {
58+ if (index === 0) {
63− if (!d.activeCall) {
59+ labelPathView.column1 = column;
64− return "";
65− } else if (d.activeCall.isConference) {
66− return i18n.tr("Conference");
67 } else {
60 } else {
61+ labelPathView.column2 = column;
62+ }
63+ }
64+
65+ Label {
66+ id: contactLabel
67+ objectName: "contactLabel"
68+
69+ anchors {
70+ left: parent.left
71+ right: parent.right
72+ }
73+ height: callHint.height
74+ verticalAlignment: Text.AlignVCenter
75+
76+ text: {
77+ if (!d.activeCall) {
78+ return "";
79+ } else if (d.activeCall.isConference) {
80+ return i18n.tr("Conference");
81+ } else {
68− return contactWatcher.alias !== "" ? contactWatcher.alias : contactWatcher.phoneNumber;
82+ return contactWatcher.alias !== "" ? contactWatcher.alias : contactWatcher.phoneNumber;
83+ }
84+ }
85+ }
86+
87+ Label {
88+ id: returnLabel
89+
90+ anchors {
91+ left: parent.left
92+ right: parent.right
69 }
93 }
94+ height: callHint.height
95+ verticalAlignment: Text.AlignVCenter
96+ text: i18n.tr("Tap to return to call...");
70 }
97 }
71 }
98 }
99+ }
100+
101+ PathView {
102+ id: labelPathView
103+ objectName: "labelPathView"
104+
105+ anchors {
106+ top: parent.top
107+ left: parent.left
108+ leftMargin:units.gu(1)
109+ right: time.left
110+ }
111+ height: columnHeight > callHint.height ? callHint.height : columnHeight
72
112
73− Label {
113+ property Column column1
74− id: label2
114+ property Column column2
75− anchors {
115+ property int columnHeight: column1 ? column1.height : 0
76− left: parent.left
116+
77− right: parent.right
117+ delegate: contactColumnRow
118+
119+ model: 2
120+ offset: 0
121+
122+ path: Path {
123+ startY: -labelPathView.columnHeight / 2
124+ PathLine {
125+ y: labelPathView.columnHeight * 1.5
126+ }
127+ }
128+
129+ property real actualOffset: 0
130+ property bool offsetGuard: false
131+ onActualOffsetChanged: {
132+ if (offsetGuard) { return; }
133+ offsetGuard = true;
134+
135+ offset = actualOffset;
136+ if (actualOffset === model) { actualOffset = 0.0; }
137+ offsetGuard = false;
138+ }
139+
140+ Behavior on offset {
141+ id: offsetBehaviour
142+ SmoothedAnimation {
143+ id: offsetAnimation
144+ // ensure we go faster than the label switch
145+ duration: alternateLabelInterval / 2
146+ velocity: 1.0
147+ easing.type: Easing.InOutQuad
78 }
148 }
79− height: callHint.height
149+ }
80− verticalAlignment: Text.AlignVCenter
150+ }
81− text: i18n.tr("Tap to return to call...");
151+
152+ // Fade in text
153+ Rectangle {
154+ anchors.fill: labelPathView
155+ gradient: Gradient {
156+ GradientStop { position: 0.0; color: Qt.rgba(callHint.color.r, callHint.color.g, callHint.color.b, 1.0) }
157+ GradientStop { position: 0.25; color: Qt.rgba(callHint.color.r, callHint.color.g, callHint.color.b, 0.0) }
158+ GradientStop { position: 0.75; color: Qt.rgba(callHint.color.r, callHint.color.g, callHint.color.b, 0.0) }
159+ GradientStop { position: 1.0; color: Qt.rgba(callHint.color.r, callHint.color.g, callHint.color.b, 1.0) }
160+ }
161+ }
162+
163+ Timer {
164+ running: callHint.active
165+ interval: alternateLabelInterval
166+ repeat: true
167+
168+ onRunningChanged: {
169+ if (running) {
170+ offsetBehaviour.enabled = false;
171+ labelPathView.actualOffset = 0;
172+ offsetBehaviour.enabled = true;
173+ }
174+ }
175+
176+ onTriggered: {
177+ labelPathView.actualOffset = labelPathView.actualOffset + 0.5;
82 }
178 }
83 }
179 }
84
180
85 Label {
181 Label {
86 id: time
182 id: time
183+ objectName: "timeLabel"
184+
87 anchors {
185 anchors {
88 right: parent.right
186 right: parent.right
89 rightMargin:units.gu(1)
187 rightMargin:units.gu(1)
@@ -106,30 +204,11 @@ Rectangle {
106 }
204 }
107
205
108 Telephony.ContactWatcher {
206 Telephony.ContactWatcher {
207+ id: _contactWatcher
109− id: contactWatcher
208+ objectName: "contactWatcher"
110 phoneNumber: d.activeCall ? d.activeCall.phoneNumber : ""
209 phoneNumber: d.activeCall ? d.activeCall.phoneNumber : ""
111 }
210 }
112
211
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 {
212 QtObject {
134 id: d
213 id: d
135
214