From 4edf0a8fbd5db1516938473213ba5462d0f34893 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Tue, 29 Jan 2019 15:22:16 +1100 Subject: [PATCH] for viewer zooming, scale texture instead of surface #332 --- panels/timeline.cpp | 2 - ui/viewercontainer.cpp | 148 ++++++++++++++++++++++++++++------------- ui/viewercontainer.h | 36 +++++----- ui/viewerwidget.cpp | 40 ++++++++--- ui/viewerwidget.h | 4 ++ 5 files changed, 154 insertions(+), 76 deletions(-) diff --git a/panels/timeline.cpp b/panels/timeline.cpp index be8239734..7626318e2 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -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); diff --git a/ui/viewercontainer.cpp b/ui/viewercontainer.cpp index 145cd49fc..8801db35e 100644 --- a/ui/viewercontainer.cpp +++ b/ui/viewercontainer.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #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()) + ); +} diff --git a/ui/viewercontainer.h b/ui/viewercontainer.h index 921e2b9aa..e9e54937d 100644 --- a/ui/viewercontainer.h +++ b/ui/viewercontainer.h @@ -1,25 +1,27 @@ #ifndef VIEWERCONTAINER_H #define VIEWERCONTAINER_H -#include +#include 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 diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 648199df2..ea2322836 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -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(); diff --git a/ui/viewerwidget.h b/ui/viewerwidget.h index 098a1201c..e6f0526c8 100644 --- a/ui/viewerwidget.h +++ b/ui/viewerwidget.h @@ -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();