mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
Added ability to show song cover in HistoryView and Overview::Layout.
This commit is contained in:
parent
a483eb98a1
commit
8fffe7d128
7 changed files with 93 additions and 18 deletions
|
@ -1488,6 +1488,10 @@ bool DocumentData::isSong() const {
|
||||||
return (type == SongDocument);
|
return (type == SongDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DocumentData::isSongWithCover() const {
|
||||||
|
return isSong() && hasThumbnail();
|
||||||
|
}
|
||||||
|
|
||||||
bool DocumentData::isAudioFile() const {
|
bool DocumentData::isAudioFile() const {
|
||||||
if (isVoiceMessage()) {
|
if (isVoiceMessage()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -139,6 +139,7 @@ public:
|
||||||
[[nodiscard]] bool isVoiceMessage() const;
|
[[nodiscard]] bool isVoiceMessage() const;
|
||||||
[[nodiscard]] bool isVideoMessage() const;
|
[[nodiscard]] bool isVideoMessage() const;
|
||||||
[[nodiscard]] bool isSong() const;
|
[[nodiscard]] bool isSong() const;
|
||||||
|
[[nodiscard]] bool isSongWithCover() const;
|
||||||
[[nodiscard]] bool isAudioFile() const;
|
[[nodiscard]] bool isAudioFile() const;
|
||||||
[[nodiscard]] bool isVideoFile() const;
|
[[nodiscard]] bool isVideoFile() const;
|
||||||
[[nodiscard]] bool isAnimation() const;
|
[[nodiscard]] bool isAnimation() const;
|
||||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text/format_values.h"
|
#include "ui/text/format_values.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
|
#include "ui/ui_utility.h"
|
||||||
#include "layout.h" // FullSelection
|
#include "layout.h" // FullSelection
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
@ -442,14 +443,14 @@ void Document::draw(
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
if (selected) {
|
|
||||||
p.setBrush(outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected);
|
|
||||||
} else {
|
|
||||||
p.setBrush(outbg ? st::msgFileOutBg : st::msgFileInBg);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
const auto coverDrawn = _data->isSongWithCover()
|
||||||
|
&& DrawThumbnailAsSongCover(p, _dataMedia, inner, selected);
|
||||||
|
if (!coverDrawn) {
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.setBrush(selected
|
||||||
|
? (outbg ? st::msgFileOutBgSelected : st::msgFileInBgSelected)
|
||||||
|
: (outbg ? st::msgFileOutBg : st::msgFileInBg));
|
||||||
p.drawEllipse(inner);
|
p.drawEllipse(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,7 +582,7 @@ void Document::ensureDataMediaCreated() const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_dataMedia = _data->createMediaView();
|
_dataMedia = _data->createMediaView();
|
||||||
if (Get<HistoryDocumentThumbed>()) {
|
if (Get<HistoryDocumentThumbed>() || _data->isSongWithCover()) {
|
||||||
_dataMedia->thumbnailWanted(_realParent->fullId());
|
_dataMedia->thumbnailWanted(_realParent->fullId());
|
||||||
}
|
}
|
||||||
history()->owner().registerHeavyViewPart(_parent);
|
history()->owner().registerHeavyViewPart(_parent);
|
||||||
|
@ -1072,4 +1073,49 @@ Ui::Text::String Document::createCaption() {
|
||||||
timestampLinkBase);
|
timestampLinkBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DrawThumbnailAsSongCover(
|
||||||
|
Painter &p,
|
||||||
|
const std::shared_ptr<Data::DocumentMedia> &dataMedia,
|
||||||
|
const QRect &rect,
|
||||||
|
const bool selected) {
|
||||||
|
if (!dataMedia) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap cover;
|
||||||
|
|
||||||
|
const auto ow = rect.width();
|
||||||
|
const auto oh = rect.height();
|
||||||
|
const auto r = ImageRoundRadius::Ellipse;
|
||||||
|
const auto c = RectPart::AllCorners;
|
||||||
|
const auto color = &st::songCoverOverlayFg;
|
||||||
|
const auto aspectRatio = Qt::KeepAspectRatioByExpanding;
|
||||||
|
|
||||||
|
const auto scaled = [&](not_null<Image*> image) -> std::pair<int, int> {
|
||||||
|
const auto size = image->size().scaled(ow, oh, aspectRatio);
|
||||||
|
return { size.width(), size.height() };
|
||||||
|
};
|
||||||
|
|
||||||
|
if (const auto normal = dataMedia->thumbnail()) {
|
||||||
|
const auto &[w, h] = scaled(normal);
|
||||||
|
cover = normal->pixSingle(w, h, ow, oh, r, c, color);
|
||||||
|
} else if (const auto blurred = dataMedia->thumbnailInline()) {
|
||||||
|
const auto &[w, h] = scaled(blurred);
|
||||||
|
cover = blurred->pixBlurredSingle(w, h, ow, oh, r, c, color);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (selected) {
|
||||||
|
auto selectedCover = Images::prepareColored(
|
||||||
|
p.textPalette().selectOverlay,
|
||||||
|
cover.toImage());
|
||||||
|
cover = QPixmap::fromImage(
|
||||||
|
std::move(selectedCover),
|
||||||
|
Qt::ColorOnly);
|
||||||
|
}
|
||||||
|
p.drawPixmap(rect.topLeft(), cover);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -143,4 +143,10 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool DrawThumbnailAsSongCover(
|
||||||
|
Painter &p,
|
||||||
|
const std::shared_ptr<Data::DocumentMedia> &dataMedia,
|
||||||
|
const QRect &rect,
|
||||||
|
const bool selected = false);
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
|
#include "history/view/media/history_view_document.h" // DrawThumbnailAsSongCover
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "base/qt_adapters.h"
|
#include "base/qt_adapters.h"
|
||||||
#include "ui/effects/round_checkbox.h"
|
#include "ui/effects/round_checkbox.h"
|
||||||
|
@ -1008,21 +1009,33 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
|
|
||||||
auto inner = style::rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
auto inner = style::rtlrect(_st.songPadding.left(), _st.songPadding.top(), _st.songThumbSize, _st.songThumbSize, _width);
|
||||||
if (clip.intersects(inner)) {
|
if (clip.intersects(inner)) {
|
||||||
|
const auto isLoading = (!cornerDownload
|
||||||
|
&& (_data->loading() || _data->uploading()));
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
if (selected) {
|
|
||||||
p.setBrush(st::msgFileInBgSelected);
|
|
||||||
} else {
|
|
||||||
auto over = ClickHandler::showAsActive((!cornerDownload && (_data->loading() || _data->uploading())) ? _cancell : (loaded || _dataMedia->canBePlayed()) ? _openl : _savel);
|
|
||||||
p.setBrush(anim::brush(_st.songIconBg, _st.songOverBg, _a_iconOver.value(over ? 1. : 0.)));
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
using namespace HistoryView;
|
||||||
|
const auto coverDrawn = _data->isSongWithCover()
|
||||||
|
&& DrawThumbnailAsSongCover(p, _dataMedia, inner, selected);
|
||||||
|
if (!coverDrawn) {
|
||||||
|
if (selected) {
|
||||||
|
p.setBrush(st::msgFileInBgSelected);
|
||||||
|
} else {
|
||||||
|
const auto over = ClickHandler::showAsActive(isLoading
|
||||||
|
? _cancell
|
||||||
|
: (loaded || _dataMedia->canBePlayed())
|
||||||
|
? _openl
|
||||||
|
: _savel);
|
||||||
|
p.setBrush(anim::brush(
|
||||||
|
_st.songIconBg,
|
||||||
|
_st.songOverBg,
|
||||||
|
_a_iconOver.value(over ? 1. : 0.)));
|
||||||
|
}
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.drawEllipse(inner);
|
p.drawEllipse(inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto icon = [&] {
|
const auto icon = [&] {
|
||||||
if (!cornerDownload && (_data->loading() || _data->uploading())) {
|
if (isLoading) {
|
||||||
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
||||||
} else if (showPause) {
|
} else if (showPause) {
|
||||||
return &(selected ? _st.songPauseSelected : _st.songPause);
|
return &(selected ? _st.songPauseSelected : _st.songPause);
|
||||||
|
|
|
@ -343,7 +343,8 @@ const QPixmap &Image::pixBlurredSingle(
|
||||||
int outerw,
|
int outerw,
|
||||||
int outerh,
|
int outerh,
|
||||||
ImageRoundRadius radius,
|
ImageRoundRadius radius,
|
||||||
RectParts corners) const {
|
RectParts corners,
|
||||||
|
const style::color *colored) const {
|
||||||
if (w <= 0 || !width() || !height()) {
|
if (w <= 0 || !width() || !height()) {
|
||||||
w = width() * cIntRetinaFactor();
|
w = width() * cIntRetinaFactor();
|
||||||
} else {
|
} else {
|
||||||
|
@ -365,11 +366,14 @@ const QPixmap &Image::pixBlurredSingle(
|
||||||
} else if (radius == ImageRoundRadius::Ellipse) {
|
} else if (radius == ImageRoundRadius::Ellipse) {
|
||||||
options |= Option::Circled | cornerOptions(corners);
|
options |= Option::Circled | cornerOptions(corners);
|
||||||
}
|
}
|
||||||
|
if (colored) {
|
||||||
|
options |= Option::Colored;
|
||||||
|
}
|
||||||
|
|
||||||
auto k = SinglePixKey(options);
|
auto k = SinglePixKey(options);
|
||||||
auto i = _cache.find(k);
|
auto i = _cache.find(k);
|
||||||
if (i == _cache.cend() || i->second.width() != (outerw * cIntRetinaFactor()) || i->second.height() != (outerh * cIntRetinaFactor())) {
|
if (i == _cache.cend() || i->second.width() != (outerw * cIntRetinaFactor()) || i->second.height() != (outerh * cIntRetinaFactor())) {
|
||||||
auto p = pixNoCache(w, h, options, outerw, outerh);
|
auto p = pixNoCache(w, h, options, outerw, outerh, colored);
|
||||||
p.setDevicePixelRatio(cRetinaFactor());
|
p.setDevicePixelRatio(cRetinaFactor());
|
||||||
i = _cache.emplace_or_assign(k, p).first;
|
i = _cache.emplace_or_assign(k, p).first;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,8 @@ public:
|
||||||
int outerw,
|
int outerw,
|
||||||
int outerh,
|
int outerh,
|
||||||
ImageRoundRadius radius,
|
ImageRoundRadius radius,
|
||||||
RectParts corners = RectPart::AllCorners) const;
|
RectParts corners = RectPart::AllCorners,
|
||||||
|
const style::color *colored = nullptr) const;
|
||||||
[[nodiscard]] const QPixmap &pixCircled(int w = 0, int h = 0) const;
|
[[nodiscard]] const QPixmap &pixCircled(int w = 0, int h = 0) const;
|
||||||
[[nodiscard]] const QPixmap &pixBlurredCircled(int w = 0, int h = 0) const;
|
[[nodiscard]] const QPixmap &pixBlurredCircled(int w = 0, int h = 0) const;
|
||||||
[[nodiscard]] QPixmap pixNoCache(
|
[[nodiscard]] QPixmap pixNoCache(
|
||||||
|
|
Loading…
Add table
Reference in a new issue