- chatgui: просмотрщик изображений (ImageViewerWindow) с зумом/поворотом - chatgui: отправка картинок как image с определением разрешения и типа - chatgui: у видео-пузыря строка info (res·size·bitrate) и бейдж только длительность - chatgui: контекстное меню медиа (сохранить в файл/скачать) - chatgui-android: большие emoji-only сообщения, битрейт/разрешение у видео - chatgui-android: сохранение неактивных интерфейсов как закомментированные секции - chatgui-android: отправка картинок по расширению (jpg/png/gif/bmp/webp) - photo_sender: content-type и расширение по типу файла
131 lines
4.9 KiB
C++
131 lines
4.9 KiB
C++
#pragma once
|
|
|
|
#include <QStyledItemDelegate>
|
|
#include <functional>
|
|
|
|
enum MessageDataRole {
|
|
MsgAuthorRole = Qt::UserRole + 1,
|
|
MsgTextRole = Qt::UserRole + 2,
|
|
MsgTimeRole = Qt::UserRole + 3,
|
|
MsgEditedRole = Qt::UserRole + 4,
|
|
MsgAvatarRole = Qt::UserRole + 5,
|
|
MsgHasQuoteRole = Qt::UserRole + 6,
|
|
MsgQuoteAuthorRole = Qt::UserRole + 7,
|
|
MsgQuoteTextRole = Qt::UserRole + 8,
|
|
MsgReactionsRole = Qt::UserRole + 9,
|
|
MsgIdRole = Qt::UserRole + 10,
|
|
MsgIsOutgoingRole = Qt::UserRole + 11,
|
|
MsgContentTypeRole = Qt::UserRole + 12,
|
|
MsgVoiceDurationRole = Qt::UserRole + 13,
|
|
MsgVoiceFileRole = Qt::UserRole + 14,
|
|
MsgVoicePlayStateRole = Qt::UserRole + 15,
|
|
MsgVoicePlayPosRole = Qt::UserRole + 16,
|
|
MsgVoiceWaveformRole = Qt::UserRole + 17,
|
|
MsgVoiceFileSizeRole = Qt::UserRole + 18,
|
|
MsgVoiceBlockSizeRole = Qt::UserRole + 19,
|
|
MsgAuthorNodeIdRole = Qt::UserRole + 20,
|
|
MsgVoiceNumBlocksRole = Qt::UserRole + 21,
|
|
MsgVoiceSigsRole = Qt::UserRole + 22,
|
|
MsgFileDisplayNameRole = Qt::UserRole + 23,
|
|
MsgFileSizeRole = Qt::UserRole + 24,
|
|
MsgFileDownloadStateRole = Qt::UserRole + 25,
|
|
MsgChannelIdRole = Qt::UserRole + 26,
|
|
MsgFileDownloadProgressRole = Qt::UserRole + 27,
|
|
MsgMediaBlocksDoneRole = Qt::UserRole + 28,
|
|
MsgMediaNumBlocksRole = Qt::UserRole + 29,
|
|
MsgVoiceDownloadPendingRole = Qt::UserRole + 30,
|
|
MsgImageWidthRole = Qt::UserRole + 31,
|
|
MsgImageHeightRole = Qt::UserRole + 32,
|
|
MsgVideoWidthRole = Qt::UserRole + 33,
|
|
MsgVideoHeightRole = Qt::UserRole + 34,
|
|
MsgVideoDurationMsRole = Qt::UserRole + 35,
|
|
};
|
|
|
|
class MessageDelegate : public QStyledItemDelegate {
|
|
Q_OBJECT
|
|
public:
|
|
explicit MessageDelegate(QObject *parent = nullptr);
|
|
|
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const override;
|
|
QSize sizeHint(const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const override;
|
|
bool editorEvent(QEvent *event, QAbstractItemModel *model,
|
|
const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) override;
|
|
|
|
static void startAutoPlay(const QString& filePath, float actualDurationSec);
|
|
static void stopAllAutoPlay();
|
|
|
|
void setVideoOpenCallback(std::function<void(const QString&)> cb) { m_videoOpenCb = std::move(cb); }
|
|
void setImageOpenCallback(std::function<void(const QString&)> cb) { m_imageOpenCb = std::move(cb); }
|
|
|
|
private:
|
|
struct Layout {
|
|
int viewWidth;
|
|
int bubbleWidth;
|
|
QRect authorRect;
|
|
QRect avatarRect;
|
|
QRect bubbleRect;
|
|
QRect quoteRect;
|
|
QRect quoteBarRect;
|
|
QRect quoteAuthorRect;
|
|
QRect quoteTextRect;
|
|
QRect textRect;
|
|
QRect statusRect;
|
|
int totalHeight;
|
|
bool narrow = false;
|
|
bool emojiOnly = false;
|
|
int emojiCount = 0;
|
|
QRect emojiArea;
|
|
bool isOutgoing = false;
|
|
bool isVoice = false;
|
|
bool isFile = false;
|
|
bool isVideo = false;
|
|
bool isImage = false;
|
|
QRect voicePlayBtnRect;
|
|
QRect voiceWaveformRect;
|
|
QRect voiceDurationRect;
|
|
QRect voiceTimeRect;
|
|
QString voiceDuration;
|
|
int mediaBarColor = 0; /* 0=gray, 1=yellow, 2=green */
|
|
QRect mediaBarRect;
|
|
QRect progressBarRect;
|
|
float progressFrac = 0.0f;
|
|
QRect videoThumbRect;
|
|
QRect videoPlayBtnRect;
|
|
QRect videoDurBadgeRect;
|
|
QRect imageThumbRect;
|
|
QRect imageBadgeRect;
|
|
};
|
|
|
|
std::function<void(const QString&)> m_videoOpenCb;
|
|
std::function<void(const QString&)> m_imageOpenCb;
|
|
|
|
Layout calcLayout(const QStyleOptionViewItem &option,
|
|
const QModelIndex &index) const;
|
|
void drawQuote(QPainter *p, const Layout &L,
|
|
const QModelIndex &index, const QStyleOptionViewItem &opt) const;
|
|
void drawBubble(QPainter *p, const Layout &L, const QStyleOptionViewItem &opt) const;
|
|
void drawStatusBar(QPainter *p, const Layout &L,
|
|
const QModelIndex &index, const QStyleOptionViewItem &opt) const;
|
|
void drawAvatar(QPainter *p, const Layout &L,
|
|
const QModelIndex &index) const;
|
|
|
|
static constexpr int kAvatar = 36;
|
|
static constexpr int kGap = 8;
|
|
static constexpr int kRadius = 10;
|
|
static constexpr int kPadH = 12;
|
|
static constexpr int kPadTop = 8;
|
|
static constexpr int kPadBot = 6;
|
|
static constexpr int kTail = 6;
|
|
static constexpr int kMarginH = 8;
|
|
static constexpr int kItemGap = 3;
|
|
static constexpr int kQuoteGap = 4;
|
|
static constexpr int kQuotePadH = 6;
|
|
static constexpr int kQuotePadV = 6;
|
|
static constexpr int kQuoteBarW = 2;
|
|
static constexpr int kQuoteAv = 16;
|
|
static constexpr int kStatusH = 18;
|
|
};
|