show node properties as a sidebar
This commit is contained in:
+51
-9
@@ -4,6 +4,7 @@
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QGraphicsProxyWidget>
|
||||
#include <QSplitter>
|
||||
#include <QDebug>
|
||||
|
||||
#include "global/global.h"
|
||||
@@ -11,23 +12,39 @@
|
||||
NodeEditor::NodeEditor(QWidget *parent) :
|
||||
EffectsPanel(parent),
|
||||
view_(&scene_)
|
||||
{
|
||||
{
|
||||
setWindowTitle(tr("Node Editor"));
|
||||
resize(720, 480);
|
||||
|
||||
QWidget* central_widget = new QWidget();
|
||||
setWidget(central_widget);
|
||||
|
||||
QSplitter* splitter = new QSplitter();
|
||||
splitter->setOrientation(Qt::Horizontal);
|
||||
splitter->setChildrenCollapsible(false);
|
||||
|
||||
splitter->addWidget(&view_);
|
||||
|
||||
QSizePolicy view_policy;
|
||||
view_policy.setHorizontalStretch(1);
|
||||
view_.setSizePolicy(view_policy);
|
||||
view_.setInteractive(true);
|
||||
view_.setDragMode(QGraphicsView::RubberBandDrag);
|
||||
|
||||
prop_layout_ = new QVBoxLayout(&props_);
|
||||
prop_layout_->setMargin(0);
|
||||
prop_layout_->setSpacing(0);
|
||||
prop_layout_->addStretch();
|
||||
splitter->addWidget(&props_);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(central_widget);
|
||||
layout->setSpacing(0);
|
||||
layout->setMargin(0);
|
||||
|
||||
layout->addWidget(&view_);
|
||||
|
||||
view_.setInteractive(true);
|
||||
view_.setDragMode(QGraphicsView::RubberBandDrag);
|
||||
layout->addWidget(splitter);
|
||||
|
||||
connect(&scene_, SIGNAL(changed(const QList<QRectF>&)), this, SLOT(ItemsChanged()));
|
||||
connect(&scene_, SIGNAL(selectionChanged()), this, SLOT(UpdateNodeProperties()));
|
||||
connect(&view_, SIGNAL(RequestContextMenu()), this, SLOT(ContextMenu()));
|
||||
}
|
||||
|
||||
@@ -49,18 +66,21 @@ void NodeEditor::LoadEvent()
|
||||
|
||||
for (int i=0;i<open_effects_.size();i++) {
|
||||
EffectUI* effect_ui = open_effects_.at(i);
|
||||
Node* node = effect_ui->GetEffect();
|
||||
|
||||
if (effect_ui->GetEffect()->parent_clip == first_clip) {
|
||||
if (node->parent_clip == first_clip) {
|
||||
NodeUI* node_ui = new NodeUI();
|
||||
|
||||
effect_ui->SetNodeParent(node_ui);
|
||||
effect_ui->SetSelectable(false);
|
||||
|
||||
node_ui->SetWidget(effect_ui);
|
||||
node_ui->SetNode(node);
|
||||
node_ui->AddToScene(&scene_);
|
||||
node_ui->setPos(effect_ui->GetEffect()->pos());
|
||||
|
||||
nodes_.append(node_ui);
|
||||
|
||||
effect_ui->setVisible(false);
|
||||
prop_layout_->insertWidget(prop_layout_->count()-1, effect_ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +173,7 @@ void NodeEditor::ItemsChanged()
|
||||
}
|
||||
|
||||
foreach (NodeUI* node, nodes_) {
|
||||
node->Widget()->GetEffect()->SetPos(node->pos());
|
||||
node->GetNode()->SetPos(node->pos());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,3 +190,25 @@ void NodeEditor::ContextMenu()
|
||||
olive::Global->ShowEffectMenu(EFFECT_TYPE_EFFECT, c->type(), {c});
|
||||
}
|
||||
}
|
||||
|
||||
void NodeEditor::UpdateNodeProperties()
|
||||
{
|
||||
// Find matching widget
|
||||
for (int j=0;j<open_effects_.size();j++) {
|
||||
open_effects_.at(j)->setVisible(false);
|
||||
}
|
||||
|
||||
QList<QGraphicsItem*> sel = scene_.selectedItems();
|
||||
for (int i=0;i<sel.size();i++) {
|
||||
NodeUI* node_ui = dynamic_cast<NodeUI*>(sel.at(i));
|
||||
|
||||
if (node_ui != nullptr) {
|
||||
for (int j=0;j<open_effects_.size();j++) {
|
||||
if (open_effects_.at(j)->GetEffect() == node_ui->GetNode()) {
|
||||
open_effects_.at(j)->setVisible(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,9 +23,12 @@ protected:
|
||||
private:
|
||||
QGraphicsScene scene_;
|
||||
NodeView view_;
|
||||
QWidget props_;
|
||||
QVector<NodeUI*> nodes_;
|
||||
QVector<NodeEdgeUI*> edges_;
|
||||
QVector<EffectRow*> connected_rows_;
|
||||
QVBoxLayout* prop_layout_;
|
||||
QVector<EffectUI*> nodes_open_in_props_;
|
||||
|
||||
void ClearEdges();
|
||||
void LoadEdges();
|
||||
@@ -37,7 +40,7 @@ private slots:
|
||||
void ItemsChanged();
|
||||
void ReloadEdges();
|
||||
void ContextMenu();
|
||||
|
||||
void UpdateNodeProperties();
|
||||
};
|
||||
|
||||
#endif // NODEEDITOR_H
|
||||
|
||||
+2
-1
@@ -153,7 +153,8 @@ void clear_audio_ibuffer() {
|
||||
}
|
||||
|
||||
int current_audio_freq() {
|
||||
return olive::Global->is_exporting() ? audio_rendering_rate : audio_output->format().sampleRate();
|
||||
return olive::Global->is_exporting()
|
||||
? audio_rendering_rate : audio_output->format().sampleRate();
|
||||
}
|
||||
|
||||
qint64 get_buffer_offset_from_frame(double framerate, long frame) {
|
||||
|
||||
+1
-27
@@ -30,8 +30,7 @@
|
||||
#include "panels/panels.h"
|
||||
|
||||
EffectUI::EffectUI(Node* e) :
|
||||
effect_(e),
|
||||
node_parent_(nullptr)
|
||||
effect_(e)
|
||||
{
|
||||
Q_ASSERT(e != nullptr);
|
||||
|
||||
@@ -282,31 +281,6 @@ bool EffectUI::IsAttachedToClip(Clip *c)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EffectUI::SetNodeParent(NodeUI *parent)
|
||||
{
|
||||
node_parent_ = parent;
|
||||
}
|
||||
|
||||
void EffectUI::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
if (node_parent_ != nullptr) {
|
||||
node_parent_->Resize(event->size());
|
||||
}
|
||||
}
|
||||
|
||||
bool EffectUI::event(QEvent *event)
|
||||
{
|
||||
if (node_parent_ != nullptr
|
||||
&& (event->type() == QEvent::MouseButtonPress
|
||||
|| event->type() == QEvent::MouseButtonRelease
|
||||
|| event->type() == QEvent::MouseMove
|
||||
|| event->type() == QEvent::MouseButtonDblClick)
|
||||
&& node_parent_->scene()->sendEvent(node_parent_, event)) {
|
||||
return true;
|
||||
}
|
||||
return CollapsibleWidget::event(event);
|
||||
}
|
||||
|
||||
QWidget *EffectUI::Widget(int row, int field)
|
||||
{
|
||||
return widgets_.at(row).at(field);
|
||||
|
||||
@@ -133,11 +133,7 @@ public:
|
||||
*/
|
||||
bool IsAttachedToClip(Clip* c);
|
||||
|
||||
void SetNodeParent(NodeUI* parent);
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent* event) override;
|
||||
virtual bool event(QEvent* event) override;
|
||||
|
||||
signals:
|
||||
/**
|
||||
@@ -203,11 +199,6 @@ private:
|
||||
*/
|
||||
QVector<KeyframeNavigator*> keyframe_navigators_;
|
||||
|
||||
/**
|
||||
* @brief Internal reference to node parent
|
||||
*/
|
||||
NodeUI* node_parent_;
|
||||
|
||||
/**
|
||||
* @brief Attach a KeyframeNavigator object to an EffectRow.
|
||||
*
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ void NodeEdgeUI::adjust()
|
||||
if (node != nullptr) {
|
||||
|
||||
// Check if this node has the output row
|
||||
int row_index = node->Widget()->GetEffect()->IndexOfRow(edge_->output());
|
||||
int row_index = node->GetNode()->IndexOfRow(edge_->output());
|
||||
|
||||
if (row_index > -1) {
|
||||
output_node_ = node;
|
||||
@@ -34,7 +34,7 @@ void NodeEdgeUI::adjust()
|
||||
}
|
||||
|
||||
// Check if this node has the input row
|
||||
row_index = node->Widget()->GetEffect()->IndexOfRow(edge_->input());
|
||||
row_index = node->GetNode()->IndexOfRow(edge_->input());
|
||||
|
||||
if (row_index > -1) {
|
||||
input_node_ = node;
|
||||
|
||||
+59
-42
@@ -15,11 +15,11 @@
|
||||
#include "ui/nodeedgeui.h"
|
||||
|
||||
const int kRoundedRectRadius = 5;
|
||||
const int kTextPadding = 4;
|
||||
const int kNodePlugSize = 12;
|
||||
|
||||
NodeUI::NodeUI() :
|
||||
central_widget_(nullptr),
|
||||
proxy_(nullptr),
|
||||
node_(nullptr),
|
||||
drag_destination_(nullptr),
|
||||
clicked_socket_(-1)
|
||||
{
|
||||
@@ -27,34 +27,23 @@ NodeUI::NodeUI() :
|
||||
setFlag(QGraphicsItem::ItemIsSelectable, true);
|
||||
}
|
||||
|
||||
NodeUI::~NodeUI()
|
||||
{
|
||||
if (proxy_ != nullptr) {
|
||||
proxy_->setParentItem(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeUI::AddToScene(QGraphicsScene *scene)
|
||||
{
|
||||
scene->addItem(this);
|
||||
|
||||
if (central_widget_ != nullptr) {
|
||||
proxy_ = scene->addWidget(central_widget_);
|
||||
proxy_->setPos(pos() + QPoint(1 + kRoundedRectRadius, 1 + kRoundedRectRadius));
|
||||
proxy_->setParentItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeUI::Resize(const QSize &s)
|
||||
void NodeUI::SetNode(Node *n)
|
||||
{
|
||||
node_ = n;
|
||||
|
||||
QRectF rectangle;
|
||||
|
||||
rectangle.setTopLeft(pos());
|
||||
rectangle.setSize(s + 2 * QSize(kRoundedRectRadius, kRoundedRectRadius));
|
||||
rectangle.setSize(QSizeF(200, GetRowY(node_->row_count())));
|
||||
|
||||
QRectF inner_rect = rectangle;
|
||||
inner_rect.translate(kNodePlugSize / 2, 0);
|
||||
|
||||
rectangle.setWidth(rectangle.width() + kNodePlugSize);
|
||||
inner_rect.setX(inner_rect.x() + kNodePlugSize/2);
|
||||
inner_rect.setWidth(inner_rect.width() - kNodePlugSize/2);
|
||||
|
||||
drag_path_ = QPainterPath();
|
||||
drag_path_.addRoundedRect(inner_rect, kRoundedRectRadius, kRoundedRectRadius);
|
||||
@@ -62,20 +51,16 @@ void NodeUI::Resize(const QSize &s)
|
||||
setRect(rectangle);
|
||||
}
|
||||
|
||||
void NodeUI::SetWidget(EffectUI *widget)
|
||||
Node *NodeUI::GetNode()
|
||||
{
|
||||
central_widget_ = widget;
|
||||
}
|
||||
|
||||
EffectUI *NodeUI::Widget()
|
||||
{
|
||||
return central_widget_;
|
||||
return node_;
|
||||
}
|
||||
|
||||
void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(widget)
|
||||
|
||||
// Draw node sockets
|
||||
QVector<QRectF> sockets = GetNodeSocketRects();
|
||||
if (!sockets.isEmpty()) {
|
||||
painter->setPen(Qt::black);
|
||||
@@ -86,6 +71,7 @@ void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
|
||||
}
|
||||
}
|
||||
|
||||
// Draw main background rounded rectangle
|
||||
QPalette palette = qApp->palette();
|
||||
|
||||
if (option->state & QStyle::State_Selected) {
|
||||
@@ -95,6 +81,34 @@ void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QW
|
||||
}
|
||||
painter->setBrush(palette.window());
|
||||
painter->drawPath(drag_path_);
|
||||
|
||||
// Draw node title
|
||||
painter->setPen(palette.text().color());
|
||||
int left_text_x = rect().x() + kNodePlugSize/2 + kTextPadding;
|
||||
painter->drawText(left_text_x,
|
||||
GetRowY(-1) + qApp->fontMetrics().ascent(),
|
||||
node_->name());
|
||||
|
||||
// Draw node row names
|
||||
for (int i=0;i<node_->row_count();i++) {
|
||||
int text_x;
|
||||
|
||||
if (node_->row(i)->IsNodeOutput()) {
|
||||
// right alignment
|
||||
text_x = rect().right() - kNodePlugSize/2 - qApp->fontMetrics().width(node_->row(i)->name()) - kTextPadding;
|
||||
} else {
|
||||
// left alignment
|
||||
text_x = left_text_x;
|
||||
}
|
||||
|
||||
painter->drawText(text_x,
|
||||
GetRowY(i) + qApp->fontMetrics().ascent(),
|
||||
node_->row(i)->name());
|
||||
}
|
||||
|
||||
// Draw title splitter line
|
||||
int line_y = GetRowY(-1) + qApp->fontMetrics().height() + kTextPadding/2;
|
||||
painter->drawLine(rect().x() + kNodePlugSize/2, line_y, rect().right() - kNodePlugSize/2, line_y);
|
||||
}
|
||||
|
||||
void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
@@ -114,8 +128,8 @@ void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
if (clicked_socket_ > -1) {
|
||||
|
||||
// See if this socket already has an edge connected
|
||||
QVector<NodeEdgePtr> edges = central_widget_->GetEffect()->row(clicked_socket_)->edges();
|
||||
if (!edges.isEmpty() && edges.last()->input()->GetParentEffect() == central_widget_->GetEffect()) {
|
||||
QVector<NodeEdgePtr> edges = node_->row(clicked_socket_)->edges();
|
||||
if (!edges.isEmpty() && edges.last()->input()->GetParentEffect() == node_) {
|
||||
|
||||
NodeEdge* e = edges.last().get();
|
||||
|
||||
@@ -144,7 +158,7 @@ void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
// Start a new edge here
|
||||
drag_line_start_ = pos() + sockets.at(clicked_socket_).center();
|
||||
|
||||
drag_source_ = central_widget_->GetEffect()->row(clicked_socket_);
|
||||
drag_source_ = node_->row(clicked_socket_);
|
||||
|
||||
}
|
||||
|
||||
@@ -254,18 +268,19 @@ QVector<QRectF> NodeUI::GetNodeSocketRects()
|
||||
{
|
||||
QVector<QRectF> rects;
|
||||
|
||||
if (proxy_ != nullptr) {
|
||||
Node* e = central_widget_->GetEffect();
|
||||
if (node_ != nullptr) {
|
||||
Node* e = node_;
|
||||
|
||||
for (int i=0;i<e->row_count();i++) {
|
||||
|
||||
EffectRow* row = e->row(i);
|
||||
qreal x = (row->IsNodeOutput()) ? rect().right() - kNodePlugSize : rect().x();
|
||||
int y = central_widget_->GetRowY(i);
|
||||
EffectRow* row = e->row(i);
|
||||
|
||||
if (row->IsNodeInput() || row->IsNodeOutput()) {
|
||||
qreal x = (row->IsNodeOutput()) ? rect().right() - kNodePlugSize : rect().x();
|
||||
int y = GetRowY(i) + qApp->fontMetrics().height()/2;
|
||||
|
||||
rects.append(QRectF(x,
|
||||
proxy_->pos().y() + y - kNodePlugSize/2,
|
||||
rect().y() + y - kNodePlugSize/2,
|
||||
kNodePlugSize,
|
||||
kNodePlugSize));
|
||||
}
|
||||
@@ -277,11 +292,8 @@ QVector<QRectF> NodeUI::GetNodeSocketRects()
|
||||
|
||||
EffectRow *NodeUI::GetRowFromIndex(int i)
|
||||
{
|
||||
if (central_widget_ != nullptr) {
|
||||
Node* e = central_widget_->GetEffect();
|
||||
if (i < e->row_count()) {
|
||||
return e->row(i);
|
||||
}
|
||||
if (node_ != nullptr && i < node_->row_count()) {
|
||||
return node_->row(i);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -296,7 +308,7 @@ NodeUI *NodeUI::FindUIFromNode(Node* n)
|
||||
|
||||
// Check if this node has the specified
|
||||
|
||||
if (node->Widget()->GetEffect() == n) {
|
||||
if (node->node_ == n) {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
@@ -304,3 +316,8 @@ NodeUI *NodeUI::FindUIFromNode(Node* n)
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int NodeUI::GetRowY(int index)
|
||||
{
|
||||
return (qApp->fontMetrics().height() + kTextPadding) * (index + 1) + kTextPadding;
|
||||
}
|
||||
|
||||
+5
-6
@@ -12,12 +12,11 @@ class Node;
|
||||
class NodeUI : public QGraphicsRectItem {
|
||||
public:
|
||||
NodeUI();
|
||||
virtual ~NodeUI() override;
|
||||
|
||||
void AddToScene(QGraphicsScene* scene);
|
||||
void Resize(const QSize& s);
|
||||
void SetWidget(EffectUI* widget);
|
||||
EffectUI* Widget();
|
||||
//void Resize(const QSize& s);
|
||||
void SetNode(Node* n);
|
||||
Node* GetNode();
|
||||
|
||||
QVector<QRectF> GetNodeSocketRects();
|
||||
|
||||
@@ -31,9 +30,9 @@ protected:
|
||||
private:
|
||||
EffectRow *GetRowFromIndex(int i);
|
||||
NodeUI* FindUIFromNode(Node* n);
|
||||
int GetRowY(int index);
|
||||
|
||||
EffectUI* central_widget_;
|
||||
QGraphicsProxyWidget* proxy_;
|
||||
Node* node_;
|
||||
|
||||
QGraphicsPathItem* drag_line_;
|
||||
QPointF drag_line_start_;
|
||||
|
||||
Reference in New Issue
Block a user