File indexing completed on 2024-09-15 04:28:33
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 #include <QSize> 0009 0010 /** 0011 * @class MediaSizeHelper 0012 * 0013 * A class to help calculate the current width of a media item within a chat delegate. 0014 * 0015 * The only realistic way to guarantee that a media item (e.g. an image or video) 0016 * is the correct size in QML is to calculate the size manually. 0017 * 0018 * The rules for this component work as follows: 0019 * - The output will always try to keep the media size if no limits are breached. 0020 * - If no media width is set, the current size will be a placeholder at a 16:9 ratio 0021 * calcualated from either the configured max width or the contentMaxWidth, whichever 0022 * is smaller (if the contentMaxWidth isn't set, the configured max width is used). 0023 * - The aspect ratio of the media will always be maintained if set (otherwise 16:9). 0024 * - The current size will never be larger than any of the limits in either direction. 0025 * - If any limit is breached the image size will be reduced while maintaining aspect 0026 * ration, i.e. no stretching or squashing. This can mean that the width or height 0027 * is reduced even if that parameter doesn't breach the limit itself. 0028 */ 0029 class MediaSizeHelper : public QObject 0030 { 0031 Q_OBJECT 0032 QML_ELEMENT 0033 0034 /** 0035 * @brief The maximum width (in px) the media can be. 0036 * 0037 * This is the upper limit placed upon the media by the delegate. 0038 */ 0039 Q_PROPERTY(qreal contentMaxWidth READ contentMaxWidth WRITE setContentMaxWidth NOTIFY contentMaxWidthChanged) 0040 0041 /** 0042 * @brief The maximum height (in px) the media can be. 0043 * 0044 * This is the upper limit placed upon the media by the delegate. 0045 */ 0046 Q_PROPERTY(qreal contentMaxHeight READ contentMaxHeight WRITE setContentMaxHeight NOTIFY contentMaxHeightChanged) 0047 0048 /** 0049 * @brief The base width (in px) of the media. 0050 */ 0051 Q_PROPERTY(qreal mediaWidth READ mediaWidth WRITE setMediaWidth NOTIFY mediaWidthChanged) 0052 0053 /** 0054 * @brief The base height (in px) of the media. 0055 */ 0056 Q_PROPERTY(qreal mediaHeight READ mediaHeight WRITE setMediaHeight NOTIFY mediaHeightChanged) 0057 0058 /** 0059 * @brief The size (in px) of the component based on the current input. 0060 * 0061 * Will always try to return a value even if some of the inputs are not set to 0062 * account for being called before the parameters are intialised. For any parameters 0063 * not set these will just be left out of the calcs. 0064 * 0065 * If no input values are provided a default placeholder value will be returned. 0066 */ 0067 Q_PROPERTY(QSize currentSize READ currentSize NOTIFY currentSizeChanged) 0068 0069 public: 0070 explicit MediaSizeHelper(QObject *parent = nullptr); 0071 0072 qreal contentMaxWidth() const; 0073 void setContentMaxWidth(qreal contentMaxWidth); 0074 0075 qreal contentMaxHeight() const; 0076 void setContentMaxHeight(qreal contentMaxHeight); 0077 0078 qreal mediaWidth() const; 0079 void setMediaWidth(qreal mediaWidth); 0080 0081 qreal mediaHeight() const; 0082 void setMediaHeight(qreal mediaHeight); 0083 0084 QSize currentSize() const; 0085 0086 Q_SIGNALS: 0087 void contentMaxWidthChanged(); 0088 void contentMaxHeightChanged(); 0089 void mediaWidthChanged(); 0090 void mediaHeightChanged(); 0091 void currentSizeChanged(); 0092 0093 private: 0094 qreal m_contentMaxWidth = -1.0; 0095 qreal m_contentMaxHeight = -1.0; 0096 qreal m_mediaWidth = -1.0; 0097 qreal m_mediaHeight = -1.0; 0098 0099 qreal resolvedMediaWidth() const; 0100 qreal resolvedMediaHeight() const; 0101 qreal aspectRatio() const; 0102 bool limitWidth() const; 0103 qreal widthLimit() const; 0104 qreal heightLimit() const; 0105 };