on ea438a7 help sign in
unity8/plugins/Unity/Indicators/qml/MenuItemFactory.qml
501 lines 18 kB history raw
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 * Nick Dedekind <nick.dedekind@canonical.com>
18 */
20import QtQuick 2.0
21import Ubuntu.Settings.Menus 0.1 as Menus
22import QMenuModel 0.1 as QMenuModel
23import Utils 0.1 as Utils
24import Ubuntu.Components.ListItems 0.1 as ListItems
25import Ubuntu.Components 0.1
27Item {
28 id: menuFactory
30 property var menuModel: null
32 property var _map: {
33 "unity.widgets.systemsettings.tablet.volumecontrol" : sliderMenu,
34 "unity.widgets.systemsettings.tablet.switch" : switchMenu,
36 "com.canonical.indicator.button" : buttonMenu,
37 "com.canonical.indicator.div" : separatorMenu,
38 "com.canonical.indicator.section" : sectionMenu,
39 "com.canonical.indicator.progress" : progressMenu,
40 "com.canonical.indicator.slider" : sliderMenu,
41 "com.canonical.indicator.switch" : switchMenu,
42 "com.canonical.indicator.alarm" : alarmMenu,
43 "com.canonical.indicator.appointment" : appointmentMenu,
45 "com.canonical.indicator.messages.messageitem" : messageItem,
46 "com.canonical.indicator.messages.sourceitem" : groupedMessage,
48 "com.canonical.unity.slider" : sliderMenu,
49 "com.canonical.unity.switch" : switchMenu,
51 "com.canonical.unity.media-player" : mediaPayerMenu,
52 "com.canonical.unity.playback-item" : playbackItemMenu,
54 "unity.widgets.systemsettings.tablet.wifisection" : wifiSection,
55 "unity.widgets.systemsettings.tablet.accesspoint" : accessPoint,
56 }
58 function getExtendedProperty(object, propertyName, defaultValue) {
59 if (object && object.hasOwnProperty(propertyName)) {
60 return object[propertyName];
61 }
62 return defaultValue;
63 }
65 Component {
66 id: separatorMenu;
67 Menus.SeparatorMenu {
68 objectName: "separatorMenu"
69 }
70 }
72 Component {
73 id: sliderMenu;
74 Menus.SliderMenu {
75 objectName: "sliderMenu"
76 property QtObject menuData: null
77 property var menuModel: menuFactory.menuModel
78 property int menuIndex: -1
79 property var extendedData: menuData && menuData.ext || undefined
81 text: menuData && menuData.label || ""
82 iconSource: menuData && menuData.icon || ""
83 minIcon: getExtendedProperty(extendedData, "minIcon", "")
84 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
86 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
87 maximumValue: {
88 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
89 if (maximum <= minimumValue) {
90 return minimumValue + 1;
91 }
92 return maximum;
93 }
94 value: menuData && menuData.actionState || 0.0
95 enabled: menuData && menuData.sensitive || false
97 onMenuModelChanged: {
98 loadAttributes();
99 }
100 onMenuIndexChanged: {
101 loadAttributes();
102 }
103 onUpdated: {
104 menuModel.changeState(menuIndex, value);
105 }
107 function loadAttributes() {
108 if (!menuModel || menuIndex == -1) return;
109 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
110 'max-value': 'double',
111 'min-icon': 'icon',
112 'max-icon': 'icon'});
113 }
114 }
115 }
117 Component {
118 id: buttonMenu;
119 Menus.ButtonMenu {
120 objectName: "buttonMenu"
121 property QtObject menuData: null
122 property var menuModel: menuFactory.menuModel
123 property int menuIndex: -1
125 buttonText: menuData && menuData.label || ""
126 enabled: menuData && menuData.sensitive || false
128 onTriggered: {
129 menuModel.activate(menuIndex);
130 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
131 }
132 }
133 }
134 Component {
135 id: sectionMenu;
136 Menus.SectionMenu {
137 objectName: "sectionMenu"
138 property QtObject menuData: null
139 property var menuIndex: undefined
141 text: menuData && menuData.label || ""
142 busy: false
143 }
144 }
146 Component {
147 id: progressMenu;
148 Menus.ProgressValueMenu {
149 objectName: "progressMenu"
150 property QtObject menuData: null
151 property int menuIndex: -1
153 text: menuData && menuData.label || ""
154 iconSource: menuData && menuData.icon || ""
155 value : menuData && menuData.actionState || 0.0
156 enabled: menuData && menuData.sensitive || false
157 }
158 }
160 Component {
161 id: standardMenu;
162 ListItems.Standard {
163 objectName: "standardMenu"
164 property QtObject menuData: null
165 property int menuIndex: -1
167 text: menuData && menuData.label || ""
168 iconSource: menuData && menuData.icon || ""
169 enabled: menuData && menuData.sensitive || false
171 onTriggered: {
172 menuModel.activate(menuIndex);
173 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
174 }
175 }
176 }
178 Component {
179 id: checkableMenu;
180 Menus.CheckableMenu {
181 objectName: "checkableMenu"
182 property QtObject menuData: null
183 property int menuIndex: -1
185 text: menuData && menuData.label || ""
186 enabled: menuData && menuData.sensitive || false
187 checked: menuData && menuData.isToggled || false
189 onTriggered: {
190 menuModel.activate(menuIndex);
191 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
192 }
193 }
194 }
197 Component {
198 id: switchMenu;
199 Menus.SwitchMenu {
200 objectName: "switchMenu"
201 property QtObject menuData: null
202 property int menuIndex: -1
204 text: menuData && menuData.label || ""
205 iconSource: menuData && menuData.icon || ""
206 enabled: menuData && menuData.sensitive || false
207 checked: menuData && menuData.isToggled || false
209 onTriggered: {
210 menuModel.activate(menuIndex);
211 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
212 }
213 }
214 }
216 Component {
217 id: alarmMenu;
218 Menus.EventMenu {
219 objectName: "alarmMenu"
220 property QtObject menuData: null
221 property var menuModel: menuFactory.menuModel
222 property int menuIndex: -1
223 property var extendedData: menuData && menuData.ext || undefined
224 // TODO - bug #1260728
225 property var timeFormatter: Utils.GDateTimeFormatter {
226 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
227 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
228 }
230 text: menuData && menuData.label || ""
231 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
232 time: timeFormatter.timeString
233 enabled: menuData && menuData.sensitive || false
235 onMenuModelChanged: {
236 loadAttributes();
237 }
238 onMenuIndexChanged: {
239 loadAttributes();
240 }
241 onTriggered: {
242 menuModel.activate(menuIndex);
243 }
245 function loadAttributes() {
246 if (!menuModel || menuIndex == -1) return;
247 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
248 'x-canonical-time-format': 'string'});
249 }
250 }
251 }
253 Component {
254 id: appointmentMenu;
255 Menus.EventMenu {
256 objectName: "appointmentMenu"
257 property QtObject menuData: null
258 property var menuModel: menuFactory.menuModel
259 property int menuIndex: -1
260 property var extendedData: menuData && menuData.ext || undefined
261 // TODO - bug #1260728
262 property var timeFormatter: Utils.GDateTimeFormatter {
263 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
264 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
265 }
267 text: menuData && menuData.label || ""
268 iconSource: menuData && menuData.icon || "image://theme/calendar"
269 time: timeFormatter.timeString
270 eventColor: menu && menu.ext.hasOwnProperty("xCanonicalColor") ? menu.ext.xCanonicalColor : Qt.rgba(0.0, 0.0, 0.0, 0.0)
271 enabled: menuData && menuData.sensitive || false
273 onMenuModelChanged: {
274 loadAttributes();
275 }
276 onMenuIndexChanged: {
277 loadAttributes();
278 }
279 onTriggered: {
280 menuModel.activate(menuIndex);
281 }
283 function loadAttributes() {
284 if (!menuModel || menuIndex == -1) return;
285 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
286 'x-canonical-time': 'int64',
287 'x-canonical-time-format': 'string'});
288 }
289 }
290 }
292 Component {
293 id: wifiSection;
294 Menus.SectionMenu {
295 objectName: "wifiSection"
296 property QtObject menuData: null
297 property var menuModel: menuFactory.menuModel
298 property int menuIndex: -1
299 property var extendedData: menuData && menuData.ext || undefined
301 text: menuData && menuData.label || ""
302 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
304 onMenuModelChanged: {
305 loadAttributes();
306 }
307 onMenuIndexChanged: {
308 loadAttributes();
309 }
311 function loadAttributes() {
312 if (!menuModel || menuIndex == -1) return;
313 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
314 }
315 }
316 }
318 Component {
319 id: accessPoint;
320 Menus.AccessPointMenu {
321 objectName: "accessPoint"
322 property QtObject menuData: null
323 property var menuModel: menuFactory.menuModel
324 property int menuIndex: -1
325 property var extendedData: menuData && menuData.ext || undefined
327 property var strengthAction: QMenuModel.UnityMenuAction {
328 model: menuModel
329 index: menuIndex
330 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
331 }
333 text: menuData && menuData.label || ""
334 enabled: menuData && menuData.sensitive || false
335 checked: menuData && menuData.isToggled || false
336 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
337 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
338 signalStrength: strengthAction.valid ? strengthAction.state : 0
340 onMenuModelChanged: {
341 loadAttributes();
342 }
343 onMenuIndexChanged: {
344 loadAttributes();
345 }
346 onTriggered: {
347 menuModel.activate(menuIndex);
348 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
349 }
351 function loadAttributes() {
352 if (!menuModel || menuIndex == -1) return;
353 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
354 'x-canonical-wifi-ap-is-secure': 'bool',
355 'x-canonical-wifi-ap-strength-action': 'string'});
356 }
357 }
358 }
360 Component {
361 id: messageItem
362 MessageMenuItemFactory {
363 objectName: "messageItem"
364 menuModel: menuFactory.menuModel
365 }
366 }
368 Component {
369 id: groupedMessage
370 Menus.GroupedMessageMenu {
371 objectName: "groupedMessage"
372 property QtObject menuData: null
373 property var menuModel: menuFactory.menuModel
374 property int menuIndex: -1
375 property var extendedData: menuData && menuData.ext || undefined
377 text: menuData && menuData.label || ""
378 iconSource: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
379 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
380 enabled: menuData && menuData.sensitive || false
381 removable: true
383 onMenuModelChanged: {
384 loadAttributes();
385 }
386 onMenuIndexChanged: {
387 loadAttributes();
388 }
389 onClicked: {
390 menuModel.activate(menuIndex, true);
391 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
392 }
393 onDismissed: {
394 menuModel.activate(menuIndex, false);
395 }
397 function loadAttributes() {
398 if (!menuModel || menuIndex == -1) return;
399 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
400 }
401 }
402 }
404 Component {
405 id: mediaPayerMenu;
406 Menus.MediaPlayerMenu {
407 objectName: "mediaPayerMenu"
408 property QtObject menuData: null
409 property var menuModel: menuFactory.menuModel
410 property int menuIndex: -1
411 property var actionState: menuData && menuData.actionState || undefined
413 playerIcon: menuData && menuData.icon || ""
414 playerName: menuData && menuData.label || ""
416 albumArt: getExtendedProperty(actionState, "art-url", "")
417 song: getExtendedProperty(actionState, "title", "unknown")
418 artist: getExtendedProperty(actionState, "artist", "unknown")
419 album: getExtendedProperty(actionState, "album", "unknown")
420 running: getExtendedProperty(actionState, "running", false)
421 state: getExtendedProperty(actionState, "state", "")
422 enabled: menuData && menuData.sensitive || false
424 onTriggered: {
425 model.activate(modelIndex);
426 }
427 }
428 }
430 Component {
431 id: playbackItemMenu;
432 Menus.PlaybackItemMenu {
433 objectName: "playbackItemMenu"
434 property QtObject menuData: null
435 property var menuModel: menuFactory.menuModel
436 property int menuIndex: -1
437 property var extendedData: menuData && menuData.ext || undefined
439 property var playAction: QMenuModel.UnityMenuAction {
440 model: menuModel
441 index: menuIndex
442 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
443 }
444 property var nextAction: QMenuModel.UnityMenuAction {
445 model: menuModel
446 index: menuIndex
447 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
448 }
449 property var previousAction: QMenuModel.UnityMenuAction {
450 model: menuModel
451 index: menuIndex
452 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
453 }
455 playing: playAction.state === "Playing"
456 canPlay: playAction.valid
457 canGoNext: nextAction.valid
458 canGoPrevious: previousAction.valid
459 enabled: menuData && menuData.sensitive || false
461 onPlay: {
462 playAction.activate();
463 }
464 onNext: {
465 nextAction.activate();
466 }
467 onPrevious: {
468 previousAction.activate();
469 }
470 onMenuModelChanged: {
471 loadAttributes();
472 }
473 onMenuIndexChanged: {
474 loadAttributes();
475 }
477 function loadAttributes() {
478 if (!menuModel || menuIndex == -1) return;
479 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
480 'x-canonical-next-action': 'string',
481 'x-canonical-previous-action': 'string'});
482 }
483 }
484 }
486 function load(modelData) {
487 if (modelData.type !== undefined) {
488 var component = _map[modelData.type];
489 if (component !== undefined) {
490 return component;
491 }
492 }
493 if (modelData.isCheck || modelData.isRadio) {
494 return checkableMenu;
495 }
496 if (modelData.isSeparator) {
497 return separatorMenu;
498 }
499 return standardMenu;
500 }