Unity 8
 All Classes Functions
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 import "../../Components/Flickables" as Flickables
25 
26 IndicatorBase {
27  id: main
28 
29  //const
30  property string title: rootActionState.title
31  property alias highlightFollowsCurrentItem : mainMenu.highlightFollowsCurrentItem
32 
33  Indicators.UnityMenuModelStack {
34  id: menuStack
35  head: main.menuModel
36 
37  property var rootMenu: null
38 
39  onTailChanged: {
40  if (!tail) {
41  rootMenu = null;
42  } else if (rootMenu != tail) {
43  if (tail.get(0, "type") === rootMenuType) {
44  rootMenu = menuStack.tail.submenu(0);
45  push(rootMenu, 0);
46  } else {
47  rootMenu = null;
48  }
49  }
50  }
51  }
52 
53  Connections {
54  target: menuStack.tail
55  onRowsInserted: {
56  if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) {
57  menuStack.rootMenu = menuStack.tail.submenu(0);
58  menuStack.push(menuStack.rootMenu, 0);
59  }
60  }
61  onModelReset: {
62  if (menuStack.rootMenu !== menuStack.tail && menuStack.tail.get(0, "type") === rootMenuType) {
63  menuStack.rootMenu = menuStack.tail.submenu(0);
64  menuStack.push(menuStack.rootMenu, 0);
65  }
66  }
67  }
68 
69  Flickables.ListView {
70  id: mainMenu
71  objectName: "mainMenu"
72  model: menuStack.rootMenu
73 
74  anchors {
75  fill: parent
76  bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - main.anchors.bottomMargin) : 0
77 
78  Behavior on bottomMargin {
79  NumberAnimation {
80  duration: 175
81  easing.type: Easing.OutQuad
82  }
83  }
84  // TODO - does ever frame.
85  onBottomMarginChanged: {
86  mainMenu.positionViewAtIndex(mainMenu.currentIndex, ListView.End)
87  }
88  }
89 
90  // Don't load all the delegates (only max of 3 pages worth -1/0/+1)
91  cacheBuffer: Math.max(height * 3, units.gu(70))
92 
93  // Only allow flicking if the content doesn't fit on the page
94  interactive: contentHeight > height
95  // FIXME - https://bugreports.qt-project.org/browse/QTBUG-41207
96  boundsBehavior: Flickable.StopAtBounds
97 
98  property int selectedIndex: -1
99  property bool blockCurrentIndexChange: false
100  // for count = 0
101  onCountChanged: {
102  if (count == 0 && selectedIndex != -1) {
103  selectedIndex = -1;
104  }
105  }
106  // for highlight following
107  onSelectedIndexChanged: {
108  if (currentIndex != selectedIndex) {
109  var blocked = blockCurrentIndexChange;
110  blockCurrentIndexChange = true;
111 
112  currentIndex = selectedIndex;
113 
114  blockCurrentIndexChange = blocked;
115  }
116  }
117  // for item addition/removal
118  onCurrentIndexChanged: {
119  if (!blockCurrentIndexChange) {
120  if (selectedIndex != -1 && selectedIndex != currentIndex) {
121  selectedIndex = currentIndex;
122  }
123  }
124  }
125 
126  delegate: Loader {
127  id: loader
128  objectName: "menuItem" + index
129  asynchronous: true
130  width: ListView.view.width
131  visible: status == Loader.Ready
132 
133  property int modelIndex: index
134  sourceComponent: factory.load(model, main.identifier)
135 
136  onLoaded: {
137  if (item.hasOwnProperty("selected")) {
138  item.selected = mainMenu.selectedIndex == index;
139  }
140  if (item.hasOwnProperty("menuSelected")) {
141  item.menuSelected.connect(function() { mainMenu.selectedIndex = index; });
142  }
143  if (item.hasOwnProperty("menuDeselected")) {
144  item.menuDeselected.connect(function() { mainMenu.selectedIndex = -1; });
145  }
146  if (item.hasOwnProperty("menuData")) {
147  item.menuData = Qt.binding(function() { return model; });
148  }
149  if (item.hasOwnProperty("menuIndex")) {
150  item.menuIndex = Qt.binding(function() { return modelIndex; });
151  }
152  }
153 
154  Binding {
155  target: item ? item : null
156  property: "objectName"
157  value: model.action
158  }
159 
160  // TODO: Fixes lp#1243146
161  // This is a workaround for a Qt bug. https://bugreports.qt-project.org/browse/QTBUG-34351
162  Connections {
163  target: mainMenu
164  onSelectedIndexChanged: {
165  if (loader.item && loader.item.hasOwnProperty("selected")) {
166  loader.item.selected = mainMenu.selectedIndex == index;
167  }
168  }
169  }
170  }
171  }
172 
173  MenuItemFactory {
174  id: factory
175  rootModel: main.menuModel ? main.menuModel : null
176  menuModel: mainMenu.model ? mainMenu.model : null
177  }
178 
179  function reset()
180  {
181  mainMenu.positionViewAtBeginning();
182  }
183 }