tabbed_search.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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/timer.h"
  9. #include "base/qt/qt_compare.h"
  10. #include "ui/rp_widget.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/text/text_custom_emoji.h"
  13. namespace style {
  14. struct EmojiPan;
  15. struct TabbedSearch;
  16. } // namespace style
  17. namespace anim {
  18. enum class type : uchar;
  19. } // namespace anim
  20. namespace Ui {
  21. class InputField;
  22. class IconButton;
  23. class CrossButton;
  24. class RpWidget;
  25. template <typename Widget>
  26. class FadeWrap;
  27. enum class EmojiGroupType {
  28. Normal,
  29. Greeting,
  30. Premium,
  31. };
  32. struct EmojiGroup {
  33. QString iconId;
  34. std::vector<QString> emoticons;
  35. EmojiGroupType type = EmojiGroupType::Normal;
  36. friend inline auto operator<=>(
  37. const EmojiGroup &a,
  38. const EmojiGroup &b) = default;
  39. };
  40. [[nodiscard]] const QString &PremiumGroupFakeEmoticon();
  41. struct SearchDescriptor {
  42. const style::TabbedSearch &st;
  43. rpl::producer<std::vector<EmojiGroup>> groups;
  44. Text::CustomEmojiFactory customEmojiFactory;
  45. };
  46. class SearchWithGroups final : public RpWidget {
  47. public:
  48. SearchWithGroups(QWidget *parent, SearchDescriptor descriptor);
  49. [[nodiscard]] rpl::producer<> escapes() const;
  50. [[nodiscard]] rpl::producer<std::vector<QString>> queryValue() const;
  51. [[nodiscard]] auto debouncedQueryValue() const
  52. -> rpl::producer<std::vector<QString>>;
  53. void cancel();
  54. void setLoading(bool loading);
  55. void stealFocus();
  56. void returnFocus();
  57. [[nodiscard]] static int IconSizeOverride();
  58. private:
  59. int resizeGetHeight(int newWidth) override;
  60. void wheelEvent(QWheelEvent *e) override;
  61. [[nodiscard]] int clampGroupsLeft(int width, int desiredLeft) const;
  62. void moveGroupsBy(int width, int delta);
  63. void moveGroupsTo(int width, int to);
  64. void scrollGroupsToIcon(int iconLeft, int iconRight);
  65. void scrollGroupsToStart();
  66. void scrollGroupsTo(int left);
  67. [[nodiscard]] anim::type animated() const;
  68. void initField();
  69. void initGroups();
  70. void initEdges();
  71. void initButtons();
  72. void ensureRounding(int size, float64 rounding);
  73. const style::TabbedSearch &_st;
  74. not_null<FadeWrap<IconButton>*> _search;
  75. not_null<FadeWrap<IconButton>*> _back;
  76. not_null<CrossButton*> _cancel;
  77. not_null<InputField*> _field;
  78. QPointer<QWidget> _focusTakenFrom;
  79. not_null<FadeWrap<RpWidget>*> _groups;
  80. not_null<RpWidget*> _fade;
  81. rpl::variable<float64> _fadeOpacity = 0.;
  82. int _fadeLeftStart = 0;
  83. rpl::variable<int> _fieldPlaceholderWidth;
  84. rpl::variable<bool> _fieldEmpty = true;
  85. Ui::Animations::Simple _groupsLeftAnimation;
  86. int _groupsLeftTo = 0;
  87. QImage _rounding;
  88. rpl::variable<std::vector<QString>> _query;
  89. rpl::variable<std::vector<QString>> _debouncedQuery;
  90. rpl::variable<QString> _chosenGroup;
  91. base::Timer _debounceTimer;
  92. bool _inited = false;
  93. };
  94. class TabbedSearch final {
  95. public:
  96. TabbedSearch(
  97. not_null<RpWidget*> parent,
  98. const style::EmojiPan &st,
  99. SearchDescriptor &&descriptor);
  100. [[nodiscard]] int height() const;
  101. [[nodiscard]] QImage grab();
  102. [[nodiscard]] rpl::producer<> escapes() const;
  103. [[nodiscard]] rpl::producer<std::vector<QString>> queryValue() const;
  104. [[nodiscard]] auto debouncedQueryValue() const
  105. ->rpl::producer<std::vector<QString>>;
  106. void cancel();
  107. void setLoading(bool loading);
  108. void stealFocus();
  109. void returnFocus();
  110. private:
  111. const style::EmojiPan &_st;
  112. SearchWithGroups _search;
  113. };
  114. } // namespace Ui