/* 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" namespace Ui { class AbstractButton; class RpWidgetWrap; namespace GL { 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; [[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); ~Viewport(); [[nodiscard]] not_null widget() const; [[nodiscard]] not_null rp() const; void setMode(PanelMode mode, not_null parent); void setControlsShown(float64 shown); void setGeometry(QRect geometry); void resizeToWidth(int newWidth); void setScrollTop(int scrollTop); void add( const VideoEndpoint &endpoint, VideoTileTrack track, 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(); private: struct Textures; class VideoTile; class Renderer; class RendererGL; 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); } }; static constexpr auto kShadowMaxAlpha = 80; 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 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::Capabilities capabilities); 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; int _scrollTop = 0; QImage _shadow; rpl::event_stream _clicks; rpl::event_stream _pinToggles; rpl::event_stream _qualityRequests; float64 _controlsShownRatio = 1.; VideoTile *_large = nullptr; 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