various: began heavy rework of curve view to link closely with param view
This commit is contained in:
@@ -32,21 +32,14 @@ CurvePanel::CurvePanel(QWidget *parent) :
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
NodeInput *CurvePanel::GetInput() const
|
||||
{
|
||||
return static_cast<CurveWidget*>(GetTimeBasedWidget())->GetInput();
|
||||
}
|
||||
|
||||
void CurvePanel::DeleteSelected()
|
||||
{
|
||||
static_cast<CurveWidget*>(GetTimeBasedWidget())->DeleteSelected();
|
||||
}
|
||||
|
||||
void CurvePanel::SetInput(NodeInput *input)
|
||||
void CurvePanel::SetNodes(const QList<Node *> &nodes)
|
||||
{
|
||||
static_cast<CurveWidget*>(GetTimeBasedWidget())->SetInput(input);
|
||||
|
||||
Retranslate();
|
||||
static_cast<CurveWidget*>(GetTimeBasedWidget())->SetNodes(nodes);
|
||||
}
|
||||
|
||||
void CurvePanel::IncreaseTrackHeight()
|
||||
@@ -66,13 +59,6 @@ void CurvePanel::Retranslate()
|
||||
TimeBasedPanel::Retranslate();
|
||||
|
||||
SetTitle(tr("Curve Editor"));
|
||||
|
||||
NodeInput* connected_input = static_cast<CurveWidget*>(GetTimeBasedWidget())->GetInput();
|
||||
if (connected_input) {
|
||||
SetSubtitle(connected_input->name());
|
||||
} else {
|
||||
SetSubtitle(QString());
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -32,12 +32,10 @@ class CurvePanel : public TimeBasedPanel
|
||||
public:
|
||||
CurvePanel(QWidget* parent);
|
||||
|
||||
NodeInput* GetInput() const;
|
||||
|
||||
virtual void DeleteSelected() override;
|
||||
|
||||
public slots:
|
||||
void SetInput(NodeInput* input);
|
||||
void SetNodes(const QList<Node*>& nodes);
|
||||
|
||||
virtual void IncreaseTrackHeight() override;
|
||||
|
||||
|
||||
@@ -28,9 +28,8 @@ ParamPanel::ParamPanel(QWidget* parent) :
|
||||
TimeBasedPanel(QStringLiteral("ParamPanel"), parent)
|
||||
{
|
||||
NodeParamView* view = new NodeParamView();
|
||||
connect(view, &NodeParamView::InputDoubleClicked, this, &ParamPanel::CreateCurvePanel);
|
||||
connect(view, &NodeParamView::RequestSelectNode, this, &ParamPanel::RequestSelectNode);
|
||||
//connect(view, &NodeParamView::FoundGizmos, this, &ParamPanel::FoundGizmos);
|
||||
connect(view, &NodeParamView::NodeOrderChanged, this, &ParamPanel::NodeOrderChanged);
|
||||
SetTimeBasedWidget(view);
|
||||
|
||||
Retranslate();
|
||||
@@ -50,14 +49,6 @@ void ParamPanel::DeselectNodes(const QList<Node *> &nodes)
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
void ParamPanel::SetTimestamp(const int64_t ×tamp)
|
||||
{
|
||||
TimeBasedPanel::SetTimestamp(timestamp);
|
||||
|
||||
// Ensure all CurvePanels are updated with this time too
|
||||
ParamViewTimeChanged(timestamp);
|
||||
}
|
||||
|
||||
void ParamPanel::DeleteSelected()
|
||||
{
|
||||
static_cast<NodeParamView*>(GetTimeBasedWidget())->DeleteSelected();
|
||||
@@ -78,69 +69,4 @@ void ParamPanel::Retranslate()
|
||||
}
|
||||
}
|
||||
|
||||
void ParamPanel::CreateCurvePanel(NodeInput *input)
|
||||
{
|
||||
if (!input->is_keyframable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CurvePanel* panel = open_curve_panels_.value(input);
|
||||
|
||||
if (panel) {
|
||||
panel->raise();
|
||||
return;
|
||||
}
|
||||
|
||||
NodeParamView* view = static_cast<NodeParamView*>(GetTimeBasedWidget());
|
||||
|
||||
panel = Core::instance()->main_window()->AppendCurvePanel();
|
||||
|
||||
panel->ConnectViewerNode(view->GetConnectedNode());
|
||||
panel->SetTimestamp(view->GetTimestamp());
|
||||
panel->SetInput(input);
|
||||
|
||||
connect(view, &NodeParamView::TimeChanged, this, &ParamPanel::ParamViewTimeChanged);
|
||||
connect(panel, &CurvePanel::TimeChanged, this, &ParamPanel::CurvePanelTimeChanged);
|
||||
connect(panel, &CurvePanel::CloseRequested, this, &ParamPanel::ClosingCurvePanel);
|
||||
|
||||
open_curve_panels_.insert(input, panel);
|
||||
}
|
||||
|
||||
void ParamPanel::ClosingCurvePanel()
|
||||
{
|
||||
CurvePanel* panel = static_cast<CurvePanel*>(sender());
|
||||
open_curve_panels_.remove(panel->GetInput());
|
||||
}
|
||||
|
||||
void ParamPanel::ParamViewTimeChanged(const int64_t &time)
|
||||
{
|
||||
// Ensure all CurvePanels are updated with this time too
|
||||
QHash<NodeInput*, CurvePanel*>::const_iterator i;
|
||||
|
||||
for (i=open_curve_panels_.begin(); i!=open_curve_panels_.end(); i++) {
|
||||
// If connected viewers are the same, set the timestamp
|
||||
if (i.value()->GetConnectedViewer() == GetConnectedViewer()) {
|
||||
i.value()->SetTimestamp(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParamPanel::CurvePanelTimeChanged(const int64_t &time)
|
||||
{
|
||||
GetTimeBasedWidget()->SetTimestamp(time);
|
||||
emit GetTimeBasedWidget()->TimeChanged(time);
|
||||
|
||||
CurvePanel* src = static_cast<CurvePanel*>(sender());
|
||||
|
||||
// Ensure all CurvePanels are updated with this time too
|
||||
QHash<NodeInput*, CurvePanel*>::const_iterator i;
|
||||
|
||||
for (i=open_curve_panels_.begin(); i!=open_curve_panels_.end(); i++) {
|
||||
// If connected viewers are the same and the panel isn't the source, set the timestamp
|
||||
if (i.value() != src && i.value()->GetConnectedViewer() == src->GetConnectedViewer()) {
|
||||
i.value()->SetTimestamp(time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
+1
-16
@@ -37,31 +37,16 @@ public slots:
|
||||
void SelectNodes(const QList<Node*>& nodes);
|
||||
void DeselectNodes(const QList<Node*>& nodes);
|
||||
|
||||
virtual void SetTimestamp(const int64_t& timestamp) override;
|
||||
|
||||
virtual void DeleteSelected() override;
|
||||
|
||||
signals:
|
||||
void RequestSelectNode(const QList<Node*>& target);
|
||||
|
||||
void FoundGizmos(Node* node);
|
||||
void NodeOrderChanged(const QList<Node*>& nodes);
|
||||
|
||||
protected:
|
||||
virtual void Retranslate() override;
|
||||
|
||||
private slots:
|
||||
void CreateCurvePanel(NodeInput* input);
|
||||
|
||||
void ClosingCurvePanel();
|
||||
|
||||
private:
|
||||
QHash<NodeInput*, CurvePanel*> open_curve_panels_;
|
||||
|
||||
private slots:
|
||||
void ParamViewTimeChanged(const int64_t& time);
|
||||
|
||||
void CurvePanelTimeChanged(const int64_t& time);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -29,9 +29,10 @@ add_subdirectory(manageddisplay)
|
||||
add_subdirectory(menu)
|
||||
add_subdirectory(nodecombobox)
|
||||
add_subdirectory(nodecopypaste)
|
||||
add_subdirectory(nodeview)
|
||||
add_subdirectory(nodeparamview)
|
||||
add_subdirectory(nodetableview)
|
||||
add_subdirectory(nodetreeview)
|
||||
add_subdirectory(nodeparamview)
|
||||
add_subdirectory(nodeview)
|
||||
add_subdirectory(panel)
|
||||
add_subdirectory(path)
|
||||
add_subdirectory(pixelsampler)
|
||||
|
||||
@@ -75,6 +75,55 @@ void CurveView::SetTrackVisible(int track, bool visible)
|
||||
SetKeyframeTrackVisible(track, visible);
|
||||
}
|
||||
|
||||
void CurveView::ConnectInput(NodeInput *input)
|
||||
{
|
||||
if (connected_inputs_.contains(input)) {
|
||||
// Input wasn't connected, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// Add keyframes from this input
|
||||
foreach (const NodeInput::KeyframeTrack& track, input->keyframe_tracks()) {
|
||||
foreach (NodeKeyframePtr key, track) {
|
||||
this->AddKeyframe(key);
|
||||
}
|
||||
}
|
||||
|
||||
// Append to the list
|
||||
connected_inputs_.append(input);
|
||||
|
||||
// Connect add/remove signals
|
||||
connect(input, &NodeInput::KeyframeAdded, this, &CurveView::AddKeyframe);
|
||||
connect(input, &NodeInput::KeyframeRemoved, this, &CurveView::RemoveKeyframe);
|
||||
}
|
||||
|
||||
void CurveView::DisconnectNode(Node *node)
|
||||
{
|
||||
QList<NodeInput*> inputs = node->GetInputsIncludingArrays();
|
||||
|
||||
foreach (NodeInput* i, inputs) {
|
||||
DisconnectInput(i);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveView::DisconnectInput(NodeInput *input)
|
||||
{
|
||||
if (!connected_inputs_.contains(input)) {
|
||||
// Input wasn't connected, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove keyframes belonging to this input
|
||||
RemoveKeyframesOfInput(input);
|
||||
|
||||
// Remove from the list
|
||||
connected_inputs_.removeOne(input);
|
||||
|
||||
// Disconnect add/remove signals
|
||||
disconnect(input, &NodeInput::KeyframeAdded, this, &CurveView::AddKeyframe);
|
||||
disconnect(input, &NodeInput::KeyframeRemoved, this, &CurveView::RemoveKeyframe);
|
||||
}
|
||||
|
||||
void CurveView::drawBackground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
if (timebase().isNull()) {
|
||||
@@ -273,10 +322,8 @@ QList<NodeKeyframe *> CurveView::GetKeyframesSortedByTime(int track)
|
||||
{
|
||||
QList<NodeKeyframe *> sorted;
|
||||
|
||||
QMap<NodeKeyframe*, KeyframeViewItem*>::const_iterator iterator;
|
||||
|
||||
for (iterator=item_map().begin();iterator!=item_map().end();iterator++) {
|
||||
NodeKeyframe* key = iterator.key();
|
||||
for (auto it=item_map().cbegin();it!=item_map().cend();it++) {
|
||||
NodeKeyframe* key = it.key();
|
||||
|
||||
if (key->track() != track) {
|
||||
continue;
|
||||
|
||||
@@ -42,6 +42,12 @@ public:
|
||||
|
||||
void SetTrackVisible(int track, bool visible);
|
||||
|
||||
void ConnectInput(NodeInput* input);
|
||||
|
||||
void DisconnectNode(Node* node);
|
||||
|
||||
void DisconnectInput(NodeInput* input);
|
||||
|
||||
public slots:
|
||||
void AddKeyframe(NodeKeyframePtr key);
|
||||
|
||||
@@ -86,6 +92,8 @@ private:
|
||||
|
||||
QVector<bool> track_visible_;
|
||||
|
||||
QList<NodeInput*> connected_inputs_;
|
||||
|
||||
int track_count_;
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <QEvent>
|
||||
#include <QLabel>
|
||||
#include <QScrollBar>
|
||||
#include <QSplitter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "core.h"
|
||||
@@ -34,12 +35,23 @@
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
CurveWidget::CurveWidget(QWidget *parent) :
|
||||
TimeBasedWidget(parent),
|
||||
input_(nullptr),
|
||||
bridge_(nullptr)
|
||||
TimeBasedWidget(parent)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QHBoxLayout* outer_layout = new QHBoxLayout(this);
|
||||
|
||||
QSplitter* splitter = new QSplitter();
|
||||
outer_layout->addWidget(splitter);
|
||||
|
||||
tree_view_ = new NodeTreeView();
|
||||
tree_view_->SetOnlyShowKeyframable(true);
|
||||
connect(tree_view_, &NodeTreeView::NodeEnableChanged, this, &CurveWidget::NodeEnabledChanged);
|
||||
connect(tree_view_, &NodeTreeView::InputEnableChanged, this, &CurveWidget::InputEnabledChanged);
|
||||
splitter->addWidget(tree_view_);
|
||||
|
||||
QWidget* workarea = new QWidget();
|
||||
QVBoxLayout* layout = new QVBoxLayout(workarea);
|
||||
layout->setMargin(0);
|
||||
splitter->addWidget(workarea);
|
||||
|
||||
QHBoxLayout* top_controls = new QHBoxLayout();
|
||||
|
||||
@@ -92,12 +104,8 @@ CurveWidget::CurveWidget(QWidget *parent) :
|
||||
view_->setHorizontalScrollBar(scrollbar());
|
||||
connect(view_->horizontalScrollBar(), &QScrollBar::valueChanged, ruler(), &TimeRuler::SetScroll);
|
||||
|
||||
widget_bridge_layout_ = new QHBoxLayout();
|
||||
widget_bridge_layout_->addStretch();
|
||||
input_label_ = new QLabel();
|
||||
widget_bridge_layout_->addWidget(input_label_);
|
||||
widget_bridge_layout_->addStretch();
|
||||
layout->addLayout(widget_bridge_layout_);
|
||||
// Disable collapsing the main curve view (but allow collapsing the tree)
|
||||
splitter->setCollapsible(1, false);
|
||||
|
||||
SetScale(120.0);
|
||||
}
|
||||
@@ -108,71 +116,6 @@ CurveWidget::~CurveWidget()
|
||||
view_->Clear();
|
||||
}
|
||||
|
||||
NodeInput *CurveWidget::GetInput() const
|
||||
{
|
||||
return input_;
|
||||
}
|
||||
|
||||
void CurveWidget::SetInput(NodeInput *input)
|
||||
{
|
||||
if (bridge_) {
|
||||
foreach (QWidget* bridge_widget, bridge_->widgets()) {
|
||||
bridge_widget->deleteLater();
|
||||
}
|
||||
bridge_->deleteLater();
|
||||
bridge_ = nullptr;
|
||||
}
|
||||
|
||||
foreach (QCheckBox* box, checkboxes_) {
|
||||
box->deleteLater();
|
||||
}
|
||||
checkboxes_.clear();
|
||||
|
||||
if (input_) {
|
||||
disconnect(input_, &NodeInput::KeyframeAdded, view_, &CurveView::AddKeyframe);
|
||||
disconnect(input_, &NodeInput::KeyframeRemoved, view_, &CurveView::RemoveKeyframe);
|
||||
}
|
||||
|
||||
view_->Clear();
|
||||
|
||||
input_ = input;
|
||||
key_control_->SetInput(input_);
|
||||
|
||||
if (input_) {
|
||||
view_->SetTrackCount(input_->get_number_of_keyframe_tracks());
|
||||
|
||||
bridge_ = new NodeParamViewWidgetBridge(input_, this);
|
||||
|
||||
bridge_->SetTimeTarget(GetTimeTarget());
|
||||
|
||||
for (int i=0;i<bridge_->widgets().size();i++) {
|
||||
// Insert between two stretches to center the widget
|
||||
QCheckBox* checkbox = new QCheckBox();
|
||||
checkbox->setChecked(true);
|
||||
widget_bridge_layout_->insertWidget(2 + i*2, checkbox);
|
||||
checkboxes_.append(checkbox);
|
||||
connect(checkbox, &QCheckBox::clicked, this, [this](bool e){
|
||||
view_->SetTrackVisible(checkboxes_.indexOf(static_cast<QCheckBox*>(sender())), e);
|
||||
});
|
||||
|
||||
widget_bridge_layout_->insertWidget(2 + i*2 + 1, bridge_->widgets().at(i));
|
||||
}
|
||||
|
||||
connect(input_, &NodeInput::KeyframeAdded, view_, &CurveView::AddKeyframe);
|
||||
connect(input_, &NodeInput::KeyframeRemoved, view_, &CurveView::RemoveKeyframe);
|
||||
|
||||
foreach (const NodeInput::KeyframeTrack& track, input_->keyframe_tracks()) {
|
||||
foreach (NodeKeyframePtr key, track) {
|
||||
view_->AddKeyframe(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateInputLabel();
|
||||
|
||||
QMetaObject::invokeMethod(view_, "ZoomToFit", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
const double &CurveWidget::GetVerticalScale()
|
||||
{
|
||||
return view_->GetYScale();
|
||||
@@ -188,12 +131,26 @@ void CurveWidget::DeleteSelected()
|
||||
view_->DeleteSelected();
|
||||
}
|
||||
|
||||
void CurveWidget::changeEvent(QEvent *e)
|
||||
void CurveWidget::SetNodes(const QList<Node *> &nodes)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
UpdateInputLabel();
|
||||
tree_view_->SetNodes(nodes);
|
||||
|
||||
// Detect removed nodes
|
||||
foreach (Node* n, nodes_) {
|
||||
if (!nodes.contains(n)) {
|
||||
view_->DisconnectNode(n);
|
||||
}
|
||||
QWidget::changeEvent(e);
|
||||
}
|
||||
|
||||
// Detect added nodes
|
||||
foreach (Node* n, nodes) {
|
||||
if (tree_view_->IsNodeEnabled(n) && !nodes_.contains(n)) {
|
||||
ConnectNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
// Save new node list
|
||||
nodes_ = nodes;
|
||||
}
|
||||
|
||||
void CurveWidget::TimeChangedEvent(const int64_t ×tamp)
|
||||
@@ -223,10 +180,6 @@ void CurveWidget::TimeTargetChangedEvent(Node *target)
|
||||
key_control_->SetTimeTarget(target);
|
||||
|
||||
view_->SetTimeTarget(target);
|
||||
|
||||
if (bridge_) {
|
||||
bridge_->SetTimeTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::ConnectedNodeChanged(ViewerOutput *n)
|
||||
@@ -234,15 +187,6 @@ void CurveWidget::ConnectedNodeChanged(ViewerOutput *n)
|
||||
SetTimeTarget(n);
|
||||
}
|
||||
|
||||
void CurveWidget::UpdateInputLabel()
|
||||
{
|
||||
if (input_) {
|
||||
input_label_->setText(QStringLiteral("%1 :: %2:").arg(input_->parentNode()->Name(), input_->name()));
|
||||
} else {
|
||||
input_label_->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::SetKeyframeButtonEnabled(bool enable)
|
||||
{
|
||||
linear_button_->setEnabled(enable);
|
||||
@@ -266,15 +210,26 @@ void CurveWidget::SetKeyframeButtonCheckedFromType(NodeKeyframe::Type type)
|
||||
|
||||
void CurveWidget::UpdateBridgeTime(const int64_t ×tamp)
|
||||
{
|
||||
if (!input_) {
|
||||
return;
|
||||
}
|
||||
|
||||
rational time = Timecode::timestamp_to_time(timestamp, view_->timebase());
|
||||
bridge_->SetTime(time);
|
||||
key_control_->SetTime(time);
|
||||
}
|
||||
|
||||
void CurveWidget::ConnectNode(Node *n)
|
||||
{
|
||||
QList<NodeInput*> inputs = n->GetInputsIncludingArrays();
|
||||
|
||||
foreach (NodeInput* i, inputs) {
|
||||
if (tree_view_->IsInputEnabled(i)) {
|
||||
view_->ConnectInput(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::DisconnectNode(Node *n)
|
||||
{
|
||||
view_->DisconnectNode(n);
|
||||
}
|
||||
|
||||
void CurveWidget::SelectionChanged()
|
||||
{
|
||||
QList<QGraphicsItem*> selected = view_->scene()->selectedItems();
|
||||
@@ -349,4 +304,22 @@ void CurveWidget::KeyControlRequestedTimeChanged(const rational &time)
|
||||
SetTimeAndSignal(Timecode::time_to_timestamp(time, view_->timebase()));
|
||||
}
|
||||
|
||||
void CurveWidget::NodeEnabledChanged(Node* n, bool e)
|
||||
{
|
||||
if (e) {
|
||||
ConnectNode(n);
|
||||
} else {
|
||||
DisconnectNode(n);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveWidget::InputEnabledChanged(NodeInput *i, bool e)
|
||||
{
|
||||
if (e) {
|
||||
view_->ConnectInput(i);
|
||||
} else {
|
||||
view_->DisconnectInput(i);
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "node/input.h"
|
||||
#include "widget/nodeparamview/nodeparamviewkeyframecontrol.h"
|
||||
#include "widget/nodeparamview/nodeparamviewwidgetbridge.h"
|
||||
#include "widget/nodetreeview/nodetreeview.h"
|
||||
#include "widget/timebased/timebased.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
@@ -42,17 +43,15 @@ public:
|
||||
|
||||
virtual ~CurveWidget() override;
|
||||
|
||||
NodeInput* GetInput() const;
|
||||
void SetInput(NodeInput* input);
|
||||
|
||||
const double& GetVerticalScale();
|
||||
void SetVerticalScale(const double& vscale);
|
||||
|
||||
void DeleteSelected();
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent *) override;
|
||||
public slots:
|
||||
void SetNodes(const QList<Node*>& nodes);
|
||||
|
||||
protected:
|
||||
virtual void TimeChangedEvent(const int64_t &) override;
|
||||
virtual void TimebaseChangedEvent(const rational &) override;
|
||||
virtual void ScaleChangedEvent(const double &) override;
|
||||
@@ -62,8 +61,6 @@ protected:
|
||||
virtual void ConnectedNodeChanged(ViewerOutput* n) override;
|
||||
|
||||
private:
|
||||
void UpdateInputLabel();
|
||||
|
||||
void SetKeyframeButtonEnabled(bool enable);
|
||||
|
||||
void SetKeyframeButtonChecked(bool checked);
|
||||
@@ -72,6 +69,12 @@ private:
|
||||
|
||||
void UpdateBridgeTime(const int64_t& timestamp);
|
||||
|
||||
void ConnectNode(Node* n);
|
||||
|
||||
void DisconnectNode(Node* n);
|
||||
|
||||
NodeTreeView* tree_view_;
|
||||
|
||||
QPushButton* linear_button_;
|
||||
|
||||
QPushButton* bezier_button_;
|
||||
@@ -80,18 +83,12 @@ private:
|
||||
|
||||
CurveView* view_;
|
||||
|
||||
NodeInput* input_;
|
||||
|
||||
QLabel* input_label_;
|
||||
|
||||
QHBoxLayout* widget_bridge_layout_;
|
||||
|
||||
NodeParamViewWidgetBridge* bridge_;
|
||||
|
||||
NodeParamViewKeyframeControl* key_control_;
|
||||
|
||||
QList<QCheckBox*> checkboxes_;
|
||||
|
||||
QList<Node*> nodes_;
|
||||
|
||||
private slots:
|
||||
void SelectionChanged();
|
||||
|
||||
@@ -99,6 +96,10 @@ private slots:
|
||||
|
||||
void KeyControlRequestedTimeChanged(const rational& time);
|
||||
|
||||
void NodeEnabledChanged(Node* n, bool e);
|
||||
|
||||
void InputEnabledChanged(NodeInput* i, bool e);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -79,12 +79,17 @@ void KeyframeViewBase::RemoveKeyframesOfNode(Node *n)
|
||||
QList<NodeInput*> inputs = n->GetInputsIncludingArrays();
|
||||
|
||||
foreach (NodeInput* i, inputs) {
|
||||
RemoveKeyframesOfInput(i);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeViewBase::RemoveKeyframesOfInput(NodeInput *i)
|
||||
{
|
||||
foreach (const NodeInput::KeyframeTrack& track, i->keyframe_tracks()) {
|
||||
foreach (NodeKeyframePtr key, track) {
|
||||
RemoveKeyframe(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyframeViewBase::RemoveKeyframe(NodeKeyframePtr key)
|
||||
|
||||
@@ -42,6 +42,8 @@ public:
|
||||
|
||||
void RemoveKeyframesOfNode(Node* n);
|
||||
|
||||
void RemoveKeyframesOfInput(NodeInput* i);
|
||||
|
||||
public slots:
|
||||
void RemoveKeyframe(NodeKeyframePtr key);
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ void NodeParamView::SelectNodes(const QList<Node *> &nodes)
|
||||
|
||||
item->setAllowedAreas(Qt::LeftDockWidgetArea);
|
||||
item->setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable);
|
||||
item->SetExpanded(node_expanded_state_.value(n, true));
|
||||
|
||||
connect(item, &NodeParamViewItem::KeyframeAdded, keyframe_view_, &KeyframeView::AddKeyframe);
|
||||
connect(item, &NodeParamViewItem::KeyframeRemoved, keyframe_view_, &KeyframeView::RemoveKeyframe);
|
||||
@@ -176,6 +177,9 @@ void NodeParamView::DeselectNodes(const QList<Node *> &nodes)
|
||||
|
||||
foreach (Node* n, nodes) {
|
||||
if (!pinned_nodes_.contains(n)) {
|
||||
// Store expanded state
|
||||
node_expanded_state_.insert(n, items_.value(n)->IsExpanded());
|
||||
|
||||
// Remove all keyframes from this node
|
||||
RemoveNode(n);
|
||||
|
||||
|
||||
@@ -115,6 +115,8 @@ private:
|
||||
|
||||
QList<Node*> active_nodes_;
|
||||
|
||||
QMap<Node*, bool> node_expanded_state_;
|
||||
|
||||
private slots:
|
||||
void ItemRequestedTimeChanged(const rational& time);
|
||||
|
||||
|
||||
@@ -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/nodetreeview/nodetreeview.h
|
||||
widget/nodetreeview/nodetreeview.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,111 @@
|
||||
#include "nodetreeview.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
NodeTreeView::NodeTreeView(QWidget *parent) :
|
||||
QTreeWidget(parent),
|
||||
only_show_keyframable_(false)
|
||||
{
|
||||
connect(this, &NodeTreeView::itemChanged, this, &NodeTreeView::ItemCheckStateChanged);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
bool NodeTreeView::IsNodeEnabled(Node *n) const
|
||||
{
|
||||
return !disabled_nodes_.contains(n);
|
||||
}
|
||||
|
||||
bool NodeTreeView::IsInputEnabled(NodeInput *i) const
|
||||
{
|
||||
return !disabled_inputs_.contains(i);
|
||||
}
|
||||
|
||||
void NodeTreeView::SetNodes(const QList<Node *> &nodes)
|
||||
{
|
||||
nodes_ = nodes;
|
||||
|
||||
this->clear();
|
||||
|
||||
foreach (Node* n, nodes_) {
|
||||
QTreeWidgetItem* node_item = new QTreeWidgetItem();
|
||||
node_item->setText(0, n->Name());
|
||||
node_item->setCheckState(0, disabled_nodes_.contains(n) ? Qt::Unchecked : Qt::Checked);
|
||||
node_item->setData(0, kItemType, kItemTypeNode);
|
||||
node_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(n));
|
||||
|
||||
QList<NodeInput*> inputs = n->GetInputsIncludingArrays();
|
||||
foreach (NodeInput* i, inputs) {
|
||||
if (only_show_keyframable_ && !i->is_keyframable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QTreeWidgetItem* input_item = new QTreeWidgetItem(node_item);
|
||||
input_item->setText(0, i->name());
|
||||
input_item->setCheckState(0, disabled_inputs_.contains(i) ? Qt::Unchecked : Qt::Checked);
|
||||
input_item->setData(0, kItemType, kItemTypeInput);
|
||||
input_item->setData(0, kItemPointer, reinterpret_cast<quintptr>(i));
|
||||
}
|
||||
|
||||
// Add at the end to prevent unnecessary signalling while we're setting these objects up
|
||||
if (node_item->childCount() > 0) {
|
||||
this->addTopLevelItem(node_item);
|
||||
} else {
|
||||
delete node_item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTreeView::changeEvent(QEvent *e)
|
||||
{
|
||||
QTreeWidget::changeEvent(e);
|
||||
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
Retranslate();
|
||||
}
|
||||
}
|
||||
|
||||
void NodeTreeView::Retranslate()
|
||||
{
|
||||
setHeaderLabel(tr("Nodes"));
|
||||
}
|
||||
|
||||
void NodeTreeView::ItemCheckStateChanged(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
Q_UNUSED(column)
|
||||
|
||||
switch (item->data(0, kItemType).toInt()) {
|
||||
case kItemTypeNode:
|
||||
{
|
||||
Node* n = reinterpret_cast<Node*>(item->data(0, kItemPointer).value<quintptr>());
|
||||
|
||||
if (item->checkState(0) == Qt::Checked) {
|
||||
if (disabled_nodes_.contains(n)) {
|
||||
disabled_nodes_.removeOne(n);
|
||||
emit NodeEnableChanged(n, true);
|
||||
}
|
||||
} else if (!disabled_nodes_.contains(n)) {
|
||||
disabled_nodes_.append(n);
|
||||
emit NodeEnableChanged(n, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kItemTypeInput:
|
||||
{
|
||||
NodeInput* i = reinterpret_cast<NodeInput*>(item->data(0, kItemPointer).value<quintptr>());
|
||||
|
||||
if (item->checkState(0) == Qt::Checked) {
|
||||
if (disabled_inputs_.contains(i)) {
|
||||
disabled_inputs_.removeOne(i);
|
||||
emit InputEnableChanged(i, true);
|
||||
}
|
||||
} else if (!disabled_inputs_.contains(i)) {
|
||||
disabled_inputs_.append(i);
|
||||
emit InputEnableChanged(i, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef NODETREEVIEW_H
|
||||
#define NODETREEVIEW_H
|
||||
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "node/node.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class NodeTreeView : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NodeTreeView(QWidget *parent = nullptr);
|
||||
|
||||
bool IsNodeEnabled(Node* n) const;
|
||||
|
||||
bool IsInputEnabled(NodeInput* i) const;
|
||||
|
||||
void SetOnlyShowKeyframable(bool e)
|
||||
{
|
||||
only_show_keyframable_ = e;
|
||||
}
|
||||
|
||||
public slots:
|
||||
void SetNodes(const QList<Node*>& nodes);
|
||||
|
||||
signals:
|
||||
void NodeEnableChanged(Node* n, bool e);
|
||||
|
||||
void InputEnableChanged(NodeInput* i, bool e);
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent* e) override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
enum ItemType {
|
||||
kItemTypeNode,
|
||||
kItemTypeInput
|
||||
};
|
||||
|
||||
static const int kItemType = Qt::UserRole;
|
||||
static const int kItemPointer = Qt::UserRole + 1;
|
||||
|
||||
QList<Node*> nodes_;
|
||||
|
||||
QList<Node*> disabled_nodes_;
|
||||
|
||||
QList<NodeInput*> disabled_inputs_;
|
||||
|
||||
bool only_show_keyframable_;
|
||||
|
||||
private slots:
|
||||
void ItemCheckStateChanged(QTreeWidgetItem* item, int column);
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // NODETREEVIEW_H
|
||||
@@ -72,6 +72,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
node_panel_ = PanelManager::instance()->CreatePanel<NodePanel>(this);
|
||||
footage_viewer_panel_ = PanelManager::instance()->CreatePanel<FootageViewerPanel>(this);
|
||||
param_panel_ = PanelManager::instance()->CreatePanel<ParamPanel>(this);
|
||||
curve_panel_ = PanelManager::instance()->CreatePanel<CurvePanel>(this);
|
||||
table_panel_ = PanelManager::instance()->CreatePanel<NodeTablePanel>(this);
|
||||
sequence_viewer_panel_ = PanelManager::instance()->CreatePanel<SequenceViewerPanel>(this);
|
||||
pixel_sampler_panel_ = PanelManager::instance()->CreatePanel<PixelSamplerPanel>(this);
|
||||
@@ -87,14 +88,25 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(node_panel_, &NodePanel::NodesSelected, table_panel_, &NodeTablePanel::SelectNodes);
|
||||
connect(node_panel_, &NodePanel::NodesDeselected, table_panel_, &NodeTablePanel::DeselectNodes);
|
||||
connect(param_panel_, &ParamPanel::RequestSelectNode, node_panel_, &NodePanel::Select);
|
||||
|
||||
// Connect time signals together
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp);
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, curve_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(param_panel_, &ParamPanel::FoundGizmos, sequence_viewer_panel_, &SequenceViewerPanel::SetGizmos);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, curve_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(curve_panel_, &ParamPanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp);
|
||||
connect(curve_panel_, &ParamPanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(curve_panel_, &ParamPanel::TimeChanged, param_panel_, &NodeTablePanel::SetTimestamp);
|
||||
|
||||
// Connect node order signals
|
||||
connect(param_panel_, &ParamPanel::NodeOrderChanged, curve_panel_, &CurvePanel::SetNodes);
|
||||
|
||||
connect(PanelManager::instance(), &PanelManager::FocusedPanelChanged, this, &MainWindow::FocusedPanelChanged);
|
||||
|
||||
sequence_viewer_panel_->ConnectTimeBasedPanel(param_panel_);
|
||||
sequence_viewer_panel_->ConnectTimeBasedPanel(curve_panel_);
|
||||
|
||||
footage_viewer_panel_->ConnectPixelSamplerPanel(pixel_sampler_panel_);
|
||||
sequence_viewer_panel_->ConnectPixelSamplerPanel(pixel_sampler_panel_);
|
||||
@@ -240,26 +252,6 @@ ScopePanel *MainWindow::AppendScopePanel()
|
||||
return AppendFloatingPanelInternal<ScopePanel>(scope_panels_);
|
||||
}
|
||||
|
||||
CurvePanel *MainWindow::AppendCurvePanel()
|
||||
{
|
||||
CurvePanel* p = AppendFloatingPanelInternal<CurvePanel>(curve_panels_);
|
||||
|
||||
sequence_viewer_panel_->ConnectTimeBasedPanel(p);
|
||||
|
||||
return p;
|
||||
|
||||
/*connect(panel, &TimelinePanel::TimeChanged, curve_panel_, &CurvePanel::SetTime);
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, panel, &TimelinePanel::SetTime);
|
||||
connect(param_panel_, &ParamPanel::SelectedInputChanged, curve_panel_, &CurvePanel::SetInput);
|
||||
connect(param_panel_, &ParamPanel::TimebaseChanged, curve_panel_, &CurvePanel::SetTimebase);
|
||||
connect(param_panel_, &ParamPanel::TimeTargetChanged, curve_panel_, &CurvePanel::SetTimeTarget);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime);
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTime);
|
||||
connect(curve_panel_, &CurvePanel::TimeChanged, param_panel_, &ParamPanel::SetTime);
|
||||
sequence_viewer_panel_->ConnectTimeBasedPanel(curve_panel_);
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, curve_panel_, &CurvePanel::SetTime);*/
|
||||
}
|
||||
|
||||
void MainWindow::SetFullscreen(bool fullscreen)
|
||||
{
|
||||
if (fullscreen) {
|
||||
@@ -495,12 +487,14 @@ TimelinePanel* MainWindow::AppendTimelinePanel()
|
||||
TimelinePanel* panel = AppendPanelInternal<TimelinePanel>(timeline_panels_);
|
||||
|
||||
connect(panel, &PanelWidget::CloseRequested, this, &MainWindow::TimelineCloseRequested);
|
||||
connect(panel, &TimelinePanel::TimeChanged, curve_panel_, &ParamPanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::TimeChanged, param_panel_, &ParamPanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::TimeChanged, table_panel_, &NodeTablePanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::TimeChanged, sequence_viewer_panel_, &SequenceViewerPanel::SetTimestamp);
|
||||
connect(panel, &TimelinePanel::BlocksSelected, node_panel_, &NodePanel::SelectBlocks);
|
||||
connect(panel, &TimelinePanel::BlocksDeselected, node_panel_, &NodePanel::DeselectBlocks);
|
||||
connect(param_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
|
||||
connect(curve_panel_, &ParamPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
|
||||
connect(sequence_viewer_panel_, &SequenceViewerPanel::TimeChanged, panel, &TimelinePanel::SetTimestamp);
|
||||
|
||||
sequence_viewer_panel_->ConnectTimeBasedPanel(panel);
|
||||
@@ -546,6 +540,7 @@ void MainWindow::TimelineFocused(ViewerOutput* viewer)
|
||||
{
|
||||
sequence_viewer_panel_->ConnectViewerNode(viewer);
|
||||
param_panel_->ConnectViewerNode(viewer);
|
||||
curve_panel_->ConnectViewerNode(viewer);
|
||||
|
||||
Sequence* seq = nullptr;
|
||||
|
||||
@@ -585,6 +580,10 @@ void MainWindow::SetDefaultLayout()
|
||||
tabifyDockWidget(footage_viewer_panel_, param_panel_);
|
||||
footage_viewer_panel_->raise();
|
||||
|
||||
curve_panel_->hide();
|
||||
curve_panel_->setFloating(true);
|
||||
addDockWidget(Qt::TopDockWidgetArea, curve_panel_);
|
||||
|
||||
table_panel_->hide();
|
||||
table_panel_->setFloating(true);
|
||||
addDockWidget(Qt::TopDockWidgetArea, table_panel_);
|
||||
|
||||
@@ -70,8 +70,6 @@ public:
|
||||
|
||||
ScopePanel* AppendScopePanel();
|
||||
|
||||
CurvePanel* AppendCurvePanel();
|
||||
|
||||
enum ProgressStatus {
|
||||
kProgressNone,
|
||||
kProgressShow,
|
||||
@@ -138,6 +136,7 @@ private:
|
||||
// Standard panels
|
||||
NodePanel* node_panel_;
|
||||
ParamPanel* param_panel_;
|
||||
CurvePanel* curve_panel_;
|
||||
SequenceViewerPanel* sequence_viewer_panel_;
|
||||
FootageViewerPanel* footage_viewer_panel_;
|
||||
QList<ProjectPanel*> project_panels_;
|
||||
@@ -146,7 +145,6 @@ private:
|
||||
QList<TimelinePanel*> timeline_panels_;
|
||||
AudioMonitorPanel* audio_monitor_panel_;
|
||||
TaskManagerPanel* task_man_panel_;
|
||||
QList<CurvePanel*> curve_panels_;
|
||||
PixelSamplerPanel* pixel_sampler_panel_;
|
||||
QList<ScopePanel*> scope_panels_;
|
||||
NodeTablePanel* table_panel_;
|
||||
|
||||
Reference in New Issue
Block a user