File indexing completed on 2024-05-12 16:44:05
0001 /* 0002 SPDX-FileCopyrightText: 2021 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "popuppositioner.h" 0007 0008 // ---------------------------------------------------------------------------- 0009 // QT Includes 0010 0011 #include <QApplication> 0012 #include <QDesktopWidget> 0013 #include <QScreen> 0014 #include <QWidget> 0015 #include <QRect> 0016 0017 // ---------------------------------------------------------------------------- 0018 // KDE Includes 0019 0020 // ---------------------------------------------------------------------------- 0021 // Project Includes 0022 0023 0024 PopupPositioner::PopupPositioner(QWidget* baseWidget, QWidget* popupWidget, Anchor anchor) 0025 { 0026 // the following two lines use deprecated functions. I have not yet 0027 // found out how to obtain the same information with newer versions (> 5.14) 0028 auto screenNr = QApplication::desktop()->screenNumber(baseWidget); 0029 const auto screenRect = QApplication::desktop()->screenGeometry(screenNr); 0030 0031 auto p = baseWidget->mapToGlobal(QPoint()); 0032 // align the y coordinate 0033 switch(anchor) { 0034 case BottemLeft: 0035 case BottomRight: 0036 if (p.y() + baseWidget->height() + popupWidget->height() > screenRect.bottomLeft().y()) { 0037 p.setY(p.y() - popupWidget->height()); 0038 } else { 0039 p.setY(p.y() + baseWidget->height()); 0040 } 0041 break; 0042 case TopLeft: 0043 case TopRight: 0044 if (p.y() - popupWidget->height() < screenRect.topLeft().y()) { 0045 p.setY(p.y() + baseWidget->height()); 0046 } else { 0047 p.setY(p.y() - popupWidget->height()); 0048 } 0049 break; 0050 } 0051 0052 // align the x coordinate 0053 switch(anchor) { 0054 case BottemLeft: 0055 case TopLeft: 0056 // if left aligning causes the widget to leave the screen area 0057 // then align it to the right edge of the base widget instead 0058 if (p.x() + popupWidget->width() > screenRect.topRight().x()) { 0059 p.setX(p.x() + baseWidget->width() - popupWidget->width()); 0060 } 0061 break; 0062 0063 case BottomRight: 0064 case TopRight: 0065 // align to the right 0066 p.setX(p.x() + baseWidget->width() - popupWidget->width()); 0067 0068 // if right aligning causes the widget to leave the screen area 0069 // then align it to the left edge of the base widget 0070 if (p.x() < screenRect.topLeft().x()) { 0071 p.setX(baseWidget->x()); 0072 } 0073 break; 0074 } 0075 0076 // if the popup widget leaves the screen to the left 0077 // then align it to the left side of the screen 0078 if (p.x() < screenRect.topLeft().x()) { 0079 p.setX(screenRect.topLeft().x()); 0080 } 0081 // if the popup widget leaves the screen to the right 0082 // then align its right edge to the right side of the screen 0083 if (p.x() + popupWidget->width() > screenRect.topRight().x()) { 0084 p.setX(screenRect.topRight().x() - popupWidget->width()); 0085 } 0086 0087 // move the popup widget to its location 0088 popupWidget->move(p); 0089 }