inline_results_inner.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "ui/rp_widget.h"
  9. #include "ui/abstract_button.h"
  10. #include "ui/widgets/tooltip.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/effects/panel_animation.h"
  13. #include "dialogs/dialogs_key.h"
  14. #include "base/timer.h"
  15. #include "mtproto/sender.h"
  16. #include "inline_bots/inline_bot_layout_item.h"
  17. #include "layout/layout_mosaic.h"
  18. namespace Api {
  19. struct SendOptions;
  20. } // namespace Api
  21. namespace Ui {
  22. class ScrollArea;
  23. class IconButton;
  24. class LinkButton;
  25. class RoundButton;
  26. class FlatLabel;
  27. class RippleAnimation;
  28. class PopupMenu;
  29. class PathShiftGradient;
  30. } // namespace Ui
  31. namespace Window {
  32. class SessionController;
  33. } // namespace Window
  34. namespace InlineBots {
  35. class Result;
  36. struct ResultSelected;
  37. } // namespace InlineBots
  38. namespace SendMenu {
  39. struct Details;
  40. } // namespace SendMenu
  41. namespace InlineBots {
  42. namespace Layout {
  43. class ItemBase;
  44. using Results = std::vector<std::shared_ptr<Result>>;
  45. struct CacheEntry {
  46. QString nextOffset;
  47. QString switchPmText;
  48. QString switchPmStartToken;
  49. QByteArray switchPmUrl;
  50. Results results;
  51. };
  52. class Inner
  53. : public Ui::RpWidget
  54. , public Ui::AbstractTooltipShower
  55. , public Context {
  56. public:
  57. Inner(QWidget *parent, not_null<Window::SessionController*> controller);
  58. void hideFinished();
  59. void clearSelection();
  60. int refreshInlineRows(PeerData *queryPeer, UserData *bot, const CacheEntry *results, bool resultsDeleted);
  61. void inlineBotChanged();
  62. void hideInlineRowsPanel();
  63. void clearInlineRowsPanel();
  64. void preloadImages();
  65. void inlineItemLayoutChanged(const ItemBase *layout) override;
  66. void inlineItemRepaint(const ItemBase *layout) override;
  67. bool inlineItemVisible(const ItemBase *layout) override;
  68. Data::FileOrigin inlineItemFileOrigin() override;
  69. int countHeight();
  70. void setResultSelectedCallback(Fn<void(ResultSelected)> callback) {
  71. _resultSelectedCallback = std::move(callback);
  72. }
  73. void setSendMenuDetails(Fn<SendMenu::Details()> &&callback);
  74. // Ui::AbstractTooltipShower interface.
  75. QString tooltipText() const override;
  76. QPoint tooltipPos() const override;
  77. bool tooltipWindowActive() const override;
  78. rpl::producer<> inlineRowsCleared() const;
  79. ~Inner();
  80. protected:
  81. void visibleTopBottomUpdated(
  82. int visibleTop,
  83. int visibleBottom) override;
  84. void mousePressEvent(QMouseEvent *e) override;
  85. void mouseReleaseEvent(QMouseEvent *e) override;
  86. void mouseMoveEvent(QMouseEvent *e) override;
  87. void resizeEvent(QResizeEvent *e) override;
  88. void paintEvent(QPaintEvent *e) override;
  89. void leaveEventHook(QEvent *e) override;
  90. void leaveToChildEvent(QEvent *e, QWidget *child) override;
  91. void enterFromChildEvent(QEvent *e, QWidget *child) override;
  92. void contextMenuEvent(QContextMenuEvent *e) override;
  93. private:
  94. static constexpr bool kRefreshIconsScrollAnimation = true;
  95. static constexpr bool kRefreshIconsNoAnimation = false;
  96. void switchPm();
  97. void updateSelected();
  98. void checkRestrictedPeer();
  99. bool isRestrictedView();
  100. void clearHeavyData();
  101. void paintInlineItems(Painter &p, const QRect &r);
  102. void refreshSwitchPmButton(const CacheEntry *entry);
  103. void refreshMosaicOffset();
  104. void showPreview();
  105. void updateInlineItems();
  106. void repaintItems(crl::time now = 0);
  107. void clearInlineRows(bool resultsDeleted);
  108. ItemBase *layoutPrepareInlineResult(std::shared_ptr<Result> result);
  109. void updateRestrictedLabelGeometry();
  110. void deleteUnusedInlineLayouts();
  111. int validateExistingInlineRows(const Results &results);
  112. void selectInlineResult(
  113. int index,
  114. Api::SendOptions options,
  115. bool open);
  116. not_null<Window::SessionController*> _controller;
  117. const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
  118. int _visibleTop = 0;
  119. int _visibleBottom = 0;
  120. UserData *_inlineBot = nullptr;
  121. PeerData *_inlineQueryPeer = nullptr;
  122. crl::time _lastScrolledAt = 0;
  123. crl::time _lastUpdatedAt = 0;
  124. base::Timer _updateInlineItems;
  125. bool _inlineWithThumb = false;
  126. object_ptr<Ui::RoundButton> _switchPmButton = { nullptr };
  127. QString _switchPmStartToken;
  128. QByteArray _switchPmUrl;
  129. object_ptr<Ui::FlatLabel> _restrictedLabel = { nullptr };
  130. QString _restrictedLabelKey;
  131. base::unique_qptr<Ui::PopupMenu> _menu;
  132. Mosaic::Layout::MosaicLayout<InlineBots::Layout::ItemBase> _mosaic;
  133. std::map<Result*, std::unique_ptr<ItemBase>> _inlineLayouts;
  134. rpl::event_stream<> _inlineRowsCleared;
  135. int _selected = -1;
  136. int _pressed = -1;
  137. QPoint _lastMousePos;
  138. base::Timer _previewTimer;
  139. bool _previewShown = false;
  140. Fn<void(ResultSelected)> _resultSelectedCallback;
  141. Fn<SendMenu::Details()> _sendMenuDetails;
  142. };
  143. } // namespace Layout
  144. } // namespace InlineBots