File indexing completed on 2024-04-28 15:39:42

0001 // SPDX-FileCopyrightText: 2014-2022 Jesper K. Pedersen <blackie@kde.org>
0002 //
0003 // SPDX-License-Identifier: GPL-2.0-or-later
0004 
0005 #include "ScreenInfo.h"
0006 #include "Settings.h"
0007 #include <QScreen>
0008 #include <QTimer>
0009 #include <cmath>
0010 
0011 namespace RemoteControl
0012 {
0013 
0014 ScreenInfo &ScreenInfo::instance()
0015 {
0016     static ScreenInfo instance;
0017     return instance;
0018 }
0019 
0020 void ScreenInfo::setScreen(QScreen *screen)
0021 {
0022     m_screen = screen;
0023     QSize size = pixelForSizeInMM(100);
0024     m_dotsPerMM = (size.width() + size.height()) / 2 / 100;
0025 }
0026 
0027 QSize ScreenInfo::pixelForSizeInMM(int size) const
0028 {
0029     const QSizeF mm = m_screen->physicalSize();
0030     const QSize pixels = screenSize();
0031     return QSize((size / mm.width()) * pixels.width(),
0032                  (size / mm.height()) * pixels.height());
0033 }
0034 
0035 void ScreenInfo::setCategoryCount(int count)
0036 {
0037     m_categoryCount = count;
0038     updateLayout();
0039 }
0040 
0041 QSize ScreenInfo::screenSize() const
0042 {
0043     return m_screen->geometry().size();
0044 }
0045 
0046 QSize ScreenInfo::viewSize() const
0047 {
0048     return QSize(m_viewWidth, m_viewHeight);
0049 }
0050 
0051 int ScreenInfo::overviewIconSize() const
0052 {
0053     return pixelForSizeInMM(Settings::instance().overviewIconSize()).width();
0054 }
0055 
0056 ScreenInfo::ScreenInfo()
0057 {
0058     connect(&Settings::instance(), &Settings::overviewIconSizeChanged, this, &ScreenInfo::updateLayout);
0059     connect(&Settings::instance(), &Settings::overviewIconSizeChanged, this, &ScreenInfo::overviewIconSizeChanged);
0060     connect(&Settings::instance(), &Settings::overviewIconSizeChanged, this, &ScreenInfo::overviewSpacingChanged);
0061     connect(this, &ScreenInfo::viewWidthChanged, this,
0062             [this]() { QTimer::singleShot(0, this, SLOT(updateLayout())); });
0063 }
0064 
0065 int ScreenInfo::possibleColumns()
0066 {
0067     // We need 1/4 * iw on each side
0068     // Add to that n * iw for the icons themselves
0069     // and finally (n-1)/2 * iw for spaces between icons
0070     // That means solve the formula
0071     // viewWidth = 2*1/4*iw + n* iw + (n-1)/2 * iw
0072 
0073     const double iconWidthMM = Settings::instance().overviewIconSize();
0074     const int iconWidthInPx = pixelForSizeInMM(iconWidthMM).width();
0075     return floor(2.0 * m_viewWidth / iconWidthInPx) / 3.0;
0076 }
0077 
0078 int ScreenInfo::iconHeight()
0079 {
0080     const int iconHeightMM = Settings::instance().overviewIconSize();
0081     const int iconHeight = pixelForSizeInMM(iconHeightMM).height();
0082     const int innerSpacing = 10; // Value from Icon.qml
0083     return iconHeight + innerSpacing + m_textHeight;
0084 }
0085 
0086 void ScreenInfo::updateLayout()
0087 {
0088     if (m_categoryCount == 0 || m_viewWidth == 0)
0089         return;
0090 
0091     const int fixedIconCount = 3; // Home, Discover, View
0092     const int iconCount = m_categoryCount + fixedIconCount;
0093     const int preferredCols = ceil(sqrt(iconCount));
0094 
0095     int columns;
0096     for (columns = qMin(possibleColumns(), preferredCols); columns < possibleColumns(); ++columns) {
0097         const int rows = ceil(1.0 * iconCount / columns);
0098         const int height = (rows + 2 * 0.25 + (rows - 1) / 2) * iconHeight();
0099         if (height < m_viewHeight)
0100             break;
0101     }
0102 
0103     m_overviewColumnCount = columns;
0104 
0105     Q_EMIT overviewColumnCountChanged();
0106 }
0107 
0108 int ScreenInfo::overviewSpacing() const
0109 {
0110     return overviewIconSize() / 2;
0111 }
0112 
0113 } // namespace RemoteControl
0114 
0115 #include "moc_ScreenInfo.cpp"