2 * Copyright (C) 2014,2015 Canonical, Ltd.
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.
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.
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/>.
18 import Ubuntu.Components 1.3
20 import "../Components"
24 objectName: "dashNavigation"
27 property var scope: null
28 property real availableHeight
33 readonly property var currentNavigation: scope && scope.hasNavigation ? scope.getNavigation(scope.currentNavigationId) : null
34 // Are we drilling down the tree or up?
35 property bool isEnteringChildren: false
38 implicitHeight: scope && scope.hasNavigation ? navigationListView.y + navigationListView.height : 0
40 function resetNavigation() {
41 if (navigationModel.count > 1) {
54 function pop(popsNeeded) {
57 isEnteringChildren = false;
58 navigationListView.currentIndex = navigationListView.currentIndex - popsNeeded;
59 navigationModel.setProperty(navigationListView.currentIndex, "nullifyNavigation", false);
60 navigationModel.remove(navigationModel.count - popsNeeded, popsNeeded);
62 popsNeeded = Math.min(headersModel.count, popsNeeded);
63 // This is effectively deleting ourselves, so needs to be the last thing of the function
64 headersModel.remove(headersModel.count - popsNeeded, popsNeeded);
71 // headerText: the text to show
72 // navigationId: the navigation Id that represents
73 // parentNavigationId: the parent navigation Id
75 delegate: DashNavigationHeader {
76 objectName: "dashNavigationHeader" + index
77 height: index == 0 && headersModel.count > 1 ? 0 : units.gu(5)
78 width: headersColumn.width
80 backVisible: index != 0
84 scope.setNavigationState(parentNavigationId);
86 var popsNeeded = headersModel.count - index;
87 headersColumn.pop(popsNeeded);
91 scope.setNavigationState(navigationId);
93 var popsNeeded = headersModel.count - index - 1;
94 headersColumn.pop(popsNeeded);
103 id: navigationListView
104 objectName: "navigationListView"
105 orientation: ListView.Horizontal
110 // navigationId: the navigation id of the navigation the list represents
111 // nullifyNavigation: overrides navigationId to be null
112 // This is used to "clear" the delegate when going "right" on the tree
115 top: headersColumn.bottom
119 readonly property int maxHeight: root.availableHeight - navigationListView.y
120 property int prevHeight: maxHeight
121 height: currentItem ? currentItem.height : maxHeight
125 prevHeight = currentItem.desiredHeight;
128 highlightMoveDuration: UbuntuAnimation.FastDuration
129 delegate: DashNavigationList {
130 objectName: "navigation" + index
132 width: navigationListView.width
133 property real desiredHeight: {
134 if (navigation && navigation.loaded && x == navigationListView.contentX)
136 return Math.min(implicitHeight, navigationListView.maxHeight);
138 return navigationListView.prevHeight;
141 height: desiredHeight
142 navigation: (nullifyNavigation || !scope) ? null : scope.getNavigation(navigationId)
143 currentNavigation: root.currentNavigation
144 onEnterNavigation: { // var newNavigationId, string newNavigationLabel, bool hasChildren
145 scope.setNavigationState(newNavigationId);
146 // We only need to add a new item to the model
147 // if we have children, otherwise just load it
149 isEnteringChildren = true;
150 navigationModel.append({"navigationId": newNavigationId, "nullifyNavigation": false});
151 headersModel.append({"headerText": newNavigationLabel,
152 "navigationId": newNavigationId,
153 "parentNavigationId": navigationId
155 navigationListView.currentIndex++;
162 if (navigationListView.highlightMoveDuration == 0)
165 if (contentX == width * navigationListView.currentIndex) {
166 if (isEnteringChildren) {
167 navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", true);
173 property bool isFirstLoad: false
174 onScopeChanged: clear();
176 navigationModel.clear();
177 headersModel.clear();
180 function setNewNavigation() {
181 if (isFirstLoad && currentNavigation && currentNavigation.loaded) {
183 if (currentNavigation.count > 0) {
184 navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
186 navigationModel.append({"navigationId": currentNavigation.parentNavigationId, "nullifyNavigation": false});
188 headersModel.append({"headerText": currentNavigation.allLabel != "" ? currentNavigation.allLabel : currentNavigation.label,
189 "navigationId": currentNavigation.navigationId,
190 "parentNavigationId": currentNavigation.parentNavigationId
195 target: currentNavigation
196 onLoadedChanged: setNewNavigation();
198 onCurrentNavigationChanged: setNewNavigation();