all time-based panels are now derived from a common base class
Cuts down on a lot of duplicate code between TimelineWidget/ViewerWidget/CurveWidget/NodeParamView and TimelinePanel/ViewerPanel/CurvePanel/ParamPanel since they all use similar time functions.
This commit is contained in:
@@ -192,8 +192,8 @@ void ExportDialog::accept()
|
||||
|
||||
QMatrix4x4 transform;
|
||||
|
||||
int dest_width = video_tab_->width_slider()->GetValue();
|
||||
int dest_height = video_tab_->height_slider()->GetValue();
|
||||
int dest_width = static_cast<int>(video_tab_->width_slider()->GetValue());
|
||||
int dest_height = static_cast<int>(video_tab_->height_slider()->GetValue());
|
||||
|
||||
if (video_tab_->scaling_method_combobox()->isEnabled()) {
|
||||
int source_width = viewer_node_->video_params().width();
|
||||
@@ -444,13 +444,14 @@ QMatrix4x4 ExportDialog::GenerateMatrix(ExportVideoTab::ScalingMethod method, in
|
||||
|
||||
void ExportDialog::UpdateViewerDimensions()
|
||||
{
|
||||
preview_viewer_->SetOverrideSize(video_tab_->width_slider()->GetValue(), video_tab_->height_slider()->GetValue());
|
||||
preview_viewer_->SetOverrideSize(static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||
static_cast<int>(video_tab_->height_slider()->GetValue()));
|
||||
|
||||
preview_viewer_->SetMatrix(GenerateMatrix(static_cast<ExportVideoTab::ScalingMethod>(video_tab_->scaling_method_combobox()->currentData().toInt()),
|
||||
viewer_node_->video_params().width(),
|
||||
viewer_node_->video_params().height(),
|
||||
video_tab_->width_slider()->GetValue(),
|
||||
video_tab_->height_slider()->GetValue()));
|
||||
static_cast<int>(video_tab_->width_slider()->GetValue()),
|
||||
static_cast<int>(video_tab_->height_slider()->GetValue())));
|
||||
}
|
||||
|
||||
void ExportDialog::ExporterIsDone()
|
||||
|
||||
@@ -21,6 +21,7 @@ add_subdirectory(node)
|
||||
add_subdirectory(param)
|
||||
add_subdirectory(project)
|
||||
add_subdirectory(taskmanager)
|
||||
add_subdirectory(timebased)
|
||||
add_subdirectory(timeline)
|
||||
add_subdirectory(tool)
|
||||
add_subdirectory(viewer)
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
#include "curve.h"
|
||||
|
||||
CurvePanel::CurvePanel(QWidget *parent) :
|
||||
PanelWidget(parent)
|
||||
TimeBasedPanel(parent)
|
||||
{
|
||||
// FIXME: This won't work if there's ever more than one of this panel
|
||||
setObjectName("CurvePanel");
|
||||
|
||||
// Create main widget and set it
|
||||
widget_ = new CurveWidget();
|
||||
setWidget(widget_);
|
||||
|
||||
connect(widget_, &CurveWidget::TimeChanged, this, &CurvePanel::TimeChanged);
|
||||
SetTimeBasedWidget(new CurveWidget());
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
@@ -18,48 +15,24 @@ CurvePanel::CurvePanel(QWidget *parent) :
|
||||
|
||||
void CurvePanel::SetInput(NodeInput *input)
|
||||
{
|
||||
widget_->SetInput(input);
|
||||
}
|
||||
|
||||
void CurvePanel::SetTimebase(const rational &timebase)
|
||||
{
|
||||
widget_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void CurvePanel::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
widget_->SetTime(timestamp);
|
||||
}
|
||||
|
||||
void CurvePanel::ZoomIn()
|
||||
{
|
||||
widget_->SetScale(widget_->GetScale() * 2);
|
||||
}
|
||||
|
||||
void CurvePanel::ZoomOut()
|
||||
{
|
||||
widget_->SetScale(widget_->GetScale() * 0.5);
|
||||
static_cast<CurveWidget*>(GetTimeBasedWidget())->SetInput(input);
|
||||
}
|
||||
|
||||
void CurvePanel::IncreaseTrackHeight()
|
||||
{
|
||||
widget_->SetVerticalScale(widget_->GetVerticalScale() * 2);
|
||||
CurveWidget* c = static_cast<CurveWidget*>(GetTimeBasedWidget());
|
||||
c->SetVerticalScale(c->GetVerticalScale() * 2);
|
||||
}
|
||||
|
||||
void CurvePanel::DecreaseTrackHeight()
|
||||
{
|
||||
widget_->SetVerticalScale(widget_->GetVerticalScale() * 0.5);
|
||||
}
|
||||
|
||||
void CurvePanel::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
PanelWidget::changeEvent(e);
|
||||
CurveWidget* c = static_cast<CurveWidget*>(GetTimeBasedWidget());
|
||||
c->SetVerticalScale(c->GetVerticalScale() * 0.5);
|
||||
}
|
||||
|
||||
void CurvePanel::Retranslate()
|
||||
{
|
||||
TimeBasedPanel::Retranslate();
|
||||
|
||||
SetTitle(tr("Curve Editor"));
|
||||
}
|
||||
|
||||
+3
-19
@@ -1,10 +1,10 @@
|
||||
#ifndef CURVEPANEL_H
|
||||
#define CURVEPANEL_H
|
||||
|
||||
#include "panel/timebased/timebased.h"
|
||||
#include "widget/curvewidget/curvewidget.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
class CurvePanel : public PanelWidget
|
||||
class CurvePanel : public TimeBasedPanel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -13,28 +13,12 @@ public:
|
||||
public slots:
|
||||
void SetInput(NodeInput* input);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
virtual void ZoomIn() override;
|
||||
|
||||
virtual void ZoomOut() override;
|
||||
|
||||
virtual void IncreaseTrackHeight() override;
|
||||
|
||||
virtual void DecreaseTrackHeight() override;
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& timestamp);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
CurveWidget* widget_;
|
||||
virtual void Retranslate() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -28,11 +28,8 @@ FootageViewerPanel::FootageViewerPanel(QWidget *parent) :
|
||||
// FIXME: This won't work if there's ever more than one of this panel
|
||||
setObjectName("FootageViewerPanel");
|
||||
|
||||
// QObject system handles deleting this
|
||||
viewer_ = new FootageViewerWidget(this);
|
||||
|
||||
// Set ViewerWidget as the central widget
|
||||
setWidget(viewer_);
|
||||
SetTimeBasedWidget(new FootageViewerWidget());
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
@@ -40,7 +37,7 @@ FootageViewerPanel::FootageViewerPanel(QWidget *parent) :
|
||||
|
||||
void FootageViewerPanel::SetFootage(Footage *f)
|
||||
{
|
||||
static_cast<FootageViewerWidget*>(viewer_)->SetFootage(f);
|
||||
static_cast<FootageViewerWidget*>(GetTimeBasedWidget())->SetFootage(f);
|
||||
|
||||
if (f) {
|
||||
SetSubtitle(f->name());
|
||||
@@ -49,19 +46,9 @@ void FootageViewerPanel::SetFootage(Footage *f)
|
||||
}
|
||||
}
|
||||
|
||||
void FootageViewerPanel::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
PanelWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
void FootageViewerPanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Footage Viewer"));
|
||||
ViewerPanelBase::Retranslate();
|
||||
|
||||
if (!static_cast<FootageViewerWidget*>(viewer_)->GetFootage()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
}
|
||||
SetTitle(tr("Footage Viewer"));
|
||||
}
|
||||
|
||||
@@ -36,10 +36,7 @@ public:
|
||||
void SetFootage(Footage* f);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
virtual void Retranslate() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
+10
-34
@@ -21,59 +21,35 @@
|
||||
#include "param.h"
|
||||
|
||||
ParamPanel::ParamPanel(QWidget* parent) :
|
||||
PanelWidget(parent)
|
||||
TimeBasedPanel(parent)
|
||||
{
|
||||
// FIXME: This won't work if there's ever more than one of this panel
|
||||
setObjectName("ParamPanel");
|
||||
|
||||
view_ = new NodeParamView(this);
|
||||
connect(view_, &NodeParamView::TimeChanged, this, &ParamPanel::TimeChanged);
|
||||
connect(view_, &NodeParamView::SelectedInputChanged, this, &ParamPanel::SelectedInputChanged);
|
||||
connect(view_, &NodeParamView::TimebaseChanged, this, &ParamPanel::TimebaseChanged);
|
||||
|
||||
setWidget(view_);
|
||||
NodeParamView* view = new NodeParamView();
|
||||
connect(view, &NodeParamView::SelectedInputChanged, this, &ParamPanel::SelectedInputChanged);
|
||||
SetTimeBasedWidget(view);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void ParamPanel::ZoomIn()
|
||||
{
|
||||
view_->SetScale(view_->GetScale() * 2);
|
||||
}
|
||||
|
||||
void ParamPanel::ZoomOut()
|
||||
{
|
||||
view_->SetScale(view_->GetScale() * 0.5);
|
||||
}
|
||||
|
||||
void ParamPanel::SetNodes(QList<Node *> nodes)
|
||||
{
|
||||
view_->SetNodes(nodes);
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->SetNodes(nodes);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void ParamPanel::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
view_->SetTime(timestamp);
|
||||
}
|
||||
|
||||
void ParamPanel::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
PanelWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
void ParamPanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Parameter Editor"));
|
||||
|
||||
if (view_->nodes().isEmpty()) {
|
||||
NodeParamView* view = static_cast<NodeParamView*>(GetTimeBasedWidget());
|
||||
|
||||
if (view->nodes().isEmpty()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
} else if (view_->nodes().size() == 1) {
|
||||
SetSubtitle(view_->nodes().first()->Name());
|
||||
} else if (view->nodes().size() == 1) {
|
||||
SetSubtitle(view->nodes().first()->Name());
|
||||
} else {
|
||||
SetSubtitle(tr("(multiple)"));
|
||||
}
|
||||
|
||||
+3
-17
@@ -21,38 +21,24 @@
|
||||
#ifndef PARAM_H
|
||||
#define PARAM_H
|
||||
|
||||
#include "panel/timebased/timebased.h"
|
||||
#include "widget/nodeparamview/nodeparamview.h"
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
class ParamPanel : public PanelWidget
|
||||
class ParamPanel : public TimeBasedPanel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ParamPanel(QWidget* parent);
|
||||
|
||||
virtual void ZoomIn() override;
|
||||
|
||||
virtual void ZoomOut() override;
|
||||
|
||||
public slots:
|
||||
void SetNodes(QList<Node*> nodes);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& timestamp);
|
||||
|
||||
void SelectedInputChanged(NodeInput* input);
|
||||
|
||||
void TimebaseChanged(const rational& timebase);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
NodeParamView* view_;
|
||||
};
|
||||
|
||||
#endif // PARAM_H
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
panel/timebased/timebased.h
|
||||
panel/timebased/timebased.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "timebased.h"
|
||||
|
||||
TimeBasedPanel::TimeBasedPanel(QWidget *parent) :
|
||||
PanelWidget(parent),
|
||||
widget_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
rational TimeBasedPanel::GetTime()
|
||||
{
|
||||
return widget_->GetTime();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::GoToStart()
|
||||
{
|
||||
widget_->GoToStart();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::PrevFrame()
|
||||
{
|
||||
widget_->PrevFrame();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::NextFrame()
|
||||
{
|
||||
widget_->NextFrame();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::GoToEnd()
|
||||
{
|
||||
widget_->GoToEnd();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ZoomIn()
|
||||
{
|
||||
widget_->ZoomIn();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ZoomOut()
|
||||
{
|
||||
widget_->ZoomOut();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::SetTimebase(const rational &timebase)
|
||||
{
|
||||
widget_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void TimeBasedPanel::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
widget_->SetTime(timestamp);
|
||||
}
|
||||
|
||||
void TimeBasedPanel::GoToPrevCut()
|
||||
{
|
||||
widget_->GoToPrevCut();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::GoToNextCut()
|
||||
{
|
||||
widget_->GoToNextCut();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::PlayPause()
|
||||
{
|
||||
emit PlayPauseRequested();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ShuttleLeft()
|
||||
{
|
||||
emit ShuttleLeftRequested();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ShuttleStop()
|
||||
{
|
||||
emit ShuttleStopRequested();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ShuttleRight()
|
||||
{
|
||||
emit ShuttleRightRequested();
|
||||
}
|
||||
|
||||
TimeBasedWidget *TimeBasedPanel::GetTimeBasedWidget() const
|
||||
{
|
||||
return widget_;
|
||||
}
|
||||
|
||||
ViewerOutput *TimeBasedPanel::GetConnectedViewer() const
|
||||
{
|
||||
return widget_->GetConnectedNode();
|
||||
}
|
||||
|
||||
void TimeBasedPanel::ConnectViewerNode(ViewerOutput *node)
|
||||
{
|
||||
if (widget_->GetConnectedNode()) {
|
||||
disconnect(widget_->GetConnectedNode(), &ViewerOutput::MediaNameChanged, this, &TimeBasedPanel::SetSubtitle);
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
widget_->ConnectViewerNode(node);
|
||||
|
||||
if (node) {
|
||||
connect(node, &ViewerOutput::MediaNameChanged, this, &TimeBasedPanel::SetSubtitle);
|
||||
SetSubtitle(node->media_name());
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedPanel::SetTimeBasedWidget(TimeBasedWidget *widget)
|
||||
{
|
||||
if (widget_) {
|
||||
disconnect(widget_, &TimeBasedWidget::TimeChanged, this, &TimeBasedPanel::TimeChanged);
|
||||
disconnect(widget_, &TimeBasedWidget::TimebaseChanged, this, &TimeBasedPanel::TimebaseChanged);
|
||||
}
|
||||
|
||||
widget_ = widget;
|
||||
|
||||
if (widget_) {
|
||||
connect(widget_, &TimeBasedWidget::TimeChanged, this, &TimeBasedPanel::TimeChanged);
|
||||
connect(widget_, &TimeBasedWidget::TimebaseChanged, this, &TimeBasedPanel::TimebaseChanged);
|
||||
}
|
||||
|
||||
setWidget(widget_);
|
||||
}
|
||||
|
||||
void TimeBasedPanel::Retranslate()
|
||||
{
|
||||
if (!GetTimeBasedWidget()->GetConnectedNode()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef TIMEBASEDPANEL_H
|
||||
#define TIMEBASEDPANEL_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
class TimeBasedPanel : public PanelWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TimeBasedPanel(QWidget *parent = nullptr);
|
||||
|
||||
void ConnectViewerNode(ViewerOutput* node);
|
||||
|
||||
void DisconnectViewerNode();
|
||||
|
||||
rational GetTime();
|
||||
|
||||
ViewerOutput* GetConnectedViewer() const;
|
||||
|
||||
virtual void ZoomIn() override;
|
||||
|
||||
virtual void ZoomOut() override;
|
||||
|
||||
virtual void GoToStart() override;
|
||||
|
||||
virtual void PrevFrame() override;
|
||||
|
||||
virtual void NextFrame() override;
|
||||
|
||||
virtual void GoToEnd() override;
|
||||
|
||||
virtual void GoToPrevCut() override;
|
||||
|
||||
virtual void GoToNextCut() override;
|
||||
|
||||
virtual void PlayPause() override;
|
||||
|
||||
virtual void ShuttleLeft() override;
|
||||
|
||||
virtual void ShuttleStop() override;
|
||||
|
||||
virtual void ShuttleRight() override;
|
||||
|
||||
public slots:
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& time);
|
||||
|
||||
void TimebaseChanged(const rational& timebase);
|
||||
|
||||
void PlayPauseRequested();
|
||||
|
||||
void ShuttleLeftRequested();
|
||||
|
||||
void ShuttleStopRequested();
|
||||
|
||||
void ShuttleRightRequested();
|
||||
|
||||
protected:
|
||||
TimeBasedWidget* GetTimeBasedWidget() const;
|
||||
|
||||
void SetTimeBasedWidget(TimeBasedWidget* widget);
|
||||
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private:
|
||||
TimeBasedWidget* widget_;
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMEBASEDPANEL_H
|
||||
@@ -21,137 +21,74 @@
|
||||
#include "timeline.h"
|
||||
|
||||
TimelinePanel::TimelinePanel(QWidget *parent) :
|
||||
PanelWidget(parent)
|
||||
TimeBasedPanel(parent)
|
||||
{
|
||||
// FIXME: This won't work if there's ever more than one of this panel
|
||||
setObjectName("TimelinePanel");
|
||||
|
||||
timeline_widget_ = new TimelineWidget();
|
||||
setWidget(timeline_widget_);
|
||||
|
||||
connect(timeline_widget_, SIGNAL(TimeChanged(const int64_t&)), this, SIGNAL(TimeChanged(const int64_t&)));
|
||||
SetTimeBasedWidget(new TimelineWidget());
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void TimelinePanel::Clear()
|
||||
{
|
||||
timeline_widget_->Clear();
|
||||
}
|
||||
|
||||
void TimelinePanel::SetTimebase(const rational &timebase)
|
||||
{
|
||||
timeline_widget_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void TimelinePanel::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
timeline_widget_->SetTime(timestamp);
|
||||
}
|
||||
|
||||
void TimelinePanel::ConnectTimelineNode(ViewerOutput *node)
|
||||
{
|
||||
if (timeline_widget_->GetConnectedNode()) {
|
||||
disconnect(timeline_widget_->GetConnectedNode(), &ViewerOutput::MediaNameChanged, this, &TimelinePanel::SetSubtitle);
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
timeline_widget_->ConnectTimelineNode(node);
|
||||
|
||||
if (node) {
|
||||
connect(node, &ViewerOutput::MediaNameChanged, this, &TimelinePanel::SetSubtitle);
|
||||
SetSubtitle(node->media_name());
|
||||
}
|
||||
}
|
||||
|
||||
void TimelinePanel::DisconnectTimelineNode()
|
||||
{
|
||||
timeline_widget_->DisconnectTimelineNode();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->Clear();
|
||||
}
|
||||
|
||||
void TimelinePanel::SplitAtPlayhead()
|
||||
{
|
||||
timeline_widget_->SplitAtPlayhead();
|
||||
}
|
||||
|
||||
void TimelinePanel::ZoomIn()
|
||||
{
|
||||
timeline_widget_->ZoomIn();
|
||||
}
|
||||
|
||||
void TimelinePanel::ZoomOut()
|
||||
{
|
||||
timeline_widget_->ZoomOut();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->SplitAtPlayhead();
|
||||
}
|
||||
|
||||
void TimelinePanel::SelectAll()
|
||||
{
|
||||
timeline_widget_->SelectAll();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->SelectAll();
|
||||
}
|
||||
|
||||
void TimelinePanel::DeselectAll()
|
||||
{
|
||||
timeline_widget_->DeselectAll();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->DeselectAll();
|
||||
}
|
||||
|
||||
void TimelinePanel::RippleToIn()
|
||||
{
|
||||
timeline_widget_->RippleToIn();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->RippleToIn();
|
||||
}
|
||||
|
||||
void TimelinePanel::RippleToOut()
|
||||
{
|
||||
timeline_widget_->RippleToOut();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->RippleToOut();
|
||||
}
|
||||
|
||||
void TimelinePanel::EditToIn()
|
||||
{
|
||||
timeline_widget_->EditToIn();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->EditToIn();
|
||||
}
|
||||
|
||||
void TimelinePanel::EditToOut()
|
||||
{
|
||||
timeline_widget_->EditToOut();
|
||||
}
|
||||
|
||||
void TimelinePanel::GoToPrevCut()
|
||||
{
|
||||
timeline_widget_->GoToPrevCut();
|
||||
}
|
||||
|
||||
void TimelinePanel::GoToNextCut()
|
||||
{
|
||||
timeline_widget_->GoToNextCut();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->EditToOut();
|
||||
}
|
||||
|
||||
void TimelinePanel::DeleteSelected()
|
||||
{
|
||||
timeline_widget_->DeleteSelected();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->DeleteSelected();
|
||||
}
|
||||
|
||||
void TimelinePanel::IncreaseTrackHeight()
|
||||
{
|
||||
timeline_widget_->IncreaseTrackHeight();
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->IncreaseTrackHeight();
|
||||
}
|
||||
|
||||
void TimelinePanel::DecreaseTrackHeight()
|
||||
{
|
||||
timeline_widget_->DecreaseTrackHeight();
|
||||
}
|
||||
|
||||
void TimelinePanel::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
PanelWidget::changeEvent(e);
|
||||
static_cast<TimelineWidget*>(GetTimeBasedWidget())->DecreaseTrackHeight();
|
||||
}
|
||||
|
||||
void TimelinePanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Timeline"));
|
||||
TimeBasedPanel::Retranslate();
|
||||
|
||||
if (!timeline_widget_->GetConnectedNode()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
}
|
||||
SetTitle(tr("Timeline"));
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@
|
||||
#ifndef TIMELINE_PANEL_H
|
||||
#define TIMELINE_PANEL_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
|
||||
#include "panel/timebased/timebased.h"
|
||||
#include "widget/timelinewidget/timelinewidget.h"
|
||||
|
||||
/**
|
||||
* @brief Panel container for a TimelineWidget
|
||||
*/
|
||||
class TimelinePanel : public PanelWidget
|
||||
class TimelinePanel : public TimeBasedPanel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -36,16 +35,8 @@ public:
|
||||
|
||||
void Clear();
|
||||
|
||||
void ConnectTimelineNode(ViewerOutput* node);
|
||||
|
||||
void DisconnectTimelineNode();
|
||||
|
||||
void SplitAtPlayhead();
|
||||
|
||||
virtual void ZoomIn() override;
|
||||
|
||||
virtual void ZoomOut() override;
|
||||
|
||||
virtual void SelectAll() override;
|
||||
|
||||
virtual void DeselectAll() override;
|
||||
@@ -58,31 +49,14 @@ public:
|
||||
|
||||
virtual void EditToOut() override;
|
||||
|
||||
virtual void GoToPrevCut() override;
|
||||
|
||||
virtual void GoToNextCut() override;
|
||||
|
||||
virtual void DeleteSelected() override;
|
||||
|
||||
virtual void IncreaseTrackHeight() override;
|
||||
|
||||
virtual void DecreaseTrackHeight() override;
|
||||
|
||||
public slots:
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& time);
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
TimelineWidget* timeline_widget_;
|
||||
virtual void Retranslate() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ protected:
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOL_PANEL_H
|
||||
|
||||
@@ -26,60 +26,16 @@ ViewerPanel::ViewerPanel(QWidget *parent) :
|
||||
// FIXME: This won't work if there's ever more than one of this panel
|
||||
setObjectName("ViewerPanel");
|
||||
|
||||
// QObject system handles deleting this
|
||||
viewer_ = new ViewerWidget(this);
|
||||
connect(viewer_, SIGNAL(TimeChanged(const int64_t&)), this, SIGNAL(TimeChanged(const int64_t&)));
|
||||
|
||||
// Set ViewerWidget as the central widget
|
||||
setWidget(viewer_);
|
||||
SetTimeBasedWidget(new ViewerWidget());
|
||||
|
||||
// Set strings
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void ViewerPanel::ConnectViewerNode(ViewerOutput *node)
|
||||
{
|
||||
if (viewer_->GetConnectedViewer()) {
|
||||
disconnect(viewer_->GetConnectedViewer(), &ViewerOutput::MediaNameChanged, this, &ViewerPanel::SetSubtitle);
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
viewer_->ConnectViewerNode(node);
|
||||
|
||||
if (node) {
|
||||
connect(node, &ViewerOutput::MediaNameChanged, this, &ViewerPanel::SetSubtitle);
|
||||
SetSubtitle(node->media_name());
|
||||
}
|
||||
}
|
||||
|
||||
rational ViewerPanel::GetTime()
|
||||
{
|
||||
return viewer_->GetTime();
|
||||
}
|
||||
|
||||
ViewerOutput *ViewerPanel::GetConnectedViewer() const
|
||||
{
|
||||
return viewer_->GetConnectedViewer();
|
||||
}
|
||||
|
||||
void ViewerPanel::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
viewer_->SetTime(timestamp);
|
||||
}
|
||||
|
||||
void ViewerPanel::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
PanelWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
void ViewerPanel::Retranslate()
|
||||
{
|
||||
SetTitle(tr("Viewer"));
|
||||
ViewerPanelBase::Retranslate();
|
||||
|
||||
if (!viewer_->GetConnectedViewer()) {
|
||||
SetSubtitle(tr("(none)"));
|
||||
}
|
||||
SetTitle(tr("Viewer"));
|
||||
}
|
||||
|
||||
@@ -33,23 +33,8 @@ class ViewerPanel : public ViewerPanelBase {
|
||||
public:
|
||||
ViewerPanel(QWidget* parent);
|
||||
|
||||
void ConnectViewerNode(ViewerOutput* node);
|
||||
|
||||
rational GetTime();
|
||||
|
||||
ViewerOutput* GetConnectedViewer() const;
|
||||
|
||||
public slots:
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t&);
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
virtual void Retranslate() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1,56 +1,34 @@
|
||||
#include "viewerbase.h"
|
||||
|
||||
ViewerPanelBase::ViewerPanelBase(QWidget *parent) :
|
||||
PanelWidget(parent)
|
||||
TimeBasedPanel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ZoomIn()
|
||||
{
|
||||
viewer_->SetScale(viewer_->scale() * 2);
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ZoomOut()
|
||||
{
|
||||
viewer_->SetScale(viewer_->scale() * 0.5);
|
||||
}
|
||||
|
||||
void ViewerPanelBase::GoToStart()
|
||||
{
|
||||
viewer_->GoToStart();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::PrevFrame()
|
||||
{
|
||||
viewer_->PrevFrame();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::PlayPause()
|
||||
{
|
||||
viewer_->TogglePlayPause();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::NextFrame()
|
||||
{
|
||||
viewer_->NextFrame();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::GoToEnd()
|
||||
{
|
||||
viewer_->GoToEnd();
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->TogglePlayPause();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ShuttleLeft()
|
||||
{
|
||||
viewer_->ShuttleLeft();
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->ShuttleLeft();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ShuttleStop()
|
||||
{
|
||||
viewer_->ShuttleStop();
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->ShuttleStop();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ShuttleRight()
|
||||
{
|
||||
viewer_->ShuttleRight();
|
||||
static_cast<ViewerWidget*>(GetTimeBasedWidget())->ShuttleRight();
|
||||
}
|
||||
|
||||
void ViewerPanelBase::ConnectTimeBasedPanel(TimeBasedPanel *panel)
|
||||
{
|
||||
connect(panel, &TimeBasedPanel::PlayPauseRequested, this, &ViewerPanelBase::PlayPause);
|
||||
connect(panel, &TimeBasedPanel::ShuttleLeftRequested, this, &ViewerPanelBase::ShuttleLeft);
|
||||
connect(panel, &TimeBasedPanel::ShuttleStopRequested, this, &ViewerPanelBase::ShuttleStop);
|
||||
connect(panel, &TimeBasedPanel::ShuttleRightRequested, this, &ViewerPanelBase::ShuttleRight);
|
||||
}
|
||||
|
||||
@@ -1,39 +1,24 @@
|
||||
#ifndef VIEWERPANELBASE_H
|
||||
#define VIEWERPANELBASE_H
|
||||
|
||||
#include "widget/panel/panel.h"
|
||||
#include "panel/timebased/timebased.h"
|
||||
#include "widget/viewer/viewer.h"
|
||||
|
||||
class ViewerPanelBase : public PanelWidget
|
||||
class ViewerPanelBase : public TimeBasedPanel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ViewerPanelBase(QWidget* parent = nullptr);
|
||||
|
||||
virtual void ZoomIn() override;
|
||||
|
||||
virtual void ZoomOut() override;
|
||||
|
||||
virtual void GoToStart() override;
|
||||
|
||||
virtual void PrevFrame() override;
|
||||
|
||||
virtual void PlayPause() override;
|
||||
|
||||
virtual void NextFrame() override;
|
||||
|
||||
virtual void GoToEnd() override;
|
||||
|
||||
virtual void ShuttleLeft() override;
|
||||
|
||||
virtual void ShuttleStop() override;
|
||||
|
||||
virtual void ShuttleRight() override;
|
||||
|
||||
protected:
|
||||
ViewerWidget* viewer_;
|
||||
|
||||
private:
|
||||
void ConnectTimeBasedPanel(TimeBasedPanel* panel);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ void Sequence::Open(Sequence* sequence)
|
||||
NodePanel* node_panel = PanelManager::instance()->MostRecentlyFocused<NodePanel>();
|
||||
|
||||
viewer_panel->ConnectViewerNode(sequence->viewer_output_);
|
||||
timeline_panel->ConnectTimelineNode(sequence->viewer_output_);
|
||||
timeline_panel->ConnectViewerNode(sequence->viewer_output_);
|
||||
node_panel->SetGraph(sequence);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ DiskManager::~DiskManager()
|
||||
ds << h.file_size;
|
||||
}
|
||||
} else {
|
||||
qWarning() << "Failed to write cache index";
|
||||
qWarning() << "Failed to write cache index:" << GetCacheIndexFilename();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,5 +196,7 @@ qint64 DiskManager::DiskLimit()
|
||||
|
||||
QString DiskManager::GetCacheIndexFilename()
|
||||
{
|
||||
return QDir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)).filePath("diskindex");
|
||||
QDir d(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
|
||||
d.mkpath(".");
|
||||
return d.filePath("diskindex");
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ add_subdirectory(projectexplorer)
|
||||
add_subdirectory(projecttoolbar)
|
||||
add_subdirectory(slider)
|
||||
add_subdirectory(taskview)
|
||||
add_subdirectory(timebased)
|
||||
add_subdirectory(timelinewidget)
|
||||
add_subdirectory(timeruler)
|
||||
add_subdirectory(toolbar)
|
||||
|
||||
@@ -53,7 +53,7 @@ void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
painter->setPen(QPen(palette().window().color(), 1));
|
||||
|
||||
do {
|
||||
x_grid_interval = qRound(x_interval * scale_ * timebase_dbl());
|
||||
x_grid_interval = qRound(x_interval * GetScale() * timebase_dbl());
|
||||
x_interval *= 2.0;
|
||||
} while (x_grid_interval < minimum_grid_space_);
|
||||
|
||||
@@ -70,7 +70,7 @@ void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
|
||||
// Add vertical lines
|
||||
for (int i=x_start;i<rect.right();i+=x_grid_interval) {
|
||||
int value = qRound(static_cast<double>(i) / scale_ / timebase_dbl());
|
||||
int value = qRound(static_cast<double>(i) / GetScale() / timebase_dbl());
|
||||
painter->drawText(i + text_padding_, qRound(scene_bottom_left.y()) - text_padding_, QString::number(value));
|
||||
lines.append(QLine(i, qRound(rect.top()), i, qRound(rect.bottom())));
|
||||
}
|
||||
@@ -183,7 +183,7 @@ void CurveView::KeyframeAboutToBeRemoved(NodeKeyframe *key)
|
||||
disconnect(key, &NodeKeyframe::TypeChanged, this, &CurveView::KeyframeTypeChanged);
|
||||
}
|
||||
|
||||
void CurveView::ScaleChangedEvent(double scale)
|
||||
void CurveView::ScaleChangedEvent(const double& scale)
|
||||
{
|
||||
KeyframeViewBase::ScaleChangedEvent(scale);
|
||||
|
||||
@@ -208,10 +208,10 @@ void CurveView::wheelEvent(QWheelEvent *event)
|
||||
if (WheelEventIsAZoomEvent(event)) {
|
||||
if (event->delta() != 0) {
|
||||
if (event->delta() > 0) {
|
||||
emit ScaleChanged(scale_ * 1.1);
|
||||
emit ScaleChanged(GetScale() * 1.1);
|
||||
SetYScale(y_scale_ * 1.1);
|
||||
} else {
|
||||
emit ScaleChanged(scale_ * 0.9);
|
||||
emit ScaleChanged(GetScale() * 0.9);
|
||||
SetYScale(y_scale_ * 0.9);
|
||||
}
|
||||
}
|
||||
@@ -259,18 +259,18 @@ void CurveView::SetItemYFromKeyframeValue(NodeKeyframe *key, KeyframeViewItem *i
|
||||
QPointF CurveView::ScalePoint(const QPointF &point)
|
||||
{
|
||||
// Flips Y coordinate because curves are drawn bottom to top
|
||||
return QPointF(point.x() * scale_, - point.y() * y_scale_);
|
||||
return QPointF(point.x() * GetScale(), - point.y() * y_scale_);
|
||||
}
|
||||
|
||||
void CurveView::CreateBezierControlPoints(KeyframeViewItem* item)
|
||||
{
|
||||
BezierControlPointItem* bezier_in_pt = new BezierControlPointItem(item->key(), NodeKeyframe::kInHandle, item);
|
||||
bezier_in_pt->SetXScale(scale_);
|
||||
bezier_in_pt->SetXScale(GetScale());
|
||||
bezier_control_points_.append(bezier_in_pt);
|
||||
connect(bezier_in_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
|
||||
|
||||
BezierControlPointItem* bezier_out_pt = new BezierControlPointItem(item->key(), NodeKeyframe::kOutHandle, item);
|
||||
bezier_out_pt->SetXScale(scale_);
|
||||
bezier_out_pt->SetXScale(GetScale());
|
||||
bezier_control_points_.append(bezier_out_pt);
|
||||
connect(bezier_out_pt, &QObject::destroyed, this, &CurveView::BezierControlPointDestroyed, Qt::DirectConnection);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ protected:
|
||||
|
||||
virtual void KeyframeAboutToBeRemoved(NodeKeyframe *key) override;
|
||||
|
||||
virtual void ScaleChangedEvent(double scale) override;
|
||||
virtual void ScaleChangedEvent(const double &scale) override;
|
||||
|
||||
virtual void VerticalScaleChangedEvent(double scale) override;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "widget/keyframeview/keyframeviewundo.h"
|
||||
|
||||
CurveWidget::CurveWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
TimeBasedWidget(parent),
|
||||
input_(nullptr),
|
||||
bridge_(nullptr)
|
||||
{
|
||||
@@ -51,8 +51,7 @@ CurveWidget::CurveWidget(QWidget *parent) :
|
||||
ruler_view_layout->setMargin(0);
|
||||
ruler_view_layout->setSpacing(0);
|
||||
|
||||
ruler_ = new TimeRuler();
|
||||
ruler_view_layout->addWidget(ruler_);
|
||||
ruler_view_layout->addWidget(ruler());
|
||||
|
||||
view_ = new CurveView();
|
||||
ruler_view_layout->addWidget(view_);
|
||||
@@ -60,15 +59,10 @@ CurveWidget::CurveWidget(QWidget *parent) :
|
||||
layout->addLayout(ruler_view_layout);
|
||||
|
||||
// Connect ruler and view together
|
||||
connect(ruler_, &TimeRuler::TimeChanged, view_, &CurveView::SetTime);
|
||||
connect(view_, &CurveView::TimeChanged, ruler_, &TimeRuler::SetTime);
|
||||
connect(ruler_, &TimeRuler::TimeChanged, this, &CurveWidget::TimeChanged);
|
||||
connect(view_, &CurveView::TimeChanged, this, &CurveWidget::TimeChanged);
|
||||
connect(ruler_, &TimeRuler::TimeChanged, this, &CurveWidget::UpdateBridgeTime);
|
||||
connect(view_, &CurveView::TimeChanged, this, &CurveWidget::UpdateBridgeTime);
|
||||
connect(view_, &CurveView::TimeChanged, this, &CurveWidget::SetTimeAndSignal);
|
||||
connect(view_->scene(), &QGraphicsScene::selectionChanged, this, &CurveWidget::SelectionChanged);
|
||||
connect(view_, &CurveView::ScaleChanged, this, &CurveWidget::SetScale);
|
||||
connect(view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler_, &TimeRuler::SetScroll);
|
||||
connect(view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
|
||||
widget_bridge_layout_ = new QHBoxLayout();
|
||||
widget_bridge_layout_->addStretch();
|
||||
@@ -127,32 +121,6 @@ void CurveWidget::SetInput(NodeInput *input)
|
||||
UpdateInputLabel();
|
||||
}
|
||||
|
||||
void CurveWidget::SetTimebase(const rational &timebase)
|
||||
{
|
||||
ruler_->SetTimebase(timebase);
|
||||
view_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void CurveWidget::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
ruler_->SetTime(timestamp);
|
||||
view_->SetTime(timestamp);
|
||||
UpdateBridgeTime(timestamp);
|
||||
}
|
||||
|
||||
const double &CurveWidget::GetScale()
|
||||
{
|
||||
return ruler_->scale();
|
||||
}
|
||||
|
||||
void CurveWidget::SetScale(double scale)
|
||||
{
|
||||
scale = qMin(scale, TimelineViewBase::kMaximumScale);
|
||||
|
||||
ruler_->SetScale(scale);
|
||||
view_->SetScale(scale, true);
|
||||
}
|
||||
|
||||
const double &CurveWidget::GetVerticalScale()
|
||||
{
|
||||
return view_->GetYScale();
|
||||
@@ -171,6 +139,28 @@ void CurveWidget::changeEvent(QEvent *e)
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
void CurveWidget::TimeChangedEvent(const int64_t ×tamp)
|
||||
{
|
||||
TimeBasedWidget::TimeChangedEvent(timestamp);
|
||||
|
||||
view_->SetTime(timestamp);
|
||||
UpdateBridgeTime(timestamp);
|
||||
}
|
||||
|
||||
void CurveWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
TimeBasedWidget::TimebaseChangedEvent(timebase);
|
||||
|
||||
view_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void CurveWidget::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
TimeBasedWidget::ScaleChangedEvent(scale);
|
||||
|
||||
view_->SetScaleAndCenterOnPlayhead(scale);
|
||||
}
|
||||
|
||||
void CurveWidget::UpdateInputLabel()
|
||||
{
|
||||
if (input_) {
|
||||
@@ -283,9 +273,5 @@ void CurveWidget::KeyframeTypeButtonTriggered(bool checked)
|
||||
|
||||
void CurveWidget::KeyControlRequestedTimeChanged(const rational &time)
|
||||
{
|
||||
int64_t timestamp = Timecode::time_to_timestamp(time, view_->timebase());
|
||||
|
||||
SetTime(timestamp);
|
||||
|
||||
emit TimeChanged(timestamp);
|
||||
SetTimeAndSignal(Timecode::time_to_timestamp(time, view_->timebase()));
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
#include "node/input.h"
|
||||
#include "widget/nodeparamview/nodeparamviewkeyframecontrol.h"
|
||||
#include "widget/nodeparamview/nodeparamviewwidgetbridge.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
class CurveWidget : public QWidget
|
||||
class CurveWidget : public TimeBasedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -21,24 +21,16 @@ public:
|
||||
|
||||
void SetInput(NodeInput* input);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
const double& GetScale();
|
||||
|
||||
const double& GetVerticalScale();
|
||||
void SetVerticalScale(const double& vscale);
|
||||
|
||||
public slots:
|
||||
void SetScale(double scale);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& timestamp);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *) override;
|
||||
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
virtual void TimebaseChangedEvent(const rational &) override;
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
|
||||
private:
|
||||
void UpdateInputLabel();
|
||||
|
||||
@@ -48,14 +40,14 @@ private:
|
||||
|
||||
void SetKeyframeButtonCheckedFromType(NodeKeyframe::Type type);
|
||||
|
||||
void UpdateBridgeTime(const int64_t& timestamp);
|
||||
|
||||
QPushButton* linear_button_;
|
||||
|
||||
QPushButton* bezier_button_;
|
||||
|
||||
QPushButton* hold_button_;
|
||||
|
||||
TimeRuler* ruler_;
|
||||
|
||||
CurveView* view_;
|
||||
|
||||
NodeInput* input_;
|
||||
@@ -69,8 +61,6 @@ private:
|
||||
NodeParamViewKeyframeControl* key_control_;
|
||||
|
||||
private slots:
|
||||
void UpdateBridgeTime(const int64_t& timestamp);
|
||||
|
||||
void SelectionChanged();
|
||||
|
||||
void KeyframeTypeButtonTriggered(bool checked);
|
||||
|
||||
@@ -59,7 +59,7 @@ void KeyframeViewBase::RemoveKeyframe(NodeKeyframePtr key)
|
||||
KeyframeViewItem *KeyframeViewBase::AddKeyframeInternal(NodeKeyframePtr key)
|
||||
{
|
||||
KeyframeViewItem* item = new KeyframeViewItem(key);
|
||||
item->SetScale(scale_);
|
||||
item->SetScale(GetScale());
|
||||
item_map_.insert(key.get(), item);
|
||||
scene()->addItem(item);
|
||||
return item;
|
||||
@@ -210,8 +210,10 @@ void KeyframeViewBase::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeViewBase::ScaleChangedEvent(double scale)
|
||||
void KeyframeViewBase::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
TimelineViewBase::ScaleChangedEvent(scale);
|
||||
|
||||
QMap<NodeKeyframe*, KeyframeViewItem*>::const_iterator iterator;
|
||||
|
||||
for (iterator=item_map_.begin();iterator!=item_map_.end();iterator++) {
|
||||
@@ -333,7 +335,7 @@ void KeyframeViewBase::ProcessBezierDrag(QPointF mouse_diff_scaled, bool include
|
||||
|
||||
QPointF KeyframeViewBase::GetScaledCursorPos(const QPoint &cursor_pos)
|
||||
{
|
||||
return QPointF(static_cast<double>(cursor_pos.x()) / scale_,
|
||||
return QPointF(static_cast<double>(cursor_pos.x()) / GetScale(),
|
||||
static_cast<double>(cursor_pos.y()) / y_scale_);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ protected:
|
||||
virtual void mouseMoveEvent(QMouseEvent *event) override;
|
||||
virtual void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
virtual void ScaleChangedEvent(double scale) override;
|
||||
virtual void ScaleChangedEvent(const double& scale) override;
|
||||
|
||||
virtual void VerticalScaleChangedEvent(double scale);
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "node/output/viewer/viewer.h"
|
||||
|
||||
NodeParamView::NodeParamView(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
TimeBasedWidget(true, false, parent),
|
||||
last_scroll_val_(0)
|
||||
{
|
||||
// Create horizontal layout to place scroll area in (and keyframe editing eventually)
|
||||
@@ -64,8 +64,7 @@ NodeParamView::NodeParamView(QWidget *parent) :
|
||||
keyframe_area_layout->setMargin(0);
|
||||
|
||||
// Create ruler object
|
||||
ruler_ = new TimeRuler(true);
|
||||
keyframe_area_layout->addWidget(ruler_);
|
||||
keyframe_area_layout->addWidget(ruler());
|
||||
|
||||
// Create keyframe view
|
||||
keyframe_view_ = new KeyframeView();
|
||||
@@ -74,10 +73,9 @@ NodeParamView::NodeParamView(QWidget *parent) :
|
||||
keyframe_area_layout->addWidget(keyframe_view_);
|
||||
|
||||
// Connect ruler and keyframe view together
|
||||
connect(ruler_, &TimeRuler::TimeChanged, keyframe_view_, &KeyframeView::SetTime);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, ruler_, &TimeRuler::SetTime);
|
||||
connect(ruler_, &TimeRuler::TimeChanged, this, &NodeParamView::RulerTimeChanged);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, this, &NodeParamView::RulerTimeChanged);
|
||||
connect(ruler(), &TimeRuler::TimeChanged, keyframe_view_, &KeyframeView::SetTime);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, ruler(), &TimeRuler::SetTime);
|
||||
connect(keyframe_view_, &KeyframeView::TimeChanged, this, &NodeParamView::SetTime);
|
||||
|
||||
// Connect keyframe view scaling to this
|
||||
connect(keyframe_view_, &KeyframeView::ScaleChanged, this, &NodeParamView::SetScale);
|
||||
@@ -106,10 +104,12 @@ NodeParamView::NodeParamView(QWidget *parent) :
|
||||
connect(vertical_scrollbar_, &QScrollBar::valueChanged, scroll_area->verticalScrollBar(), &QScrollBar::setValue);
|
||||
connect(vertical_scrollbar_, &QScrollBar::valueChanged, keyframe_view_->verticalScrollBar(), &QScrollBar::setValue);
|
||||
|
||||
connect(keyframe_view_->horizontalScrollBar(), SIGNAL(valueChanged(int)), ruler_, SLOT(SetScroll(int)));
|
||||
connect(keyframe_view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
|
||||
// Set a default scale - FIXME: Hardcoded
|
||||
SetScale(120);
|
||||
|
||||
SetMaximumScale(TimelineViewBase::kMaximumScale);
|
||||
}
|
||||
|
||||
void NodeParamView::SetNodes(QList<Node *> nodes)
|
||||
@@ -169,38 +169,32 @@ void NodeParamView::resizeEvent(QResizeEvent *event)
|
||||
vertical_scrollbar_->setPageStep(vertical_scrollbar_->height());
|
||||
}
|
||||
|
||||
const QList<Node *> &NodeParamView::nodes()
|
||||
void NodeParamView::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
return nodes_;
|
||||
TimeBasedWidget::ScaleChangedEvent(scale);
|
||||
|
||||
keyframe_view_->SetScaleAndCenterOnPlayhead(scale);
|
||||
}
|
||||
|
||||
const double &NodeParamView::GetScale() const
|
||||
void NodeParamView::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
return ruler_->scale();
|
||||
TimeBasedWidget::TimebaseChangedEvent(timebase);
|
||||
|
||||
keyframe_view_->SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void NodeParamView::SetScale(double scale)
|
||||
void NodeParamView::TimeChangedEvent(const int64_t ×tamp)
|
||||
{
|
||||
scale = qMin(scale, TimelineViewBase::kMaximumScale);
|
||||
TimeBasedWidget::TimeChangedEvent(timestamp);
|
||||
|
||||
ruler_->SetScale(scale);
|
||||
keyframe_view_->SetScale(scale, true);
|
||||
}
|
||||
|
||||
void NodeParamView::SetTime(const int64_t ×tamp)
|
||||
{
|
||||
ruler_->SetTime(timestamp);
|
||||
keyframe_view_->SetTime(timestamp);
|
||||
|
||||
UpdateItemTime(timestamp);
|
||||
}
|
||||
|
||||
void NodeParamView::SetTimebase(const rational &timebase)
|
||||
const QList<Node *> &NodeParamView::nodes()
|
||||
{
|
||||
ruler_->SetTimebase(timebase);
|
||||
keyframe_view_->SetTimebase(timebase);
|
||||
|
||||
emit TimebaseChanged(timebase);
|
||||
return nodes_;
|
||||
}
|
||||
|
||||
void NodeParamView::UpdateItemTime(const int64_t ×tamp)
|
||||
@@ -212,18 +206,9 @@ void NodeParamView::UpdateItemTime(const int64_t ×tamp)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeParamView::RulerTimeChanged(const int64_t ×tamp)
|
||||
{
|
||||
UpdateItemTime(timestamp);
|
||||
|
||||
emit TimeChanged(timestamp);
|
||||
}
|
||||
|
||||
void NodeParamView::ItemRequestedTimeChanged(const rational &time)
|
||||
{
|
||||
int64_t timestamp = Timecode::time_to_timestamp(time, keyframe_view_->timebase());
|
||||
SetTime(timestamp);
|
||||
emit TimeChanged(timestamp);
|
||||
SetTimeAndSignal(Timecode::time_to_timestamp(time, keyframe_view_->timebase()));
|
||||
}
|
||||
|
||||
void NodeParamView::ForceKeyframeViewToScroll(int min, int max)
|
||||
|
||||
@@ -27,45 +27,34 @@
|
||||
#include "node/node.h"
|
||||
#include "nodeparamviewitem.h"
|
||||
#include "widget/keyframeview/keyframeview.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
class NodeParamView : public QWidget
|
||||
class NodeParamView : public TimeBasedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeParamView(QWidget* parent);
|
||||
NodeParamView(QWidget* parent = nullptr);
|
||||
|
||||
void SetNodes(QList<Node*> nodes);
|
||||
const QList<Node*>& nodes();
|
||||
|
||||
const double& GetScale() const;
|
||||
|
||||
public slots:
|
||||
void SetScale(double scale);
|
||||
|
||||
void SetTime(const int64_t& timestamp);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& timestamp);
|
||||
|
||||
void SelectedInputChanged(NodeInput* input);
|
||||
|
||||
void TimebaseChanged(const rational& timebase);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
void SetTimebase(const rational& timebase);
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
virtual void TimebaseChangedEvent(const rational&) override;
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
|
||||
private:
|
||||
void UpdateItemTime(const int64_t ×tamp);
|
||||
|
||||
QVBoxLayout* param_layout_;
|
||||
|
||||
KeyframeView* keyframe_view_;
|
||||
|
||||
TimeRuler* ruler_;
|
||||
|
||||
QList<Node*> nodes_;
|
||||
|
||||
QList<NodeParamViewItem*> items_;
|
||||
@@ -77,8 +66,6 @@ private:
|
||||
int last_scroll_val_;
|
||||
|
||||
private slots:
|
||||
void RulerTimeChanged(const int64_t& timestamp);
|
||||
|
||||
void ItemRequestedTimeChanged(const rational& time);
|
||||
|
||||
void ForceKeyframeViewToScroll(int min, int max);
|
||||
|
||||
@@ -101,3 +101,15 @@ void PanelWidget::UpdateTitle()
|
||||
setWindowTitle(tr("%1: %2").arg(title_, subtitle_));
|
||||
}
|
||||
}
|
||||
|
||||
void PanelWidget::changeEvent(QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
QDockWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
void PanelWidget::Retranslate()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -119,6 +119,9 @@ protected:
|
||||
*/
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
virtual void Retranslate();
|
||||
|
||||
protected slots:
|
||||
/**
|
||||
|
||||
@@ -49,7 +49,8 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
lower_left_layout->setSpacing(0);
|
||||
lower_left_layout->setMargin(0);
|
||||
|
||||
cur_tc_lbl_ = new QLabel();
|
||||
cur_tc_lbl_ = new TimeSlider();
|
||||
connect(cur_tc_lbl_, &TimeSlider::ValueChanged, this, &PlaybackControls::TimeChanged);
|
||||
lower_left_layout->addWidget(cur_tc_lbl_);
|
||||
lower_left_layout->addStretch();
|
||||
|
||||
@@ -67,12 +68,12 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
// Go To Start Button
|
||||
go_to_start_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(go_to_start_btn_);
|
||||
connect(go_to_start_btn_, SIGNAL(clicked(bool)), this, SIGNAL(BeginClicked()));
|
||||
connect(go_to_start_btn_, &QPushButton::clicked, this, &PlaybackControls::BeginClicked);
|
||||
|
||||
// Prev Frame Button
|
||||
prev_frame_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(prev_frame_btn_);
|
||||
connect(prev_frame_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PrevFrameClicked()));
|
||||
connect(prev_frame_btn_, &QPushButton::clicked, this, &PlaybackControls::PrevFrameClicked);
|
||||
|
||||
// Play/Pause Button
|
||||
playpause_stack_ = new QStackedWidget();
|
||||
@@ -80,11 +81,11 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
|
||||
play_btn_ = new QPushButton();
|
||||
playpause_stack_->addWidget(play_btn_);
|
||||
connect(play_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PlayClicked()));
|
||||
connect(play_btn_, &QPushButton::clicked, this, &PlaybackControls::PlayClicked);
|
||||
|
||||
pause_btn_ = new QPushButton();
|
||||
playpause_stack_->addWidget(pause_btn_);
|
||||
connect(pause_btn_, SIGNAL(clicked(bool)), this, SIGNAL(PauseClicked()));
|
||||
connect(pause_btn_, &QPushButton::clicked, this, &PlaybackControls::PauseClicked);
|
||||
|
||||
// Default to showing play button
|
||||
playpause_stack_->setCurrentWidget(play_btn_);
|
||||
@@ -93,12 +94,12 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
// Next Frame Button
|
||||
next_frame_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(next_frame_btn_);
|
||||
connect(next_frame_btn_, SIGNAL(clicked(bool)), this, SIGNAL(NextFrameClicked()));
|
||||
connect(next_frame_btn_, &QPushButton::clicked, this, &PlaybackControls::NextFrameClicked);
|
||||
|
||||
// Go To End Button
|
||||
go_to_end_btn_ = new QPushButton();
|
||||
lower_middle_layout->addWidget(go_to_end_btn_);
|
||||
connect(go_to_end_btn_, SIGNAL(clicked(bool)), this, SIGNAL(EndClicked()));
|
||||
connect(go_to_end_btn_, &QPushButton::clicked, this, &PlaybackControls::EndClicked);
|
||||
|
||||
lower_middle_layout->addStretch();
|
||||
|
||||
@@ -117,6 +118,8 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
|
||||
lower_right_layout->addWidget(end_tc_lbl_);
|
||||
|
||||
UpdateIcons();
|
||||
|
||||
SetTimebase(0);
|
||||
}
|
||||
|
||||
void PlaybackControls::SetTimecodeEnabled(bool enabled)
|
||||
@@ -128,16 +131,25 @@ void PlaybackControls::SetTimecodeEnabled(bool enabled)
|
||||
void PlaybackControls::SetTimebase(const rational &r)
|
||||
{
|
||||
time_base_ = r;
|
||||
cur_tc_lbl_->SetTimebase(r);
|
||||
|
||||
cur_tc_lbl_->setEnabled(!r.isNull());
|
||||
}
|
||||
|
||||
void PlaybackControls::SetTime(const int64_t &r)
|
||||
{
|
||||
SetTimeLabelInternal(cur_tc_lbl_, r);
|
||||
cur_tc_lbl_->SetValue(r);
|
||||
}
|
||||
|
||||
void PlaybackControls::SetEndTime(const int64_t &r)
|
||||
{
|
||||
SetTimeLabelInternal(end_tc_lbl_, r);
|
||||
if (time_base_.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
end_tc_lbl_->setText(Timecode::timestamp_to_timecode(r,
|
||||
time_base_,
|
||||
Timecode::CurrentDisplay()));
|
||||
}
|
||||
|
||||
void PlaybackControls::ShowPauseButton()
|
||||
@@ -169,14 +181,3 @@ void PlaybackControls::UpdateIcons()
|
||||
next_frame_btn_->setIcon(icon::NextFrame);
|
||||
go_to_end_btn_->setIcon(icon::GoToEnd);
|
||||
}
|
||||
|
||||
void PlaybackControls::SetTimeLabelInternal(QLabel* label, const int64_t& time)
|
||||
{
|
||||
if (time_base_.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
label->setText(Timecode::timestamp_to_timecode(time,
|
||||
time_base_,
|
||||
Timecode::CurrentDisplay()));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <QStackedWidget>
|
||||
|
||||
#include "common/rational.h"
|
||||
#include "widget/slider/timeslider.h"
|
||||
|
||||
/**
|
||||
* @brief A playback controls widget providing buttons for navigating media
|
||||
@@ -86,18 +87,18 @@ signals:
|
||||
*/
|
||||
void EndClicked();
|
||||
|
||||
void TimeChanged(const int64_t& t);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *) override;
|
||||
|
||||
private:
|
||||
void UpdateIcons();
|
||||
|
||||
void SetTimeLabelInternal(QLabel *label, const int64_t &time);
|
||||
|
||||
QWidget* lower_left_container_;
|
||||
QWidget* lower_right_container_;
|
||||
|
||||
QLabel* cur_tc_lbl_;
|
||||
TimeSlider* cur_tc_lbl_;
|
||||
QLabel* end_tc_lbl_;
|
||||
|
||||
rational time_base_;
|
||||
|
||||
@@ -149,10 +149,10 @@ double FloatSlider::AdjustDragDistanceInternal(const double &start, const double
|
||||
current_db += drag;
|
||||
qreal adjusted_linear = QAudio::convertVolume(current_db, QAudio::DecibelVolumeScale, QAudio::LinearVolumeScale);
|
||||
|
||||
return adjusted_linear - start;
|
||||
return adjusted_linear;
|
||||
}
|
||||
case kPercentage:
|
||||
return drag * 0.01;
|
||||
return SliderBase::AdjustDragDistanceInternal(start, drag * 0.01);
|
||||
}
|
||||
|
||||
return SliderBase::AdjustDragDistanceInternal(start, drag);
|
||||
|
||||
@@ -26,9 +26,9 @@ IntegerSlider::IntegerSlider(QWidget* parent) :
|
||||
connect(this, SIGNAL(ValueChanged(QVariant)), this, SLOT(ConvertValue(QVariant)));
|
||||
}
|
||||
|
||||
int IntegerSlider::GetValue()
|
||||
int64_t IntegerSlider::GetValue()
|
||||
{
|
||||
return Value().toInt();
|
||||
return Value().toLongLong();
|
||||
}
|
||||
|
||||
void IntegerSlider::SetValue(const int64_t &v)
|
||||
|
||||
@@ -29,7 +29,7 @@ class IntegerSlider : public SliderBase
|
||||
public:
|
||||
IntegerSlider(QWidget* parent = nullptr);
|
||||
|
||||
int GetValue();
|
||||
int64_t GetValue();
|
||||
|
||||
void SetValue(const int64_t& v);
|
||||
|
||||
|
||||
@@ -119,6 +119,10 @@ const QVariant &SliderBase::Value()
|
||||
|
||||
void SliderBase::SetValue(const QVariant &v)
|
||||
{
|
||||
if (IsDragging()) {
|
||||
return;
|
||||
}
|
||||
|
||||
value_ = ClampValue(v);
|
||||
|
||||
// Disable tristate
|
||||
@@ -185,8 +189,7 @@ void SliderBase::UpdateLabel(const QVariant &v)
|
||||
|
||||
double SliderBase::AdjustDragDistanceInternal(const double &start, const double &drag)
|
||||
{
|
||||
Q_UNUSED(start)
|
||||
return drag;
|
||||
return start + drag;
|
||||
}
|
||||
|
||||
QString SliderBase::ValueToString(const QVariant &v)
|
||||
@@ -203,16 +206,13 @@ QVariant SliderBase::StringToValue(const QString &s, bool *ok)
|
||||
void SliderBase::LabelPressed()
|
||||
{
|
||||
dragged_ = false;
|
||||
|
||||
if (mode_ != kString) {
|
||||
dragged_diff_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SliderBase::LabelClicked()
|
||||
{
|
||||
if (dragged_) {
|
||||
double drag_val = value_.toDouble() + AdjustDragDistanceInternal(value_.toDouble(), dragged_diff_);
|
||||
dragged_ = false;
|
||||
|
||||
// This was a drag
|
||||
switch (mode_) {
|
||||
@@ -220,14 +220,13 @@ void SliderBase::LabelClicked()
|
||||
// No-op
|
||||
break;
|
||||
case kInteger:
|
||||
SetValue(qRound(drag_val));
|
||||
SetValue(temp_dragged_value_.toInt());
|
||||
break;
|
||||
case kFloat:
|
||||
SetValue(drag_val);
|
||||
SetValue(temp_dragged_value_.toDouble());
|
||||
break;
|
||||
}
|
||||
|
||||
dragged_ = false;
|
||||
emit ValueChanged(value_);
|
||||
} else {
|
||||
// This was a simple click
|
||||
@@ -255,11 +254,9 @@ void SliderBase::LabelDragged(int i)
|
||||
case kInteger:
|
||||
case kFloat:
|
||||
{
|
||||
double real_drag = static_cast<double>(i) * drag_multiplier_;
|
||||
dragged_diff_ += static_cast<double>(i) * drag_multiplier_;
|
||||
|
||||
dragged_diff_ += real_drag;
|
||||
|
||||
double drag_val = value_.toDouble() + AdjustDragDistanceInternal(value_.toDouble(), dragged_diff_);
|
||||
double drag_val = AdjustDragDistanceInternal(value_.toDouble(), dragged_diff_);
|
||||
|
||||
// Update temporary value
|
||||
if (mode_ == kInteger) {
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/timebased/timebased.h
|
||||
widget/timebased/timebased.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,201 @@
|
||||
#include "timebased.h"
|
||||
|
||||
#include "common/timecodefunctions.h"
|
||||
|
||||
TimeBasedWidget::TimeBasedWidget(bool ruler_text_visible, bool ruler_cache_status_visible, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
viewer_node_(nullptr)
|
||||
{
|
||||
ruler_ = new TimeRuler(ruler_text_visible, ruler_cache_status_visible, this);
|
||||
connect(ruler_, &TimeRuler::TimeChanged, this, &TimeBasedWidget::SetTimeAndSignal);
|
||||
|
||||
scrollbar_ = new QScrollBar(Qt::Horizontal, this);
|
||||
}
|
||||
|
||||
rational TimeBasedWidget::GetTime() const
|
||||
{
|
||||
return Timecode::timestamp_to_time(ruler()->GetTime(), timebase());
|
||||
}
|
||||
|
||||
const int64_t &TimeBasedWidget::GetTimestamp() const
|
||||
{
|
||||
return ruler_->GetTime();
|
||||
}
|
||||
|
||||
ViewerOutput *TimeBasedWidget::GetConnectedNode() const
|
||||
{
|
||||
return viewer_node_;
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ConnectViewerNode(ViewerOutput *node)
|
||||
{
|
||||
if (viewer_node_) {
|
||||
DisconnectNodeInternal(viewer_node_);
|
||||
}
|
||||
|
||||
viewer_node_ = node;
|
||||
|
||||
ConnectedNodeChanged(viewer_node_);
|
||||
|
||||
if (viewer_node_) {
|
||||
ConnectNodeInternal(viewer_node_);
|
||||
}
|
||||
}
|
||||
|
||||
TimeRuler *TimeBasedWidget::ruler() const
|
||||
{
|
||||
return ruler_;
|
||||
}
|
||||
|
||||
QScrollBar *TimeBasedWidget::scrollbar() const
|
||||
{
|
||||
return scrollbar_;
|
||||
}
|
||||
|
||||
void TimeBasedWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
TimelineScaledObject::TimebaseChangedEvent(timebase);
|
||||
|
||||
ruler_->SetTimebase(timebase);
|
||||
|
||||
emit TimebaseChanged(timebase);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
TimelineScaledObject::ScaleChangedEvent(scale);
|
||||
|
||||
ruler_->SetScale(scale);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
|
||||
// Update horizontal scrollbar's page step to the width of the panel
|
||||
scrollbar()->setPageStep(scrollbar()->width());
|
||||
}
|
||||
|
||||
void TimeBasedWidget::SetTime(int64_t timestamp)
|
||||
{
|
||||
ruler_->SetTime(timestamp);
|
||||
|
||||
TimeChangedEvent(timestamp);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::SetTimebase(const rational &timebase)
|
||||
{
|
||||
TimelineScaledObject::SetTimebase(timebase);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::SetScale(const double &scale)
|
||||
{
|
||||
TimelineScaledObject::SetScale(scale);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ZoomIn()
|
||||
{
|
||||
SetScale(GetScale() * 2);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::ZoomOut()
|
||||
{
|
||||
SetScale(GetScale() * 0.5);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::GoToPrevCut()
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetTimestamp() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t closest_cut = 0;
|
||||
|
||||
foreach (TrackOutput* track, viewer_node_->Tracks()) {
|
||||
int64_t this_track_closest_cut = 0;
|
||||
|
||||
foreach (Block* block, track->Blocks()) {
|
||||
int64_t block_out_ts = Timecode::time_to_timestamp(block->out(), timebase());
|
||||
|
||||
if (block_out_ts < GetTimestamp()) {
|
||||
this_track_closest_cut = block_out_ts;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closest_cut = qMax(closest_cut, this_track_closest_cut);
|
||||
}
|
||||
|
||||
SetTimeAndSignal(closest_cut);
|
||||
}
|
||||
|
||||
void TimeBasedWidget::GoToNextCut()
|
||||
{
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t closest_cut = INT64_MAX;
|
||||
|
||||
foreach (TrackOutput* track, GetConnectedNode()->Tracks()) {
|
||||
int64_t this_track_closest_cut = Timecode::time_to_timestamp(track->track_length(), timebase());
|
||||
|
||||
if (this_track_closest_cut <= GetTimestamp()) {
|
||||
this_track_closest_cut = INT64_MAX;
|
||||
}
|
||||
|
||||
foreach (Block* block, track->Blocks()) {
|
||||
int64_t block_in_ts = Timecode::time_to_timestamp(block->in(), timebase());
|
||||
|
||||
if (block_in_ts > GetTimestamp()) {
|
||||
this_track_closest_cut = block_in_ts;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closest_cut = qMin(closest_cut, this_track_closest_cut);
|
||||
}
|
||||
|
||||
if (closest_cut < INT64_MAX) {
|
||||
SetTimeAndSignal(closest_cut);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::GoToStart()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
SetTimeAndSignal(0);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::PrevFrame()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
SetTimeAndSignal(qMax(static_cast<int64_t>(0), ruler()->GetTime() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::NextFrame()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
SetTimeAndSignal(ruler()->GetTime() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::GoToEnd()
|
||||
{
|
||||
if (viewer_node_) {
|
||||
SetTimeAndSignal(Timecode::time_to_timestamp(viewer_node_->Length(), timebase()));
|
||||
}
|
||||
}
|
||||
|
||||
void TimeBasedWidget::SetTimeAndSignal(const int64_t &t)
|
||||
{
|
||||
SetTime(t);
|
||||
emit TimeChanged(t);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#ifndef TIMEBASEDWIDGET_H
|
||||
#define TIMEBASEDWIDGET_H
|
||||
|
||||
#include <QScrollBar>
|
||||
#include <QWidget>
|
||||
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "widget/timelinewidget/timelinescaledobject.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
|
||||
class TimeBasedWidget : public QWidget, public TimelineScaledObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TimeBasedWidget(bool ruler_text_visible = true, bool ruler_cache_status_visible = false, QWidget* parent = nullptr);
|
||||
|
||||
rational GetTime() const;
|
||||
|
||||
const int64_t& GetTimestamp() const;
|
||||
|
||||
void ZoomIn();
|
||||
|
||||
void ZoomOut();
|
||||
|
||||
ViewerOutput* GetConnectedNode() const;
|
||||
|
||||
void ConnectViewerNode(ViewerOutput *node);
|
||||
|
||||
public slots:
|
||||
// FIXME: Rename this to SetTimestamp to reduce confusion
|
||||
void SetTime(int64_t timestamp);
|
||||
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
void GoToStart();
|
||||
|
||||
void PrevFrame();
|
||||
|
||||
void NextFrame();
|
||||
|
||||
void GoToEnd();
|
||||
|
||||
void GoToPrevCut();
|
||||
|
||||
void GoToNextCut();
|
||||
|
||||
protected slots:
|
||||
void SetTimeAndSignal(const int64_t& t);
|
||||
|
||||
protected:
|
||||
TimeRuler* ruler() const;
|
||||
|
||||
QScrollBar* scrollbar() const;
|
||||
|
||||
virtual void TimebaseChangedEvent(const rational&) override;
|
||||
|
||||
virtual void TimeChangedEvent(const int64_t&){}
|
||||
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
|
||||
virtual void ConnectedNodeChanged(ViewerOutput*){}
|
||||
|
||||
virtual void ConnectNodeInternal(ViewerOutput*){}
|
||||
|
||||
virtual void DisconnectNodeInternal(ViewerOutput*){}
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t&);
|
||||
|
||||
void TimebaseChanged(const rational&);
|
||||
|
||||
private:
|
||||
ViewerOutput* viewer_node_;
|
||||
|
||||
TimeRuler* ruler_;
|
||||
|
||||
QScrollBar* scrollbar_;
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMEBASEDWIDGET_H
|
||||
@@ -3,11 +3,20 @@
|
||||
#include <QtMath>
|
||||
|
||||
TimelineScaledObject::TimelineScaledObject() :
|
||||
scale_(1.0)
|
||||
scale_(1.0),
|
||||
max_scale_(DBL_MAX)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TimelineScaledObject::SetTimebase(const rational &timebase)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
timebase_dbl_ = timebase_.toDouble();
|
||||
|
||||
TimebaseChangedEvent(timebase);
|
||||
}
|
||||
|
||||
const rational &TimelineScaledObject::timebase() const
|
||||
{
|
||||
return timebase_;
|
||||
@@ -45,8 +54,23 @@ rational TimelineScaledObject::SceneToTime(const double &x, bool round)
|
||||
return SceneToTime(x, scale_, timebase_, round);
|
||||
}
|
||||
|
||||
void TimelineScaledObject::SetTimebaseInternal(const rational &timebase)
|
||||
void TimelineScaledObject::SetMaximumScale(const double &max)
|
||||
{
|
||||
timebase_ = timebase;
|
||||
timebase_dbl_ = timebase_.toDouble();
|
||||
max_scale_ = max;
|
||||
|
||||
if (GetScale() > max_scale_) {
|
||||
SetScale(max_scale_);
|
||||
}
|
||||
}
|
||||
|
||||
const double& TimelineScaledObject::GetScale() const
|
||||
{
|
||||
return scale_;
|
||||
}
|
||||
|
||||
void TimelineScaledObject::SetScale(const double& scale)
|
||||
{
|
||||
scale_ = scale;
|
||||
|
||||
ScaleChangedEvent(scale_);
|
||||
}
|
||||
|
||||
@@ -7,25 +7,38 @@ class TimelineScaledObject
|
||||
{
|
||||
public:
|
||||
TimelineScaledObject();
|
||||
virtual ~TimelineScaledObject() = default;
|
||||
|
||||
void SetTimebase(const rational &timebase);
|
||||
|
||||
const rational& timebase() const;
|
||||
const double& timebase_dbl() const;
|
||||
|
||||
static rational SceneToTime(const double &x, const double& x_scale, const rational& timebase, bool round = false);
|
||||
|
||||
const double& GetScale() const;
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
protected:
|
||||
double TimeToScene(const rational& time);
|
||||
rational SceneToTime(const double &x, bool round = false);
|
||||
|
||||
void SetTimebaseInternal(const rational& timebase);
|
||||
virtual void TimebaseChangedEvent(const rational&){}
|
||||
|
||||
double scale_;
|
||||
virtual void ScaleChangedEvent(const double&){}
|
||||
|
||||
void SetMaximumScale(const double& max);
|
||||
|
||||
private:
|
||||
rational timebase_;
|
||||
|
||||
double timebase_dbl_;
|
||||
|
||||
double scale_;
|
||||
|
||||
double max_scale_;
|
||||
|
||||
};
|
||||
|
||||
#endif // TIMELINESCALEDOBJECT_H
|
||||
|
||||
@@ -14,11 +14,9 @@
|
||||
#include "widget/nodeview/nodeviewundo.h"
|
||||
|
||||
TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
TimeBasedWidget(true, true, parent),
|
||||
rubberband_(QRubberBand::Rectangle, this),
|
||||
active_tool_(nullptr),
|
||||
timeline_node_(nullptr),
|
||||
playhead_(0)
|
||||
active_tool_(nullptr)
|
||||
{
|
||||
QVBoxLayout* vert_layout = new QVBoxLayout(this);
|
||||
vert_layout->setSpacing(0);
|
||||
@@ -30,14 +28,10 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
timecode_label_ = new TimeSlider();
|
||||
timecode_label_->SetAlignment(Qt::AlignCenter);
|
||||
timecode_label_->setVisible(false);
|
||||
connect(timecode_label_, SIGNAL(ValueChanged(int64_t)), this, SIGNAL(TimeChanged(const int64_t&)));
|
||||
connect(timecode_label_, SIGNAL(ValueChanged(int64_t)), this, SLOT(UpdateInternalTime(const int64_t&)));
|
||||
connect(timecode_label_, &TimeSlider::ValueChanged, this, &TimelineWidget::SetTimeAndSignal);
|
||||
ruler_and_time_layout->addWidget(timecode_label_);
|
||||
|
||||
ruler_ = new TimeRuler(true, true);
|
||||
connect(ruler_, SIGNAL(TimeChanged(const int64_t&)), this, SIGNAL(TimeChanged(const int64_t&)));
|
||||
connect(ruler_, SIGNAL(TimeChanged(const int64_t&)), this, SLOT(UpdateInternalTime(const int64_t&)));
|
||||
ruler_and_time_layout->addWidget(ruler_);
|
||||
ruler_and_time_layout->addWidget(ruler());
|
||||
|
||||
// Create list of TimelineViews - these MUST correspond to the ViewType enum
|
||||
|
||||
@@ -74,10 +68,9 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
tools_.append(import_tool_);
|
||||
|
||||
// Global scrollbar
|
||||
horizontal_scroll_ = new QScrollBar(Qt::Horizontal);
|
||||
connect(horizontal_scroll_, SIGNAL(valueChanged(int)), ruler_, SLOT(SetScroll(int)));
|
||||
connect(views_.first()->view()->horizontalScrollBar(), SIGNAL(rangeChanged(int, int)), horizontal_scroll_, SLOT(setRange(int, int)));
|
||||
vert_layout->addWidget(horizontal_scroll_);
|
||||
connect(scrollbar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
connect(views_.first()->view()->horizontalScrollBar(), &QScrollBar::rangeChanged, scrollbar(), &QScrollBar::setRange);
|
||||
vert_layout->addWidget(scrollbar());
|
||||
|
||||
foreach (TimelineAndTrackView* tview, views_) {
|
||||
TimelineView* view = tview->view();
|
||||
@@ -87,32 +80,32 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
|
||||
view_splitter->addWidget(tview);
|
||||
|
||||
connect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), ruler_, SLOT(SetScroll(int)));
|
||||
connect(view, SIGNAL(ScaleChanged(double)), this, SLOT(SetScale(double)));
|
||||
connect(ruler_, SIGNAL(TimeChanged(const int64_t&)), view, SLOT(SetTime(const int64_t&)));
|
||||
connect(view, SIGNAL(TimeChanged(const int64_t&)), ruler_, SLOT(SetTime(const int64_t&)));
|
||||
connect(view, SIGNAL(TimeChanged(const int64_t&)), this, SIGNAL(TimeChanged(const int64_t&)));
|
||||
connect(view, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(ShowContextMenu()));
|
||||
connect(horizontal_scroll_, SIGNAL(valueChanged(int)), view->horizontalScrollBar(), SLOT(setValue(int)));
|
||||
connect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), horizontal_scroll_, SLOT(setValue(int)));
|
||||
connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
connect(view, &TimelineView::ScaleChanged, this, &TimelineWidget::SetScale);
|
||||
connect(ruler(), &TimeRuler::TimeChanged, view, &TimelineView::SetTime);
|
||||
connect(view, &TimelineView::TimeChanged, ruler(), &TimeRuler::SetTime);
|
||||
connect(view, &TimelineView::TimeChanged, this, &TimelineWidget::TimeChanged);
|
||||
connect(view, &TimelineView::customContextMenuRequested, this, &TimelineWidget::ShowContextMenu);
|
||||
connect(scrollbar(), &QScrollBar::valueChanged, view->horizontalScrollBar(), &QScrollBar::setValue);
|
||||
connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, scrollbar(), &QScrollBar::setValue);
|
||||
|
||||
connect(view, SIGNAL(MousePressed(TimelineViewMouseEvent*)), this, SLOT(ViewMousePressed(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(MouseMoved(TimelineViewMouseEvent*)), this, SLOT(ViewMouseMoved(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(MouseReleased(TimelineViewMouseEvent*)), this, SLOT(ViewMouseReleased(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(MouseDoubleClicked(TimelineViewMouseEvent*)), this, SLOT(ViewMouseDoubleClicked(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(DragEntered(TimelineViewMouseEvent*)), this, SLOT(ViewDragEntered(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(DragMoved(TimelineViewMouseEvent*)), this, SLOT(ViewDragMoved(TimelineViewMouseEvent*)));
|
||||
connect(view, SIGNAL(DragLeft(QDragLeaveEvent*)), this, SLOT(ViewDragLeft(QDragLeaveEvent*)));
|
||||
connect(view, SIGNAL(DragDropped(TimelineViewMouseEvent*)), this, SLOT(ViewDragDropped(TimelineViewMouseEvent*)));
|
||||
connect(view, &TimelineView::MousePressed, this, &TimelineWidget::ViewMousePressed);
|
||||
connect(view, &TimelineView::MouseMoved, this, &TimelineWidget::ViewMouseMoved);
|
||||
connect(view, &TimelineView::MouseReleased, this, &TimelineWidget::ViewMouseReleased);
|
||||
connect(view, &TimelineView::MouseDoubleClicked, this, &TimelineWidget::ViewMouseDoubleClicked);
|
||||
connect(view, &TimelineView::DragEntered, this, &TimelineWidget::ViewDragEntered);
|
||||
connect(view, &TimelineView::DragMoved, this, &TimelineWidget::ViewDragMoved);
|
||||
connect(view, &TimelineView::DragLeft, this, &TimelineWidget::ViewDragLeft);
|
||||
connect(view, &TimelineView::DragDropped, this, &TimelineWidget::ViewDragDropped);
|
||||
|
||||
connect(tview->splitter(), SIGNAL(splitterMoved(int, int)), this, SLOT(UpdateHorizontalSplitters()));
|
||||
connect(tview->splitter(), &QSplitter::splitterMoved, this, &TimelineWidget::UpdateHorizontalSplitters);
|
||||
|
||||
// Connect each view's scroll to each other
|
||||
foreach (TimelineAndTrackView* other_tview, views_) {
|
||||
TimelineView* other_view = other_tview->view();
|
||||
|
||||
if (view != other_view) {
|
||||
connect(view->horizontalScrollBar(), SIGNAL(valueChanged(int)), other_view->horizontalScrollBar(), SLOT(setValue(int)));
|
||||
connect(view->horizontalScrollBar(), &QScrollBar::valueChanged, other_view->horizontalScrollBar(), &QScrollBar::setValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +114,7 @@ TimelineWidget::TimelineWidget(QWidget *parent) :
|
||||
view_splitter->setSizes({INT_MAX, INT_MAX});
|
||||
|
||||
// FIXME: Magic number
|
||||
SetMaximumScale(TimelineViewBase::kMaximumScale);
|
||||
SetScale(90.0);
|
||||
}
|
||||
|
||||
@@ -146,11 +140,10 @@ void TimelineWidget::Clear()
|
||||
block_items_.clear();
|
||||
}
|
||||
|
||||
void TimelineWidget::SetTimebase(const rational &timebase)
|
||||
void TimelineWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
SetTimebaseInternal(timebase);
|
||||
TimeBasedWidget::TimebaseChangedEvent(timebase);
|
||||
|
||||
ruler_->SetTimebase(timebase);
|
||||
timecode_label_->SetTimebase(timebase);
|
||||
|
||||
timecode_label_->setVisible(!timebase.isNull());
|
||||
@@ -162,36 +155,82 @@ void TimelineWidget::SetTimebase(const rational &timebase)
|
||||
|
||||
void TimelineWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
|
||||
// Update horizontal scrollbar's page step to the width of the panel
|
||||
horizontal_scroll_->setPageStep(horizontal_scroll_->width());
|
||||
TimeBasedWidget::resizeEvent(event);
|
||||
|
||||
// Update timecode label size
|
||||
UpdateTimecodeWidthFromSplitters(views_.first()->splitter());
|
||||
}
|
||||
|
||||
void TimelineWidget::SetTime(int64_t timestamp)
|
||||
void TimelineWidget::TimeChangedEvent(const int64_t& timestamp)
|
||||
{
|
||||
ruler_->SetTime(timestamp);
|
||||
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
view->view()->SetTime(timestamp);
|
||||
}
|
||||
|
||||
UpdateInternalTime(timestamp);
|
||||
timecode_label_->SetValue(timestamp);
|
||||
}
|
||||
|
||||
void TimelineWidget::ConnectTimelineNode(ViewerOutput *node)
|
||||
void TimelineWidget::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
if (timeline_node_ != nullptr) {
|
||||
disconnect(timeline_node_, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength);
|
||||
disconnect(timeline_node_, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
|
||||
disconnect(timeline_node_, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
|
||||
disconnect(timeline_node_, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
disconnect(timeline_node_, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
disconnect(timeline_node_, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
disconnect(timeline_node_, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
|
||||
TimeBasedWidget::ScaleChangedEvent(scale);
|
||||
|
||||
QMapIterator<Block*, TimelineViewBlockItem*> iterator(block_items_);
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
|
||||
if (iterator.value() != nullptr) {
|
||||
iterator.value()->SetScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (TimelineViewGhostItem* ghost, ghost_items_) {
|
||||
ghost->SetScale(scale);
|
||||
}
|
||||
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
view->view()->SetScale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
{
|
||||
connect(n, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength);
|
||||
connect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
|
||||
connect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
|
||||
connect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
connect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
connect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
connect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
|
||||
|
||||
SetTimebase(n->video_params().time_base());
|
||||
|
||||
for (int i=0;i<views_.size();i++) {
|
||||
Timeline::TrackType track_type = static_cast<Timeline::TrackType>(i);
|
||||
TimelineView* view = views_.at(i)->view();
|
||||
TrackList* track_list = n->track_list(track_type);
|
||||
TrackView* track_view = views_.at(i)->track_view();
|
||||
|
||||
track_view->ConnectTrackList(track_list);
|
||||
view->ConnectTrackList(track_list);
|
||||
view->SetEndTime(n->Length());
|
||||
|
||||
// Defer to the track to make all the block UI items necessary
|
||||
foreach (TrackOutput* track, n->track_list(track_type)->Tracks()) {
|
||||
AddTrack(track, track_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
{
|
||||
disconnect(n, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength);
|
||||
disconnect(n, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
|
||||
disconnect(n, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
|
||||
disconnect(n, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
disconnect(n, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
disconnect(n, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
disconnect(n, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
|
||||
|
||||
SetTimebase(0);
|
||||
|
||||
@@ -203,52 +242,6 @@ void TimelineWidget::ConnectTimelineNode(ViewerOutput *node)
|
||||
}
|
||||
}
|
||||
|
||||
timeline_node_ = node;
|
||||
|
||||
if (timeline_node_ != nullptr) {
|
||||
connect(timeline_node_, &ViewerOutput::LengthChanged, this, &TimelineWidget::UpdateTimelineLength);
|
||||
connect(timeline_node_, &ViewerOutput::BlockAdded, this, &TimelineWidget::AddBlock);
|
||||
connect(timeline_node_, &ViewerOutput::BlockRemoved, this, &TimelineWidget::RemoveBlock);
|
||||
connect(timeline_node_, &ViewerOutput::TrackAdded, this, &TimelineWidget::AddTrack);
|
||||
connect(timeline_node_, &ViewerOutput::TrackRemoved, this, &TimelineWidget::RemoveTrack);
|
||||
connect(timeline_node_, &ViewerOutput::TimebaseChanged, this, &TimelineWidget::SetTimebase);
|
||||
connect(timeline_node_, &ViewerOutput::TrackHeightChanged, this, &TimelineWidget::TrackHeightChanged);
|
||||
|
||||
SetTimebase(timeline_node_->video_params().time_base());
|
||||
|
||||
for (int i=0;i<views_.size();i++) {
|
||||
Timeline::TrackType track_type = static_cast<Timeline::TrackType>(i);
|
||||
TimelineView* view = views_.at(i)->view();
|
||||
TrackList* track_list = timeline_node_->track_list(track_type);
|
||||
TrackView* track_view = views_.at(i)->track_view();
|
||||
|
||||
track_view->ConnectTrackList(track_list);
|
||||
view->ConnectTrackList(track_list);
|
||||
view->SetEndTime(timeline_node_->Length());
|
||||
|
||||
// Defer to the track to make all the block UI items necessary
|
||||
foreach (TrackOutput* track, timeline_node_->track_list(track_type)->Tracks()) {
|
||||
AddTrack(track, track_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::DisconnectTimelineNode()
|
||||
{
|
||||
ConnectTimelineNode(nullptr);
|
||||
}
|
||||
|
||||
void TimelineWidget::ZoomIn()
|
||||
{
|
||||
SetScale(scale_ * 2);
|
||||
}
|
||||
|
||||
void TimelineWidget::ZoomOut()
|
||||
{
|
||||
SetScale(scale_ * 0.5);
|
||||
}
|
||||
|
||||
void TimelineWidget::SelectAll()
|
||||
{
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
@@ -283,72 +276,13 @@ void TimelineWidget::EditToOut()
|
||||
RippleEditTo(Timeline::kTrimOut, true);
|
||||
}
|
||||
|
||||
void TimelineWidget::GoToPrevCut()
|
||||
{
|
||||
if (timeline_node_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (playhead_ == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t closest_cut = 0;
|
||||
|
||||
foreach (TrackOutput* track, timeline_node_->Tracks()) {
|
||||
int64_t this_track_closest_cut = 0;
|
||||
|
||||
foreach (Block* block, track->Blocks()) {
|
||||
int64_t block_out_ts = Timecode::time_to_timestamp(block->out(), timebase());
|
||||
|
||||
if (block_out_ts < playhead_) {
|
||||
this_track_closest_cut = block_out_ts;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closest_cut = qMax(closest_cut, this_track_closest_cut);
|
||||
}
|
||||
|
||||
SetTimeAndSignal(closest_cut);
|
||||
}
|
||||
|
||||
void TimelineWidget::GoToNextCut()
|
||||
{
|
||||
if (timeline_node_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
int64_t closest_cut = INT64_MAX;
|
||||
|
||||
foreach (TrackOutput* track, timeline_node_->Tracks()) {
|
||||
int64_t this_track_closest_cut = Timecode::time_to_timestamp(track->track_length(), timebase());
|
||||
|
||||
if (this_track_closest_cut <= playhead_) {
|
||||
this_track_closest_cut = INT64_MAX;
|
||||
}
|
||||
|
||||
foreach (Block* block, track->Blocks()) {
|
||||
int64_t block_in_ts = Timecode::time_to_timestamp(block->in(), timebase());
|
||||
|
||||
if (block_in_ts > playhead_) {
|
||||
this_track_closest_cut = block_in_ts;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closest_cut = qMin(closest_cut, this_track_closest_cut);
|
||||
}
|
||||
|
||||
if (closest_cut < INT64_MAX) {
|
||||
SetTimeAndSignal(closest_cut);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::SplitAtPlayhead()
|
||||
{
|
||||
rational playhead_time = Timecode::timestamp_to_time(playhead_, timebase());
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
rational playhead_time = Timecode::timestamp_to_time(GetTimestamp(), timebase());
|
||||
|
||||
QList<TimelineViewBlockItem *> selected_blocks = GetSelectedBlocks();
|
||||
|
||||
@@ -359,7 +293,7 @@ void TimelineWidget::SplitAtPlayhead()
|
||||
bool some_blocks_are_selected = false;
|
||||
|
||||
// Get all blocks at the playhead
|
||||
foreach (TrackOutput* track, timeline_node_->Tracks()) {
|
||||
foreach (TrackOutput* track, GetConnectedNode()->Tracks()) {
|
||||
Block* b = track->BlockContainingTime(playhead_time);
|
||||
|
||||
if (b && b->type() == Block::kClip) {
|
||||
@@ -470,7 +404,7 @@ void TimelineWidget::DeleteSelected()
|
||||
|
||||
// Clean each track
|
||||
foreach (const TrackReference& track, tracks_affected) {
|
||||
new TrackCleanGapsCommand(timeline_node_->track_list(track.type()),
|
||||
new TrackCleanGapsCommand(GetConnectedNode()->track_list(track.type()),
|
||||
track.index(),
|
||||
command);
|
||||
}
|
||||
@@ -480,11 +414,11 @@ void TimelineWidget::DeleteSelected()
|
||||
|
||||
void TimelineWidget::IncreaseTrackHeight()
|
||||
{
|
||||
if (!timeline_node_) {
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<TrackOutput*> all_tracks = timeline_node_->Tracks();
|
||||
QVector<TrackOutput*> all_tracks = GetConnectedNode()->Tracks();
|
||||
|
||||
// Increase the height of each track by one "unit"
|
||||
foreach (TrackOutput* t, all_tracks) {
|
||||
@@ -494,11 +428,11 @@ void TimelineWidget::IncreaseTrackHeight()
|
||||
|
||||
void TimelineWidget::DecreaseTrackHeight()
|
||||
{
|
||||
if (!timeline_node_) {
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<TrackOutput*> all_tracks = timeline_node_->Tracks();
|
||||
QVector<TrackOutput*> all_tracks = GetConnectedNode()->Tracks();
|
||||
|
||||
// Decrease the height of each track by one "unit"
|
||||
foreach (TrackOutput* t, all_tracks) {
|
||||
@@ -517,7 +451,7 @@ QList<TimelineViewBlockItem *> TimelineWidget::GetSelectedBlocks()
|
||||
|
||||
TimelineViewBlockItem* item = iterator.value();
|
||||
|
||||
if (item != nullptr && item->isSelected()) {
|
||||
if (item && item->isSelected()) {
|
||||
list.append(item);
|
||||
}
|
||||
}
|
||||
@@ -525,14 +459,9 @@ QList<TimelineViewBlockItem *> TimelineWidget::GetSelectedBlocks()
|
||||
return list;
|
||||
}
|
||||
|
||||
ViewerOutput *TimelineWidget::GetConnectedNode() const
|
||||
{
|
||||
return timeline_node_;
|
||||
}
|
||||
|
||||
void TimelineWidget::RippleEditTo(Timeline::MovementMode mode, bool insert_gaps)
|
||||
{
|
||||
rational playhead_time = Timecode::timestamp_to_time(playhead_, timebase());
|
||||
rational playhead_time = GetTime();
|
||||
|
||||
rational closest_point_to_playhead;
|
||||
if (mode == Timeline::kTrimIn) {
|
||||
@@ -541,7 +470,7 @@ void TimelineWidget::RippleEditTo(Timeline::MovementMode mode, bool insert_gaps)
|
||||
closest_point_to_playhead = RATIONAL_MAX;
|
||||
}
|
||||
|
||||
foreach (TrackOutput* track, timeline_node_->Tracks()) {
|
||||
foreach (TrackOutput* track, GetConnectedNode()->Tracks()) {
|
||||
Block* b = track->NearestBlockBefore(playhead_time);
|
||||
|
||||
if (b != nullptr) {
|
||||
@@ -568,7 +497,7 @@ void TimelineWidget::RippleEditTo(Timeline::MovementMode mode, bool insert_gaps)
|
||||
rational out_ripple = qMax(closest_point_to_playhead, playhead_time);
|
||||
rational ripple_length = out_ripple - in_ripple;
|
||||
|
||||
foreach (TrackOutput* track, timeline_node_->Tracks()) {
|
||||
foreach (TrackOutput* track, GetConnectedNode()->Tracks()) {
|
||||
GapBlock* gap = nullptr;
|
||||
if (insert_gaps) {
|
||||
gap = new GapBlock();
|
||||
@@ -595,15 +524,9 @@ void TimelineWidget::RippleEditTo(Timeline::MovementMode mode, bool insert_gaps)
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::SetTimeAndSignal(const int64_t &t)
|
||||
{
|
||||
SetTime(t);
|
||||
emit TimeChanged(t);
|
||||
}
|
||||
|
||||
TrackOutput *TimelineWidget::GetTrackFromReference(const TrackReference &ref)
|
||||
{
|
||||
return timeline_node_->track_list(ref.type())->TrackAt(ref.index());
|
||||
return GetConnectedNode()->track_list(ref.type())->TrackAt(ref.index());
|
||||
}
|
||||
|
||||
int TimelineWidget::GetTrackY(const TrackReference &ref)
|
||||
@@ -618,32 +541,7 @@ int TimelineWidget::GetTrackHeight(const TrackReference &ref)
|
||||
|
||||
void TimelineWidget::CenterOn(qreal scene_pos)
|
||||
{
|
||||
horizontal_scroll_->setValue(qRound(scene_pos - horizontal_scroll_->width()/2));
|
||||
}
|
||||
|
||||
void TimelineWidget::SetScale(double scale, bool center_on_playhead)
|
||||
{
|
||||
scale_ = qMin(scale, TimelineViewBase::kMaximumScale);
|
||||
|
||||
ruler_->SetScale(scale_);
|
||||
|
||||
QMapIterator<Block*, TimelineViewBlockItem*> iterator(block_items_);
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
iterator.next();
|
||||
|
||||
if (iterator.value() != nullptr) {
|
||||
iterator.value()->SetScale(scale_);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (TimelineViewGhostItem* ghost, ghost_items_) {
|
||||
ghost->SetScale(scale_);
|
||||
}
|
||||
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
view->view()->SetScale(scale_, center_on_playhead);
|
||||
}
|
||||
scrollbar()->setValue(qRound(scene_pos - scrollbar()->width()/2));
|
||||
}
|
||||
|
||||
void TimelineWidget::ClearGhosts()
|
||||
@@ -662,12 +560,6 @@ bool TimelineWidget::HasGhosts()
|
||||
return !ghost_items_.isEmpty();
|
||||
}
|
||||
|
||||
void TimelineWidget::UpdateInternalTime(const int64_t ×tamp)
|
||||
{
|
||||
playhead_ = timestamp;
|
||||
timecode_label_->SetValue(timestamp);
|
||||
}
|
||||
|
||||
void TimelineWidget::UpdateTimelineLength(const rational &length)
|
||||
{
|
||||
foreach (TimelineAndTrackView* view, views_) {
|
||||
@@ -684,14 +576,14 @@ void TimelineWidget::ViewMousePressed(TimelineViewMouseEvent *event)
|
||||
{
|
||||
active_tool_ = GetActiveTool();
|
||||
|
||||
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
|
||||
if (GetConnectedNode() && active_tool_ != nullptr) {
|
||||
active_tool_->MousePress(event);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_) {
|
||||
if (GetConnectedNode()) {
|
||||
if (active_tool_) {
|
||||
active_tool_->MouseMove(event);
|
||||
} else {
|
||||
@@ -707,7 +599,7 @@ void TimelineWidget::ViewMouseMoved(TimelineViewMouseEvent *event)
|
||||
|
||||
void TimelineWidget::ViewMouseReleased(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
|
||||
if (GetConnectedNode() && active_tool_ != nullptr) {
|
||||
active_tool_->MouseRelease(event);
|
||||
active_tool_ = nullptr;
|
||||
}
|
||||
@@ -715,7 +607,7 @@ void TimelineWidget::ViewMouseReleased(TimelineViewMouseEvent *event)
|
||||
|
||||
void TimelineWidget::ViewMouseDoubleClicked(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr && active_tool_ != nullptr) {
|
||||
if (GetConnectedNode() && active_tool_ != nullptr) {
|
||||
active_tool_->MouseDoubleClick(event);
|
||||
active_tool_ = nullptr;
|
||||
}
|
||||
@@ -723,28 +615,28 @@ void TimelineWidget::ViewMouseDoubleClicked(TimelineViewMouseEvent *event)
|
||||
|
||||
void TimelineWidget::ViewDragEntered(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr) {
|
||||
if (GetConnectedNode()) {
|
||||
import_tool_->DragEnter(event);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ViewDragMoved(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr) {
|
||||
if (GetConnectedNode()) {
|
||||
import_tool_->DragMove(event);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ViewDragLeft(QDragLeaveEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr) {
|
||||
if (GetConnectedNode()) {
|
||||
import_tool_->DragLeave(event);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineWidget::ViewDragDropped(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (timeline_node_ != nullptr) {
|
||||
if (GetConnectedNode()) {
|
||||
import_tool_->DragDrop(event);
|
||||
}
|
||||
}
|
||||
@@ -761,7 +653,7 @@ void TimelineWidget::AddBlock(Block *block, TrackReference track)
|
||||
// Set up clip with view parameters (clip item will automatically size its rect accordingly)
|
||||
item->SetBlock(block);
|
||||
item->SetYCoords(GetTrackY(track), GetTrackHeight(track));
|
||||
item->SetScale(scale_);
|
||||
item->SetScale(GetScale());
|
||||
item->SetTrack(track);
|
||||
|
||||
// Add to list of clip items that can be iterated through
|
||||
@@ -770,7 +662,7 @@ void TimelineWidget::AddBlock(Block *block, TrackReference track)
|
||||
// Add item to graphics scene
|
||||
views_.at(track.type())->view()->scene()->addItem(item);
|
||||
|
||||
connect(block, SIGNAL(Refreshed()), this, SLOT(BlockChanged()));
|
||||
connect(block, &Block::Refreshed, this, &TimelineWidget::BlockChanged);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -854,7 +746,7 @@ void TimelineWidget::ShowContextMenu()
|
||||
|
||||
if (!selected.isEmpty()) {
|
||||
QAction* speed_duration_action = menu.addAction(tr("Speed/Duration"));
|
||||
connect(speed_duration_action, SIGNAL(triggered(bool)), this, SLOT(ShowSpeedDurationDialog()));
|
||||
connect(speed_duration_action, &QAction::triggered, this, &TimelineWidget::ShowSpeedDurationDialog);
|
||||
}
|
||||
|
||||
menu.exec(QCursor::pos());
|
||||
@@ -882,12 +774,12 @@ void TimelineWidget::ShowSpeedDurationDialog()
|
||||
|
||||
void TimelineWidget::DeferredScrollAction()
|
||||
{
|
||||
horizontal_scroll_->setValue(deferred_scroll_value_);
|
||||
scrollbar()->setValue(deferred_scroll_value_);
|
||||
}
|
||||
|
||||
void TimelineWidget::AddGhost(TimelineViewGhostItem *ghost)
|
||||
{
|
||||
ghost->SetScale(scale_);
|
||||
ghost->SetScale(GetScale());
|
||||
ghost_items_.append(ghost);
|
||||
views_.at(ghost->Track().type())->view()->scene()->addItem(ghost);
|
||||
}
|
||||
|
||||
@@ -9,15 +9,14 @@
|
||||
#include "timelineandtrackview.h"
|
||||
#include "node/output/viewer/viewer.h"
|
||||
#include "widget/slider/timeslider.h"
|
||||
#include "widget/timelinewidget/timelinescaledobject.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
/**
|
||||
* @brief Full widget for working with TimelineOutput nodes
|
||||
*
|
||||
* Encapsulates TimelineViews, TimeRulers, and scrollbars for a complete widget to manipulate Timelines
|
||||
*/
|
||||
class TimelineWidget : public QWidget, public TimelineScaledObject
|
||||
class TimelineWidget : public TimeBasedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -27,16 +26,6 @@ public:
|
||||
|
||||
void Clear();
|
||||
|
||||
void SetTime(int64_t timestamp);
|
||||
|
||||
void ConnectTimelineNode(ViewerOutput *node);
|
||||
|
||||
void DisconnectTimelineNode();
|
||||
|
||||
void ZoomIn();
|
||||
|
||||
void ZoomOut();
|
||||
|
||||
void SelectAll();
|
||||
|
||||
void DeselectAll();
|
||||
@@ -49,10 +38,6 @@ public:
|
||||
|
||||
void EditToOut();
|
||||
|
||||
void GoToPrevCut();
|
||||
|
||||
void GoToNextCut();
|
||||
|
||||
void SplitAtPlayhead();
|
||||
|
||||
void DeleteSelected();
|
||||
@@ -63,16 +48,15 @@ public:
|
||||
|
||||
QList<TimelineViewBlockItem*> GetSelectedBlocks();
|
||||
|
||||
ViewerOutput* GetConnectedNode() const;
|
||||
|
||||
public slots:
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t& time);
|
||||
virtual void TimebaseChangedEvent(const rational &) override;
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
|
||||
virtual void ConnectNodeInternal(ViewerOutput* n) override;
|
||||
virtual void DisconnectNodeInternal(ViewerOutput* n) override;
|
||||
|
||||
private:
|
||||
class Tool
|
||||
@@ -364,20 +348,10 @@ private:
|
||||
|
||||
void RippleEditTo(Timeline::MovementMode mode, bool insert_gaps);
|
||||
|
||||
void SetTimeAndSignal(const int64_t& t);
|
||||
|
||||
TrackOutput* GetTrackFromReference(const TrackReference& ref);
|
||||
|
||||
QList<TimelineAndTrackView*> views_;
|
||||
|
||||
TimeRuler* ruler_;
|
||||
|
||||
ViewerOutput* timeline_node_;
|
||||
|
||||
int64_t playhead_;
|
||||
|
||||
QScrollBar* horizontal_scroll_;
|
||||
|
||||
TimeSlider* timecode_label_;
|
||||
|
||||
int deferred_scroll_value_;
|
||||
@@ -390,10 +364,6 @@ private:
|
||||
void AddGhost(TimelineViewGhostItem* ghost);
|
||||
|
||||
private slots:
|
||||
void SetScale(double scale, bool center_on_playhead = true);
|
||||
|
||||
void UpdateInternalTime(const int64_t& timestamp);
|
||||
|
||||
void UpdateTimelineLength(const rational& length);
|
||||
|
||||
void ViewMousePressed(TimelineViewMouseEvent* event);
|
||||
|
||||
@@ -51,11 +51,11 @@ void TimelineWidget::AddTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
|
||||
ClipBlock* clip = new ClipBlock();
|
||||
clip->set_length_and_media_out(ghost_->AdjustedLength());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->timeline_node_->parent()),
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent()),
|
||||
clip,
|
||||
command);
|
||||
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()),
|
||||
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track.type()),
|
||||
track.index(),
|
||||
clip,
|
||||
ghost_->GetAdjustedIn(),
|
||||
|
||||
@@ -217,7 +217,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event)
|
||||
{
|
||||
if (parent()->HasGhosts()) {
|
||||
QUndoCommand* command = new QUndoCommand();
|
||||
NodeGraph* dst_graph = static_cast<NodeGraph*>(parent()->timeline_node_->parent());
|
||||
NodeGraph* dst_graph = static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent());
|
||||
|
||||
QVector<Block*> block_items(parent()->ghost_items_.size());
|
||||
|
||||
@@ -269,7 +269,7 @@ void TimelineWidget::ImportTool::DragDrop(TimelineViewMouseEvent *event)
|
||||
if (event->GetModifiers() & Qt::ControlModifier) {
|
||||
//emit parent()->RequestInsertBlockAtTime(clip, ghost->GetAdjustedIn());
|
||||
} else {
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(ghost->GetAdjustedTrack().type()),
|
||||
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(ghost->GetAdjustedTrack().type()),
|
||||
ghost->GetAdjustedTrack().index(),
|
||||
clip,
|
||||
ghost->GetAdjustedIn(),
|
||||
|
||||
@@ -274,7 +274,7 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e
|
||||
command);
|
||||
} else {
|
||||
// Normal block placement
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track_ref.type()),
|
||||
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track_ref.type()),
|
||||
track_ref.index(),
|
||||
b,
|
||||
ghost->GetAdjustedIn(),
|
||||
@@ -284,7 +284,7 @@ void TimelineWidget::PointerTool::MouseReleaseInternal(TimelineViewMouseEvent *e
|
||||
|
||||
if (command->childCount() > 0) {
|
||||
foreach (const TrackReference& t, tracks_affected) {
|
||||
new TrackCleanGapsCommand(parent()->timeline_node_->track_list(t.type()),
|
||||
new TrackCleanGapsCommand(parent()->GetConnectedNode()->track_list(t.type()),
|
||||
t.index(),
|
||||
command);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void TimelineWidget::RippleTool::MouseReleaseInternal(TimelineViewMouseEvent *ev
|
||||
if (ghost->AdjustedLength() > 0) {
|
||||
GapBlock* gap = new GapBlock();
|
||||
gap->set_length_and_media_out(ghost->AdjustedLength());
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->timeline_node_->parent()), gap, command);
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent()), gap, command);
|
||||
|
||||
Block* block_to_append_gap_to = Node::ValueToPtr<Block>(ghost->data(TimelineViewGhostItem::kReferenceBlock));
|
||||
|
||||
@@ -116,7 +116,7 @@ void TimelineWidget::RippleTool::InitiateGhosts(TimelineViewBlockItem *clicked_i
|
||||
}
|
||||
|
||||
// For each track that does NOT have a ghost, we need to make one for Gaps
|
||||
foreach (TrackOutput* track, parent()->timeline_node_->Tracks()) {
|
||||
foreach (TrackOutput* track, parent()->GetConnectedNode()->Tracks()) {
|
||||
// Determine if we've already created a ghost on this track
|
||||
bool ghost_on_this_track_exists = false;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void TimelineWidget::RollingTool::MouseReleaseInternal(TimelineViewMouseEvent *e
|
||||
if (b->previous() == nullptr) {
|
||||
const TrackReference& track_ref = ghost->Track();
|
||||
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track_ref.type()),
|
||||
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track_ref.type()),
|
||||
track_ref.index(),
|
||||
b,
|
||||
ghost->GetAdjustedIn(),
|
||||
|
||||
@@ -157,16 +157,16 @@ bool TimelineWidget::Tool::SnapPoint(QList<rational> start_times, rational* move
|
||||
QList<double> proposed_pts;
|
||||
|
||||
foreach (rational s, start_times) {
|
||||
proposed_pts.append((s + *movement).toDouble() * parent()->scale_);
|
||||
proposed_pts.append((s + *movement).toDouble() * parent()->GetScale());
|
||||
}
|
||||
|
||||
if (snap_points & kSnapToPlayhead) {
|
||||
|
||||
|
||||
rational playhead_abs_time = rational(parent()->playhead_ * parent()->timebase().numerator(),
|
||||
rational playhead_abs_time = rational(parent()->GetTimestamp() * parent()->timebase().numerator(),
|
||||
parent()->timebase().denominator());
|
||||
|
||||
qreal playhead_pos = playhead_abs_time.toDouble() * parent()->scale_;
|
||||
qreal playhead_pos = playhead_abs_time.toDouble() * parent()->GetScale();
|
||||
|
||||
AttemptSnap(proposed_pts, playhead_pos, start_times, playhead_abs_time, movement, &diff);
|
||||
}
|
||||
|
||||
@@ -94,11 +94,11 @@ void TimelineWidget::TransitionTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
QUndoCommand* command = new QUndoCommand();
|
||||
|
||||
// Place transition in place
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->timeline_node_->parent()),
|
||||
new NodeAddCommand(static_cast<NodeGraph*>(parent()->GetConnectedNode()->parent()),
|
||||
transition,
|
||||
command);
|
||||
|
||||
new TrackPlaceBlockCommand(parent()->timeline_node_->track_list(track.type()),
|
||||
new TrackPlaceBlockCommand(parent()->GetConnectedNode()->track_list(track.type()),
|
||||
track.index(),
|
||||
transition,
|
||||
ghost_->GetAdjustedIn(),
|
||||
|
||||
@@ -59,17 +59,17 @@ void TimelineWidget::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
double scene_right = scene_bottomright.x();
|
||||
|
||||
// Normalize scale to 1.0 scale
|
||||
double scene_width = (scene_right - scene_left) / parent()->scale_;
|
||||
double scene_width = (scene_right - scene_left) / parent()->GetScale();
|
||||
|
||||
double new_scale = qMin(TimelineViewBase::kMaximumScale, static_cast<double>(reference_view->viewport()->width()) / scene_width);
|
||||
parent()->deferred_scroll_value_ = qMax(0, qRound(scene_left / parent()->scale_ * new_scale));
|
||||
parent()->deferred_scroll_value_ = qMax(0, qRound(scene_left / parent()->GetScale() * new_scale));
|
||||
|
||||
parent()->SetScale(new_scale, false);
|
||||
parent()->SetScale(new_scale);
|
||||
|
||||
dragging_ = false;
|
||||
} else {
|
||||
// Simple zoom in/out at the cursor position
|
||||
double scale = parent()->scale_;
|
||||
double scale = parent()->GetScale();
|
||||
|
||||
if (event->GetModifiers() & Qt::AltModifier) {
|
||||
// Zoom out if the user clicks while holding Alt
|
||||
@@ -79,7 +79,7 @@ void TimelineWidget::ZoomTool::MouseRelease(TimelineViewMouseEvent *event)
|
||||
scale *= 2.0;
|
||||
}
|
||||
|
||||
parent()->SetScale(scale, false);
|
||||
parent()->SetScale(scale);
|
||||
|
||||
// Adjust scroll location for new scale
|
||||
double frame_x = event->GetFrame().toDouble() * scale;
|
||||
|
||||
@@ -267,7 +267,7 @@ TimelineViewMouseEvent TimelineView::CreateMouseEvent(const QPoint& pos, Qt::Key
|
||||
QPointF scene_pt = mapToScene(pos);
|
||||
|
||||
TimelineViewMouseEvent timeline_event(scene_pt.x(),
|
||||
scale_,
|
||||
GetScale(),
|
||||
timebase(),
|
||||
TrackReference(ConnectedTrackType(), SceneToTrack(scene_pt.y())),
|
||||
modifiers);
|
||||
|
||||
@@ -27,7 +27,7 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
|
||||
scene_.addItem(end_item_);
|
||||
|
||||
// Set default scale
|
||||
SetScale(1.0, true);
|
||||
SetScaleAndCenterOnPlayhead(1.0);
|
||||
|
||||
SetDefaultDragMode(NoDrag);
|
||||
|
||||
@@ -35,30 +35,12 @@ TimelineViewBase::TimelineViewBase(QWidget *parent) :
|
||||
|
||||
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(UpdateSceneRect()));
|
||||
connect(Core::instance(), &Core::ToolChanged, this, &TimelineViewBase::ApplicationToolChanged);
|
||||
|
||||
SetMaximumScale(kMaximumScale);
|
||||
}
|
||||
|
||||
void TimelineViewBase::SetScale(const double &scale, bool center_on_playhead)
|
||||
void TimelineViewBase::TimebaseChangedEvent(const rational &)
|
||||
{
|
||||
scale_ = qMin(scale, kMaximumScale);
|
||||
|
||||
end_item_->SetScale(scale_);
|
||||
|
||||
ScaleChangedEvent(scale_);
|
||||
|
||||
// Force redraw for playhead
|
||||
viewport()->update();
|
||||
|
||||
if (center_on_playhead) {
|
||||
// Zoom towards the playhead
|
||||
// (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated)
|
||||
QTimer::singleShot(0, this, &TimelineViewBase::CenterScrollOnPlayhead);
|
||||
}
|
||||
}
|
||||
|
||||
void TimelineViewBase::SetTimebase(const rational &timebase)
|
||||
{
|
||||
SetTimebaseInternal(timebase);
|
||||
|
||||
// Timebase influences position/visibility of playhead
|
||||
viewport()->update();
|
||||
}
|
||||
@@ -298,9 +280,23 @@ void TimelineViewBase::resizeEvent(QResizeEvent *event)
|
||||
UpdateSceneRect();
|
||||
}
|
||||
|
||||
void TimelineViewBase::ScaleChangedEvent(double scale)
|
||||
void TimelineViewBase::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
Q_UNUSED(scale)
|
||||
TimelineScaledObject::ScaleChangedEvent(scale);
|
||||
|
||||
end_item_->SetScale(scale);
|
||||
|
||||
// Force redraw for playhead
|
||||
viewport()->update();
|
||||
}
|
||||
|
||||
void TimelineViewBase::SetScaleAndCenterOnPlayhead(const double &scale)
|
||||
{
|
||||
SetScale(scale);
|
||||
|
||||
// Zoom towards the playhead
|
||||
// (using a hacky singleShot so the scroll occurs after the scene and its scrollbars have updated)
|
||||
QTimer::singleShot(0, this, &TimelineViewBase::CenterScrollOnPlayhead);
|
||||
}
|
||||
|
||||
bool TimelineViewBase::HandleZoomFromScroll(QWheelEvent *event)
|
||||
@@ -309,9 +305,9 @@ bool TimelineViewBase::HandleZoomFromScroll(QWheelEvent *event)
|
||||
// If CTRL is held (or a preference is set to swap CTRL behavior), we zoom instead of scrolling
|
||||
if (event->delta() != 0) {
|
||||
if (event->delta() > 0) {
|
||||
emit ScaleChanged(scale_ * 2.0);
|
||||
emit ScaleChanged(GetScale() * 2.0);
|
||||
} else {
|
||||
emit ScaleChanged(scale_ * 0.5);
|
||||
emit ScaleChanged(GetScale() * 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,15 +14,13 @@ class TimelineViewBase : public QGraphicsView, public TimelineScaledObject
|
||||
public:
|
||||
TimelineViewBase(QWidget* parent = nullptr);
|
||||
|
||||
void SetScale(const double& scale, bool center_on_playhead);
|
||||
|
||||
void SetEndTime(const rational& length);
|
||||
|
||||
void SetScaleAndCenterOnPlayhead(const double& scale);
|
||||
|
||||
static const double kMaximumScale;
|
||||
|
||||
public slots:
|
||||
void SetTimebase(const rational& timebase);
|
||||
|
||||
void SetTime(const int64_t time);
|
||||
|
||||
signals:
|
||||
@@ -35,7 +33,7 @@ protected:
|
||||
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
virtual void ScaleChangedEvent(double scale);
|
||||
virtual void ScaleChangedEvent(const double& scale) override;
|
||||
|
||||
bool HandleZoomFromScroll(QWheelEvent* event);
|
||||
|
||||
@@ -58,6 +56,8 @@ protected:
|
||||
|
||||
virtual void ToolChangedEvent(Tool::Item tool);
|
||||
|
||||
virtual void TimebaseChangedEvent(const rational &) override;
|
||||
|
||||
private:
|
||||
qreal GetPlayheadX();
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ void TimelineViewRect::SetTrack(const TrackReference &track)
|
||||
track_ = track;
|
||||
}
|
||||
|
||||
void TimelineViewRect::SetScale(const double &scale)
|
||||
void TimelineViewRect::ScaleChangedEvent(const double &scale)
|
||||
{
|
||||
scale_ = scale;
|
||||
TimelineScaledObject::ScaleChangedEvent(scale);
|
||||
|
||||
UpdateRect();
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ public:
|
||||
const TrackReference& Track();
|
||||
void SetTrack(const TrackReference& track);
|
||||
|
||||
void SetScale(const double& scale);
|
||||
|
||||
virtual void UpdateRect() = 0;
|
||||
|
||||
protected:
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
|
||||
int y_;
|
||||
|
||||
int height_;
|
||||
|
||||
@@ -58,7 +58,7 @@ TimeRuler::TimeRuler(bool text_visible, bool cache_status_visible, QWidget* pare
|
||||
UpdateHeight();
|
||||
}
|
||||
|
||||
const double &TimeRuler::scale()
|
||||
const double &TimeRuler::GetScale()
|
||||
{
|
||||
return scale_;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ void TimeRuler::paintEvent(QPaintEvent *)
|
||||
}
|
||||
|
||||
if (short_interval < minimum_gap_between_lines_) {
|
||||
if (long_interval == -1) {
|
||||
if (long_interval <= 0) {
|
||||
do {
|
||||
short_interval *= 2;
|
||||
} while (short_interval < minimum_gap_between_lines_);
|
||||
|
||||
@@ -34,7 +34,7 @@ class TimeRuler : public QWidget
|
||||
public:
|
||||
TimeRuler(bool text_visible = true, bool cache_status_visible = false, QWidget* parent = nullptr);
|
||||
|
||||
const double& scale();
|
||||
const double& GetScale();
|
||||
void SetScale(const double& d);
|
||||
|
||||
void SetTimebase(const rational& r);
|
||||
|
||||
+93
-156
@@ -35,11 +35,12 @@
|
||||
#include "widget/menu/menu.h"
|
||||
|
||||
ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
QWidget(parent),
|
||||
viewer_node_(nullptr),
|
||||
TimeBasedWidget(false, true, parent),
|
||||
playback_speed_(0),
|
||||
color_menu_enabled_(true),
|
||||
divider_(Config::Current()["DefaultViewerDivider"].toInt())
|
||||
divider_(Config::Current()["DefaultViewerDivider"].toInt()),
|
||||
override_color_manager_(nullptr),
|
||||
time_changed_from_timer_(false)
|
||||
{
|
||||
// Set up main layout
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
@@ -54,15 +55,11 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
sizer_->SetWidget(gl_widget_);
|
||||
|
||||
// Create time ruler
|
||||
ruler_ = new TimeRuler(false, true);
|
||||
layout->addWidget(ruler_);
|
||||
connect(ruler_, &TimeRuler::TimeChanged, this, &ViewerWidget::RulerTimeChange);
|
||||
layout->addWidget(ruler());
|
||||
|
||||
// Create scrollbar
|
||||
scrollbar_ = new QScrollBar(Qt::Horizontal);
|
||||
layout->addWidget(scrollbar_);
|
||||
connect(scrollbar_, &QScrollBar::valueChanged, ruler_, &TimeRuler::SetScroll);
|
||||
scrollbar_->setPageStep(ruler_->width());
|
||||
layout->addWidget(scrollbar());
|
||||
connect(scrollbar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
|
||||
// Create lower controls
|
||||
controls_ = new PlaybackControls();
|
||||
@@ -74,58 +71,87 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
connect(controls_, &PlaybackControls::NextFrameClicked, this, &ViewerWidget::NextFrame);
|
||||
connect(controls_, &PlaybackControls::BeginClicked, this, &ViewerWidget::GoToStart);
|
||||
connect(controls_, &PlaybackControls::EndClicked, this, &ViewerWidget::GoToEnd);
|
||||
connect(controls_, &PlaybackControls::TimeChanged, this, &ViewerWidget::SetTimeAndSignal);
|
||||
layout->addWidget(controls_);
|
||||
|
||||
// Connect timer
|
||||
connect(&playback_timer_, &QTimer::timeout, this, &ViewerWidget::PlaybackTimerUpdate);
|
||||
|
||||
// FIXME: Magic number
|
||||
ruler_->SetScale(48.0);
|
||||
ruler()->SetScale(48.0);
|
||||
|
||||
// Start background renderers
|
||||
video_renderer_ = new OpenGLBackend(this);
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedFrameReady, this, &ViewerWidget::RendererCachedFrame);
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, this, &ViewerWidget::RendererCachedTime);
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler_, &TimeRuler::CacheTimeReady);
|
||||
connect(video_renderer_, &VideoRenderBackend::RangeInvalidated, ruler_, &TimeRuler::CacheInvalidatedRange);
|
||||
connect(video_renderer_, &VideoRenderBackend::CachedTimeReady, ruler(), &TimeRuler::CacheTimeReady);
|
||||
connect(video_renderer_, &VideoRenderBackend::RangeInvalidated, ruler(), &TimeRuler::CacheInvalidatedRange);
|
||||
audio_renderer_ = new AudioBackend(this);
|
||||
|
||||
connect(PixelService::instance(), &PixelService::FormatChanged, this, &ViewerWidget::UpdateRendererParameters);
|
||||
}
|
||||
|
||||
void ViewerWidget::SetTimebase(const rational &r)
|
||||
void ViewerWidget::TimeChangedEvent(const int64_t &i)
|
||||
{
|
||||
time_base_ = r;
|
||||
time_base_dbl_ = r.toDouble();
|
||||
|
||||
ruler_->SetTimebase(r);
|
||||
controls_->SetTimebase(r);
|
||||
|
||||
controls_->SetTime(ruler_->GetTime());
|
||||
LengthChangedSlot(viewer_node_ ? viewer_node_->Length() : 0);
|
||||
|
||||
playback_timer_.setInterval(qFloor(r.toDouble()));
|
||||
if (!time_changed_from_timer_) {
|
||||
Pause();
|
||||
}
|
||||
|
||||
const double &ViewerWidget::scale() const
|
||||
{
|
||||
return ruler_->scale();
|
||||
controls_->SetTime(i);
|
||||
|
||||
if (GetConnectedNode() && last_time_ != i) {
|
||||
rational time_set = Timecode::timestamp_to_time(i, timebase());
|
||||
|
||||
UpdateTextureFromNode(time_set);
|
||||
|
||||
PushScrubbedAudio();
|
||||
}
|
||||
|
||||
rational ViewerWidget::GetTime() const
|
||||
{
|
||||
return Timecode::timestamp_to_time(ruler_->GetTime(), time_base_);
|
||||
last_time_ = i;
|
||||
}
|
||||
|
||||
void ViewerWidget::SetScale(const double &scale_)
|
||||
void ViewerWidget::ConnectNodeInternal(ViewerOutput *n)
|
||||
{
|
||||
ruler_->SetScale(scale_);
|
||||
SetTimebase(n->video_params().time_base());
|
||||
|
||||
connect(n, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase);
|
||||
connect(n, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot);
|
||||
connect(n, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
connect(n, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible);
|
||||
|
||||
SizeChangedSlot(n->video_params().width(), n->video_params().height());
|
||||
LengthChangedSlot(n->Length());
|
||||
|
||||
if (override_color_manager_) {
|
||||
gl_widget_->ConnectColorManager(override_color_manager_);
|
||||
} else if (n->parent()) {
|
||||
gl_widget_->ConnectColorManager(static_cast<Sequence*>(n->parent())->project()->color_manager());
|
||||
} else {
|
||||
qWarning() << "Failed to find a suitable color manager for the connected viewer node";
|
||||
}
|
||||
|
||||
void ViewerWidget::SetTime(const int64_t &time)
|
||||
UpdateRendererParameters();
|
||||
}
|
||||
|
||||
void ViewerWidget::DisconnectNodeInternal(ViewerOutput *n)
|
||||
{
|
||||
ruler_->SetTime(time);
|
||||
UpdateTimeInternal(time);
|
||||
SetTimebase(0);
|
||||
|
||||
disconnect(n, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase);
|
||||
disconnect(n, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot);
|
||||
disconnect(n, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
disconnect(n, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible);
|
||||
|
||||
// Effectively disables the viewer and clears the state
|
||||
SizeChangedSlot(0, 0);
|
||||
|
||||
gl_widget_->DisconnectColorManager();
|
||||
}
|
||||
|
||||
void ViewerWidget::ConnectedNodeChanged(ViewerOutput *n)
|
||||
{
|
||||
video_renderer_->SetViewerNode(n);
|
||||
audio_renderer_->SetViewerNode(n);
|
||||
}
|
||||
|
||||
void ViewerWidget::TogglePlayPause()
|
||||
@@ -144,54 +170,12 @@ bool ViewerWidget::IsPlaying() const
|
||||
|
||||
void ViewerWidget::ConnectViewerNode(ViewerOutput *node, ColorManager* color_manager)
|
||||
{
|
||||
if (viewer_node_ != nullptr) {
|
||||
SetTimebase(0);
|
||||
override_color_manager_ = color_manager;
|
||||
|
||||
disconnect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase);
|
||||
disconnect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot);
|
||||
disconnect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
disconnect(viewer_node_, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible);
|
||||
|
||||
// Effectively disables the viewer and clears the state
|
||||
SizeChangedSlot(0, 0);
|
||||
|
||||
gl_widget_->DisconnectColorManager();
|
||||
}
|
||||
|
||||
viewer_node_ = node;
|
||||
|
||||
video_renderer_->SetViewerNode(viewer_node_);
|
||||
audio_renderer_->SetViewerNode(viewer_node_);
|
||||
TimeBasedWidget::ConnectViewerNode(node);
|
||||
|
||||
// Set texture to new texture (or null if no viewer node is available)
|
||||
UpdateTextureFromNode(GetTime());
|
||||
|
||||
if (viewer_node_ != nullptr) {
|
||||
SetTimebase(viewer_node_->video_params().time_base());
|
||||
|
||||
connect(viewer_node_, &ViewerOutput::TimebaseChanged, this, &ViewerWidget::SetTimebase);
|
||||
connect(viewer_node_, &ViewerOutput::SizeChanged, this, &ViewerWidget::SizeChangedSlot);
|
||||
connect(viewer_node_, &ViewerOutput::LengthChanged, this, &ViewerWidget::LengthChangedSlot);
|
||||
connect(viewer_node_, &ViewerOutput::VisibleInvalidated, this, &ViewerWidget::InvalidateVisible);
|
||||
|
||||
SizeChangedSlot(viewer_node_->video_params().width(), viewer_node_->video_params().height());
|
||||
LengthChangedSlot(viewer_node_->Length());
|
||||
|
||||
if (color_manager) {
|
||||
gl_widget_->ConnectColorManager(color_manager);
|
||||
} else if (viewer_node_->parent()) {
|
||||
gl_widget_->ConnectColorManager(static_cast<Sequence*>(viewer_node_->parent())->project()->color_manager());
|
||||
} else {
|
||||
qWarning() << "Failed to find a suitable color manager for the connected viewer node";
|
||||
}
|
||||
|
||||
UpdateRendererParameters();
|
||||
}
|
||||
}
|
||||
|
||||
ViewerOutput *ViewerWidget::GetConnectedViewer() const
|
||||
{
|
||||
return viewer_node_;
|
||||
}
|
||||
|
||||
void ViewerWidget::SetColorMenuEnabled(bool enabled)
|
||||
@@ -219,26 +203,9 @@ void ViewerWidget::SetTexture(OpenGLTexturePtr tex)
|
||||
gl_widget_->SetTexture(tex);
|
||||
}
|
||||
|
||||
void ViewerWidget::UpdateTimeInternal(int64_t i)
|
||||
{
|
||||
rational time_set = rational(i) * time_base_;
|
||||
|
||||
controls_->SetTime(i);
|
||||
|
||||
if (viewer_node_ != nullptr && last_time_ != i) {
|
||||
UpdateTextureFromNode(time_set);
|
||||
|
||||
PushScrubbedAudio();
|
||||
}
|
||||
|
||||
last_time_ = i;
|
||||
|
||||
emit TimeChanged(i);
|
||||
}
|
||||
|
||||
void ViewerWidget::UpdateTextureFromNode(const rational& time)
|
||||
{
|
||||
if (viewer_node_ == nullptr) {
|
||||
if (!GetConnectedNode()) {
|
||||
SetTexture(nullptr);
|
||||
} else {
|
||||
SetTexture(video_renderer_->GetCachedFrameAsTexture(time));
|
||||
@@ -249,7 +216,7 @@ void ViewerWidget::PlayInternal(int speed)
|
||||
{
|
||||
Q_ASSERT(speed != 0);
|
||||
|
||||
if (time_base_.isNull()) {
|
||||
if (timebase().isNull()) {
|
||||
qWarning() << "ViewerWidget can't play with an invalid timebase";
|
||||
return;
|
||||
}
|
||||
@@ -264,7 +231,7 @@ void ViewerWidget::PlayInternal(int speed)
|
||||
}
|
||||
|
||||
start_msec_ = QDateTime::currentMSecsSinceEpoch();
|
||||
start_timestamp_ = ruler_->GetTime();
|
||||
start_timestamp_ = ruler()->GetTime();
|
||||
|
||||
playback_timer_.start();
|
||||
|
||||
@@ -273,13 +240,13 @@ void ViewerWidget::PlayInternal(int speed)
|
||||
|
||||
void ViewerWidget::PushScrubbedAudio()
|
||||
{
|
||||
if (Config::Current()["AudioScrubbing"].toBool() && !IsPlaying()) {
|
||||
if (!IsPlaying() && Config::Current()["AudioScrubbing"].toBool()) {
|
||||
// Get audio src device from renderer
|
||||
QIODevice* audio_src = audio_renderer_->GetAudioPullDevice();
|
||||
|
||||
if (audio_src != nullptr && audio_src->open(QFile::ReadOnly)) {
|
||||
if (audio_src && audio_src->open(QFile::ReadOnly)) {
|
||||
// Try to get one "frame" of audio
|
||||
int size_of_sample = audio_renderer_->params().time_to_bytes(time_base_);
|
||||
int size_of_sample = audio_renderer_->params().time_to_bytes(timebase());
|
||||
|
||||
// Push audio
|
||||
audio_src->seek(audio_renderer_->params().time_to_bytes(GetTime()));
|
||||
@@ -294,20 +261,20 @@ void ViewerWidget::PushScrubbedAudio()
|
||||
|
||||
void ViewerWidget::UpdateRendererParameters()
|
||||
{
|
||||
if (!viewer_node_) {
|
||||
if (!GetConnectedNode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderMode::Mode render_mode = RenderMode::kOffline;
|
||||
|
||||
video_renderer_->SetParameters(VideoRenderingParams(viewer_node_->video_params(),
|
||||
video_renderer_->SetParameters(VideoRenderingParams(GetConnectedNode()->video_params(),
|
||||
PixelService::instance()->GetConfiguredFormatForMode(render_mode),
|
||||
render_mode,
|
||||
divider_));
|
||||
audio_renderer_->SetParameters(AudioRenderingParams(viewer_node_->audio_params(),
|
||||
audio_renderer_->SetParameters(AudioRenderingParams(GetConnectedNode()->audio_params(),
|
||||
SampleFormat::GetConfiguredFormatForMode(render_mode)));
|
||||
|
||||
video_renderer_->InvalidateCache(0, viewer_node_->Length());
|
||||
video_renderer_->InvalidateCache(0, GetConnectedNode()->Length());
|
||||
}
|
||||
|
||||
void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
@@ -371,13 +338,6 @@ void ViewerWidget::ShowContextMenu(const QPoint &pos)
|
||||
menu.exec(mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ViewerWidget::RulerTimeChange(int64_t i)
|
||||
{
|
||||
Pause();
|
||||
|
||||
UpdateTimeInternal(i);
|
||||
}
|
||||
|
||||
void ViewerWidget::Play()
|
||||
{
|
||||
PlayInternal(1);
|
||||
@@ -393,36 +353,6 @@ void ViewerWidget::Pause()
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::GoToStart()
|
||||
{
|
||||
Pause();
|
||||
|
||||
SetTime(0);
|
||||
}
|
||||
|
||||
void ViewerWidget::PrevFrame()
|
||||
{
|
||||
Pause();
|
||||
|
||||
SetTime(qMax(static_cast<int64_t>(0), ruler_->GetTime() - 1));
|
||||
}
|
||||
|
||||
void ViewerWidget::NextFrame()
|
||||
{
|
||||
Pause();
|
||||
|
||||
SetTime(ruler_->GetTime() + 1);
|
||||
}
|
||||
|
||||
void ViewerWidget::GoToEnd()
|
||||
{
|
||||
if (viewer_node_ != nullptr) {
|
||||
Pause();
|
||||
|
||||
SetTime(Timecode::time_to_timestamp(viewer_node_->Length(), time_base_));
|
||||
}
|
||||
}
|
||||
|
||||
void ViewerWidget::ShuttleLeft()
|
||||
{
|
||||
int current_speed = playback_speed_;
|
||||
@@ -478,20 +408,33 @@ void ViewerWidget::SetOCIOLook(const QString &look)
|
||||
gl_widget_->SetOCIOLook(look);
|
||||
}
|
||||
|
||||
void ViewerWidget::TimebaseChangedEvent(const rational &timebase)
|
||||
{
|
||||
TimeBasedWidget::TimebaseChangedEvent(timebase);
|
||||
|
||||
controls_->SetTimebase(timebase);
|
||||
|
||||
controls_->SetTime(ruler()->GetTime());
|
||||
LengthChangedSlot(GetConnectedNode() ? GetConnectedNode()->Length() : 0);
|
||||
|
||||
playback_timer_.setInterval(qFloor(timebase.toDouble()));
|
||||
}
|
||||
|
||||
void ViewerWidget::PlaybackTimerUpdate()
|
||||
{
|
||||
int64_t real_time = QDateTime::currentMSecsSinceEpoch() - start_msec_;
|
||||
|
||||
int64_t frames_since_start = qRound(static_cast<double>(real_time) / (time_base_dbl_ * 1000));
|
||||
int64_t frames_since_start = qRound(static_cast<double>(real_time) / (timebase_dbl() * 1000));
|
||||
|
||||
int64_t current_time = start_timestamp_ + frames_since_start * playback_speed_;
|
||||
|
||||
if (current_time < 0) {
|
||||
current_time = 0;
|
||||
Pause();
|
||||
SetTimeAndSignal(0);
|
||||
} else {
|
||||
time_changed_from_timer_ = true;
|
||||
SetTimeAndSignal(current_time);
|
||||
time_changed_from_timer_ = false;
|
||||
}
|
||||
|
||||
SetTime(current_time);
|
||||
}
|
||||
|
||||
void ViewerWidget::RendererCachedFrame(const rational &time, QVariant value, qint64 job_time)
|
||||
@@ -519,14 +462,8 @@ void ViewerWidget::SizeChangedSlot(int width, int height)
|
||||
|
||||
void ViewerWidget::LengthChangedSlot(const rational &length)
|
||||
{
|
||||
controls_->SetEndTime(Timecode::time_to_timestamp(length, time_base_));
|
||||
ruler_->SetCacheStatusLength(length);
|
||||
}
|
||||
|
||||
void ViewerWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
// Set scrollbar page step to the width
|
||||
scrollbar_->setPageStep(event->size().width());
|
||||
controls_->SetEndTime(Timecode::time_to_timestamp(length, timebase()));
|
||||
ruler()->SetCacheStatusLength(length);
|
||||
}
|
||||
|
||||
void ViewerWidget::ColorDisplayChanged(QAction* action)
|
||||
|
||||
+12
-38
@@ -36,12 +36,12 @@
|
||||
#include "viewerglwidget.h"
|
||||
#include "viewersizer.h"
|
||||
#include "widget/playbackcontrols/playbackcontrols.h"
|
||||
#include "widget/timeruler/timeruler.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
/**
|
||||
* @brief An OpenGL-based viewer widget with playback controls (a PlaybackControls widget).
|
||||
*/
|
||||
class ViewerWidget : public QWidget
|
||||
class ViewerWidget : public TimeBasedWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
@@ -51,22 +51,12 @@ public:
|
||||
|
||||
void SetTimeRulerEnabled(bool enabled);
|
||||
|
||||
const double& scale() const;
|
||||
|
||||
rational GetTime() const;
|
||||
|
||||
void SetScale(const double& scale_);
|
||||
|
||||
void SetTime(const int64_t& time);
|
||||
|
||||
void TogglePlayPause();
|
||||
|
||||
bool IsPlaying() const;
|
||||
|
||||
void ConnectViewerNode(ViewerOutput* node, ColorManager *color_manager = nullptr);
|
||||
|
||||
ViewerOutput* GetConnectedViewer() const;
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the color management menu
|
||||
*
|
||||
@@ -91,20 +81,10 @@ public slots:
|
||||
*/
|
||||
void SetTexture(OpenGLTexturePtr tex);
|
||||
|
||||
void SetTimebase(const rational& r);
|
||||
|
||||
void GoToStart();
|
||||
|
||||
void PrevFrame();
|
||||
|
||||
void Play();
|
||||
|
||||
void Pause();
|
||||
|
||||
void NextFrame();
|
||||
|
||||
void GoToEnd();
|
||||
|
||||
void ShuttleLeft();
|
||||
|
||||
void ShuttleStop();
|
||||
@@ -134,11 +114,13 @@ public slots:
|
||||
*/
|
||||
void SetOCIOLook(const QString& look);
|
||||
|
||||
signals:
|
||||
void TimeChanged(const int64_t&);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event) override;
|
||||
virtual void TimebaseChangedEvent(const rational &) override;
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
|
||||
virtual void ConnectNodeInternal(ViewerOutput *) override;
|
||||
virtual void DisconnectNodeInternal(ViewerOutput *) override;
|
||||
virtual void ConnectedNodeChanged(ViewerOutput*n) override;
|
||||
|
||||
OpenGLBackend* video_renderer_;
|
||||
AudioBackend* audio_renderer_;
|
||||
@@ -158,21 +140,11 @@ private:
|
||||
|
||||
PlaybackControls* controls_;
|
||||
|
||||
TimeRuler* ruler_;
|
||||
|
||||
QScrollBar* scrollbar_;
|
||||
|
||||
rational time_base_;
|
||||
|
||||
double time_base_dbl_;
|
||||
|
||||
QTimer playback_timer_;
|
||||
|
||||
qint64 start_msec_;
|
||||
int64_t start_timestamp_;
|
||||
|
||||
ViewerOutput* viewer_node_;
|
||||
|
||||
int playback_speed_;
|
||||
|
||||
qint64 frame_cache_job_time_;
|
||||
@@ -183,9 +155,11 @@ private:
|
||||
|
||||
int divider_;
|
||||
|
||||
private slots:
|
||||
void RulerTimeChange(int64_t);
|
||||
ColorManager* override_color_manager_;
|
||||
|
||||
bool time_changed_from_timer_;
|
||||
|
||||
private slots:
|
||||
void PlaybackTimerUpdate();
|
||||
|
||||
void RendererCachedFrame(const rational& time, QVariant value, qint64 job_time);
|
||||
|
||||
@@ -90,6 +90,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, viewer_panel_, &ViewerPanel::SetTime);
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, timeline_panel_, &TimelinePanel::SetTime);
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, param_panel_, &ParamPanel::SetTime);
|
||||
|
||||
viewer_panel_->ConnectTimeBasedPanel(timeline_panel_);
|
||||
viewer_panel_->ConnectTimeBasedPanel(param_panel_);
|
||||
viewer_panel_->ConnectTimeBasedPanel(curve_panel_);
|
||||
}
|
||||
|
||||
void MainWindow::SetFullscreen(bool fullscreen)
|
||||
|
||||
Reference in New Issue
Block a user