viewer: implemented basic zoom
No scrolling functionality yet, but the zoom is functional and efficient.
This commit is contained in:
@@ -57,11 +57,11 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
|||||||
|
|
||||||
gl_widget_ = new ViewerGLWidget();
|
gl_widget_ = new ViewerGLWidget();
|
||||||
connect(gl_widget_, &ViewerGLWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
connect(gl_widget_, &ViewerGLWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||||
|
connect(sizer_, &ViewerSizer::RequestMatrix, gl_widget_, &ViewerGLWidget::SetMatrix);
|
||||||
sizer_->SetWidget(gl_widget_);
|
sizer_->SetWidget(gl_widget_);
|
||||||
|
|
||||||
// Create waveform view when audio is connected and video isn't
|
// Create waveform view when audio is connected and video isn't
|
||||||
waveform_view_ = new WaveformView();
|
waveform_view_ = new WaveformView();
|
||||||
|
|
||||||
stack_->addWidget(waveform_view_);
|
stack_->addWidget(waveform_view_);
|
||||||
|
|
||||||
// Create time ruler
|
// Create time ruler
|
||||||
@@ -272,7 +272,7 @@ void ViewerWidget::PlayInternal(int speed)
|
|||||||
|
|
||||||
controls_->ShowPauseButton();
|
controls_->ShowPauseButton();
|
||||||
|
|
||||||
if (stack_->currentWidget() == gl_widget_) {
|
if (stack_->currentWidget() == sizer_) {
|
||||||
connect(gl_widget_, &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
connect(gl_widget_, &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||||
} else {
|
} else {
|
||||||
connect(AudioManager::instance(), &AudioManager::OutputNotified, this, &ViewerWidget::PlaybackTimerUpdate);
|
connect(AudioManager::instance(), &AudioManager::OutputNotified, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||||
@@ -315,7 +315,7 @@ int ViewerWidget::CalculateDivider()
|
|||||||
void ViewerWidget::UpdateStack()
|
void ViewerWidget::UpdateStack()
|
||||||
{
|
{
|
||||||
if (!GetConnectedNode() || GetConnectedNode()->texture_input()->IsConnected()) {
|
if (!GetConnectedNode() || GetConnectedNode()->texture_input()->IsConnected()) {
|
||||||
stack_->setCurrentWidget(gl_widget_);
|
stack_->setCurrentWidget(sizer_);
|
||||||
} else {
|
} else {
|
||||||
stack_->setCurrentWidget(waveform_view_);
|
stack_->setCurrentWidget(waveform_view_);
|
||||||
}
|
}
|
||||||
@@ -393,12 +393,21 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
|||||||
// Playback resolution
|
// Playback resolution
|
||||||
QMenu* playback_resolution_menu = menu.addMenu(tr("Resolution"));
|
QMenu* playback_resolution_menu = menu.addMenu(tr("Resolution"));
|
||||||
playback_resolution_menu->addAction(tr("Full"))->setData(1);
|
playback_resolution_menu->addAction(tr("Full"))->setData(1);
|
||||||
playback_resolution_menu->addAction(tr("1/2"))->setData(2);
|
int dividers[] = {2, 4, 8, 16};
|
||||||
playback_resolution_menu->addAction(tr("1/4"))->setData(4);
|
for (int i=0;i<4;i++) {
|
||||||
playback_resolution_menu->addAction(tr("1/8"))->setData(8);
|
playback_resolution_menu->addAction(tr("1/%1").arg(dividers[i]))->setData(dividers[i]);
|
||||||
playback_resolution_menu->addAction(tr("1/16"))->setData(16);
|
}
|
||||||
connect(playback_resolution_menu, &QMenu::triggered, this, &ViewerWidget::SetDividerFromMenu);
|
connect(playback_resolution_menu, &QMenu::triggered, this, &ViewerWidget::SetDividerFromMenu);
|
||||||
|
|
||||||
|
// Viewer Zoom Level
|
||||||
|
QMenu* zoom_menu = menu.addMenu(tr("Zoom"));
|
||||||
|
int zoom_levels[] = {10, 25, 50, 75, 100, 150, 200, 400};
|
||||||
|
zoom_menu->addAction(tr("Fit"))->setData(0);
|
||||||
|
for (int i=0;i<8;i++) {
|
||||||
|
zoom_menu->addAction(tr("%1%").arg(zoom_levels[i]))->setData(zoom_levels[i]);
|
||||||
|
}
|
||||||
|
connect(zoom_menu, &QMenu::triggered, this, &ViewerWidget::SetZoomFromMenu);
|
||||||
|
|
||||||
foreach (QAction* a, playback_resolution_menu->actions()) {
|
foreach (QAction* a, playback_resolution_menu->actions()) {
|
||||||
a->setCheckable(true);
|
a->setCheckable(true);
|
||||||
if (a->data() == divider_) {
|
if (a->data() == divider_) {
|
||||||
@@ -564,6 +573,11 @@ void ViewerWidget::SetDividerFromMenu(QAction *action)
|
|||||||
UpdateRendererParameters();
|
UpdateRendererParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewerWidget::SetZoomFromMenu(QAction *action)
|
||||||
|
{
|
||||||
|
sizer_->SetZoom(action->data().toInt());
|
||||||
|
}
|
||||||
|
|
||||||
void ViewerWidget::InvalidateVisible()
|
void ViewerWidget::InvalidateVisible()
|
||||||
{
|
{
|
||||||
video_renderer_->InvalidateCache(TimeRange(GetTime(), GetTime()));
|
video_renderer_->InvalidateCache(TimeRange(GetTime(), GetTime()));
|
||||||
|
|||||||
@@ -187,6 +187,8 @@ private slots:
|
|||||||
|
|
||||||
void SetDividerFromMenu(QAction* action);
|
void SetDividerFromMenu(QAction* action);
|
||||||
|
|
||||||
|
void SetZoomFromMenu(QAction* action);
|
||||||
|
|
||||||
void InvalidateVisible();
|
void InvalidateVisible();
|
||||||
|
|
||||||
void UpdateStack();
|
void UpdateStack();
|
||||||
|
|||||||
@@ -68,18 +68,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
void DisconnectColorManager();
|
void DisconnectColorManager();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Set the transformation matrix to draw with
|
|
||||||
*
|
|
||||||
* Set this if you want the drawing to pass through some sort of transform (most of the time you won't want this).
|
|
||||||
*/
|
|
||||||
void SetMatrix(const QMatrix4x4& mat);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set an image to load and display on screen
|
* @brief Set an image to load and display on screen
|
||||||
*/
|
*/
|
||||||
void SetImage(const QString& fn);
|
void SetImage(const QString& fn);
|
||||||
|
|
||||||
|
ColorManager* color_manager() const;
|
||||||
|
|
||||||
|
const QString& ocio_display() const;
|
||||||
|
const QString& ocio_view() const;
|
||||||
|
const QString& ocio_look() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/**
|
/**
|
||||||
* @brief Set the texture to draw and draw it
|
* @brief Set the texture to draw and draw it
|
||||||
@@ -113,11 +112,12 @@ public slots:
|
|||||||
*/
|
*/
|
||||||
void SetOCIOLook(const QString& look);
|
void SetOCIOLook(const QString& look);
|
||||||
|
|
||||||
ColorManager* color_manager() const;
|
/**
|
||||||
|
* @brief Set the transformation matrix to draw with
|
||||||
const QString& ocio_display() const;
|
*
|
||||||
const QString& ocio_view() const;
|
* Set this if you want the drawing to pass through some sort of transform (most of the time you won't want this).
|
||||||
const QString& ocio_look() const;
|
*/
|
||||||
|
void SetMatrix(const QMatrix4x4& mat);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void DragStarted();
|
void DragStarted();
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "viewersizer.h"
|
#include "viewersizer.h"
|
||||||
|
|
||||||
|
#include <QMatrix4x4>
|
||||||
|
|
||||||
ViewerSizer::ViewerSizer(QWidget *parent) :
|
ViewerSizer::ViewerSizer(QWidget *parent) :
|
||||||
QWidget(parent),
|
QWidget(parent),
|
||||||
widget_(nullptr),
|
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)
|
void ViewerSizer::SetChildSize(int width, int height)
|
||||||
{
|
{
|
||||||
if (height == 0) {
|
width_ = width;
|
||||||
|
height_ = height;
|
||||||
|
|
||||||
|
if (!width_ || !height_) {
|
||||||
aspect_ratio_ = 0;
|
aspect_ratio_ = 0;
|
||||||
} else {
|
} else {
|
||||||
aspect_ratio_ = static_cast<double>(width) / static_cast<double>(height);
|
aspect_ratio_ = static_cast<double>(width_) / static_cast<double>(height_);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateSize();
|
UpdateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViewerSizer::SetZoom(int percent)
|
||||||
|
{
|
||||||
|
zoom_ = percent;
|
||||||
|
|
||||||
|
UpdateSize();
|
||||||
|
}
|
||||||
|
|
||||||
void ViewerSizer::resizeEvent(QResizeEvent *event)
|
void ViewerSizer::resizeEvent(QResizeEvent *event)
|
||||||
{
|
{
|
||||||
QWidget::resizeEvent(event);
|
QWidget::resizeEvent(event);
|
||||||
@@ -53,21 +66,51 @@ void ViewerSizer::UpdateSize()
|
|||||||
|
|
||||||
widget_->setVisible(true);
|
widget_->setVisible(true);
|
||||||
|
|
||||||
double our_aspect_ratio = static_cast<double>(width()) / static_cast<double>(height());
|
QSize child_size;
|
||||||
|
QMatrix4x4 child_matrix;
|
||||||
|
|
||||||
QPoint child_pos;
|
if (zoom_ <= 0) {
|
||||||
QSize child_size = size();
|
|
||||||
|
// 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 {
|
} else {
|
||||||
// This container is taller than the image, scale by width
|
|
||||||
child_size.setHeight(qRound(child_size.width() / aspect_ratio_));
|
float x_scale = 1.0f;
|
||||||
child_pos.setY(height() / 2 - child_size.height() / 2);
|
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_->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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetChildSize(int width, int height);
|
void SetChildSize(int width, int height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the zoom value of the child widget
|
||||||
|
*
|
||||||
|
* The number is an integer percentage (100 = 100%). Set to 0 to auto-fit.
|
||||||
|
*/
|
||||||
|
void SetZoom(int percent);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void RequestMatrix(const QMatrix4x4& matrix);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* @brief Listen for resize events to ensure the child widget remains correctly sized
|
* @brief Listen for resize events to ensure the child widget remains correctly sized
|
||||||
@@ -71,11 +81,22 @@ private:
|
|||||||
*/
|
*/
|
||||||
QWidget* widget_;
|
QWidget* widget_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal resolution values
|
||||||
|
*/
|
||||||
|
int width_;
|
||||||
|
int height_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Aspect ratio calculated from the size provided by SetChildSize()
|
* @brief Aspect ratio calculated from the size provided by SetChildSize()
|
||||||
*/
|
*/
|
||||||
double aspect_ratio_;
|
double aspect_ratio_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal zoom value
|
||||||
|
*/
|
||||||
|
int zoom_;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VIEWERSIZER_H
|
#endif // VIEWERSIZER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user