viewersizer: use float for all calculations, center manual zoom
This commit is contained in:
@@ -1376,10 +1376,10 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
Menu* zoom_menu = new Menu(tr("Zoom"), &menu);
|
||||
menu.addMenu(zoom_menu);
|
||||
|
||||
zoom_menu->addAction(tr("Fit"))->setData(0);
|
||||
zoom_menu->addAction(tr("Fit"))->setData(-1);
|
||||
for (int i=0;i<ViewerSizer::kZoomLevelCount;i++) {
|
||||
int z = ViewerSizer::kZoomLevels[i];
|
||||
zoom_menu->addAction(tr("%1%").arg(z))->setData(z);
|
||||
double z = ViewerSizer::kZoomLevels[i];
|
||||
zoom_menu->addAction(tr("%1%").arg(z * 100.0))->setData(z);
|
||||
}
|
||||
|
||||
connect(zoom_menu, &QMenu::triggered, this, &ViewerWidget::SetZoomFromMenu);
|
||||
@@ -1822,7 +1822,8 @@ void ViewerWidget::UpdateRendererAudioParameters()
|
||||
|
||||
void ViewerWidget::SetZoomFromMenu(QAction *action)
|
||||
{
|
||||
sizer_->SetZoom(action->data().toInt());
|
||||
auto s = sizer_->GetContainerSize();
|
||||
sizer_->SetZoomAnchored(action->data().toDouble(), s.width()/2, s.height()/2);
|
||||
}
|
||||
|
||||
void ViewerWidget::ViewerInvalidatedVideoRange(const TimeRange &range)
|
||||
|
||||
@@ -35,7 +35,7 @@ ViewerSizer::ViewerSizer(QWidget *parent) :
|
||||
width_(0),
|
||||
height_(0),
|
||||
pixel_aspect_(1),
|
||||
zoom_(0),
|
||||
zoom_(-1),
|
||||
current_widget_scale_(0)
|
||||
{
|
||||
horiz_scrollbar_ = new QScrollBar(Qt::Horizontal, this);
|
||||
@@ -64,6 +64,12 @@ void ViewerSizer::SetWidget(QWidget *widget)
|
||||
}
|
||||
}
|
||||
|
||||
QSize ViewerSizer::GetContainerSize() const
|
||||
{
|
||||
double s = GetRealCurrentZoom();
|
||||
return QSize(std::min(this->width(), int(width_ * s)) - vert_scrollbar_->width(), std::min(int(height_ * s), this->height()) - horiz_scrollbar_->height());
|
||||
}
|
||||
|
||||
void ViewerSizer::SetChildSize(int width, int height)
|
||||
{
|
||||
width_ = width;
|
||||
@@ -79,13 +85,36 @@ void ViewerSizer::SetPixelAspectRatio(const rational &pixel_aspect)
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void ViewerSizer::SetZoom(int percent)
|
||||
void ViewerSizer::SetZoom(double percent)
|
||||
{
|
||||
zoom_ = percent;
|
||||
|
||||
UpdateSize();
|
||||
}
|
||||
|
||||
void ViewerSizer::SetZoomAnchored(double next_scale, double cursor_x, double cursor_y)
|
||||
{
|
||||
if (next_scale > 0) {
|
||||
double cur_scale = GetRealCurrentZoom();
|
||||
|
||||
// Clamp scale within safe values
|
||||
next_scale = std::clamp(next_scale, kZoomLevels[0], kZoomLevels[kZoomLevelCount-1]);
|
||||
|
||||
int anchor_x = qRound(double(cursor_x + horiz_scrollbar_->value()) / cur_scale * next_scale - cursor_x);
|
||||
int anchor_y = qRound(double(cursor_y + vert_scrollbar_->value()) / cur_scale * next_scale - cursor_y);
|
||||
|
||||
SetZoom(next_scale);
|
||||
|
||||
horiz_scrollbar_->setValue(anchor_x);
|
||||
vert_scrollbar_->setValue(anchor_y);
|
||||
} else {
|
||||
SetZoom(-1);
|
||||
|
||||
horiz_scrollbar_->setValue(0);
|
||||
vert_scrollbar_->setValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerSizer::HandDragMove(int x, int y)
|
||||
{
|
||||
if (horiz_scrollbar_->isVisible()) {
|
||||
@@ -104,28 +133,9 @@ bool ViewerSizer::eventFilter(QObject *watched, QEvent *event)
|
||||
QWheelEvent *w = static_cast<QWheelEvent*>(event);
|
||||
|
||||
if (HandMovableView::WheelEventIsAZoomEvent(w)) {
|
||||
int current_percent = zoom_;
|
||||
if (current_percent == 0) {
|
||||
// Currently set to "fit"
|
||||
current_percent = current_widget_scale_;
|
||||
}
|
||||
|
||||
double cur_scale = current_percent * 0.01;
|
||||
|
||||
current_percent *= HandMovableView::GetScrollZoomMultiplier(w);
|
||||
current_percent = std::clamp(current_percent, kZoomLevels[0], kZoomLevels[kZoomLevelCount-1]);
|
||||
|
||||
double next_scale = current_percent * 0.01;
|
||||
|
||||
double next_scale = GetRealCurrentZoom() * HandMovableView::GetScrollZoomMultiplier(w);
|
||||
QPointF cursor_pos = w->position();
|
||||
|
||||
int anchor_x = qRound(double(cursor_pos.x() + horiz_scrollbar_->value()) / cur_scale * next_scale - cursor_pos.x());
|
||||
int anchor_y = qRound(double(cursor_pos.y() + vert_scrollbar_->value()) / cur_scale * next_scale - cursor_pos.y());
|
||||
|
||||
SetZoom(current_percent);
|
||||
|
||||
horiz_scrollbar_->setValue(anchor_x);
|
||||
vert_scrollbar_->setValue(anchor_y);
|
||||
SetZoomAnchored(next_scale, cursor_pos.x(), cursor_pos.y());
|
||||
} else {
|
||||
// Pass scroll values to scrollbars
|
||||
QPoint p = w->pixelDelta();
|
||||
@@ -218,12 +228,12 @@ void ViewerSizer::UpdateSize()
|
||||
|
||||
}
|
||||
|
||||
current_widget_scale_ = current_scale * 100;
|
||||
current_widget_scale_ = current_scale;
|
||||
|
||||
if (zoom_ > 0) {
|
||||
|
||||
// Scale to get to the requested zoom
|
||||
double zoom_diff = (zoom_ * 0.01) / current_scale;
|
||||
double zoom_diff = zoom_ / current_scale;
|
||||
child_matrix.scale(zoom_diff, zoom_diff, 1.0);
|
||||
|
||||
}
|
||||
@@ -235,7 +245,18 @@ void ViewerSizer::UpdateSize()
|
||||
|
||||
int ViewerSizer::GetZoomedValue(int value)
|
||||
{
|
||||
return qRound(value * static_cast<double>(zoom_) * 0.01);
|
||||
return qRound(value * zoom_);
|
||||
}
|
||||
|
||||
double ViewerSizer::GetRealCurrentZoom() const
|
||||
{
|
||||
if (zoom_ < 0) {
|
||||
// Currently set to "fit"
|
||||
return current_widget_scale_;
|
||||
} else {
|
||||
// Explicit zoom set
|
||||
return zoom_;
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerSizer::ScrollBarMoved()
|
||||
|
||||
@@ -51,8 +51,10 @@ public:
|
||||
*/
|
||||
void SetWidget(QWidget* widget);
|
||||
|
||||
static constexpr int kZoomLevelCount = 8;
|
||||
static constexpr int kZoomLevels[kZoomLevelCount] = {10, 25, 50, 75, 100, 150, 200, 400};
|
||||
QSize GetContainerSize() const;
|
||||
|
||||
static constexpr int kZoomLevelCount = 10;
|
||||
static constexpr double kZoomLevels[kZoomLevelCount] = {0.05, 0.1, 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 4.0, 8.0};
|
||||
|
||||
public slots:
|
||||
/**
|
||||
@@ -72,7 +74,8 @@ public slots:
|
||||
*
|
||||
* The number is an integer percentage (100 = 100%). Set to 0 to auto-fit.
|
||||
*/
|
||||
void SetZoom(int percent);
|
||||
void SetZoom(double percent);
|
||||
void SetZoomAnchored(double percent, double cursor_x, double cursor_y);
|
||||
|
||||
void HandDragMove(int x, int y);
|
||||
|
||||
@@ -97,6 +100,8 @@ private:
|
||||
|
||||
int GetZoomedValue(int value);
|
||||
|
||||
double GetRealCurrentZoom() const;
|
||||
|
||||
/**
|
||||
* @brief Reference to widget
|
||||
*
|
||||
@@ -115,8 +120,8 @@ private:
|
||||
/**
|
||||
* @brief Internal zoom value
|
||||
*/
|
||||
int zoom_;
|
||||
int current_widget_scale_;
|
||||
double zoom_;
|
||||
double current_widget_scale_;
|
||||
|
||||
QScrollBar* horiz_scrollbar_;
|
||||
QScrollBar* vert_scrollbar_;
|
||||
|
||||
Reference in New Issue
Block a user