From ecef73ddb0c6038f6e0208121cfb8786c2cab7f2 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Thu, 1 Jun 2017 20:09:44 +0200 Subject: QQuickMenu: add support for declaring Actions [ChangeLog][Controls][Menu] Added support for declaring Actions. The new "delegate" property is used to define a Component that is used to create menu items that present the actions. Change-Id: If26f38f6910aa5592879703429a2b418193d5710 Reviewed-by: Mitch Curtis --- src/quicktemplates2/qquickmenu.cpp | 80 +++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) (limited to 'src/quicktemplates2/qquickmenu.cpp') diff --git a/src/quicktemplates2/qquickmenu.cpp b/src/quicktemplates2/qquickmenu.cpp index 726a0fca..63d5d00c 100644 --- a/src/quicktemplates2/qquickmenu.cpp +++ b/src/quicktemplates2/qquickmenu.cpp @@ -39,11 +39,14 @@ #include "qquickmenuitem_p.h" #include "qquickcontrol_p_p.h" #include "qquickpopupitem_p_p.h" +#include "qquickaction_p.h" #include #include #include #include +#include +#include #include #include #include @@ -129,6 +132,17 @@ QT_BEGIN_NAMESPACE } \endcode + Since QtQuick.Controls 2.3 (Qt 5.10), it is also possible to declare + Action objects inside Menu: + + \code + Menu { + Action { text: "Cut" } + Action { text: "Copy" } + Action { text: "Paste" } + } + \endcode + Typically, menu items are statically declared as children of the menu, but Menu also provides API to \l {addItem}{add}, \l {insertItem}{insert}, \l {moveItem}{move} and \l {removeItem}{remove} items dynamically. The @@ -143,7 +157,8 @@ QT_BEGIN_NAMESPACE QQuickMenuPrivate::QQuickMenuPrivate() : contentItem(nullptr), - contentModel(nullptr) + contentModel(nullptr), + delegate(nullptr) { Q_Q(QQuickMenu); contentModel = new QQmlObjectModel(q); @@ -196,6 +211,30 @@ void QQuickMenuPrivate::removeItem(int index, QQuickItem *item) } } +QQuickItem *QQuickMenuPrivate::createItem(QQuickAction *action) +{ + Q_Q(QQuickMenu); + if (!delegate) + return nullptr; + + QQmlContext *creationContext = delegate->creationContext(); + if (!creationContext) + creationContext = qmlContext(q); + QQmlContext *context = new QQmlContext(creationContext, q); + context->setContextObject(q); + + QObject *object = delegate->beginCreate(context); + if (QQuickItem *item = qobject_cast(object)) { + if (QQuickAbstractButton *button = qobject_cast(object)) + button->setAction(action); + delegate->completeCreate(); + return item; + } + + delete object; + return nullptr; +} + void QQuickMenuPrivate::resizeItem(QQuickItem *item) { if (!item || !contentItem) @@ -293,7 +332,13 @@ void QQuickMenuPrivate::contentData_append(QQmlListProperty *prop, QObj { QQuickMenuPrivate *p = static_cast(prop->data); QQuickMenu *q = static_cast(prop->object); + QQuickItem *item = qobject_cast(obj); + if (!item) { + if (QQuickAction *action = qobject_cast(obj)) + item = p->createItem(action); + } + if (item) { if (QQuickItemPrivate::get(item)->isTransparentForPositioner()) { QQuickItemPrivate::get(item)->addItemChangeListener(p, QQuickItemPrivate::SiblingOrder); @@ -491,6 +536,39 @@ void QQuickMenu::setTitle(QString &title) emit titleChanged(); } +/*! + \since QtQuick.Controls 2.3 (Qt 5.10) + \qmlproperty Component QtQuick.Controls::Menu::delegate + + This property holds the component that is used to create items + to present actions. + + \code + Menu { + Action { text: "Cut" } + Action { text: "Copy" } + Action { text: "Paste" } + } + \endcode + + \sa Action +*/ +QQmlComponent *QQuickMenu::delegate() const +{ + Q_D(const QQuickMenu); + return d->delegate; +} + +void QQuickMenu::setDelegate(QQmlComponent *delegate) +{ + Q_D(QQuickMenu); + if (d->delegate == delegate) + return; + + d->delegate = delegate; + emit delegateChanged(); +} + /*! \since QtQuick.Controls 2.3 (Qt 5.10) \qmlmethod void QtQuick.Controls::Menu::popup(MenuItem item = null) -- cgit v1.2.3