106 lines
3.6 KiB
C++
106 lines
3.6 KiB
C++
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QQmlEngine>
|
|
#include <QSize>
|
|
|
|
/**
|
|
* @class MediaSizeHelper
|
|
*
|
|
* A class to help calculate the current width of a media item within a chat delegate.
|
|
*
|
|
* The only realistic way to guarantee that a media item (e.g. an image or video)
|
|
* is the correct size in QML is to calculate the size manually.
|
|
*
|
|
* The rules for this component work as follows:
|
|
* - The output will always try to keep the media size if no limits are breached.
|
|
* - If no media width is set, the current size will be a placeholder at a 16:9 ratio
|
|
* calcualated from either the configured max width or the contentMaxWidth, whichever
|
|
* is smaller (if the contentMaxWidth isn't set, the configured max width is used).
|
|
* - The aspect ratio of the media will always be maintained if set (otherwise 16:9).
|
|
* - The current size will never be larger than any of the limits in either direction.
|
|
* - If any limit is breached the image size will be reduced while maintaining aspect
|
|
* ration, i.e. no stretching or squashing. This can mean that the width or height
|
|
* is reduced even if that parameter doesn't breach the limit itself.
|
|
*/
|
|
class MediaSizeHelper : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QML_ELEMENT
|
|
|
|
/**
|
|
* @brief The maximum width (in px) the media can be.
|
|
*
|
|
* This is the upper limit placed upon the media by the delegate.
|
|
*/
|
|
Q_PROPERTY(qreal contentMaxWidth READ contentMaxWidth WRITE setContentMaxWidth NOTIFY contentMaxWidthChanged)
|
|
|
|
/**
|
|
* @brief The maximum height (in px) the media can be.
|
|
*
|
|
* This is the upper limit placed upon the media by the delegate.
|
|
*/
|
|
Q_PROPERTY(qreal contentMaxHeight READ contentMaxHeight WRITE setContentMaxHeight NOTIFY contentMaxHeightChanged)
|
|
|
|
/**
|
|
* @brief The base width (in px) of the media.
|
|
*/
|
|
Q_PROPERTY(qreal mediaWidth READ mediaWidth WRITE setMediaWidth NOTIFY mediaWidthChanged)
|
|
|
|
/**
|
|
* @brief The base height (in px) of the media.
|
|
*/
|
|
Q_PROPERTY(qreal mediaHeight READ mediaHeight WRITE setMediaHeight NOTIFY mediaHeightChanged)
|
|
|
|
/**
|
|
* @brief The size (in px) of the component based on the current input.
|
|
*
|
|
* Will always try to return a value even if some of the inputs are not set to
|
|
* account for being called before the parameters are intialised. For any parameters
|
|
* not set these will just be left out of the calcs.
|
|
*
|
|
* If no input values are provided a default placeholder value will be returned.
|
|
*/
|
|
Q_PROPERTY(QSize currentSize READ currentSize NOTIFY currentSizeChanged)
|
|
|
|
public:
|
|
explicit MediaSizeHelper(QObject *parent = nullptr);
|
|
|
|
qreal contentMaxWidth() const;
|
|
void setContentMaxWidth(qreal contentMaxWidth);
|
|
|
|
qreal contentMaxHeight() const;
|
|
void setContentMaxHeight(qreal contentMaxHeight);
|
|
|
|
qreal mediaWidth() const;
|
|
void setMediaWidth(qreal mediaWidth);
|
|
|
|
qreal mediaHeight() const;
|
|
void setMediaHeight(qreal mediaHeight);
|
|
|
|
QSize currentSize() const;
|
|
|
|
Q_SIGNALS:
|
|
void contentMaxWidthChanged();
|
|
void contentMaxHeightChanged();
|
|
void mediaWidthChanged();
|
|
void mediaHeightChanged();
|
|
void currentSizeChanged();
|
|
|
|
private:
|
|
qreal m_contentMaxWidth = -1.0;
|
|
qreal m_contentMaxHeight = -1.0;
|
|
qreal m_mediaWidth = -1.0;
|
|
qreal m_mediaHeight = -1.0;
|
|
|
|
qreal resolvedMediaWidth() const;
|
|
qreal resolvedMediaHeight() const;
|
|
qreal aspectRatio() const;
|
|
bool limitWidth() const;
|
|
qreal widthLimit() const;
|
|
qreal heightLimit() const;
|
|
};
|