From 6ed25d012fca40c50c3d16bfe5aa1bf17e928adf Mon Sep 17 00:00:00 2001 From: John Preston Date: Sat, 26 Oct 2024 12:03:44 +0400 Subject: [PATCH] Use new settings icon in the player. --- .../icons/player/player_settings.png | Bin 0 -> 997 bytes .../icons/player/player_settings@2x.png | Bin 0 -> 1658 bytes .../icons/player/player_settings@3x.png | Bin 0 -> 2211 bytes .../media/player/media_player_button.cpp | 84 +++++++++++++++++- .../media/player/media_player_button.h | 27 +++++- .../media/player/media_player_dropdown.cpp | 36 +++++--- .../media/player/media_player_dropdown.h | 8 +- .../media/player/media_player_widget.cpp | 7 ++ .../SourceFiles/media/view/media_view.style | 2 +- .../view/media_view_playback_controls.cpp | 10 ++- .../media/view/media_view_playback_controls.h | 4 +- 11 files changed, 157 insertions(+), 21 deletions(-) create mode 100644 Telegram/Resources/icons/player/player_settings.png create mode 100644 Telegram/Resources/icons/player/player_settings@2x.png create mode 100644 Telegram/Resources/icons/player/player_settings@3x.png diff --git a/Telegram/Resources/icons/player/player_settings.png b/Telegram/Resources/icons/player/player_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..65a420de07ae2242344fa7ebd2f07f08268a96dd GIT binary patch literal 997 zcmVU>h*?d$b`aT5T$j!+ zmv){4Q-A$k)t||l8vWnYL5&#};E{=yZHo!sB_1(oDdMW&yvxUe(=MMoo|R;r_?B4G z3TlS9Ni3&3^n3@Gie;^}gV^4m)mN9r9O_ZbVG|}8icnF31O?%L{L_vm;#3HD6?Va!XbBie+=k*;rwF^@ErnnmGiG7&g~k7pMfj= z2Nx-7yi*22%K!iX1Y=1lBtyYUq2?PR)3?OVY8lg}K1GbyA4?#AYJ)KU= z<&vDmVo@v>Wkab{TCG+{7_enB8Clh^&1Rd==iP1>Dv?Oo?RHI5k;CCgCX+znG``j2o#IO#^dqfa1czbR-4Uc&({U0R;xn7HknMK z(WqcFkWQzmd@vZeTrOCj&v!f?>5Jk35JD%jF;`XfzthDj}r8 zFjkdHMOL-a1Zy@Mj5|&y{&Km9lpFA^()eq4OY8Uh!{Jcgn`YA&Dq;cTW@E$L>-A*+ zJO1?d)7>xrer-p2AXBN7$K%m7715eVBtoP&kjUbQ&`2hw*=$;^R&|p%bvm6I9}y)% zIke1ip->rH4@U4csy==XvNDF@S|%)-b=pNxZ(6KHiOywovT*FP)U>h*?d$b`aT5T$j!+ zmv){4Q-A$k)t||l8vWnYL5&#};E{=yZHo!sB_1(oDdMW&yvxUe(=MMoo|R;r_?B4G z3TlS9Ni3&3^n3@Gie;^}gV^4m)mN9r9O_ZbVG|}8icnF31O?%L{L_vm;#3HD6?Va!XbBie+=k*;rwF^@ErnnmGiG7&g~k7pMfj= z2Nx-7yi*22%K!iX1Y=1&dbZo&d$#D_4O}mI;6+P$Is8tGl(CmLK7n{hoX*Yv9Yl?H#e%0xKwcga4hbG zI5|1V5U#GSs;jG0Q&azXEmUY?#5FN7;Y8ON$IHu0!qe2$q*uVmfB*o~d)-?8U5xK7 zd3kxhzP_-wwzl+KF#^cR$5q?(Vw|3y9vB$t?d>fnC@3l_!oIMu(B0jAadDw%*|J1NMjjs@yDZnY#_8#4Wo4y@ zhw-jaQBiSrcJ_vK`9~00Tit6wK0ZDKAF-#Wr;(A7@$qruLG%9pzN4dq$Z7DJW>{EQ ze}6wwfdUaaB1qBP+}uQ5gLmI-Y;1%~;c*3>oSfX**%=WL;hy}4h>3~m>gs|h2Bbt2 z@i&OQ|M2ke%gam1v$M1I7FI$+gcA}H-a)egO-xLbiK7b}@K*>g z)cN^21M2JRv*vJ+wY9aauC8)^QC3z~XkxTxA&WR&(2+IrKQ9vxfnvRpup8~|?Fmx- zixHPaPr13dg6CAWfcKa;);p8}#>Up`sWq#)PcshlGT;Pot&J=b8KvEaB8Xv z?d|Qj2!>`fg25oOl?%xaRC6P zHd5c--p0PZzK*!Yr8G?s*WKOStgI|{RiK*Si`?SkqN1Xyh)dtApPwJd;o)J#H58?3 zIv_#F@u^=%c+Czn3zwW24-XGY_xg(IfMm*K*C)AAGv)cx)6>;PbzNNgFtD6~m6et0 zgQun&)RU5u)QdVTElmw_yr^epW@J&mdr^O`*WS*?n4h1o?17FqMmkal-n9PFM+Ya8 zOdK7V4npm4e7JJTe#qg<;65(>AfI`6`oVxcU4q7#3{%*lp`og(D#LwJJ?Tn4Ffg#W zxtUEwEY4F{_-08y>yhNYu&_|+)v&_n2ht3=doV}8A<3s3{WVCYU*3_y!NK6*V8hX* zq@*k@EeTBXdvtW<@ERmNaouTcZ6$4(nwqMwujg{Z#=pP6FWnRu7wZRJ zakv1;-eI9*=yG$nH{_6$aLMPo-qO;-4QqLMnUH`a9^{r7sRNMI#Zck*8$aC#D;|+O z_ai>(8GpX8AJTw;0J1IRqbErjU(oE+zmQ)M_yZ#F4`g8Q}R-T(jq07*qoM6N<$ Ef_^L@6aWAK literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/player/player_settings@3x.png b/Telegram/Resources/icons/player/player_settings@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..da1ec8c72c34b0a7d175967e5aab4d10dea1351b GIT binary patch literal 2211 zcmV;U2weAxP)U>h*?d$b`aT5T$j!+ zmv){4Q-A$k)t||l8vWnYL5&#};E{=yZHo!sB_1(oDdMW&yvxUe(=MMoo|R;r_?B4G z3TlS9Ni3&3^n3@Gie;^}gV^4m)mN9r9O_ZbVG|}8icnF31O?%L{L_vm;#3HD6?Va!XbBie+=k*;rwF^@ErnnmGiG7&g~k7pMfj= z2Nx-7yi*22%K!iX1Y=1e5 zT1iNidlc_EkctY4qKP1AJ}AtfB1;e)77mLx>dH`5#7#68w6v{=ZX^dpL_u(4>Ove5 zE!1#C6Ga8ZaKs65NX_?ty#M38(>H(Dd+Xlb{Z{8Y=XZwxeE!3wOU}<(1I`+7)_}7H zoHgLMHSmW`L-+9TxOwwtKtOQ&;;&CL<5NN@mGR0Nx4T3E1< zkdUaTsNmpW@`sfwCnu+~vy(Vz4WbnZ4rp(0PfJVVFc^mmIO0rO(HQsH+1Y$5N3B13 z@+3Jqd31D?`jsFaKYpwoM?pb>M5U{%>%oHuFbK0Gnwgo&%F2RkZEKcGy}Y~z1_sEV z2C=)li&F7yL(OY`e*VtRj)o}`!8HO=w{PEw-`(AP`}S=^=47CRgoMwZKa(k# zt*fhp3pj#1;v)>1>IE2RfxW#wVg2OfBtAZ#jA1$Y@ZkdnSW;3FF)b!Ae|-7!rMbEJ z+O=zB1n%Hect;qfx&s+eCaSBesm_Xuij+aNdu`z7&*f3+S;10udj9N zny~_>a4ll^{{1^bGNY}6{rK@C)mCn9t_sTLY`CT{5R$GxosA~OG^PY$Wn^UJ-o1Nh zJzb*`z>OO>km-umd}U>2Vq#)?dRl_f{l(&e*@fCFF)^{Hr$<*y6~NQExVSh~oRZ-3 z<;yQ$zT`_SRXLat0idL(%0mET;r;vfsyHKp{{DVp>+9FAM(~8WfB*jC;v&VNNB{sB zsTd&;hA`FF*Qbrw$rUMk;2SD!i;!kyWc2p-hK7b}BLM&mU~L$eQWz8%mztpYL?0U) zYeW-`z?an1)6!Oo>baXV?+S=Meva4M-97`=N zEs+XV+q-w~%2mLGh+t5Gq8!FKaE$;+1%Yv?C3Hte2blwbge@W>Le0>tSFZ>>H8rIX zE<^wj7>a5(k%b@^AtVUwan!&j_}BuDjg4`;NaWtUd824zVPQca(b;HfRz!jc0QE^I zs=-=YTe)`xW3^qWkB^TewMTL&k0UZNk|NMO7ZB=vIf1&|CO9-R!#Kh~Fp4nCnGYX6 zTwh-op<^ME8_LYgq=M;=MxhQEsX$$B6CCO<$Pg3(icFp9p6j5thK7a&$J^VRiv-P2 z3g+kMRW3NCxNkw*X!1bPOykg+lZWDT zk3(sB!N9S_bdR)<3I@Vz)4hCw=KV)fJbpA{*9-J-n^M^#2}Vv#2?x5?uStSGeflK& zH}+1FUZ?Skod{3x`3RBFfSKC1&>jzgX#}7zqJe8~8%^X{`q673umh($cC4d;|Lb86 z8q-dW-}3VEsP7m#e$(iN|BA3{`aKU!Q9eHDD;{y%`g+bLN8Biw?xh4eNn2YRJr>aK z1}ccKu&{=PhNh+_ek*UoO9_O*b0sW3iq}Z!vAFxOto5#3xl&S6LYGoM=^61X6obW>va{jE$Sp!NEaAuh^bR_`}1)I7gJ(kTP)K zg?nd-uHvt)u4+X@*f`^!TYkBYw_dn(r>83-vggmAOUv=&e@aRUHj%s-c**nP#fzVP zxz3}KKZk%6hZALGWfUkvXO;0>d|~xSb$HJ0)nO{n|%j)_?9&RaI43ScqE3ki#9M#^-3pOH(hgY&#o%qcvQc4GYo_@g^ajH9O lz*z&%8gSNtvjz;+z~4q->i4;Fql^Fm002ovPDHLkV1i9A15f|} literal 0 HcmV?d00001 diff --git a/Telegram/SourceFiles/media/player/media_player_button.cpp b/Telegram/SourceFiles/media/player/media_player_button.cpp index 0e9ab424a..a42929211 100644 --- a/Telegram/SourceFiles/media/player/media_player_button.cpp +++ b/Telegram/SourceFiles/media/player/media_player_button.cpp @@ -307,7 +307,7 @@ SpeedButton::SpeedButton(QWidget *parent, const style::MediaSpeedButton &st) resize(_st.size); } -void SpeedButton::setSpeed(float64 speed, anim::type animated) { +void SpeedButton::setSpeed(float64 speed) { _isDefault = EqualSpeeds(speed, 1.); _layout.setSpeed(speed); update(); @@ -337,4 +337,86 @@ QImage SpeedButton::prepareRippleMask() const { _st.rippleRadius); } +SettingsButton::SettingsButton( + QWidget *parent, + const style::MediaSpeedButton &st) +: RippleButton(parent, st.ripple) +, _st(st) +, _isDefaultSpeed(true) { + resize(_st.size); +} + +void SettingsButton::setSpeed(float64 speed) { + _isDefaultSpeed = EqualSpeeds(speed, 1.); + update(); +} + +void SettingsButton::setQuality(int quality) { + update(); +} + +void SettingsButton::setActive(bool active) { + if (_active == active) { + return; + } + _active = active; + _activeAnimation.start([=] { + update(); + }, active ? 0. : 1., active ? 1. : 0., crl::time(150)); +} + +void SettingsButton::paintEvent(QPaintEvent *e) { + auto p = QPainter(this); + + paintRipple( + p, + QPoint(_st.padding.left(), _st.padding.top()), + _isDefaultSpeed ? nullptr : &_st.rippleActiveColor->c); + + //const auto active = !_isDefaultSpeed; + const auto inner = QRect( + QPoint(), + _st.size + ).marginsRemoved(_st.padding); + + auto hq = std::optional(); + const auto active = _activeAnimation.value(_active ? 1. : 0.); + if (active > 0.) { + const auto shift = QRectF(inner).center(); + p.save(); + p.translate(shift); + p.rotate(active * 60.); + p.translate(-shift); + hq.emplace(p); + } + _st.icon.paintInCenter(p, inner); + if (active > 0.) { + p.restore(); + hq.reset(); + } + + //p.setPen(color); + //p.setFont(_st.font); + + //p.drawText( + // QPointF(inner.topLeft()) + QPointF( + // (inner.width() - _textWidth) / 2., + // (inner.height() - _adjustedHeight) / 2. + _adjustedAscent), + // _text); +} + +QPoint SettingsButton::prepareRippleStartPosition() const { + const auto inner = rect().marginsRemoved(_st.padding); + const auto result = mapFromGlobal(QCursor::pos()) - inner.topLeft(); + return inner.contains(result) + ? result + : DisabledRippleStartPosition(); +} + +QImage SettingsButton::prepareRippleMask() const { + return Ui::RippleAnimation::RoundRectMask( + rect().marginsRemoved(_st.padding).size(), + _st.rippleRadius); +} + } // namespace Media::Player diff --git a/Telegram/SourceFiles/media/player/media_player_button.h b/Telegram/SourceFiles/media/player/media_player_button.h index 750b533eb..8709c0cdd 100644 --- a/Telegram/SourceFiles/media/player/media_player_button.h +++ b/Telegram/SourceFiles/media/player/media_player_button.h @@ -87,7 +87,7 @@ public: return _st; } - void setSpeed(float64 speed, anim::type animated = anim::type::normal); + void setSpeed(float64 speed); private: void paintEvent(QPaintEvent *e) override; @@ -101,4 +101,29 @@ private: }; +class SettingsButton final : public Ui::RippleButton { +public: + SettingsButton(QWidget *parent, const style::MediaSpeedButton &st); + + [[nodiscard]] const style::MediaSpeedButton &st() const { + return _st; + } + + void setSpeed(float64 speed); + void setQuality(int quality); + void setActive(bool active); + +private: + void paintEvent(QPaintEvent *e) override; + + QPoint prepareRippleStartPosition() const override; + QImage prepareRippleMask() const override; + + const style::MediaSpeedButton &_st; + Ui::Animations::Simple _activeAnimation; + bool _isDefaultSpeed = false; + bool _active = false; + +}; + } // namespace Media::Player diff --git a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp index 843ce1553..45e4e2c04 100644 --- a/Telegram/SourceFiles/media/player/media_player_dropdown.cpp +++ b/Telegram/SourceFiles/media/player/media_player_dropdown.cpp @@ -558,6 +558,10 @@ void WithDropdownController::updateDropdownGeometry() { _menu->move(position); } +rpl::producer WithDropdownController::menuToggledValue() const { + return _menuToggled.value(); +} + void WithDropdownController::hideTemporarily() { if (_menu && !_menu->isHidden()) { _temporarilyHidden = true; @@ -590,10 +594,20 @@ void WithDropdownController::showMenu() { } }, _menu->lifetime()); _menu->setHiddenCallback([=]{ + if (_menu.get() == raw) { + _menuToggled = false; + } Ui::PostponeCall(raw, [this] { _menu = nullptr; + _menuToggled = false; }); }); + _menu->setShowStartCallback([=] { + _menuToggled = true; + }); + _menu->setHideStartCallback([=] { + _menuToggled = false; + }); _button->installEventFilter(raw); fillMenu(raw); updateDropdownGeometry(); @@ -608,6 +622,7 @@ void WithDropdownController::showMenu() { Unexpected("Menu align value."); }(); _menu->showAnimated(origin); + _menuToggled = true; } OrderController::OrderController( @@ -695,7 +710,8 @@ void OrderController::updateIcon() { } SpeedController::SpeedController( - not_null button, + not_null button, + const style::MediaSpeedButton &st, not_null menuParent, Fn menuOverCallback, Fn value, @@ -706,10 +722,10 @@ SpeedController::SpeedController( : WithDropdownController( button, menuParent, - button->st().menu.dropdown, - button->st().menuAlign, + st.menu.dropdown, + st.menuAlign, std::move(menuOverCallback)) -, _st(button->st()) +, _st(st) , _lookup(std::move(value)) , _change(std::move(change)) , _qualities(std::move(qualities)) @@ -727,20 +743,16 @@ SpeedController::SpeedController( setSpeed(_lookup(false)); _speed = _lookup(true); - - button->setSpeed(_speed, anim::type::instant); - - _speedChanged.events_starting_with( - speed() - ) | rpl::start_with_next([=](float64 speed) { - button->setSpeed(speed); - }, button->lifetime()); } rpl::producer<> SpeedController::saved() const { return _saved.events(); } +rpl::producer SpeedController::realtimeValue() const { + return _speedChanged.events_starting_with(speed()); +} + float64 SpeedController::speed() const { return _isDefault ? 1. : _speed; } diff --git a/Telegram/SourceFiles/media/player/media_player_dropdown.h b/Telegram/SourceFiles/media/player/media_player_dropdown.h index 7fcdc1f29..7975677ff 100644 --- a/Telegram/SourceFiles/media/player/media_player_dropdown.h +++ b/Telegram/SourceFiles/media/player/media_player_dropdown.h @@ -30,8 +30,6 @@ class Menu; namespace Media::Player { -class SpeedButton; - class Dropdown final : public Ui::RpWidget { public: explicit Dropdown(QWidget *parent); @@ -82,6 +80,7 @@ public: Ui::DropdownMenu *menu() const; void updateDropdownGeometry(); + [[nodiscard]] rpl::producer menuToggledValue() const; void hideTemporarily(); void showBack(); @@ -98,6 +97,7 @@ private: const Qt::Alignment _menuAlign = Qt::AlignTop | Qt::AlignRight; const Fn _menuOverCallback; base::unique_qptr _menu; + rpl::variable _menuToggled; bool _temporarilyHidden = false; bool _overButton = false; @@ -125,7 +125,8 @@ private: class SpeedController final : public WithDropdownController { public: SpeedController( - not_null button, + not_null button, + const style::MediaSpeedButton &st, not_null menuParent, Fn menuOverCallback, Fn value, @@ -135,6 +136,7 @@ public: Fn changeQuality = nullptr); [[nodiscard]] rpl::producer<> saved() const; + [[nodiscard]] rpl::producer realtimeValue() const; private: void fillMenu(not_null menu) override; diff --git a/Telegram/SourceFiles/media/player/media_player_widget.cpp b/Telegram/SourceFiles/media/player/media_player_widget.cpp index a74be5945..6425b7951 100644 --- a/Telegram/SourceFiles/media/player/media_player_widget.cpp +++ b/Telegram/SourceFiles/media/player/media_player_widget.cpp @@ -73,10 +73,17 @@ Widget::Widget( , _speedController( std::make_unique( _speedToggle.data(), + _speedToggle->st(), dropdownsParent, [=](bool over) { markOver(over); }, [=](bool lastNonDefault) { return speedLookup(lastNonDefault); }, [=](float64 speed) { saveSpeed(speed); })) { + _speedController->realtimeValue( + ) | rpl::start_with_next([=](float64 speed) { + _speedToggle->setSpeed(speed); + }, _speedToggle->lifetime()); + _speedToggle->finishAnimating(); + setAttribute(Qt::WA_OpaquePaintEvent); setMouseTracking(true); resize(width(), st::mediaPlayerHeight + st::lineWidth); diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 3c3ae5fbf..55efb6fcc 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -354,7 +354,7 @@ mediaviewSpeedButton: MediaSpeedButton(mediaPlayerSpeedButton) { fg: mediaviewPlaybackIconFg; overFg: mediaviewPlaybackIconFgOver; activeFg: mediaviewTextLinkFg; - icon: icon{{ "player/player_speed", mediaviewPlaybackIconFg }}; + icon: icon{{ "player/player_settings", mediaviewPlaybackIconFg }}; ripple: RippleAnimation(defaultRippleAnimation) { color: mediaviewPlaybackIconRipple; } diff --git a/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp b/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp index 8ec6bd86c..ac46c78db 100644 --- a/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp +++ b/Telegram/SourceFiles/media/view/media_view_playback_controls.cpp @@ -36,7 +36,7 @@ PlaybackControls::PlaybackControls( , _volumeController(this, st::mediaviewPlayback) , _speedToggle((Media::Audio::SupportsSpeedControl() || !_delegate->playbackControlsQualities().empty()) - ? object_ptr(this, st::mediaviewSpeedButton) + ? object_ptr(this, st::mediaviewSpeedButton) : nullptr) , _fullScreenToggle(this, st::mediaviewFullScreenButton) , _pictureInPicture(this, st::mediaviewPipButton) @@ -45,6 +45,7 @@ PlaybackControls::PlaybackControls( , _speedController(_speedToggle ? std::make_unique( _speedToggle.data(), + _speedToggle->st(), parent, [=](bool) {}, [=](bool lastNonDefault) { return speedLookup(lastNonDefault); }, @@ -62,6 +63,11 @@ PlaybackControls::PlaybackControls( fadeUpdated(opacity); }); + _speedController->menuToggledValue( + ) | rpl::start_with_next([=](bool toggled) { + _speedToggle->setActive(toggled); + }, _speedToggle->lifetime()); + _pictureInPicture->addClickHandler([=] { _delegate->playbackControlsToPictureInPicture(); }); @@ -193,10 +199,12 @@ float64 PlaybackControls::speedLookup(bool lastNonDefault) const { } void PlaybackControls::saveSpeed(float64 speed) { + _speedToggle->setSpeed(speed); _delegate->playbackControlsSpeedChanged(speed); } void PlaybackControls::saveQuality(int quality) { + _speedToggle->setQuality(quality); _delegate->playbackControlsQualityChanged(quality); } diff --git a/Telegram/SourceFiles/media/view/media_view_playback_controls.h b/Telegram/SourceFiles/media/view/media_view_playback_controls.h index 0970808c8..5357fb2fe 100644 --- a/Telegram/SourceFiles/media/view/media_view_playback_controls.h +++ b/Telegram/SourceFiles/media/view/media_view_playback_controls.h @@ -21,7 +21,7 @@ class PopupMenu; namespace Media { namespace Player { struct TrackState; -class SpeedButton; +class SettingsButton; class SpeedController; } // namespace Player @@ -114,7 +114,7 @@ private: std::unique_ptr _receivedTillProgress; object_ptr _volumeToggle; object_ptr _volumeController; - object_ptr _speedToggle; + object_ptr _speedToggle; object_ptr _fullScreenToggle; object_ptr _pictureInPicture; object_ptr _playedAlready;