mirror of https://github.com/procxx/kepka.git
Use Data::CloudImage for location thumbnails.
This commit is contained in:
parent
ae9ed820ee
commit
29a498b959
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue