viewerwindow: implemented displaying a viewer image fullscreen on another monitor
Implements an extra widget to display images on a separate monitor. Both viewers have separate display color controls since different monitors may conform to different standards/transforms.
This commit is contained in:
@@ -28,5 +28,7 @@ set(OLIVE_SOURCES
|
||||
widget/viewer/viewerglwidget.cpp
|
||||
widget/viewer/viewersizer.h
|
||||
widget/viewer/viewersizer.cpp
|
||||
widget/viewer/viewerwindow.h
|
||||
widget/viewer/viewerwindow.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ FootageViewerWidget::FootageViewerWidget(QWidget *parent) :
|
||||
audio_node_ = new AudioInput();
|
||||
viewer_node_ = new ViewerOutput();
|
||||
|
||||
connect(gl_widget_, &ViewerGLWidget::DragStarted, this, &FootageViewerWidget::StartFootageDrag);
|
||||
connect(main_gl_widget(), &ViewerGLWidget::DragStarted, this, &FootageViewerWidget::StartFootageDrag);
|
||||
|
||||
controls_->SetAudioVideoDragButtonsVisible(true);
|
||||
connect(controls_, &PlaybackControls::VideoPressed, this, &FootageViewerWidget::StartVideoDrag);
|
||||
|
||||
+135
-42
@@ -21,8 +21,10 @@
|
||||
#include "viewer.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QGuiApplication>
|
||||
#include <QLabel>
|
||||
#include <QResizeEvent>
|
||||
#include <QScreen>
|
||||
#include <QtMath>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -55,11 +57,12 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
sizer_ = new ViewerSizer();
|
||||
stack_->addWidget(sizer_);
|
||||
|
||||
gl_widget_ = new ViewerGLWidget();
|
||||
connect(gl_widget_, &ViewerGLWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||
connect(gl_widget_, &ViewerGLWidget::CursorColor, this, &ViewerWidget::CursorColor);
|
||||
connect(sizer_, &ViewerSizer::RequestMatrix, gl_widget_, &ViewerGLWidget::SetMatrix);
|
||||
sizer_->SetWidget(gl_widget_);
|
||||
ViewerGLWidget* main_widget = new ViewerGLWidget();
|
||||
connect(main_widget, &ViewerGLWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||
connect(main_widget, &ViewerGLWidget::CursorColor, this, &ViewerWidget::CursorColor);
|
||||
connect(sizer_, &ViewerSizer::RequestMatrix, main_widget, &ViewerGLWidget::SetMatrix);
|
||||
sizer_->SetWidget(main_widget);
|
||||
gl_widgets_.append(main_widget);
|
||||
|
||||
// Create waveform view when audio is connected and video isn't
|
||||
waveform_view_ = new AudioWaveformView();
|
||||
@@ -145,12 +148,18 @@ void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
SizeChangedSlot(n->video_params().width(), n->video_params().height());
|
||||
LengthChangedSlot(n->Length());
|
||||
|
||||
ColorManager* using_manager;
|
||||
if (override_color_manager_) {
|
||||
gl_widget_->ConnectColorManager(override_color_manager_);
|
||||
using_manager = override_color_manager_;
|
||||
} else if (n->parent()) {
|
||||
gl_widget_->ConnectColorManager(static_cast<Sequence*>(n->parent())->project()->color_manager());
|
||||
using_manager = static_cast<Sequence*>(n->parent())->project()->color_manager();
|
||||
} else {
|
||||
qWarning() << "Failed to find a suitable color manager for the connected viewer node";
|
||||
using_manager = nullptr;
|
||||
}
|
||||
|
||||
foreach (ViewerGLWidget* glw, gl_widgets_) {
|
||||
glw->ConnectColorManager(using_manager);
|
||||
}
|
||||
|
||||
divider_ = CalculateDivider();
|
||||
@@ -181,7 +190,9 @@ void ViewerWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
// Effectively disables the viewer and clears the state
|
||||
SizeChangedSlot(0, 0);
|
||||
|
||||
gl_widget_->DisconnectColorManager();
|
||||
foreach (ViewerGLWidget* glw, gl_widgets_) {
|
||||
glw->DisconnectColorManager();
|
||||
}
|
||||
|
||||
waveform_view_->ConnectTimelinePoints(nullptr);
|
||||
}
|
||||
@@ -213,6 +224,16 @@ void ViewerWidget::resizeEvent(QResizeEvent *event)
|
||||
UpdateMinimumScale();
|
||||
}
|
||||
|
||||
const QList<ViewerGLWidget*> &ViewerWidget::gl_widgets() const
|
||||
{
|
||||
return gl_widgets_;
|
||||
}
|
||||
|
||||
ViewerGLWidget *ViewerWidget::main_gl_widget() const
|
||||
{
|
||||
return gl_widgets_.first();
|
||||
}
|
||||
|
||||
void ViewerWidget::TogglePlayPause()
|
||||
{
|
||||
if (IsPlaying()) {
|
||||
@@ -249,7 +270,9 @@ void ViewerWidget::SetOverrideSize(int width, int height)
|
||||
|
||||
void ViewerWidget::SetMatrix(const QMatrix4x4 &mat)
|
||||
{
|
||||
gl_widget_->SetMatrix(mat);
|
||||
foreach (ViewerGLWidget* glw, gl_widgets_) {
|
||||
glw->SetMatrix(mat);
|
||||
}
|
||||
}
|
||||
|
||||
VideoRenderBackend *ViewerWidget::video_renderer() const
|
||||
@@ -260,12 +283,12 @@ VideoRenderBackend *ViewerWidget::video_renderer() const
|
||||
void ViewerWidget::UpdateTextureFromNode(const rational& time)
|
||||
{
|
||||
if (!GetConnectedNode() || time >= GetConnectedNode()->Length()) {
|
||||
gl_widget_->SetImage(QString());
|
||||
main_gl_widget()->SetImage(QString());
|
||||
} else {
|
||||
QString frame_fn = video_renderer_->GetCachedFrame(time);
|
||||
|
||||
if (!frame_fn.isEmpty()) {
|
||||
gl_widget_->SetImage(frame_fn);
|
||||
main_gl_widget()->SetImage(frame_fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,7 +317,7 @@ void ViewerWidget::PlayInternal(int speed)
|
||||
controls_->ShowPauseButton();
|
||||
|
||||
if (stack_->currentWidget() == sizer_) {
|
||||
connect(gl_widget_, &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
connect(main_gl_widget(), &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
} else {
|
||||
connect(AudioManager::instance(), &AudioManager::OutputNotified, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
}
|
||||
@@ -325,7 +348,7 @@ int ViewerWidget::CalculateDivider()
|
||||
{
|
||||
if (GetConnectedNode() && Config::Current()["AutoSelectDivider"].toBool()) {
|
||||
int long_side_of_video = qMax(GetConnectedNode()->video_params().width(), GetConnectedNode()->video_params().height());
|
||||
int long_side_of_widget = qMax(gl_widget_->width(), gl_widget_->height());
|
||||
int long_side_of_widget = qMax(main_gl_widget()->width(), main_gl_widget()->height());
|
||||
|
||||
return qMax(1, long_side_of_video / long_side_of_widget);
|
||||
}
|
||||
@@ -356,6 +379,35 @@ void ViewerWidget::UpdateStack()
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::SetFullScreenDisplay(QAction *action)
|
||||
{
|
||||
QScreen* target = QGuiApplication::screens().at(action->data().toInt());
|
||||
|
||||
ViewerWindow* vw = new ViewerWindow(this);
|
||||
|
||||
vw->showFullScreen();
|
||||
vw->setGeometry(target->geometry());
|
||||
vw->gl_widget()->ConnectColorManager(main_gl_widget()->color_manager());
|
||||
main_gl_widget()->ConnectSibling(vw->gl_widget());
|
||||
connect(vw, &ViewerWindow::destroyed, this, &ViewerWidget::WindowAboutToClose);
|
||||
connect(vw->gl_widget(), &ViewerGLWidget::customContextMenuRequested, this, &ViewerWidget::ShowContextMenu);
|
||||
|
||||
if (GetConnectedNode()) {
|
||||
vw->SetResolution(GetConnectedNode()->video_params().width(), GetConnectedNode()->video_params().height());
|
||||
}
|
||||
|
||||
windows_.append(vw);
|
||||
gl_widgets_.append(vw->gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::WindowAboutToClose()
|
||||
{
|
||||
ViewerWindow* vw = static_cast<ViewerWindow*>(sender());
|
||||
|
||||
windows_.removeAll(vw);
|
||||
gl_widgets_.removeAll(vw->gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::UpdateRendererParameters()
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
@@ -385,40 +437,42 @@ void ViewerWidget::UpdateRendererParameters()
|
||||
|
||||
void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu menu(this);
|
||||
QMenu menu(static_cast<QWidget*>(sender()));
|
||||
|
||||
context_menu_widget_ = static_cast<ViewerGLWidget*>(sender());
|
||||
|
||||
// Color options
|
||||
if (gl_widget_->color_manager() && color_menu_enabled_) {
|
||||
QStringList displays = gl_widget_->color_manager()->ListAvailableDisplays();
|
||||
if (context_menu_widget_->color_manager() && color_menu_enabled_) {
|
||||
QStringList displays = context_menu_widget_->color_manager()->ListAvailableDisplays();
|
||||
QMenu* ocio_display_menu = menu.addMenu(tr("Display"));
|
||||
connect(ocio_display_menu, &QMenu::triggered, this, &ViewerWidget::ColorDisplayChanged);
|
||||
connect(ocio_display_menu, &QMenu::triggered, this, &ViewerWidget::ContextMenuOCIODisplay);
|
||||
foreach (const QString& d, displays) {
|
||||
QAction* action = ocio_display_menu->addAction(d);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(gl_widget_->ocio_display() == d);
|
||||
action->setChecked(context_menu_widget_->ocio_display() == d);
|
||||
action->setData(d);
|
||||
}
|
||||
|
||||
QStringList views = gl_widget_->color_manager()->ListAvailableViews(gl_widget_->ocio_display());
|
||||
QStringList views = context_menu_widget_->color_manager()->ListAvailableViews(context_menu_widget_->ocio_display());
|
||||
QMenu* ocio_view_menu = menu.addMenu(tr("View"));
|
||||
connect(ocio_view_menu, &QMenu::triggered, this, &ViewerWidget::ColorViewChanged);
|
||||
connect(ocio_view_menu, &QMenu::triggered, this, &ViewerWidget::ContextMenuOCIOView);
|
||||
foreach (const QString& v, views) {
|
||||
QAction* action = ocio_view_menu->addAction(v);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(gl_widget_->ocio_view() == v);
|
||||
action->setChecked(context_menu_widget_->ocio_view() == v);
|
||||
action->setData(v);
|
||||
}
|
||||
|
||||
QStringList looks = gl_widget_->color_manager()->ListAvailableLooks();
|
||||
QStringList looks = context_menu_widget_->color_manager()->ListAvailableLooks();
|
||||
QMenu* ocio_look_menu = menu.addMenu(tr("Look"));
|
||||
connect(ocio_look_menu, &QMenu::triggered, this, &ViewerWidget::ColorLookChanged);
|
||||
connect(ocio_look_menu, &QMenu::triggered, this, &ViewerWidget::ContextMenuOCIOLook);
|
||||
QAction* no_look_action = ocio_look_menu->addAction(tr("(None)"));
|
||||
no_look_action->setCheckable(true);
|
||||
no_look_action->setChecked(gl_widget_->ocio_look().isEmpty());
|
||||
no_look_action->setChecked(context_menu_widget_->ocio_look().isEmpty());
|
||||
foreach (const QString& l, looks) {
|
||||
QAction* action = ocio_look_menu->addAction(l);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(gl_widget_->ocio_look() == l);
|
||||
action->setChecked(context_menu_widget_->ocio_look() == l);
|
||||
action->setData(l);
|
||||
}
|
||||
|
||||
@@ -434,6 +488,13 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
}
|
||||
connect(playback_resolution_menu, &QMenu::triggered, this, &ViewerWidget::SetDividerFromMenu);
|
||||
|
||||
foreach (QAction* a, playback_resolution_menu->actions()) {
|
||||
a->setCheckable(true);
|
||||
if (a->data() == divider_) {
|
||||
a->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Viewer Zoom Level
|
||||
QMenu* zoom_menu = menu.addMenu(tr("Zoom"));
|
||||
int zoom_levels[] = {10, 25, 50, 75, 100, 150, 200, 400};
|
||||
@@ -443,12 +504,18 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
}
|
||||
connect(zoom_menu, &QMenu::triggered, this, &ViewerWidget::SetZoomFromMenu);
|
||||
|
||||
foreach (QAction* a, playback_resolution_menu->actions()) {
|
||||
a->setCheckable(true);
|
||||
if (a->data() == divider_) {
|
||||
a->setChecked(true);
|
||||
}
|
||||
// Full Screen Menu
|
||||
QMenu* full_screen_menu = menu.addMenu(tr("Full Screen"));
|
||||
for (int i=0;i<QGuiApplication::screens().size();i++) {
|
||||
QScreen* s = QGuiApplication::screens().at(i);
|
||||
|
||||
QAction* a = full_screen_menu->addAction(tr("Screen %1: %2x%3").arg(QString::number(i),
|
||||
QString::number(s->size().width()),
|
||||
QString::number(s->size().height())));
|
||||
|
||||
a->setData(i);
|
||||
}
|
||||
connect(full_screen_menu, &QMenu::triggered, this, &ViewerWidget::SetFullScreenDisplay);
|
||||
|
||||
menu.exec(static_cast<QWidget*>(sender())->mapToGlobal(pos));
|
||||
}
|
||||
@@ -466,7 +533,7 @@ void ViewerWidget::Pause()
|
||||
controls_->ShowPlayButton();
|
||||
|
||||
if (stack_->currentWidget() == sizer_) {
|
||||
disconnect(gl_widget_, &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
disconnect(main_gl_widget(), &ViewerGLWidget::frameSwapped, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
} else {
|
||||
disconnect(AudioManager::instance(), &AudioManager::OutputNotified, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
}
|
||||
@@ -514,27 +581,49 @@ void ViewerWidget::ShuttleRight()
|
||||
|
||||
void ViewerWidget::SetOCIOParameters(const QString &display, const QString &view, const QString &look)
|
||||
{
|
||||
gl_widget_->SetOCIOParameters(display, view, look);
|
||||
SetOCIOParameters(display, view, look, main_gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOParameters(const QString &display, const QString &view, const QString &look, ViewerGLWidget* sender)
|
||||
{
|
||||
sender->SetOCIOParameters(display, view, look);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIODisplay(const QString &display)
|
||||
{
|
||||
gl_widget_->SetOCIODisplay(display);
|
||||
SetOCIODisplay(display, main_gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIODisplay(const QString &display, ViewerGLWidget* sender)
|
||||
{
|
||||
sender->SetOCIODisplay(display);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOView(const QString &view)
|
||||
{
|
||||
gl_widget_->SetOCIOView(view);
|
||||
SetOCIOView(view, main_gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOLook(const QString &look)
|
||||
{
|
||||
gl_widget_->SetOCIOLook(look);
|
||||
SetOCIOLook(look, main_gl_widget());
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOView(const QString &view, ViewerGLWidget* sender)
|
||||
{
|
||||
sender->SetOCIOView(view);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetOCIOLook(const QString &look, ViewerGLWidget* sender)
|
||||
{
|
||||
sender->SetOCIOLook(look);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetSignalCursorColorEnabled(bool e)
|
||||
{
|
||||
gl_widget_->SetSignalCursorColorEnabled(e);
|
||||
foreach (ViewerGLWidget* glw, gl_widgets_) {
|
||||
glw->SetSignalCursorColorEnabled(e);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
@@ -576,6 +665,10 @@ void ViewerWidget::RendererCachedTime(const rational &time, qint64 job_time)
|
||||
void ViewerWidget::SizeChangedSlot(int width, int height)
|
||||
{
|
||||
sizer_->SetChildSize(width, height);
|
||||
|
||||
foreach (ViewerWindow* vw, windows_) {
|
||||
vw->SetResolution(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::LengthChangedSlot(const rational &length)
|
||||
@@ -585,19 +678,19 @@ void ViewerWidget::LengthChangedSlot(const rational &length)
|
||||
UpdateMinimumScale();
|
||||
}
|
||||
|
||||
void ViewerWidget::ColorDisplayChanged(QAction* action)
|
||||
void ViewerWidget::ContextMenuOCIODisplay(QAction* action)
|
||||
{
|
||||
SetOCIODisplay(action->data().toString());
|
||||
SetOCIODisplay(action->data().toString(), context_menu_widget_);
|
||||
}
|
||||
|
||||
void ViewerWidget::ColorViewChanged(QAction *action)
|
||||
void ViewerWidget::ContextMenuOCIOView(QAction *action)
|
||||
{
|
||||
SetOCIOView(action->data().toString());
|
||||
SetOCIOView(action->data().toString(), context_menu_widget_);
|
||||
}
|
||||
|
||||
void ViewerWidget::ColorLookChanged(QAction *action)
|
||||
void ViewerWidget::ContextMenuOCIOLook(QAction *action)
|
||||
{
|
||||
SetOCIOLook(action->data().toString());
|
||||
SetOCIOLook(action->data().toString(), context_menu_widget_);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetDividerFromMenu(QAction *action)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "render/backend/audio/audiobackend.h"
|
||||
#include "viewerglwidget.h"
|
||||
#include "viewersizer.h"
|
||||
#include "viewerwindow.h"
|
||||
#include "widget/playbackcontrols/playbackcontrols.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
@@ -132,10 +133,11 @@ protected:
|
||||
OpenGLBackend* video_renderer_;
|
||||
AudioBackend* audio_renderer_;
|
||||
|
||||
ViewerGLWidget* gl_widget_;
|
||||
|
||||
PlaybackControls* controls_;
|
||||
|
||||
const QList<ViewerGLWidget *> &gl_widgets() const;
|
||||
ViewerGLWidget* main_gl_widget() const;
|
||||
|
||||
private:
|
||||
void UpdateTimeInternal(int64_t i);
|
||||
|
||||
@@ -149,6 +151,11 @@ private:
|
||||
|
||||
void UpdateMinimumScale();
|
||||
|
||||
void SetOCIOParameters(const QString& display, const QString& view, const QString& look, ViewerGLWidget* sender);
|
||||
void SetOCIODisplay(const QString& display, ViewerGLWidget* sender);
|
||||
void SetOCIOView(const QString& view, ViewerGLWidget* sender);
|
||||
void SetOCIOLook(const QString& look, ViewerGLWidget* sender);
|
||||
|
||||
QStackedWidget* stack_;
|
||||
|
||||
ViewerSizer* sizer_;
|
||||
@@ -172,6 +179,12 @@ private:
|
||||
|
||||
AudioWaveformView* waveform_view_;
|
||||
|
||||
QList<ViewerWindow*> windows_;
|
||||
|
||||
QList<ViewerGLWidget*> gl_widgets_;
|
||||
|
||||
ViewerGLWidget* context_menu_widget_;
|
||||
|
||||
private slots:
|
||||
void PlaybackTimerUpdate();
|
||||
|
||||
@@ -188,17 +201,17 @@ private slots:
|
||||
/**
|
||||
* @brief Slot called whenever this viewer's OCIO display setting has changed
|
||||
*/
|
||||
void ColorDisplayChanged(QAction* action);
|
||||
void ContextMenuOCIODisplay(QAction* action);
|
||||
|
||||
/**
|
||||
* @brief Slot called whenever this viewer's OCIO view setting has changed
|
||||
*/
|
||||
void ColorViewChanged(QAction* action);
|
||||
void ContextMenuOCIOView(QAction* action);
|
||||
|
||||
/**
|
||||
* @brief Slot called whenever this viewer's OCIO look setting has changed
|
||||
*/
|
||||
void ColorLookChanged(QAction* action);
|
||||
void ContextMenuOCIOLook(QAction* action);
|
||||
|
||||
void SetDividerFromMenu(QAction* action);
|
||||
|
||||
@@ -208,6 +221,10 @@ private slots:
|
||||
|
||||
void UpdateStack();
|
||||
|
||||
void SetFullScreenDisplay(QAction* action);
|
||||
|
||||
void WindowAboutToClose();
|
||||
|
||||
};
|
||||
|
||||
#endif // VIEWER_WIDGET_H
|
||||
|
||||
@@ -114,6 +114,8 @@ void ViewerGLWidget::SetImage(const QString &fn)
|
||||
|
||||
texture_.Upload(load_buffer_.data());
|
||||
|
||||
emit LoadedBuffer(&load_buffer_);
|
||||
|
||||
doneCurrent();
|
||||
|
||||
has_image_ = true;
|
||||
@@ -128,12 +130,16 @@ void ViewerGLWidget::SetImage(const QString &fn)
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
if (has_image_) {
|
||||
emit LoadedBuffer(&load_buffer_);
|
||||
} else {
|
||||
emit LoadedBuffer(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerGLWidget::SetSignalCursorColorEnabled(bool e)
|
||||
{
|
||||
qDebug() << e;
|
||||
|
||||
signal_cursor_color_ = e;
|
||||
setMouseTracking(e);
|
||||
|
||||
@@ -149,6 +155,28 @@ void ViewerGLWidget::SetSignalCursorColorEnabled(bool e)
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerGLWidget::SetImageFromLoadBuffer(Frame *in_buffer)
|
||||
{
|
||||
has_image_ = in_buffer;
|
||||
|
||||
if (has_image_) {
|
||||
makeCurrent();
|
||||
|
||||
if (!texture_.IsCreated()
|
||||
|| texture_.width() != in_buffer->width()
|
||||
|| texture_.height() != in_buffer->height()
|
||||
|| texture_.format() != in_buffer->format()) {
|
||||
texture_.Create(context(), in_buffer->width(), in_buffer->height(), in_buffer->format(), in_buffer->data());
|
||||
} else {
|
||||
texture_.Upload(in_buffer->data());
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ViewerGLWidget::SetOCIODisplay(const QString &display)
|
||||
{
|
||||
ocio_display_ = display;
|
||||
@@ -198,6 +226,12 @@ const QString &ViewerGLWidget::ocio_look() const
|
||||
return ocio_look_;
|
||||
}
|
||||
|
||||
void ViewerGLWidget::ConnectSibling(ViewerGLWidget *sibling)
|
||||
{
|
||||
connect(this, &ViewerGLWidget::LoadedBuffer, sibling, &ViewerGLWidget::SetImageFromLoadBuffer, Qt::QueuedConnection);
|
||||
sibling->SetImageFromLoadBuffer(&load_buffer_);
|
||||
}
|
||||
|
||||
void ViewerGLWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QOpenGLWidget::mousePressEvent(event);
|
||||
|
||||
@@ -81,6 +81,10 @@ public:
|
||||
const QString& ocio_view() const;
|
||||
const QString& ocio_look() const;
|
||||
|
||||
const QMatrix4x4& GetMatrix();
|
||||
|
||||
void ConnectSibling(ViewerGLWidget* sibling);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Set the texture to draw and draw it
|
||||
@@ -130,6 +134,14 @@ public slots:
|
||||
*/
|
||||
void SetSignalCursorColorEnabled(bool e);
|
||||
|
||||
/**
|
||||
* @brief Overrides the image with the load buffer of another ViewerGLWidget
|
||||
*
|
||||
* If there are multiple ViewerGLWidgets showing the same thing, this is faster than decoding the image from file
|
||||
* each time.
|
||||
*/
|
||||
void SetImageFromLoadBuffer(Frame* in_buffer);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when the user starts dragging from the viewer
|
||||
@@ -141,6 +153,11 @@ signals:
|
||||
*/
|
||||
void CursorColor(const Color& reference, const Color& display);
|
||||
|
||||
/**
|
||||
* @brief Connect this to the SetImageFromLoadBuffer() slot of another ViewerGLWidget to show the same thing
|
||||
*/
|
||||
void LoadedBuffer(Frame* load_buffer);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Override the mouse press event simply to emit the DragStarted() signal
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "viewerwindow.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
ViewerWindow::ViewerWindow(QWidget *parent) :
|
||||
QWidget(parent, Qt::Window | Qt::WindowStaysOnTopHint)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
|
||||
gl_widget_ = new ViewerGLWidget();
|
||||
layout->addWidget(gl_widget_);
|
||||
}
|
||||
|
||||
ViewerGLWidget *ViewerWindow::gl_widget() const
|
||||
{
|
||||
return gl_widget_;
|
||||
}
|
||||
|
||||
void ViewerWindow::SetResolution(int width, int height)
|
||||
{
|
||||
// Set GL widget matrix to maintain this texture's aspect ratio
|
||||
double window_ar = static_cast<double>(this->width()) / static_cast<double>(this->height());
|
||||
double image_ar = static_cast<double>(width) / static_cast<double>(height);
|
||||
|
||||
QMatrix4x4 mat;
|
||||
|
||||
if (window_ar > image_ar) {
|
||||
// Window is wider than image, adjust X scale
|
||||
mat.scale(image_ar / window_ar, 1.0f, 1.0f);
|
||||
} else if (window_ar < image_ar) {
|
||||
// Window is taller than image, adjust Y scale
|
||||
mat.scale(1.0f, window_ar / image_ar, 1.0f);
|
||||
}
|
||||
|
||||
gl_widget_->SetMatrix(mat);
|
||||
}
|
||||
|
||||
void ViewerWindow::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
QWidget::keyPressEvent(e);
|
||||
|
||||
if (e->key() == Qt::Key_Escape) {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWindow::closeEvent(QCloseEvent *e)
|
||||
{
|
||||
QWidget::closeEvent(e);
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef VIEWERWINDOW_H
|
||||
#define VIEWERWINDOW_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "viewerglwidget.h"
|
||||
|
||||
class ViewerWindow : public QWidget
|
||||
{
|
||||
public:
|
||||
ViewerWindow(QWidget* parent = nullptr);
|
||||
|
||||
ViewerGLWidget* gl_widget() const;
|
||||
|
||||
/**
|
||||
* @brief Used to adjust resulting picture to be the right aspect ratio
|
||||
*/
|
||||
void SetResolution(int width, int height);
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent* e) override;
|
||||
|
||||
virtual void closeEvent(QCloseEvent* e) override;
|
||||
|
||||
private:
|
||||
ViewerGLWidget* gl_widget_;
|
||||
|
||||
};
|
||||
|
||||
#endif // VIEWERWINDOW_H
|
||||
Reference in New Issue
Block a user