From 4259e90a71b8152d40afaa6563d8489878e54aac Mon Sep 17 00:00:00 2001 From: aleksusklim Date: Mon, 10 May 2021 15:44:53 +0500 Subject: [PATCH 1/7] Hide photo viewer overlay after zooming an image, fixes #7931 --- .../media/view/media_view_overlay_widget.cpp | 42 ++++++++++++++++++- .../media/view/media_view_overlay_widget.h | 2 + 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 21f04f85dbea2..13d934f7539c6 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -1035,6 +1035,12 @@ void OverlayWidget::resizeContentByScreenSize() { } _x = (width() - _w) / 2; _y = (height() - _h) / 2; + _initialZoom = _zoom; + if (_controlsState == ControlsDisabled) { + _controlsState = ControlsHidden; + activateControls(); + updateCursor(); + } } float64 OverlayWidget::radialProgress() const { @@ -1155,7 +1161,7 @@ void OverlayWidget::zoomReset() { auto newZoom = _zoom; const auto full = _fullScreenVideo ? _zoomToScreen : _zoomToDefault; if (_zoom == 0) { - if (qFloor(full) == qCeil(full) && qRound(full) >= -kMaxZoomLevel && qRound(full) <= kMaxZoomLevel) { + if (qFloor(full) == qCeil(full) && qRound(full) >= -kMaxZoomLevel && qRound(full) <= kMaxZoomLevel && qRound(full) != 0) { newZoom = qRound(full); } else { newZoom = kZoomToScreenLevel; @@ -1271,6 +1277,9 @@ void OverlayWidget::close() { } void OverlayWidget::activateControls() { + if (_controlsState == ControlsDisabled) { + return; + } if (!_menu && !_mousePressed) { _controlsHideTimer.callOnce(st::mediaviewWaitHide); } @@ -1304,7 +1313,11 @@ void OverlayWidget::onHideControls(bool force) { if (_fullScreenVideo) { _streamed->controls.hideAnimated(); } - if (_controlsState == ControlsHiding || _controlsState == ControlsHidden) return; + if (_controlsState == ControlsHiding + || _controlsState == ControlsHidden + || _controlsState == ControlsDisabled) { + return; + } _lastMouseMovePos = mapFromGlobal(QCursor::pos()); _controlsState = ControlsHiding; @@ -3681,6 +3694,22 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) { if (!force && _zoom == newZoom) { return; } + if (!_fullScreenVideo) { + if ((_initialZoom == 0 && newZoom > 0) + || (_initialZoom != 0 && newZoom >= 0 && newZoom != _initialZoom)) { + if (_controlsState != ControlsDisabled) { + activateControls(); + onHideControls(true); + updateControlsAnimation(_controlsAnimStarted + st::mediaviewHideDuration); + _controlsState = ControlsDisabled; + updateCursor(); + } + } else if (_controlsState == ControlsDisabled) { + _controlsState = ControlsHidden; + activateControls(); + updateCursor(); + } + } const auto full = _fullScreenVideo ? _zoomToScreen : _zoomToDefault; float64 nx, ny, z = (_zoom == kZoomToScreenLevel) ? full : _zoom; @@ -4034,6 +4063,15 @@ void OverlayWidget::updateOverRect(OverState state) { bool OverlayWidget::updateOverState(OverState newState) { bool result = true; + if (_controlsState == ControlsDisabled + && newState != OverLeftNav + && newState != OverRightNav + && newState != OverClose + && newState != OverVideo) { + _over = OverNone; + updateCursor(); + return false; + } if (_over != newState) { if (newState == OverMore && !_ignoringDropdown) { _dropdownShowTimer.callOnce(0); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index dc9234e0adf41..0d0ed13585e69 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -436,6 +436,7 @@ private Q_SLOTS: int _x = 0, _y = 0, _w = 0, _h = 0; int _xStart = 0, _yStart = 0; int _zoom = 0; // < 0 - out, 0 - none, > 0 - in + int _initialZoom = 0; float64 _zoomToScreen = 0.; // for documents float64 _zoomToDefault = 0.; QPoint _mStart; @@ -498,6 +499,7 @@ private Q_SLOTS: ControlsShown, ControlsHiding, ControlsHidden, + ControlsDisabled }; ControlsState _controlsState = ControlsShown; crl::time _controlsAnimStarted = 0; From c45dc79d8347626ddb44a0ce55c71a8a71116403 Mon Sep 17 00:00:00 2001 From: aleksusklim Date: Mon, 10 May 2021 15:45:47 +0500 Subject: [PATCH 2/7] More hotkeys to zoom images in viewer: Plus, Minus and Asterisk without Ctrl key; alias Enter and Space to reset zoom level for simple photos --- .../SourceFiles/media/view/media_view_overlay_widget.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 13d934f7539c6..65dba9ec9f021 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -3631,6 +3631,8 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) { playbackPauseResume(); } else if (_document && !_document->loading() && (documentBubbleShown() || !_documentMedia->loaded())) { onDocClick(); + } else { + zoomReset(); } } else if (e->key() == Qt::Key_Left) { if (_controlsHideTimer.isActive()) { @@ -3652,6 +3654,12 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) { } else if (e->key() == Qt::Key_I) { update(); } + } else if (e->key() == Qt::Key_Plus) { + zoomIn(); + } else if (e->key() == Qt::Key_Minus) { + zoomOut(); + } else if (e->key() == Qt::Key_Asterisk) { + zoomReset(); } } From 361654a4e0345b30a163b4d587424f509c7483bf Mon Sep 17 00:00:00 2001 From: aleksusklim Date: Tue, 11 May 2021 18:32:46 +0500 Subject: [PATCH 3/7] Second attempt to resolve #7931. Make controls hiding time much shorter if the image was zoomed --- .../SourceFiles/media/view/media_view.style | 3 + .../media/view/media_view_overlay_widget.cpp | 76 ++++++------------- .../media/view/media_view_overlay_widget.h | 2 +- 3 files changed, 26 insertions(+), 55 deletions(-) diff --git a/Telegram/SourceFiles/media/view/media_view.style b/Telegram/SourceFiles/media/view/media_view.style index 40efafa809b40..99e1c60253718 100644 --- a/Telegram/SourceFiles/media/view/media_view.style +++ b/Telegram/SourceFiles/media/view/media_view.style @@ -247,6 +247,9 @@ mediaviewWaitHide: 2000; mediaviewHideDuration: 1000; mediaviewShowDuration: 200; mediaviewFadeDuration: 150; +mediaviewZoomWait: 150; +mediaviewZoomHide: 150; +mediaviewZoomShow: 150; mediaviewDeltaFromLastAction: 5px; mediaviewSwipeDistance: 80px; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 65dba9ec9f021..4c8fb5bb40927 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -928,8 +928,8 @@ bool OverlayWidget::updateControlsAnimation(crl::time now) { return false; } const auto duration = (_controlsState == ControlsShowing) - ? st::mediaviewShowDuration - : st::mediaviewHideDuration; + ? (isZoomedIn() ? st::mediaviewZoomShow : st::mediaviewShowDuration) + : (isZoomedIn() ? st::mediaviewZoomHide : st::mediaviewHideDuration); const auto dt = float64(now - _controlsAnimStarted) / duration; if (dt >= 1) { @@ -1036,11 +1036,6 @@ void OverlayWidget::resizeContentByScreenSize() { _x = (width() - _w) / 2; _y = (height() - _h) / 2; _initialZoom = _zoom; - if (_controlsState == ControlsDisabled) { - _controlsState = ControlsHidden; - activateControls(); - updateCursor(); - } } float64 OverlayWidget::radialProgress() const { @@ -1161,7 +1156,7 @@ void OverlayWidget::zoomReset() { auto newZoom = _zoom; const auto full = _fullScreenVideo ? _zoomToScreen : _zoomToDefault; if (_zoom == 0) { - if (qFloor(full) == qCeil(full) && qRound(full) >= -kMaxZoomLevel && qRound(full) <= kMaxZoomLevel && qRound(full) != 0) { + if (qFloor(full) == qCeil(full) && qRound(full) >= -kMaxZoomLevel && qRound(full) <= kMaxZoomLevel && full != 0.0) { newZoom = qRound(full); } else { newZoom = kZoomToScreenLevel; @@ -1277,11 +1272,8 @@ void OverlayWidget::close() { } void OverlayWidget::activateControls() { - if (_controlsState == ControlsDisabled) { - return; - } - if (!_menu && !_mousePressed) { - _controlsHideTimer.callOnce(st::mediaviewWaitHide); + if (!_menu && !_mousePressed && (_over == OverNone || _over == OverVideo)) { + _controlsHideTimer.callOnce(isZoomedIn() ? st::mediaviewZoomWait : st::mediaviewWaitHide); } if (_fullScreenVideo) { if (_streamed) { @@ -1304,6 +1296,7 @@ void OverlayWidget::onHideControls(bool force) { || (_streamed && _streamed->controls.hasMenu()) || _menu || _mousePressed + || (_over != OverNone && _over != OverVideo) || (_fullScreenVideo && !videoIsGifOrUserpic() && _streamed->controls.geometry().contains(_lastMouseMovePos))) { @@ -1313,11 +1306,7 @@ void OverlayWidget::onHideControls(bool force) { if (_fullScreenVideo) { _streamed->controls.hideAnimated(); } - if (_controlsState == ControlsHiding - || _controlsState == ControlsHidden - || _controlsState == ControlsDisabled) { - return; - } + if (_controlsState == ControlsHiding || _controlsState == ControlsHidden) return; _lastMouseMovePos = mapFromGlobal(QCursor::pos()); _controlsState = ControlsHiding; @@ -3631,8 +3620,6 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) { playbackPauseResume(); } else if (_document && !_document->loading() && (documentBubbleShown() || !_documentMedia->loaded())) { onDocClick(); - } else { - zoomReset(); } } else if (e->key() == Qt::Key_Left) { if (_controlsHideTimer.isActive()) { @@ -3644,22 +3631,16 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) { activateControls(); } moveToNext(1); - } else if (ctrl) { + } else if (ctrl || !_streamed) { if (e->key() == Qt::Key_Plus || e->key() == Qt::Key_Equal || e->key() == Qt::Key_Asterisk || e->key() == ']') { zoomIn(); - } else if (e->key() == Qt::Key_Minus || e->key() == Qt::Key_Underscore) { + } else if (e->key() == Qt::Key_Minus || e->key() == Qt::Key_Underscore || e->key() == '[') { zoomOut(); } else if (e->key() == Qt::Key_0) { zoomReset(); } else if (e->key() == Qt::Key_I) { update(); } - } else if (e->key() == Qt::Key_Plus) { - zoomIn(); - } else if (e->key() == Qt::Key_Minus) { - zoomOut(); - } else if (e->key() == Qt::Key_Asterisk) { - zoomReset(); } } @@ -3702,22 +3683,6 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) { if (!force && _zoom == newZoom) { return; } - if (!_fullScreenVideo) { - if ((_initialZoom == 0 && newZoom > 0) - || (_initialZoom != 0 && newZoom >= 0 && newZoom != _initialZoom)) { - if (_controlsState != ControlsDisabled) { - activateControls(); - onHideControls(true); - updateControlsAnimation(_controlsAnimStarted + st::mediaviewHideDuration); - _controlsState = ControlsDisabled; - updateCursor(); - } - } else if (_controlsState == ControlsDisabled) { - _controlsState = ControlsHidden; - activateControls(); - updateCursor(); - } - } const auto full = _fullScreenVideo ? _zoomToScreen : _zoomToDefault; float64 nx, ny, z = (_zoom == kZoomToScreenLevel) ? full : _zoom; @@ -3746,6 +3711,12 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) { _x = qRound(nx / (-z + 1) + width() / 2.); _y = qRound(ny / (-z + 1) + height() / 2.); } + if(isZoomedIn()){ + if(_controlsState == ControlsHiding){ + _controlsState = ControlsShown; + } + onHideControls(); + } snapXY(); update(); } @@ -4071,15 +4042,6 @@ void OverlayWidget::updateOverRect(OverState state) { bool OverlayWidget::updateOverState(OverState newState) { bool result = true; - if (_controlsState == ControlsDisabled - && newState != OverLeftNav - && newState != OverRightNav - && newState != OverClose - && newState != OverVideo) { - _over = OverNone; - updateCursor(); - return false; - } if (_over != newState) { if (newState == OverMore && !_ignoringDropdown) { _dropdownShowTimer.callOnce(0); @@ -4114,6 +4076,7 @@ bool OverlayWidget::updateOverState(OverState newState) { if (!_stateAnimation.animating()) { _stateAnimation.start(); } + activateControls(); } updateCursor(); } @@ -4250,7 +4213,7 @@ void OverlayWidget::mouseReleaseEvent(QMouseEvent *e) { _pressed = false; } _down = OverNone; - if (!isHidden()) { + if (isHidden() && _controlsState == ControlsHidden) { activateControls(); } } @@ -4570,5 +4533,10 @@ float64 OverlayWidget::overLevel(OverState control) const { : i->second.current(); } +bool OverlayWidget::isZoomedIn() { + return ((_initialZoom == 0 && _zoom > 0) + || (_initialZoom != 0 && _zoom >= 0 && _zoom != _initialZoom)); +} + } // namespace View } // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 0d0ed13585e69..5ce8da01216f0 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -361,6 +361,7 @@ private Q_SLOTS: void updateOverRect(OverState state); bool updateOverState(OverState newState); float64 overLevel(OverState control) const; + bool isZoomedIn(); void checkGroupThumbsAnimation(); void initGroupThumbs(); @@ -499,7 +500,6 @@ private Q_SLOTS: ControlsShown, ControlsHiding, ControlsHidden, - ControlsDisabled }; ControlsState _controlsState = ControlsShown; crl::time _controlsAnimStarted = 0; From 3318812d06f5e092adf446b7a910742bc64ebbc1 Mon Sep 17 00:00:00 2001 From: Kly_Men_COmpany Date: Tue, 11 May 2021 18:34:30 +0500 Subject: [PATCH 4/7] Fix indentation --- Telegram/SourceFiles/media/view/media_view_overlay_widget.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 5ce8da01216f0..22192bac04908 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -361,7 +361,7 @@ private Q_SLOTS: void updateOverRect(OverState state); bool updateOverState(OverState newState); float64 overLevel(OverState control) const; - bool isZoomedIn(); + bool isZoomedIn(); void checkGroupThumbsAnimation(); void initGroupThumbs(); From e8ef9832b7325f8604794eccff3e3c51e861d4ee Mon Sep 17 00:00:00 2001 From: Kly_Men_COmpany Date: Tue, 11 May 2021 18:39:27 +0500 Subject: [PATCH 5/7] Fix wrong thing --- Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 4c8fb5bb40927..1e68638aad4e3 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -4213,7 +4213,7 @@ void OverlayWidget::mouseReleaseEvent(QMouseEvent *e) { _pressed = false; } _down = OverNone; - if (isHidden() && _controlsState == ControlsHidden) { + if (!isHidden() || (isZoomedIn() && _controlsState == ControlsHidden)) { activateControls(); } } From c768790b579397a9b1f6d2f0e9a9abeab8d75b4b Mon Sep 17 00:00:00 2001 From: Kly_Men_COmpany Date: Tue, 11 May 2021 22:14:35 +0500 Subject: [PATCH 6/7] Fix spacing Co-authored-by: 23rd <23rd@vivaldi.net> --- Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 1e68638aad4e3..5021bc0a76542 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -3711,8 +3711,8 @@ void OverlayWidget::setZoomLevel(int newZoom, bool force) { _x = qRound(nx / (-z + 1) + width() / 2.); _y = qRound(ny / (-z + 1) + height() / 2.); } - if(isZoomedIn()){ - if(_controlsState == ControlsHiding){ + if (isZoomedIn()) { + if (_controlsState == ControlsHiding) { _controlsState = ControlsShown; } onHideControls(); From 2740a3f0a95e3e890e6c7c6ec68650be6b054f52 Mon Sep 17 00:00:00 2001 From: aleksusklim Date: Thu, 13 May 2021 18:03:07 +0500 Subject: [PATCH 7/7] Make cursor always visible when image was zoomed. Also hide menu button in the right-down corner if so. --- .../SourceFiles/media/view/media_view_overlay_widget.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 5021bc0a76542..9dda31de55339 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -964,7 +964,7 @@ void OverlayWidget::waitingAnimationCallback() { } void OverlayWidget::updateCursor() { - setCursor(_controlsState == ControlsHidden + setCursor(_controlsState == ControlsHidden && !isZoomedIn() ? Qt::BlankCursor : (_over == OverNone ? style::cur_default : style::cur_pointer)); } @@ -3291,7 +3291,7 @@ void OverlayWidget::paintEvent(QPaintEvent *e) { } // more area - if (_moreNavIcon.intersects(r)) { + if (_moreNavIcon.intersects(r) && !isZoomedIn()) { auto o = overLevel(OverMore); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co); st::mediaviewMore.paintInCenter(p, _moreNavIcon); @@ -4131,7 +4131,7 @@ void OverlayWidget::updateOver(QPoint pos) { updateOverState(OverRotate); } else if (_document && documentBubbleShown() && _docIconRect.contains(pos)) { updateOverState(OverIcon); - } else if (_moreNav.contains(pos)) { + } else if (_moreNav.contains(pos) && !isZoomedIn()) { updateOverState(OverMore); } else if (_closeNav.contains(pos)) { updateOverState(OverClose);