tdesktop/Telegram/SourceFiles/ui/controls/tabbed_search.h

137 lines
3.3 KiB
C++

/*
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 <typename Widget>
class FadeWrap;
struct EmojiGroup {
QString iconId;
std::vector<QString> emoticons;
friend inline auto operator<=>(
const EmojiGroup &a,
const EmojiGroup &b) = default;
};
struct SearchDescriptor {
const style::TabbedSearch &st;
rpl::producer<std::vector<EmojiGroup>> groups;
Text::CustomEmojiFactory customEmojiFactory;
};
class SearchWithGroups final : public RpWidget {
public:
SearchWithGroups(QWidget *parent, SearchDescriptor descriptor);
[[nodiscard]] rpl::producer<> escapes() const;
[[nodiscard]] rpl::producer<std::vector<QString>> queryValue() const;
[[nodiscard]] auto debouncedQueryValue() const
-> rpl::producer<std::vector<QString>>;
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<FadeWrap<IconButton>*> _search;
not_null<FadeWrap<IconButton>*> _back;
not_null<CrossButton*> _cancel;
not_null<InputField*> _field;
QPointer<QWidget> _focusTakenFrom;
not_null<FadeWrap<RpWidget>*> _groups;
not_null<RpWidget*> _fade;
rpl::variable<float64> _fadeOpacity = 0.;
int _fadeLeftStart = 0;
rpl::variable<int> _fieldPlaceholderWidth;
rpl::variable<bool> _fieldEmpty = true;
Ui::Animations::Simple _groupsLeftAnimation;
int _groupsLeftTo = 0;
QImage _rounding;
rpl::variable<std::vector<QString>> _query;
rpl::variable<std::vector<QString>> _debouncedQuery;
rpl::variable<QString> _chosenGroup;
base::Timer _debounceTimer;
bool _inited = false;
};
class TabbedSearch final {
public:
TabbedSearch(
not_null<RpWidget*> parent,
const style::EmojiPan &st,
SearchDescriptor &&descriptor);
[[nodiscard]] int height() const;
[[nodiscard]] QImage grab();
[[nodiscard]] rpl::producer<> escapes() const;
[[nodiscard]] rpl::producer<std::vector<QString>> queryValue() const;
[[nodiscard]] auto debouncedQueryValue() const
->rpl::producer<std::vector<QString>>;
void cancel();
void setLoading(bool loading);
void stealFocus();
void returnFocus();
private:
const style::EmojiPan &_st;
SearchWithGroups _search;
};
} // namespace Ui