/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "base/timer.h" #include "base/qt/qt_compare.h" #include "ui/rp_widget.h" #include "ui/effects/animations.h" #include "ui/text/text_custom_emoji.h" namespace style { struct EmojiPan; struct TabbedSearch; } // namespace style namespace anim { enum class type : uchar; } // namespace anim namespace Ui { class InputField; class IconButton; class CrossButton; class RpWidget; template class FadeWrap; struct EmojiGroup { QString iconId; std::vector emoticons; friend inline auto operator<=>( const EmojiGroup &a, const EmojiGroup &b) = default; }; struct SearchDescriptor { const style::TabbedSearch &st; rpl::producer> groups; Text::CustomEmojiFactory customEmojiFactory; }; class SearchWithGroups final : public RpWidget { public: SearchWithGroups(QWidget *parent, SearchDescriptor descriptor); [[nodiscard]] rpl::producer<> escapes() const; [[nodiscard]] rpl::producer> queryValue() const; [[nodiscard]] auto debouncedQueryValue() const -> rpl::producer>; void cancel(); void setLoading(bool loading); void stealFocus(); void returnFocus(); [[nodiscard]] static int IconSizeOverride(); private: int resizeGetHeight(int newWidth) override; void wheelEvent(QWheelEvent *e) override; [[nodiscard]] int clampGroupsLeft(int width, int desiredLeft) const; void moveGroupsBy(int width, int delta); void moveGroupsTo(int width, int to); void scrollGroupsToIcon(int iconLeft, int iconRight); void scrollGroupsToStart(); void scrollGroupsTo(int left); [[nodiscard]] anim::type animated() const; void initField(); void initGroups(); void initEdges(); void initButtons(); void ensureRounding(int size, float64 rounding); const style::TabbedSearch &_st; not_null*> _search; not_null*> _back; not_null _cancel; not_null _field; QPointer _focusTakenFrom; not_null*> _groups; not_null _fade; rpl::variable _fadeOpacity = 0.; int _fadeLeftStart = 0; rpl::variable _fieldPlaceholderWidth; rpl::variable _fieldEmpty = true; Ui::Animations::Simple _groupsLeftAnimation; int _groupsLeftTo = 0; QImage _rounding; rpl::variable> _query; rpl::variable> _debouncedQuery; rpl::variable _chosenGroup; base::Timer _debounceTimer; bool _inited = false; }; class TabbedSearch final { public: TabbedSearch( not_null parent, const style::EmojiPan &st, SearchDescriptor &&descriptor); [[nodiscard]] int height() const; [[nodiscard]] QImage grab(); [[nodiscard]] rpl::producer<> escapes() const; [[nodiscard]] rpl::producer> queryValue() const; [[nodiscard]] auto debouncedQueryValue() const ->rpl::producer>; void cancel(); void setLoading(bool loading); void stealFocus(); void returnFocus(); private: const style::EmojiPan &_st; SearchWithGroups _search; }; } // namespace Ui