on xenial help sign in
replaced old listview indicator menus with tab menus. Fixed tests
ca7aa6dNick Dedekind
Panel/Indicators.qml+1−1
@@ -165,7 +165,7 @@ Showable {
165 source: "graphics/VerticalDivider.png"
165 source: "graphics/VerticalDivider.png"
166 }
166 }
167
167
168− MenuContentTabs {
168+ MenuContent {
169 id: menuContent
169 id: menuContent
170 objectName: "menuContent"
170 objectName: "menuContent"
171
171
Panel/MenuContent.qml+71−97
@@ -19,22 +19,26 @@ import Ubuntu.Components 0.1
19import Unity.Indicators 0.1 as Indicators
19import Unity.Indicators 0.1 as Indicators
20import "../Components"
20import "../Components"
21
21
22−Rectangle {
22+MainView {
23 id: content
23 id: content
24
24
25 property QtObject indicatorsModel: null
25 property QtObject indicatorsModel: null
26 property bool __contentActive: false
26 property bool __contentActive: false
27− readonly property int currentMenuIndex : menus.currentIndex
27+ readonly property int currentMenuIndex : tabs.selectedTabIndex
28− property color backgroundColor: "#221e1c" // FIXME not in palette yet
28+ backgroundColor: "#221e1c" // FIXME not in palette yet
29 property int contentReleaseInterval: 20000
29 property int contentReleaseInterval: 20000
30+ property bool activeHeader: false
30
31
31 width: units.gu(40)
32 width: units.gu(40)
32 height: units.gu(42)
33 height: units.gu(42)
33− color: backgroundColor
34
34
35 function setCurrentMenuIndex(index) {
35 function setCurrentMenuIndex(index) {
36 if (currentMenuIndex !== index) {
36 if (currentMenuIndex !== index) {
37− menus.currentIndex = index;
37+ if (currentMenuIndex == -1) {
38+ tabs.tabBar.animate = false;
39+ }
40+ tabs.selectedTabIndex = index;
41+ tabs.tabBar.animate = true;
38 }
42 }
39 }
43 }
40
44
@@ -44,95 +48,75 @@ Rectangle {
44 }
48 }
45
49
46 function releaseContent() {
50 function releaseContent() {
47− if (__contentActive)
51+ if (__contentActive) {
48 contentReleaseTimer.restart();
52 contentReleaseTimer.restart();
53+ }
49 }
54 }
50
55
51− ListView {
56+ onActiveHeaderChanged: {
52− id: menus
57+ tabs.tabBar.selectionMode = activeHeader;
53− objectName: "menus"
58+ tabs.tabBar.alwaysSelectionMode = activeHeader;
54−
55− anchors.bottom: parent.bottom
56− anchors.top: header.bottom
57− width: parent.width
58−
59− spacing: units.gu(0.5)
60− enabled: opacity != 0
61− orientation: ListView.Horizontal
62− model: indicatorsModel
63− interactive: false
64− //FIXME: This will make sure that all plugins still alive
65− //check bug https://bugs.launchpad.net/manhattan/+bug/1088945 for more details
66− cacheBuffer: 2147483647
67−
68− delegate: Loader {
69− clip: true
70− property bool contentActive: content.__contentActive && menuActivator.content[index].active
71−
72− onContentActiveChanged: {
73− if (contentActive && item) {
74− item.start();
75− } else if (!contentActive && item) {
76− item.stop();
77− }
78− }
59+ }
79
60
80− width: menus.width
61+ Tabs {
81− height: menus.height
62+ id: tabs
82− source: pageSource
63+ objectName: "tabs"
83− onVisibleChanged: {
64+ anchors.fill: parent
84− // Reset the indicator states
65+ selectedTabIndex: -1
85− if (!visible && item && item["reset"]) {
66+
86− item.reset();
67+ Repeater {
87− }
68+ id: repeater
69+ model: indicatorsModel
70+ objectName: "menus"
71+
72+ // FIXME: This is needed because tabs dont handle repeaters well.
73+ // Due to the child ordering happening after child insertion.
74+ // QTBUG-32438
75+ onItemAdded: {
76+ parent.childrenChanged();
88 }
77 }
89− asynchronous: true
90
78
79+ Tab {
80+ id: tab
81+ objectName: indicatorsModel.data(index, Indicators.IndicatorsModelRole.Identifier)
82+ title: indicatorsModel.data(index, Indicators.IndicatorsModelRole.Title)
83+
84+ page: Page {
85+ Loader {
86+ clip: true
87+ anchors.fill: parent
88+ source: pageSource
89+ asynchronous: true
90+
91+ property bool contentActive: content.__contentActive
92+
93+ onContentActiveChanged: {
94+ if (contentActive && item) {
95+ item.start()
96+ } else if (!contentActive && item) {
97+ item.stop()
98+ }
99+ }
100+
101+ onVisibleChanged: {
102+ // Reset the indicator states
103+ if (!visible && item && item["reset"]) {
104+ item.reset()
105+ }
106+ }
107+
91− onLoaded: {
108+ onLoaded: {
92− for(var pName in indicatorProperties) {
109+ for(var pName in indicatorProperties) {
93− if (item.hasOwnProperty(pName)) {
110+ if (item.hasOwnProperty(pName)) {
94− item[pName] = indicatorProperties[pName];
111+ item[pName] = indicatorProperties[pName]
112+ }
113+ }
114+ if (contentActive && menus.visible) {
115+ item.start()
116+ }
117+ }
95 }
118 }
96 }
119 }
97− if (contentActive && menus.visible) {
98− item.start();
99− }
100− }
101−
102− // Need to use a binding because the handle height changes.
103− // FIXME: Dont know why we're using handle height (introduces dep).. Check with design about bottom margin
104− Binding {
105− target: item
106− property: "anchors.bottomMargin"
107− value: handle.height
108− }
109− }
110− }
111−
112− Rectangle {
113− id: header
114− objectName: "header"
115−
116− property alias title: pageHeader.text
117−
118− color: backgroundColor
119− opacity: pageHeader.opacity
120− anchors {
121− left: parent.left
122− right: parent.right
123− }
124− height: childrenRect.height
125−
126− PageHeader {
127− id: pageHeader
128− anchors {
129− left: parent.left
130− right: parent.right
131− }
132− text: {
133− if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
134− return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
135− return "";
136 }
120 }
137 }
121 }
138 }
122 }
@@ -141,16 +125,6 @@ Rectangle {
141 id: contentReleaseTimer
125 id: contentReleaseTimer
142
126
143 interval: contentReleaseInterval
127 interval: contentReleaseInterval
144− onTriggered: {
145− __contentActive = false;
128+ onTriggered: content.__contentActive = false
146− menuActivator.clear();
147− }
148− }
149−
150− Indicators.MenuContentActivator {
151− id: menuActivator
152− running: content.__contentActive
153− baseIndex: content.currentMenuIndex
154− count: indicatorsModel.count
155 }
129 }
156}
130}
Panel/MenuContentTabs.qmldeleted−132
@@ -1,132 +0,0 @@
1−/*
2− * Copyright (C) 2013 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.Components 0.1
19−import Unity.Indicators 0.1 as Indicators
20−import "../Components"
21−
22−MainView {
23− id: content
24−
25− property QtObject indicatorsModel: null
26− readonly property int currentMenuIndex : tabs.selectedTabIndex
27− backgroundColor: "#221e1c" // FIXME not in palette yet
28− property int contentReleaseInterval: 20000
29− property bool activeHeader: false
30−
31− width: units.gu(40)
32− height: units.gu(42)
33−
34− QtObject {
35− id: d
36− property bool contentActive: false
37− }
38−
39− function setCurrentMenuIndex(index) {
40− if (currentMenuIndex !== index) {
41− if (currentMenuIndex == -1) {
42− tabs.tabBar.animate = false;
43− }
44− tabs.selectedTabIndex = index;
45− tabs.tabBar.animate = true;
46− }
47− }
48−
49− function activateContent() {
50− contentReleaseTimer.stop();
51− d.contentActive = true;
52− }
53−
54− function releaseContent() {
55− if (d.contentActive) {
56− contentReleaseTimer.restart();
57− }
58− }
59−
60− onActiveHeaderChanged: {
61− tabs.tabBar.selectionMode = activeHeader;
62− tabs.tabBar.alwaysSelectionMode = activeHeader;
63− }
64−
65− Tabs {
66− id: tabs
67− anchors.fill: parent
68− selectedTabIndex: -1
69−
70− Repeater {
71− id: repeater
72− model: indicatorsModel
73− objectName: "menus"
74−
75− // FIXME: This is needed because tabs dont handle repeaters well.
76− // Due to the child ordering happening after child insertion.
77− // QTBUG-32438
78− onItemAdded: {
79− parent.childrenChanged();
80− }
81−
82− Tab {
83− id: tab
84− title: indicatorsModel ? indicatorsModel.data(index, Indicators.IndicatorsModelRole.Title) : ""
85−
86− page: Page {
87− Loader {
88− clip: true
89− anchors.fill: parent
90− source: pageSource
91− asynchronous: true
92−
93− property bool contentActive: d.contentActive
94−
95− onContentActiveChanged: {
96− if (contentActive && item) {
97− item.start()
98− } else if (!contentActive && item) {
99− item.stop()
100− }
101− }
102−
103− onVisibleChanged: {
104− // Reset the indicator states
105− if (!visible && item && item["reset"]) {
106− item.reset()
107− }
108− }
109−
110− onLoaded: {
111− for(var pName in indicatorProperties) {
112− if (item.hasOwnProperty(pName)) {
113− item[pName] = indicatorProperties[pName]
114− }
115− }
116− if (contentActive && menus.visible) {
117− item.start()
118− }
119− }
120− }
121− }
122− }
123− }
124− }
125−
126− Timer {
127− id: contentReleaseTimer
128−
129− interval: contentReleaseInterval
130− onTriggered: d.contentActive = false
131− }
132−}
tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1
@@ -64,7 +64,7 @@ ListModel {
64 isValid: "";
64 isValid: "";
65 }
65 }
66 ListElement {
66 ListElement {
67− identifier: "indicator-fake4";
67+ identifier: "indicator-fake5";
68 priority: 4
68 priority: 4
69 title: "Menu5";
69 title: "Menu5";
70 description: "";
70 description: "";
tests/qmltests/Panel/tst_MenuContent.qml+32−47
@@ -85,29 +85,29 @@ Item {
85
85
86 function activate_content(index)
86 function activate_content(index)
87 {
87 {
88− menuContent.currentMenuIndex = index
88+ menuContent.setCurrentMenuIndex(index)
89 }
89 }
90
90
91 function get_test_menu_objecName(index) {
91 function get_test_menu_objecName(index) {
92 return "menu_page"+(index+1);
92 return "menu_page"+(index+1);
93 }
93 }
94
94
95− property string test_menu_objectName : ""
95+ property string testTabObjectName : ""
96− function current_menu_equals_test_menu() {
96+
97+ function selected_tab_equals_test_tab() {
97− var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
98+ var currentTab = menu_content_test.findChild(menuContent, "tabs").selectedTab
98− if (current_loader == undefined) {
99+ if (currentTab == undefined) {
99− console.log("current_loader 'menus' undefined");
100+ console.log("selected tab undefined");
100 return false;
101 return false;
101 }
102 }
102
103
103− var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
104+ var testTab = menu_content_test.findChild(menuContent, testTabObjectName);
104− if (menu == undefined) {
105+ if (testTab == undefined) {
105− console.log("test_menu " + test_menu_objectName + " undefined");
106+ console.log("test_tab " + testTabObjectName + " undefined");
106 return false;
107 return false;
107 }
108 }
108
109
109− // The parent of the menu will be the loader
110+ return testTab == currentTab;
110− return menu.parent == current_loader;
111 }
111 }
112
112
113 UT.UnityTestCase {
113 UT.UnityTestCase {
@@ -123,81 +123,66 @@ Item {
123
123
124 // Check that the correct menus are displayed for the requested item.
124 // Check that the correct menus are displayed for the requested item.
125 function test_show_menu() {
125 function test_show_menu() {
126− var menu_count = indicatorsModel.count;
126+ var menuCount = indicatorsModel.count;
127− verify(menu_count > 0, "Menu count should be greater than zero");
127+ verify(menuCount > 0, "Menu count should be greater than zero");
128
128
129− var menus = menu_content_test.findChild(menuContent, "menus")
129+ var tabs = menu_content_test.findChild(menuContent, "tabs")
130
130
131 // Loop over twice to test jump between last and first.
131 // Loop over twice to test jump between last and first.
132− for (var i = 0; i < menu_count*2; i++) {
132+ for (var i = 0; i < menuCount*2; i++) {
133
133
134− var menu_index = i%menu_count;
134+ var menuIndex = i%menuCount;
135
135
136− activate_content(menu_index);
136+ activate_content(menuIndex);
137− test_menu_objectName = get_test_menu_objecName(menu_index);
137+ testTabObjectName = indicatorsModel.data(menuIndex, Indicators.IndicatorsModelRole.Identifier);
138− compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
138+ compare(tabs.selectedTabIndex, menuIndex, "Current tab index does not match selected tab index");
139− tryCompareFunction(current_menu_equals_test_menu, true);
139+ tryCompareFunction(selected_tab_equals_test_tab, true);
140 }
140 }
141 }
141 }
142
142
143 // Calling activateContent should call start on all menus
143 // Calling activateContent should call start on all menus
144 function test_activate_content() {
144 function test_activate_content() {
145− var menu_count = indicatorsModel.count;
145+ var menuCount = indicatorsModel.count;
146− verify(menu_count > 0, "Menu count should be greater than zero");
146+ verify(menuCount > 0, "Menu count should be greater than zero");
147
147
148 // Ensure all the menus are stopped first
148 // Ensure all the menus are stopped first
149 menuContent.__contentActive = false;
149 menuContent.__contentActive = false;
150− for (var i = 0; i < menu_count; i++) {
150+ for (var i = 0; i < menuCount; i++) {
151 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
151 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
152 }
152 }
153
153
154 // activate content the content to call stop.
154 // activate content the content to call stop.
155 menuContent.activateContent();
155 menuContent.activateContent();
156− for (var i = 0; i < menu_count; i++) {
156+ for (var i = 0; i < menuCount; i++) {
157 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
157 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
158 }
158 }
159 }
159 }
160
160
161 // Calling activateContent should call stop on all menus.
161 // Calling activateContent should call stop on all menus.
162 function test_release_content() {
162 function test_release_content() {
163− var menu_count = indicatorsModel.count;
163+ var menuCount = indicatorsModel.count;
164− verify(menu_count > 0, "Menu count should be greater than zero");
164+ verify(menuCount > 0, "Menu count should be greater than zero");
165
165
166 // Ensure all the menus are started first
166 // Ensure all the menus are started first
167 menuContent.__contentActive = true;
167 menuContent.__contentActive = true;
168− for (var i = 0; i < menu_count; i++) {
168+ for (var i = 0; i < menuCount; i++) {
169 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
169 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
170 }
170 }
171 // release the content to call stop.
171 // release the content to call stop.
172 menuContent.releaseContent();
172 menuContent.releaseContent();
173− for (var i = 0; i < menu_count; i++) {
173+ for (var i = 0; i < menuCount; i++) {
174 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
174 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
175 }
175 }
176 }
176 }
177
177
178− // Header title should be the same as the item
179− function test_menu_header() {
180− var menu_count = indicatorsModel.count;
181− verify(menu_count > 0, "Menu count should be greater than zero");
182−
183− var header = findChild(menuContent, "header")
184−
185− for (var i = 0; i < menu_count; i++) {
186− activate_content(i);
187−
188− var menu_title = indicatorsModel.get(i).title;
189− compare(header.title, menu_title, "Header doesnt match menu title for menu " + i);
190− }
191− }
192−
193 // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly.
178 // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly.
194 function test_multi_activate() {
179 function test_multi_activate() {
195− var menu_count = indicatorsModel.count;
180+ var menuCount = indicatorsModel.count;
196− verify(menu_count > 0, "Menu count should be greater than zero");
181+ verify(menuCount > 0, "Menu count should be greater than zero");
197
182
198 for (var i = 0; i < 100; i++) {
183 for (var i = 0; i < 100; i++) {
199− activate_content(i % menu_count);
184+ activate_content(i % menuCount);
200− compare(menuContent.currentMenuIndex, i%menu_count);
185+ compare(menuContent.currentMenuIndex, i%menuCount);
201 }
186 }
202 wait(100);
187 wait(100);
203 }
188 }