Use Data::CloudImage for location thumbnails.

This commit is contained in:
John Preston 2020-05-28 17:05:44 +04:00
parent ae9ed820ee
commit 29a498b959
8 changed files with 124 additions and 93 deletions

View File

@ -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<float64>()(_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

View File

@ -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<float64>()(_lat),
_lon);
#else // OS_MAC_OLD
const auto h1 = std::hash<float64>()(_lat);
const auto h2 = std::hash<float64>()(_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

View File

@ -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<Media> MediaLocation::clone(not_null<HistoryItem*> parent) {
return std::make_unique<MediaLocation>(
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<HistoryView::Media> MediaLocation::createView(
return std::make_unique<HistoryView::Location>(
message,
_location,
_point,
_title,
_description);
}

View File

@ -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<Media> clone(not_null<HistoryItem*> 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<HistoryItem*> realParent) override;
private:
not_null<LocationThumbnail*> _location;
LocationPoint _point;
not_null<Data::CloudImage*> _location;
QString _title;
QString _description;

View File

@ -3025,13 +3025,22 @@ void Session::applyUpdate(const MTPDupdateChatDefaultBannedRights &update) {
}
}
not_null<LocationThumbnail*> Session::location(const LocationPoint &point) {
not_null<Data::CloudImage*> Session::location(const LocationPoint &point) {
const auto i = _locations.find(point);
return (i != _locations.cend())
? i->second.get()
: _locations.emplace(
point,
std::make_unique<LocationThumbnail>(point)).first->second.get();
if (i != _locations.cend()) {
return i->second.get();
}
const auto result = _locations.emplace(
point,
std::make_unique<Data::CloudImage>(_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(

View File

@ -561,7 +561,7 @@ public:
not_null<PollData*> processPoll(const MTPPoll &data);
not_null<PollData*> processPoll(const MTPDmessageMediaPoll &data);
[[nodiscard]] not_null<LocationThumbnail*> location(
[[nodiscard]] not_null<Data::CloudImage*> location(
const LocationPoint &point);
void registerPhotoItem(
@ -939,7 +939,7 @@ private:
base::flat_set<not_null<ViewElement*>>> _webpageViews;
std::unordered_map<
LocationPoint,
std::unique_ptr<LocationThumbnail>> _locations;
std::unique_ptr<Data::CloudImage>> _locations;
std::unordered_map<
PollId,
std::unique_ptr<PollData>> _polls;

View File

@ -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<Element*> parent,
not_null<Data::LocationThumbnail*> location,
not_null<Data::CloudImage*> 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<LocationClickHandler>(_data->point)) {
, _link(std::make_shared<LocationClickHandler>(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);

View File

@ -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<Element*> parent,
not_null<Data::LocationThumbnail*> location,
not_null<Data::CloudImage*> 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::LocationThumbnail*> _data;
const not_null<Data::CloudImage*> _data;
mutable std::shared_ptr<Data::CloudImageView> _media;
Ui::Text::String _title, _description;
ClickHandlerPtr _link;