/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "viewersizer.h" #include OLIVE_NAMESPACE_ENTER ViewerSizer::ViewerSizer(QWidget *parent) : QWidget(parent), widget_(nullptr), width_(0), height_(0), pixel_aspect_(1), zoom_(0) { } void ViewerSizer::SetWidget(QWidget *widget) { // Delete any previous widgets occupying this space delete widget_; widget_ = widget; if (widget_ != nullptr) { widget_->setParent(this); UpdateSize(); } } void ViewerSizer::SetChildSize(int width, int height) { width_ = width; height_ = height; UpdateSize(); } void ViewerSizer::SetPixelAspectRatio(const rational &pixel_aspect) { pixel_aspect_ = pixel_aspect; UpdateSize(); } void ViewerSizer::SetZoom(int percent) { zoom_ = percent; UpdateSize(); } void ViewerSizer::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); UpdateSize(); } void ViewerSizer::UpdateSize() { if (widget_ == nullptr) { return; } // If the aspect ratio is 0, the widget is always hidden if (!width_ || !height_) { widget_->setVisible(false); return; } widget_->setVisible(true); QSize child_size; QMatrix4x4 child_matrix; double sequence_aspect_ratio = static_cast(width_) / static_cast(height_) * pixel_aspect_.toDouble(); if (zoom_ <= 0) { // If zoom is 0, we auto-fit double our_aspect_ratio = static_cast(width()) / static_cast(height()); child_size = size(); if (our_aspect_ratio > sequence_aspect_ratio) { // This container is wider than the image, scale by height child_size = QSize(qRound(child_size.height() * sequence_aspect_ratio), height()); } else { // This container is taller than the image, scale by width child_size = QSize(width(), qRound(child_size.width() / sequence_aspect_ratio)); } } else { float x_scale = 1.0f; float y_scale = 1.0f; int zoomed_width = qRound(width_ * static_cast(zoom_) * 0.01); int zoomed_height = qRound(height_ * static_cast(zoom_) * 0.01); if (zoomed_width > width()) { x_scale = static_cast(zoomed_width) / static_cast(width()); zoomed_width = width(); } if (zoomed_height > height()) { y_scale = static_cast(zoomed_height) / static_cast(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(width() / 2 - child_size.width() / 2, height() / 2 - child_size.height() / 2); emit RequestMatrix(child_matrix); } OLIVE_NAMESPACE_EXIT