@@ -17,71 +17,170 @@
17import QtQuick 2.2
17import QtQuick 2.2
18import Ubuntu.Components 1.1
18import Ubuntu.Components 1.1
19import Dash 0.1
19import Dash 0.1
20−import "../Components"
24 objectName: "dashNavigation"
23 objectName: "dashNavigation"
26 property var scope: null
26 property var scope: null
27 property var scopeStyle: null
27 property var scopeStyle: null
28+ property real availableHeight
29− property alias windowWidth: blackRect.width
30+ signal leafClicked()
30− property alias windowHeight: blackRect.height
31− readonly property var openList: {
32− if (navigationButton.showList) return navigationButton.listView;
35− readonly property bool disableParentInteractive: {
36− return navigationButton.showList || navigationButton.inverseMousePressed;
39− // FIXME this is only here for highlight purposes (see Background.qml, too)
32+ // internal
40− readonly property var background: backgroundItem
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 isGoingBack: false
42 visible: height != 0
37 visible: height != 0
43− height: navigationButton.currentNavigation ? units.gu(5) : 0
38+ implicitHeight: navigationListView.y + navigationListView.height
45 QtObject {
40 QtObject {
47 readonly property color foregroundColor: root.scopeStyle
42 readonly property color foregroundColor: root.scopeStyle
48 ? root.scopeStyle.getTextColor(backgroundItem.luminance)
43 ? root.scopeStyle.getTextColor(backgroundItem.luminance)
49 : Theme.palette.normal.baseText
44 : Theme.palette.normal.baseText
50− readonly property real navigationWidth: root.width >= units.gu(60) ? units.gu(40) : root.width
53− Rectangle {
47+ Label {
54− id: blackRect
48+ id: label
55− objectName: "blackRect"
49+ anchors.top: parent.top
56− color: "black"
50+ anchors.left: parent.left
57− opacity: openList && openList.currentItem && openList.currentItem.visible ? 0.5 : 0
51+ anchors.margins: units.gu(2)
58− Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
52+ text: root.currentNavigation ? root.currentNavigation.label : ""
59− anchors { left: parent.left; right: parent.right }
53+ color: d.foregroundColor
60− visible: opacity > 0
54+ elide: Text.ElideRight
63− Background {
58+ ListView {
64− id: backgroundItem
59+ id: navigationListView
65− anchors.fill: parent
60+ objectName: "navigationListView"
66− style: scopeStyle ? scopeStyle.navigationBackground : "color:///#f5f5f5"
61+ orientation: ListView.Horizontal
66+ // navigationId: the navigation id of the navigation the list represents
67+ // nullifyNavigation: overrides navigationId to be null
68+ // This is used to "clear" the delegate when going "right" on the tree
70+ anchors.top: label.bottom
71+ property int maxHeight: -1
72+ Component.onCompleted: updateMaxHeight();
73+ function updateMaxHeight()
75+ maxHeight = root.availableHeight - mapToItem(root, 0, 0).y;
77+ property int prevHeight: maxHeight
78+ height: currentItem ? currentItem.height : maxHeight
83+ prevHeight = currentItem.desiredHeight;
86+ highlightMoveDuration: UbuntuAnimation.FastDuration
87+ delegate: DashNavigationList {
88+ objectName: "navigation" + index
90+ width: navigationListView.width
91+ scopeStyle: root.scopeStyle
92+ foregroundColor: d.foregroundColor
93+ property real desiredHeight: {
94+ if (navigation && navigation.loaded && x == navigationListView.contentX)
96+ navigationListView.updateMaxHeight();
97+ return Math.min(implicitHeight, navigationListView.maxHeight);
99+ return navigationListView.prevHeight;
102+ height: desiredHeight
103+ navigation: (nullifyNavigation || !scope) ? null : scope.getNavigation(navigationId)
104+ currentNavigation: root.currentNavigation
105+ onEnterNavigation: {
106+ scope.setNavigationState(newNavigationId);
107+ // We only need to add a new item to the model
108+ // if we have children, otherwise just load it
110+ isGoingBack = false;
111+ navigationModel.append({"navigationId": newNavigationId, "nullifyNavigation": false});
112+ navigationListView.currentIndex++;
117+ onGoBackToParentClicked: {
118+ if (navigationListView.currentIndex == 0) {
119+ // This can happen if we jumped to the non root of a deep tree and the user
120+ // is now going back, create space in the list for the list to move "left"
121+ var aux = navigationListView.highlightMoveDuration;
122+ navigationListView.highlightMoveDuration = 0;
123+ navigationModel.insert(0, {"navigationId": navigation.parentNavigationId, "nullifyNavigation": false});
124+ navigationListView.currentIndex = navigationListView.currentIndex + 1;
125+ navigationListView.contentX = width * navigationListView.currentIndex;
126+ navigationListView.highlightMoveDuration = aux;
129+ scope.setNavigationState(navigation.parentNavigationId);
131+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", false);
132+ navigationListView.currentIndex--;
134+ onAllNavigationClicked: {
136+ if (root.currentNavigation.parentNavigationId == navigation.navigationId) {
137+ // For leaves we have to go to the parent too
138+ scope.setNavigationState(root.currentNavigation.parentNavigationId);
142+ onContentXChanged: {
143+ if (navigationListView.highlightMoveDuration == 0)
146+ if (contentX == width * navigationListView.currentIndex) {
148+ navigationModel.remove(navigationListView.currentIndex + 1);
150+ navigationModel.setProperty(navigationListView.currentIndex - 1, "nullifyNavigation", true);
158+ top: navigationListView.bottom
159+ left: navigationListView.left
160+ right: navigationListView.right
70 fillMode: Image.Stretch
162 fillMode: Image.Stretch
71− source: scopeStyle.backgroundLuminance > 0.2 ? "graphics/navigation_shadow.png" : "graphics/navigation_shadow_light.png"
163+ source: "graphics/navigation_shadow.png"
72− anchors { top: parent.bottom; left: parent.left; right: parent.right }
75− DashNavigationButton {
166+ property bool isFirstLoad: false
76− id: navigationButton
167+ onScopeChanged: {
77− objectName: "navigationButton"
168+ navigationModel.clear();
78− height: root.height
169+ isFirstLoad = true;
79− width: d.navigationWidth
170+ }
80− scope: root.scope
171+ function setNewNavigation() {
81− scopeStyle: root.scopeStyle
172+ if (isFirstLoad && currentNavigation && currentNavigation.loaded) {
82− foregroundColor: d.foregroundColor
173+ isFirstLoad = false;
83− listView.width: d.navigationWidth
174+ if (currentNavigation.count > 0) {
84− listView.x: -x
175+ navigationModel.append({"navigationId": scope.currentNavigationId, "nullifyNavigation": false});
85− showDivider: root.width > d.navigationWidth
176+ } else {
177+ navigationModel.append({"navigationId": currentNavigation.parentNavigationId, "nullifyNavigation": false});
182+ target: currentNavigation
183+ onLoadedChanged: setNewNavigation();
185+ onCurrentNavigationChanged: setNewNavigation();