1 /* 2 This file is part of Telegram Desktop, 3 the official desktop application for the Telegram messaging service. 4 5 For license and copyright information please follow this link: 6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL 7 */ 8 #pragma once 9 10 #include "layout/layout_item_base.h" 11 #include "layout/layout_document_generic_preview.h" 12 #include "media/clip/media_clip_reader.h" 13 #include "core/click_handler_types.h" 14 #include "ui/effects/animations.h" 15 #include "ui/effects/radial_animation.h" 16 #include "styles/style_overview.h" 17 18 class Image; 19 20 namespace style { 21 struct RoundCheckbox; 22 } // namespace style 23 24 namespace Data { 25 class Media; 26 class PhotoMedia; 27 class DocumentMedia; 28 } // namespace Data 29 30 namespace Overview { 31 namespace Layout { 32 33 class Checkbox; 34 class ItemBase; 35 class Delegate; 36 37 class PaintContext : public PaintContextBase { 38 public: PaintContext(crl::time ms,bool selecting)39 PaintContext(crl::time ms, bool selecting) : PaintContextBase(ms, selecting) { 40 } 41 bool isAfterDate = false; 42 43 }; 44 45 class ItemBase : public LayoutItemBase, public base::has_weak_ptr { 46 public: 47 ItemBase(not_null<Delegate*> delegate, not_null<HistoryItem*> parent); 48 ~ItemBase(); 49 50 virtual void paint( 51 Painter &p, 52 const QRect &clip, 53 TextSelection selection, 54 const PaintContext *context) = 0; 55 56 QDateTime dateTime() const; 57 getItem()58 HistoryItem *getItem() const { 59 return _parent; 60 } 61 62 void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; 63 void clickHandlerPressedChanged(const ClickHandlerPtr &action, bool pressed) override; 64 65 void invalidateCache(); 66 clearHeavyPart()67 virtual void clearHeavyPart() { 68 } 69 70 protected: parent()71 [[nodiscard]] not_null<HistoryItem*> parent() const { 72 return _parent; 73 } delegate()74 [[nodiscard]] not_null<Delegate*> delegate() const { 75 return _delegate; 76 } 77 void paintCheckbox( 78 Painter &p, 79 QPoint position, 80 bool selected, 81 const PaintContext *context); 82 virtual const style::RoundCheckbox &checkboxStyle() const; 83 84 private: 85 void ensureCheckboxCreated(); 86 87 const not_null<Delegate*> _delegate; 88 const not_null<HistoryItem*> _parent; 89 const QDateTime _dateTime; 90 std::unique_ptr<Checkbox> _check; 91 92 }; 93 94 class RadialProgressItem : public ItemBase { 95 public: RadialProgressItem(not_null<Delegate * > delegate,not_null<HistoryItem * > parent)96 RadialProgressItem( 97 not_null<Delegate*> delegate, 98 not_null<HistoryItem*> parent) 99 : ItemBase(delegate, parent) { 100 } 101 RadialProgressItem(const RadialProgressItem &other) = delete; 102 103 void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override; 104 105 ~RadialProgressItem(); 106 107 protected: 108 ClickHandlerPtr _openl, _savel, _cancell; 109 void setLinks( 110 ClickHandlerPtr &&openl, 111 ClickHandlerPtr &&savel, 112 ClickHandlerPtr &&cancell); 113 void setDocumentLinks( 114 not_null<DocumentData*> document, 115 bool forceOpen = false); 116 117 void radialAnimationCallback(crl::time now) const; 118 119 void ensureRadial(); 120 void checkRadialFinished() const; 121 isRadialAnimation()122 bool isRadialAnimation() const { 123 if (_radial) { 124 if (_radial->animating()) { 125 return true; 126 } 127 checkRadialFinished(); 128 } 129 return false; 130 } 131 132 virtual float64 dataProgress() const = 0; 133 virtual bool dataFinished() const = 0; 134 virtual bool dataLoaded() const = 0; iconAnimated()135 virtual bool iconAnimated() const { 136 return false; 137 } 138 139 mutable std::unique_ptr<Ui::RadialAnimation> _radial; 140 Ui::Animations::Simple _a_iconOver; 141 142 }; 143 144 class StatusText { 145 public: 146 // duration = -1 - no duration, duration = -2 - "GIF" duration 147 void update(int newSize, int fullSize, int duration, crl::time realDuration); 148 void setSize(int newSize); 149 size()150 int size() const { 151 return _size; 152 } text()153 QString text() const { 154 return _text; 155 } 156 157 private: 158 // >= 0 will contain download / upload string, _size = loaded bytes 159 // < 0 will contain played string, _size = -(seconds + 1) played 160 // 0x7FFFFFF0 will contain status for not yet downloaded file 161 // 0x7FFFFFF1 will contain status for already downloaded file 162 // 0x7FFFFFF2 will contain status for failed to download / upload file 163 int _size = 0; 164 QString _text; 165 166 }; 167 168 struct Info : public RuntimeComponent<Info, LayoutItemBase> { 169 int top = 0; 170 }; 171 172 class Photo final : public ItemBase { 173 public: 174 Photo( 175 not_null<Delegate*> delegate, 176 not_null<HistoryItem*> parent, 177 not_null<PhotoData*> photo); 178 179 void initDimensions() override; 180 int32 resizeGetHeight(int32 width) override; 181 void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; 182 TextState getState( 183 QPoint point, 184 StateRequest request) const override; 185 186 void clearHeavyPart() override; 187 188 private: 189 void ensureDataMediaCreated() const; 190 void setPixFrom(not_null<Image*> image); 191 192 const not_null<PhotoData*> _data; 193 mutable std::shared_ptr<Data::PhotoMedia> _dataMedia; 194 ClickHandlerPtr _link; 195 196 QPixmap _pix; 197 bool _goodLoaded = false; 198 199 }; 200 201 class Gif final : public RadialProgressItem { 202 public: 203 Gif( 204 not_null<Delegate*> delegate, 205 not_null<HistoryItem*> parent, 206 not_null<DocumentData*> gif); 207 ~Gif(); 208 209 void initDimensions() override; 210 int32 resizeGetHeight(int32 width) override; 211 void paint( 212 Painter &p, 213 const QRect &clip, 214 TextSelection selection, 215 const PaintContext *context) override; 216 TextState getState( 217 QPoint point, 218 StateRequest request) const override; 219 220 void clearHeavyPart() override; 221 void setPosition(int32 position) override; 222 223 protected: 224 float64 dataProgress() const override; 225 bool dataFinished() const override; 226 bool dataLoaded() const override; 227 bool iconAnimated() const override; 228 229 private: 230 QSize countFrameSize() const; 231 int contentWidth() const; 232 int contentHeight() const; 233 234 void validateThumbnail( 235 Image *image, 236 QSize size, 237 QSize frame, 238 bool good); 239 void prepareThumbnail(QSize size, QSize frame); 240 241 void update(); 242 243 void ensureDataMediaCreated() const; 244 void updateStatusText(); 245 246 void clipCallback(Media::Clip::Notification notification); 247 248 Media::Clip::ReaderPointer _gif; 249 250 const not_null<DocumentData*> _data; 251 mutable std::shared_ptr<Data::DocumentMedia> _dataMedia; 252 StatusText _status; 253 254 QPixmap _thumb; 255 bool _thumbGood = false; 256 257 }; 258 259 class Video final : public RadialProgressItem { 260 public: 261 Video( 262 not_null<Delegate*> delegate, 263 not_null<HistoryItem*> parent, 264 not_null<DocumentData*> video); 265 ~Video(); 266 267 void initDimensions() override; 268 int32 resizeGetHeight(int32 width) override; 269 void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; 270 TextState getState( 271 QPoint point, 272 StateRequest request) const override; 273 274 void clearHeavyPart() override; 275 276 protected: 277 float64 dataProgress() const override; 278 bool dataFinished() const override; 279 bool dataLoaded() const override; 280 bool iconAnimated() const override; 281 282 private: 283 void ensureDataMediaCreated() const; 284 void updateStatusText(); 285 286 const not_null<DocumentData*> _data; 287 mutable std::shared_ptr<Data::DocumentMedia> _dataMedia; 288 StatusText _status; 289 290 QString _duration; 291 QPixmap _pix; 292 bool _pixBlurred = true; 293 294 }; 295 296 class Voice final : public RadialProgressItem { 297 public: 298 Voice( 299 not_null<Delegate*> delegate, 300 not_null<HistoryItem*> parent, 301 not_null<DocumentData*> voice, 302 const style::OverviewFileLayout &st); 303 304 void initDimensions() override; 305 void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; 306 TextState getState( 307 QPoint point, 308 StateRequest request) const override; 309 310 void clearHeavyPart() override; 311 312 protected: 313 float64 dataProgress() const override; 314 bool dataFinished() const override; 315 bool dataLoaded() const override; 316 bool iconAnimated() const override; 317 const style::RoundCheckbox &checkboxStyle() const override; 318 319 private: 320 void ensureDataMediaCreated() const; 321 int duration() const; 322 323 not_null<DocumentData*> _data; 324 mutable std::shared_ptr<Data::DocumentMedia> _dataMedia; 325 StatusText _status; 326 ClickHandlerPtr _namel; 327 328 const style::OverviewFileLayout &_st; 329 330 Ui::Text::String _name, _details; 331 int _nameVersion; 332 333 void updateName(); 334 bool updateStatusText(); 335 336 }; 337 338 class Document final : public RadialProgressItem { 339 public: 340 Document( 341 not_null<Delegate*> delegate, 342 not_null<HistoryItem*> parent, 343 not_null<DocumentData*> document, 344 const style::OverviewFileLayout &st); 345 346 void initDimensions() override; 347 void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; 348 TextState getState( 349 QPoint point, 350 StateRequest request) const override; 351 352 void clearHeavyPart() override; 353 354 protected: 355 float64 dataProgress() const override; 356 bool dataFinished() const override; 357 bool dataLoaded() const override; 358 bool iconAnimated() const override; 359 const style::RoundCheckbox &checkboxStyle() const override; 360 361 private: 362 [[nodiscard]] bool downloadInCorner() const; 363 void drawCornerDownload(Painter &p, bool selected, const PaintContext *context) const; 364 [[nodiscard]] TextState cornerDownloadTextState( 365 QPoint point, 366 StateRequest request) const; 367 368 void ensureDataMediaCreated() const; 369 370 not_null<DocumentData*> _data; 371 mutable std::shared_ptr<Data::DocumentMedia> _dataMedia; 372 StatusText _status; 373 ClickHandlerPtr _msgl, _namel; 374 375 const style::OverviewFileLayout &_st; 376 const ::Layout::DocumentGenericPreview _generic; 377 378 bool _thumbLoaded = false; 379 QPixmap _thumb; 380 381 Ui::Text::String _name; 382 QString _date, _ext; 383 int32 _datew, _extw; 384 int32 _thumbw; 385 386 bool withThumb() const; 387 bool updateStatusText(); 388 389 }; 390 391 class Link final : public ItemBase { 392 public: 393 Link( 394 not_null<Delegate*> delegate, 395 not_null<HistoryItem*> parent, 396 Data::Media *media); 397 398 void initDimensions() override; 399 int32 resizeGetHeight(int32 width) override; 400 void paint(Painter &p, const QRect &clip, TextSelection selection, const PaintContext *context) override; 401 TextState getState( 402 QPoint point, 403 StateRequest request) const override; 404 405 void clearHeavyPart() override; 406 407 protected: 408 const style::RoundCheckbox &checkboxStyle() const override; 409 410 private: 411 void ensurePhotoMediaCreated(); 412 void ensureDocumentMediaCreated(); 413 void validateThumbnail(); 414 415 ClickHandlerPtr _photol; 416 417 QString _title, _letter; 418 int _titlew = 0; 419 WebPageData *_page = nullptr; 420 std::shared_ptr<Data::PhotoMedia> _photoMedia; 421 std::shared_ptr<Data::DocumentMedia> _documentMedia; 422 int _pixw = 0; 423 int _pixh = 0; 424 Ui::Text::String _text = { st::msgMinWidth }; 425 QPixmap _thumbnail; 426 bool _thumbnailBlurred = true; 427 428 struct LinkEntry { LinkEntryLinkEntry429 LinkEntry() : width(0) { 430 } 431 LinkEntry(const QString &url, const QString &text); 432 QString text; 433 int32 width; 434 std::shared_ptr<TextClickHandler> lnk; 435 }; 436 QVector<LinkEntry> _links; 437 438 }; 439 440 } // namespace Layout 441 } // namespace Overview 442