// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include "base/unique_qptr.h" #include "ui/effects/animations.h" #include "ui/effects/cross_line.h" #include "ui/effects/gradient.h" #include "ui/effects/radial_animation.h" #include "lottie/lottie_icon.h" namespace st { extern const style::InfiniteRadialAnimation &callConnectingRadial; } // namespace st namespace Ui { class BlobsWidget; class AbstractButton; class FlatLabel; class RpWidget; class AnimatedLabel; struct CallButtonColors; enum class CallMuteButtonType { Connecting, Active, Muted, ForceMuted, RaisedHand, ScheduledCanStart, ScheduledSilent, ScheduledNotify, }; struct CallMuteButtonState { QString text; QString subtext; CallMuteButtonType type = CallMuteButtonType::Connecting; }; class CallMuteButton final { public: explicit CallMuteButton( not_null parent, rpl::producer &&hideBlobs, CallMuteButtonState initial = CallMuteButtonState()); ~CallMuteButton(); void setState(const CallMuteButtonState &state); void setLevel(float level); [[nodiscard]] rpl::producer clicks(); [[nodiscard]] QSize innerSize() const; [[nodiscard]] QRect innerGeometry() const; void moveInner(QPoint position); void shake(); void setVisible(bool visible); void show() { setVisible(true); } void hide() { setVisible(false); } void raise(); void lower(); [[nodiscard]] rpl::producer colorOverrides() const; [[nodiscard]] rpl::lifetime &lifetime(); private: enum class HandleMouseState { Enabled, Blocked, Disabled, }; struct RadialInfo { std::optional state = std::nullopt; bool isDirectionToShow = false; rpl::variable rawShowProgress = 0.; float64 realShowProgress = 0.; const style::InfiniteRadialAnimation &st = st::callConnectingRadial; }; struct IconState { int index = -1; int frameFrom = 0; int frameTo = 0; inline bool operator==(const IconState &other) const { return (index == other.index) && (frameFrom == other.frameFrom) && (frameTo == other.frameTo); } inline bool operator!=(const IconState &other) const { return !(*this == other); } bool valid() const { return (index >= 0); } explicit operator bool() const { return valid(); } }; void init(); void overridesColors( CallMuteButtonType fromType, CallMuteButtonType toType, float64 progress); void setHandleMouseState(HandleMouseState state); void updateCenterLabelGeometry(QRect my, QSize size); void updateLabelGeometry(QRect my, QSize size); void updateSublabelGeometry(QRect my, QSize size); void updateLabelsGeometry(); [[nodiscard]] IconState initialState(); [[nodiscard]] IconState iconStateFrom(CallMuteButtonType previous); [[nodiscard]] IconState randomWavingState(); [[nodiscard]] IconState iconStateAnimated(CallMuteButtonType previous); void scheduleIconState(const IconState &state); void startIconState(const IconState &state); void iconAnimationCallback(); [[nodiscard]] static HandleMouseState HandleMouseStateFromType( CallMuteButtonType type); rpl::variable _state; float _level = 0.; QRect _muteIconRect; HandleMouseState _handleMouseState = HandleMouseState::Enabled; const style::CallButton &_st; const base::unique_qptr _blobs; const base::unique_qptr _content; const base::unique_qptr _centerLabel; const base::unique_qptr _label; const base::unique_qptr _sublabel; int _labelShakeShift = 0; RadialInfo _radialInfo; std::unique_ptr _radial; const base::flat_map _colors; std::array, 2> _icons; IconState _iconState; std::optional _scheduledState; Animations::Simple _switchAnimation; Animations::Simple _shakeAnimation; rpl::event_stream _colorOverrides; }; } // namespace Ui