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 <QQuickWindow>
|
||||
#include <QQuickItem>
|
||||
#include <QScreen>
|
||||
|
||||
#include "plasmacomponentsplugin.h"
|
||||
QMenuProxy::QMenuProxy(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_status(DialogStatus::Closed)
|
||||
m_status(DialogStatus::Closed),
|
||||
m_placement(Plasma::Types::LeftPosedTopAlignedPopup)
|
||||
{
|
||||
m_menu = new QMenu(0);
|
||||
connect(m_menu, &QMenu::triggered, this, &QMenuProxy::itemTriggered);
|
||||
@ -116,6 +118,20 @@ void QMenuProxy::setTransientParent(QWindow *parent)
|
||||
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
|
||||
{
|
||||
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();
|
||||
|
||||
foreach (QMenuItem *item, m_items) {
|
||||
if (item->section()) {
|
||||
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) {
|
||||
parentItem = qobject_cast<QQuickItem *>(m_visualParent.data());
|
||||
} else {
|
||||
parentItem = qobject_cast<QQuickItem *>(parent());
|
||||
}
|
||||
|
||||
if (!parentItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
rebuildMenu();
|
||||
|
||||
QPointF pos = parentItem->mapToScene(QPointF(x, y));
|
||||
|
||||
if (parentItem->window() && parentItem->window()->screen()) {
|
||||
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;
|
||||
emit statusChanged();
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <QQmlListProperty>
|
||||
#include "qmenuitem.h"
|
||||
#include "enums.h"
|
||||
#include "plasma.h"
|
||||
|
||||
class QDeclarativeItem;
|
||||
|
||||
@ -82,6 +83,11 @@ class QMenuProxy : public QObject
|
||||
Q_PROPERTY(QObject *visualParent READ visualParent WRITE setVisualParent NOTIFY visualParentChanged())
|
||||
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.
|
||||
*/
|
||||
@ -102,6 +108,9 @@ public:
|
||||
QWindow *transientParent();
|
||||
void setTransientParent(QWindow *parent);
|
||||
|
||||
Plasma::Types::PopupPlacement placement() const;
|
||||
void setPlacement(Plasma::Types::PopupPlacement placement);
|
||||
|
||||
int minimumWidth() const;
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -142,6 +154,7 @@ Q_SIGNALS:
|
||||
void statusChanged();
|
||||
void visualParentChanged();
|
||||
void transientParentChanged();
|
||||
void placementChanged();
|
||||
void minimumWidthChanged();
|
||||
void triggered(QMenuItem *item);
|
||||
void triggeredIndex(int index);
|
||||
@ -150,10 +163,14 @@ private Q_SLOTS:
|
||||
void itemTriggered(QAction *item);
|
||||
|
||||
private:
|
||||
void rebuildMenu();
|
||||
void openInternal(QPoint pos);
|
||||
|
||||
QList<QMenuItem *> m_items;
|
||||
QMenu *m_menu;
|
||||
DialogStatus::Status m_status;
|
||||
QWeakPointer<QObject> m_visualParent;
|
||||
Plasma::Types::PopupPlacement m_placement;
|
||||
};
|
||||
|
||||
#endif //QMENU_PROXY_H
|
||||
|
Loading…
Reference in New Issue
Block a user