From aaea367fbabc3d78b394322a379a7ed277473ea4 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 18 May 2021 10:32:06 +0400 Subject: [PATCH] Hide controls when mouse is out of video area. --- .../Resources/icons/calls/voice_enlarge.png | Bin 692 -> 0 bytes .../icons/calls/voice_enlarge@2x.png | Bin 1346 -> 0 bytes .../icons/calls/voice_enlarge@3x.png | Bin 1992 -> 0 bytes Telegram/Resources/icons/calls/voice_pin.png | Bin 585 -> 0 bytes .../Resources/icons/calls/voice_pin@2x.png | Bin 961 -> 0 bytes .../Resources/icons/calls/voice_pin@3x.png | Bin 1336 -> 0 bytes Telegram/SourceFiles/calls/calls.style | 6 +- .../calls/group/calls_group_large_video.cpp | 90 +++----------- .../calls/group/calls_group_large_video.h | 14 +-- .../calls/group/calls_group_members.cpp | 5 +- .../calls/group/calls_group_panel.cpp | 110 ++++++++++-------- .../calls/group/calls_group_panel.h | 8 +- 12 files changed, 85 insertions(+), 148 deletions(-) delete mode 100644 Telegram/Resources/icons/calls/voice_enlarge.png delete mode 100644 Telegram/Resources/icons/calls/voice_enlarge@2x.png delete mode 100644 Telegram/Resources/icons/calls/voice_enlarge@3x.png delete mode 100644 Telegram/Resources/icons/calls/voice_pin.png delete mode 100644 Telegram/Resources/icons/calls/voice_pin@2x.png delete mode 100644 Telegram/Resources/icons/calls/voice_pin@3x.png diff --git a/Telegram/Resources/icons/calls/voice_enlarge.png b/Telegram/Resources/icons/calls/voice_enlarge.png deleted file mode 100644 index 19900113226d47aead30dd88081671776c052a4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$NbB7>k44ofy`glX(f`xTHpSruq6Z zXaU(A42G$TlC0TWzSWdSpS4N|DZ_xKM31CyMmi(^Ox z=i6zv=NTOZjz70hUHgM8YHL?Zlb7S7h01{*08CDR&IN3wXMFSEo6U;-sVR~ z59`YCd9R(^qtBkmraje5=1h&Sbg9rxdRB^az&yJD)QC)>7EkD|GoGVK)tv;H&eeO7#8;n_%E PP>S(%^>bP0l+XkK@9-N7 diff --git a/Telegram/Resources/icons/calls/voice_enlarge@2x.png b/Telegram/Resources/icons/calls/voice_enlarge@2x.png deleted file mode 100644 index 3c23f91e9acb1307aa57f5bc96d0aea9d8ab80e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1346 zcmV-I1-<%-P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*ISF9{1$6iL~kY^0QxA{!+Z-g18PoPOsz z_hrtUpL5T-GxyHa>CByH=G^&yJoEP4!vz2exn!aca8t@<@jn6*5W^KDAPI;;fMJ#% zBmpr9FwD|}7=ZpT>|C15%F1ANb{2ASa(>;vhldB~?(T-8qa(v-xQJD_jpE+k9+a1t z8wxXHL`bEjrG`}_dWdCZWf{UjqmY0`M@Ql9?Tsle7!`yBbar+Ijg5`){{9{e28PcN z5)djnIXQu*rY89K_%IY`)hH|=6n=bs49(5W@cH>^l>@cC(11|Y;o%{)w6wt2*B4c! z6@&1AQ2fEc0SpcfTH!!#8y0{vGc%#Bt&J+uia~fl85tR{y}fN|S8W7PXh7-d>9Do6 z1$lXSMj9>IgawqEnhKknn~2xkBW+dsi`SyU6w&84@yi-gpG|2C@wCh>YA9Cfa&RJk9}oj z1^W8>JfHtJBMhK~gaj2%Nl6J+BZ8Tnob(*A*P1b)>g0f*Vos~HVDy7rI6K$i;GiscXz#n`GOi588O{Ia&}Yh?(Wp9uC9*R zj_ZhGY-}v7t*t>tMFn*@?A6QdTJi79al2t}-}u0mB+RUnOO+2Z1& zZD%m;OSzq-`}_M1;o!t;*8x?7gLiH{=<4bU($doOef8v*mzSZpw-*!zrx1G+w;n_j zk8_e!a1cGWfDnXl!cAgVSC=E6qyKK^Qb#H~UMD&_TEV@|<>jS9g7ivzd%NOxyB+Tb zw{wvGFBr-^w?izHQ1ss|0qJQ3$V)&0py-Q20;saG6887^;pXNB*4Nh|H#b+`C+_l& zt_(FbHOl?{z1QLM;^IQVLn$G{-Q}nU5jZeEKMxq?)2Hn0Y^biT))#S;cMK2>jz)s) zakMN~cSm}~f`czIot~a@1xD+P?SNQtUSD6;-_~DVUbH@ObvFeFe`dk!e^YI3ZNNE4 zdk(@OQ9U4&v{uCB-Eif=5G5G`>ebQFVOW=_^VkU-ztu_~D!skERmgjWp8EQ>oaKK+ z1?m{tt9UKRB-FqZMTS+lz)_e(EGa38aQjI;Jw0kX=BLCvXJ*d9VRe3f?%j~nPfS38 z`b~pmcFqw64r>1uAZ+Lh3E|Am&G~Htu`VWULKX=Q_S@2L^9TtOo~gnS4r*ft%*e`v z^$Zink6kW&lz$S{b2KHt9%9-9@E)#kP+L#{;e&h=dQN?Py)dhlZ~wK=wgA%L;2ZIx zCtCpR?Cd}|z`;MREr1#t8Vom+B6*c9fDnN1K1n1f`o7u*C|n@f3Md>P*$zm9L_#Hc z&lM&gl%2F0wcp?0P*hX|Pft%~s&i9^=|LDTj^xAyg#S8i71Hzbv-&oeXx@X4!5m_d z>^-QR=|K`uq!VE1mmVYmF$gfs(t{)*1_6dydJqH9U)2zL8to2-a{vGU07*qoM6N<$ Ef;YrZZ2$lO diff --git a/Telegram/Resources/icons/calls/voice_enlarge@3x.png b/Telegram/Resources/icons/calls/voice_enlarge@3x.png deleted file mode 100644 index dd75b153a57fafe7f3b0310ada73038b8de94752..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1992 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 rmZi^4@BSTYZ<+&O1OK= 0) ? std::make_unique(&_content) : nullptr) -, _controlsShown(_st.enlargeAlign != style::al_center) -, _hasEnlarge(_st.enlargeAlign == style::al_center) -, _controlsShownRatio(_controlsShown.current() ? 1. : 0.) { +, _smallLayout(!_pinButton) { _content.setVisible(visible); + if (_smallLayout) { + _content.setCursor(style::cur_pointer); + } setup(std::move(track), std::move(pinned)); } @@ -62,15 +63,13 @@ void LargeVideo::setGeometry(int x, int y, int width, int height) { } } -void LargeVideo::setControlsShown(bool shown) { - if (_mouseInside == shown) { +void LargeVideo::setControlsShown(float64 shown) { + if (_controlsShownRatio == shown) { return; } - _mouseInside = shown; - if (!_toggleControlsScheduled) { - _toggleControlsScheduled = true; - crl::on_main(&_content, [=] { toggleControls(); }); - } + _controlsShownRatio = shown; + _content.update(); + updateControlsGeometry(); } rpl::producer LargeVideo::pinToggled() const { @@ -79,10 +78,6 @@ rpl::producer LargeVideo::pinToggled() const { : rpl::never() | rpl::type_erased(); } -rpl::producer LargeVideo::controlsShown() const { - return _controlsShownRatio.value(); -} - QSize LargeVideo::trackSize() const { return _trackSize.current(); } @@ -108,14 +103,7 @@ void LargeVideo::setup( _content.events( ) | rpl::start_with_next([=](not_null e) { - if (e->type() == QEvent::Enter) { - Ui::Integration::Instance().registerLeaveSubscription(&_content); - setControlsShown(true); - } else if (e->type() == QEvent::Leave) { - Ui::Integration::Instance().unregisterLeaveSubscription( - &_content); - setControlsShown(false); - } else if (e->type() == QEvent::MouseButtonPress + if (e->type() == QEvent::MouseButtonPress && static_cast( e.get())->button() == Qt::LeftButton) { _mouseDown = true; @@ -134,13 +122,6 @@ void LargeVideo::setup( _content.shownValue(), std::move(track) ) | rpl::map([=](bool shown, LargeVideoTrack track) { - if (!shown) { - _controlsAnimation.stop(); - if (_hasEnlarge) { - _controlsShown = _mouseInside = false; - } - _controlsShownRatio = _controlsShown.current() ? 1. : 0.; - } return shown ? track : LargeVideoTrack(); }) | rpl::distinct_until_changed( ) | rpl::start_with_next([=](LargeVideoTrack track) { @@ -170,39 +151,6 @@ void LargeVideo::setup( setupControls(std::move(pinned)); } -void LargeVideo::toggleControlsHidingEnabled(bool enabled) { - if (_controlsHidingEnabled == enabled) { - return; - } - _controlsHidingEnabled = enabled; - toggleControls(); -} - -void LargeVideo::toggleControls() { - _toggleControlsScheduled = false; - const auto shown = _mouseInside - || (!_hasEnlarge && !_controlsHidingEnabled); - if (_controlsShown.current() == shown) { - return; - } - _controlsShown = shown; - const auto callback = [=] { - _controlsShownRatio = _controlsAnimation.value( - _controlsShown.current() ? 1. : 0.); - _content.update(); - updateControlsGeometry(); - }; - if (_content.isHidden()) { - updateControlsGeometry(); - } else { - _controlsAnimation.start( - callback, - shown ? 0. : 1., - shown ? 1. : 0., - st::slideWrapDuration); - } -} - void LargeVideo::setupControls(rpl::producer pinned) { std::move(pinned) | rpl::start_with_next([=](bool pinned) { _pinned = pinned; @@ -287,9 +235,7 @@ void LargeVideo::paint(QRect clip) { } void LargeVideo::paintControls(Painter &p, QRect clip) { - const auto ratio = _controlsShownRatio.current(); - const auto shown = _hasEnlarge ? 1. : ratio; - const auto enlarge = _hasEnlarge ? ratio : 0.; + const auto shown = _controlsShownRatio; if (shown == 0.) { return; } @@ -309,7 +255,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { width, _st.shadowHeight); const auto shadowFill = shadowRect.intersected(clip); - if (shadowFill.isEmpty() && enlarge == 0. && !_pinButton) { + if (shadowFill.isEmpty() && _smallLayout) { return; } const auto factor = style::DevicePixelRatio(); @@ -321,16 +267,6 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { (shadowFill.y() - shadowRect.y()) * factor, _shadow.width(), shadowFill.height() * factor)); - if (enlarge > 0.) { - auto color = st::radialBg->c; - color.setAlphaF(color.alphaF() * enlarge); - p.fillRect(clip, color); - - p.setOpacity(enlarge); - st::groupCallVideoEnlarge.paintInCenter(p, _content.rect()); - p.setOpacity(1.); - } - _track.row->lazyInitialize(st::groupCallMembersListItem); // Mute. @@ -358,7 +294,7 @@ void LargeVideo::paintControls(Painter &p, QRect clip) { _track.row->name().drawLeftElided(p, nameLeft, nameTop, hasWidth, width); // Pin. - if (_st.pinPosition.x() >= 0) { + if (_pinButton) { const auto &pin = st::groupCallLargeVideoPin.icon; const auto pinLeft = (width - _st.pinPosition.x() - pin.width()); const auto pinShift = anim::interpolate( diff --git a/Telegram/SourceFiles/calls/group/calls_group_large_video.h b/Telegram/SourceFiles/calls/group/calls_group_large_video.h index 39d361604..ecdb08c9d 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_large_video.h +++ b/Telegram/SourceFiles/calls/group/calls_group_large_video.h @@ -65,11 +65,9 @@ public: void raise(); void setVisible(bool visible); void setGeometry(int x, int y, int width, int height); - void setControlsShown(bool shown); - void toggleControlsHidingEnabled(bool enabled); + void setControlsShown(float64 shown); [[nodiscard]] rpl::producer pinToggled() const; - [[nodiscard]] rpl::producer controlsShown() const; [[nodiscard]] rpl::producer<> clicks() const { return _clicks.events(); } @@ -112,7 +110,6 @@ private: void paint(QRect clip); void paintControls(Painter &p, QRect clip); void updateControlsGeometry(); - void toggleControls(); Content _content; const style::GroupCallLargeVideo &_st; @@ -120,16 +117,11 @@ private: QImage _shadow; Ui::CrossLineAnimation _pin; std::unique_ptr _pinButton; - Ui::Animations::Simple _controlsAnimation; - rpl::variable _controlsShown = true; rpl::event_stream<> _clicks; - const bool _hasEnlarge = true; + const bool _smallLayout = true; bool _pinned = false; - bool _controlsHidingEnabled = false; - bool _mouseInside = false; bool _mouseDown = false; - bool _toggleControlsScheduled = false; - rpl::variable _controlsShownRatio = 1.; + float64 _controlsShownRatio = 1.; rpl::variable _trackSize; rpl::variable _requestedQuality; rpl::lifetime _trackLifetime; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index 6f84478ff..40b8dcbd1 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -1865,8 +1865,9 @@ void Members::refreshTilesGeometry() { QSize(width, heightMax), Qt::KeepAspectRatio); const auto height = std::max(scaled.height(), heightMin); + const auto skip = st::groupCallVideoSmallSkip; sizes.front().first->setGeometry(0, 0, width, height); - _pinnedVideoWrap->resize(width, height); + _pinnedVideoWrap->resize(width, height + skip); return; } const auto min = (st::groupCallWidth @@ -1900,7 +1901,7 @@ void Members::refreshTilesGeometry() { } } } - _pinnedVideoWrap->resize(width, rows * (min + skip) - skip); + _pinnedVideoWrap->resize(width, rows * (min + skip)); } void Members::setupPinnedVideo() { diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 4ba350f34..1f6887ab4 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -1085,9 +1085,10 @@ void Panel::refreshTilesGeometry() { if (_videoTiles.empty() || outer.isEmpty() || _mode == PanelMode::Default) { - trackControls(nullptr); + trackControls(false); return; } + trackControls(true); struct Geometry { QSize size; QRect columns; @@ -1102,15 +1103,12 @@ void Panel::refreshTilesGeometry() { ? QSize() : video->trackSize(); if (size.isEmpty()) { - video->toggleControlsHidingEnabled(false); video->setGeometry(0, 0, outer.width(), 0); } else { sizes.emplace(video, Geometry{ size }); } } if (sizes.size() == 1) { - trackControls(sizes.front().first); - sizes.front().first->toggleControlsHidingEnabled(true); sizes.front().first->setGeometry(0, 0, outer.width(), outer.height()); return; } @@ -1191,7 +1189,6 @@ void Panel::refreshTilesGeometry() { const auto &rect = (columnsBlack < rowsBlack) ? geometry.columns : geometry.rows; - video->toggleControlsHidingEnabled(false); video->setGeometry(rect.x(), rect.y(), rect.width(), rect.height()); } } @@ -1199,6 +1196,7 @@ void Panel::refreshTilesGeometry() { void Panel::setupPinnedVideo() { using namespace rpl::mappers; _pinnedVideoWrap = std::make_unique(widget()); + const auto raw = _pinnedVideoWrap.get(); const auto setupTile = [=]( const VideoEndpoint &endpoint, @@ -1206,7 +1204,7 @@ void Panel::setupPinnedVideo() { const auto row = _members->lookupRow(track.peer); Assert(row != nullptr); auto video = std::make_unique( - _pinnedVideoWrap.get(), + raw, st::groupCallLargeVideoWide, (_mode == PanelMode::Wide), rpl::single(LargeVideoTrack{ track.track.get(), row }), @@ -1227,12 +1225,6 @@ void Panel::setupPinnedVideo() { refreshTilesGeometry(); }, video->lifetime()); - video->lifetime().add([=, video = video.get()] { - if (_trackControlsTile == video) { - trackControls(nullptr); - } - }); - return VideoTile{ .video = std::move(video), .endpoint = endpoint, @@ -1245,7 +1237,7 @@ void Panel::setupPinnedVideo() { ) | rpl::start_with_next([=](const VideoEndpoint &endpoint) { if (_call->activeVideoTracks().contains(endpoint)) { // Add async (=> the participant row is definitely in Members). - crl::on_main(_pinnedVideoWrap.get(), [=] { + crl::on_main(raw, [=] { const auto &tracks = _call->activeVideoTracks(); const auto i = tracks.find(endpoint); if (i != end(tracks)) { @@ -1264,15 +1256,38 @@ void Panel::setupPinnedVideo() { refreshTilesGeometry(); } } - }, _pinnedVideoWrap->lifetime()); + }, raw->lifetime()); - _pinnedVideoWrap->sizeValue() | rpl::start_with_next([=] { + raw->sizeValue() | rpl::start_with_next([=] { refreshTilesGeometry(); - }, _pinnedVideoWrap->lifetime()); + }, raw->lifetime()); + + raw->events( + ) | rpl::start_with_next([=](not_null e) { + if (e->type() == QEvent::Enter) { + Ui::Integration::Instance().registerLeaveSubscription(raw); + toggleWideControls(true); + } else if (e->type() == QEvent::Leave) { + Ui::Integration::Instance().unregisterLeaveSubscription(raw); + toggleWideControls(false); + } + }, raw->lifetime()); raiseControls(); } +void Panel::toggleWideControls(bool shown) { + if (_wideControlsShown == shown) { + return; + } + _wideControlsShown = shown; + _wideControlsAnimation.start( + [=] { updateButtonsGeometry(); }, + shown ? 0. : 1., + shown ? 1. : 0., + st::slideWrapDuration); +} + void Panel::setupJoinAsChangedToasts() { _call->rejoinEvents( ) | rpl::filter([](RejoinEvent event) { @@ -1780,9 +1795,12 @@ bool Panel::updateMode() { _members->setMode(mode); } if (_pinnedVideoWrap) { + _wideControlsAnimation.stop(); + _wideControlsShown = true; _pinnedVideoWrap->setVisible(mode == PanelMode::Wide); for (const auto &tile : _videoTiles) { tile.video->setVisible(mode == PanelMode::Wide); + tile.video->setControlsShown(1.); } } refreshControlsBackground(); @@ -1817,16 +1835,17 @@ void Panel::refreshControlsBackground() { raiseControls(); } -void Panel::trackControls(LargeVideo *video) { - if (_trackControlsTile == video) { +void Panel::trackControls(bool track) { + if (_trackControls == track) { return; } - _trackControlsTile = video; - if (!video) { + _trackControls = track; + if (!track) { _trackControlsLifetime.destroy(); _trackControlsOverStateLifetime.destroy(); - if (_pinnedVideoControlsShown != 1.) { - _pinnedVideoControlsShown = 1.; + toggleWideControls(true); + if (_wideControlsAnimation.animating()) { + _wideControlsAnimation.stop(); updateButtonsGeometry(); } return; @@ -1834,39 +1853,24 @@ void Panel::trackControls(LargeVideo *video) { const auto trackOne = [=](auto &&widget) { if (widget) { - widget->events( + const auto raw = &*widget; + raw->events( ) | rpl::start_with_next([=](not_null e) { if (e->type() == QEvent::Enter) { - video->setControlsShown(true); + toggleWideControls(true); } else if (e->type() == QEvent::Leave) { - video->setControlsShown(false); + toggleWideControls(false); } }, _trackControlsOverStateLifetime); } }; - const auto trackOverState = [=] { - trackOne(_mute); - trackOne(_video); - trackOne(_screenShare); - trackOne(_settings); - trackOne(_callShare); - trackOne(_hangup); - trackOne(_controlsBackground); - }; - - video->controlsShown( - ) | rpl::filter([=](float64 shown) { - return (_pinnedVideoControlsShown != shown); - }) | rpl::start_with_next([=](float64 shown) { - const auto hiding = (shown <= _pinnedVideoControlsShown); - _pinnedVideoControlsShown = shown; - if (hiding && _trackControlsLifetime) { - _trackControlsOverStateLifetime.destroy(); - } else if (!hiding && !_trackControlsOverStateLifetime) { - trackOverState(); - } - updateButtonsGeometry(); - }, _trackControlsLifetime); + trackOne(_mute); + trackOne(_video); + trackOne(_screenShare); + trackOne(_settings); + trackOne(_callShare); + trackOne(_hangup); + trackOne(_controlsBackground); } void Panel::updateControlsGeometry() { @@ -1916,14 +1920,20 @@ void Panel::updateButtonsGeometry() { }; if (_videoMode.current()) { _mute->setStyle(st::callMuteButtonSmall); - toggle(_mode != PanelMode::Wide || _pinnedVideoControlsShown > 0.); + const auto shown = _wideControlsAnimation.value( + _wideControlsShown ? 1. : 0.); + toggle(_mode != PanelMode::Wide || shown > 0.); + + for (const auto &tile : _videoTiles) { + tile.video->setControlsShown(shown); + } const auto buttonsTop = widget()->height() - (_mode == PanelMode::Wide ? anim::interpolate( 0, st::groupCallButtonBottomSkipWide, - _pinnedVideoControlsShown) + shown) : st::groupCallButtonBottomSkipSmall); const auto addSkip = st::callMuteButtonSmall.active.outerRadius; const auto muteSize = _mute->innerSize().width() + 2 * addSkip; diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.h b/Telegram/SourceFiles/calls/group/calls_group_panel.h index e6777e917..0c9ea5860 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.h +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.h @@ -92,7 +92,7 @@ private: bool handleClose(); void startScheduledNow(); - void trackControls(LargeVideo *video); + void trackControls(bool track); void raiseControls(); void enlargeVideo(); void minimizeVideo(); @@ -105,6 +105,7 @@ private: void showControls(); void refreshLeftButton(); void refreshTilesGeometry(); + void toggleWideControls(bool shown); void endCall(); @@ -149,9 +150,7 @@ private: object_ptr _joinAsToggle = { nullptr }; object_ptr _members = { nullptr }; std::unique_ptr _pinnedVideoWrap; - float64 _pinnedVideoControlsShown = 1.; std::vector _videoTiles; - LargeVideo *_trackControlsTile = nullptr; rpl::lifetime _trackControlsLifetime; rpl::lifetime _trackControlsOverStateLifetime; object_ptr _startsIn = { nullptr }; @@ -163,6 +162,9 @@ private: std::optional _lastSmallGeometry; std::optional _lastLargeGeometry; bool _lastLargeMaximized = false; + bool _wideControlsShown = false; + bool _trackControls = false; + Ui::Animations::Simple _wideControlsAnimation; object_ptr _controlsBackground = { nullptr }; object_ptr _settings = { nullptr };