From a4ea4689a260a59fbe5436718a262a94caacafcf Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 20 Dec 2019 17:13:55 +0300 Subject: [PATCH] Autoplay full-width videos in albums. --- Telegram/CMakeLists.txt | 2 - Telegram/Resources/langs/lang.strings | 2 +- .../SourceFiles/data/data_media_types.cpp | 1 - .../history/view/media/history_view_gif.cpp | 284 +++++--- .../history/view/media/history_view_gif.h | 8 +- .../history/view/media/history_view_media.cpp | 1 + .../history/view/media/history_view_media.h | 2 + .../view/media/history_view_media_common.cpp | 1 - .../view/media/history_view_media_grouped.cpp | 22 +- .../view/media/history_view_media_grouped.h | 2 + .../history/view/media/history_view_photo.cpp | 2 + .../history/view/media/history_view_photo.h | 2 + .../history/view/media/history_view_video.cpp | 622 ------------------ .../history/view/media/history_view_video.h | 106 --- 14 files changed, 222 insertions(+), 835 deletions(-) delete mode 100644 Telegram/SourceFiles/history/view/media/history_view_video.cpp delete mode 100644 Telegram/SourceFiles/history/view/media/history_view_video.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 55be51a5e..5567ef226 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -419,8 +419,6 @@ PRIVATE history/view/media/history_view_sticker.cpp history/view/media/history_view_theme_document.h history/view/media/history_view_theme_document.cpp - history/view/media/history_view_video.h - history/view/media/history_view_video.cpp history/view/media/history_view_web_page.h history/view/media/history_view_web_page.cpp history/view/history_view_compose_controls.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 235d47775..e15261dc9 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -416,7 +416,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_settings_performance" = "Performance"; "lng_settings_enable_animations" = "Enable animations"; "lng_settings_autoplay_gifs" = "Autoplay GIFs"; -"lng_settings_autoplay_videos" = "Autoplay video files"; +"lng_settings_autoplay_videos" = "Autoplay Videos"; "lng_settings_sensitive_title" = "Sensitive content"; "lng_settings_sensitive_disable_filtering" = "Disable filtering"; "lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices."; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index d5df18e86..34939fb5d 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/media/history_view_photo.h" #include "history/view/media/history_view_sticker.h" #include "history/view/media/history_view_gif.h" -#include "history/view/media/history_view_video.h" #include "history/view/media/history_view_document.h" #include "history/view/media/history_view_contact.h" #include "history/view/media/history_view_location.h" diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index a77226b6f..20aba0af9 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -247,8 +247,8 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; const auto item = _parent->data(); - auto displayLoading = (item->id < 0) || _data->displayLoading(); - auto selected = (selection == FullSelection); + const auto displayLoading = (item->id < 0) || _data->displayLoading(); + const auto selected = (selection == FullSelection); const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any); const auto cornerDownload = downloadInCorner(); const auto canBePlayed = _data->canBePlayed(); @@ -493,7 +493,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms } if (!isRound) { - drawCornerStatus(p, selected); + drawCornerStatus(p, selected, QPoint()); } if (!inWebPage && isRound) { @@ -597,7 +597,7 @@ void Gif::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms } } -void Gif::drawCornerStatus(Painter &p, bool selected) const { +void Gif::drawCornerStatus(Painter &p, bool selected, QPoint position) const { if (!needInfoDisplay()) { return; } @@ -614,8 +614,8 @@ void Gif::drawCornerStatus(Painter &p, bool selected) const { const auto downloadWidth = cornerDownload ? st::normalFont->width(_downloadSize) : 0; const auto statusW = std::max(downloadWidth, st::normalFont->width(text)) + 2 * padding.x() + addLeft + addRight; const auto statusH = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : (st::normalFont->height + 2 * padding.y()); - const auto statusX = st::msgDateImgDelta + padding.x(); - const auto statusY = st::msgDateImgDelta + padding.y(); + const auto statusX = position.x() + st::msgDateImgDelta + padding.x(); + const auto statusY = position.y() + st::msgDateImgDelta + padding.y(); const auto around = style::rtlrect(statusX - padding.x(), statusY - padding.y(), statusW, statusH, width()); const auto statusTextTop = statusY + (cornerDownload ? (((statusH - 2 * st::normalFont->height) / 3) - padding.y()) : 0); App::roundRect(p, around, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners); @@ -646,14 +646,16 @@ void Gif::drawCornerStatus(Painter &p, bool selected) const { TextState Gif::cornerStatusTextState( QPoint point, - StateRequest request) const { + StateRequest request, + QPoint position) const { auto result = TextState(_parent); if (!needInfoDisplay() || !downloadInCorner() || _data->loaded()) { return result; } const auto padding = st::msgDateImgPadding; const auto addWidth = st::historyVideoDownloadSize + 2 * padding.y() - padding.x(); - const auto statusX = st::msgDateImgDelta + padding.x(), statusY = st::msgDateImgDelta + padding.y(); + const auto statusX = position.x() + st::msgDateImgDelta + padding.x(); + const auto statusY = position.y() + st::msgDateImgDelta + padding.y(); const auto inner = QRect(statusX + padding.y() - padding.x(), statusY, st::historyVideoDownloadSize, st::historyVideoDownloadSize); if (inner.contains(point)) { result.link = _data->loading() ? _cancell : _savel; @@ -760,20 +762,20 @@ TextState Gif::textState(QPoint point, StateRequest request) const { } } if (!isRound) { - if (const auto state = cornerStatusTextState(point, request); state.link) { + if (const auto state = cornerStatusTextState(point, request, QPoint()); state.link) { return state; } } if (QRect(usex + paintx, painty, usew, painth).contains(point)) { - if (_data->uploading()) { - result.link = _cancell; - } else { - result.link = (_data->loaded() || _data->canBePlayed()) - ? _openl : - _data->loading() - ? _cancell - : _savel; - } + result.link = _data->uploading() + ? _cancell + : !IsServerMsgId(_realParent->id) + ? nullptr + : (_data->loaded() || _data->canBePlayed()) + ? _openl + : _data->loading() + ? _cancell + : _savel; } if (isRound || _caption.isEmpty()) { auto fullRight = usex + paintx + usew; @@ -818,6 +820,10 @@ TextForMimeData Gif::selectedText(TextSelection selection) const { return _caption.toTextForMimeData(selection); } +bool Gif::fullFeaturedGrouped(RectParts sides) const { + return (sides & RectPart::Left) && (sides & RectPart::Right); +} + QSize Gif::sizeForGrouping() const { return sizeForAspectRatio(); } @@ -828,113 +834,207 @@ void Gif::drawGrouped( TextSelection selection, crl::time ms, const QRect &geometry, + RectParts sides, RectParts corners, not_null cacheKey, not_null cache) const { - validateGroupedCache(geometry, corners, cacheKey, cache); - + const auto item = _parent->data(); + const auto displayLoading = (item->id < 0) || _data->displayLoading(); const auto selected = (selection == FullSelection); - const auto loaded = _data->loaded(); - const auto displayLoading = _data->displayLoading(); - const auto bubble = _parent->hasBubble(); + const auto autoPaused = App::wnd()->sessionController()->isGifPausedAtLeastFor(Window::GifPauseReason::Any); + const auto fullFeatured = fullFeaturedGrouped(sides); + const auto cornerDownload = fullFeatured && downloadInCorner(); + const auto canBePlayed = _data->canBePlayed(); + const auto autoplay = fullFeatured && autoplayEnabled() && canBePlayed; + const auto startPlayAsync = autoplay && !_streamed; + if (startPlayAsync) { + if (!autoPaused) { + const_cast(this)->playAnimation(true); + } + } else { + checkStreamedIsStarted(); + } + const auto streamingMode = _streamed || autoplay; + const auto activeOwnPlaying = activeOwnStreamed(); - if (displayLoading) { + auto paintx = geometry.x(), painty = geometry.y(), paintw = geometry.width(), painth = geometry.height(); + + auto displayMute = false; + const auto streamed = activeOwnPlaying + ? &activeOwnPlaying->instance + : nullptr; + + if (displayLoading + && (!streamed + || item->isSending() + || (cornerDownload && _data->loading()))) { ensureAnimation(); if (!_animation->radial.animating()) { - _animation->radial.start(_data->progress()); + _animation->radial.start(dataProgress()); } } - const auto radial = isRadialAnimation(); + updateStatusText(); + const auto radial = isRadialAnimation() + || (streamed && streamed->waitingShown()); - if (!bubble) { -// App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners); + const auto roundRadius = ImageRoundRadius::Large; + + if (streamed) { + const auto paused = autoPaused; + auto request = ::Media::Streaming::FrameRequest(); + const auto original = sizeForAspectRatio(); + const auto originalWidth = style::ConvertScale(original.width()); + const auto originalHeight = style::ConvertScale(original.height()); + const auto pixSize = Ui::GetImageScaleSizeForGeometry( + { originalWidth, originalHeight }, + { geometry.width(), geometry.height() }); + request.outer = geometry.size() * cIntRetinaFactor(); + request.resize = pixSize * cIntRetinaFactor(); + request.corners = corners; + request.radius = roundRadius; + if (activeOwnPlaying->instance.playerLocked()) { + if (activeOwnPlaying->frozenFrame.isNull()) { + activeOwnPlaying->frozenRequest = request; + activeOwnPlaying->frozenFrame = streamed->frame(request); + activeOwnPlaying->frozenStatusText = _statusText; + } else if (activeOwnPlaying->frozenRequest != request) { + activeOwnPlaying->frozenRequest = request; + activeOwnPlaying->frozenFrame = streamed->frame(request); + } + p.drawImage(geometry, activeOwnPlaying->frozenFrame); + } else { + if (activeOwnPlaying) { + activeOwnPlaying->frozenFrame = QImage(); + activeOwnPlaying->frozenStatusText = QString(); + } + p.drawImage(geometry, streamed->frame(request)); + if (!paused) { + streamed->markFrameShown(); + } + } + } else { + validateGroupedCache(geometry, corners, cacheKey, cache); + p.drawPixmap(geometry, *cache); } - p.drawPixmap(geometry.topLeft(), *cache); + if (selected) { - const auto roundRadius = ImageRoundRadius::Large; App::complexOverlayRect(p, geometry, roundRadius, corners); } - const auto radialOpacity = radial - ? _animation->radial.opacity() - : 1.; - const auto backOpacity = (loaded && !_data->uploading()) - ? radialOpacity - : 1.; - const auto radialSize = st::historyGroupRadialSize; - const auto inner = QRect( - geometry.x() + (geometry.width() - radialSize) / 2, - geometry.y() + (geometry.height() - radialSize) / 2, - radialSize, - radialSize); - p.setPen(Qt::NoPen); - if (selected) { - p.setBrush(st::msgDateImgBgSelected); - } else if (isThumbAnimation()) { - auto over = _animation->a_thumbOver.value(1.); - p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, over)); - } else { - auto over = ClickHandler::showAsActive(_data->loading() ? _cancell : _savel); - p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); - } - - p.setOpacity(backOpacity * p.opacity()); - - { - PainterHighQualityEnabler hq(p); - p.drawEllipse(inner); - } - - auto icon = [&]() -> const style::icon * { - if (_data->waitingForAlbum()) { - return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting); - } else if (_data->loading() || _data->uploading()) { - return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); - } else if (!IsServerMsgId(_realParent->id)) { - return nullptr; - } else if (loaded || _data->canBePlayed()) { - return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay); - } - return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); - }(); - const auto previous = [&]() -> const style::icon* { - if (_data->waitingForAlbum()) { - return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); - } - return nullptr; - }(); - p.setOpacity(backOpacity); - if (icon) { - if (previous && radialOpacity > 0. && radialOpacity < 1.) { - PaintInterpolatedIcon(p, *icon, *previous, radialOpacity, inner); + if (radial + || (!streamingMode + && ((!_data->loaded() && !_data->loading()) + || !autoplayEnabled()))) { + const auto radialOpacity = item->isSending() + ? 1. + : streamed + ? streamed->waitingOpacity() + : (radial && _data->loaded()) + ? _animation->radial.opacity() + : 1.; + const auto radialSize = st::historyGroupRadialSize; + const auto inner = QRect( + geometry.x() + (geometry.width() - radialSize) / 2, + geometry.y() + (geometry.height() - radialSize) / 2, + radialSize, + radialSize); + p.setPen(Qt::NoPen); + if (selected) { + p.setBrush(st::msgDateImgBgSelected); + } else if (isThumbAnimation()) { + auto over = _animation->a_thumbOver.value(1.); + p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, over)); } else { - icon->paintInCenter(p, inner); + auto over = ClickHandler::showAsActive(_data->loading() ? _cancell : _savel); + p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); + } + p.setOpacity(radialOpacity * p.opacity()); + + { + PainterHighQualityEnabler hq(p); + p.drawEllipse(inner); + } + + p.setOpacity(radialOpacity); + const auto icon = [&]() -> const style::icon * { + if (_data->waitingForAlbum()) { + return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting); + } else if (streamingMode && !_data->uploading()) { + return nullptr; + } else if ((_data->loaded() || canBePlayed) && (!radial || cornerDownload)) { + return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay); + } else if (radial || _data->loading()) { + if (!item->isSending() || _data->uploading()) { + return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); + } + return nullptr; + } + return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); + }(); + const auto previous = [&]() -> const style::icon* { + if (_data->waitingForAlbum()) { + return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); + } + return nullptr; + }(); + if (icon) { + if (previous && radialOpacity > 0. && radialOpacity < 1.) { + PaintInterpolatedIcon(p, *icon, *previous, radialOpacity, inner); + } else { + icon->paintInCenter(p, inner); + } + } + p.setOpacity(1); + if (radial) { + const auto line = st::historyGroupRadialLine; + const auto rinner = inner.marginsRemoved({ line, line, line, line }); + const auto fg = selected + ? st::historyFileThumbRadialFgSelected + : st::historyFileThumbRadialFg; + if (streamed && !_data->uploading()) { + Ui::InfiniteRadialAnimation::Draw( + p, + streamed->waitingState(), + rinner.topLeft(), + rinner.size(), + width(), + fg, + st::msgFileRadialLine); + } else if (!cornerDownload) { + _animation->radial.draw( + p, + rinner, + st::msgFileRadialLine, + fg); + } } } - p.setOpacity(1); - if (radial) { - const auto line = st::historyGroupRadialLine; - const auto rinner = inner.marginsRemoved({ line, line, line, line }); - const auto color = selected - ? st::historyFileThumbRadialFgSelected - : st::historyFileThumbRadialFg; - _animation->radial.draw(p, rinner, line, color); + if (fullFeatured) { + drawCornerStatus(p, selected, geometry.topLeft()); } } TextState Gif::getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const { if (!geometry.contains(point)) { return {}; } - return TextState(_parent, (_data->loading() || _data->uploading()) + if (fullFeaturedGrouped(sides)) { + if (const auto state = cornerStatusTextState(point, request, geometry.topLeft()); state.link) { + return state; + } + } + return TextState(_parent, _data->uploading() ? _cancell : !IsServerMsgId(_realParent->id) ? nullptr : (_data->loaded() || _data->canBePlayed()) ? _openl + : _data->loading() + ? _cancell : _savel); } diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h index 18b4907ef..4ace8dfe8 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.h +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h @@ -63,6 +63,7 @@ public: return _data; } + bool fullFeaturedGrouped(RectParts sides) const; QSize sizeForGrouping() const override; void drawGrouped( Painter &p, @@ -70,11 +71,13 @@ public: TextSelection selection, crl::time ms, const QRect &geometry, + RectParts sides, RectParts corners, not_null cacheKey, not_null cache) const override; TextState getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const override; @@ -147,10 +150,11 @@ private: QSize sizeForAspectRatio() const; [[nodiscard]] bool downloadInCorner() const; - void drawCornerStatus(Painter &p, bool selected) const; + void drawCornerStatus(Painter &p, bool selected, QPoint position) const; [[nodiscard]] TextState cornerStatusTextState( QPoint point, - StateRequest request) const; + StateRequest request, + QPoint position) const; not_null _data; int _thumbw = 1; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.cpp b/Telegram/SourceFiles/history/view/media/history_view_media.cpp index 5d2a9cc41..8339b1637 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media.cpp @@ -66,6 +66,7 @@ PointState Media::pointState(QPoint point) const { TextState Media::getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const { Unexpected("Grouping method call."); diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 134d8745e..99507e18d 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -145,6 +145,7 @@ public: TextSelection selection, crl::time ms, const QRect &geometry, + RectParts sides, RectParts corners, not_null cacheKey, not_null cache) const { @@ -152,6 +153,7 @@ public: } [[nodiscard]] virtual TextState getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp index bf949d31d..090d94246 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_common.cpp @@ -15,7 +15,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/view/media/history_view_gif.h" #include "history/view/media/history_view_document.h" #include "history/view/media/history_view_sticker.h" -#include "history/view/media/history_view_video.h" #include "history/view/media/history_view_theme_document.h" #include "styles/style_history.h" diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp index cccc8ea96..18af76bdf 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.cpp @@ -160,6 +160,17 @@ void GroupedMedia::refreshParentId( } } +RectParts GroupedMedia::cornersFromSides(RectParts sides) const { + auto result = Ui::GetCornersFromSides(sides); + if (!isBubbleTop()) { + result &= ~(RectPart::TopLeft | RectPart::TopRight); + } + if (!isBubbleBottom() || !_caption.isEmpty()) { + result &= ~(RectPart::BottomLeft | RectPart::BottomRight); + } + return result; +} + void GroupedMedia::draw( Painter &p, const QRect &clip, @@ -172,20 +183,14 @@ void GroupedMedia::draw( : IsGroupItemSelection(selection, i) ? FullSelection : TextSelection(); - auto corners = Ui::GetCornersFromSides(part.sides); - if (!isBubbleTop()) { - corners &= ~(RectPart::TopLeft | RectPart::TopRight); - } - if (!isBubbleBottom() || !_caption.isEmpty()) { - corners &= ~(RectPart::BottomLeft | RectPart::BottomRight); - } part.content->drawGrouped( p, clip, partSelection, ms, part.geometry, - corners, + part.sides, + cornersFromSides(part.sides), &part.cacheKey, &part.cache); } @@ -221,6 +226,7 @@ TextState GroupedMedia::getPartState( if (part.geometry.contains(point)) { auto result = part.content->getStateGrouped( part.geometry, + part.sides, point, request); result.itemId = part.item->fullId(); diff --git a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h index b5cdc9478..0c5323019 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media_grouped.h @@ -121,6 +121,8 @@ private: QPoint point, StateRequest request) const; + [[nodiscard]] RectParts cornersFromSides(RectParts sides) const; + Ui::Text::String _caption; std::vector _parts; bool _needBubble = false; diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp index 9d7e1b6d4..2b326315b 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.cpp @@ -345,6 +345,7 @@ void Photo::drawGrouped( TextSelection selection, crl::time ms, const QRect &geometry, + RectParts sides, RectParts corners, not_null cacheKey, not_null cache) const { @@ -448,6 +449,7 @@ void Photo::drawGrouped( TextState Photo::getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const { if (!geometry.contains(point)) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_photo.h b/Telegram/SourceFiles/history/view/media/history_view_photo.h index 6bb23681d..fd9295b90 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_photo.h +++ b/Telegram/SourceFiles/history/view/media/history_view_photo.h @@ -51,11 +51,13 @@ public: TextSelection selection, crl::time ms, const QRect &geometry, + RectParts sides, RectParts corners, not_null cacheKey, not_null cache) const override; TextState getStateGrouped( const QRect &geometry, + RectParts sides, QPoint point, StateRequest request) const override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_video.cpp b/Telegram/SourceFiles/history/view/media/history_view_video.cpp deleted file mode 100644 index 12ef0cb56..000000000 --- a/Telegram/SourceFiles/history/view/media/history_view_video.cpp +++ /dev/null @@ -1,622 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "history/view/media/history_view_video.h" - -#include "history/view/media/history_view_media_common.h" -#include "layout.h" -#include "history/history_item_components.h" -#include "history/history_item.h" -#include "history/history.h" -#include "history/view/history_view_element.h" -#include "history/view/history_view_cursor_state.h" -#include "ui/image/image.h" -#include "ui/grouped_layout.h" -#include "data/data_session.h" -#include "data/data_document.h" -#include "data/data_file_origin.h" -#include "app.h" -#include "styles/style_history.h" - -namespace HistoryView { - -Video::Video( - not_null parent, - not_null realParent, - not_null document) -: File(parent, realParent) -, _data(document) -, _thumbw(1) -, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { - _caption = createCaption(realParent); - - setDocumentLinks(_data, realParent); - - setStatusSize(FileStatusSizeReady); - _downloadSize = formatSizeText(_data->size); - - _data->loadThumbnail(realParent->fullId()); -} - -QSize Video::sizeForAspectRatio() const { - // We use size only for aspect ratio and we want to have it - // as close to the thumbnail as possible. - //if (!_data->dimensions.isEmpty()) { - // return _data->dimensions; - //} - if (const auto thumb = _data->thumbnail()) { - if (!thumb->size().isEmpty()) { - return thumb->size(); - } - } - return { 1, 1 }; -} - -QSize Video::countOptimalDimensions() const { - const auto desired = style::ConvertScale(_data->dimensions); - const auto size = desired.isEmpty() ? sizeForAspectRatio() : desired; - auto tw = size.width(); - auto th = size.height(); - if (!tw || !th) { - tw = th = 1; - } else if (tw >= th && tw > st::maxMediaSize) { - th = qRound((st::maxMediaSize / float64(tw)) * th); - tw = st::maxMediaSize; - } else if (tw < th && th > st::maxMediaSize) { - tw = qRound((st::maxMediaSize / float64(th)) * tw); - th = st::maxMediaSize; - } else if ((tw < st::msgVideoSize.width()) - && (tw * st::msgVideoSize.height() - >= th * st::msgVideoSize.width())) { - th = qRound((st::msgVideoSize.width() / float64(tw)) * th); - tw = st::msgVideoSize.width(); - } else if ((th < st::msgVideoSize.height()) - && (tw * st::msgVideoSize.height() - < th * st::msgVideoSize.width())) { - tw = qRound((st::msgVideoSize.height() / float64(th)) * tw); - th = st::msgVideoSize.height(); - } - return QSize(tw, th); -} - -QSize Video::countOptimalSize() { - if (_parent->media() != this) { - _caption = Ui::Text::String(); - } else if (_caption.hasSkipBlock()) { - _caption.updateSkipBlock( - _parent->skipBlockWidth(), - _parent->skipBlockHeight()); - } - - const auto size = countOptimalDimensions(); - const auto tw = size.width(); - const auto th = size.height(); - _thumbw = qMax(tw, 1); - _thumbh = qMax(th, 1); - - auto minWidth = qMax(st::minVideoSize, _parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x())); - minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x())); - auto maxWidth = qMax(_thumbw, minWidth); - auto minHeight = qMax(th, st::minVideoSize); - if (_parent->hasBubble() && !_caption.isEmpty()) { - const auto captionw = maxWidth - - st::msgPadding.left() - - st::msgPadding.right(); - minHeight += st::mediaCaptionSkip + _caption.countHeight(captionw); - if (isBubbleBottom()) { - minHeight += st::msgPadding.bottom(); - } - } - return { maxWidth, minHeight }; -} - -QSize Video::countCurrentSize(int newWidth) { - const auto size = countOptimalDimensions(); - auto tw = size.width(); - auto th = size.height(); - if (newWidth < tw) { - th = qRound((newWidth / float64(tw)) * th); - tw = newWidth; - } - - _thumbw = qMax(tw, 1); - _thumbh = qMax(th, 1); - auto minWidth = qMax(st::minPhotoSize, _parent->infoWidth() + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x())); - minWidth = qMax(minWidth, documentMaxStatusWidth(_data) + 2 * (st::msgDateImgDelta + st::msgDateImgPadding.x())); - newWidth = qMax(_thumbw, minWidth); - auto newHeight = qMax(th, st::minPhotoSize); - if (_parent->hasBubble() && !_caption.isEmpty()) { - const auto captionw = newWidth - - st::msgPadding.left() - - st::msgPadding.right(); - newHeight += st::mediaCaptionSkip + _caption.countHeight(captionw); - if (isBubbleBottom()) { - newHeight += st::msgPadding.bottom(); - } - } - return { newWidth, newHeight }; -} - -bool Video::downloadInCorner() const { - return _data->canBeStreamed() - && !_data->inappPlaybackFailed() - && IsServerMsgId(_parent->data()->id); -} - -void Video::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const { - if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return; - - _data->automaticLoad(_realParent->fullId(), _parent->data()); - bool loaded = _data->loaded(), displayLoading = _data->displayLoading(); - bool selected = (selection == FullSelection); - - auto paintx = 0, painty = 0, paintw = width(), painth = height(); - bool bubble = _parent->hasBubble(); - const auto cornerDownload = downloadInCorner(); - - int captionw = paintw - st::msgPadding.left() - st::msgPadding.right(); - - if (displayLoading) { - ensureAnimation(); - if (!_animation->radial.animating()) { - _animation->radial.start(_data->progress()); - } - } - updateStatusText(); - const auto radial = isRadialAnimation(); - - if (bubble) { - if (!_caption.isEmpty()) { - painth -= st::mediaCaptionSkip + _caption.countHeight(captionw); - if (isBubbleBottom()) { - painth -= st::msgPadding.bottom(); - } - } - } else { - App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners); - } - - auto inWebPage = (_parent->media() != this); - auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large; - auto roundCorners = inWebPage ? RectPart::AllCorners : ((isBubbleTop() ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) - | ((isBubbleBottom() && _caption.isEmpty()) ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None)); - QRect rthumb(style::rtlrect(paintx, painty, paintw, painth, width())); - - const auto good = _data->goodThumbnail(); - if (good && good->loaded()) { - p.drawPixmap(rthumb.topLeft(), good->pixSingle({}, _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners)); - } else { - if (good) { - good->load({}); - } - const auto normal = _data->thumbnail(); - if (normal && normal->loaded()) { - p.drawPixmap(rthumb.topLeft(), normal->pixSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners)); - } else if (const auto blurred = _data->thumbnailInline()) { - p.drawPixmap(rthumb.topLeft(), blurred->pixBlurredSingle(_realParent->fullId(), _thumbw, _thumbh, paintw, painth, roundRadius, roundCorners)); - } else { - const auto roundTop = (roundCorners & RectPart::TopLeft); - const auto roundBottom = (roundCorners & RectPart::BottomLeft); - const auto margin = inWebPage - ? st::buttonRadius - : st::historyMessageRadius; - const auto parts = roundCorners - | RectPart::NoTopBottom - | (roundTop ? RectPart::Top : RectPart::None) - | (roundBottom ? RectPart::Bottom : RectPart::None); - App::roundRect(p, rthumb.marginsAdded({ 0, roundTop ? 0 : margin, 0, roundBottom ? 0 : margin }), st::imageBg, roundRadius, parts); - } - } - if (selected) { - App::complexOverlayRect(p, rthumb, roundRadius, roundCorners); - } - - QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize); - p.setPen(Qt::NoPen); - if (selected) { - p.setBrush(st::msgDateImgBgSelected); - } else if (isThumbAnimation()) { - auto over = _animation->a_thumbOver.value(1.); - p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, over)); - } else { - bool over = ClickHandler::showAsActive((_data->loading() || _data->uploading()) ? _cancell : _savel); - p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); - } - - { - PainterHighQualityEnabler hq(p); - p.drawEllipse(inner); - } - - const auto icon = [&]() -> const style::icon * { - if (!cornerDownload && (_data->loading() || _data->uploading())) { - return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); - } else if (!IsServerMsgId(_parent->data()->id)) { - return nullptr; - } else if (loaded || _data->canBePlayed()) { - return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay); - } - return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); - }(); - if (icon) { - icon->paintInCenter(p, inner); - } - if (radial && !cornerDownload) { - QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine))); - _animation->radial.draw(p, rinner, st::msgFileRadialLine, selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg); - } - - drawCornerStatus(p, selected); - - // date - if (!_caption.isEmpty()) { - auto outbg = _parent->hasOutLayout(); - p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg)); - _caption.draw(p, st::msgPadding.left(), painty + painth + st::mediaCaptionSkip, captionw, style::al_left, 0, -1, selection); - } else if (_parent->media() == this) { - auto fullRight = paintx + paintw, fullBottom = painty + painth; - _parent->drawInfo(p, fullRight, fullBottom, 2 * paintx + paintw, selected, InfoDisplayType::Image); - if (!bubble && _parent->displayRightAction()) { - auto fastShareLeft = (fullRight + st::historyFastShareLeft); - auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize); - _parent->drawRightAction(p, fastShareLeft, fastShareTop, 2 * paintx + paintw); - } - } -} - -void Video::drawCornerStatus(Painter &p, bool selected) const { - const auto padding = st::msgDateImgPadding; - const auto radial = _animation && _animation->radial.animating(); - const auto cornerDownload = downloadInCorner() && !_data->loaded() && !_data->loadedInMediaCache(); - const auto addWidth = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : 0; - const auto downloadWidth = cornerDownload ? st::normalFont->width(_downloadSize) : 0; - const auto statusW = std::max(downloadWidth, st::normalFont->width(_statusText)) + 2 * padding.x() + addWidth; - const auto statusH = cornerDownload ? (st::historyVideoDownloadSize + 2 * padding.y()) : (st::normalFont->height + 2 * padding.y()); - const auto statusX = st::msgDateImgDelta + padding.x(); - const auto statusY = st::msgDateImgDelta + padding.y(); - const auto around = style::rtlrect(statusX - padding.x(), statusY - padding.y(), statusW, statusH, width()); - const auto statusTextTop = statusY + (cornerDownload ? (((statusH - 2 * st::normalFont->height) / 3) - padding.y()) : 0); - App::roundRect(p, around, selected ? st::msgDateImgBgSelected : st::msgDateImgBg, selected ? DateSelectedCorners : DateCorners); - p.setFont(st::normalFont); - p.setPen(st::msgDateImgFg); - p.drawTextLeft(statusX + addWidth, statusTextTop, width(), _statusText, statusW - 2 * padding.x()); - if (cornerDownload) { - const auto downloadTextTop = statusY + st::normalFont->height + (2 * (statusH - 2 * st::normalFont->height) / 3) - padding.y(); - p.drawTextLeft(statusX + addWidth, downloadTextTop, width(), _downloadSize, statusW - 2 * padding.x()); - const auto inner = QRect(statusX + padding.y() - padding.x(), statusY, st::historyVideoDownloadSize, st::historyVideoDownloadSize); - const auto icon = [&]() -> const style::icon * { - if (_data->loading()) { - return &(selected ? st::historyVideoCancelSelected : st::historyVideoCancel); - } - return &(selected ? st::historyVideoDownloadSelected : st::historyVideoDownload); - }(); - if (icon) { - icon->paintInCenter(p, inner); - } - if (radial) { - QRect rinner(inner.marginsRemoved(QMargins(st::historyVideoRadialLine, st::historyVideoRadialLine, st::historyVideoRadialLine, st::historyVideoRadialLine))); - _animation->radial.draw(p, rinner, st::historyVideoRadialLine, selected ? st::historyFileThumbRadialFgSelected : st::historyFileThumbRadialFg); - } - } -} - -TextState Video::cornerStatusTextState( - QPoint point, - StateRequest request) const { - auto result = TextState(_parent); - if (!downloadInCorner() || _data->loaded()) { - return result; - } - const auto padding = st::msgDateImgPadding; - const auto addWidth = st::historyVideoDownloadSize + 2 * padding.y() - padding.x(); - const auto statusX = st::msgDateImgDelta + padding.x(), statusY = st::msgDateImgDelta + padding.y(); - const auto inner = QRect(statusX + padding.y() - padding.x(), statusY, st::historyVideoDownloadSize, st::historyVideoDownloadSize); - if (inner.contains(point)) { - result.link = _data->loading() ? _cancell : _savel; - } - return result; -} - -TextState Video::textState(QPoint point, StateRequest request) const { - if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) { - return {}; - } - - auto result = TextState(_parent); - - auto paintx = 0, painty = 0, paintw = width(), painth = height(); - bool bubble = _parent->hasBubble(); - - if (bubble && !_caption.isEmpty()) { - const auto captionw = paintw - - st::msgPadding.left() - - st::msgPadding.right(); - painth -= _caption.countHeight(captionw); - if (isBubbleBottom()) { - painth -= st::msgPadding.bottom(); - } - if (QRect(st::msgPadding.left(), painth, captionw, height() - painth).contains(point)) { - result = TextState(_parent, _caption.getState( - point - QPoint(st::msgPadding.left(), painth), - captionw, - request.forText())); - } - painth -= st::mediaCaptionSkip; - } - if (const auto state = cornerStatusTextState(point, request); state.link) { - return state; - } - if (QRect(paintx, painty, paintw, painth).contains(point)) { - if (!downloadInCorner() && (_data->loading() || _data->uploading())) { - result.link = _cancell; - } else if (!IsServerMsgId(_parent->data()->id)) { - } else if (_data->loaded() || _data->canBePlayed()) { - result.link = _openl; - } else { - result.link = _savel; - } - } - if (_caption.isEmpty() && _parent->media() == this) { - auto fullRight = paintx + paintw; - auto fullBottom = painty + painth; - if (_parent->pointInTime(fullRight, fullBottom, point, InfoDisplayType::Image)) { - result.cursor = CursorState::Date; - } - if (!bubble && _parent->displayRightAction()) { - auto fastShareLeft = (fullRight + st::historyFastShareLeft); - auto fastShareTop = (fullBottom - st::historyFastShareBottom - st::historyFastShareSize); - if (QRect(fastShareLeft, fastShareTop, st::historyFastShareSize, st::historyFastShareSize).contains(point)) { - result.link = _parent->rightActionLink(); - } - } - } - return result; -} - -QSize Video::sizeForGrouping() const { - return sizeForAspectRatio(); -} - -void Video::drawGrouped( - Painter &p, - const QRect &clip, - TextSelection selection, - crl::time ms, - const QRect &geometry, - RectParts corners, - not_null cacheKey, - not_null cache) const { - _data->automaticLoad(_realParent->fullId(), _parent->data()); - - validateGroupedCache(geometry, corners, cacheKey, cache); - - const auto selected = (selection == FullSelection); - const auto loaded = _data->loaded(); - const auto displayLoading = _data->displayLoading(); - const auto bubble = _parent->hasBubble(); - - if (displayLoading) { - ensureAnimation(); - if (!_animation->radial.animating()) { - _animation->radial.start(_data->progress()); - } - } - const auto radial = isRadialAnimation(); - - if (!bubble) { -// App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners); - } - p.drawPixmap(geometry.topLeft(), *cache); - if (selected) { - const auto roundRadius = ImageRoundRadius::Large; - App::complexOverlayRect(p, geometry, roundRadius, corners); - } - - const auto radialOpacity = radial - ? _animation->radial.opacity() - : 1.; - const auto backOpacity = (loaded && !_data->uploading()) - ? radialOpacity - : 1.; - const auto radialSize = st::historyGroupRadialSize; - const auto inner = QRect( - geometry.x() + (geometry.width() - radialSize) / 2, - geometry.y() + (geometry.height() - radialSize) / 2, - radialSize, - radialSize); - p.setPen(Qt::NoPen); - if (selected) { - p.setBrush(st::msgDateImgBgSelected); - } else if (isThumbAnimation()) { - auto over = _animation->a_thumbOver.value(1.); - p.setBrush(anim::brush(st::msgDateImgBg, st::msgDateImgBgOver, over)); - } else { - auto over = ClickHandler::showAsActive(_data->loading() ? _cancell : _savel); - p.setBrush(over ? st::msgDateImgBgOver : st::msgDateImgBg); - } - - p.setOpacity(backOpacity * p.opacity()); - - { - PainterHighQualityEnabler hq(p); - p.drawEllipse(inner); - } - - auto icon = [&]() -> const style::icon * { - if (_data->waitingForAlbum()) { - return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting); - } else if (_data->loading() || _data->uploading()) { - return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); - } else if (!IsServerMsgId(_realParent->id)) { - return nullptr; - } else if (loaded || _data->canBePlayed()) { - return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay); - } - return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload); - }(); - const auto previous = [&]() -> const style::icon* { - if (_data->waitingForAlbum()) { - return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel); - } - return nullptr; - }(); - p.setOpacity(backOpacity); - if (icon) { - if (previous && radialOpacity > 0. && radialOpacity < 1.) { - PaintInterpolatedIcon(p, *icon, *previous, radialOpacity, inner); - } else { - icon->paintInCenter(p, inner); - } - } - p.setOpacity(1); - if (radial) { - const auto line = st::historyGroupRadialLine; - const auto rinner = inner.marginsRemoved({ line, line, line, line }); - const auto color = selected - ? st::historyFileThumbRadialFgSelected - : st::historyFileThumbRadialFg; - _animation->radial.draw(p, rinner, line, color); - } -} - -TextState Video::getStateGrouped( - const QRect &geometry, - QPoint point, - StateRequest request) const { - if (!geometry.contains(point)) { - return {}; - } - return TextState(_parent, (_data->loading() || _data->uploading()) - ? _cancell - : !IsServerMsgId(_realParent->id) - ? nullptr - : (_data->loaded() || _data->canBePlayed()) - ? _openl - : _savel); -} - -bool Video::uploading() const { - return _data->uploading(); -} - -float64 Video::dataProgress() const { - return _data->progress(); -} - -bool Video::dataFinished() const { - return !_data->loading() - && (!_data->uploading() || _data->waitingForAlbum()); -} - -bool Video::dataLoaded() const { - return _data->loaded(); -} - -void Video::validateGroupedCache( - const QRect &geometry, - RectParts corners, - not_null cacheKey, - not_null cache) const { - using Option = Images::Option; - const auto good = _data->goodThumbnail(); - const auto useGood = (good && good->loaded()); - const auto thumb = _data->thumbnail(); - const auto useThumb = (thumb && thumb->loaded()); - const auto image = useGood - ? good - : useThumb - ? thumb - : _data->thumbnailInline(); - if (good && !useGood) { - good->load({}); - } - - const auto loadLevel = useGood ? 3 : useThumb ? 2 : image ? 1 : 0; - const auto width = geometry.width(); - const auto height = geometry.height(); - const auto options = Option::Smooth - | Option::RoundedLarge - | (useGood ? Option(0) : Option::Blurred) - | ((corners & RectPart::TopLeft) ? Option::RoundedTopLeft : Option::None) - | ((corners & RectPart::TopRight) ? Option::RoundedTopRight : Option::None) - | ((corners & RectPart::BottomLeft) ? Option::RoundedBottomLeft : Option::None) - | ((corners & RectPart::BottomRight) ? Option::RoundedBottomRight : Option::None); - const auto key = (uint64(width) << 48) - | (uint64(height) << 32) - | (uint64(options) << 16) - | (uint64(loadLevel)); - if (*cacheKey == key) { - return; - } - - const auto original = sizeForAspectRatio(); - const auto originalWidth = style::ConvertScale(original.width()); - const auto originalHeight = style::ConvertScale(original.height()); - const auto pixSize = Ui::GetImageScaleSizeForGeometry( - { originalWidth, originalHeight }, - { width, height }); - const auto pixWidth = pixSize.width() * cIntRetinaFactor(); - const auto pixHeight = pixSize.height() * cIntRetinaFactor(); - - *cacheKey = key; - *cache = (image ? image : Image::BlankMedia().get())->pixNoCache( - _realParent->fullId(), - pixWidth, - pixHeight, - options, - width, - height); -} - -void Video::setStatusSize(int newSize) const { - File::setStatusSize(newSize, _data->size, _data->getDuration(), 0); -} - -TextForMimeData Video::selectedText(TextSelection selection) const { - return _caption.toTextForMimeData(selection); -} - -bool Video::needsBubble() const { - if (!_caption.isEmpty()) { - return true; - } - const auto item = _parent->data(); - return item->viaBot() - || item->Has() - || _parent->displayForwardedFrom() - || _parent->displayFromName(); - return false; -} - -void Video::parentTextUpdated() { - _caption = (_parent->media() == this) - ? createCaption(_parent->data()) - : Ui::Text::String(); - history()->owner().requestViewResize(_parent); -} - -void Video::updateStatusText() const { - auto showPause = false; - auto statusSize = 0; - auto realDuration = 0; - if (_data->status == FileDownloadFailed || _data->status == FileUploadFailed) { - statusSize = FileStatusSizeFailed; - } else if (_data->uploading()) { - statusSize = _data->uploadingData->offset; - } else if (!downloadInCorner() && _data->loading()) { - statusSize = _data->loadOffset(); - } else if (_data->canBePlayed()) { - statusSize = FileStatusSizeLoaded; - } else { - statusSize = FileStatusSizeReady; - } - if (statusSize != _statusSize) { - setStatusSize(statusSize); - } -} - -} // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_video.h b/Telegram/SourceFiles/history/view/media/history_view_video.h deleted file mode 100644 index 33b63434a..000000000 --- a/Telegram/SourceFiles/history/view/media/history_view_video.h +++ /dev/null @@ -1,106 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#pragma once - -#include "history/view/media/history_view_file.h" - -namespace HistoryView { - -class Video : public File { -public: - Video( - not_null parent, - not_null realParent, - not_null document); - - void draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const override; - TextState textState(QPoint point, StateRequest request) const override; - - [[nodiscard]] TextSelection adjustSelection( - TextSelection selection, - TextSelectType type) const override { - return _caption.adjustSelection(selection, type); - } - uint16 fullSelectionLength() const override { - return _caption.length(); - } - bool hasTextForCopy() const override { - return !_caption.isEmpty(); - } - - TextForMimeData selectedText(TextSelection selection) const override; - - DocumentData *getDocument() const override { - return _data; - } - - QSize sizeForGrouping() const override; - void drawGrouped( - Painter &p, - const QRect &clip, - TextSelection selection, - crl::time ms, - const QRect &geometry, - RectParts corners, - not_null cacheKey, - not_null cache) const override; - TextState getStateGrouped( - const QRect &geometry, - QPoint point, - StateRequest request) const override; - - bool uploading() const override; - - TextWithEntities getCaption() const override { - return _caption.toTextWithEntities(); - } - bool needsBubble() const override; - bool customInfoLayout() const override { - return _caption.isEmpty(); - } - bool skipBubbleTail() const override { - return isBubbleBottom() && _caption.isEmpty(); - } - - void parentTextUpdated() override; - -protected: - float64 dataProgress() const override; - bool dataFinished() const override; - bool dataLoaded() const override; - -private: - [[nodiscard]] QSize countOptimalSize() override; - [[nodiscard]] QSize countCurrentSize(int newWidth) override; - [[nodiscard]] QSize countOptimalDimensions() const; - [[nodiscard]] bool downloadInCorner() const; - - void drawCornerStatus(Painter &p, bool selected) const; - [[nodiscard]] TextState cornerStatusTextState( - QPoint point, - StateRequest request) const; - - void validateGroupedCache( - const QRect &geometry, - RectParts corners, - not_null cacheKey, - not_null cache) const; - void setStatusSize(int newSize) const; - void updateStatusText() const; - QSize sizeForAspectRatio() const; - - not_null _data; - int _thumbw = 1; - int _thumbh = 1; - Ui::Text::String _caption; - - QString _downloadSize; - -}; - -} // namespace HistoryView