[Menu] Improve available space correction for openRelative
There was already some kind of detection and adjustment if there is not enough space for the popup available. Do some more work by placing the popup according to its PopupPlacement enum. Do this also if the popup breaks the top or left boundary of the screen. Also fixes some minor problems: * TopPosedRightAlignedPopup was the same as RightPosedTopAlignedPopup, but in the first case the menu should be on top of parentItem * LeftPosedTopAlignedPopup was above parentItem and not left of it * Small documentation error Reviewers: #plasma, hein Subscribers: plasma-devel, #frameworks Tags: #frameworks, #plasma Differential Revision: https://phabricator.kde.org/D4867
This commit is contained in:
parent
2b3e8dfe86
commit
daee27f096
|
@ -340,29 +340,65 @@ Q_INVOKABLE void QMenuProxy::openRelative()
|
|||
|
||||
using namespace Plasma;
|
||||
|
||||
auto boundaryCorrection = [&pos, this, parentItem](int hDelta, int vDelta) {
|
||||
if (!parentItem->window()) {
|
||||
return;
|
||||
}
|
||||
QScreen *screen = parentItem->window()->screen();
|
||||
if (!screen) {
|
||||
return;
|
||||
}
|
||||
QRect geo = screen->geometry();
|
||||
pos = parentItem->window()->mapToGlobal(pos.toPoint());
|
||||
|
||||
if (pos.x() < geo.x()) {
|
||||
pos.setX(pos.x() + hDelta);
|
||||
}
|
||||
if (pos.y() < geo.y()) {
|
||||
pos.setY(pos.y() + vDelta);
|
||||
}
|
||||
|
||||
if (geo.x() + geo.width() < pos.x() + this->m_menu->width()) {
|
||||
pos.setX(pos.x() + hDelta);
|
||||
}
|
||||
if (geo.y() + geo.height() < pos.y() + this->m_menu->height()) {
|
||||
pos.setY(pos.y() + vDelta);
|
||||
}
|
||||
};
|
||||
|
||||
switch(m_placement) {
|
||||
case Types::TopPosedLeftAlignedPopup: {
|
||||
pos = parentItem->mapToScene(QPointF(0, -m_menu->height()));
|
||||
boundaryCorrection(- m_menu->width() + parentItem->width(), m_menu->height() + parentItem->height());
|
||||
break;
|
||||
}
|
||||
case Types::LeftPosedTopAlignedPopup: {
|
||||
pos = parentItem->mapToScene(QPointF(0, 0));
|
||||
pos = parentItem->mapToScene(QPointF(-m_menu->width(), 0));
|
||||
boundaryCorrection(m_menu->width() + parentItem->width(), - m_menu->height() + parentItem->height());
|
||||
break;
|
||||
}
|
||||
case Types::TopPosedRightAlignedPopup:
|
||||
pos = parentItem->mapToScene(QPointF(parentItem->width(), -m_menu->height()));
|
||||
boundaryCorrection(- m_menu->width() + parentItem->width(), m_menu->height()); // in top right corner this will cover the parent item
|
||||
break;
|
||||
case Types::RightPosedTopAlignedPopup: {
|
||||
pos = parentItem->mapToScene(QPointF(parentItem->width(), 0));
|
||||
boundaryCorrection(- m_menu->width() - parentItem->width(), m_menu->height() + parentItem->height());
|
||||
break;
|
||||
}
|
||||
case Types::LeftPosedBottomAlignedPopup:
|
||||
pos = parentItem->mapToScene(QPointF(-m_menu->width(), parentItem->height()));
|
||||
boundaryCorrection(m_menu->width(), - m_menu->height()); // in lower left corner this will cover the parent item
|
||||
break;
|
||||
case Types::BottomPosedLeftAlignedPopup: {
|
||||
pos = parentItem->mapToScene(QPointF(0, parentItem->height()));
|
||||
boundaryCorrection(- m_menu->width() + parentItem->width(), - m_menu->height() - parentItem->height());
|
||||
break;
|
||||
}
|
||||
case Types::BottomPosedRightAlignedPopup:
|
||||
case Types::RightPosedBottomAlignedPopup: {
|
||||
pos = parentItem->mapToScene(QPointF(parentItem->width(), parentItem->height()));
|
||||
boundaryCorrection(- m_menu->width() + parentItem->width(), - m_menu->height() + parentItem->height());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -370,22 +406,6 @@ Q_INVOKABLE void QMenuProxy::openRelative()
|
|||
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().x() + screen->geometry().width())) {
|
||||
pos.setX(pos.x() - m_menu->width());
|
||||
}
|
||||
|
||||
if (pos.y() + m_menu->height() > (screen->geometry().y() + screen->geometry().height())) {
|
||||
pos.setY(pos.y() - m_menu->height());
|
||||
}
|
||||
}
|
||||
|
||||
openInternal(pos.toPoint());
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ public:
|
|||
TopPosedRightAlignedPopup, /**< Popup positioned on the top, aligned
|
||||
to the right of the widget */
|
||||
LeftPosedTopAlignedPopup, /**< Popup positioned on the left, aligned
|
||||
to the right of the wigdet */
|
||||
to the top of the wigdet */
|
||||
LeftPosedBottomAlignedPopup, /**< Popup positioned on the left, aligned
|
||||
to the bottom of the widget */
|
||||
BottomPosedLeftAlignedPopup, /**< Popup positioned on the bottom, aligned
|
||||
|
|
Loading…
Reference in New Issue
Block a user