From 29a498b9598219f1ad92fd8115029c5e64909da7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 28 May 2020 17:05:44 +0400 Subject: [PATCH] Use Data::CloudImage for location thumbnails. --- Telegram/SourceFiles/data/data_location.cpp | 59 ++++++++++++---- Telegram/SourceFiles/data/data_location.h | 68 ++++--------------- .../SourceFiles/data/data_media_types.cpp | 10 +-- Telegram/SourceFiles/data/data_media_types.h | 12 ++-- Telegram/SourceFiles/data/data_session.cpp | 21 ++++-- Telegram/SourceFiles/data/data_session.h | 4 +- .../view/media/history_view_location.cpp | 24 ++++--- .../view/media/history_view_location.h | 19 +++++- 8 files changed, 124 insertions(+), 93 deletions(-) diff --git a/Telegram/SourceFiles/data/data_location.cpp b/Telegram/SourceFiles/data/data_location.cpp index 0c608b868..c26e50e71 100644 --- a/Telegram/SourceFiles/data/data_location.cpp +++ b/Telegram/SourceFiles/data/data_location.cpp @@ -13,7 +13,53 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Data { namespace { -GeoPointLocation ComputeLocation(const Data::LocationPoint &point) { +[[nodiscard]] QString AsString(float64 value) { + constexpr auto kPrecision = 6; + return QString::number(value, 'f', kPrecision); +} + +} // namespace + +LocationPoint::LocationPoint(const MTPDgeoPoint &point) +: _lat(point.vlat().v) +, _lon(point.vlong().v) +, _access(point.vaccess_hash().v) { +} + +QString LocationPoint::latAsString() const { + return AsString(_lat); +} + +QString LocationPoint::lonAsString() const { + return AsString(_lon); +} + +MTPGeoPoint LocationPoint::toMTP() const { + return MTP_geoPoint( + MTP_double(_lon), + MTP_double(_lat), + MTP_long(_access)); +} + +float64 LocationPoint::lat() const { + return _lat; +} + +float64 LocationPoint::lon() const { + return _lon; +} + +uint64 LocationPoint::accessHash() const { + return _access; +} + +size_t LocationPoint::hash() const { + return QtPrivate::QHashCombine().operator()( + std::hash()(_lat), + _lon); +} + +GeoPointLocation ComputeLocation(const LocationPoint &point) { const auto scale = 1 + (cScale() * cIntRetinaFactor()) / 200; const auto zoom = 13 + (scale - 1); const auto w = st::locationSize.width() / scale; @@ -30,15 +76,4 @@ GeoPointLocation ComputeLocation(const Data::LocationPoint &point) { return result; } -} // namespace - -LocationThumbnail::LocationThumbnail(const LocationPoint &point) -: point(point) -, thumb(Images::Create(ComputeLocation(point))) { -} - -void LocationThumbnail::load(FileOrigin origin) { - thumb->load(origin); -} - } // namespace Data diff --git a/Telegram/SourceFiles/data/data_location.h b/Telegram/SourceFiles/data/data_location.h index 00350af3e..7d9a59b4a 100644 --- a/Telegram/SourceFiles/data/data_location.h +++ b/Telegram/SourceFiles/data/data_location.h @@ -14,58 +14,28 @@ struct FileOrigin; class LocationPoint { public: LocationPoint() = default; - explicit LocationPoint(const MTPDgeoPoint &point) - : _lat(point.vlat().v) - , _lon(point.vlong().v) - , _access(point.vaccess_hash().v) { - } + explicit LocationPoint(const MTPDgeoPoint &point); - QString latAsString() const { - return AsString(_lat); - } - QString lonAsString() const { - return AsString(_lon); - } - MTPGeoPoint toMTP() const { - return MTP_geoPoint( - MTP_double(_lon), - MTP_double(_lat), - MTP_long(_access)); - } + [[nodiscard]] QString latAsString() const; + [[nodiscard]] QString lonAsString() const; + [[nodiscard]] MTPGeoPoint toMTP() const; - float64 lat() const { - return _lat; - } - float64 lon() const { - return _lon; - } - uint64 accessHash() const { - return _access; - } + [[nodiscard]] float64 lat() const; + [[nodiscard]] float64 lon() const; + [[nodiscard]] uint64 accessHash() const; - inline size_t hash() const { -#ifndef OS_MAC_OLD - return QtPrivate::QHashCombine().operator()( - std::hash()(_lat), - _lon); -#else // OS_MAC_OLD - const auto h1 = std::hash()(_lat); - const auto h2 = std::hash()(_lon); - return ((h1 << 16) | (h1 >> 16)) ^ h2; -#endif // OS_MAC_OLD - } + [[nodiscard]] size_t hash() const; private: - static QString AsString(float64 value) { - constexpr auto kPrecision = 6; - return QString::number(value, 'f', kPrecision); - } - - friend inline bool operator==(const LocationPoint &a, const LocationPoint &b) { + friend inline bool operator==( + const LocationPoint &a, + const LocationPoint &b) { return (a._lat == b._lat) && (a._lon == b._lon); } - friend inline bool operator<(const LocationPoint &a, const LocationPoint &b) { + friend inline bool operator<( + const LocationPoint &a, + const LocationPoint &b) { return (a._lat < b._lat) || ((a._lat == b._lat) && (a._lon < b._lon)); } @@ -75,15 +45,7 @@ private: }; -struct LocationThumbnail { - LocationThumbnail(const LocationPoint &point); - - LocationPoint point; - ImagePtr thumb; - - void load(FileOrigin origin); - -}; +[[nodiscard]] GeoPointLocation ComputeLocation(const LocationPoint &point); } // namespace Data diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 72b167b92..b4aeb8817 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -173,7 +173,7 @@ const Invoice *Media::invoice() const { return nullptr; } -LocationThumbnail *Media::location() const { +Data::CloudImage *Media::location() const { return nullptr; } @@ -782,6 +782,7 @@ MediaLocation::MediaLocation( const QString &title, const QString &description) : Media(parent) +, _point(point) , _location(parent->history()->owner().location(point)) , _title(title) , _description(description) { @@ -790,12 +791,12 @@ MediaLocation::MediaLocation( std::unique_ptr MediaLocation::clone(not_null parent) { return std::make_unique( parent, - _location->point, + _point, _title, _description); } -LocationThumbnail *MediaLocation::location() const { +Data::CloudImage *MediaLocation::location() const { return _location; } @@ -826,7 +827,7 @@ TextForMimeData MediaLocation::clipboardText() const { if (!descriptionResult.text.isEmpty()) { result.append(std::move(descriptionResult)); } - result.append(LocationClickHandler(_location->point).dragText()); + result.append(LocationClickHandler(_point).dragText()); return result; } @@ -844,6 +845,7 @@ std::unique_ptr MediaLocation::createView( return std::make_unique( message, _location, + _point, _title, _description); } diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index b410d4fed..7baa7c558 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +#include "data/data_location.h" + class HistoryItem; namespace base { @@ -27,8 +29,7 @@ class Media; namespace Data { -class LocationPoint; -struct LocationThumbnail; +class CloudImage; enum class CallFinishReason : char { Missed, @@ -77,7 +78,7 @@ public: virtual const Call *call() const; virtual GameData *game() const; virtual const Invoice *invoice() const; - virtual LocationThumbnail *location() const; + virtual Data::CloudImage *location() const; virtual PollData *poll() const; virtual bool uploading() const; @@ -236,7 +237,7 @@ public: std::unique_ptr clone(not_null parent) override; - LocationThumbnail *location() const override; + Data::CloudImage *location() const override; QString chatListText() const override; QString notificationText() const override; QString pinnedTextSubstring() const override; @@ -249,7 +250,8 @@ public: not_null realParent) override; private: - not_null _location; + LocationPoint _point; + not_null _location; QString _title; QString _description; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index 8e1370a1d..79da37b0d 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -3025,13 +3025,22 @@ void Session::applyUpdate(const MTPDupdateChatDefaultBannedRights &update) { } } -not_null Session::location(const LocationPoint &point) { +not_null Session::location(const LocationPoint &point) { const auto i = _locations.find(point); - return (i != _locations.cend()) - ? i->second.get() - : _locations.emplace( - point, - std::make_unique(point)).first->second.get(); + if (i != _locations.cend()) { + return i->second.get(); + } + const auto result = _locations.emplace( + point, + std::make_unique(_session)).first->second.get(); + const auto location = Data::ComputeLocation(point); + result->set(ImageWithLocation{ + .location = ImageLocation( + { location }, + location.width, + location.height) + }); + return result; } void Session::registerPhotoItem( diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 32454f246..6f3ac2e83 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -561,7 +561,7 @@ public: not_null processPoll(const MTPPoll &data); not_null processPoll(const MTPDmessageMediaPoll &data); - [[nodiscard]] not_null location( + [[nodiscard]] not_null location( const LocationPoint &point); void registerPhotoItem( @@ -939,7 +939,7 @@ private: base::flat_set>> _webpageViews; std::unordered_map< LocationPoint, - std::unique_ptr> _locations; + std::unique_ptr> _locations; std::unordered_map< PollId, std::unique_ptr> _polls; diff --git a/Telegram/SourceFiles/history/view/media/history_view_location.cpp b/Telegram/SourceFiles/history/view/media/history_view_location.cpp index 36d7c7c11..57a386a71 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_location.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_location.cpp @@ -16,7 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/image/image.h" #include "ui/text_options.h" #include "data/data_file_origin.h" -#include "data/data_location.h" +#include "data/data_cloud_file.h" #include "app.h" #include "styles/style_history.h" @@ -24,14 +24,15 @@ namespace HistoryView { Location::Location( not_null parent, - not_null location, + not_null data, + Data::LocationPoint point, const QString &title, const QString &description) : Media(parent) -, _data(location) +, _data(data) , _title(st::msgMinWidth) , _description(st::msgMinWidth) -, _link(std::make_shared(_data->point)) { +, _link(std::make_shared(point)) { if (!title.isEmpty()) { _title.setText( st::webPageTitleStyle, @@ -48,6 +49,14 @@ Location::Location( } } +void Location::ensureMediaCreated() const { + if (_media) { + return; + } + _media = _data->createView(); + _data->load(_parent->data()->fullId()); +} + QSize Location::countOptimalSize() { auto tw = fullWidth(); auto th = fullHeight(); @@ -155,14 +164,13 @@ void Location::draw(Painter &p, const QRect &r, TextSelection selection, crl::ti App::roundShadow(p, 0, 0, paintw, painth, selected ? st::msgInShadowSelected : st::msgInShadow, selected ? InSelectedShadowCorners : InShadowCorners); } - const auto contextId = _parent->data()->fullId(); - _data->load(contextId); auto roundRadius = ImageRoundRadius::Large; auto roundCorners = ((isBubbleTop() && _title.isEmpty() && _description.isEmpty()) ? (RectPart::TopLeft | RectPart::TopRight) : RectPart::None) | (isBubbleBottom() ? (RectPart::BottomLeft | RectPart::BottomRight) : RectPart::None); auto rthumb = QRect(paintx, painty, paintw, painth); - if (_data && !_data->thumb->isNull()) { - const auto &pix = _data->thumb->pixSingle(contextId, paintw, painth, paintw, painth, roundRadius, roundCorners); + ensureMediaCreated(); + if (const auto thumbnail = _media->image()) { + const auto &pix = thumbnail->pixSingle({}, paintw, painth, paintw, painth, roundRadius, roundCorners); p.drawPixmap(rthumb.topLeft(), pix); } else { App::complexLocationRect(p, rthumb, roundRadius, roundCorners); diff --git a/Telegram/SourceFiles/history/view/media/history_view_location.h b/Telegram/SourceFiles/history/view/media/history_view_location.h index 89e66b17a..2538dc3e5 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_location.h +++ b/Telegram/SourceFiles/history/view/media/history_view_location.h @@ -8,9 +8,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "history/view/media/history_view_media.h" +#include "data/data_location.h" namespace Data { -struct LocationThumbnail; +class CloudImage; +class CloudImageView; } // namespace Data namespace HistoryView { @@ -19,7 +21,8 @@ class Location : public Media { public: Location( not_null parent, - not_null location, + not_null data, + Data::LocationPoint point, const QString &title = QString(), const QString &description = QString()); @@ -54,14 +57,24 @@ public: return isBubbleBottom(); } + void unloadHeavyPart() override { + _media = nullptr; + } + bool hasHeavyPart() const override { + return (_media != nullptr); + } + private: + void ensureMediaCreated() const; + QSize countOptimalSize() override; QSize countCurrentSize(int newWidth) override; TextSelection toDescriptionSelection(TextSelection selection) const; TextSelection fromDescriptionSelection(TextSelection selection) const; - const not_null _data; + const not_null _data; + mutable std::shared_ptr _media; Ui::Text::String _title, _description; ClickHandlerPtr _link;