From 97c192672ead76f2bc63f4b9e4fd35629647b6e5 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Wed, 25 Dec 2019 02:42:07 +1100 Subject: [PATCH] constructed keyframeview and timeruler together inside nodeparamview and connected them --- app/node/node.h | 31 ++++++++++++ app/node/output/viewer/viewer.cpp | 4 +- app/node/output/viewer/viewer.h | 4 +- app/panel/param/param.cpp | 10 ++++ app/panel/param/param.h | 6 ++- app/widget/keyframeview/keyframeview.cpp | 45 ++++++++++------- app/widget/keyframeview/keyframeview.h | 12 ++--- app/widget/nodeparamview/nodeparamview.cpp | 56 ++++++++++++++++++++-- app/widget/nodeparamview/nodeparamview.h | 8 ++++ 9 files changed, 143 insertions(+), 33 deletions(-) diff --git a/app/node/node.h b/app/node/node.h index c89c11e1f..3c7afebb1 100644 --- a/app/node/node.h +++ b/app/node/node.h @@ -202,6 +202,12 @@ public: */ void DisconnectAll(); + template + /** + * @brief Find a node of a certain type that this Node outputs to + */ + const T* FindOutputNode() const; + /** * @brief Convert a pointer to a value that can be sent between NodeParams */ @@ -385,4 +391,29 @@ T* Node::ValueToPtr(const QVariant &ptr) return reinterpret_cast(ptr.value()); } +template +const Node* FindOutputNodeInternal(const Node* n) { + foreach (NodeEdgePtr edge, n->output()->edges()) { + Node* connected = edge->input()->parentNode(); + T* cast_test = dynamic_cast(connected); + + if (cast_test) { + return cast_test; + } else { + const Node* drill_test = FindOutputNodeInternal(connected); + if (drill_test) { + return drill_test; + } + } + } + + return nullptr; +} + +template +const T* Node::FindOutputNode() const +{ + return static_cast(FindOutputNodeInternal(this)); +} + #endif // NODE_H diff --git a/app/node/output/viewer/viewer.cpp b/app/node/output/viewer/viewer.cpp index 3db4849be..f5b527182 100644 --- a/app/node/output/viewer/viewer.cpp +++ b/app/node/output/viewer/viewer.cpp @@ -93,12 +93,12 @@ void ViewerOutput::InvalidateCache(const rational &start_range, const rational & SendInvalidateCache(start_range, end_range); } -const VideoParams &ViewerOutput::video_params() +const VideoParams &ViewerOutput::video_params() const { return video_params_; } -const AudioParams &ViewerOutput::audio_params() +const AudioParams &ViewerOutput::audio_params() const { return audio_params_; } diff --git a/app/node/output/viewer/viewer.h b/app/node/output/viewer/viewer.h index a64ab5e63..411c814d7 100644 --- a/app/node/output/viewer/viewer.h +++ b/app/node/output/viewer/viewer.h @@ -51,8 +51,8 @@ public: virtual void InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from = nullptr) override; - const VideoParams& video_params(); - const AudioParams& audio_params(); + const VideoParams& video_params() const; + const AudioParams& audio_params() const; void set_video_params(const VideoParams& video); void set_audio_params(const AudioParams& audio); diff --git a/app/panel/param/param.cpp b/app/panel/param/param.cpp index 37575b4b9..ce0810666 100644 --- a/app/panel/param/param.cpp +++ b/app/panel/param/param.cpp @@ -33,6 +33,16 @@ ParamPanel::ParamPanel(QWidget* parent) : Retranslate(); } +void ParamPanel::ZoomIn() +{ + view_->SetScale(view_->GetScale() * 2); +} + +void ParamPanel::ZoomOut() +{ + view_->SetScale(view_->GetScale() * 0.5); +} + void ParamPanel::SetNodes(QList nodes) { view_->SetNodes(nodes); diff --git a/app/panel/param/param.h b/app/panel/param/param.h index 6d1155840..07250453c 100644 --- a/app/panel/param/param.h +++ b/app/panel/param/param.h @@ -30,11 +30,15 @@ class ParamPanel : public PanelWidget public: ParamPanel(QWidget* parent); + virtual void ZoomIn() override; + + virtual void ZoomOut() override; + public slots: void SetNodes(QList nodes); protected: - virtual void changeEvent(QEvent* e); + virtual void changeEvent(QEvent* e) override; private: void Retranslate(); diff --git a/app/widget/keyframeview/keyframeview.cpp b/app/widget/keyframeview/keyframeview.cpp index 8c75bc107..203a8d70a 100644 --- a/app/widget/keyframeview/keyframeview.cpp +++ b/app/widget/keyframeview/keyframeview.cpp @@ -3,25 +3,36 @@ #include KeyframeView::KeyframeView(QWidget *parent) : - QWidget(parent) + TimelineViewBase(parent) { - QVBoxLayout* layout = new QVBoxLayout(this); - layout->setSpacing(0); - layout->setMargin(0); - - ruler_ = new TimeRuler(); - ruler_->SetTextVisible(true); - layout->addWidget(ruler_); - - view_ = new QGraphicsView(); - view_->setScene(&scene_); - view_->setBackgroundRole(QPalette::Base); - view_->setAlignment(Qt::AlignLeft | Qt::AlignTop); - view_->setDragMode(QGraphicsView::RubberBandDrag); - layout->addWidget(view_); + setBackgroundRole(QPalette::Base); + setAlignment(Qt::AlignLeft | Qt::AlignTop); + setDragMode(QGraphicsView::RubberBandDrag); } -void KeyframeView::SetTimebase(const rational &timebase) +void KeyframeView::mousePressEvent(QMouseEvent *event) { - ruler_->SetTimebase(timebase); + if (PlayheadPress(event)) { + return; + } + + QGraphicsView::mousePressEvent(event); +} + +void KeyframeView::mouseMoveEvent(QMouseEvent *event) +{ + if (PlayheadMove(event)) { + return; + } + + QGraphicsView::mouseMoveEvent(event); +} + +void KeyframeView::mouseReleaseEvent(QMouseEvent *event) +{ + if (PlayheadRelease(event)) { + return; + } + + QGraphicsView::mouseReleaseEvent(event); } diff --git a/app/widget/keyframeview/keyframeview.h b/app/widget/keyframeview/keyframeview.h index 9e9b7ca8e..cb7abc79d 100644 --- a/app/widget/keyframeview/keyframeview.h +++ b/app/widget/keyframeview/keyframeview.h @@ -5,22 +5,22 @@ #include "common/rational.h" #include "keyframeviewitem.h" -#include "widget/timeruler/timeruler.h" +#include "widget/timelinewidget/view/timelineviewbase.h" -class KeyframeView : public QWidget +class KeyframeView : public TimelineViewBase { public: KeyframeView(QWidget* parent = nullptr); void AddKeyframe(const rational& time, int y); - void SetTimebase(const rational& timebase); +protected: + virtual void mousePressEvent(QMouseEvent *event) override; + virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void mouseReleaseEvent(QMouseEvent *event) override; private: - TimeRuler* ruler_; - QGraphicsView* view_; - QGraphicsScene scene_; }; #endif // KEYFRAMEVIEW_H diff --git a/app/widget/nodeparamview/nodeparamview.cpp b/app/widget/nodeparamview/nodeparamview.cpp index d5a4f2ea1..205dccc0c 100644 --- a/app/widget/nodeparamview/nodeparamview.cpp +++ b/app/widget/nodeparamview/nodeparamview.cpp @@ -23,16 +23,18 @@ #include #include +#include "node/output/viewer/viewer.h" + NodeParamView::NodeParamView(QWidget *parent) : QWidget(parent) { // Create horizontal layout to place scroll area in (and keyframe editing eventually) - QHBoxLayout* widget_layout = new QHBoxLayout(this); - widget_layout->setSpacing(0); - widget_layout->setMargin(0); + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setSpacing(0); + layout->setMargin(0); QSplitter* splitter = new QSplitter(Qt::Horizontal); - widget_layout->addWidget(splitter); + layout->addWidget(splitter); // Set up scroll area for params QScrollArea* scroll_area = new QScrollArea(); @@ -52,8 +54,24 @@ NodeParamView::NodeParamView(QWidget *parent) : param_layout_->addStretch(); // Set up keyframe view + QWidget* keyframe_area = new QWidget(); + QVBoxLayout* keyframe_area_layout = new QVBoxLayout(keyframe_area); + keyframe_area_layout->setSpacing(0); + keyframe_area_layout->setMargin(0); + + // Create ruler object + ruler_ = new TimeRuler(true); + keyframe_area_layout->addWidget(ruler_); + + // Create keyframe view keyframe_view_ = new KeyframeView(); - splitter->addWidget(keyframe_view_); + keyframe_area_layout->addWidget(keyframe_view_); + + // Connect ruler and keyframe view together + connect(ruler_, SIGNAL(TimeChanged(const int64_t&)), keyframe_view_, SLOT(SetTime(const int64_t&))); + connect(keyframe_view_, SIGNAL(TimeChanged(const int64_t&)), ruler_, SLOT(SetTime(const int64_t&))); + + splitter->addWidget(keyframe_area); // Disable collapsing param view (but collapsing keyframe view is permitted) splitter->setCollapsible(0, false); @@ -67,6 +85,9 @@ void NodeParamView::SetNodes(QList nodes) } items_.clear(); + // Reset keyframe view + SetTimebase(rational()); + // Set the internal list to the one we've received nodes_ = nodes; @@ -97,9 +118,34 @@ void NodeParamView::SetNodes(QList nodes) items_.append(item); } } + + if (!nodes_.isEmpty()) { + const ViewerOutput* viewer = nodes_.first()->FindOutputNode(); + + if (viewer) { + SetTimebase(viewer->video_params().time_base()); + } + } } const QList &NodeParamView::nodes() { return nodes_; } + +const double &NodeParamView::GetScale() const +{ + return ruler_->scale(); +} + +void NodeParamView::SetScale(const double& scale) +{ + ruler_->SetScale(scale); + keyframe_view_->SetScale(scale); +} + +void NodeParamView::SetTimebase(const rational &timebase) +{ + ruler_->SetTimebase(timebase); + keyframe_view_->SetTimebase(timebase); +} diff --git a/app/widget/nodeparamview/nodeparamview.h b/app/widget/nodeparamview/nodeparamview.h index 6c4adf0ab..1430d3728 100644 --- a/app/widget/nodeparamview/nodeparamview.h +++ b/app/widget/nodeparamview/nodeparamview.h @@ -27,6 +27,7 @@ #include "node/node.h" #include "nodeparamviewitem.h" #include "widget/keyframeview/keyframeview.h" +#include "widget/timeruler/timeruler.h" class NodeParamView : public QWidget { @@ -36,11 +37,18 @@ public: void SetNodes(QList nodes); const QList& nodes(); + const double& GetScale() const; + void SetScale(const double &scale); + private: + void SetTimebase(const rational& timebase); + QVBoxLayout* param_layout_; KeyframeView* keyframe_view_; + TimeRuler* ruler_; + QList nodes_; QList items_;