diff --git a/Telegram/Resources/icons/mediaview/download.png b/Telegram/Resources/icons/mediaview/download.png index 8866edd51..1c15631e5 100644 Binary files a/Telegram/Resources/icons/mediaview/download.png and b/Telegram/Resources/icons/mediaview/download.png differ diff --git a/Telegram/Resources/icons/mediaview/download@2x.png b/Telegram/Resources/icons/mediaview/download@2x.png index e5c3cf39f..36edd45eb 100644 Binary files a/Telegram/Resources/icons/mediaview/download@2x.png and b/Telegram/Resources/icons/mediaview/download@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/download@3x.png b/Telegram/Resources/icons/mediaview/download@3x.png index 20e22ce52..ff3e812ec 100644 Binary files a/Telegram/Resources/icons/mediaview/download@3x.png and b/Telegram/Resources/icons/mediaview/download@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/next.png b/Telegram/Resources/icons/mediaview/next.png index 8a1869c77..785425070 100644 Binary files a/Telegram/Resources/icons/mediaview/next.png and b/Telegram/Resources/icons/mediaview/next.png differ diff --git a/Telegram/Resources/icons/mediaview/next@2x.png b/Telegram/Resources/icons/mediaview/next@2x.png index 360fae2ce..81c5463d8 100644 Binary files a/Telegram/Resources/icons/mediaview/next@2x.png and b/Telegram/Resources/icons/mediaview/next@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/next@3x.png b/Telegram/Resources/icons/mediaview/next@3x.png index 06197f226..8bc7d530c 100644 Binary files a/Telegram/Resources/icons/mediaview/next@3x.png and b/Telegram/Resources/icons/mediaview/next@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/next_shadow.png b/Telegram/Resources/icons/mediaview/next_shadow.png new file mode 100644 index 000000000..0e432c95a Binary files /dev/null and b/Telegram/Resources/icons/mediaview/next_shadow.png differ diff --git a/Telegram/Resources/icons/mediaview/next_shadow@2x.png b/Telegram/Resources/icons/mediaview/next_shadow@2x.png new file mode 100644 index 000000000..bcf60caa7 Binary files /dev/null and b/Telegram/Resources/icons/mediaview/next_shadow@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/next_shadow@3x.png b/Telegram/Resources/icons/mediaview/next_shadow@3x.png new file mode 100644 index 000000000..48eb42399 Binary files /dev/null and b/Telegram/Resources/icons/mediaview/next_shadow@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/rotate.png b/Telegram/Resources/icons/mediaview/rotate.png index 818a9b872..14104385b 100644 Binary files a/Telegram/Resources/icons/mediaview/rotate.png and b/Telegram/Resources/icons/mediaview/rotate.png differ diff --git a/Telegram/Resources/icons/mediaview/rotate@2x.png b/Telegram/Resources/icons/mediaview/rotate@2x.png index 1fc04404b..a846ec5bf 100644 Binary files a/Telegram/Resources/icons/mediaview/rotate@2x.png and b/Telegram/Resources/icons/mediaview/rotate@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/rotate@3x.png b/Telegram/Resources/icons/mediaview/rotate@3x.png index 8369b477b..bfa39cd9f 100644 Binary files a/Telegram/Resources/icons/mediaview/rotate@3x.png and b/Telegram/Resources/icons/mediaview/rotate@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/shadow_bottom.png b/Telegram/Resources/icons/mediaview/shadow_bottom.png index ccf350f2b..bd3799f32 100644 Binary files a/Telegram/Resources/icons/mediaview/shadow_bottom.png and b/Telegram/Resources/icons/mediaview/shadow_bottom.png differ diff --git a/Telegram/Resources/icons/mediaview/shadow_bottom@2x.png b/Telegram/Resources/icons/mediaview/shadow_bottom@2x.png index 6d0c8762d..72a588323 100644 Binary files a/Telegram/Resources/icons/mediaview/shadow_bottom@2x.png and b/Telegram/Resources/icons/mediaview/shadow_bottom@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/shadow_bottom@3x.png b/Telegram/Resources/icons/mediaview/shadow_bottom@3x.png index 52ea5cfd1..3870e77d2 100644 Binary files a/Telegram/Resources/icons/mediaview/shadow_bottom@3x.png and b/Telegram/Resources/icons/mediaview/shadow_bottom@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize.png b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize.png index 84df61a0a..0023e0551 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize.png and b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@2x.png b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@2x.png index 77f55bfa9..8b8b2f1ad 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@2x.png and b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@3x.png b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@3x.png index 7dca97312..a36a73d54 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@3x.png and b/Telegram/Resources/icons/mediaview/title_viewer_button_maximize@3x.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize.png b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize.png index 07e3a28e6..69cd79d4e 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize.png and b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@2x.png b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@2x.png index 312be9534..cc39d499f 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@2x.png and b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@2x.png differ diff --git a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@3x.png b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@3x.png index 5c5509cfa..11d3a9f35 100644 Binary files a/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@3x.png and b/Telegram/Resources/icons/mediaview/title_viewer_shadow_maximize@3x.png differ diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 23116be7f..5130bc448 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -101,11 +101,17 @@ mediaviewVolumeToggle: IconButton(mediaviewControlsButton) { } mediaviewVolumeSkip: 4px; -mediaviewLeft: icon {{ "mediaview/next-flip_horizontal", mediaviewControlFg }}; -mediaviewRight: icon {{ "mediaview/next", mediaviewControlFg }}; +mediaviewLeft: icon { + { "mediaview/next_shadow-flip_horizontal", windowShadowFg } + { "mediaview/next-flip_horizontal", mediaviewControlFg } +}; +mediaviewRight: icon { + { "mediaview/next_shadow", windowShadowFg } + { "mediaview/next", mediaviewControlFg } +}; mediaviewSave: icon {{ "mediaview/download", mediaviewControlFg }}; mediaviewRotate: icon {{ "mediaview/rotate", mediaviewControlFg }}; -mediaviewMore: icon {{ "mediaview/more", mediaviewControlFg }}; +mediaviewMore: icon {{ "title_menu_dots", mediaviewControlFg }}; mediaviewFileRed: icon { { size(25px, 25px), mediaviewFileBg }, @@ -232,15 +238,13 @@ mediaviewThickFont: semiboldFont; mediaviewFont: normalFont; mediaviewTextStyle: defaultTextStyle; -mediaviewTextLeft: 16px; +mediaviewTextLeft: 14px; mediaviewTextSkip: 10px; -mediaviewHeaderTop: 48px; -mediaviewTextTop: 24px; +mediaviewHeaderTop: 47px; +mediaviewTextTop: 26px; -mediaviewIconOpacity: 0.45; -mediaviewIconOverOpacity: 1.; mediaviewControlSize: 90px; -mediaviewIconSize: size(60px, 56px); +mediaviewIconSize: size(46px, 54px); mediaviewWaitHide: 2000; mediaviewHideDuration: 1000; @@ -250,9 +254,9 @@ mediaviewFadeDuration: 150; mediaviewDeltaFromLastAction: 5px; mediaviewSwipeDistance: 80px; -mediaviewCaptionPadding: margins(18px, 10px, 18px, 10px); +mediaviewCaptionPadding: margins(11px, 6px, 11px, 6px); mediaviewCaptionMargin: size(11px, 11px); -mediaviewCaptionRadius: 2px; +mediaviewCaptionRadius: 6px; mediaviewGroupPadding: margins(0px, 14px, 0px, 14px); mediaviewGroupHeight: 80px; @@ -317,6 +321,8 @@ mediaviewTitle: WindowTitle(defaultWindowTitle) { closeIconActive: mediaviewTitleClose; closeIconActiveOver: mediaviewTitleClose; } +mediaviewShadowTop: icon{{ "mediaview/shadow_top", windowShadowFg }}; +mediaviewShadowBottom: icon{{ "mediaview/shadow_bottom", windowShadowFg }}; themePreviewSize: size(903px, 584px); themePreviewBg: windowBg; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp index 880cc2b9d..a4d7c8875 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp @@ -29,6 +29,31 @@ constexpr auto kGroupThumbsOffset = kCaptionOffset + 4; constexpr auto kControlsOffset = kGroupThumbsOffset + 4; constexpr auto kControlValues = 2 * 4 + 4 * 4; +[[nodiscard]] ShaderPart FragmentApplyControlsFade() { + return { + .header = R"( +uniform sampler2D f_texture; +uniform vec4 shadowTopRect; +uniform vec2 shadowBottomAndOpacity; +)", + .body = R"( + float topHeight = shadowTopRect.w; + float bottomHeight = shadowBottomAndOpacity.x; + float opacity = shadowBottomAndOpacity.y; + float viewportHeight = shadowTopRect.y + topHeight; + float fullHeight = topHeight + bottomHeight; + float topY = min( + (viewportHeight - gl_FragCoord.y) / fullHeight, + topHeight / fullHeight); + float topX = (gl_FragCoord.x - shadowTopRect.x) / shadowTopRect.z; + vec4 fadeTop = texture2D(f_texture, vec2(topX, topY)) * opacity; + float bottomY = max(fullHeight - gl_FragCoord.y, topHeight) / fullHeight; + vec4 fadeBottom = texture2D(f_texture, vec2(0.5, bottomY)) * opacity; + result.rgb = result.rgb * (1. - fadeTop.a) * (1. - fadeBottom.a); +)", + }; +} + [[nodiscard]] ShaderPart FragmentPlaceOnTransparentBackground() { return { .header = R"( @@ -77,6 +102,7 @@ OverlayWidget::RendererGL::RendererGL(not_null<OverlayWidget*> owner) : _owner(owner) { style::PaletteChanged( ) | rpl::start_with_next([=] { + _controlsFadeImage.invalidate(); _radialImage.invalidate(); _documentBubbleImage.invalidate(); _themePreviewImage.invalidate(); @@ -118,6 +144,15 @@ void OverlayWidget::RendererGL::init( FragmentSampleARGB32Texture(), })).vertex; + _staticContentProgram.emplace(); + LinkProgram( + &*_staticContentProgram, + _texturedVertexShader, + FragmentShader({ + FragmentSampleARGB32Texture(), + FragmentApplyControlsFade() + })); + _withTransparencyProgram.emplace(); LinkProgram( &*_withTransparencyProgram, @@ -125,6 +160,7 @@ void OverlayWidget::RendererGL::init( FragmentShader({ FragmentSampleARGB32Texture(), FragmentPlaceOnTransparentBackground(), + FragmentApplyControlsFade() })); _yuv420Program.emplace(); @@ -133,6 +169,7 @@ void OverlayWidget::RendererGL::init( _texturedVertexShader, FragmentShader({ FragmentSampleYUV420Texture(), + FragmentApplyControlsFade() })); _nv12Program.emplace(); @@ -141,6 +178,7 @@ void OverlayWidget::RendererGL::init( _texturedVertexShader, FragmentShader({ FragmentSampleNV12Texture(), + FragmentApplyControlsFade() })); _fillProgram.emplace(); @@ -195,6 +233,7 @@ void OverlayWidget::RendererGL::paint( if (_factor != factor) { _factor = factor; _controlsImage.invalidate(); + _controlsFadeImage.invalidate(); } _blendingEnabled = false; _viewport = widget->size(); @@ -283,7 +322,12 @@ void OverlayWidget::RendererGL::paintTransformedVideoFrame( } _chromaNV12 = nv12; } - if (!nv12) { + + validateControlsFade(); + if (nv12) { + _f->glActiveTexture(GL_TEXTURE2); + _controlsFadeImage.bind(*_f); + } else { _f->glActiveTexture(GL_TEXTURE2); _textures.bind(*_f, 3); if (upload) { @@ -297,6 +341,9 @@ void OverlayWidget::RendererGL::paintTransformedVideoFrame( _chromaSize = yuv->chromaSize; _f->glPixelStorei(GL_UNPACK_ALIGNMENT, 4); } + + _f->glActiveTexture(GL_TEXTURE3); + _controlsFadeImage.bind(*_f); } program->setUniformValue("y_texture", GLint(0)); if (nv12) { @@ -305,6 +352,7 @@ void OverlayWidget::RendererGL::paintTransformedVideoFrame( program->setUniformValue("u_texture", GLint(1)); program->setUniformValue("v_texture", GLint(2)); } + program->setUniformValue("f_texture", GLint(nv12 ? 2 : 3)); toggleBlending(false); paintTransformedContent(program, geometry); @@ -325,7 +373,7 @@ void OverlayWidget::RendererGL::paintTransformedStaticContent( auto &program = fillTransparentBackground ? _withTransparencyProgram - : _imageProgram; + : _staticContentProgram; program->bind(); if (fillTransparentBackground) { program->setUniformValue( @@ -369,7 +417,13 @@ void OverlayWidget::RendererGL::paintTransformedStaticContent( _rgbaSize = image.size(); } } + + validateControlsFade(); + _f->glActiveTexture(GL_TEXTURE1); + _controlsFadeImage.bind(*_f); + program->setUniformValue("s_texture", GLint(0)); + program->setUniformValue("f_texture", GLint(1)); toggleBlending(semiTransparent && !fillTransparentBackground); paintTransformedContent(&*program, geometry); @@ -412,6 +466,15 @@ void OverlayWidget::RendererGL::paintTransformedContent( _contentBuffer->write(0, coords, sizeof(coords)); program->setUniformValue("viewport", _uniformViewport); + const auto &top = st::mediaviewShadowTop.size(); + program->setUniformValue( + "shadowTopRect", + Uniform(transformRect( + QRect(QPoint(_viewport.width() - top.width(), 0), top)))); + const auto &bottom = st::mediaviewShadowBottom; + program->setUniformValue( + "shadowBottomAndOpacity", + QVector2D(bottom.height() * _factor, geometry.controlsOpacity)); FillTexturedRectangle(*_f, &*program); } @@ -607,6 +670,36 @@ void OverlayWidget::RendererGL::invalidateControls() { ranges::fill(_controlsTextures, QRect()); } +void OverlayWidget::RendererGL::validateControlsFade() { + if (!_controlsFadeImage.image().isNull()) { + return; + } + const auto width = st::mediaviewShadowTop.width(); + const auto bottomTop = st::mediaviewShadowTop.height(); + const auto height = bottomTop + st::mediaviewShadowBottom.height(); + + auto image = QImage( + QSize(width, height) * _factor, + QImage::Format_ARGB32_Premultiplied); + image.fill(Qt::transparent); + image.setDevicePixelRatio(_factor); + + auto p = QPainter(&image); + st::mediaviewShadowTop.paint(p, 0, 0, width); + st::mediaviewShadowBottom.fill( + p, + QRect(0, bottomTop, width, st::mediaviewShadowBottom.height())); + p.end(); + + _controlsFadeImage.setImage(std::move(image)); + _shadowTopTexture = QRect( + QPoint(), + QSize(width, st::mediaviewShadowTop.height()) * _factor); + _shadowBottomTexture = QRect( + QPoint(0, bottomTop) * _factor, + QSize(width, st::mediaviewShadowBottom.height()) * _factor); +} + void OverlayWidget::RendererGL::paintFooter(QRect outer, float64 opacity) { paintUsingRaster(_footerImage, outer, [&](Painter &&p) { const auto newOuter = QRect(QPoint(), outer.size()); @@ -699,25 +792,25 @@ void OverlayWidget::RendererGL::paintRoundedCorners(int radius) { _f->glDisableVertexAttribArray(position); } - -void OverlayWidget::RendererGL::invalidate() { - _trackFrameIndex = -1; - _streamedIndex = -1; - const auto images = { - &_radialImage, - &_documentBubbleImage, - &_themePreviewImage, - &_saveMsgImage, - &_footerImage, - &_captionImage, - &_groupThumbsImage, - &_controlsImage, - }; - for (const auto image : images) { - image->setImage(QImage()); - } - invalidateControls(); -} +// +//void OverlayWidget::RendererGL::invalidate() { +// _trackFrameIndex = -1; +// _streamedIndex = -1; +// const auto images = { +// &_radialImage, +// &_documentBubbleImage, +// &_themePreviewImage, +// &_saveMsgImage, +// &_footerImage, +// &_captionImage, +// &_groupThumbsImage, +// &_controlsImage, +// }; +// for (const auto image : images) { +// image->setImage(QImage()); +// } +// invalidateControls(); +//} void OverlayWidget::RendererGL::paintUsingRaster( Ui::GL::Image &image, diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h index 668a75113..2cf5994a2 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h @@ -70,7 +70,7 @@ private: void paintGroupThumbs(QRect outer, float64 opacity) override; void paintRoundedCorners(int radius) override; - void invalidate(); + //void invalidate(); void paintUsingRaster( Ui::GL::Image &image, @@ -79,6 +79,7 @@ private: int bufferOffset, bool transparent = false); + void validateControlsFade(); void validateControls(); void invalidateControls(); void toggleBlending(bool enabled); @@ -105,6 +106,7 @@ private: std::optional<QOpenGLBuffer> _contentBuffer; std::optional<QOpenGLShaderProgram> _imageProgram; + std::optional<QOpenGLShaderProgram> _staticContentProgram; QOpenGLShader *_texturedVertexShader = nullptr; std::optional<QOpenGLShaderProgram> _withTransparencyProgram; std::optional<QOpenGLShaderProgram> _yuv420Program; @@ -121,6 +123,7 @@ private: int _streamedIndex = 0; bool _chromaNV12 = false; + Ui::GL::Image _controlsFadeImage; Ui::GL::Image _radialImage; Ui::GL::Image _documentBubbleImage; Ui::GL::Image _themePreviewImage; @@ -134,6 +137,9 @@ private: [[nodiscard]] static Control ControlMeta(OverState control); std::array<QRect, kControlsCount> _controlsTextures; + QRect _shadowTopTexture; + QRect _shadowBottomTexture; + bool _blendingEnabled = false; rpl::lifetime _lifetime; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp index 3755be032..60707c97a 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/painter.h" #include "media/view/media_view_pip.h" +#include "styles/style_media_view.h" namespace Media::View { @@ -73,6 +74,7 @@ void OverlayWidget::RendererSW::paintTransformedVideoFrame( return; } paintTransformedImage(_owner->videoFrame(), rect, rotation); + paintControlsFade(rect, geometry.controlsOpacity); } void OverlayWidget::RendererSW::paintTransformedStaticContent( @@ -89,10 +91,34 @@ void OverlayWidget::RendererSW::paintTransformedStaticContent( if (fillTransparentBackground) { _p->fillRect(rect, _transparentBrush); } - if (image.isNull()) { - return; + if (!image.isNull()) { + paintTransformedImage(image, rect, rotation); } - paintTransformedImage(image, rect, rotation); + paintControlsFade(rect, geometry.controlsOpacity); +} + +void OverlayWidget::RendererSW::paintControlsFade( + QRect geometry, + float64 opacity) { + _p->setOpacity(opacity); + _p->setClipRect(geometry); + const auto width = _owner->width(); + const auto &top = st::mediaviewShadowTop; + const auto topShadow = QRect( + QPoint(width - top.width(), 0), + top.size()); + if (topShadow.intersected(geometry).intersects(_clipOuter)) { + top.paint(*_p, topShadow.topLeft(), width); + } + const auto &bottom = st::mediaviewShadowBottom; + const auto bottomShadow = QRect( + QPoint(0, _owner->height() - bottom.height()), + QSize(width, bottom.height())); + if (bottomShadow.intersected(geometry).intersects(_clipOuter)) { + bottom.fill(*_p, bottomShadow); + } + _p->setClipping(false); + _p->setOpacity(1.); } void OverlayWidget::RendererSW::paintTransformedImage( diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_raster.h b/Telegram/SourceFiles/media/view/media_view_overlay_raster.h index 7e91f660b..25d3d3248 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_raster.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_raster.h @@ -32,6 +32,7 @@ private: const QImage &image, QRect rect, int rotation); + void paintControlsFade(QRect geometry, float64 opacity); void paintRadialLoading( QRect inner, bool radial, diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index aa4f64971..b5d3498d4 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -790,6 +790,11 @@ void OverlayWidget::updateControlsGeometry() { _saveMsg.moveTo((width() - _saveMsg.width()) / 2, (height() - _saveMsg.height()) / 2); _photoRadialRect = QRect(QPoint((width() - st::radialSize.width()) / 2, (height() - st::radialSize.height()) / 2), st::radialSize); + const auto bottom = st::mediaviewShadowBottom.height(); + const auto top = st::mediaviewShadowTop.size(); + _bottomShadowRect = QRect(0, height() - bottom, width(), bottom); + _topShadowRect = QRect(QPoint(width() - top.width(), 0), top); + updateControls(); resizeContentByScreenSize(); update(); @@ -1367,6 +1372,7 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) { _controlsOpacity.update(dt, anim::linear); } _helper->setControlsOpacity(_controlsOpacity.current()); + const auto content = finalContentRect(); const auto toUpdate = QRegion() + (_over == OverLeftNav ? _leftNav : _leftNavIcon) + (_over == OverRightNav ? _rightNav : _rightNavIcon) @@ -1377,7 +1383,9 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) { + _nameNav + _dateNav + _captionRect.marginsAdded(st::mediaviewCaptionPadding) - + _groupThumbsRect; + + _groupThumbsRect + + content.intersected(_bottomShadowRect) + + content.intersected(_topShadowRect); update(toUpdate); return (dt < 1); } @@ -1407,6 +1415,7 @@ QRect OverlayWidget::finalContentRect() const { } OverlayWidget::ContentGeometry OverlayWidget::contentGeometry() const { + const auto controlsOpacity = _controlsOpacity.current(); const auto toRotation = qreal(finalContentRotation()); const auto toRectRotated = QRectF(finalContentRect()); const auto toRectCenter = toRectRotated.center(); @@ -1418,7 +1427,7 @@ OverlayWidget::ContentGeometry OverlayWidget::contentGeometry() const { toRectRotated.width()) : toRectRotated; if (!_geometryAnimation.animating()) { - return { toRect, toRotation }; + return { toRect, toRotation, controlsOpacity }; } const auto fromRect = _oldGeometry.rect; const auto fromRotation = _oldGeometry.rotation; @@ -1441,7 +1450,7 @@ OverlayWidget::ContentGeometry OverlayWidget::contentGeometry() const { fromRect.width() + (toRect.width() - fromRect.width()) * progress, fromRect.height() + (toRect.height() - fromRect.height()) * progress ); - return { useRect, useRotation }; + return { useRect, useRotation, controlsOpacity }; } void OverlayWidget::updateContentRect() { @@ -4152,6 +4161,7 @@ void OverlayWidget::paintControls( const QRect &outer; const QRect &inner; const style::icon &icon; + bool nonbright = false; }; const QRect kEmpty; // When adding / removing controls please update RendererGL. @@ -4161,13 +4171,15 @@ void OverlayWidget::paintControls( _leftNavVisible, _leftNav, _leftNavIcon, - st::mediaviewLeft }, + st::mediaviewLeft, + true }, { OverRightNav, _rightNavVisible, _rightNav, _rightNavIcon, - st::mediaviewRight }, + st::mediaviewRight, + true }, { OverSave, _saveVisible, @@ -4193,9 +4205,9 @@ void OverlayWidget::paintControls( if (!control.visible) { continue; } - const auto bg = overLevel(control.state); - const auto icon = bg * st::mediaviewIconOverOpacity - + (1 - bg) * st::mediaviewIconOpacity; + const auto progress = overLevel(control.state); + const auto bg = progress; + const auto icon = controlOpacity(progress, control.nonbright); renderer->paintControl( control.state, control.outer, @@ -4206,6 +4218,15 @@ void OverlayWidget::paintControls( } } +float64 OverlayWidget::controlOpacity( + float64 progress, + bool nonbright) const { + const auto normal = _windowed + ? kNormalIconOpacity + : kMaximizedIconOpacity; + return progress + (1. - progress) * normal; +} + void OverlayWidget::paintFooterContent( Painter &p, QRect outer, @@ -4221,7 +4242,7 @@ void OverlayWidget::paintFooterContent( const auto date = _dateNav.translated(shift); if (header.intersects(clip)) { auto o = _headerHasLink ? overLevel(OverHeader) : 0; - p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * opacity); + p.setOpacity(controlOpacity(o) * opacity); p.drawText(header.left(), header.top() + st::mediaviewThickFont->ascent, _headerText); if (o > 0) { @@ -4235,7 +4256,7 @@ void OverlayWidget::paintFooterContent( // name if (_nameNav.isValid() && name.intersects(clip)) { float64 o = _from ? overLevel(OverName) : 0.; - p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * opacity); + p.setOpacity(controlOpacity(o) * opacity); _fromNameLabel.drawElided(p, name.left(), name.top(), name.width()); if (o > 0) { @@ -4247,7 +4268,7 @@ void OverlayWidget::paintFooterContent( // date if (date.intersects(clip)) { float64 o = overLevel(OverDate); - p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * opacity); + p.setOpacity(controlOpacity(o) * opacity); p.drawText(date.left(), date.top() + st::mediaviewFont->ascent, _dateText); if (o > 0) { @@ -4323,6 +4344,7 @@ void OverlayWidget::handleKeyPress(not_null<QKeyEvent*> e) { } else if (_fullScreenVideo) { if (key == Qt::Key_Escape) { playbackToggleFullScreen(); + } else if (ctrl) { } else if (key == Qt::Key_0) { activateControls(); restartAtSeekPosition(0); @@ -4337,7 +4359,6 @@ void OverlayWidget::handleKeyPress(not_null<QKeyEvent*> e) { activateControls(); seekRelativeTime(kSeekTimeMs); } - return; } } @@ -4379,8 +4400,6 @@ void OverlayWidget::handleKeyPress(not_null<QKeyEvent*> e) { zoomIn(); } else if (key == Qt::Key_Minus || key == Qt::Key_Underscore) { zoomOut(); - } else if (key == Qt::Key_0) { - zoomReset(); } else if (key == Qt::Key_I) { update(); } @@ -5090,10 +5109,13 @@ bool OverlayWidget::filterApplicationEvent( not_null<QEvent*> e) { const auto type = e->type(); if (type == QEvent::ShortcutOverride) { - const auto keyEvent = static_cast<QKeyEvent*>(e.get()); - const auto ctrl = keyEvent->modifiers().testFlag(Qt::ControlModifier); - if (keyEvent->key() == Qt::Key_F && ctrl && _streamed) { + const auto event = static_cast<QKeyEvent*>(e.get()); + const auto key = event->key(); + const auto ctrl = event->modifiers().testFlag(Qt::ControlModifier); + if (key == Qt::Key_F && ctrl && _streamed) { playbackToggleFullScreen(); + } else if (key == Qt::Key_0 && ctrl) { + zoomReset(); } return true; } else if (type == QEvent::MouseMove diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index becfa9053..2411089f9 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -154,6 +154,7 @@ private: struct ContentGeometry { QRectF rect; qreal rotation = 0.; + qreal controlsOpacity = 0.; }; struct StartStreaming { StartStreaming() : continueStreaming(false), startTime(0) { @@ -417,6 +418,9 @@ private: QRect clip, float64 opacity); + [[nodiscard]] float64 controlOpacity( + float64 progress, + bool nonbright = false) const; [[nodiscard]] bool isSaveMsgShown() const; void updateOverRect(OverState state); @@ -552,6 +556,9 @@ private: object_ptr<Ui::LinkButton> _docSaveAs; object_ptr<Ui::LinkButton> _docCancel; + QRect _bottomShadowRect; + QRect _topShadowRect; + QRect _photoRadialRect; Ui::RadialAnimation _radial;