From 7e8d1f7974fb9e1bf5245d0d8b5948f0f5adfe97 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 11 May 2021 12:57:41 +0400 Subject: [PATCH] Toggle video pin from LargeVideo. --- Telegram/SourceFiles/calls/calls.style | 6 +- .../calls/group/calls_group_large_video.cpp | 81 +++++++++++++++---- .../calls/group/calls_group_large_video.h | 14 ++++ .../calls/group/calls_group_members_row.cpp | 6 +- .../calls/group/calls_group_panel.cpp | 8 ++ Telegram/lib_ui | 2 +- 6 files changed, 95 insertions(+), 22 deletions(-) diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 453186d9d..567b2eee8 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1173,7 +1173,7 @@ groupCallVideoCrossLine: CrossLineAnimation(groupCallNarrowInactiveCrossLine) { } groupCallLargeVideoCrossLine: CrossLineAnimation(groupCallMemberColoredCrossLine) { - fg: groupCallVideoTextFg; + fg: groupCallVideoSubTextFg; icon: icon {{ "calls/group_calls_unmuted", groupCallVideoSubTextFg }}; } @@ -1187,7 +1187,7 @@ GroupCallLargeVideo { } groupCallLargeVideoWide: GroupCallLargeVideo { - shadowHeight: 60px; + shadowHeight: 100px; controlsAlign: align(top); namePosition: point(15px, 8px); statusPosition: point(15px, 28px); @@ -1195,7 +1195,7 @@ groupCallLargeVideoWide: GroupCallLargeVideo { iconPosition: point(14px, 15px); } groupCallLargeVideoNarrow: GroupCallLargeVideo { - shadowHeight: 50px; + shadowHeight: 80px; controlsAlign: align(top); namePosition: point(64px, 44px); statusPosition: point(64px, 20px); diff --git a/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp b/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp index 9380c41c3..88d19d1d4 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_large_video.cpp @@ -28,7 +28,9 @@ LargeVideo::LargeVideo( rpl::producer pinned) : _content(parent, [=](QRect clip) { paint(clip); }) , _st(st) -, _pin(st::groupCallLargeVideoPin) { +, _pin(st::groupCallLargeVideoPin) +, _pinButton(&_content) +, _topControls(_st.controlsAlign == style::al_top) { _content.setVisible(visible); setup(std::move(track), std::move(pinned)); } @@ -45,16 +47,15 @@ void LargeVideo::setGeometry(int x, int y, int width, int height) { _content.setGeometry(x, y, width, height); } +rpl::producer LargeVideo::pinToggled() const { + return _pinButton.clicks() | rpl::map([=] { return !_pinned; }); +} + void LargeVideo::setup( rpl::producer track, rpl::producer pinned) { _content.setAttribute(Qt::WA_OpaquePaintEvent); - std::move(pinned) | rpl::start_with_next([=](bool pinned) { - _pinned = pinned; - _content.update(); - }, _content.lifetime()); - rpl::combine( _content.shownValue(), std::move(track) @@ -78,6 +79,45 @@ void LargeVideo::setup( _content.update(); }, _trackLifetime); }, _content.lifetime()); + + setupControls(std::move(pinned)); +} + +void LargeVideo::setupControls(rpl::producer pinned) { + std::move(pinned) | rpl::start_with_next([=](bool pinned) { + _pinned = pinned; + _content.update(); + }, _content.lifetime()); + + _content.sizeValue( + ) | rpl::start_with_next([=](QSize size) { + updateControlsGeometry(); + }, _content.lifetime()); +} + +void LargeVideo::updateControlsGeometry() { + if (_topControls) { + const auto &pin = st::groupCallLargeVideoPin.icon; + const auto pinWidth = pin.width(); + const auto pinRight = (_content.width() - _st.pinPosition.x()); + const auto pinTop = _st.pinPosition.y(); + const auto &icon = st::groupCallLargeVideoCrossLine.icon; + const auto iconLeft = _content.width() + - _st.iconPosition.x() + - icon.width(); + const auto skip = iconLeft - pinRight; + _pinButton.setGeometry( + pinRight - pin.width() - (skip / 2), + 0, + pin.width() + skip, + pinTop * 2 + pin.height()); + } else { + _pinButton.setGeometry( + 0, + _content.height() - _st.namePosition.y(), + _st.namePosition.x(), + _st.namePosition.y()); + } } void LargeVideo::paint(QRect clip) { @@ -139,12 +179,17 @@ void LargeVideo::paint(QRect clip) { } void LargeVideo::paintControls(Painter &p, QRect clip) { + const auto shown = _controlsAnimation.value(_controlsShown ? 1. : 0.); + if (shown == 0.) { + return; + } + const auto width = _content.width(); const auto height = _content.height(); - const auto topControls = (_st.controlsAlign == style::al_top); + // Shadow. if (_shadow.isNull()) { - if (topControls) { + if (_topControls) { _shadow = GenerateShadow(_st.shadowHeight, kShadowMaxAlpha, 0); } else { _shadow = GenerateShadow(_st.shadowHeight, 0, kShadowMaxAlpha); @@ -152,7 +197,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { } const auto shadowRect = QRect( 0, - topControls ? 0 : (height - _st.shadowHeight), + _topControls ? 0 : (height - _st.shadowHeight), width, _st.shadowHeight); const auto shadowFill = shadowRect.intersected(clip); @@ -170,21 +215,23 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { shadowFill.height() * factor)); _track.row->lazyInitialize(st::groupCallMembersListItem); - p.setPen(topControls + // Name. + p.setPen(_topControls ? st::groupCallVideoTextFg : st::groupCallVideoSubTextFg); const auto hasWidth = width - - (topControls ? _st.pinPosition.x() : _st.iconPosition.x()) + - (_topControls ? _st.pinPosition.x() : _st.iconPosition.x()) - _st.namePosition.x(); const auto nameLeft = _st.namePosition.x(); - const auto nameTop = topControls + const auto nameTop = _topControls ? _st.namePosition.y() : (height - _st.namePosition.y()); _track.row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width); + // Status. p.setPen(st::groupCallVideoSubTextFg); const auto statusLeft = _st.statusPosition.x(); - const auto statusTop = topControls + const auto statusTop = _topControls ? _st.statusPosition.y() : (height - _st.statusPosition.y()); _track.row->paintComplexStatusText( @@ -197,9 +244,10 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { false, MembersRowStyle::LargeVideo); + // Mute. const auto &icon = st::groupCallLargeVideoCrossLine.icon; const auto iconLeft = width - _st.iconPosition.x() - icon.width(); - const auto iconTop = topControls + const auto iconTop = _topControls ? _st.iconPosition.y() : (height - _st.iconPosition.y()); _track.row->paintMuteIcon( @@ -207,11 +255,12 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { { iconLeft, iconTop, icon.width(), icon.height() }, MembersRowStyle::LargeVideo); + // Pin. const auto pinWidth = st::groupCallLargeVideoPin.icon.width(); - const auto pinLeft = topControls + const auto pinLeft = _topControls ? (width - _st.pinPosition.x() - pinWidth) : _st.pinPosition.x(); - const auto pinTop = topControls + const auto pinTop = _topControls ? _st.pinPosition.y() : (height - _st.pinPosition.y()); _pin.paint(p, pinLeft, pinTop, _pinned ? 1. : 0.); diff --git a/Telegram/SourceFiles/calls/group/calls_group_large_video.h b/Telegram/SourceFiles/calls/group/calls_group_large_video.h index 551e45c7e..a93d728fd 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_large_video.h +++ b/Telegram/SourceFiles/calls/group/calls_group_large_video.h @@ -8,7 +8,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "ui/rp_widget.h" +#include "ui/abstract_button.h" #include "ui/effects/cross_line.h" +#include "ui/effects/animations.h" #if defined Q_OS_MAC #define USE_OPENGL_LARGE_VIDEO @@ -60,6 +62,12 @@ public: void setVisible(bool visible); void setGeometry(int x, int y, int width, int height); + [[nodiscard]] rpl::producer pinToggled() const; + + [[nodiscard]] rpl::lifetime &lifetime() { + return _content.lifetime(); + } + private: #ifdef USE_OPENGL_LARGE_VIDEO using ContentParent = Ui::RpWidgetWrap; @@ -86,15 +94,21 @@ private: void setup( rpl::producer track, rpl::producer pinned); + void setupControls(rpl::producer pinned); void paint(QRect clip); void paintControls(Painter &p, QRect clip); + void updateControlsGeometry(); Content _content; const style::GroupCallLargeVideo &_st; LargeVideoTrack _track; QImage _shadow; Ui::CrossLineAnimation _pin; + Ui::AbstractButton _pinButton; + Ui::Animations::Simple _controlsAnimation; + bool _topControls = false; bool _pinned = false; + bool _controlsShown = true; rpl::lifetime _trackLifetime; }; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp b/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp index eca54186b..f9b396d34 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp @@ -727,7 +727,9 @@ void MembersRow::paintComplexStatusText( bool selected, MembersRowStyle style) { const auto &font = st::normalFont; - const auto about = (_state == State::Inactive + const auto about = (style == MembersRowStyle::LargeVideo) + ? QString() + : (_state == State::Inactive || _state == State::Muted || (_state == State::RaisedHand && !_raisedHandStatus)) ? _aboutText @@ -767,7 +769,7 @@ void MembersRow::paintComplexStatusText( outerWidth, (_state == State::MutedByMe ? tr::lng_group_call_muted_by_me_status(tr::now) - : (!about.isEmpty() && style != MembersRowStyle::LargeVideo) + : !about.isEmpty() ? font->m.elidedText(about, Qt::ElideRight, availableWidth) : _delegate->rowIsMe(peer()) ? tr::lng_status_connecting(tr::now) diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 4abf38968..7a545d47f 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -1008,6 +1008,14 @@ void Panel::setupPinnedVideo() { visible, std::move(track), _call->videoEndpointPinnedValue()); + _pinnedVideo->pinToggled( + ) | rpl::start_with_next([=](bool pinned) { + if (!pinned) { + _call->pinVideoEndpoint(VideoEndpoint{}); + } else if (const auto &large = _call->videoEndpointLarge()) { + _call->pinVideoEndpoint(large); + } + }, _pinnedVideo->lifetime()); raiseControls(); } diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 2b36c36dc..aeeb13bd0 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 2b36c36dcbe49fa0d62543b45f42f820cb0c22ad +Subproject commit aeeb13bd029597da8cf5104c2e7c56f4641cd6b6