top_peers_strip.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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 "base/weak_ptr.h"
  9. #include "ui/effects/animations.h"
  10. #include "ui/widgets/menu/menu_add_action_callback.h"
  11. #include "ui/round_rect.h"
  12. #include "ui/rp_widget.h"
  13. namespace Ui {
  14. class DynamicImage;
  15. class LinkButton;
  16. struct ScrollToRequest;
  17. } // namespace Ui
  18. namespace Dialogs {
  19. struct TopPeersEntry {
  20. uint64 id = 0;
  21. QString name;
  22. std::shared_ptr<Ui::DynamicImage> userpic;
  23. uint32 badge : 28 = 0;
  24. uint32 unread : 1 = 0;
  25. uint32 muted : 1 = 0;
  26. uint32 online : 1 = 0;
  27. };
  28. struct TopPeersList {
  29. std::vector<TopPeersEntry> entries;
  30. };
  31. struct ShowTopPeerMenuRequest {
  32. uint64 id = 0;
  33. Ui::Menu::MenuCallback callback;
  34. };
  35. class TopPeersStrip final : public Ui::RpWidget {
  36. public:
  37. TopPeersStrip(
  38. not_null<QWidget*> parent,
  39. rpl::producer<TopPeersList> content);
  40. ~TopPeersStrip();
  41. [[nodiscard]] bool empty() const;
  42. [[nodiscard]] rpl::producer<bool> emptyValue() const;
  43. [[nodiscard]] rpl::producer<uint64> clicks() const;
  44. [[nodiscard]] rpl::producer<uint64> pressed() const;
  45. [[nodiscard]] rpl::producer<> pressCancelled() const;
  46. [[nodiscard]] auto showMenuRequests() const
  47. -> rpl::producer<ShowTopPeerMenuRequest>;
  48. [[nodiscard]] auto scrollToRequests() const
  49. -> rpl::producer<Ui::ScrollToRequest>;
  50. void removeLocally(uint64 id = 0);
  51. [[nodiscard]] bool selectedByKeyboard() const;
  52. bool selectByKeyboard(Qt::Key direction);
  53. void deselectByKeyboard();
  54. bool chooseRow();
  55. void pressLeftToContextMenu(bool shown);
  56. uint64 updateFromParentDrag(QPoint globalPosition);
  57. void dragLeft();
  58. [[nodiscard]] auto verticalScrollEvents() const
  59. -> rpl::producer<not_null<QWheelEvent*>>;
  60. private:
  61. struct Entry;
  62. struct Layout;
  63. int resizeGetHeight(int newWidth) override;
  64. void setupHeader();
  65. void setupStrip();
  66. void paintStrip(QRect clip);
  67. void stripWheelEvent(QWheelEvent *e);
  68. void stripMousePressEvent(QMouseEvent *e);
  69. void stripMouseMoveEvent(QMouseEvent *e);
  70. void stripMouseReleaseEvent(QMouseEvent *e);
  71. void stripContextMenuEvent(QContextMenuEvent *e);
  72. void stripLeaveEvent(QEvent *e);
  73. void updateScrollMax(int newWidth = 0);
  74. void updateSelected();
  75. void setSelected(int selected);
  76. void setExpanded(bool expanded);
  77. void scrollToSelected();
  78. void checkDragging();
  79. bool finishDragging();
  80. void subscribeUserpic(Entry &entry);
  81. void unsubscribeUserpics(bool all = false);
  82. void paintUserpic(Painter &p, int x, int y, int index, bool selected);
  83. void clearSelection();
  84. void selectByMouse(QPoint globalPosition);
  85. [[nodiscard]] QRect outer() const;
  86. [[nodiscard]] QRect innerRounded() const;
  87. [[nodiscard]] int scrollLeft() const;
  88. [[nodiscard]] Layout currentLayout() const;
  89. int clearPressed();
  90. void apply(const TopPeersList &list);
  91. void apply(Entry &entry, const TopPeersEntry &data);
  92. Ui::RpWidget _header;
  93. Ui::RpWidget _strip;
  94. std::vector<Entry> _entries;
  95. rpl::variable<int> _count = 0;
  96. base::flat_set<uint64> _removed;
  97. rpl::variable<Ui::LinkButton*> _toggleExpanded = nullptr;
  98. rpl::event_stream<uint64> _clicks;
  99. rpl::event_stream<uint64> _presses;
  100. rpl::event_stream<> _pressCancelled;
  101. rpl::event_stream<ShowTopPeerMenuRequest> _showMenuRequests;
  102. rpl::event_stream<not_null<QWheelEvent*>> _verticalScrollEvents;
  103. std::optional<QPoint> _lastMousePosition;
  104. std::optional<QPoint> _mouseDownPosition;
  105. int _startDraggingLeft = 0;
  106. int _scrollLeft = 0;
  107. int _scrollLeftMax = 0;
  108. bool _dragging = false;
  109. Qt::Orientation _scrollingLock = {};
  110. int _selected = -1;
  111. int _pressed = -1;
  112. int _contexted = -1;
  113. bool _selectionByKeyboard = false;
  114. bool _hiddenLocally = false;
  115. Ui::Animations::Simple _expandAnimation;
  116. rpl::variable<bool> _expanded = false;
  117. rpl::event_stream<Ui::ScrollToRequest> _scrollToRequests;
  118. Ui::RoundRect _selection;
  119. base::unique_qptr<Ui::PopupMenu> _menu;
  120. base::has_weak_ptr _menuGuard;
  121. };
  122. } // namespace Dialogs