diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp index 35468706b..576df55fb 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.cpp @@ -234,7 +234,12 @@ void OverlayWidget::RendererGL::paint( if (_factor != factor) { _factor = factor; _controlsImage.invalidate(); - _controlsFadeImage.invalidate(); + + // We use the fact that fade texture atlas + // takes exactly full texture size. In case we + // just invalidate it we may get larger image + // in case of moving from greater _factor to lesser. + _controlsFadeImage.destroy(&f); } _blendingEnabled = false; _viewport = widget->size(); @@ -468,10 +473,10 @@ void OverlayWidget::RendererGL::paintTransformedContent( program->setUniformValue("viewport", _uniformViewport); const auto &top = st::mediaviewShadowTop.size(); + const auto point = QPoint(_shadowTopFlip ? 0 : (_viewport.width() - top.width()), 0); program->setUniformValue( "shadowTopRect", - Uniform(transformRect( - QRect(QPoint(_viewport.width() - top.width(), 0), top)))); + Uniform(transformRect(QRect(point, top)))); const auto &bottom = st::mediaviewShadowBottom; program->setUniformValue( "shadowBottomAndOpacity", @@ -687,9 +692,12 @@ void OverlayWidget::RendererGL::invalidateControls() { } void OverlayWidget::RendererGL::validateControlsFade() { - if (!_controlsFadeImage.image().isNull()) { + const auto flip = !_owner->topShadowOnTheRight(); + if (!_controlsFadeImage.image().isNull() + && _shadowTopFlip == flip) { return; } + _shadowTopFlip = flip; const auto width = st::mediaviewShadowTop.width(); const auto bottomTop = st::mediaviewShadowTop.height(); const auto height = bottomTop + st::mediaviewShadowBottom.height(); @@ -707,6 +715,10 @@ void OverlayWidget::RendererGL::validateControlsFade() { QRect(0, bottomTop, width, st::mediaviewShadowBottom.height())); p.end(); + if (flip) { + image = std::move(image).mirrored(true, false); + } + _controlsFadeImage.setImage(std::move(image)); _shadowTopTexture = QRect( QPoint(), diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h index ba04535de..effab47ad 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_opengl.h @@ -142,6 +142,7 @@ private: QRect _shadowTopTexture; QRect _shadowBottomTexture; + bool _shadowTopFlip; 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 16b54a99f..bd9675380 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_raster.cpp @@ -105,11 +105,22 @@ void OverlayWidget::RendererSW::paintControlsFade( _p->setClipRect(geometry); const auto width = _owner->width(); const auto &top = st::mediaviewShadowTop; + const auto flip = !_owner->topShadowOnTheRight(); const auto topShadow = QRect( - QPoint(width - top.width(), 0), + QPoint(flip ? 0 : (width - top.width()), 0), top.size()); if (topShadow.intersected(geometry).intersects(_clipOuter)) { - top.paint(*_p, topShadow.topLeft(), width); + if (flip) { + if (_topShadowCache.isNull() + || _topShadowColor != st::windowShadowFg->c) { + _topShadowColor = st::windowShadowFg->c; + _topShadowCache = top.instance( + _topShadowColor).mirrored(true, false); + } + _p->drawImage(0, 0, _topShadowCache); + } else { + top.paint(*_p, topShadow.topLeft(), width); + } } const auto &bottom = st::mediaviewShadowBottom; const auto bottomShadow = QRect( diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_raster.h b/Telegram/SourceFiles/media/view/media_view_overlay_raster.h index 9fb6e42cb..3df304236 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_raster.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_raster.h @@ -66,6 +66,9 @@ private: QImage _overControlImage; + QImage _topShadowCache; + QColor _topShadowColor; + }; } // namespace Media::View diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index c8a5b38e8..339e5332d 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -493,6 +493,12 @@ OverlayWidget::OverlayWidget() } } }, lifetime()); + _topShadowRight = _helper->controlsSideRightValue(); + _topShadowRight.changes( + ) | rpl::start_with_next([=] { + updateControlsGeometry(); + update(); + }, lifetime()); _window->setTitle(u"Media viewer"_q); _window->setTitleStyle(st::mediaviewTitle); @@ -822,13 +828,19 @@ void OverlayWidget::updateControlsGeometry() { 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); + _topShadowRect = QRect( + QPoint(topShadowOnTheRight() ? (width() - top.width()) : 0, 0), + top); updateControls(); resizeContentByScreenSize(); update(); } +bool OverlayWidget::topShadowOnTheRight() const { + return _topShadowRight.current(); +} + QSize OverlayWidget::flipSizeByRotation(QSize size) const { return FlipSizeByRotation(size, _rotation); } diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index f2b40976d..7b9dd5788 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -458,6 +458,7 @@ private: void clearStreaming(bool savePosition = true); bool canInitStreaming() const; + [[nodiscard]] bool topShadowOnTheRight() const; void applyHideWindowWorkaround(); Window::SessionController *findWindow(bool switchTo = true) const; @@ -561,6 +562,7 @@ private: QRect _bottomShadowRect; QRect _topShadowRect; + rpl::variable _topShadowRight = false; QRect _photoRadialRect; Ui::RadialAnimation _radial; diff --git a/Telegram/SourceFiles/platform/mac/overlay_widget_mac.h b/Telegram/SourceFiles/platform/mac/overlay_widget_mac.h index 2fa33447b..1e292891f 100644 --- a/Telegram/SourceFiles/platform/mac/overlay_widget_mac.h +++ b/Telegram/SourceFiles/platform/mac/overlay_widget_mac.h @@ -35,6 +35,7 @@ public: void minimize(not_null window) override; void clearState() override; void setControlsOpacity(float64 opacity) override; + rpl::producer controlsSideRightValue() override; private: using Control = Ui::Platform::TitleControl; diff --git a/Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm b/Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm index 3429763d6..7f26d7083 100644 --- a/Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm +++ b/Telegram/SourceFiles/platform/mac/overlay_widget_mac.mm @@ -148,6 +148,10 @@ void MacOverlayWidgetHelper::setControlsOpacity(float64 opacity) { _data->masterOpacity = opacity; } +rpl::producer MacOverlayWidgetHelper::controlsSideRightValue() { + return rpl::single(false); +} + object_ptr MacOverlayWidgetHelper::create( not_null parent, Control control) { diff --git a/Telegram/SourceFiles/platform/platform_overlay_widget.cpp b/Telegram/SourceFiles/platform/platform_overlay_widget.cpp index aa1f38b16..5707b54f3 100644 --- a/Telegram/SourceFiles/platform/platform_overlay_widget.cpp +++ b/Telegram/SourceFiles/platform/platform_overlay_widget.cpp @@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/effects/animations.h" #include "ui/platform/ui_platform_window_title.h" +#include "ui/platform/ui_platform_utility.h" #include "ui/widgets/rp_window.h" #include "ui/abstract_button.h" #include "styles/style_media_view.h" @@ -222,6 +223,13 @@ rpl::producer<> DefaultOverlayWidgetHelper::controlsActivations() { return _buttons->activations(); } +rpl::producer DefaultOverlayWidgetHelper::controlsSideRightValue() { + return Ui::Platform::TitleControlsLayoutValue() | rpl::map([=] { + return _controls->controls.geometry().center().x() + > _controls->wrap.geometry().center().x(); + }) | rpl::distinct_until_changed(); +} + void DefaultOverlayWidgetHelper::beforeShow(bool fullscreen) { _buttons->clearState(); } diff --git a/Telegram/SourceFiles/platform/platform_overlay_widget.h b/Telegram/SourceFiles/platform/platform_overlay_widget.h index 26e6220ec..2bc2eea33 100644 --- a/Telegram/SourceFiles/platform/platform_overlay_widget.h +++ b/Telegram/SourceFiles/platform/platform_overlay_widget.h @@ -38,6 +38,9 @@ public: [[nodiscard]] virtual rpl::producer<> controlsActivations() { return rpl::never<>(); } + [[nodiscard]] virtual rpl::producer controlsSideRightValue() { + return rpl::single(true); + } virtual void beforeShow(bool fullscreen) { } virtual void afterShow(bool fullscreen) { @@ -72,6 +75,7 @@ public: void beforeShow(bool fullscreen) override; void clearState() override; void setControlsOpacity(float64 opacity) override; + rpl::producer controlsSideRightValue() override; rpl::producer> mouseEvents() const override; private: diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 849a84050..c80df2cdd 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 849a84050356a1321eedc36eb5296374e42fadd6 +Subproject commit c80df2cdd2d2838d5e4aab50075e4f6e7c05e380