viewer: implemented basic zoom
No scrolling functionality yet, but the zoom is functional and efficient.
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
#include "viewersizer.h"
|
||||
|
||||
#include <QMatrix4x4>
|
||||
|
||||
ViewerSizer::ViewerSizer(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
widget_(nullptr),
|
||||
aspect_ratio_(0)
|
||||
aspect_ratio_(0),
|
||||
zoom_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,15 +26,25 @@ void ViewerSizer::SetWidget(QWidget *widget)
|
||||
|
||||
void ViewerSizer::SetChildSize(int width, int height)
|
||||
{
|
||||
if (height == 0) {
|
||||
width_ = width;
|
||||
height_ = height;
|
||||
|
||||
if (!width_ || !height_) {
|
||||
aspect_ratio_ = 0;
|
||||
} else {
|
||||
aspect_ratio_ = static_cast<double>(width) / static_cast<double>(height);
|
||||
aspect_ratio_ = static_cast<double>(width_) / static_cast<double>(height_);
|
||||
}
|
||||
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void ViewerSizer::SetZoom(int percent)
|
||||
{
|
||||
zoom_ = percent;
|
||||
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void ViewerSizer::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
@@ -53,21 +66,51 @@ void ViewerSizer::UpdateSize()
|
||||
|
||||
widget_->setVisible(true);
|
||||
|
||||
double our_aspect_ratio = static_cast<double>(width()) / static_cast<double>(height());
|
||||
QSize child_size;
|
||||
QMatrix4x4 child_matrix;
|
||||
|
||||
QPoint child_pos;
|
||||
QSize child_size = size();
|
||||
if (zoom_ <= 0) {
|
||||
|
||||
// If zoom is 0, we auto-fit
|
||||
double our_aspect_ratio = static_cast<double>(width()) / static_cast<double>(height());
|
||||
|
||||
child_size = size();
|
||||
|
||||
if (our_aspect_ratio > aspect_ratio_) {
|
||||
// This container is wider than the image, scale by height
|
||||
child_size = QSize(qRound(child_size.height() * aspect_ratio_), height());
|
||||
} else {
|
||||
// This container is taller than the image, scale by width
|
||||
child_size = QSize(width(), qRound(child_size.width() / aspect_ratio_));
|
||||
}
|
||||
|
||||
if (our_aspect_ratio > aspect_ratio_) {
|
||||
// This container is wider than the image, scale by height
|
||||
child_size.setWidth(qRound(child_size.height() * aspect_ratio_));
|
||||
child_pos.setX(width() / 2 - child_size.width() / 2);
|
||||
} else {
|
||||
// This container is taller than the image, scale by width
|
||||
child_size.setHeight(qRound(child_size.width() / aspect_ratio_));
|
||||
child_pos.setY(height() / 2 - child_size.height() / 2);
|
||||
|
||||
float x_scale = 1.0f;
|
||||
float y_scale = 1.0f;
|
||||
|
||||
int zoomed_width = qRound(width_ * static_cast<double>(zoom_) * 0.01);
|
||||
int zoomed_height = qRound(height_ * static_cast<double>(zoom_) * 0.01);
|
||||
|
||||
if (zoomed_width > width()) {
|
||||
x_scale = static_cast<double>(zoomed_width) / static_cast<double>(width());
|
||||
zoomed_width = width();
|
||||
}
|
||||
|
||||
if (zoomed_height > height()) {
|
||||
y_scale = static_cast<double>(zoomed_height) / static_cast<double>(height());
|
||||
zoomed_height = height();
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
widget_->resize(child_size);
|
||||
widget_->move(child_pos);
|
||||
widget_->move(width() / 2 - child_size.width() / 2, height() / 2 - child_size.height() / 2);
|
||||
|
||||
emit RequestMatrix(child_matrix);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user