File indexing completed on 2024-05-26 05:38:26

0001 /*
0002     SPDX-FileCopyrightText: 2014 David Edmundson <kde@davidedmundson.co.uk>
0003     SPDX-FileCopyrightText: 2014 Eike Hein <hein@kde.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "submenu.h"
0009 
0010 #include <cmath>
0011 
0012 #include <QScreen>
0013 
0014 #include <KWindowSystem>
0015 
0016 SubMenu::SubMenu(QQuickItem *parent)
0017     : PlasmaQuick::Dialog(parent)
0018     , m_offset(0)
0019     , m_facingLeft(false)
0020 {
0021     setType(AppletPopup);
0022 }
0023 
0024 SubMenu::~SubMenu()
0025 {
0026 }
0027 
0028 int SubMenu::offset() const
0029 {
0030     return m_offset;
0031 }
0032 
0033 void SubMenu::setOffset(int offset)
0034 {
0035     if (m_offset != offset) {
0036         m_offset = offset;
0037 
0038         Q_EMIT offsetChanged();
0039     }
0040 }
0041 
0042 QPoint SubMenu::popupPosition(QQuickItem *item, const QSize &size)
0043 {
0044     if (!item || !item->window()) {
0045         return QPoint(0, 0);
0046     }
0047 
0048     QPointF pos = item->mapToScene(QPointF(0, 0));
0049     pos = item->window()->mapToGlobal(pos.toPoint());
0050 
0051     pos.setX(pos.x() + m_offset + item->width());
0052 
0053     QRect avail = availableScreenRectForItem(item);
0054 
0055     if (pos.x() + size.width() > avail.right()) {
0056         pos.setX(pos.x() - m_offset - item->width() - size.width());
0057 
0058         m_facingLeft = true;
0059         Q_EMIT facingLeftChanged();
0060     }
0061 
0062     pos.setY(pos.y() - margins()->property("top").toInt());
0063 
0064     if (pos.y() + size.height() > avail.bottom()) {
0065         int overshoot = std::ceil(((avail.bottom() - (pos.y() + size.height())) * -1) / item->height()) * item->height();
0066 
0067         pos.setY(pos.y() - overshoot);
0068     }
0069 
0070     return pos.toPoint();
0071 }
0072 
0073 QRect SubMenu::availableScreenRectForItem(QQuickItem *item) const
0074 {
0075     QScreen *screen = QGuiApplication::primaryScreen();
0076 
0077     const QPoint globalPosition = item->window()->mapToGlobal(item->position().toPoint());
0078 
0079     const QList<QScreen *> screens = QGuiApplication::screens();
0080     for (QScreen *s : screens) {
0081         if (s->geometry().contains(globalPosition)) {
0082             screen = s;
0083         }
0084     }
0085 
0086     return screen->availableGeometry();
0087 }