Merge lp:~nick-dedekind/ubuntu-ui-toolkit/menus into lp:ubuntu-ui-toolkit

Proposed by Nick Dedekind
Status: Superseded
Proposed branch: lp:~nick-dedekind/ubuntu-ui-toolkit/menus
Merge into: lp:ubuntu-ui-toolkit
Prerequisite: lp:~nick-dedekind/ubuntu-ui-toolkit/actionItem-mnemonics
Diff against target: 2175 lines (+1727/-152)
19 files modified
components.api (+27/-6)
src/Ubuntu/Components/1.2/ActionList.qml (+0/-47)
src/Ubuntu/Components/1.3/ActionList.qml (+0/-47)
src/Ubuntu/Components/ComponentModule.pro (+0/-2)
src/Ubuntu/Components/plugin/plugin.cpp (+10/-0)
src/Ubuntu/Components/plugin/plugin.pri (+13/-3)
src/Ubuntu/Components/plugin/ucaction.cpp (+103/-37)
src/Ubuntu/Components/plugin/ucaction.h (+27/-7)
src/Ubuntu/Components/plugin/ucactionlist.cpp (+104/-0)
src/Ubuntu/Components/plugin/ucactionlist.h (+53/-0)
src/Ubuntu/Components/plugin/ucexclusivegroup.cpp (+106/-0)
src/Ubuntu/Components/plugin/ucexclusivegroup.h (+53/-0)
src/Ubuntu/Components/plugin/ucmenu.cpp (+613/-0)
src/Ubuntu/Components/plugin/ucmenu.h (+108/-0)
src/Ubuntu/Components/plugin/ucmenu_p.h (+83/-0)
src/Ubuntu/Components/plugin/ucmenubar.cpp (+299/-0)
src/Ubuntu/Components/plugin/ucmenubar.h (+60/-0)
src/Ubuntu/Components/plugin/ucmenubar_p.h (+68/-0)
src/Ubuntu/Components/qmldir (+0/-3)
To merge this branch: bzr merge lp:~nick-dedekind/ubuntu-ui-toolkit/menus
Reviewer Review Type Date Requested Status
Ubuntu SDK team Pending
Review via email: mp+295432@code.launchpad.net

This proposal has been superseded by a proposal from 2016-06-07.

Commit message

API for MenuBar, Menus, MenuItem & MenuSeparator

To post a comment you must log in.
1323. By Timo Jyrinki

Rebuild for arm64 gles switch.

1324. By Timo Jyrinki

no "-gles" in changelog package name

1325. By Albert Astals Cid

OTA12-2016-05-20

1326. By CI Train Bot Account

Releasing 1.3.1984+16.10.20160527.2

1327. By Zoltan Balogh

OTA12-2016-06-01

1328. By CI Train Bot Account

Releasing 1.3.1988+16.10.20160601

1329. By CI Train Bot Account

Resync trunk.

1330. By Nick Dedekind

merged actionList

1331. By Nick Dedekind

members accessors to functions

1332. By Nick Dedekind

Menu API

1333. By Nick Dedekind

merged with actionList

1334. By Nick Dedekind

new components.api

1335. By Nick Dedekind

fix platform abstraction

1336. By Nick Dedekind

better dynamicness

1337. By Nick Dedekind

updated api

1338. By Nick Dedekind

removed debug

1339. By Nick Dedekind

removed attached properties

1340. By Nick Dedekind

better removal

1341. By Nick Dedekind

activate state

1342. By Nick Dedekind

enable fix

1343. By Nick Dedekind

added MenuGroup::at

1344. By Nick Dedekind

simplified insert

1345. By Nick Dedekind

Added menu unit tests

1346. By Nick Dedekind

updated menu tests

1347. By Nick Dedekind

updated menu tests

1348. By Nick Dedekind

updated menu tests

1349. By Nick Dedekind

removed distfile from pro

1350. By Nick Dedekind

merged exclusiveGroup

1351. By Nick Dedekind

merged with staging

1352. By Nick Dedekind

merged parent

1353. By Nick Dedekind

fixed namespace

1354. By Nick Dedekind

merged with trunk

1355. By Nick Dedekind

removed uc prefix

1356. By Nick Dedekind

moved menus to Labs

1357. By Nick Dedekind

merged parent

1358. By Nick Dedekind

merged staging

1359. By Nick Dedekind

fixed broken build

Unmerged revisions

1359. By Nick Dedekind

