diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index a90c7242d..aa1fe9a07 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -79,7 +79,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) : connect(display_widget_, &ViewerDisplayWidget::ColorProcessorChanged, this, &ViewerWidget::ColorProcessorChanged); connect(display_widget_, &ViewerDisplayWidget::ColorManagerChanged, this, &ViewerWidget::ColorManagerChanged); connect(sizer_, &ViewerSizer::RequestMatrix, display_widget_, &ViewerDisplayWidget::SetMatrixZoom); - connect(sizer_, &ViewerSizer::SetZoomFlag, display_widget_, &ViewerDisplayWidget::SetZoomFlag); + connect(sizer_, &ViewerSizer::SendZoomData, display_widget_, &ViewerDisplayWidget::SetZoomData); sizer_->SetWidget(display_widget_); // Create waveform view when audio is connected and video isn't diff --git a/app/widget/viewer/viewerdisplay.cpp b/app/widget/viewer/viewerdisplay.cpp index 1228530de..f55299ff2 100644 --- a/app/widget/viewer/viewerdisplay.cpp +++ b/app/widget/viewer/viewerdisplay.cpp @@ -48,7 +48,8 @@ ViewerDisplayWidget::ViewerDisplayWidget(QWidget *parent) : gizmos_(nullptr), gizmo_click_(false), last_loaded_buffer_(nullptr), - zoomed_(false) + zoomed_(false), + zoom_multiplier_(1.0) { } @@ -69,13 +70,17 @@ void ViewerDisplayWidget::SetMatrixZoom(const QMatrix4x4 &mat) update(); } -void ViewerDisplayWidget::SetZoomFlag(bool flag) +void ViewerDisplayWidget::SetZoomData(bool flag, int percent) { zoomed_ = flag; - // If not scaled reset translation matrix to identity + // If the image is smaller than the conainer widget we disable translation if (!flag) { QMatrix4x4 mat; SetMatrixTranslate(mat); + zoom_multiplier_ = 1.0f; + } + else { + zoom_multiplier_ = 1.0 / (static_cast(percent) * 0.01); } } @@ -174,7 +179,7 @@ void ViewerDisplayWidget::mousePressEvent(QMouseEvent *event) SetMatrixTranslate(mat); } - // get current position in preperation for move event + // If translation is enabled get current position in preperation for move event if (event->button() == Qt::MiddleButton && zoomed_) { position_ = event->pos(); return; @@ -189,11 +194,12 @@ void ViewerDisplayWidget::mousePressEvent(QMouseEvent *event) void ViewerDisplayWidget::mouseMoveEvent(QMouseEvent *event) { + // Only allow translation if the image is larger than the container widget if (event->buttons() & Qt::MiddleButton && zoomed_) { QPointF delta = event->pos() - position_; - // scale delta to widget size - delta.setX(delta.x() / width()); - delta.setY(delta.y() / height()); + // scale delta to widget size and zoom level + delta.setX(zoom_multiplier_ * delta.x() / width()); + delta.setY(zoom_multiplier_ * delta.y() / height()); QMatrix4x4 mat; mat = GetMatrixTranslate(); diff --git a/app/widget/viewer/viewerdisplay.h b/app/widget/viewer/viewerdisplay.h index 4d98af1ce..f6c10a92f 100644 --- a/app/widget/viewer/viewerdisplay.h +++ b/app/widget/viewer/viewerdisplay.h @@ -116,7 +116,7 @@ public slots: */ void SetImage(FramePtr in_buffer); - void SetZoomFlag(bool flag); + void SetZoomData(bool flag, int percent); signals: /** @@ -181,8 +181,6 @@ private: */ QMatrix4x4 scale_matrix_; - bool zoomed_; - #ifdef Q_OS_LINUX static bool nouveau_check_done_; #endif @@ -201,6 +199,16 @@ private: FramePtr last_loaded_buffer_; + /** + * @brief Tells us if the image is zoomed in to be larger than the container widget. + */ + bool zoomed_; + + /** + * @brief Scale the translation so the image sticks to the mouse and we get sensible movement + */ + double zoom_multiplier_; + /** * @brief position of mouse to calculate delta from. */ diff --git a/app/widget/viewer/viewersizer.cpp b/app/widget/viewer/viewersizer.cpp index 0780f3c58..7cab8239f 100644 --- a/app/widget/viewer/viewersizer.cpp +++ b/app/widget/viewer/viewersizer.cpp @@ -105,12 +105,15 @@ void ViewerSizer::UpdateSize() // This container is taller than the image, scale by width child_size = QSize(width(), qRound(child_size.width() / aspect_ratio_)); } - emit SetZoomFlag(false); + emit SendZoomData(false, 0); } else { float x_scale = 1.0f; float y_scale = 1.0f; + // Translation is only active if the image is bigger then the widget + // See ViewerDisplayWidget::SetZoomData + bool zoomed_in = false; int zoomed_width = qRound(width_ * static_cast(zoom_) * 0.01); int zoomed_height = qRound(height_ * static_cast(zoom_) * 0.01); @@ -118,18 +121,20 @@ void ViewerSizer::UpdateSize() if (zoomed_width > width()) { x_scale = static_cast(zoomed_width) / static_cast(width()); zoomed_width = width(); + zoomed_in = true; } if (zoomed_height > height()) { y_scale = static_cast(zoomed_height) / static_cast(height()); zoomed_height = height(); + zoomed_in = true; } // Rather than make a huge surface, we still crop at our width/height and then signal a matrix child_matrix.scale(x_scale, y_scale, 1.0F); child_size = QSize(zoomed_width, zoomed_height); - emit SetZoomFlag(true); + emit SendZoomData(zoomed_in, zoom_); } widget_->resize(child_size); diff --git a/app/widget/viewer/viewersizer.h b/app/widget/viewer/viewersizer.h index 6728018a6..9c838a834 100644 --- a/app/widget/viewer/viewersizer.h +++ b/app/widget/viewer/viewersizer.h @@ -65,7 +65,7 @@ public: signals: void RequestMatrix(const QMatrix4x4& matrix); - void SetZoomFlag(bool flag); + void SendZoomData(bool flag, int percent); protected: /**