Unity 8
 All Classes Functions Properties
DefaultIndicatorPage.qml
1 /*
2  * Copyright 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors:
17  * Renato Araujo Oliveira Filho <renato@canonical.com>
18  * Nick Dedekind <nick.dedekind@canonical.com>
19  */
20 
21 import QtQuick 2.0
22 import Ubuntu.Components 0.1 as Components
23 import Unity.Indicators 0.1 as Indicators
24 
25 IndicatorBase {
26  id: main
27 
28  //const
29  property bool contentActive: false
30  property string title: rootActionState.title
31  property alias emptyText: emptyLabel.text
32  property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
33 
34  Indicators.UnityMenuModelStack {
35  id: menuStack
36  head: contentActive ? main.menuModel : null
37 
38  property var rootMenu: null
39 
40  onTailChanged: {
41  if (!tail) {
42  rootMenu = null;
43  } else if (rootMenu != tail) {
44  if (tail.get(0, "type") === rootMenuType) {
45  rootMenu = menuStack.tail.submenu(0);
46  push(rootMenu, 0);
47  } else {
48  rootMenu = null;
49  }
50  }
51  }
52  }
53 
54  Connections {
55  target: menuStack.tail
56  onRowsInserted: {
57  if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) {
58  menuStack.rootMenu = menuStack.tail.submenu(0);
59  menuStack.push(menuStack.rootMenu, 0);
60  }
61  }
62  onModelReset: {
63  if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) {
64  menuStack.rootMenu = menuStack.tail.submenu(0);
65  menuStack.push(menuStack.rootMenu, 0);
66  }
67  }
68  }
69 
70  ListView {
71  id: mainMenu
72  objectName: "mainMenu"
73  model: menuStack.rootMenu
74 
75  anchors {
76  fill: parent
77  bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
78 
79  Behavior on bottomMargin {
80  NumberAnimation {
81  duration: 175
82  easing.type: Easing.OutQuad
83  }
84  }
85  // TODO - does ever frame.
86  onBottomMarginChanged: {
87  mainMenu.positionViewAtIndex(mainMenu.currentIndex, ListView.End)
88  }
89  }
90 
91  // Ensure all delegates are cached in order to improve smoothness of scrolling
92  cacheBuffer: 10000
93 
94  // Only allow flicking if the content doesn't fit on the page
95  interactive: contentHeight > height
96 
97  property int selectedIndex: -1
98  property bool blockCurrentIndexChange: false
99  // for count = 0
100  onCountChanged: {
101  if (count == 0 && selectedIndex != -1) {
102  selectedIndex = -1;
103  }
104  }
105  // for highlight following
106  onSelectedIndexChanged: {
107  if (currentIndex != selectedIndex) {
108  var blocked = blockCurrentIndexChange;
109  blockCurrentIndexChange = true;
110 
111  currentIndex = selectedIndex;
112 
113  blockCurrentIndexChange = blocked;
114  }
115  }
116  // for item addition/removal
117  onCurrentIndexChanged: {
118  if (!blockCurrentIndexChange) {
119  if (selectedIndex != -1 && selectedIndex != currentIndex) {
120  selectedIndex = currentIndex;
121  }
122  }
123  }
124 
125  delegate: Loader {
126  id: loader
127  objectName: "menuItem" + index
128  asynchronous: false
129  visible: height > 0
130 
131  property int modelIndex: index
132 
133  anchors {
134  left: parent.left
135  right: parent.right
136  }
137 
138  sourceComponent: factory.load(model)
139 
140  onLoaded: {
141  if (item.hasOwnProperty("selected")) {
142  item.selected = mainMenu.selectedIndex == index;
143  }
144  if (item.hasOwnProperty("menuSelected")) {
145  item.menuSelected.connect(function() { mainMenu.selectedIndex = index; });
146  }
147  if (item.hasOwnProperty("menuDeselected")) {
148  item.menuDeselected.connect(function() { mainMenu.selectedIndex = -1; });
149  }
150  if (item.hasOwnProperty("menuData")) {
151  item.menuData = Qt.binding(function() { return model; });
152  }
153  if (item.hasOwnProperty("menuIndex")) {
154  item.menuIndex = Qt.binding(function() { return modelIndex; });
155  }
156  }
157 
158  Binding {
159  target: item ? item : null
160  property: "objectName"
161  value: model.action
162  }
163 
164  // TODO: Fixes lp#1243146
165  // This is a workaround for a Qt bug. https://bugreports.qt-project.org/browse/QTBUG-34351
166  Connections {
167  target: mainMenu
168  onSelectedIndexChanged: {
169  if (loader.item && loader.item.hasOwnProperty("selected")) {
170  loader.item.selected = mainMenu.selectedIndex == index;
171  }
172  }
173  }
174  }
175  }
176 
177  MenuItemFactory {
178  id: factory
179  rootModel: main.menuModel ? main.menuModel : null
180  menuModel: mainMenu.model ? mainMenu.model : null
181  }
182 
183  Components.Label {
184  id: emptyLabel
185  objectName: "emptyLabel"
186  visible: mainMenu.count == 0
187  anchors {
188  top: parent.top
189  left: parent.left
190  right: parent.right
191  topMargin: units.gu(2)
192  }
193  wrapMode: Text.WordWrap
194  horizontalAlignment: Text.AlignHCenter
195 
196  //style
197  color: "#e8e1d0"
198  fontSize: "medium"
199 
200  text: "Empty!"
201  }
202 
203  function start()
204  {
205  reset()
206  if (!contentActive) {
207  contentActive = true;
208  }
209  }
210 
211  function stop()
212  {
213  if (contentActive) {
214  contentActive = false;
215  }
216  }
217 
218  function reset()
219  {
220  mainMenu.selectedIndex = -1;
221  mainMenu.positionViewAtBeginning();
222  }
223 }