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 #pragma once
0005 
0006 #include <QObject>
0007 
0008 /**
0009  * @class DelegateSizeHelper
0010  *
0011  * A class to help calculate the current width of a chat delegate/bar.
0012  *
0013  * The aim is to support a dynamic sizing based upon the width of the page. There is
0014  * a built in curve that allows the width to transition between two percentages based
0015  * upon a start and finish break point. This is to provide better convergence where
0016  * generally the delegate will need to fill all or most the screen when thin but
0017  * should max out in size and only fill a lower percentage of the screen when wide.
0018  *
0019  * @note While the main intended usage is to start with a high percentage when the parentWidth
0020  *       is small and transition to a lower one when large, the math is setup for the
0021  *       general case so any combination of parameters works.
0022  */
0023 class DelegateSizeHelper : public QObject
0024 {
0025     Q_OBJECT
0026 
0027     /**
0028      * @brief The width of the component's parent.
0029      */
0030     Q_PROPERTY(qreal parentWidth READ parentWidth WRITE setParentWidth NOTIFY parentWidthChanged)
0031 
0032     /**
0033      * @brief The width (in px) when the width percentage should start to transition.
0034      */
0035     Q_PROPERTY(qreal startBreakpoint READ startBreakpoint WRITE setStartBreakpoint NOTIFY startBreakpointChanged)
0036 
0037     /**
0038      * @brief The width (in px) when the width percentage should finish transitioning.
0039      */
0040     Q_PROPERTY(qreal endBreakpoint READ endBreakpoint WRITE setEndBreakpoint NOTIFY endBreakpointChanged)
0041 
0042     /**
0043      * @brief The width (in %) of the component at or before the startBreakpoint.
0044      *
0045      * @sa startBreakpoint
0046      */
0047     Q_PROPERTY(int startPercentWidth READ startPercentWidth WRITE setStartPercentWidth NOTIFY startPercentWidthChanged)
0048 
0049     /**
0050      * @brief The width (in %) of the component at or after the endBreakpoint.
0051      *
0052      * @sa endBreakpoint
0053      */
0054     Q_PROPERTY(int endPercentWidth READ endPercentWidth WRITE setEndPercentWidth NOTIFY endPercentWidthChanged)
0055 
0056     /**
0057      * @brief The absolute maximum width (in px) the component can be.
0058      */
0059     Q_PROPERTY(qreal maxWidth READ maxWidth WRITE setMaxWidth NOTIFY maxWidthChanged)
0060 
0061     /**
0062      * @brief The width (in %) of the component at the current parentWidth.
0063      *
0064      * Will return -1 if no parentWidth is set or startBreakpoint == endBreakpoint.
0065      *
0066      * @sa parentWidth, startBreakpoint, endBreakpoint
0067      */
0068     Q_PROPERTY(int currentPercentageWidth READ currentPercentageWidth NOTIFY currentPercentageWidthChanged)
0069 
0070     /**
0071      * @brief The width (in px) of the component at the current parentWidth.
0072      *
0073      * Will return 0.0 if no parentWidth is set.
0074      *
0075      * @sa parentWidth
0076      */
0077     Q_PROPERTY(qreal currentWidth READ currentWidth NOTIFY currentWidthChanged)
0078 
0079 public:
0080     explicit DelegateSizeHelper(QObject *parent = nullptr);
0081 
0082     qreal parentWidth() const;
0083     void setParentWidth(qreal parentWidth);
0084 
0085     qreal startBreakpoint() const;
0086     void setStartBreakpoint(qreal startBreakpoint);
0087 
0088     qreal endBreakpoint() const;
0089     void setEndBreakpoint(qreal endBreakpoint);
0090 
0091     int startPercentWidth() const;
0092     void setStartPercentWidth(int startPercentWidth);
0093 
0094     int endPercentWidth() const;
0095     void setEndPercentWidth(int endPercentWidth);
0096 
0097     qreal maxWidth() const;
0098     void setMaxWidth(qreal maxWidth);
0099 
0100     int currentPercentageWidth() const;
0101 
0102     qreal currentWidth() const;
0103 
0104 Q_SIGNALS:
0105     void parentWidthChanged();
0106     void startBreakpointChanged();
0107     void endBreakpointChanged();
0108     void startPercentWidthChanged();
0109     void endPercentWidthChanged();
0110     void maxWidthChanged();
0111     void currentPercentageWidthChanged();
0112     void currentWidthChanged();
0113 
0114 private:
0115     qreal m_parentWidth = -1.0;
0116     qreal m_startBreakpoint;
0117     qreal m_endBreakpoint;
0118     int m_startPercentWidth;
0119     int m_endPercentWidth;
0120     qreal m_maxWidth = -1.0;
0121 
0122     int calculateCurrentPercentageWidth() const;
0123 };