/* 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 "ui/text/text_variant.h" #include "ui/rp_widget.h" #include "ui/round_rect.h" #include "base/object_ptr.h" #include "settings/settings_type.h" #include namespace anim { enum class repeat : uchar; } // namespace anim namespace Info { struct SelectedItems; enum class SelectionAction; } // namespace Info namespace Main { class Session; } // namespace Main namespace Ui { class VerticalLayout; class FlatLabel; class SettingsButton; class AbstractButton; class MediaSlider; } // namespace Ui namespace Ui::Menu { struct MenuCallback; } // namespace Ui::Menu namespace Window { class SessionController; } // namespace Window namespace style { struct FlatLabel; struct SettingsButton; struct MediaSlider; } // namespace style namespace Lottie { struct IconDescriptor; } // namespace Lottie namespace Settings { using Button = Ui::SettingsButton; enum class HighlightShape { Rect, Ellipse, }; struct HighlightArgs { style::margins margin; HighlightShape shape = HighlightShape::Rect; int radius = 0; const style::color *color = nullptr; float64 opacity = 0.4; bool below = false; bool rippleShape = false; bool scroll = true; crl::time showDelay = 400; crl::time showDuration = 600; crl::time shownDuration = 400; crl::time hideDuration = 600; }; void HighlightWidget(QWidget *target, HighlightArgs &&args = {}); void ScrollToWidget(not_null target); [[nodiscard]] HighlightArgs SubsectionTitleHighlight(); struct HighlightEntry { QPointer widget; HighlightArgs args; }; using HighlightRegistry = std::vector>; using SectionBuildMethod = Fn container, not_null controller, Fn showOther, rpl::producer<> showFinished)>; class AbstractSection : public Ui::RpWidget { public: AbstractSection( QWidget *parent, not_null controller); [[nodiscard]] not_null controller() const { return _controller; } [[nodiscard]] virtual Type id() const = 0; [[nodiscard]] virtual rpl::producer sectionShowOther() { return _showOtherRequests.events(); } [[nodiscard]] virtual rpl::producer<> sectionShowBack() { return nullptr; } [[nodiscard]] virtual rpl::producer> removeFromStack() { return nullptr; } [[nodiscard]] virtual bool closeByOutsideClick() const { return true; } virtual void checkBeforeClose(Fn close) { close(); } [[nodiscard]] virtual rpl::producer title() = 0; virtual void sectionSaveChanges(FnMut done) { done(); } virtual void showFinished() { _showFinished.fire({}); } virtual void setInnerFocus() { setFocus(); } [[nodiscard]] virtual const Ui::RoundRect *bottomSkipRounding() const { return nullptr; } [[nodiscard]] virtual base::weak_qptr createPinnedToTop( not_null parent) { return nullptr; } [[nodiscard]] virtual base::weak_qptr createPinnedToBottom( not_null parent) { return nullptr; } [[nodiscard]] virtual bool hasFlexibleTopBar() const { return false; } virtual void setStepDataReference(std::any &data) { } virtual void sectionSaveState(std::any &state) { } virtual void sectionRestoreState(const std::any &state) { } [[nodiscard]] virtual auto selectedListValue() -> rpl::producer { return nullptr; } virtual void selectionAction(Info::SelectionAction action) { } virtual void fillTopBarMenu( const Ui::Menu::MenuCallback &addAction) { } virtual bool paintOuter( not_null outer, int maxVisibleHeight, QRect clip) { return false; } [[nodiscard]] rpl::producer<> showFinishes() const { return _showFinished.events(); } void showOther(Type type) { _showOtherRequests.fire_copy(type); } [[nodiscard]] Fn showOtherMethod() { return crl::guard(this, [=](Type type) { showOther(type); }); } protected: void build( not_null container, SectionBuildMethod method); private: const not_null _controller; rpl::event_stream _showOtherRequests; rpl::event_stream<> _showFinished; }; enum class IconType { Rounded, Round, Simple, }; struct IconDescriptor { const style::icon *icon = nullptr; IconType type = IconType::Rounded; const style::color *background = nullptr; std::optional backgroundBrush; // Can be useful for gradients. bool newBadge = false; explicit operator bool() const { return (icon != nullptr); } }; class Icon final { public: explicit Icon(IconDescriptor descriptor); void paint(QPainter &p, QPoint position) const; void paint(QPainter &p, int x, int y) const; [[nodiscard]] int width() const; [[nodiscard]] int height() const; [[nodiscard]] QSize size() const; private: not_null _icon; std::optional _background; std::optional> _backgroundBrush; }; void AddButtonIcon( not_null button, const style::SettingsButton &st, IconDescriptor &&descriptor); object_ptr