2 * Copyright 2013-2016 Canonical Ltd.
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.
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.
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/>.
19import Lomiri.Components 1.3
20import Lomiri.Components.ListItems 1.3 as ListItems
21import Lomiri.Indicators 0.1 as Indicators
28 property var submenuIndex: undefined
29 property QtObject menuModel: null
30 property Component factory
34 target: root.menuModel
35 property bool ready: false
37 // fix async creation with signal from model before it's finished.
38 function onRowsInserted(parent, first, last) {
39 if (submenuIndex !== undefined && first <= submenuIndex) {
43 function onRowsRemoved(parent, first, last) {
44 if (submenuIndex !== undefined && first <= submenuIndex) {
48 function onModelReset() {
49 if (root.submenuIndex !== undefined) {
55 Component.onCompleted: {
57 dynamicChanges.ready = true;
60 function reset(clearModel) {
63 var model = root.submenuIndex == undefined ? menuModel : menuModel.submenu(root.submenuIndex)
65 push(pageComponent, { "menuModel": model });
67 } else if (root.currentPage) {
68 root.currentPage.reset();
77 property alias menuModel: listView.model
78 property alias title: backLabel.title
79 property bool isSubmenu: false
82 listView.positionViewAtBeginning();
85 property QtObject factory: root.factory.createObject(page, { menuModel: page.menuModel } )
89 visible: page.isSubmenu
90 leadingActionBar.actions: [
103 objectName: "listView"
106 top: page.isSubmenu ? backLabel.bottom : parent.top
109 bottom: parent.bottom
110 bottomMargin: Qt.inputMethod.visible ? (Qt.inputMethod.keyboardRectangle.height - root.anchors.bottomMargin) : 0
112 Behavior on bottomMargin {
115 easing.type: Easing.OutQuad
118 // TODO - does ever frame.
119 onBottomMarginChanged: {
120 listView.positionViewAtIndex(listView.currentIndex, ListView.End)
124 // Don't load all the delegates (only max of 3 pages worth -1/0/+1)
125 cacheBuffer: Math.max(height * 3, units.gu(70))
127 // Only allow flicking if the content doesn't fit on the page
128 interactive: contentHeight > height
130 property int selectedIndex: -1
131 property bool blockCurrentIndexChange: false
134 if (count == 0 && selectedIndex != -1) {
138 // for highlight following
139 onSelectedIndexChanged: {
140 if (currentIndex != selectedIndex) {
141 var blocked = blockCurrentIndexChange;
142 blockCurrentIndexChange = true;
144 currentIndex = selectedIndex;
146 blockCurrentIndexChange = blocked;
149 // for item addition/removal
150 onCurrentIndexChanged: {
151 if (!blockCurrentIndexChange) {
152 if (selectedIndex != -1 && selectedIndex != currentIndex) {
153 selectedIndex = currentIndex;
159 target: listView.model ? listView.model : null
160 function onRowsAboutToBeRemoved(parent, first, last) {
161 // track current item deletion.
162 if (listView.selectedIndex >= first && listView.selectedIndex <= last) {
163 listView.selectedIndex = -1;
170 objectName: "menuItem" + index
171 width: ListView.view.width
172 visible: status == Loader.Ready
174 property int modelIndex: index
175 sourceComponent: page.factory.load(model)
178 if (item.hasOwnProperty("selected")) {
179 item.selected = listView.selectedIndex == index;
181 if (item.hasOwnProperty("menuSelected")) {
182 item.menuSelected.connect(function() { listView.selectedIndex = index; });
184 if (item.hasOwnProperty("menuDeselected")) {
185 item.menuDeselected.connect(function() { listView.selectedIndex = -1; });
187 if (item.hasOwnProperty("menuData")) {
188 item.menuData = Qt.binding(function() { return model; });
190 if (item.hasOwnProperty("menuIndex")) {
191 item.menuIndex = Qt.binding(function() { return modelIndex; });
193 if (item.hasOwnProperty("clicked")) {
194 item.clicked.connect(function() {
195 if (model.hasSubmenu) {
196 page.menuModel.aboutToShow(modelIndex);
197 root.push(pageComponent, {
199 "title": model.label.replace(/_|&/, ""),
200 "menuModel": page.menuModel.submenu(modelIndex)
208 target: item ? item : null
209 restoreMode: Binding.RestoreBinding
210 property: "objectName"
214 // TODO: Fixes lp#1243146
215 // This is a workaround for a Qt bug. https://bugreports.qt-project.org/browse/QTBUG-34351
218 function onSelectedIndexChanged() {
219 if (loader.item && loader.item.hasOwnProperty("selected")) {
220 loader.item.selected = listView.selectedIndex == index;