Unity 8
 All Classes Functions Properties
DashDepartments.qml
1 /*
2  * Copyright (C) 2014 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.2
18 import Ubuntu.Components 0.1
19 
20 AbstractButton {
21  id: root
22  objectName: "dashDepartments"
23 
24  property var scope: null
25 
26  property bool showList: false
27 
28  readonly property var currentDepartment: scope && scope.hasDepartments ? scope.getDepartment(scope.currentDepartmentId) : null
29 
30  property alias windowWidth: blackRect.width
31  property alias windowHeight: blackRect.height
32  property var scopeStyle: null
33 
34  // Are we drilling down the tree or up?
35  property bool isGoingBack: false
36 
37  visible: root.currentDepartment != null
38 
39  height: visible ? units.gu(5) : 0
40 
41  onClicked: {
42  root.showList = !root.showList;
43  }
44 
45  Rectangle {
46  id: blackRect
47  color: "black"
48  opacity: departmentListView.currentItem && departmentListView.currentItem.visible ? 0.3 : 0
49  Behavior on opacity { UbuntuNumberAnimation { duration: UbuntuAnimation.SnapDuration } }
50  anchors.top: departmentListView.top
51  anchors.right: parent.right
52  visible: opacity != 0
53  }
54 
55  Image {
56  anchors {
57  top: parent.top
58  left: parent.left
59  right: parent.right
60  }
61  fillMode: Image.Stretch
62  source: "graphics/dash_divider_top_lightgrad.png"
63  z: -1
64  }
65 
66  Image {
67  anchors {
68  bottom: parent.bottom
69  left: parent.left
70  right: parent.right
71  }
72  fillMode: Image.Stretch
73  source: "graphics/dash_divider_top_darkgrad.png"
74  z: -1
75  }
76 
77  Label {
78  anchors.fill: parent
79  anchors.margins: units.gu(2)
80  verticalAlignment: Text.AlignVCenter
81  text: root.currentDepartment ? root.currentDepartment.label : ""
82  color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
83  }
84 
85  Icon {
86  anchors.verticalCenter: parent.verticalCenter
87  anchors.right: parent.right
88  anchors.rightMargin: units.gu(2)
89  name: showList ? "up" : "down"
90  height: units.gu(2)
91  width: height
92  color: root.scopeStyle ? root.scopeStyle.foreground : "grey"
93  }
94 
95  // departmentListView is outside root
96  ListView {
97  id: departmentListView
98  objectName: "departmentListView"
99  orientation: ListView.Horizontal
100  interactive: false
101  clip: root.width != windowWidth
102  model: ListModel {
103  id: departmentModel
104  // We have two roles
105  // departmentId: the department id of the department the list represents
106  // nullifyDepartment: overrides departmentId to be null
107  // This is used to "clear" the delegate when going "right" on the tree
108  }
109  anchors {
110  left: parent.left
111  right: parent.right
112  top: root.bottom
113  }
114  readonly property int maxHeight: (windowHeight - mapToItem(null, root.x, root.y).y) - units.gu(8)
115  property int prevHeight: maxHeight
116  height: currentItem ? currentItem.height : maxHeight
117  onHeightChanged: {
118  if (root.showList) {
119  prevHeight = currentItem.desiredHeight;
120  }
121  }
122  highlightMoveDuration: UbuntuAnimation.FastDuration
123  delegate: DashDepartmentsList {
124  objectName: "department" + index
125  visible: height != 0
126  width: departmentListView.width
127  scopeStyle: root.scopeStyle
128  property real desiredHeight: {
129  if (root.showList) {
130  if (department && department.loaded && x == departmentListView.contentX)
131  {
132  return Math.min(implicitHeight, departmentListView.maxHeight);
133  } else {
134  return departmentListView.prevHeight;
135  }
136  } else {
137  return 0;
138  }
139  }
140  height: desiredHeight
141  department: (nullifyDepartment || !scope) ? null : scope.getDepartment(departmentId)
142  currentDepartment: root.currentDepartment
143  onEnterDepartment: {
144  scope.loadDepartment(newDepartmentId);
145  // We only need to add a new item to the model
146  // if we have children, otherwise just load it
147  if (hasChildren) {
148  isGoingBack = false;
149  departmentModel.append({"departmentId": newDepartmentId, "nullifyDepartment": false});
150  departmentListView.currentIndex++;
151  } else {
152  showList = false;
153  }
154  }
155  onGoBackToParentClicked: {
156  scope.loadDepartment(department.parentDepartmentId);
157  isGoingBack = true;
158  departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", false);
159  departmentListView.currentIndex--;
160  }
161  onAllDepartmentClicked: {
162  showList = false;
163  if (root.currentDepartment.parentDepartmentId == department.departmentId) {
164  // For leaves we have to go to the parent too
165  scope.loadDepartment(root.currentDepartment.parentDepartmentId);
166  }
167  }
168  }
169  onContentXChanged: {
170  if (contentX == width * departmentListView.currentIndex) {
171  if (isGoingBack) {
172  departmentModel.remove(departmentListView.currentIndex + 1);
173  } else {
174  departmentModel.setProperty(departmentListView.currentIndex - 1, "nullifyDepartment", true);
175  }
176  }
177  }
178  }
179 
180  InverseMouseArea {
181  anchors.fill: departmentListView
182  enabled: root.showList
183  onClicked: root.showList = false
184  }
185 
186  onScopeChanged: {
187  departmentModel.clear();
188  if (scope && scope.hasDepartments) {
189  departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
190  }
191  }
192 
193  Connections {
194  target: scope
195  onHasDepartmentsChanged: {
196  if (scope.hasDepartments) {
197  departmentModel.append({"departmentId": scope.currentDepartmentId, "nullifyDepartment": false});
198  } else {
199  departmentModel.clear();
200  }
201  }
202  }
203 }