on xenial help sign in
Replaced indicator menu listView with tabs view.

Approved by PS Jenkins bot, Michał Sawicz.

commitbc86943c72d641397e4abda2076b54b47b2baba9 authorNick Dedekind <nicholas.dedekind@gmail.com> dateWed 14 Aug 2013, 10:44 (13 years ago) parente54fd97e82ecc9
5 files changed+129−162
Panel/Indicators.qml+3−6 Panel/Indicators/NetworkIndicatorPage.qml+15−11 Panel/MenuContent.qml+78−97 tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1 tests/qmltests/Panel/tst_MenuContent.qml+32−47
Panel/Indicators.qml+3−6
@@ -177,15 +177,12 @@ Showable {
177177 }
178178 indicatorsModel: indicatorsModel
179179 clip: !indicators.fullyOpened
180+ activeHeader: indicators.state == "hint" || indicators.state == "reveal"
180181
181182 Connections {
182183 target: indicatorRow
183− onCurrentItemIndexChanged: menuContent.updateCurrentMenu();
184− }
185−
186− function updateCurrentMenu() {
187− if (currentMenuIndex != indicatorRow.currentItemIndex) {
188− currentMenuIndex = indicatorRow.currentItemIndex;
184+ onCurrentItemIndexChanged: {
185+ menuContent.setCurrentMenuIndex(indicatorRow.currentItemIndex);
189186 }
190187 }
191188
Panel/Indicators/NetworkIndicatorPage.qml+15−11
@@ -23,23 +23,27 @@ import Unity.Indicators.Network 0.1 as ICNetwork
2323import Ubuntu.Components 0.1
2424
2525PageStack {
26− id: _network
26+ id: network
27+ // Stops the search for a parent tree node.
28+ // We don't want it going up to the indicator tabs.
29+ // FIXME: need a better way of doing this.
30+ // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211704
31+ __propagated: null
2732
2833 property alias title: _mainPage.title
29− property alias emptyText: _pluginItem.emptyText
30− property alias busType: _pluginItem.busType
31− property alias busName: _pluginItem.busName
32− property alias actionsObjectPath : _pluginItem.actionsObjectPath
33− property alias menuObjectPaths : _pluginItem.menuObjectPaths
34+ property alias emptyText: pluginItem.emptyText
35+ property alias busType: pluginItem.busType
36+ property alias busName: pluginItem.busName
37+ property alias actionsObjectPath : pluginItem.actionsObjectPath
38+ property alias menuObjectPaths : pluginItem.menuObjectPaths
3439
35− __showHeader: false
3640 anchors.fill: parent
3741
3842 Page {
3943 id: _mainPage
4044
4145 Indicators.IndicatorPage {
42− id: _pluginItem
46+ id: pluginItem
4347 anchors.fill: parent
4448 }
4549 }
@@ -63,17 +67,17 @@ PageStack {
6367 function start()
6468 {
6569 push(_mainPage);
66− _pluginItem.start();
70+ pluginItem.start();
6771 }
6872
6973 function stop()
7074 {
7175 clear();
72− _pluginItem.stop();
76+ pluginItem.stop();
7377 }
7478
7579 function reset()
7680 {
77− _pluginItem.reset();
81+ pluginItem.reset();
7882 }
7983}
Panel/MenuContent.qml+78−97
@@ -19,20 +19,31 @@ import Ubuntu.Components 0.1
1919import Unity.Indicators 0.1 as Indicators
2020import "../Components"
2121
22−Rectangle {
22+// FIXME : We dont want to use MainView.
23+// Need a regular Item which can have tabs with local header.
24+// https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1211704
25+MainView {
2326 id: content
2427
2528 property QtObject indicatorsModel: null
2629 property bool __contentActive: false
27− property alias currentMenuIndex : menus.currentIndex
28− property color backgroundColor: "#221e1c" // FIXME not in palette yet
30+ readonly property int currentMenuIndex : tabs.selectedTabIndex
31+ backgroundColor: "#221e1c" // FIXME not in palette yet
2932 property int contentReleaseInterval: 20000
33+ property bool activeHeader: false
3034
3135 width: units.gu(40)
3236 height: units.gu(42)
33− color: backgroundColor
3437
35− signal menuSelected(int index)
38+ function setCurrentMenuIndex(index) {
39+ if (currentMenuIndex !== index) {
40+ if (currentMenuIndex == -1) {
41+ tabs.tabBar.animate = false;
42+ }
43+ tabs.selectedTabIndex = index;
44+ tabs.tabBar.animate = true;
45+ }
46+ }
3647
3748 function activateContent() {
3849 contentReleaseTimer.stop();
@@ -40,95 +51,75 @@ Rectangle {
4051 }
4152
4253 function releaseContent() {
43− if (__contentActive)
54+ if (__contentActive) {
4455 contentReleaseTimer.restart();
56+ }
4557 }
4658
47− ListView {
48− id: menus
49− objectName: "menus"
50−
51− anchors.bottom: parent.bottom
52− anchors.top: header.bottom
53− width: parent.width
54−
55− spacing: units.gu(0.5)
56− enabled: opacity != 0
57− orientation: ListView.Horizontal
58− model: indicatorsModel
59− interactive: false
60− //FIXME: This will make sure that all plugins still alive
61− //check bug https://bugs.launchpad.net/manhattan/+bug/1088945 for more details
62− cacheBuffer: 2147483647
63−
64− delegate: Loader {
65− clip: true
66− property bool contentActive: content.__contentActive && menuActivator.content[index].active
67−
68− onContentActiveChanged: {
69− if (contentActive && item) {
70− item.start();
71− } else if (!contentActive && item) {
72− item.stop();
73− }
74− }
59+ onActiveHeaderChanged: {
60+ tabs.tabBar.selectionMode = activeHeader;
61+ tabs.tabBar.alwaysSelectionMode = activeHeader;
62+ }
7563
76− width: menus.width
77− height: menus.height
78− source: pageSource
79− onVisibleChanged: {
80− // Reset the indicator states
81− if (!visible && item && item["reset"]) {
82− item.reset();
83− }
64+ Tabs {
65+ id: tabs
66+ objectName: "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();
8480 }
85− asynchronous: true
8681
87− onLoaded: {
88− for(var pName in indicatorProperties) {
89− if (item.hasOwnProperty(pName)) {
90− item[pName] = indicatorProperties[pName];
82+ Tab {
83+ id: tab
84+ objectName: model.identifier
85+ title: model.title
86+
87+ page: Page {
88+ Loader {
89+ clip: true
90+ anchors.fill: parent
91+ source: pageSource
92+ asynchronous: true
93+
94+ property bool contentActive: content.__contentActive
95+
96+ onContentActiveChanged: {
97+ if (contentActive && item) {
98+ item.start()
99+ } else if (!contentActive && item) {
100+ item.stop()
101+ }
102+ }
103+
104+ onVisibleChanged: {
105+ // Reset the indicator states
106+ if (!visible && item && item["reset"]) {
107+ item.reset()
108+ }
109+ }
110+
111+ onLoaded: {
112+ for(var pName in indicatorProperties) {
113+ if (item.hasOwnProperty(pName)) {
114+ item[pName] = indicatorProperties[pName]
115+ }
116+ }
117+ if (contentActive && menus.visible) {
118+ item.start()
119+ }
120+ }
91121 }
92122 }
93− if (contentActive && menus.visible) {
94− item.start();
95− }
96− }
97−
98− // Need to use a binding because the handle height changes.
99− // FIXME: Dont know why we're using handle height (introduces dep).. Check with design about bottom margin
100− Binding {
101− target: item
102− property: "anchors.bottomMargin"
103− value: handle.height
104− }
105− }
106− }
107−
108− Rectangle {
109− id: header
110− objectName: "header"
111−
112− property alias title: pageHeader.text
113−
114− color: backgroundColor
115− opacity: pageHeader.opacity
116− anchors {
117− left: parent.left
118− right: parent.right
119− }
120− height: childrenRect.height
121−
122− PageHeader {
123− id: pageHeader
124− anchors {
125− left: parent.left
126− right: parent.right
127− }
128− text: {
129− if (indicatorsModel && menus.currentIndex >= 0 && menus.currentIndex < indicatorsModel.count)
130− return indicatorsModel.data(menus.currentIndex, Indicators.IndicatorsModelRole.Title);
131− return "";
132123 }
133124 }
134125 }
@@ -137,16 +128,6 @@ Rectangle {
137128 id: contentReleaseTimer
138129
139130 interval: contentReleaseInterval
140− onTriggered: {
141− __contentActive = false;
142− menuActivator.clear();
143− }
144− }
145−
146− Indicators.MenuContentActivator {
147− id: menuActivator
148− running: content.__contentActive
149− baseIndex: content.currentMenuIndex
150− count: indicatorsModel.count
131+ onTriggered: content.__contentActive = false
151132 }
152133}
tests/mocks/Unity/Indicators/IndicatorsModel.qml+1−1
@@ -64,7 +64,7 @@ ListModel {
6464 isValid: "";
6565 }
6666 ListElement {
67− identifier: "indicator-fake4";
67+ identifier: "indicator-fake5";
6868 priority: 4
6969 title: "Menu5";
7070 description: "";
tests/qmltests/Panel/tst_MenuContent.qml+32−47
@@ -85,29 +85,29 @@ Item {
8585
8686 function activate_content(index)
8787 {
88− menuContent.currentMenuIndex = index
88+ menuContent.setCurrentMenuIndex(index)
8989 }
9090
9191 function get_test_menu_objecName(index) {
9292 return "menu_page"+(index+1);
9393 }
9494
95− property string test_menu_objectName : ""
96− function current_menu_equals_test_menu() {
97− var current_loader = menu_content_test.findChild(menuContent, "menus").currentItem
98− if (current_loader == undefined) {
99− console.log("current_loader 'menus' undefined");
95+ property string testTabObjectName : ""
96+
97+ function selected_tab_equals_test_tab() {
98+ var currentTab = menu_content_test.findChild(menuContent, "tabs").selectedTab
99+ if (currentTab == undefined) {
100+ console.log("selected tab undefined");
100101 return false;
101102 }
102103
103− var menu = menu_content_test.findChild(menuContent, test_menu_objectName);
104− if (menu == undefined) {
105− console.log("test_menu " + test_menu_objectName + " undefined");
104+ var testTab = menu_content_test.findChild(menuContent, testTabObjectName);
105+ if (testTab == undefined) {
106+ console.log("test_tab " + testTabObjectName + " undefined");
106107 return false;
107108 }
108109
109− // The parent of the menu will be the loader
110− return menu.parent == current_loader;
110+ return testTab == currentTab;
111111 }
112112
113113 UT.UnityTestCase {
@@ -123,81 +123,66 @@ Item {
123123
124124 // Check that the correct menus are displayed for the requested item.
125125 function test_show_menu() {
126− var menu_count = indicatorsModel.count;
127− verify(menu_count > 0, "Menu count should be greater than zero");
126+ var menuCount = indicatorsModel.count;
127+ verify(menuCount > 0, "Menu count should be greater than zero");
128128
129− var menus = menu_content_test.findChild(menuContent, "menus")
129+ var tabs = menu_content_test.findChild(menuContent, "tabs")
130130
131131 // 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++) {
133133
134− var menu_index = i%menu_count;
134+ var menuIndex = i%menuCount;
135135
136− activate_content(menu_index);
137− test_menu_objectName = get_test_menu_objecName(menu_index);
138− compare(menus.currentIndex, menu_index, "Current menu index does not match selected menu index");
139− tryCompareFunction(current_menu_equals_test_menu, true);
136+ activate_content(menuIndex);
137+ testTabObjectName = indicatorsModel.data(menuIndex, Indicators.IndicatorsModelRole.Identifier);
138+ compare(tabs.selectedTabIndex, menuIndex, "Current tab index does not match selected tab index");
139+ tryCompareFunction(selected_tab_equals_test_tab, true);
140140 }
141141 }
142142
143143 // Calling activateContent should call start on all menus
144144 function test_activate_content() {
145− var menu_count = indicatorsModel.count;
146− verify(menu_count > 0, "Menu count should be greater than zero");
145+ var menuCount = indicatorsModel.count;
146+ verify(menuCount > 0, "Menu count should be greater than zero");
147147
148148 // Ensure all the menus are stopped first
149149 menuContent.__contentActive = false;
150− for (var i = 0; i < menu_count; i++) {
150+ for (var i = 0; i < menuCount; i++) {
151151 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
152152 }
153153
154154 // activate content the content to call stop.
155155 menuContent.activateContent();
156− for (var i = 0; i < menu_count; i++) {
156+ for (var i = 0; i < menuCount; i++) {
157157 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
158158 }
159159 }
160160
161161 // Calling activateContent should call stop on all menus.
162162 function test_release_content() {
163− var menu_count = indicatorsModel.count;
164− verify(menu_count > 0, "Menu count should be greater than zero");
163+ var menuCount = indicatorsModel.count;
164+ verify(menuCount > 0, "Menu count should be greater than zero");
165165
166166 // Ensure all the menus are started first
167167 menuContent.__contentActive = true;
168− for (var i = 0; i < menu_count; i++) {
168+ for (var i = 0; i < menuCount; i++) {
169169 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", true);
170170 }
171171 // release the content to call stop.
172172 menuContent.releaseContent();
173− for (var i = 0; i < menu_count; i++) {
173+ for (var i = 0; i < menuCount; i++) {
174174 tryCompare(indicator_status[get_test_menu_objecName(i)], "started", false);
175175 }
176176 }
177177
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−
193178 // Tests QTBUG-30632 - asynchronous loader crashes when changing index quickly.
194179 function test_multi_activate() {
195− var menu_count = indicatorsModel.count;
196− verify(menu_count > 0, "Menu count should be greater than zero");
180+ var menuCount = indicatorsModel.count;
181+ verify(menuCount > 0, "Menu count should be greater than zero");
197182
198183 for (var i = 0; i < 100; i++) {
199− activate_content(i % menu_count);
200− compare(menuContent.currentMenuIndex, i%menu_count);
184+ activate_content(i % menuCount);
185+ compare(menuContent.currentMenuIndex, i%menuCount);
201186 }
202187 wait(100);
203188 }