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"