/* 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/rp_widget.h" #include "ui/effects/animations.h" namespace Ui { class AbstractButton; class RpWidgetWrap; namespace GL { enum class Backend; struct Capabilities; struct ChosenRenderer; } // namespace GL } // namespace Ui namespace Calls { class GroupCall; struct VideoEndpoint; struct VideoQualityRequest; } // namespace Calls namespace Webrtc { class VideoTrack; } // namespace Webrtc namespace Calls::Group { class MembersRow; enum class PanelMode; enum class VideoQuality; struct VideoTileTrack { Webrtc::VideoTrack *track = nullptr; MembersRow *row = nullptr; rpl::variable trackSize; [[nodiscard]] explicit operator bool() const { return track != nullptr; } }; [[nodiscard]] inline bool operator==( VideoTileTrack a, VideoTileTrack b) noexcept { return (a.track == b.track) && (a.row == b.row); } [[nodiscard]] inline bool operator!=( VideoTileTrack a, VideoTileTrack b) noexcept { return !(a == b); } class Viewport final { public: Viewport( not_null parent, PanelMode mode, Ui::GL::Backend backend); ~Viewport(); [[nodiscard]] not_null widget() const; [[nodiscard]] not_null rp() const; void setMode(PanelMode mode, not_null parent); void setControlsShown(float64 shown); void setCursorShown(bool shown); void setGeometry(bool fullscreen, QRect geometry); void resizeToWidth(int newWidth); void setScrollTop(int scrollTop); void add( const VideoEndpoint &endpoint, VideoTileTrack track, rpl::producer trackSize, rpl::producer pinned); void remove(const VideoEndpoint &endpoint); void showLarge(const VideoEndpoint &endpoint); [[nodiscard]] bool requireARGB32() const; [[nodiscard]] int fullHeight() const; [[nodiscard]] rpl::producer fullHeightValue() const; [[nodiscard]] rpl::producer pinToggled() const; [[nodiscard]] rpl::producer clicks() const; [[nodiscard]] rpl::producer qualityRequests() const; [[nodiscard]] rpl::producer mouseInsideValue() const; [[nodiscard]] rpl::lifetime &lifetime(); static constexpr auto kShadowMaxAlpha = 80; private: struct Textures; class VideoTile; class RendererSW; class RendererGL; using TileId = quintptr; struct Geometry { VideoTile *tile = nullptr; QSize size; QRect rows; QRect columns; }; struct Layout { std::vector list; QSize outer; bool useColumns = false; }; struct TileAnimation { QSize from; QSize to; float64 ratio = -1.; }; struct Selection { enum class Element { None, Tile, PinButton, BackButton, }; VideoTile *tile = nullptr; Element element = Element::None; inline bool operator==(Selection other) const { return (tile == other.tile) && (element == other.element); } }; void setup(); [[nodiscard]] bool wide() const; void updateCursor(); void updateTilesGeometry(); void updateTilesGeometry(int outerWidth); void updateTilesGeometryWide(int outerWidth, int outerHeight); void updateTilesGeometryNarrow(int outerWidth); void updateTilesGeometryColumn(int outerWidth); void setTileGeometry(not_null tile, QRect geometry); void refreshHasTwoOrMore(); void updateTopControlsVisibility(); void prepareLargeChangeAnimation(); void startLargeChangeAnimation(); void updateTilesAnimated(); [[nodiscard]] Layout countWide(int outerWidth, int outerHeight) const; [[nodiscard]] Layout applyLarge(Layout layout) const; void setSelected(Selection value); void setPressed(Selection value); void handleMousePress(QPoint position, Qt::MouseButton button); void handleMouseRelease(QPoint position, Qt::MouseButton button); void handleMouseMove(QPoint position); void updateSelected(QPoint position); void updateSelected(); [[nodiscard]] Ui::GL::ChosenRenderer chooseRenderer( Ui::GL::Backend backend); PanelMode _mode = PanelMode(); bool _opengl = false; bool _geometryStaleAfterModeChange = false; const std::unique_ptr _content; std::vector> _tiles; std::vector> _tilesForOrder; rpl::variable _fullHeight = 0; bool _hasTwoOrMore = false; bool _fullscreen = false; bool _cursorHidden = false; int _scrollTop = 0; QImage _shadow; rpl::event_stream _clicks; rpl::event_stream _pinToggles; rpl::event_stream _qualityRequests; float64 _controlsShownRatio = 1.; VideoTile *_large = nullptr; Fn _updateLargeScheduled; Ui::Animations::Simple _largeChangeAnimation; Layout _startTilesLayout; Layout _finishTilesLayout; Selection _selected; Selection _pressed; rpl::variable _mouseInside = false; }; [[nodiscard]] QImage GenerateShadow( int height, int topAlpha, int bottomAlpha, QColor color = QColor(0, 0, 0)); [[nodiscard]] rpl::producer MuteButtonTooltip( not_null call); } // namespace Calls::Group