on xenial help sign in
Visual updates for indicator panel highlight and opening opacity.
04de85dNick Dedekind
qml/Panel/IndicatorItem.qml−13
@@ -23,7 +23,6 @@ Item {
23 id: indicatorItem
23 id: indicatorItem
24
24
25 property alias widgetSource: loader.source
25 property alias widgetSource: loader.source
26− property bool highlighted: false
27 property bool dimmed: false
26 property bool dimmed: false
28 property var indicatorProperties: undefined
27 property var indicatorProperties: undefined
29 property bool indicatorVisible: loader.item ? loader.item.enabled : false
28 property bool indicatorVisible: loader.item ? loader.item.enabled : false
@@ -46,16 +45,4 @@ Item {
46 }
45 }
47 }
46 }
48 }
47 }
49−
50− Rectangle {
51− color: Theme.palette.selected.foreground
52− objectName: "highlight"
53− height: units.dp(2)
54− width: parent.width
55− anchors.top: parent.bottom
56− visible: highlighted
57−
58− opacity: highlighted ? 1 : 0
59− Behavior on opacity { StandardAnimation {} }
60− }
61}
48}
qml/Panel/IndicatorRow.qml+39−8
@@ -29,6 +29,8 @@ Item {
29 property var visibleIndicators: defined
29 property var visibleIndicators: defined
30 property int overFlowWidth: width
30 property int overFlowWidth: width
31 property bool showAll: false
31 property bool showAll: false
32+ property real currentItemOffset: 0.0
33+ property real unitProgress: 0.0
32
34
33 width: units.gu(40)
35 width: units.gu(40)
34 height: units.gu(3)
36 height: units.gu(3)
@@ -79,23 +81,23 @@ Item {
79 height: indicatorRow.height
81 height: indicatorRow.height
80 width: indicatorItem.width
82 width: indicatorItem.width
81 visible: indicatorItem.indicatorVisible
83 visible: indicatorItem.indicatorVisible
82− opacity: 1.0
84+ opacity: 1.0 * opacityMultiplier
83 y: 0
85 y: 0
84 state: "standard"
86 state: "standard"
85
87
86 property int ownIndex: index
88 property int ownIndex: index
87− property alias highlighted: indicatorItem.highlighted
89+ property bool highlighted: indicatorRow.state != "initial" ? ownIndex == indicatorRow.currentItemIndex : false
88− property alias dimmed: indicatorItem.dimmed
90+ property bool dimmed: indicatorRow.state != "initial" ? ownIndex != indicatorRow.currentItemIndex : false
89
91
90− property bool hidden: !showAll && !indicatorItem.highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
92+ property bool hidden: !showAll && !highlighted && (indicatorRow.state == "locked" || indicatorRow.state == "commit")
91 property bool overflow: row.width - itemWrapper.x > overFlowWidth
93 property bool overflow: row.width - itemWrapper.x > overFlowWidth
94+ property real opacityMultiplier: highlighted ? 1 : (1 - indicatorRow.unitProgress)
92
95
93 IndicatorItem {
96 IndicatorItem {
94 id: indicatorItem
97 id: indicatorItem
95 height: parent.height
98 height: parent.height
96
99
97− highlighted: indicatorRow.state != "initial" ? itemWrapper.ownIndex == indicatorRow.currentItemIndex : false
100+ dimmed: itemWrapper.dimmed
98− dimmed: indicatorRow.state != "initial" ? itemWrapper.ownIndex != indicatorRow.currentItemIndex : false
99
101
100 widgetSource: model.widgetSource
102 widgetSource: model.widgetSource
101 indicatorProperties : model.indicatorProperties
103 indicatorProperties : model.indicatorProperties
@@ -135,14 +137,43 @@ Item {
135
137
136 transitions: [
138 transitions: [
137 Transition {
139 Transition {
138− StandardAnimation {
140+ UbuntuNumberAnimation {
139 target: itemWrapper
141 target: itemWrapper
140 property: "opacity"
142 property: "opacity"
141− duration: 300
143+ duration: UbuntuAnimation.BriskDuration
142 }
144 }
143 }
145 }
144 ]
146 ]
145 }
147 }
146 }
148 }
147 }
149 }
150+
151+ Rectangle {
152+ id: highlight
153+ color: Theme.palette.selected.foreground
154+ objectName: "highlight"
155+ height: units.dp(2)
156+ anchors.top: row.bottom
157+ visible: indicatorRow.currentItem != null
158+ x: row.x + (indicatorRow.currentItem != null ? indicatorRow.currentItem.x + centerOffset : 0)
159+ width: indicatorRow.currentItem != null ? indicatorRow.currentItem.width : 0
160+
161+ property real centerOffset: {
162+ if (indicatorRow.currentItemOffset > 0.1) {
163+ return (indicatorRow.currentItemOffset - 0.1) * units.gu(0.4);
164+ } else if (indicatorRow.currentItemOffset < -0.1) {
165+ return (indicatorRow.currentItemOffset + 0.1) * units.gu(0.4);
166+ }
167+ return 0.0;
168+ }
169+
170+ Behavior on width {
171+ enabled: unitProgress > 0;
172+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
173+ }
174+ Behavior on x {
175+ enabled: unitProgress > 0;
176+ UbuntuNumberAnimation { duration: UbuntuAnimation.FastDuration }
177+ }
178+ }
148}
179}
qml/Panel/Indicators.qml+22−11
@@ -39,6 +39,7 @@ Showable {
39 property bool contentEnabled: true
39 property bool contentEnabled: true
40 property bool initalizeItem: true
40 property bool initalizeItem: true
41 readonly property alias content: menuContent
41 readonly property alias content: menuContent
42+ property real unitProgress: 0.0
42
43
43 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
44 // TODO: Perhaps we need a animation standard for showing/hiding? Each showable seems to
44 // use its own values. Need to ask design about this.
45 // use its own values. Need to ask design about this.
@@ -128,23 +129,31 @@ Showable {
128 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
129 rowCoordinates = indicatorRow.mapToItem(indicatorRow.row, xValue, 0);
129 // get the current delegate
130 // get the current delegate
130 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
131 currentItem = indicatorRow.row.childAt(rowCoordinates.x, 0);
131− if (currentItem && currentItem != indicatorRow.currentItem ) {
132+ if (currentItem) {
132 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
133 itemCoordinates = indicatorRow.row.mapToItem(currentItem, rowCoordinates.x, 0);
133 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
134 distanceFromRightEdge = (currentItem.width - itemCoordinates.x) / (currentItem.width);
135+ if (currentItem != indicatorRow.currentItem) {
134− if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
136+ if (Math.abs(currentItem.ownIndex - indicatorRow.currentItemIndex) > 1) {
135− bufferExceeded = true;
136− } else {
137− if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
138− bufferExceeded = true;
139− } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
140 bufferExceeded = true;
137 bufferExceeded = true;
138+ } else {
139+ if (indicatorRow.currentItemIndex < currentItem.ownIndex && distanceFromRightEdge < (1 - effectiveBufferThreshold)) {
140+ bufferExceeded = true;
141+ } else if (indicatorRow.currentItemIndex > currentItem.ownIndex && distanceFromRightEdge > effectiveBufferThreshold) {
142+ bufferExceeded = true;
143+ }
141 }
144 }
145+ if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItemIndex < 0 || indicatorRow.currentItem == null) {
146+ indicatorRow.currentItem = currentItem;
147+ }
148+
149+ // need to re-init the distanceFromRightEdge for offset calculation
150+ itemCoordinates = indicatorRow.row.mapToItem(indicatorRow.currentItem, rowCoordinates.x, 0);
151+ distanceFromRightEdge = (indicatorRow.currentItem.width - itemCoordinates.x) / (indicatorRow.currentItem.width);
142 }
152 }
143− if ((!useBuffer || (useBuffer && bufferExceeded)) || indicatorRow.currentItem < 0 || indicatorRow.currentItem == null) {
153+ indicatorRow.currentItemOffset = 1 - (distanceFromRightEdge * 2);
144− indicatorRow.currentItem = currentItem;
154+ } else {
145− }
146− } else if (!currentItem) {
147 indicatorRow.setDefaultItem();
155 indicatorRow.setDefaultItem();
156+ indicatorRow.currentItemOffset = 0;
148 }
157 }
149 initalizeItem = indicatorRow.currentItem == null;
158 initalizeItem = indicatorRow.currentItem == null;
150 }
159 }
@@ -268,6 +277,7 @@ Showable {
268 height: indicators.panelHeight
277 height: indicators.panelHeight
269 indicatorsModel: indicatorsModel
278 indicatorsModel: indicatorsModel
270 state: indicators.state
279 state: indicators.state
280+ unitProgress: indicators.unitProgress
271
281
272 Connections {
282 Connections {
273 property bool enableIndexChangeSignal: true
283 property bool enableIndexChangeSignal: true
@@ -326,6 +336,7 @@ Showable {
326 if (hideAnimation.running) {
336 if (hideAnimation.running) {
327 indicators.state = "initial";
337 indicators.state = "initial";
328 initalizeItem = true;
338 initalizeItem = true;
339+ menuContent.animateNextMenuChange = false;
329 }
340 }
330 }
341 }
331 }
342 }
qml/Panel/MenuContent.qml+3−1
@@ -33,6 +33,7 @@ MainView {
33 property int contentReleaseInterval: 20000
33 property int contentReleaseInterval: 20000
34 property bool activeHeader: false
34 property bool activeHeader: false
35 property alias visibleIndicators: visibleIndicatorsModel.visible
35 property alias visibleIndicators: visibleIndicatorsModel.visible
36+ property bool animateNextMenuChange: false
36
37
37 width: units.gu(40)
38 width: units.gu(40)
38 height: units.gu(42)
39 height: units.gu(42)
@@ -41,11 +42,12 @@ MainView {
41 var filteredIndex = filteredIndicators.mapFromSource(index)
42 var filteredIndex = filteredIndicators.mapFromSource(index)
42
43
43 if (tabs.selectedTabIndex !== filteredIndex) {
44 if (tabs.selectedTabIndex !== filteredIndex) {
44− if (tabs.selectedTabIndex == -1) {
45+ if (tabs.selectedTabIndex == -1 || !animateNextMenuChange) {
45 tabs.tabBar.animate = false;
46 tabs.tabBar.animate = false;
46 }
47 }
47 tabs.selectedTabIndex = filteredIndex;
48 tabs.selectedTabIndex = filteredIndex;
48 tabs.tabBar.animate = true;
49 tabs.tabBar.animate = true;
50+ animateNextMenuChange = true;
49 }
51 }
50 }
52 }
51
53
qml/Panel/Panel.qml+1−1
@@ -107,7 +107,7 @@ Item {
107 pinnedMode: !fullscreenMode
107 pinnedMode: !fullscreenMode
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
108 overFlowWidth: search.state=="hidden" ? parent.width : parent.width - search.width
109
109
110− property real unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
110+ unitProgress: (height - panelHeight) / (openedHeight - panelHeight)
111 }
111 }
112
112
113 PanelSeparatorLine {
113 PanelSeparatorLine {
tests/qmltests/Panel/tst_IndicatorItem.qml−11
@@ -41,17 +41,6 @@ Rectangle {
41 tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true);
41 tryCompareFunction(function(){return indicatorItem.opacity < 1.0}, true);
42 }
42 }
43
43
44− function test_highlight() {
45− var itemHighlight = findChild(indicatorItem, "highlight");
46− verify(itemHighlight != undefined);
47−
48− indicatorItem.highlighted = true;
49− compare(itemHighlight.visible, true, "Indicator should be highlighted");
50−
51− indicatorItem.highlighted = false;
52− compare(itemHighlight.visible, false, "Indicator should not be highlighted");
53− }
54−
55 function test_empty() {
44 function test_empty() {
56 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
45 compare(indicatorItem.indicatorVisible, false, "IndicatorItem should not be visible.");
57 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
46 indicatorItem.widgetSource = "qrc:/tests/indciators/qml/fake_menu_widget1.qml";
tests/qmltests/Panel/tst_IndicatorRow.qml+18−4
@@ -34,6 +34,7 @@ Item {
34 {
34 {
35 indicatorRow.state = "initial";
35 indicatorRow.state = "initial";
36 indicatorRow.currentItem = null;
36 indicatorRow.currentItem = null;
37+ indicatorRow.unitProgress = 0.0;
37 }
38 }
38
39
39 PanelBackground {
40 PanelBackground {
@@ -83,14 +84,13 @@ Item {
83 function test_current_item_commit() {
84 function test_current_item_commit() {
84 init_test();
85 init_test();
85
86
86− indicatorRow.setCurrentItem(1);
87+ indicatorRow.setCurrentItem(2);
87 indicatorRow.state = "commit";
88 indicatorRow.state = "commit";
88 tryCompare(get_indicator_item_at(0), "opacity", 0.0);
89 tryCompare(get_indicator_item_at(0), "opacity", 0.0);
89− tryCompare(get_indicator_item_at(1), "opacity", 1.0);
90+ tryCompare(get_indicator_item_at(1), "opacity", 0.0);
90− tryCompare(get_indicator_item_at(2), "opacity", 0.0);
91+ tryCompare(get_indicator_item_at(2), "opacity", 1.0);
91 tryCompare(get_indicator_item_at(3), "opacity", 0.0);
92 tryCompare(get_indicator_item_at(3), "opacity", 0.0);
92 tryCompare(get_indicator_item_at(4), "opacity", 0.0);
93 tryCompare(get_indicator_item_at(4), "opacity", 0.0);
93−
94 }
94 }
95 }
95 }
96
96
@@ -166,6 +166,20 @@ Item {
166 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
166 compare(get_indicator_item_at(3).highlighted, false, "Other indicators should not highlight when in locked state");
167 compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
167 compare(get_indicator_item_at(4).highlighted, false, "Other indicators should not highlight when in locked state");
168 }
168 }
169+
170+ function test_opacity() {
171+ init_test();
172+
173+ indicatorRow.state = "reveal";
174+ indicatorRow.unitProgress = 0.5;
175+ indicatorRow.setCurrentItem(2);
176+
177+ compare(get_indicator_item_at(0).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
178+ compare(get_indicator_item_at(1).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
179+ compare(get_indicator_item_at(2).opacity, 1.0, "Current indicator should not change in response to panel progress");
180+ compare(get_indicator_item_at(3).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
181+ compare(get_indicator_item_at(4).opacity, 0.5, "Other indicator opacity should change in response to panel progress");
182+ }
169 }
183 }
170
184
171 UT.UnityTestCase {
185 UT.UnityTestCase {