1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
/*
SPDX-FileCopyrightText: 2014 David Edmundson <kde@davidedmundson.co.uk>
SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "submenu.h"
#include <cmath>
#include <QScreen>
#include <QApplication>
#include <KWindowSystem>
SubMenu::SubMenu(QQuickItem *parent)
: PlasmaQuick::Dialog(parent)
, m_offset(0)
, m_facingLeft(false)
{
setType(AppletPopup);
}
SubMenu::~SubMenu()
{
}
int SubMenu::offset() const
{
return m_offset;
}
void SubMenu::setOffset(int offset)
{
if (m_offset != offset) {
m_offset = offset;
Q_EMIT offsetChanged();
}
}
QPoint SubMenu::popupPosition(QQuickItem *item, const QSize &size)
{
if (!item || !item->window()) {
return QPoint(0, 0);
}
const bool isRightToLeft = QApplication::layoutDirection() == Qt::RightToLeft;
QPointF pos = item->mapToScene(QPointF(0, 0));
pos = item->window()->mapToGlobal(pos.toPoint());
QRect avail = availableScreenRectForItem(item);
qreal xPopupLeft = pos.x() - m_offset - size.width();
qreal xPopupRight = pos.x() + m_offset + item->width();
bool fitsLeft = xPopupLeft >= avail.left();
bool fitsRight = xPopupRight + size.width() <= avail.right();
if ((isRightToLeft && fitsLeft) || (!isRightToLeft && !fitsRight)) {
pos.setX(xPopupLeft);
m_facingLeft = true;
Q_EMIT facingLeftChanged();
} else {
pos.setX(xPopupRight);
}
pos.setY(pos.y() - margins()->property("top").toInt());
if (pos.y() + size.height() > avail.bottom()) {
int overshoot = std::ceil(((avail.bottom() - (pos.y() + size.height())) * -1) / item->height()) * item->height();
pos.setY(pos.y() - overshoot);
}
return pos.toPoint();
}
QRect SubMenu::availableScreenRectForItem(QQuickItem *item) const
{
QScreen *screen = QGuiApplication::primaryScreen();
const QPoint globalPosition = item->window()->mapToGlobal(item->position().toPoint());
const QList<QScreen *> screens = QGuiApplication::screens();
for (QScreen *s : screens) {
if (s->geometry().contains(globalPosition)) {
screen = s;
}
}
return screen->availableGeometry();
}
#include "moc_submenu.cpp"
|