2 * Copyright (C) 2014 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.1
19 import "../Components/Flickables" as Flickables
23 objectName: "dashNavigation"
26 property var scope: null
27 property var scopeStyle: null
28 property color foregroundColor: Theme.palette.normal.baseText
29 property bool isAltNavigation: false
30 property bool showDivider: false
33 readonly property var currentNavigation: scope && scope[hasNavigation] ? getNavigation(scope[currentNavigationId]) : null
34 readonly property alias listView: navigationListView
35 property bool showList: false
38 // Are we drilling down the tree or up?
39 property bool isGoingBack: false
40 readonly property string hasNavigation: isAltNavigation ? "hasAltNavigation" : "hasNavigation"
41 readonly property string currentNavigationId: isAltNavigation ? "currentAltNavigationId" : "currentNavigationId"
42 function getNavigation(navId) {
43 if (isAltNavigation) {
44 return scope.getAltNavigation(navId);
46 return scope.getNavigation(navId);
50 visible: root.currentNavigation != null
53 navigationListView.updateMaxHeight();
54 root.showList = !root.showList;
59 anchors.margins: units.gu(2)
60 anchors.rightMargin: units.gu(5)
61 verticalAlignment: Text.AlignVCenter
62 text: root.currentNavigation ? root.currentNavigation.label : ""
63 color: root.foregroundColor
64 elide: Text.ElideRight
69 anchors.verticalCenter: parent.verticalCenter
70 anchors.right: parent.right
71 anchors.rightMargin: units.gu(2)
72 name: showList ? "up" : "down"
75 color: root.foregroundColor
78 // navigationListView is outside root
80 id: navigationListView
81 objectName: "navigationListView"
83 orientation: ListView.Horizontal
85 clip: root.width != windowWidth
89 // navigationId: the navigation id of the navigation the list represents
90 // nullifyNavigation: overrides navigationId to be null
91 // This is used to "clear" the delegate when going "right" on the tree
93 anchors.top: root.bottom
94 property int maxHeight: -1
95 Component.onCompleted: updateMaxHeight();
96 function updateMaxHeight()
98 maxHeight = (windowHeight - mapToItem(null, 0, 0).y) - units.gu(8);
100 property int prevHeight: maxHeight
101 height: currentItem ? currentItem.height : maxHeight
104 prevHeight = currentItem.desiredHeight;
107 highlightMoveDuration: UbuntuAnimation.FastDuration
108 delegate: DashNavigationList {
109 objectName: "navigation" + index
111 width: navigationListView.width
112 scopeStyle: root.scopeStyle
113 foregroundColor: root.foregroundColor
114 property real desiredHeight: {
116 if (navigation && navigation.loaded && x == navigationListView.contentX)
118 navigationListView.updateMaxHeight();
119 return Math.min(implicitHeight, navigationListView.maxHeight);
121 return navigationListView.prevHeight;
127 height: desiredHeight
128 navigation: (nullifyNavigation || !scope) ? null : getNavigation(navigationId)
129 currentNavigation: root.currentNavigation
131 scope.setNavigationState(newNavigationId, isAltNavigation);
132 // We only need to add a new item to the model
133 // if we have children, otherwise just load it
136 navigationModel.append({"navigationId": newNavigationId, "nullifyNavigation": false});
137 navigationListView.currentIndex++;
142 onGoBackToParentClicked: {
143 scope.setNavigationState(navigation.parentNavigationId, isAltNavigation);
145 navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", false);
146 navigationListView.currentIndex--;
148 onAllNavigationClicked: {
150 if (root.currentNavigation.parentNavigationId == navigation.navigationId) {
151 // For leaves we have to go to the parent too
152 scope.setNavigationState(root.currentNavigation.parentNavigationId, isAltNavigation);
157 if (contentX == width * navigationListView.currentIndex) {
159 navigationModel.remove(navigationListView.currentIndex + 1);
161 navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", true);
169 top: navigationListView.bottom
170 left: navigationListView.left
171 right: navigationListView.right
173 fillMode: Image.Stretch
174 source: "graphics/navigation_shadow.png"
175 visible: root.showList
179 navigationModel.clear();
180 if (scope && scope[hasNavigation]) {
181 navigationModel.append({"navigationId": scope[currentNavigationId], "nullifyNavigation": false});
187 // This is duplicated since we can't have something based on the dynamic hasNavigation string property
188 onHasNavigationChanged: {
189 if (!root.isAltNavigation) {
190 if (scope.hasNavigation) {
191 navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
193 navigationModel.clear();
197 onHasAltNavigationChanged: {
198 if (root.isAltNavigation) {
199 if (scope.hasAltNavigation) {
200 navigationModel.append({"navigationId": scope.currentAltNavigationId, "nullifyNavigation": false});
202 navigationModel.clear();
209 anchors.fill: navigationListView
210 enabled: root.showList
211 onPressed: root.showList = false
215 visible: root.showDivider
218 topMargin: units.dp(1)
219 bottom: parent.bottom
221 leftMargin: -units.dp(0.5)
224 color: root.foregroundColor