Merge pull request #373 from olive-editor/betterzoom
for viewer zooming, scale texture instead of surface #332
This commit is contained in:
@@ -1825,7 +1825,6 @@ void Timeline::setup_ui() {
|
||||
videoScrollbar = new QScrollBar(videoContainer);
|
||||
videoScrollbar->setMaximum(0);
|
||||
videoScrollbar->setSingleStep(20);
|
||||
videoScrollbar->setPageStep(1826);
|
||||
videoScrollbar->setOrientation(Qt::Vertical);
|
||||
|
||||
videoContainerLayout->addWidget(videoScrollbar);
|
||||
@@ -1856,7 +1855,6 @@ void Timeline::setup_ui() {
|
||||
horizontalScrollBar = new ResizableScrollBar(timeline_area);
|
||||
horizontalScrollBar->setMaximum(0);
|
||||
horizontalScrollBar->setSingleStep(20);
|
||||
horizontalScrollBar->setPageStep(1826);
|
||||
horizontalScrollBar->setOrientation(Qt::Horizontal);
|
||||
|
||||
timeline_area_layout->addWidget(horizontalScrollBar);
|
||||
|
||||
+100
-48
@@ -4,6 +4,7 @@
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
#include <QApplication>
|
||||
|
||||
#include "viewerwidget.h"
|
||||
#include "panels/viewer.h"
|
||||
@@ -12,42 +13,52 @@
|
||||
|
||||
// enforces aspect ratio
|
||||
ViewerContainer::ViewerContainer(QWidget *parent) :
|
||||
QScrollArea(parent),
|
||||
QWidget(parent),
|
||||
fit(true),
|
||||
child(nullptr)
|
||||
{
|
||||
setFrameShadow(QFrame::Plain);
|
||||
setFrameShape(QFrame::NoFrame);
|
||||
horizontal_scrollbar = new QScrollBar(Qt::Horizontal, this);
|
||||
vertical_scrollbar = new QScrollBar(Qt::Vertical, this);
|
||||
|
||||
area = new QWidget(this);
|
||||
area->move(0, 0);
|
||||
setWidget(area);
|
||||
horizontal_scrollbar->setSingleStep(20);
|
||||
vertical_scrollbar->setSingleStep(20);
|
||||
|
||||
child = new ViewerWidget(area);
|
||||
child = new ViewerWidget(this);
|
||||
child->container = this;
|
||||
|
||||
connect(horizontal_scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scroll_changed()));
|
||||
connect(vertical_scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scroll_changed()));
|
||||
}
|
||||
|
||||
ViewerContainer::~ViewerContainer() {
|
||||
delete child;
|
||||
delete area;
|
||||
|
||||
delete horizontal_scrollbar;
|
||||
delete vertical_scrollbar;
|
||||
}
|
||||
|
||||
void ViewerContainer::dragScrollPress(const QPoint &p) {
|
||||
drag_start_x = p.x();
|
||||
drag_start_y = p.y();
|
||||
horiz_start = horizontalScrollBar()->value();
|
||||
vert_start = verticalScrollBar()->value();
|
||||
|
||||
horiz_start = horizontal_scrollbar->value();
|
||||
vert_start = vertical_scrollbar->value();
|
||||
}
|
||||
|
||||
void ViewerContainer::dragScrollMove(const QPoint &p) {
|
||||
int true_x = p.x() + (horiz_start - horizontalScrollBar()->value());
|
||||
int true_y = p.y() + (vert_start - verticalScrollBar()->value());
|
||||
int this_x = p.x();
|
||||
int this_y = p.y();
|
||||
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + (drag_start_x - true_x));
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->value() + (drag_start_y - true_y));
|
||||
horizontal_scrollbar->setValue(horiz_start + (drag_start_x-this_x));
|
||||
vertical_scrollbar->setValue(vert_start + (drag_start_y-this_y));
|
||||
}
|
||||
|
||||
drag_start_x = true_x;
|
||||
drag_start_y = true_y;
|
||||
void ViewerContainer::parseWheelEvent(QWheelEvent *event) {
|
||||
if (event->modifiers() & Qt::AltModifier) {
|
||||
QApplication::sendEvent(horizontal_scrollbar, event);
|
||||
} else {
|
||||
QApplication::sendEvent(vertical_scrollbar, event);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerContainer::adjust() {
|
||||
@@ -55,46 +66,87 @@ void ViewerContainer::adjust() {
|
||||
if (child->waveform) {
|
||||
child->move(0, 0);
|
||||
child->resize(size());
|
||||
} else if (fit) {
|
||||
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
|
||||
|
||||
int widget_x = 0;
|
||||
int widget_y = 0;
|
||||
int widget_width = width();
|
||||
int widget_height = height();
|
||||
double widget_ar = double(widget_width) / double(widget_height);
|
||||
|
||||
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
|
||||
|
||||
if (widget_is_wider_than_sequence) {
|
||||
widget_width = widget_height * aspect_ratio;
|
||||
widget_x = (width() / 2) - (widget_width / 2);
|
||||
} else {
|
||||
widget_height = widget_width / aspect_ratio;
|
||||
widget_y = (height() / 2) - (widget_height / 2);
|
||||
}
|
||||
|
||||
child->move(widget_x, widget_y);
|
||||
child->resize(widget_width, widget_height);
|
||||
|
||||
zoom = double(widget_width) / double(viewer->seq->width);
|
||||
} else {
|
||||
int zoomed_width = double(viewer->seq->width)*zoom;
|
||||
int zoomed_height = double(viewer->seq->height)*zoom;
|
||||
int zoomed_x = 0;
|
||||
int zoomed_y = 0;
|
||||
horizontal_scrollbar->setVisible(false);
|
||||
vertical_scrollbar->setVisible(false);
|
||||
|
||||
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
|
||||
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
|
||||
int zoomed_width = qRound(double(viewer->seq->width)*zoom);
|
||||
int zoomed_height = qRound(double(viewer->seq->height)*zoom);
|
||||
|
||||
child->move(zoomed_x, zoomed_y);
|
||||
child->resize(zoomed_width, zoomed_height);
|
||||
if (fit || zoomed_width > width() || zoomed_height > height()) {
|
||||
// if the zoom size is greater than or equal to the available area, only use the available area
|
||||
|
||||
double aspect_ratio = double(viewer->seq->width)/double(viewer->seq->height);
|
||||
|
||||
int widget_x = 0;
|
||||
int widget_y = 0;
|
||||
int widget_width = width();
|
||||
int widget_height = height();
|
||||
|
||||
if (!fit) {
|
||||
widget_width -= vertical_scrollbar->width();
|
||||
widget_height -= horizontal_scrollbar->height();
|
||||
}
|
||||
|
||||
double widget_ar = double(widget_width) / double(widget_height);
|
||||
|
||||
bool widget_is_wider_than_sequence = widget_ar > aspect_ratio;
|
||||
|
||||
if (widget_is_wider_than_sequence) {
|
||||
widget_width = widget_height * aspect_ratio;
|
||||
widget_x = (width() / 2) - (widget_width / 2);
|
||||
} else {
|
||||
widget_height = widget_width / aspect_ratio;
|
||||
widget_y = (height() / 2) - (widget_height / 2);
|
||||
}
|
||||
|
||||
child->move(widget_x, widget_y);
|
||||
child->resize(widget_width, widget_height);
|
||||
|
||||
if (fit) {
|
||||
zoom = double(widget_width) / double(viewer->seq->width);
|
||||
} else if (zoomed_width > width() || zoomed_height > height()) {
|
||||
horizontal_scrollbar->setVisible(true);
|
||||
vertical_scrollbar->setVisible(true);
|
||||
|
||||
horizontal_scrollbar->setMaximum(zoomed_width - width());
|
||||
vertical_scrollbar->setMaximum(zoomed_height - height());
|
||||
|
||||
horizontal_scrollbar->setValue(horizontal_scrollbar->maximum()/2);
|
||||
vertical_scrollbar->setValue(vertical_scrollbar->maximum()/2);
|
||||
}
|
||||
} else {
|
||||
// if the zoom size is smaller than the available area, scale the surface down
|
||||
|
||||
int zoomed_x = 0;
|
||||
int zoomed_y = 0;
|
||||
|
||||
if (zoomed_width < width()) zoomed_x = (width()>>1)-(zoomed_width>>1);
|
||||
if (zoomed_height < height()) zoomed_y = (height()>>1)-(zoomed_height>>1);
|
||||
|
||||
child->move(zoomed_x, zoomed_y);
|
||||
child->resize(zoomed_width, zoomed_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
area->resize(qMax(width(), child->width()), qMax(height(), child->height()));
|
||||
}
|
||||
|
||||
void ViewerContainer::resizeEvent(QResizeEvent *event) {
|
||||
horizontal_scrollbar->move(0, height()-horizontal_scrollbar->height());
|
||||
horizontal_scrollbar->setFixedWidth(width()-vertical_scrollbar->width());
|
||||
horizontal_scrollbar->setPageStep(width());
|
||||
|
||||
vertical_scrollbar->move(width() - vertical_scrollbar->width(), 0);
|
||||
vertical_scrollbar->setFixedHeight(height()-horizontal_scrollbar->height());
|
||||
vertical_scrollbar->setPageStep(height());
|
||||
|
||||
event->accept();
|
||||
adjust();
|
||||
}
|
||||
|
||||
void ViewerContainer::scroll_changed() {
|
||||
child->set_scroll(
|
||||
double(horizontal_scrollbar->value())/double(horizontal_scrollbar->maximum()),
|
||||
double(vertical_scrollbar->value())/double(vertical_scrollbar->maximum())
|
||||
);
|
||||
}
|
||||
|
||||
+21
-15
@@ -1,25 +1,27 @@
|
||||
#ifndef VIEWERCONTAINER_H
|
||||
#define VIEWERCONTAINER_H
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QWidget>
|
||||
class Viewer;
|
||||
class ViewerWidget;
|
||||
class QScrollBar;
|
||||
|
||||
class ViewerContainer : public QScrollArea
|
||||
class ViewerContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ViewerContainer(QWidget *parent = 0);
|
||||
~ViewerContainer();
|
||||
explicit ViewerContainer(QWidget *parent = 0);
|
||||
~ViewerContainer();
|
||||
|
||||
bool fit;
|
||||
double zoom;
|
||||
bool fit;
|
||||
double zoom;
|
||||
|
||||
void dragScrollPress(const QPoint&);
|
||||
void dragScrollMove(const QPoint&);
|
||||
void dragScrollPress(const QPoint&);
|
||||
void dragScrollMove(const QPoint&);
|
||||
void parseWheelEvent(QWheelEvent* event);
|
||||
|
||||
Viewer* viewer;
|
||||
ViewerWidget* child;
|
||||
Viewer* viewer;
|
||||
ViewerWidget* child;
|
||||
void adjust();
|
||||
|
||||
protected:
|
||||
@@ -29,12 +31,16 @@ signals:
|
||||
|
||||
public slots:
|
||||
|
||||
private slots:
|
||||
void scroll_changed();
|
||||
|
||||
private:
|
||||
QWidget* area;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
int horiz_start;
|
||||
int vert_start;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
int horiz_start;
|
||||
int vert_start;
|
||||
QScrollBar* horizontal_scrollbar;
|
||||
QScrollBar* vertical_scrollbar;
|
||||
};
|
||||
|
||||
#endif // VIEWERCONTAINER_H
|
||||
|
||||
+29
-11
@@ -56,7 +56,9 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
dragging(false),
|
||||
gizmos(nullptr),
|
||||
selected_gizmo(nullptr),
|
||||
window(nullptr)
|
||||
window(nullptr),
|
||||
x_scroll(0),
|
||||
y_scroll(0)
|
||||
{
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
@@ -238,6 +240,12 @@ RenderThread *ViewerWidget::get_renderer() {
|
||||
return renderer;
|
||||
}
|
||||
|
||||
void ViewerWidget::set_scroll(double x, double y) {
|
||||
x_scroll = x;
|
||||
y_scroll = y;
|
||||
update();
|
||||
}
|
||||
|
||||
//void ViewerWidget::resizeGL(int w, int h)
|
||||
//{
|
||||
//}
|
||||
@@ -384,6 +392,10 @@ void ViewerWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
void ViewerWidget::wheelEvent(QWheelEvent *event) {
|
||||
container->parseWheelEvent(event);
|
||||
}
|
||||
|
||||
void ViewerWidget::close_window() {
|
||||
if (window != nullptr) window->hide();
|
||||
}
|
||||
@@ -547,7 +559,6 @@ void ViewerWidget::paintGL() {
|
||||
makeCurrent();
|
||||
|
||||
// clear to solid black
|
||||
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
@@ -558,7 +569,7 @@ void ViewerWidget::paintGL() {
|
||||
|
||||
// set screen coords to widget size
|
||||
glLoadIdentity();
|
||||
glOrtho(0, 1, 0, 1, -1, 1);
|
||||
glOrtho(-1, 1, -1, 1, -1, 1);
|
||||
|
||||
// draw texture from render thread
|
||||
|
||||
@@ -566,14 +577,21 @@ void ViewerWidget::paintGL() {
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glVertex2f(0, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2f(0, 1);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex2f(1, 1);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex2f(1, 0);
|
||||
glTexCoord2f(0, 1);
|
||||
double zoom_factor = container->zoom/(double(width())/double(viewer->seq->width));
|
||||
double zoom_size = (zoom_factor*2.0) - 2.0;
|
||||
double zoom_left = -zoom_size*x_scroll - 1.0;
|
||||
double zoom_right = zoom_size*(1.0-x_scroll) + 1.0;
|
||||
double zoom_bottom = -zoom_size*(1.0-y_scroll) - 1.0;
|
||||
double zoom_top = zoom_size*(y_scroll) + 1.0;
|
||||
|
||||
glVertex2d(zoom_left, zoom_bottom);
|
||||
glTexCoord2d(0, 0);
|
||||
glVertex2d(zoom_left, zoom_top);
|
||||
glTexCoord2d(1, 0);
|
||||
glVertex2d(zoom_right, zoom_top);
|
||||
glTexCoord2d(1, 1);
|
||||
glVertex2d(zoom_right, zoom_bottom);
|
||||
glTexCoord2d(0, 1);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
@@ -44,12 +44,14 @@ public:
|
||||
|
||||
void frame_update();
|
||||
RenderThread* get_renderer();
|
||||
void set_scroll(double x, double y);
|
||||
public slots:
|
||||
void set_waveform_scroll(int s);
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
private:
|
||||
void draw_waveform_func();
|
||||
void draw_title_safe_area();
|
||||
@@ -66,6 +68,8 @@ private:
|
||||
EffectGizmo* selected_gizmo;
|
||||
RenderThread* renderer;
|
||||
ViewerWindow* window;
|
||||
double x_scroll;
|
||||
double y_scroll;
|
||||
private slots:
|
||||
void context_destroy();
|
||||
void retry();
|
||||
|
||||
Reference in New Issue
Block a user