File indexing completed on 2024-04-28 04:59:38

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