File indexing completed on 2024-10-06 12:53:59

0001 // SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
0002 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0003 
0004 #include "delegatesizehelper.h"
0005 
0006 #include <cmath>
0007 
0008 #include <QDebug>
0009 
0010 DelegateSizeHelper::DelegateSizeHelper(QObject *parent)
0011     : QObject(parent)
0012 {
0013 }
0014 
0015 qreal DelegateSizeHelper::parentWidth() const
0016 {
0017     return m_parentWidth;
0018 }
0019 
0020 void DelegateSizeHelper::setParentWidth(qreal parentWidth)
0021 {
0022     if (parentWidth == m_parentWidth) {
0023         return;
0024     }
0025     m_parentWidth = parentWidth;
0026     Q_EMIT parentWidthChanged();
0027     Q_EMIT currentPercentageWidthChanged();
0028     Q_EMIT currentWidthChanged();
0029 }
0030 
0031 qreal DelegateSizeHelper::startBreakpoint() const
0032 {
0033     return m_startBreakpoint;
0034 }
0035 
0036 void DelegateSizeHelper::setStartBreakpoint(qreal startBreakpoint)
0037 {
0038     if (startBreakpoint == m_startBreakpoint) {
0039         return;
0040     }
0041     m_startBreakpoint = startBreakpoint;
0042     Q_EMIT startBreakpointChanged();
0043 }
0044 
0045 qreal DelegateSizeHelper::endBreakpoint() const
0046 {
0047     return m_endBreakpoint;
0048 }
0049 
0050 void DelegateSizeHelper::setEndBreakpoint(qreal endBreakpoint)
0051 {
0052     if (endBreakpoint == m_endBreakpoint) {
0053         return;
0054     }
0055     m_endBreakpoint = endBreakpoint;
0056     Q_EMIT endBreakpointChanged();
0057 }
0058 
0059 int DelegateSizeHelper::startPercentWidth() const
0060 {
0061     return m_startPercentWidth;
0062 }
0063 
0064 void DelegateSizeHelper::setStartPercentWidth(int startPercentWidth)
0065 {
0066     if (startPercentWidth == m_startPercentWidth) {
0067         return;
0068     }
0069     m_startPercentWidth = startPercentWidth;
0070     Q_EMIT startPercentWidthChanged();
0071 }
0072 
0073 int DelegateSizeHelper::endPercentWidth() const
0074 {
0075     return m_endPercentWidth;
0076 }
0077 
0078 void DelegateSizeHelper::setEndPercentWidth(int endPercentWidth)
0079 {
0080     if (endPercentWidth == m_endPercentWidth) {
0081         return;
0082     }
0083     m_endPercentWidth = endPercentWidth;
0084     Q_EMIT endPercentWidthChanged();
0085 }
0086 
0087 qreal DelegateSizeHelper::maxWidth() const
0088 {
0089     return m_maxWidth;
0090 }
0091 
0092 void DelegateSizeHelper::setMaxWidth(qreal maxWidth)
0093 {
0094     if (maxWidth == m_maxWidth) {
0095         return;
0096     }
0097     m_maxWidth = maxWidth;
0098     Q_EMIT maxWidthChanged();
0099 }
0100 
0101 int DelegateSizeHelper::calculateCurrentPercentageWidth() const
0102 {
0103     // Don't do anything if m_parentWidth hasn't been set yet.
0104     if (m_parentWidth < 0) {
0105         return -1;
0106     }
0107     // Don't bother with calculations for a horizontal line.
0108     if (m_startPercentWidth == m_endPercentWidth) {
0109         return m_startPercentWidth;
0110     }
0111     // Dividing by zero is a bad idea.
0112     if (m_startBreakpoint == m_endBreakpoint) {
0113         qWarning() << "DelegateSizeHelper::calculateCurrentPercentageWidth() - m_startBreakpoint is equal to m_endBreakpoint this would lead to divide by "
0114                       "zero, aborting";
0115         return -1;
0116     }
0117 
0118     // Fit to y = mx + c
0119     qreal m = (m_endPercentWidth - m_startPercentWidth) / (m_endBreakpoint - m_startBreakpoint);
0120     qreal c = m_startPercentWidth - m * m_startBreakpoint;
0121 
0122     // This allows us to clamp correctly if the start or end width is bigger.
0123     bool endPercentBigger = m_endPercentWidth > m_startPercentWidth;
0124     int maxPercentWidth = endPercentBigger ? m_endPercentWidth : m_startPercentWidth;
0125     int minPercentWidth = endPercentBigger ? m_startPercentWidth : m_endPercentWidth;
0126 
0127     int calcPercentWidth = std::ceil(m * m_parentWidth + c);
0128     return std::clamp(calcPercentWidth, minPercentWidth, maxPercentWidth);
0129 }
0130 
0131 int DelegateSizeHelper::currentPercentageWidth() const
0132 {
0133     return calculateCurrentPercentageWidth();
0134 }
0135 
0136 qreal DelegateSizeHelper::currentWidth() const
0137 {
0138     if (m_parentWidth < 0) {
0139         return 0.0;
0140     }
0141     int percentWidth = calculateCurrentPercentageWidth();
0142     // - 1 means bad input values so don't try to calculate.
0143     if (percentWidth == -1) {
0144         return 0.0;
0145     }
0146 
0147     qreal absoluteWidth = m_parentWidth * percentWidth * 0.01;
0148     if (m_maxWidth < 0.0) {
0149         return std::ceil(absoluteWidth);
0150     } else {
0151         return std::ceil(std::min(absoluteWidth, m_maxWidth));
0152     }
0153 }
0154 
0155 #include "moc_delegatesizehelper.cpp"