File indexing completed on 2024-05-12 05:08:00
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 <QRect> 0013 #include <QScreen> 0014 #include <QWidget> 0015 0016 // ---------------------------------------------------------------------------- 0017 // KDE Includes 0018 0019 // ---------------------------------------------------------------------------- 0020 // Project Includes 0021 0022 0023 PopupPositioner::PopupPositioner(QWidget* baseWidget, QWidget* popupWidget, Anchor anchor) 0024 { 0025 const auto screenRect = baseWidget->screen()->availableGeometry(); 0026 0027 auto p = baseWidget->mapToGlobal(QPoint()); 0028 // align the y coordinate 0029 switch(anchor) { 0030 case BottemLeft: 0031 case BottomRight: 0032 if (p.y() + baseWidget->height() + popupWidget->height() > screenRect.bottomLeft().y()) { 0033 p.setY(p.y() - popupWidget->height()); 0034 } else { 0035 p.setY(p.y() + baseWidget->height()); 0036 } 0037 break; 0038 case TopLeft: 0039 case TopRight: 0040 if (p.y() - popupWidget->height() < screenRect.topLeft().y()) { 0041 p.setY(p.y() + baseWidget->height()); 0042 } else { 0043 p.setY(p.y() - popupWidget->height()); 0044 } 0045 break; 0046 } 0047 0048 // align the x coordinate 0049 switch(anchor) { 0050 case BottemLeft: 0051 case TopLeft: 0052 // if left aligning causes the widget to leave the screen area 0053 // then align it to the right edge of the base widget instead 0054 if (p.x() + popupWidget->width() > screenRect.topRight().x()) { 0055 p.setX(p.x() + baseWidget->width() - popupWidget->width()); 0056 } 0057 break; 0058 0059 case BottomRight: 0060 case TopRight: 0061 // align to the right 0062 p.setX(p.x() + baseWidget->width() - popupWidget->width()); 0063 0064 // if right aligning causes the widget to leave the screen area 0065 // then align it to the left edge of the base widget 0066 if (p.x() < screenRect.topLeft().x()) { 0067 p.setX(baseWidget->x()); 0068 } 0069 break; 0070 } 0071 0072 // if the popup widget leaves the screen to the left 0073 // then align it to the left side of the screen 0074 if (p.x() < screenRect.topLeft().x()) { 0075 p.setX(screenRect.topLeft().x()); 0076 } 0077 // if the popup widget leaves the screen to the right 0078 // then align its right edge to the right side of the screen 0079 if (p.x() + popupWidget->width() > screenRect.topRight().x()) { 0080 p.setX(screenRect.topRight().x() - popupWidget->width()); 0081 } 0082 0083 // move the popup widget to its location 0084 popupWidget->move(p); 0085 }