Add a prop and method for aligning the menu against a corner of its visual parent.
REVIEW:127646
This commit is contained in:
parent
17cea8059e
commit
9bd7e4ce5f
@ -22,11 +22,13 @@
|
|||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
#include <QQuickItem>
|
#include <QQuickItem>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
#include "plasmacomponentsplugin.h"
|
#include "plasmacomponentsplugin.h"
|
||||||
QMenuProxy::QMenuProxy(QObject *parent)
|
QMenuProxy::QMenuProxy(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_status(DialogStatus::Closed)
|
m_status(DialogStatus::Closed),
|
||||||
|
m_placement(Plasma::Types::LeftPosedTopAlignedPopup)
|
||||||
{
|
{
|
||||||
m_menu = new QMenu(0);
|
m_menu = new QMenu(0);
|
||||||
connect(m_menu, &QMenu::triggered, this, &QMenuProxy::itemTriggered);
|
connect(m_menu, &QMenu::triggered, this, &QMenuProxy::itemTriggered);
|
||||||
@ -116,6 +118,20 @@ void QMenuProxy::setTransientParent(QWindow *parent)
|
|||||||
emit transientParentChanged();
|
emit transientParentChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Plasma::Types::PopupPlacement QMenuProxy::placement() const
|
||||||
|
{
|
||||||
|
return m_placement;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMenuProxy::setPlacement(Plasma::Types::PopupPlacement placement)
|
||||||
|
{
|
||||||
|
if (m_placement != placement) {
|
||||||
|
m_placement = placement;
|
||||||
|
|
||||||
|
emit placementChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int QMenuProxy::minimumWidth() const
|
int QMenuProxy::minimumWidth() const
|
||||||
{
|
{
|
||||||
return m_menu->minimumWidth();
|
return m_menu->minimumWidth();
|
||||||
@ -222,10 +238,10 @@ void QMenuProxy::itemTriggered(QAction *action)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QMenuProxy::open(int x, int y)
|
void QMenuProxy::rebuildMenu()
|
||||||
{
|
{
|
||||||
qDebug() << "opening menu at " << x << y;
|
|
||||||
m_menu->clear();
|
m_menu->clear();
|
||||||
|
|
||||||
foreach (QMenuItem *item, m_items) {
|
foreach (QMenuItem *item, m_items) {
|
||||||
if (item->section()) {
|
if (item->section()) {
|
||||||
if (!item->isVisible()) {
|
if (!item->isVisible()) {
|
||||||
@ -240,18 +256,104 @@ void QMenuProxy::open(int x, int y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickItem *parentItem;
|
m_menu->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMenuProxy::open(int x, int y)
|
||||||
|
{
|
||||||
|
qDebug() << "opening menu at " << x << y;
|
||||||
|
|
||||||
|
QQuickItem *parentItem = nullptr;
|
||||||
|
|
||||||
if (m_visualParent) {
|
if (m_visualParent) {
|
||||||
parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
|
parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
|
||||||
} else {
|
} else {
|
||||||
parentItem = qobject_cast<QQuickItem *>(parent());
|
parentItem = qobject_cast<QQuickItem *>(parent());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!parentItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuildMenu();
|
||||||
|
|
||||||
QPointF pos = parentItem->mapToScene(QPointF(x, y));
|
QPointF pos = parentItem->mapToScene(QPointF(x, y));
|
||||||
|
|
||||||
if (parentItem->window() && parentItem->window()->screen()) {
|
if (parentItem->window() && parentItem->window()->screen()) {
|
||||||
pos = parentItem->window()->mapToGlobal(pos.toPoint());
|
pos = parentItem->window()->mapToGlobal(pos.toPoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
m_menu->popup(pos.toPoint());
|
openInternal(pos.toPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void QMenuProxy::openRelative()
|
||||||
|
{
|
||||||
|
QQuickItem *parentItem = nullptr;
|
||||||
|
|
||||||
|
if (m_visualParent) {
|
||||||
|
parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
|
||||||
|
} else {
|
||||||
|
parentItem = qobject_cast<QQuickItem *>(parent());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parentItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rebuildMenu();
|
||||||
|
|
||||||
|
QPointF pos;
|
||||||
|
|
||||||
|
using namespace Plasma;
|
||||||
|
|
||||||
|
switch(m_placement) {
|
||||||
|
case Types::TopPosedLeftAlignedPopup:
|
||||||
|
case Types::LeftPosedTopAlignedPopup: {
|
||||||
|
pos = parentItem->mapToScene(QPointF(0, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Types::TopPosedRightAlignedPopup:
|
||||||
|
case Types::RightPosedTopAlignedPopup: {
|
||||||
|
pos = parentItem->mapToScene(QPointF(parentItem->width(), 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Types::LeftPosedBottomAlignedPopup:
|
||||||
|
case Types::BottomPosedLeftAlignedPopup: {
|
||||||
|
pos = parentItem->mapToScene(QPointF(0, parentItem->height()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Types::BottomPosedRightAlignedPopup:
|
||||||
|
case Types::RightPosedBottomAlignedPopup: {
|
||||||
|
pos = parentItem->mapToScene(QPointF(parentItem->width(), parentItem->height()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parentItem->window() && parentItem->window()->screen()) {
|
||||||
|
pos = parentItem->window()->mapToGlobal(pos.toPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
QScreen *screen = parentItem->window()->screen();
|
||||||
|
|
||||||
|
if (screen) {
|
||||||
|
if (pos.x() + m_menu->width() > screen->geometry().width()) {
|
||||||
|
pos.setX(pos.x() - m_menu->width());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos.y() + m_menu->height() > screen->geometry().height()) {
|
||||||
|
pos.setY(pos.y() - m_menu->height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openInternal(pos.toPoint());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QMenuProxy::openInternal(QPoint pos)
|
||||||
|
{
|
||||||
|
m_menu->popup(pos);
|
||||||
m_status = DialogStatus::Open;
|
m_status = DialogStatus::Open;
|
||||||
emit statusChanged();
|
emit statusChanged();
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <QQmlListProperty>
|
#include <QQmlListProperty>
|
||||||
#include "qmenuitem.h"
|
#include "qmenuitem.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
#include "plasma.h"
|
||||||
|
|
||||||
class QDeclarativeItem;
|
class QDeclarativeItem;
|
||||||
|
|
||||||
@ -82,6 +83,11 @@ class QMenuProxy : public QObject
|
|||||||
Q_PROPERTY(QObject *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged())
|
Q_PROPERTY(QObject *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged())
|
||||||
Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged)
|
Q_PROPERTY(DialogStatus::Status status READ status NOTIFY statusChanged)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default placement for the menu.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY(Plasma::Types::PopupPlacement placement READ placement WRITE setPlacement NOTIFY placementChanged)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A minimum width for the menu.
|
* A minimum width for the menu.
|
||||||
*/
|
*/
|
||||||
@ -102,6 +108,9 @@ public:
|
|||||||
QWindow *transientParent();
|
QWindow *transientParent();
|
||||||
void setTransientParent(QWindow *parent);
|
void setTransientParent(QWindow *parent);
|
||||||
|
|
||||||
|
Plasma::Types::PopupPlacement placement() const;
|
||||||
|
void setPlacement(Plasma::Types::PopupPlacement placement);
|
||||||
|
|
||||||
int minimumWidth() const;
|
int minimumWidth() const;
|
||||||
void setMinimumWidth(int width);
|
void setMinimumWidth(int width);
|
||||||
|
|
||||||
@ -109,7 +118,10 @@ public:
|
|||||||
* This opens the menu at position x,y on the given visualParent. By default x and y are set to 0
|
* This opens the menu at position x,y on the given visualParent. By default x and y are set to 0
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void open(int x = 0, int y = 0);
|
Q_INVOKABLE void open(int x = 0, int y = 0);
|
||||||
//Q_INVOKABLE void open();
|
/**
|
||||||
|
* This opens the menu at the specified placement relative to the visualParent.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void openRelative();
|
||||||
/**
|
/**
|
||||||
* This closes the menu
|
* This closes the menu
|
||||||
*/
|
*/
|
||||||
@ -142,6 +154,7 @@ Q_SIGNALS:
|
|||||||
void statusChanged();
|
void statusChanged();
|
||||||
void visualParentChanged();
|
void visualParentChanged();
|
||||||
void transientParentChanged();
|
void transientParentChanged();
|
||||||
|
void placementChanged();
|
||||||
void minimumWidthChanged();
|
void minimumWidthChanged();
|
||||||
void triggered(QMenuItem *item);
|
void triggered(QMenuItem *item);
|
||||||
void triggeredIndex(int index);
|
void triggeredIndex(int index);
|
||||||
@ -150,10 +163,14 @@ private Q_SLOTS:
|
|||||||
void itemTriggered(QAction *item);
|
void itemTriggered(QAction *item);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void rebuildMenu();
|
||||||
|
void openInternal(QPoint pos);
|
||||||
|
|
||||||
QList<QMenuItem *> m_items;
|
QList<QMenuItem *> m_items;
|
||||||
QMenu *m_menu;
|
QMenu *m_menu;
|
||||||
DialogStatus::Status m_status;
|
DialogStatus::Status m_status;
|
||||||
QWeakPointer<QObject> m_visualParent;
|
QWeakPointer<QObject> m_visualParent;
|
||||||
|
Plasma::Types::PopupPlacement m_placement;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //QMENU_PROXY_H
|
#endif //QMENU_PROXY_H
|
||||||
|
Loading…
Reference in New Issue
Block a user