on 75772ee help sign in
unity8/plugins/Unity/Indicators/qml/MenuItemFactory.qml
507 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
80 property var serverValue: getExtendedProperty(menuData, "actionState", undefined)
82 text: menuData && menuData.label || ""
83 iconSource: menuData && menuData.icon || ""
84 minIcon: getExtendedProperty(extendedData, "minIcon", "")
85 maxIcon: getExtendedProperty(extendedData, "maxIcon", "")
87 minimumValue: getExtendedProperty(extendedData, "minValue", 0.0)
88 maximumValue: {
89 var maximum = getExtendedProperty(extendedData, "maxValue", 1.0);
90 if (maximum <= minimumValue) {
91 return minimumValue + 1;
92 }
93 return maximum;
94 }
95 enabled: menuData && menuData.sensitive || false
97 onMenuModelChanged: {
98 loadAttributes();
99 }
100 onMenuIndexChanged: {
101 loadAttributes();
102 }
103 onServerValueChanged: {
104 // value can be changed by slider, so a binding won't work.
105 if (serverValue !== undefined) {
106 value = serverValue;
107 }
108 }
109 onUpdated: {
110 menuModel.changeState(menuIndex, value);
111 }
113 function loadAttributes() {
114 if (!menuModel || menuIndex == -1) return;
115 menuModel.loadExtendedAttributes(menuIndex, {'min-value': 'double',
116 'max-value': 'double',
117 'min-icon': 'icon',
118 'max-icon': 'icon'});
119 }
120 }
121 }
123 Component {
124 id: buttonMenu;
125 Menus.ButtonMenu {
126 objectName: "buttonMenu"
127 property QtObject menuData: null
128 property var menuModel: menuFactory.menuModel
129 property int menuIndex: -1
131 buttonText: menuData && menuData.label || ""
132 enabled: menuData && menuData.sensitive || false
134 onTriggered: {
135 menuModel.activate(menuIndex);
136 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
137 }
138 }
139 }
140 Component {
141 id: sectionMenu;
142 Menus.SectionMenu {
143 objectName: "sectionMenu"
144 property QtObject menuData: null
145 property var menuIndex: undefined
147 text: menuData && menuData.label || ""
148 busy: false
149 }
150 }
152 Component {
153 id: progressMenu;
154 Menus.ProgressValueMenu {
155 objectName: "progressMenu"
156 property QtObject menuData: null
157 property int menuIndex: -1
159 text: menuData && menuData.label || ""
160 iconSource: menuData && menuData.icon || ""
161 value : menuData && menuData.actionState || 0.0
162 enabled: menuData && menuData.sensitive || false
163 }
164 }
166 Component {
167 id: standardMenu;
168 ListItems.Standard {
169 objectName: "standardMenu"
170 property QtObject menuData: null
171 property int menuIndex: -1
173 text: menuData && menuData.label || ""
174 iconSource: menuData && menuData.icon || ""
175 enabled: menuData && menuData.sensitive || false
177 onTriggered: {
178 menuModel.activate(menuIndex);
179 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
180 }
181 }
182 }
184 Component {
185 id: checkableMenu;
186 Menus.CheckableMenu {
187 objectName: "checkableMenu"
188 property QtObject menuData: null
189 property int menuIndex: -1
191 text: menuData && menuData.label || ""
192 enabled: menuData && menuData.sensitive || false
193 checked: menuData && menuData.isToggled || false
195 onTriggered: {
196 menuModel.activate(menuIndex);
197 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
198 }
199 }
200 }
203 Component {
204 id: switchMenu;
205 Menus.SwitchMenu {
206 objectName: "switchMenu"
207 property QtObject menuData: null
208 property int menuIndex: -1
210 text: menuData && menuData.label || ""
211 iconSource: menuData && menuData.icon || ""
212 enabled: menuData && menuData.sensitive || false
213 checked: menuData && menuData.isToggled || false
215 onTriggered: {
216 menuModel.activate(menuIndex);
217 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
218 }
219 }
220 }
222 Component {
223 id: alarmMenu;
224 Menus.EventMenu {
225 objectName: "alarmMenu"
226 property QtObject menuData: null
227 property var menuModel: menuFactory.menuModel
228 property int menuIndex: -1
229 property var extendedData: menuData && menuData.ext || undefined
230 // TODO - bug #1260728
231 property var timeFormatter: Utils.GDateTimeFormatter {
232 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
233 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
234 }
236 text: menuData && menuData.label || ""
237 iconSource: menuData && menuData.icon || "image://theme/alarm-clock"
238 time: timeFormatter.timeString
239 enabled: menuData && menuData.sensitive || false
241 onMenuModelChanged: {
242 loadAttributes();
243 }
244 onMenuIndexChanged: {
245 loadAttributes();
246 }
247 onTriggered: {
248 menuModel.activate(menuIndex);
249 }
251 function loadAttributes() {
252 if (!menuModel || menuIndex == -1) return;
253 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-time': 'int64',
254 'x-canonical-time-format': 'string'});
255 }
256 }
257 }
259 Component {
260 id: appointmentMenu;
261 Menus.EventMenu {
262 objectName: "appointmentMenu"
263 property QtObject menuData: null
264 property var menuModel: menuFactory.menuModel
265 property int menuIndex: -1
266 property var extendedData: menuData && menuData.ext || undefined
267 // TODO - bug #1260728
268 property var timeFormatter: Utils.GDateTimeFormatter {
269 time: getExtendedProperty(extendedData, "xCanonicalTime", 0)
270 format: getExtendedProperty(extendedData, "xCanonicalTimeFormat", "")
271 }
273 text: menuData && menuData.label || ""
274 iconSource: menuData && menuData.icon || "image://theme/calendar"
275 time: timeFormatter.timeString
276 eventColor: menu && menu.ext.hasOwnProperty("xCanonicalColor") ? menu.ext.xCanonicalColor : Qt.rgba(0.0, 0.0, 0.0, 0.0)
277 enabled: menuData && menuData.sensitive || false
279 onMenuModelChanged: {
280 loadAttributes();
281 }
282 onMenuIndexChanged: {
283 loadAttributes();
284 }
285 onTriggered: {
286 menuModel.activate(menuIndex);
287 }
289 function loadAttributes() {
290 if (!menuModel || menuIndex == -1) return;
291 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-color': 'string',
292 'x-canonical-time': 'int64',
293 'x-canonical-time-format': 'string'});
294 }
295 }
296 }
298 Component {
299 id: wifiSection;
300 Menus.SectionMenu {
301 objectName: "wifiSection"
302 property QtObject menuData: null
303 property var menuModel: menuFactory.menuModel
304 property int menuIndex: -1
305 property var extendedData: menuData && menuData.ext || undefined
307 text: menuData && menuData.label || ""
308 busy: getExtendedProperty(extendedData, "xCanonicalBusyAction", false)
310 onMenuModelChanged: {
311 loadAttributes();
312 }
313 onMenuIndexChanged: {
314 loadAttributes();
315 }
317 function loadAttributes() {
318 if (!menuModel || menuIndex == -1) return;
319 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-busy-action': 'bool'})
320 }
321 }
322 }
324 Component {
325 id: accessPoint;
326 Menus.AccessPointMenu {
327 objectName: "accessPoint"
328 property QtObject menuData: null
329 property var menuModel: menuFactory.menuModel
330 property int menuIndex: -1
331 property var extendedData: menuData && menuData.ext || undefined
333 property var strengthAction: QMenuModel.UnityMenuAction {
334 model: menuModel
335 index: menuIndex
336 name: getExtendedProperty(extendedData, "xCanonicalWifiApStrengthAction", "")
337 }
339 text: menuData && menuData.label || ""
340 enabled: menuData && menuData.sensitive || false
341 checked: menuData && menuData.isToggled || false
342 secure: getExtendedProperty(extendedData, "xCanonicalWifiApIsSecure", false)
343 adHoc: getExtendedProperty(extendedData, "xCanonicalWifiApIsAdhoc", false)
344 signalStrength: strengthAction.valid ? strengthAction.state : 0
346 onMenuModelChanged: {
347 loadAttributes();
348 }
349 onMenuIndexChanged: {
350 loadAttributes();
351 }
352 onTriggered: {
353 menuModel.activate(menuIndex);
354 shell.hideIndicatorMenu(UbuntuAnimation.BriskDuration);
355 }
357 function loadAttributes() {
358 if (!menuModel || menuIndex == -1) return;
359 menuModel.loadExtendedAttributes(menuIndex, {'x-canonical-wifi-ap-is-adhoc': 'bool',
360 'x-canonical-wifi-ap-is-secure': 'bool',
361 'x-canonical-wifi-ap-strength-action': 'string'});
362 }
363 }
364 }
366 Component {
367 id: messageItem
368 MessageMenuItemFactory {
369 objectName: "messageItem"
370 menuModel: menuFactory.menuModel
371 }
372 }
374 Component {
375 id: groupedMessage
376 Menus.GroupedMessageMenu {
377 objectName: "groupedMessage"
378 property QtObject menuData: null
379 property var menuModel: menuFactory.menuModel
380 property int menuIndex: -1
381 property var extendedData: menuData && menuData.ext || undefined
383 text: menuData && menuData.label || ""
384 iconSource: getExtendedProperty(extendedData, "icon", "qrc:/indicators/artwork/messaging/default_app.svg")
385 count: menuData && menuData.actionState.length > 0 ? menuData.actionState[0] : "0"
386 enabled: menuData && menuData.sensitive || false
387 removable: true
389 onMenuModelChanged: {
390 loadAttributes();
391 }
392 onMenuIndexChanged: {
393 loadAttributes();
394 }
395 onClicked: {
396 menuModel.activate(menuIndex, true);
397 shell.hideIndicatorMenu(UbuntuAnimation.FastDuration);
398 }
399 onDismissed: {
400 menuModel.activate(menuIndex, false);
401 }
403 function loadAttributes() {
404 if (!menuModel || menuIndex == -1) return;
405 menuModel.loadExtendedAttributes(modelIndex, {'icon': 'icon'});
406 }
407 }
408 }
410 Component {
411 id: mediaPayerMenu;
412 Menus.MediaPlayerMenu {
413 objectName: "mediaPayerMenu"
414 property QtObject menuData: null
415 property var menuModel: menuFactory.menuModel
416 property int menuIndex: -1
417 property var actionState: menuData && menuData.actionState || undefined
419 playerIcon: menuData && menuData.icon || ""
420 playerName: menuData && menuData.label || ""
422 albumArt: getExtendedProperty(actionState, "art-url", "")
423 song: getExtendedProperty(actionState, "title", "unknown")
424 artist: getExtendedProperty(actionState, "artist", "unknown")
425 album: getExtendedProperty(actionState, "album", "unknown")
426 running: getExtendedProperty(actionState, "running", false)
427 state: getExtendedProperty(actionState, "state", "")
428 enabled: menuData && menuData.sensitive || false
430 onTriggered: {
431 model.activate(modelIndex);
432 }
433 }
434 }
436 Component {
437 id: playbackItemMenu;
438 Menus.PlaybackItemMenu {
439 objectName: "playbackItemMenu"
440 property QtObject menuData: null
441 property var menuModel: menuFactory.menuModel
442 property int menuIndex: -1
443 property var extendedData: menuData && menuData.ext || undefined
445 property var playAction: QMenuModel.UnityMenuAction {
446 model: menuModel
447 index: menuIndex
448 name: getExtendedProperty(extendedData, "xCanonicalPlayAction", "")
449 }
450 property var nextAction: QMenuModel.UnityMenuAction {
451 model: menuModel
452 index: menuIndex
453 name: getExtendedProperty(extendedData, "xCanonicalNextAction", "")
454 }
455 property var previousAction: QMenuModel.UnityMenuAction {
456 model: menuModel
457 index: menuIndex
458 name: getExtendedProperty(extendedData, "xCanonicalPreviousAction", "")
459 }
461 playing: playAction.state === "Playing"
462 canPlay: playAction.valid
463 canGoNext: nextAction.valid
464 canGoPrevious: previousAction.valid
465 enabled: menuData && menuData.sensitive || false
467 onPlay: {
468 playAction.activate();
469 }
470 onNext: {
471 nextAction.activate();
472 }
473 onPrevious: {
474 previousAction.activate();
475 }
476 onMenuModelChanged: {
477 loadAttributes();
478 }
479 onMenuIndexChanged: {
480 loadAttributes();
481 }
483 function loadAttributes() {
484 if (!menuModel || menuIndex == -1) return;
485 menuModel.loadExtendedAttributes(modelIndex, {'x-canonical-play-action': 'string',
486 'x-canonical-next-action': 'string',
487 'x-canonical-previous-action': 'string'});
488 }
489 }
490 }
492 function load(modelData) {
493 if (modelData.type !== undefined) {
494 var component = _map[modelData.type];
495 if (component !== undefined) {
496 return component;
497 }
498 }
499 if (modelData.isCheck || modelData.isRadio) {
500 return checkableMenu;
501 }
502 if (modelData.isSeparator) {
503 return separatorMenu;
504 }
505 return standardMenu;
506 }