fixed broken build

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2016-05-20 17:33:56 +0000
+++ components.api 2016-06-07 14:25:30 +0000
@@ -12,6 +12,7 @@
12Ubuntu.Components.Action 1.3 1.0 0.1 UCAction: QtObject12Ubuntu.Components.Action 1.3 1.0 0.1 UCAction: QtObject
13 property string description13 property string description
14 property bool enabled14 property bool enabled
15 property ExclusiveGroup exclusiveGroup 1.3
15 property string iconName16 property string iconName
16 property url iconSource17 property url iconSource
17 property Component itemHint18 property Component itemHint
@@ -19,9 +20,11 @@
19 signal triggered(var value)20 signal triggered(var value)
20 function trigger(var value)21 function trigger(var value)
21 function trigger()22 function trigger()
23 function setState(var )
22 property string name24 property string name
23 property Type parameterType25 property Type parameterType
24 property var shortcut 1.326 property var shortcut 1.3
27 property var state 1.3
25 property string text28 property string text
26 property bool visible29 property bool visible
27Ubuntu.Components.Action.Type: Enum30Ubuntu.Components.Action.Type: Enum
@@ -54,12 +57,12 @@
54 function trigger(var value)57 function trigger(var value)
55 function trigger()58 function trigger()
56 property string text59 property string text
57Ubuntu.Components.ActionList 1.0 0.1: QtObject60Ubuntu.Components.ActionList 1.0 0.1 UCActionList: QtObject
58 property list<Action> actions61 default property list<Action> actions
59 default property list<Action> children62 signal added(Action action)
60Ubuntu.Components.ActionList 1.3: QtObject63 signal removed(Action action)
61 property list<Action> actions64 function addAction(Action action)
62 default property list<Action> children65 function removeAction(Action action)
63Ubuntu.Components.ActionManager 1.0 0.1 UCActionManager: QtObject66Ubuntu.Components.ActionManager 1.0 0.1 UCActionManager: QtObject
64 default property list<Action> actions67 default property list<Action> actions
65 readonly property ActionContext globalContext68 readonly property ActionContext globalContext
@@ -456,6 +459,8 @@
456 property bool showDivider459 property bool showDivider
457 readonly property string swipingState460 readonly property string swipingState
458 readonly property bool waitingConfirmationForRemoval461 readonly property bool waitingConfirmationForRemoval
462Ubuntu.Components.ExclusiveGroup 1.3 UCExclusiveGroup: ActionList
463 readonly property Action selected
459Ubuntu.Components.ListItems.Expandable 1.0 0.1: Empty464Ubuntu.Components.ListItems.Expandable 1.0 0.1: Empty
460 property bool collapseOnClick465 property bool collapseOnClick
461 property double collapsedHeight466 property double collapsedHeight
@@ -656,6 +661,22 @@
656 function double lerp(double delta, double from, double to)661 function double lerp(double delta, double from, double to)
657 function double projectValue(double x, double xmin, double xmax, double ymin, double ymax)662 function double projectValue(double x, double xmin, double xmax, double ymin, double ymax)
658 function double clampAndProject(double x, double xmin, double xmax, double ymin, double ymax)663 function double clampAndProject(double x, double xmin, double xmax, double ymin, double ymax)
664Ubuntu.Components.Menu 1.3 UCMenu: Action
665 default property list<QtObject> data
666 function show(Qt.point pt)
667 function dismiss()
668 function appendObject(QtObject obj)
669 function insertObject(int index, QtObject obj)
670 function removeObject(QtObject obj)
671Ubuntu.Components.MenuBar 1.3 UCMenuBar: QtObject
672 default property list<Menu> menus
673 function appendMenu(Menu menu)
674 function insertMenu(int index, Menu menu)
675 function removeMenu(Menu menu)
676Ubuntu.Components.MenuGroup 1.3 UCMenuGroup: ActionList
677Ubuntu.Components.Menus 1.3: QtObject
678 readonly property MenuBar menuBar
679 readonly property Menu parentMenu
659Ubuntu.Components.MimeData 1.0 0.1 QQuickMimeData: QtObject680Ubuntu.Components.MimeData 1.0 0.1 QQuickMimeData: QtObject
660 property color color681 property color color
661 property var data682 property var data
662683
=== removed file 'src/Ubuntu/Components/1.2/ActionList.qml'
--- src/Ubuntu/Components/1.2/ActionList.qml 2016-05-25 12:48:10 +0000
+++ src/Ubuntu/Components/1.2/ActionList.qml 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
1/*
2 * Copyright 2012 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
17import QtQuick 2.4
18import Ubuntu.Components 1.2
19
20/*!
21 \qmltype ActionList
22 \inqmlmodule Ubuntu.Components
23 \ingroup ubuntu
24 \brief List of \l Action items
25*/
26
27QtObject {
28 id: list
29 // internal objects using nested elements,
30 // which isn't allowed by QtObject; this fix makes this possible
31 /*!
32 Default property to allow adding of children.
33 \qmlproperty list<Action> children
34 \default
35 */
36 default property alias children: list.actions
37
38 /*!
39 List of already defined actions when not defining them as children of the ActionList.
40 Note that when you set this property, the children of the ActionList will be ignored,
41 so do not set the list and define children.
42
43 The advantage of setting actions over using the children is that the same
44 \l Action items can be used in several sets of actions.
45 */
46 property list<Action> actions
47}
480
=== removed file 'src/Ubuntu/Components/1.3/ActionList.qml'
--- src/Ubuntu/Components/1.3/ActionList.qml 2016-05-25 12:48:10 +0000
+++ src/Ubuntu/Components/1.3/ActionList.qml 1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
1/*
2 * Copyright 2012 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
17import QtQuick 2.4
18import Ubuntu.Components 1.3
19
20/*!
21 \qmltype ActionList
22 \inqmlmodule Ubuntu.Components
23 \ingroup ubuntu
24 \brief List of \l Action items
25*/
26
27QtObject {
28 id: list
29 // internal objects using nested elements,
30 // which isn't allowed by QtObject; this fix makes this possible
31 /*!
32 Default property to allow adding of children.
33 \qmlproperty list<Action> children
34 \default
35 */
36 default property alias children: list.actions
37
38 /*!
39 List of already defined actions when not defining them as children of the ActionList.
40 Note that when you set this property, the children of the ActionList will be ignored,
41 so do not set the list and define children.
42
43 The advantage of setting actions over using the children is that the same
44 \l Action items can be used in several sets of actions.
45 */
46 property list<Action> actions
47}
480
=== modified file 'src/Ubuntu/Components/ComponentModule.pro'
--- src/Ubuntu/Components/ComponentModule.pro 2016-02-16 11:39:32 +0000
+++ src/Ubuntu/Components/ComponentModule.pro 2016-06-07 14:25:30 +0000
@@ -25,7 +25,6 @@
2525
26#1.226#1.2
27QML_FILES += 1.2/AbstractButton.qml \27QML_FILES += 1.2/AbstractButton.qml \
28 1.2/ActionList.qml \
29 1.2/ActivityIndicator.qml \28 1.2/ActivityIndicator.qml \
30 1.2/AnimatedItem.qml \29 1.2/AnimatedItem.qml \
31 1.2/AppHeader.qml \30 1.2/AppHeader.qml \
@@ -78,7 +77,6 @@
7877
79#1.378#1.3
80QML_FILES += 1.3/ActionBar.qml \79QML_FILES += 1.3/ActionBar.qml \
81 1.3/ActionList.qml \
82 1.3/ActivityIndicator.qml \80 1.3/ActivityIndicator.qml \
83 1.3/AdaptivePageLayout.qml \81 1.3/AdaptivePageLayout.qml \
84 1.3/AnimatedItem.qml \82 1.3/AnimatedItem.qml \
8583
=== modified file 'src/Ubuntu/Components/plugin/plugin.cpp'
--- src/Ubuntu/Components/plugin/plugin.cpp 2016-04-20 15:00:27 +0000
+++ src/Ubuntu/Components/plugin/plugin.cpp 2016-06-07 14:25:30 +0000
@@ -78,9 +78,13 @@
78#include "ucpagetreenode.h"78#include "ucpagetreenode.h"
79#include "ucmainviewbase.h"79#include "ucmainviewbase.h"
80#include "ucperformancemonitor.h"80#include "ucperformancemonitor.h"
81#include "ucmenu.h"
82#include "ucmenubar.h"
81#include "privates/frame.h"83#include "privates/frame.h"
82#include "privates/ucpagewrapper.h"84#include "privates/ucpagewrapper.h"
83#include "privates/appheaderbase.h"85#include "privates/appheaderbase.h"
86#include "ucactionlist.h"
87#include "ucexclusivegroup.h"
8488
85// From UbuntuGestures89// From UbuntuGestures
86#include "private/ucswipearea_p.h"90#include "private/ucswipearea_p.h"
@@ -173,6 +177,7 @@
173 qmlRegisterSimpleSingletonType<UCHaptics>(uri, major, minor, "Haptics");177 qmlRegisterSimpleSingletonType<UCHaptics>(uri, major, minor, "Haptics");
174 qmlRegisterSimpleSingletonType<UCMathUtils>(uri, major, minor, "MathUtils");178 qmlRegisterSimpleSingletonType<UCMathUtils>(uri, major, minor, "MathUtils");
175 qmlRegisterSimpleSingletonType<UbuntuToolkit::ColorUtils>(uri, major, minor, "ColorUtils");179 qmlRegisterSimpleSingletonType<UbuntuToolkit::ColorUtils>(uri, major, minor, "ColorUtils");
180 qmlRegisterType<UCActionList>(uri, major, minor, "ActionList");
176}181}
177182
178void UbuntuComponentsPlugin::registerTypes(const char *uri)183void UbuntuComponentsPlugin::registerTypes(const char *uri)
@@ -235,6 +240,11 @@
235 qmlRegisterType<UCPageTreeNode>(uri, 1, 3, "PageTreeNode");240 qmlRegisterType<UCPageTreeNode>(uri, 1, 3, "PageTreeNode");
236 qmlRegisterType<UCPopupContext>(uri, 1, 3, "PopupContext");241 qmlRegisterType<UCPopupContext>(uri, 1, 3, "PopupContext");
237 qmlRegisterType<UCMainViewBase>(uri, 1, 3, "MainViewBase");242 qmlRegisterType<UCMainViewBase>(uri, 1, 3, "MainViewBase");
243 qmlRegisterType<UCMenu>(uri, 1, 3, "Menu");
244 qmlRegisterType<UCMenuBar>(uri, 1, 3, "MenuBar");
245 qmlRegisterUncreatableType<UCMenuAttached>(uri, 1, 3, "Menus", "Not instantiable");
246 qmlRegisterType<UCMenuGroup>(uri, 1, 3, "MenuGroup");
247 qmlRegisterType<UCExclusiveGroup>(uri, 1, 3, "ExclusiveGroup");
238}248}
239249
240void UbuntuComponentsPlugin::initializeContextProperties(QQmlEngine *engine)250void UbuntuComponentsPlugin::initializeContextProperties(QQmlEngine *engine)
241251
=== modified file 'src/Ubuntu/Components/plugin/plugin.pri'
--- src/Ubuntu/Components/plugin/plugin.pri 2016-04-01 05:30:24 +0000
+++ src/Ubuntu/Components/plugin/plugin.pri 2016-06-07 14:25:30 +0000
@@ -3,7 +3,7 @@
3 PKGCONFIG += gio-2.0 dbus-1 libnih-dbus3 PKGCONFIG += gio-2.0 dbus-1 libnih-dbus
4}4}
55
6QT *= core-private qml qml-private quick quick-private gui-private dbus svg UbuntuGestures UbuntuGestures_private UbuntuToolkit6QT *= core-private qml qml-private quick quick-private gui-private dbus svg platformsupport-private UbuntuGestures UbuntuGestures_private UbuntuToolkit
77
8equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {8equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) {
9 QT += v8-private9 QT += v8-private
@@ -117,7 +117,13 @@
117 $$PWD/privates/ucpagewrapperincubator_p.h \117 $$PWD/privates/ucpagewrapperincubator_p.h \
118 $$PWD/privates/appheaderbase.h \118 $$PWD/privates/appheaderbase.h \
119 $$PWD/label_p.h \119 $$PWD/label_p.h \
120 $$PWD/ucbottomedgeregion_p.h120 $$PWD/ucbottomedgeregion_p.h \
121 $$PWD/ucactionlist.h \
122 $$PWD/ucmenu.h \
123 $$PWD/ucmenu_p.h \
124 $$PWD/ucmenubar.h \
125 $$PWD/ucmenubar_p.h \
126 $$PWD/ucexclusivegroup.h
121127
122SOURCES += $$PWD/plugin.cpp \128SOURCES += $$PWD/plugin.cpp \
123 $$PWD/uctheme.cpp \129 $$PWD/uctheme.cpp \
@@ -194,7 +200,11 @@
194 $$PWD/privates/frame.cpp \200 $$PWD/privates/frame.cpp \
195 $$PWD/privates/ucpagewrapper.cpp \201 $$PWD/privates/ucpagewrapper.cpp \
196 $$PWD/privates/ucpagewrapperincubator.cpp \202 $$PWD/privates/ucpagewrapperincubator.cpp \
197 $$PWD/privates/appheaderbase.cpp203 $$PWD/privates/appheaderbase.cpp \
204 $$PWD/ucactionlist.cpp \
205 $$PWD/ucmenu.cpp \
206 $$PWD/ucmenubar.cpp \
207 $$PWD/ucexclusivegroup.cpp
198208
199# adapters209# adapters
200SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp210SOURCES += $$PWD/adapters/alarmsadapter_organizer.cpp
201211
=== modified file 'src/Ubuntu/Components/plugin/ucaction.cpp'
--- src/Ubuntu/Components/plugin/ucaction.cpp 2016-05-25 12:48:10 +0000
+++ src/Ubuntu/Components/plugin/ucaction.cpp 2016-06-07 14:25:30 +0000
@@ -17,6 +17,7 @@
17#include "ucaction.h"17#include "ucaction.h"
18#include "quickutils.h"18#include "quickutils.h"
19#include "ucactioncontext.h"19#include "ucactioncontext.h"
20#include "ucexclusivegroup.h"
2021
21#include <QtDebug>22#include <QtDebug>
22#include <QtQml/QQmlInfo>23#include <QtQml/QQmlInfo>
@@ -248,43 +249,6 @@
248 * \endqml249 * \endqml
249 */250 */
250251
251/*!
252 * \qmlproperty enum Action::parameterType
253 * Type of the parameter passed to \l trigger and \l triggered.
254 * Type is an enumeration:
255 * \list
256 * \li \b Action.None: No paramater. (default)
257 * \li \b Action.String: String parameter.
258 * \li \b Action.Integer: Integer parameter.
259 * \li \b Action.Bool: Boolean parameter.
260 * \li \b Action.Real: Single precision floating point parameter.
261 * \li \b Action.Object: The parameter is an object.
262 * \endlist
263 * \qml
264 * Action {
265 * id: action
266 * parameterType: Action.String
267 * onTriggered: {
268 * // value arguments now contain strings
269 * console.log(value);
270 * }
271 * Component.onCompleted: action.trigger("Hello World")
272 * }
273 * \endqml
274 */
275
276/*!
277 * \qmlproperty bool Action::enabled
278 * If set to false the action can not be triggered. Components visualizing the
279 * action migth either hide the action or make it insensitive. However visibility
280 * can be controlled separately using the \l visible property.
281 */
282
283/*!
284 * \qmlproperty bool Action::visible
285 * Specifies whether the action is visible to the user. Defaults to true.
286 */
287
288UCAction::UCAction(QObject *parent)252UCAction::UCAction(QObject *parent)
289 : QObject(parent)253 : QObject(parent)
290 , m_itemHint(Q_NULLPTR)254 , m_itemHint(Q_NULLPTR)
@@ -293,12 +257,15 @@
293 , m_enabled(true)257 , m_enabled(true)
294 , m_visible(true)258 , m_visible(true)
295 , m_published(false)259 , m_published(false)
260 , m_exclusiveGroup(Q_NULLPTR)
296{261{
297 generateName();262 generateName();
298 // FIXME: we need QInputDeviceInfo to detect the keyboard attechment263 // FIXME: we need QInputDeviceInfo to detect the keyboard attechment
299 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808264 // https://bugs.launchpad.net/ubuntu/+source/ubuntu-ui-toolkit/+bug/1276808
300 connect(QuickUtils::instance(), &QuickUtils::keyboardAttachedChanged,265 connect(QuickUtils::instance(), &QuickUtils::keyboardAttachedChanged,
301 this, &UCAction::onKeyboardAttached);266 this, &UCAction::onKeyboardAttached);
267
268 connect(this, &UCAction::triggered, this, &UCAction::setState);
302}269}
303270
304UCAction::~UCAction()271UCAction::~UCAction()
@@ -434,6 +401,100 @@
434 Q_EMIT shortcutChanged();401 Q_EMIT shortcutChanged();
435}402}
436403
404/*!
405 * \qmlproperty bool Action::visible
406 * Specifies whether the action is visible to the user. Defaults to true.
407 */
408void UCAction::setVisible(bool visible)
409{
410 if (m_visible == visible) {
411 return;
412 }
413 m_visible = visible;
414 Q_EMIT visibleChanged();
415}
416
417/*!
418 * \qmlproperty bool Action::enabled
419 * If set to false the action can not be triggered. Components visualizing the
420 * action migth either hide the action or make it insensitive. However visibility
421 * can be controlled separately using the \l visible property.
422 */
423void UCAction::setEnabled(bool enabled)
424{
425 if (m_enabled == enabled) {
426 return;
427 }
428 m_enabled = enabled;
429 Q_EMIT enabledChanged();
430
431}
432
433/*!
434 * \qmlproperty enum Action::parameterType
435 * Type of the parameter passed to \l trigger and \l triggered.
436 * Type is an enumeration:
437 * \list
438 * \li \b Action.None: No paramater. (default)
439 * \li \b Action.String: String parameter.
440 * \li \b Action.Integer: Integer parameter.
441 * \li \b Action.Bool: Boolean parameter.
442 * \li \b Action.Real: Single precision floating point parameter.
443 * \li \b Action.Object: The parameter is an object.
444 * \endlist
445 * \qml
446 * Action {
447 * id: action
448 * parameterType: Action.String
449 * onTriggered: {
450 * // value arguments now contain strings
451 * console.log(value);
452 * }
453 * Component.onCompleted: action.trigger("Hello World")
454 * }
455 * \endqml
456 */
457void UCAction::setParameterType(UCAction::Type type)
458{
459 if (m_parameterType == type) {
460 return;
461 }
462 m_parameterType = type;
463 Q_EMIT parameterTypeChanged();
464}
465
466void UCAction::setState(const QVariant &state)
467{
468 if (m_state == state) {
469 return;
470 }
471 m_state = state;
472 Q_EMIT stateChanged();
473}
474
475UCExclusiveGroup *UCAction::exclusiveGroup() const
476{
477 return m_exclusiveGroup;
478}
479
480void UCAction::setExclusiveGroup(UCExclusiveGroup *exclusiveGroup)
481{
482 if (m_exclusiveGroup == exclusiveGroup) {
483 return;
484 }
485
486 if (m_exclusiveGroup) {
487 m_exclusiveGroup->removeAction(this);
488 }
489
490 m_exclusiveGroup = exclusiveGroup;
491
492 if (m_exclusiveGroup) {
493 m_exclusiveGroup->addAction(this);
494 }
495 Q_EMIT exclusiveGroupChanged();
496}
497
437bool UCAction::event(QEvent *event)498bool UCAction::event(QEvent *event)
438{499{
439 if (event->type() != QEvent::Shortcut)500 if (event->type() != QEvent::Shortcut)
@@ -473,6 +534,11 @@
473 if (!m_enabled) {534 if (!m_enabled) {
474 return;535 return;
475 }536 }
537
538 if (m_exclusiveGroup && !m_exclusiveGroup->checkValidTrigger(this, value)) {
539 return;
540 }
541
476 if (!isValidType(value.type())) {542 if (!isValidType(value.type())) {
477 Q_EMIT triggered(QVariant());543 Q_EMIT triggered(QVariant());
478 } else {544 } else {
479545
=== modified file 'src/Ubuntu/Components/plugin/ucaction.h'
--- src/Ubuntu/Components/plugin/ucaction.h 2016-04-28 11:19:46 +0000
+++ src/Ubuntu/Components/plugin/ucaction.h 2016-06-07 14:25:30 +0000
@@ -49,7 +49,7 @@
4949
50class QQmlComponent;50class QQmlComponent;
51class QQuickItem;51class QQuickItem;
52class UCActionAttached;52class UCExclusiveGroup;
53class UCAction : public QObject53class UCAction : public QObject
54{54{
55 Q_OBJECT55 Q_OBJECT
@@ -58,19 +58,21 @@
58 Q_ENUMS(Type)58 Q_ENUMS(Type)
59 Q_PROPERTY(QString name MEMBER m_name WRITE setName NOTIFY nameChanged)59 Q_PROPERTY(QString name MEMBER m_name WRITE setName NOTIFY nameChanged)
60 Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged)60 Q_PROPERTY(QString text READ text WRITE setText RESET resetText NOTIFY textChanged)
61 Q_PROPERTY(QString iconName MEMBER m_iconName WRITE setIconName NOTIFY iconNameChanged)61 Q_PROPERTY(QString iconName READ iconName WRITE setIconName NOTIFY iconNameChanged)
62 Q_PROPERTY(QString description MEMBER m_description NOTIFY descriptionChanged)62 Q_PROPERTY(QString description MEMBER m_description NOTIFY descriptionChanged)
63 Q_PROPERTY(QString keywords MEMBER m_keywords NOTIFY keywordsChanged)63 Q_PROPERTY(QString keywords MEMBER m_keywords NOTIFY keywordsChanged)
64 Q_PROPERTY(bool enabled MEMBER m_enabled NOTIFY enabledChanged)64 Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
65 Q_PROPERTY(Type parameterType MEMBER m_parameterType NOTIFY parameterTypeChanged)65 Q_PROPERTY(Type parameterType READ parameterType WRITE setParameterType NOTIFY parameterTypeChanged)
66 Q_PROPERTY(QVariant state READ state WRITE setState NOTIFY stateChanged REVISION 1)
67 Q_PROPERTY(UCExclusiveGroup* exclusiveGroup READ exclusiveGroup WRITE setExclusiveGroup NOTIFY exclusiveGroupChanged REVISION 1)
6668
67 // Toolkit Actions API69 // Toolkit Actions API
68 Q_PROPERTY(QUrl iconSource MEMBER m_iconSource WRITE setIconSource NOTIFY iconSourceChanged)70 Q_PROPERTY(QUrl iconSource READ iconSource WRITE setIconSource NOTIFY iconSourceChanged)
69 Q_PROPERTY(bool visible MEMBER m_visible NOTIFY visibleChanged)71 Q_PROPERTY(bool visible READ visible WRITE setVisible NOTIFY visibleChanged)
70 Q_PROPERTY(QQmlComponent *itemHint MEMBER m_itemHint WRITE setItemHint)72 Q_PROPERTY(QQmlComponent *itemHint MEMBER m_itemHint WRITE setItemHint)
7173
72 // QtQuickControls.Action74 // QtQuickControls.Action
73 Q_PROPERTY(QVariant shortcut MEMBER m_shortcut WRITE setShortcut RESET resetShortcut NOTIFY shortcutChanged REVISION 1)75 Q_PROPERTY(QVariant shortcut READ shortcut WRITE setShortcut RESET resetShortcut NOTIFY shortcutChanged REVISION 1)
74public:76public:
75 enum Type {77 enum Type {
76 None,78 None,
@@ -104,11 +106,24 @@
104 QString text();106 QString text();
105 void setText(const QString &text);107 void setText(const QString &text);
106 void resetText();108 void resetText();
109 QString iconName() const { return m_iconName; }
107 void setIconName(const QString &name);110 void setIconName(const QString &name);
111 QUrl iconSource() const { return m_iconSource; }
108 void setIconSource(const QUrl &url);112 void setIconSource(const QUrl &url);
109 void setItemHint(QQmlComponent *);113 void setItemHint(QQmlComponent *);
114 QVariant shortcut() const { return m_shortcut; }
110 void setShortcut(const QVariant&);115 void setShortcut(const QVariant&);
111 void resetShortcut();116 void resetShortcut();
117 bool visible() const { return m_visible; }
118 void setVisible(bool visible);
119 void setEnabled(bool enabled);
120
121 void setParameterType(Type type);
122 Type parameterType() const { return m_parameterType; }
123 QVariant state() const { return m_state; }
124
125 UCExclusiveGroup *exclusiveGroup() const;
126 void setExclusiveGroup(UCExclusiveGroup *exclusiveGroup);
112127
113Q_SIGNALS:128Q_SIGNALS:
114 void nameChanged();129 void nameChanged();
@@ -121,10 +136,13 @@
121 void iconSourceChanged();136 void iconSourceChanged();
122 void visibleChanged();137 void visibleChanged();
123 void shortcutChanged();138 void shortcutChanged();
139 void stateChanged();
140 void exclusiveGroupChanged();
124 void triggered(const QVariant &value);141 void triggered(const QVariant &value);
125142
126public Q_SLOTS:143public Q_SLOTS:
127 void trigger(const QVariant &value = QVariant());144 void trigger(const QVariant &value = QVariant());
145 void setState(const QVariant&);
128146
129private:147private:
130 QPODVector<QQuickItem*, 4> m_owningItems;148 QPODVector<QQuickItem*, 4> m_owningItems;
@@ -142,6 +160,8 @@
142 bool m_enabled:1;160 bool m_enabled:1;
143 bool m_visible:1;161 bool m_visible:1;
144 bool m_published:1;162 bool m_published:1;
163 UCExclusiveGroup *m_exclusiveGroup;
164 QVariant m_state;
145165
146 friend class UCActionContext;166 friend class UCActionContext;
147 friend class UCActionItem;167 friend class UCActionItem;
148168
=== added file 'src/Ubuntu/Components/plugin/ucactionlist.cpp'
--- src/Ubuntu/Components/plugin/ucactionlist.cpp 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucactionlist.cpp 2016-06-07 14:25:30 +0000
@@ -0,0 +1,104 @@
1/*
2 * Copyright 2016 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
17#include "ucactionlist.h"
18#include "ucaction.h"
19
20/*!
21 * \qmltype ActionList
22 * \inqmlmodule Ubuntu.Components
23 * \ingroup ubuntu
24 * \brief List of \l Action items
25 */
26UCActionList::UCActionList(QObject *parent)
27 : QObject(parent)
28{
29}
30
31/*!
32 * \qmlmethod ActionList::addAction(Action action)
33 * \deprecated
34 * Adds an Action to the context programatically.
35 */
36void UCActionList::addAction(UCAction *action)
37{
38 if (m_actions.contains(action)) {
39 return;
40 }
41 m_actions.append(action);
42 Q_EMIT added(action);
43}
44
45/*!
46 * \qmlmethod ActionList::removeAction(Action action)
47 * \deprecated
48 * Removes an action from the context programatically.
49 */
50void UCActionList::removeAction(UCAction *action)
51{
52 if (!action) {
53 return;
54 }
55 if (m_actions.removeOne(action)) {
56 Q_EMIT removed(action);
57 }
58}
59
60/*!
61
62 * \qmlproperty list<Action> ActionContext::actions
63 * \default
64 * List of Actions in this ActionContext
65 * Note that when you set this property, the children of the ActionList will be ignored,
66 * so do not set the list and define children.
67 *
68 * The advantage of setting actions over using the children is that the same
69 * \l Action items can be used in several sets of actions.
70 */
71QQmlListProperty<UCAction> UCActionList::actions()
72{
73 return QQmlListProperty<UCAction>(this, 0, UCActionList::append, UCActionList::count, 0, UCActionList::clear);
74}
75
76const QList<UCAction*> &UCActionList::list() const
77{
78 return m_actions;
79}
80
81void UCActionList::append(QQmlListProperty<UCAction> *list, UCAction *action)
82{
83 UCActionList *actionList = qobject_cast<UCActionList*>(list->object);
84 if (actionList) {
85 actionList->addAction(action);
86 }
87}
88
89void UCActionList::clear(QQmlListProperty<UCAction> *list)
90{
91 UCActionList *actionList = qobject_cast<UCActionList*>(list->object);
92 if (actionList) {
93 actionList->m_actions.clear();
94 }
95}
96
97int UCActionList::count(QQmlListProperty<UCAction> *list)
98{
99 UCActionList *actionList = qobject_cast<UCActionList*>(list->object);
100 if (actionList) {
101 return actionList->m_actions.count();
102 }
103 return 0;
104}
0105
=== added file 'src/Ubuntu/Components/plugin/ucactionlist.h'
--- src/Ubuntu/Components/plugin/ucactionlist.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucactionlist.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2016 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
17#ifndef UCACTIONLIST_H
18#define UCACTIONLIST_H
19
20#include <QObject>
21#include <QtQml/QQmlListProperty>
22
23class UCAction;
24
25class UCActionList : public QObject
26{
27 Q_OBJECT
28 Q_PROPERTY(QQmlListProperty<UCAction> actions READ actions)
29 Q_CLASSINFO("DefaultProperty", "actions")
30public:
31 explicit UCActionList(QObject *parent = 0);
32
33 QQmlListProperty<UCAction> actions();
34
35 const QList<UCAction*> &list() const;
36
37public Q_SLOTS:
38 void addAction(UCAction *action);
39 void removeAction(UCAction *action);
40
41Q_SIGNALS:
42 void added(UCAction *action);
43 void removed(UCAction *action);
44
45protected:
46 QList<UCAction*> m_actions;
47
48 static void append(QQmlListProperty<UCAction> *list, UCAction *action);
49 static void clear(QQmlListProperty<UCAction> *list);
50 static int count(QQmlListProperty<UCAction> *list);
51};
52
53#endif // UCACTIONLIST_H
054
=== added file 'src/Ubuntu/Components/plugin/ucexclusivegroup.cpp'
--- src/Ubuntu/Components/plugin/ucexclusivegroup.cpp 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucexclusivegroup.cpp 2016-06-07 14:25:30 +0000
@@ -0,0 +1,106 @@
1/*
2 * Copyright 2016 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 */
17
18#include "ucexclusivegroup.h"
19#include "ucaction.h"
20
21UCExclusiveGroup::UCExclusiveGroup(QObject *parent)
22 : UCActionList(parent)
23 , m_entranceGuard(false)
24{
25 connect(this, &UCActionList::added, this, &UCExclusiveGroup::onActionAdded);
26 connect(this, &UCActionList::removed, this, &UCExclusiveGroup::onActionRemoved);
27}
28
29void UCExclusiveGroup::onActionAdded(UCAction *action)
30{
31 action->setExclusiveGroup(this);
32 connect(action, &UCAction::stateChanged, this, [this, action]() { stateChanged(action); });
33}
34
35void UCExclusiveGroup::onActionRemoved(UCAction *action)
36{
37 action->setExclusiveGroup(nullptr);
38 disconnect(action, &UCAction::stateChanged, this, 0);
39}
40
41void UCExclusiveGroup::stateChanged(UCAction* action)
42{
43 if (m_entranceGuard) return;
44 m_entranceGuard = true;
45
46 if (action->state().type() != QVariant::Bool) {
47 m_entranceGuard = false;
48 return;
49 }
50
51 Q_FOREACH(UCAction* fromList, list()) {
52 if (fromList->parameterType() != UCAction::Bool) {
53 continue;
54 }
55
56 if (fromList != action && fromList->state().toBool() == true) {
57 fromList->trigger(false);
58 }
59 }
60
61 if (action->state().toBool() == true) {
62 setSelected(action);
63 } else {
64 setSelected(nullptr);
65 }
66
67 m_entranceGuard = false;
68}
69
70void UCExclusiveGroup::setSelected(UCAction *action)
71{
72 if (m_selected != action) {
73 if (action) {
74 m_selected = action;
75 } else {
76 m_selected.clear();
77 }
78 Q_EMIT selectedChanged();
79 }
80}
81
82UCAction *UCExclusiveGroup::selected() const
83{
84 return m_selected;
85}
86
87bool UCExclusiveGroup::checkValidTrigger(UCAction *action, const QVariant &value)
88{
89 // deselect others.
90 if (value.type() == QVariant::Bool && value.toBool() == false) {
91
92 int trueCount = 0;
93 Q_FOREACH(UCAction* fromList, list()) {
94 if (fromList->parameterType() != UCAction::Bool ||
95 action == fromList) {
96 continue;
97 }
98 trueCount += fromList->state().toBool();
99 }
100
101 if (trueCount == 0) {
102 return false;
103 }
104 }
105 return true;
106}
0107
=== added file 'src/Ubuntu/Components/plugin/ucexclusivegroup.h'
--- src/Ubuntu/Components/plugin/ucexclusivegroup.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucexclusivegroup.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,53 @@
1/*
2 * Copyright 2016 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 */
17
18#ifndef UCEXCLUSIVEGROUP_H
19#define UCEXCLUSIVEGROUP_H
20
21#include "ucactionlist.h"
22#include "ucaction.h"
23#include <QQmlParserStatus>
24
25class UCExclusiveGroup : public UCActionList
26{
27 Q_OBJECT
28 Q_PROPERTY(UCAction* selected READ selected NOTIFY selectedChanged)
29
30public:
31 explicit UCExclusiveGroup(QObject *parent = 0);
32
33 UCAction* selected() const;
34
35 bool checkValidTrigger(UCAction* action, const QVariant& value);
36
37Q_SIGNALS:
38 void selectedChanged();
39
40
41protected Q_SLOTS:
42 void onActionAdded(UCAction* action);
43 void onActionRemoved(UCAction* action);
44
45private:
46 void stateChanged(UCAction* action);
47 void setSelected(UCAction* action);
48
49 QPointer<UCAction> m_selected;
50 bool m_entranceGuard;
51};
52
53#endif // UCEXCLUSIVEGROUP_H
054
=== added file 'src/Ubuntu/Components/plugin/ucmenu.cpp'
--- src/Ubuntu/Components/plugin/ucmenu.cpp 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenu.cpp 2016-06-07 14:25:30 +0000
@@ -0,0 +1,613 @@
1/*
2 * Copyright 2016 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
17#include "ucmenu.h"
18#include "ucmenu_p.h"
19#include "ucmenubar.h"
20#include "ucaction.h"
21#include "ucactionlist.h"
22
23// Qt
24#include <QtGui/qpa/qplatformtheme.h>
25#include <QtGui/qpa/qplatformmenu.h>
26#include <QQuickItem>
27#include <private/qguiapplication_p.h>
28#include <private/qquickitem_p.h>
29#include <QPointer>
30
31
32Q_LOGGING_CATEGORY(ucMenu, "ubuntu.components.Menu", QtMsgType::QtWarningMsg)
33
34namespace {
35
36QWindow* findWindowForObject(QObject* object)
37{
38 QObject* window = object;
39 while (window && !window->isWindowType()) {
40 window = window->parent();
41 if (QQuickItem* item = qobject_cast<QQuickItem*>(window)) {
42 window = item->window();
43 }
44 }
45 return qobject_cast<QWindow*>(window);
46}
47
48}
49
50UCMenuPrivate::UCMenuPrivate(UCMenu *qq)
51 : q_ptr(qq)
52 , m_platformMenu(QGuiApplicationPrivate::platformTheme()->createPlatformMenu())
53{
54}
55
56UCMenuPrivate::~UCMenuPrivate()
57{
58 delete m_platformMenu;
59}
60
61void UCMenuPrivate::insertObject(int index, QObject *o)
62{
63 Q_Q(UCMenu);
64 if (!o) return;
65 qCInfo(ucMenu).nospace() << "UCMenu::insertObject(index="<< index << ", object=" << o << ")";
66
67 // If the menus contains lists, we need to alter the insertion index to account for them.
68 int actualIndex = 0;
69 for (int i = 0; i < index && i < m_data.count(); i++) {
70 QObject* data = m_data[i];
71 auto list = qobject_cast<UCActionList*>(data);
72 actualIndex += list ? list->list().count() : 1;
73
74 // menu group adds a separator item.
75 if (qobject_cast<UCMenuGroup*>(data)) {
76 actualIndex++;
77 }
78 }
79
80 QVector<QObject*>::iterator position = m_data.count() > index ? m_data.begin() + index : m_data.end();
81 m_data.insert(position, o);
82
83 QObjectList objects;
84 if (UCActionList* actionList = qobject_cast<UCActionList*>(o)) {
85 Q_FOREACH(UCAction* action, actionList->list()) {
86 qCInfo(ucMenu).nospace() << " UCMenu::insertObject(actionList=" << actionList << ", action=" << action << ")";
87 objects << action;
88 }
89 // menu group adds a separator item; so add self as well.
90 if (qobject_cast<UCMenuGroup*>(actionList)) {
91 objects << o;
92 }
93 } else {
94 objects << o;
95 }
96
97 Q_FOREACH(QObject* object, objects) {
98
99 UCMenuAttached *attached = qobject_cast<UCMenuAttached*>(qmlAttachedPropertiesObject<UCMenuAttached>(object));
100 if (attached) {
101 attached->setParentObject(q);
102 }
103
104 // add to platform
105 if (m_platformMenu) {
106 auto platformWrapper = new PlatformItemWrapper(object, q);
107 platformWrapper->insert(actualIndex++);
108 m_platformItems[object] = platformWrapper;
109
110 QObject::connect(object, &QObject::destroyed, q, [platformWrapper]() {
111 platformWrapper->remove();
112 });
113 }
114 }
115}
116
117void UCMenuPrivate::removeObject(QObject *o)
118{
119 Q_Q(UCMenu);
120 m_data.removeOne(o);
121 qCInfo(ucMenu).nospace() << "UCMenu::insertObject(" << o << ")";
122
123 QObjectList objects;
124 if (UCActionList* actionList = qobject_cast<UCActionList*>(o)) {
125 Q_FOREACH(UCAction* action, actionList->list()) {
126 objects << action;
127 }
128 if (qobject_cast<UCMenuGroup*>(actionList)) {
129 objects << o;
130 }
131 } else {
132 objects << o;
133 }
134
135 Q_FOREACH(QObject* object, objects) {
136 // remove from platform.
137 if (m_platformMenu && m_platformItems.contains(object)) {
138 m_platformItems[object]->remove();
139 m_platformItems.remove(object);
140 }
141 }
142}
143
144void UCMenuPrivate::_q_updateEnabled()
145{
146 Q_Q(UCMenu);
147
148 bool isEnabled = q->isEnabled();
149 if (m_platformMenu) { m_platformMenu->setEnabled(isEnabled); }
150}
151
152void UCMenuPrivate::_q_updateText()
153{
154 Q_Q(UCMenu);
155
156 QString text = q->text();
157 if (m_platformMenu) { m_platformMenu->setText(text); }
158}
159
160void UCMenuPrivate::_q_updateIcon()
161{
162 Q_Q(UCMenu);
163
164 QIcon icon;
165 if (!q->iconSource().isEmpty()) {
166 icon = QIcon(q->iconSource().path());
167 } else if (!q->iconName().isEmpty()) {
168 icon = QIcon::fromTheme(q->iconName());
169 }
170
171 if (m_platformMenu) { m_platformMenu->setIcon(icon); }
172}
173
174void UCMenuPrivate::_q_updateVisible()
175{
176 Q_Q(UCMenu);
177
178 bool visible = q->visible();
179 if (m_platformMenu) { m_platformMenu->setVisible(visible); }
180}
181
182void UCMenuPrivate::data_append(QQmlListProperty<QObject> *prop, QObject *o)
183{
184 UCMenu *q = qobject_cast<UCMenu *>(prop->object);
185 q->appendObject(o);
186}
187
188int UCMenuPrivate::data_count(QQmlListProperty<QObject> *prop)
189{
190 UCMenuPrivate *p = static_cast<UCMenuPrivate *>(prop->data);
191 return p->m_data.count();
192}
193
194QObject *UCMenuPrivate::data_at(QQmlListProperty<QObject> *prop, int index)
195{
196 UCMenuPrivate *p = static_cast<UCMenuPrivate *>(prop->data);
197 return p->m_data.value(index);
198}
199
200void UCMenuPrivate::data_clear(QQmlListProperty<QObject> *prop)
201{
202 UCMenuPrivate *p = static_cast<UCMenuPrivate *>(prop->data);
203 p->m_data.clear();
204}
205
206/*!
207 * \qmltype Menu
208 * \instantiates UCMenu
209 * \inqmlmodule Ubuntu.Components
210 * \ingroup ubuntu
211 * \brief Menu defines a context menu or submenu structure of a MenuBar
212 *
213 * Example usage:
214 * \qml
215 * import QtQuick 2.4
216 * import Ubuntu.Components 1.3
217 * Menu {
218 * text: "&File"
219 *
220 * MenuGroup {
221 * Action {
222 * text: "&New"
223 * shortcut: "Ctrl+N"
224 * }
225 *
226 * Action {
227 * text: "&Open"
228 * shortcut: "Ctrl+O"
229 * }
230 * }
231 *
232 * Menu {
233 * text: "Recent Files"
234 *
235 * ActionList {
236 * Action { text: "1.txt" }
237 * Action { text: "2.txt" }
238 * Action { text: "3.txt" }
239 * }
240 * }
241 *
242 * Action {
243 * action: Action {
244 * text: "E&xit"
245 * shortcut: "Ctrl+X"
246 * }
247 * }
248 * }
249 * \endqml
250 */
251UCMenu::UCMenu(QObject *parent)
252 : UCAction(parent)
253 , d_ptr(new UCMenuPrivate(this))
254{
255 Q_D(UCMenu);
256
257 connect(this, SIGNAL(enabledChanged()), this, SLOT(_q_updateEnabled()));
258 connect(this, SIGNAL(textChanged()), this, SLOT(_q_updateText()));
259 connect(this, SIGNAL(iconNameChanged()), this, SLOT(_q_updateIcon()));
260 connect(this, SIGNAL(iconSourceChanged()), this, SLOT(_q_updateIcon()));
261 connect(this, SIGNAL(visibleChanged()), this, SLOT(_q_updateVisible()));
262}
263
264UCMenu::~UCMenu()
265{
266}
267
268/*!
269 * \qmlproperty list<Object> Menu::data
270 * \default
271 * List of objects representing menu items within the menu.
272 *
273 * Currently supports Menu, MenuItem, MenuSeparator & Item objects.
274 * \note Item object which do not support platformItem will not be exported for native menus.
275 */
276QQmlListProperty<QObject> UCMenu::data()
277{
278 Q_D(UCMenu);
279 return QQmlListProperty<QObject>(this, d,
280 &UCMenuPrivate::data_append,
281 &UCMenuPrivate::data_count,
282 &UCMenuPrivate::data_at,
283 &UCMenuPrivate::data_clear);
284}
285
286/*!
287 * \qmlmethod Menu::appendObject(object o)
288 * Add a object tto the menu
289 */
290void UCMenu::appendObject(QObject *o)
291{
292 Q_D(UCMenu);
293
294 insertObject(d->m_data.count(), o);
295}
296
297/*!
298 * \qmlmethod Menu::insertObject(int index, object o)
299 * Inserts an item at the index in the menu.
300 *
301 * Currently supports Menu, MenuItem, MenuSeparator & Item objects.
302 * \note Item object which do not support platformItem will not be exported for native menus.
303 */
304void UCMenu::insertObject(int index, QObject *o)
305{
306 Q_D(UCMenu);
307 d->insertObject(index, o);
308}
309
310/*!
311 * \qmlmethod Menu::removeObject(object o)
312 * Removes the item from the menu.
313 */
314void UCMenu::removeObject(QObject *o)
315{
316 Q_D(UCMenu);
317 qCInfo(ucMenu) << "UCMenu::removeObject" << o;
318
319 d->removeObject(o);
320}
321
322QPlatformMenu* UCMenu::platformMenu() const
323{
324 Q_D(const UCMenu);
325 return d->m_platformMenu;
326}
327
328/*!
329 * \qmlmethod Menu::show(point point)
330 * Show the menu popup at the given point
331 */
332void UCMenu::show(const QPoint &point)
333{
334 Q_D(UCMenu);
335 qCInfo(ucMenu, "UCMenu::popup(%s, point(%d,%d))", qPrintable(text()), point.x(), point.y());
336
337 if (d->m_platformMenu) {
338 d->m_platformMenu->showPopup(findWindowForObject(this), QRect(point, QSize()), nullptr);
339 }
340}
341
342/*!
343 * \qmlmethod Menu::dismiss()
344 * Dismiss and destroy the menu popup.
345 */
346void UCMenu::dismiss()
347{
348 Q_D(UCMenu);
349 qCInfo(ucMenu, "UCMenu::dismiss(%s)", qPrintable(text()));
350
351 if (d->m_platformMenu) {
352 d->m_platformMenu->dismiss();
353 }
354}
355
356/*!
357 * \qmltype Menus
358 * \instantiates UCMenuAttached
359 * \inqmlmodule Ubuntu.Components 1.3
360 * \ingroup ubuntu
361 * \since Ubuntu.Components 1.3
362 * \brief A set of properties attached to the Menu.
363 *
364 */
365UCMenuAttached::UCMenuAttached(QObject *parent)
366 : QObject(parent)
367 , m_parentObject(nullptr)
368{
369}
370
371UCMenuAttached *UCMenuAttached::qmlAttachedProperties(QObject *o)
372{
373 return new UCMenuAttached(o);
374}
375
376void UCMenuAttached::setParentObject(QObject *o)
377{
378 if (m_parentObject != o) {
379 UCMenu* oldMenu = parentMenu();
380 UCMenuBar* oldBar = menuBar();
381
382 m_parentObject = o;
383
384 if (oldMenu != parentMenu()) Q_EMIT parentMenuChanged();
385 if (oldBar != menuBar()) Q_EMIT menuBarChanged();
386 }
387}
388
389/*!
390 * \qmlattachedproperty bool Menus::parentMenu
391 * The property returns the parent Menu of the object, or null if there is none.
392 */
393UCMenu *UCMenuAttached::parentMenu() const
394{
395 return qobject_cast<UCMenu*>(m_parentObject);
396}
397
398/*!
399 * \qmlattachedproperty bool Menus::menuBar
400 * The property returns the parent MenuBar of the object, or null if there is none.
401 */
402UCMenuBar *UCMenuAttached::menuBar() const
403{
404 return qobject_cast<UCMenuBar*>(m_parentObject);
405}
406
407
408PlatformItemWrapper::PlatformItemWrapper(QObject *target, UCMenu* menu)
409 : QObject(menu)
410 , m_target(target)
411 , m_menu(menu)
412 , m_platformItem(menu->platformMenu() ? menu->platformMenu()->createMenuItem() : Q_NULLPTR)
413{
414 connect(m_target, &QObject::destroyed, this, &QObject::deleteLater);
415
416 if (UCMenu* menu = qobject_cast<UCMenu*>(m_target)) {
417 if (m_platformItem) {
418 m_platformItem->setMenu(menu->platformMenu());
419 }
420
421 connect(menu, &UCMenu::visibleChanged, this, &PlatformItemWrapper::updateVisible);
422 connect(menu, &UCMenu::textChanged, this, &PlatformItemWrapper::updateText);
423 connect(menu, &UCMenu::enabledChanged, this, &PlatformItemWrapper::updateEnabled);
424 connect(menu, &UCMenu::iconSourceChanged, this, &PlatformItemWrapper::updateIcon);
425 connect(menu, &UCMenu::iconNameChanged, this, &PlatformItemWrapper::updateIcon);
426
427 } else if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
428
429 connect(action, &UCAction::visibleChanged, this, &PlatformItemWrapper::updateVisible);
430 connect(action, &UCAction::textChanged, this, &PlatformItemWrapper::updateText);
431 connect(action, &UCAction::enabledChanged, this, &PlatformItemWrapper::updateEnabled);
432 connect(action, &UCAction::iconSourceChanged, this, &PlatformItemWrapper::updateIcon);
433 connect(action, &UCAction::iconNameChanged, this, &PlatformItemWrapper::updateIcon);
434 connect(action, &UCAction::shortcutChanged, this, &PlatformItemWrapper::updateShortcut);
435 connect(action, &UCAction::parameterTypeChanged, this, &PlatformItemWrapper::updateCheck);
436 connect(action, &UCAction::stateChanged, this, &PlatformItemWrapper::updateCheck);
437
438 if (m_platformItem) {
439 connect(m_platformItem, SIGNAL(activated()), action, SLOT(trigger()));
440 }
441
442 } else if (qobject_cast<UCActionList*>(m_target)) {
443 if (m_platformItem) {
444 m_platformItem->setIsSeparator(true);
445 }
446 }
447
448 syncPlatformItem();
449}
450
451void PlatformItemWrapper::insert(int index)
452{
453 auto platformMenu = m_menu->platformMenu();
454 if (!platformMenu) return;
455 if (!m_platformItem) return;
456
457 QPlatformMenuItem* before = platformMenu->menuItemAt(index);
458 platformMenu->insertMenuItem(m_platformItem, before);
459}
460
461void PlatformItemWrapper::remove()
462{
463 auto platformMenu = m_menu->platformMenu();
464 if (!platformMenu) return;
465 if (!m_platformItem) return;
466
467 platformMenu->removeMenuItem(m_platformItem);
468}
469
470void PlatformItemWrapper::updateVisible()
471{
472 if (!m_platformItem) return;
473
474 if (UCMenu* menu = qobject_cast<UCMenu*>(m_target)) {
475 m_platformItem->setVisible(menu->visible());
476 if (menu->platformMenu()) menu->platformMenu()->setVisible(menu->visible());
477 } else if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
478 m_platformItem->setVisible(action->visible());
479 }
480}
481
482void PlatformItemWrapper::updateEnabled()
483{
484 if (!m_platformItem) return;
485
486 if (UCMenu* menu = qobject_cast<UCMenu*>(m_target)) {
487 m_platformItem->setEnabled(menu->isEnabled());
488 if (menu->platformMenu()) menu->platformMenu()->setEnabled(menu->isEnabled());
489 } else if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
490 m_platformItem->setText(action->text());
491 }
492}
493
494void PlatformItemWrapper::updateText()
495{
496 if (!m_platformItem) return;
497
498 if (UCMenu* menu = qobject_cast<UCMenu*>(m_target)) {
499 m_platformItem->setText(menu->text());
500 if (menu->platformMenu()) menu->platformMenu()->setText(menu->text());
501 } else if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
502 m_platformItem->setText(action->text());
503 }
504}
505
506void PlatformItemWrapper::updateIcon()
507{
508 if (!m_platformItem) return;
509
510 QIcon icon;
511 if (UCMenu* menu = qobject_cast<UCMenu*>(m_target)) {
512
513 if (!menu->iconSource().isEmpty()) {
514 icon = QIcon(menu->iconSource().path());
515 } else if (!menu->iconName().isEmpty()) {
516 icon = QIcon::fromTheme(menu->iconName());
517 }
518 if (menu->platformMenu()) menu->platformMenu()->setIcon(icon);
519
520 } else if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
521
522 if (!action->iconSource().isEmpty()) {
523 icon = QIcon(action->iconSource().path());
524 } else if (!action->iconName().isEmpty()) {
525 icon = QIcon::fromTheme(action->iconName());
526 }
527 }
528 m_platformItem->setIcon(icon);
529}
530
531
532inline QKeySequence sequenceFromVariant(const QVariant& variant)
533{
534 if (variant.type() == QVariant::Int) {
535 return static_cast<QKeySequence::StandardKey>(variant.toInt());
536 }
537 if (variant.type() == QVariant::String) {
538 return QKeySequence::fromString(variant.toString());
539 }
540 return QKeySequence();
541}
542
543void PlatformItemWrapper::updateShortcut()
544{
545 if (!m_platformItem) return;
546
547 if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
548 m_platformItem->setShortcut(sequenceFromVariant(action->shortcut()));
549 }
550}
551
552void PlatformItemWrapper::updateCheck()
553{
554 if (!m_platformItem) return;
555
556 if (UCAction* action = qobject_cast<UCAction*>(m_target)) {
557 bool checkable = action->parameterType() == UCAction::Bool;
558 m_platformItem->setCheckable(checkable);
559 m_platformItem->setChecked(checkable && action->state().toBool());
560 }
561}
562
563void PlatformItemWrapper::syncPlatformItem()
564{
565 updateVisible();
566 updateEnabled();
567 updateText();
568 updateIcon();
569 updateShortcut();
570 updateCheck();
571
572 if (m_menu->platformMenu() && m_platformItem) {
573 m_menu->platformMenu()->syncMenuItem(m_platformItem);
574 }
575}
576
577
578/*!
579 * \qmltype MenuGroup
580 * \inqmlmodule Ubuntu.Components
581 * \ingroup ubuntu
582 * \brief List of \l Action items for a menu which adds a separator between logical groups of menus.
583 *
584 * Example usage:
585 * \qml
586 * import QtQuick 2.4
587 * import Ubuntu.Components 1.3
588 * Menu {
589 * text: "Edit"
590 *
591 * MenuGroup {
592 * Action { text: "Undo" }
593 * Action { text: "Redo" }
594 * }
595 *
596 * MenuGroup {
597 * Action { text: "Cut" }
598 * Action { text: "Copy" }
599 * Action { text: "Paste" }
600 * }
601 *
602 * MenuGroup {
603 * Action { text: "Select All" }
604 * }
605 * }
606 * \endqml
607 */
608UCMenuGroup::UCMenuGroup(QObject *parent)
609 : UCActionList(parent)
610{
611}
612
613#include "moc_ucmenu.cpp"
0614
=== added file 'src/Ubuntu/Components/plugin/ucmenu.h'
--- src/Ubuntu/Components/plugin/ucmenu.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenu.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,108 @@
1/*
2 * Copyright 2016 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 */
17
18#ifndef UCMENU_H
19#define UCMENU_H
20
21#include <QQmlListProperty>
22#include <QUrl>
23#include <QLoggingCategory>
24#include <QPointer>
25#include <qqml.h>
26#include <QtQml/qqml.h>
27#include <private/qquickitemchangelistener_p.h>
28
29#include "ucaction.h"
30#include "ucactionlist.h"
31
32Q_DECLARE_LOGGING_CATEGORY(ucMenu);
33
34class QPlatformMenu;
35class QPlatformMenuItem;
36class QQuickItem;
37class UCMenuPrivate;
38class UCMenuAttached;
39class UCMenuBar;
40class UCAction;
41
42class UCMenu : public UCAction
43{
44 Q_OBJECT
45
46 Q_PROPERTY(QQmlListProperty<QObject> data READ data FINAL)
47 Q_CLASSINFO("DefaultProperty", "data")
48
49public:
50 explicit UCMenu(QObject *parent = 0);
51 ~UCMenu();
52
53 QQmlListProperty<QObject> data();
54
55 Q_INVOKABLE void appendObject(QObject* obj);
56 Q_INVOKABLE void insertObject(int index, QObject* obj);
57 Q_INVOKABLE void removeObject(QObject* obj);
58
59 QPlatformMenu *platformMenu() const;
60
61public Q_SLOTS:
62 void show(const QPoint& pt);
63 void dismiss();
64
65private:
66 Q_DISABLE_COPY(UCMenu)
67 Q_DECLARE_PRIVATE(UCMenu)
68 QScopedPointer<UCMenuPrivate> d_ptr;
69
70 Q_PRIVATE_SLOT(d_func(), void _q_updateEnabled())
71 Q_PRIVATE_SLOT(d_func(), void _q_updateText())
72 Q_PRIVATE_SLOT(d_func(), void _q_updateIcon())
73 Q_PRIVATE_SLOT(d_func(), void _q_updateVisible())
74};
75
76class UCMenuAttached : public QObject
77{
78 Q_OBJECT
79 Q_PROPERTY(UCMenu* parentMenu READ parentMenu NOTIFY parentMenuChanged)
80 Q_PROPERTY(UCMenuBar* menuBar READ menuBar NOTIFY parentMenuChanged)
81public:
82 explicit UCMenuAttached(QObject *parent);
83
84 static UCMenuAttached *qmlAttachedProperties(QObject *);
85
86 void setParentObject(QObject* o);
87
88 UCMenu *parentMenu() const;
89 UCMenuBar *menuBar() const;
90
91Q_SIGNALS:
92 void parentMenuChanged();
93 void menuBarChanged();
94
95private:
96 QPointer<QObject> m_parentObject;
97};
98QML_DECLARE_TYPEINFO(UCMenuAttached, QML_HAS_ATTACHED_PROPERTIES)
99
100
101class UCMenuGroup : public UCActionList
102{
103 Q_OBJECT
104public:
105 explicit UCMenuGroup(QObject *parent = 0);
106};
107
108#endif // UCMENU_H
0109
=== added file 'src/Ubuntu/Components/plugin/ucmenu_p.h'
--- src/Ubuntu/Components/plugin/ucmenu_p.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenu_p.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,83 @@
1/*
2 * Copyright 2016 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 */
17
18#ifndef UCMENU_P
19#define UCMENU_P
20
21#include <private/qquickitemchangelistener_p.h>
22#include "ucmenu.h"
23
24class QObject;
25class UCAction;
26class QQmlComponent;
27class UCMenu;
28class PlatformItemWrapper;
29
30class UCMenuPrivate
31{
32 Q_DECLARE_PUBLIC(UCMenu)
33public:
34 UCMenuPrivate(UCMenu *qq);
35 virtual ~UCMenuPrivate();
36
37 void insertObject(int index, QObject *obj);
38 void removeObject(QObject *obj);
39
40 void _q_updateEnabled();
41 void _q_updateText();
42 void _q_updateIcon();
43 void _q_updateVisible();
44
45 static void data_append(QQmlListProperty<QObject> *prop, QObject *o);
46 static int data_count(QQmlListProperty<QObject> *prop);
47 static QObject *data_at(QQmlListProperty<QObject> *prop, int index);
48 static void data_clear(QQmlListProperty<QObject> *prop);
49
50 UCMenu* q_ptr;
51 QPlatformMenu* m_platformMenu;
52 UCAction* m_action;
53
54 QHash<QObject*, PlatformItemWrapper*> m_platformItems;
55 QVector<QObject*> m_data;
56};
57
58class PlatformItemWrapper : public QObject
59{
60 Q_OBJECT
61public:
62 PlatformItemWrapper(QObject *target, UCMenu* menu);
63
64 void insert(int index);
65 void remove();
66
67public Q_SLOTS:
68 void updateVisible();
69 void updateEnabled();
70 void updateText();
71 void updateIcon();
72 void updateShortcut();
73 void updateCheck();
74
75private:
76 void syncPlatformItem();
77
78 QObject* m_target;
79 UCMenu* m_menu;
80 QPlatformMenuItem* m_platformItem;
81};
82
83#endif // UCMENU_P
084
=== added file 'src/Ubuntu/Components/plugin/ucmenubar.cpp'
--- src/Ubuntu/Components/plugin/ucmenubar.cpp 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenubar.cpp 2016-06-07 14:25:30 +0000
@@ -0,0 +1,299 @@
1/*
2 * Copyright 2016 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 */
17
18#include "ucmenubar.h"
19#include "ucmenubar_p.h"
20
21// Qt
22#include <QQuickItem>
23#include <QQuickWindow>
24#include <private/qguiapplication_p.h>
25#include <QtGui/qpa/qplatformtheme.h>
26#include <QtGui/qpa/qplatformmenu.h>
27
28UCMenuBarPrivate::UCMenuBarPrivate(UCMenuBar *qq)
29 : q_ptr(qq)
30{
31 m_platformBar = QGuiApplicationPrivate::platformTheme()->createPlatformMenuBar();
32}
33
34void UCMenuBarPrivate::insertMenu(int index, UCMenu* menu)
35{
36 Q_Q(UCMenuBar);
37 UCMenu* prevMenu = m_menus.count() > index ? m_menus[index] : nullptr;
38
39 m_menus.insert(index, menu);
40
41 UCMenuAttached *attached = qobject_cast<UCMenuAttached*>(qmlAttachedPropertiesObject<UCMenuAttached>(menu));
42 if (attached) {
43 attached->setParentObject(q);
44 }
45
46 if (m_platformBar && menu->platformMenu()) {
47 m_platformBar->insertMenu(menu->platformMenu(), prevMenu ? prevMenu->platformMenu() : nullptr);
48 }
49}
50
51void UCMenuBarPrivate::menu_append(QQmlListProperty<UCMenu> *prop, UCMenu *o)
52{
53 UCMenuBarPrivate *q = static_cast<UCMenuBarPrivate *>(prop->data);
54 // menubar is the menus parent
55 o->setParent(prop->object);
56 q->insertMenu(q->m_menus.count(), o);
57}
58
59int UCMenuBarPrivate::menu_count(QQmlListProperty<UCMenu> *prop)
60{
61 UCMenuBarPrivate *p = static_cast<UCMenuBarPrivate *>(prop->data);
62 return p->m_menus.count();
63}
64
65UCMenu *UCMenuBarPrivate::menu_at(QQmlListProperty<UCMenu> *prop, int index)
66{
67 UCMenuBarPrivate *p = static_cast<UCMenuBarPrivate *>(prop->data);
68 return p->m_menus.value(index);
69}
70
71void UCMenuBarPrivate::menu_clear(QQmlListProperty<UCMenu> *prop)
72{
73 UCMenuBarPrivate *p = static_cast<UCMenuBarPrivate *>(prop->data);
74 p->m_menus.clear();
75}
76
77/*!
78 * \qmltype MenuBar
79 * \instantiates UCMenuBar
80 * \inqmlmodule Ubuntu.Components 1.3
81 * \ingroup ubuntu
82 * \brief MenuBar defines an application menu bar structure
83 *
84 * Example usage:
85 * \qml
86 * import QtQuick 2.4
87 * import Ubuntu.Components 1.3
88 * MainView {
89 * MenuBar {
90 * Menu {
91 * text: "_File"
92 *
93 * MenuItem {
94 * text: "_New"
95 * shortcut: "Ctrl+N"
96 * }
97 *
98 * MenuItem {
99 * text: "_Open"
100 * shortcut: "Ctrl+O"
101 * }
102 *
103 * MenuSeparator {}
104 *
105 * MenuItem {
106 * action: exitAction
107 * }
108 * }
109 *
110 * Menu {
111 * text: "_Edit"
112 *
113 * MenuItem {
114 * text: "_Undo"
115 * iconSource: "image://theme/undo"
116 * }
117 * }
118 * Menu {
119 * text: "_Window"
120 *
121 * MenuItem {
122 * text: "Fullscreen"
123 * checkable: true
124 * checked: false
125 * }
126 * }
127 * }
128 * Action {
129 * id: boundAction
130 * text: "E_xit"
131 * onTriggered: {
132 * Qt.quit();
133 * }
134 * }
135 * }
136 * \endqml
137 */
138UCMenuBar::UCMenuBar(QObject *parent)
139 : QObject(parent)
140 , d_ptr(new UCMenuBarPrivate(this))
141{
142}
143
144UCMenuBar::~UCMenuBar()
145{
146}
147
148/*!
149 * \qmlmethod void MenuBar::appendMenu(Menu menu)
150 * Append a Menu to the MenuBar
151 */
152void UCMenuBar::appendMenu(UCMenu *menu)
153{
154 Q_D(UCMenuBar);
155 insertMenu(d->m_menus.count(), menu);
156}
157
158/*!
159 * \qmlmethod void MenuBar::insertMenu(int index, Menu menu)
160 * Insert a Menu to the MenuBar at the specified position
161 */
162void UCMenuBar::insertMenu(int index, UCMenu *menu)
163{
164 Q_D(UCMenuBar);
165 if (!menu) return;
166
167 d->insertMenu(index, menu);
168 Q_EMIT menusChanged();
169}
170
171/*!
172 * \qmlmethod void MenuBar::removeMenu(Menu menu)
173 * Remove a Menu from the MenuBar
174 */
175void UCMenuBar::removeMenu(UCMenu *menu)
176{
177 Q_D(UCMenuBar);
178 if (!menu) return;
179
180 if (d->m_menus.removeOne(menu)) {
181 Q_EMIT menusChanged();
182 }
183}
184/*!
185 * \qmlproperty list<Menu> MenuBar::menus
186 * \default
187 * List of Menus in this MenuBar.
188 */
189QQmlListProperty<UCMenu> UCMenuBar::menus()
190{
191 Q_D(UCMenuBar);
192 return QQmlListProperty<UCMenu>(this, d,
193 &UCMenuBarPrivate::menu_append,
194 &UCMenuBarPrivate::menu_count,
195 &UCMenuBarPrivate::menu_at,
196 &UCMenuBarPrivate::menu_clear);
197}
198
199QPlatformMenuBar *UCMenuBar::platformMenuBar() const
200{
201 Q_D(const UCMenuBar);
202 return d->m_platformBar;
203}
204
205void UCMenuBar::classBegin()
206{
207}
208
209void UCMenuBar::componentComplete()
210{
211 Q_D(UCMenuBar);
212
213 auto parentItem = qobject_cast<QQuickItem*>(parent());
214 if (parentItem && d->m_platformBar) {
215 d->m_platformBar->handleReparent(parentItem->window());
216 }
217}
218
219PlatformMenuWrapper::PlatformMenuWrapper(UCMenu *target, UCMenuBar* bar)
220 : QObject(bar)
221 , m_bar(bar)
222 , m_target(target)
223 , m_platformItem(target->platformMenu() ? target->platformMenu()->createMenuItem() : Q_NULLPTR)
224{
225 connect(m_target, &QObject::destroyed, this, &QObject::deleteLater);
226
227 connect(m_target, &UCMenu::visibleChanged, this, &PlatformMenuWrapper::updateVisible);
228 connect(m_target, &UCMenu::textChanged, this, &PlatformMenuWrapper::updateText);
229 connect(m_target, &UCMenu::enabledChanged, this, &PlatformMenuWrapper::updateEnabled);
230 connect(m_target, &UCMenu::iconSourceChanged, this, &PlatformMenuWrapper::updateIcon);
231 connect(m_target, &UCMenu::iconNameChanged, this, &PlatformMenuWrapper::updateIcon);
232
233 if (m_platformItem) {
234 m_platformItem->setMenu(target->platformMenu());
235 }
236 syncPlatformItem();
237}
238
239void PlatformMenuWrapper::insert(int index)
240{
241 Q_UNUSED(index);
242
243 auto platformBar = m_bar->platformMenuBar();
244 if (!platformBar) return;
245 auto platformMenu = m_target->platformMenu();
246 if (!platformMenu) return;
247
248 platformBar->insertMenu(platformMenu, Q_NULLPTR);
249}
250
251void PlatformMenuWrapper::remove()
252{
253 auto platformBar = m_bar->platformMenuBar();
254 if (!platformBar) return;
255 auto platformMenu = m_target->platformMenu();
256 if (!platformMenu) return;
257
258 platformBar->removeMenu(platformMenu);
259}
260
261void PlatformMenuWrapper::updateVisible()
262{
263 if (m_platformItem) m_platformItem->setVisible(m_target->visible());
264 if (m_target->platformMenu()) m_target->platformMenu()->setVisible(m_target->visible());
265}
266
267void PlatformMenuWrapper::updateEnabled()
268{
269 if (!m_platformItem) m_platformItem->setEnabled(m_target->isEnabled());
270 if (m_target->platformMenu()) m_target->platformMenu()->setEnabled(m_target->isEnabled());
271}
272
273void PlatformMenuWrapper::updateText()
274{
275 if (!m_platformItem) m_platformItem->setText(m_target->text());
276 if (m_target->platformMenu()) m_target->platformMenu()->setText(m_target->text());
277}
278
279void PlatformMenuWrapper::updateIcon()
280{
281 QIcon icon;
282 if (!m_target->iconSource().isEmpty()) {
283 icon = QIcon(m_target->iconSource().path());
284 } else if (!m_target->iconName().isEmpty()) {
285 icon = QIcon::fromTheme(m_target->iconName());
286 }
287 if (m_target->platformMenu()) m_target->platformMenu()->setIcon(icon);
288 if (!m_platformItem) m_platformItem->setIcon(icon);
289}
290
291void PlatformMenuWrapper::syncPlatformItem()
292{
293 updateVisible();
294 updateEnabled();
295 updateText();
296 updateIcon();
297}
298
299#include "moc_ucmenubar.cpp"
0300
=== added file 'src/Ubuntu/Components/plugin/ucmenubar.h'
--- src/Ubuntu/Components/plugin/ucmenubar.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenubar.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,60 @@
1/*
2 * Copyright 2016 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 */
17
18#ifndef UCMENUBAR_H
19#define UCMENUBAR_H
20
21#include "ucmenu.h"
22
23#include <QQmlParserStatus>
24
25class UCMenuBarPrivate;
26class QPlatformMenuBar;
27
28class UCMenuBar : public QObject, public QQmlParserStatus
29{
30 Q_OBJECT
31 Q_INTERFACES(QQmlParserStatus)
32
33 Q_PROPERTY(QQmlListProperty<UCMenu> menus READ menus NOTIFY menusChanged FINAL)
34 Q_CLASSINFO("DefaultProperty", "menus")
35
36public:
37 explicit UCMenuBar(QObject *parent = 0);
38 ~UCMenuBar();
39
40 Q_INVOKABLE void appendMenu(UCMenu *menu);
41 Q_INVOKABLE void insertMenu(int index, UCMenu *menu);
42 Q_INVOKABLE void removeMenu(UCMenu *menu);
43
44 QQmlListProperty<UCMenu> menus();
45
46 QPlatformMenuBar *platformMenuBar() const;
47
48 void classBegin() Q_DECL_OVERRIDE;
49 void componentComplete() Q_DECL_OVERRIDE;
50
51Q_SIGNALS:
52 void menusChanged();
53
54private:
55 Q_DISABLE_COPY(UCMenuBar)
56 Q_DECLARE_PRIVATE(UCMenuBar)
57 QScopedPointer<UCMenuBarPrivate> d_ptr;
58};
59
60#endif // UCMENUBAR_H
061
=== added file 'src/Ubuntu/Components/plugin/ucmenubar_p.h'
--- src/Ubuntu/Components/plugin/ucmenubar_p.h 1970-01-01 00:00:00 +0000
+++ src/Ubuntu/Components/plugin/ucmenubar_p.h 2016-06-07 14:25:30 +0000
@@ -0,0 +1,68 @@
1/*
2 * Copyright 2016 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 */
17
18#ifndef UCMENUBAR_P
19#define UCMENUBAR_P
20
21#include "ucmenubar.h"
22
23class QPlatformMenuBar;
24
25class UCMenuBarPrivate : public QQuickItemChangeListener
26{
27 Q_DECLARE_PUBLIC(UCMenuBar)
28public:
29 UCMenuBarPrivate(UCMenuBar *qq);
30
31 void insertMenu(int index, UCMenu *menu);
32
33 static void menu_append(QQmlListProperty<UCMenu> *prop, UCMenu *o);
34 static int menu_count(QQmlListProperty<UCMenu> *prop);
35 static UCMenu *menu_at(QQmlListProperty<UCMenu> *prop, int index);
36 static void menu_clear(QQmlListProperty<UCMenu> *prop);
37
38 UCMenuBar* q_ptr;
39 QPlatformMenuBar* m_platformBar;
40 QVector<UCMenu*> m_menus;
41};
42
43class PlatformMenuWrapper : public QObject
44{
45 Q_OBJECT
46public:
47 PlatformMenuWrapper(UCMenu *target, UCMenuBar *bar);
48
49 void insert(int index);
50 void remove();
51
52public Q_SLOTS:
53 void updateVisible();
54 void updateEnabled();
55 void updateText();
56 void updateIcon();
57 void updateShortcut();
58
59private:
60 void syncPlatformItem();
61
62 UCMenuBar* m_bar;
63 UCMenu* m_target;
64 QPlatformMenuItem* m_platformItem;
65};
66
67#endif // UCMENUBAR_P
68
069
=== modified file 'src/Ubuntu/Components/qmldir'
--- src/Ubuntu/Components/qmldir 2016-02-16 11:39:32 +0000
+++ src/Ubuntu/Components/qmldir 2016-06-07 14:25:30 +0000
@@ -1,6 +1,5 @@
1module Ubuntu.Components1module Ubuntu.Components
2plugin UbuntuComponents2plugin UbuntuComponents
3ActionList 0.1 1.2/ActionList.qml
4ToolbarItems 0.1 1.2/ToolbarItems.qml3ToolbarItems 0.1 1.2/ToolbarItems.qml
5ToolbarButton 0.1 1.2/ToolbarButton.qml4ToolbarButton 0.1 1.2/ToolbarButton.qml
6MainView 0.1 1.2/MainView.qml5MainView 0.1 1.2/MainView.qml
@@ -40,7 +39,6 @@
40DateUtils 0.1 1.2/dateUtils.js39DateUtils 0.1 1.2/dateUtils.js
4140
42#version 1.041#version 1.0
43ActionList 1.0 1.2/ActionList.qml
44ToolbarItems 1.0 1.2/ToolbarItems.qml42ToolbarItems 1.0 1.2/ToolbarItems.qml
45ToolbarButton 1.0 1.2/ToolbarButton.qml43ToolbarButton 1.0 1.2/ToolbarButton.qml
46MainView 1.0 1.2/MainView.qml44MainView 1.0 1.2/MainView.qml
@@ -95,7 +93,6 @@
95#################################################93#################################################
96#version 1.394#version 1.3
97ActionBar 1.3 1.3/ActionBar.qml95ActionBar 1.3 1.3/ActionBar.qml
98ActionList 1.3 1.3/ActionList.qml
99AdaptivePageLayout 1.3 1.3/AdaptivePageLayout.qml96AdaptivePageLayout 1.3 1.3/AdaptivePageLayout.qml
100PageColumnsLayout 1.3 1.3/PageColumnsLayout.qml97PageColumnsLayout 1.3 1.3/PageColumnsLayout.qml
101PageColumn 1.3 1.3/PageColumn.qml98PageColumn 1.3 1.3/PageColumn.qml

Subscribers

People subscribed via source and target branches

to status/vote changes: