nodes: added ability to label nodes
This commit is contained in:
@@ -31,6 +31,7 @@ Node* XMLLoadNode(QXmlStreamReader* reader)
|
||||
QString node_id;
|
||||
quintptr node_ptr = 0;
|
||||
QPointF node_pos;
|
||||
QString node_label;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
@@ -45,6 +46,8 @@ Node* XMLLoadNode(QXmlStreamReader* reader)
|
||||
node_pos.setX(pos.at(0).toDouble());
|
||||
node_pos.setY(pos.at(1).toDouble());
|
||||
}
|
||||
} else if (attr.name() == QStringLiteral("label")) {
|
||||
node_label = attr.value().toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +61,7 @@ Node* XMLLoadNode(QXmlStreamReader* reader)
|
||||
if (node) {
|
||||
node->setProperty("xml_ptr", node_ptr);
|
||||
node->SetPosition(node_pos);
|
||||
node->SetLabel(node_label);
|
||||
} else {
|
||||
qWarning() << "Failed to load" << node_id << "- no node with that ID is installed";
|
||||
}
|
||||
|
||||
@@ -107,6 +107,9 @@ void Node::Save(QXmlStreamWriter *writer, const QString &custom_name) const
|
||||
QStringLiteral("%1:%2").arg(QString::number(GetPosition().x()),
|
||||
QString::number(GetPosition().y())));
|
||||
|
||||
writer->writeAttribute(QStringLiteral("label"),
|
||||
GetLabel());
|
||||
|
||||
foreach (NodeParam* param, parameters()) {
|
||||
param->Save(writer);
|
||||
}
|
||||
@@ -277,6 +280,20 @@ QList<NodeOutput *> Node::GetOutputs() const
|
||||
return {output_};
|
||||
}
|
||||
|
||||
const QString &Node::GetLabel() const
|
||||
{
|
||||
return label_;
|
||||
}
|
||||
|
||||
void Node::SetLabel(const QString &s)
|
||||
{
|
||||
if (label_ != s) {
|
||||
label_ = s;
|
||||
|
||||
emit LabelChanged(label_);
|
||||
}
|
||||
}
|
||||
|
||||
void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
|
||||
{
|
||||
Q_ASSERT(source->id() == destination->id());
|
||||
@@ -295,6 +312,9 @@ void Node::CopyInputs(Node *source, Node *destination, bool include_connections)
|
||||
NodeInput::CopyValues(src, dst, include_connections);
|
||||
}
|
||||
}
|
||||
|
||||
destination->SetPosition(source->GetPosition());
|
||||
destination->SetLabel(source->GetLabel());
|
||||
}
|
||||
|
||||
bool Node::CanBeDeleted() const
|
||||
|
||||
@@ -359,6 +359,9 @@ public:
|
||||
|
||||
QList<NodeOutput*> GetOutputs() const;
|
||||
|
||||
const QString& GetLabel() const;
|
||||
void SetLabel(const QString& s);
|
||||
|
||||
protected:
|
||||
void AddInput(NodeInput* input);
|
||||
|
||||
@@ -396,6 +399,11 @@ signals:
|
||||
*/
|
||||
void PositionChanged(const QPointF& pos);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when SetLabel() is called
|
||||
*/
|
||||
void LabelChanged(const QString& s);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Add a parameter to this node
|
||||
@@ -431,6 +439,11 @@ private:
|
||||
*/
|
||||
QPointF position_;
|
||||
|
||||
/**
|
||||
* @brief Custom user label for node
|
||||
*/
|
||||
QString label_;
|
||||
|
||||
private slots:
|
||||
void InputChanged(const OLIVE_NAMESPACE::TimeRange &range);
|
||||
|
||||
|
||||
@@ -73,6 +73,8 @@ NodeParamViewItem::NodeParamViewItem(Node *node, QWidget *parent) :
|
||||
connect(title_bar_collapse_btn_, &QPushButton::toggled, body_, &NodeParamViewItemBody::setVisible);
|
||||
main_layout->addWidget(body_);
|
||||
|
||||
connect(node_, &Node::LabelChanged, this, &NodeParamViewItem::Retranslate);
|
||||
|
||||
Retranslate();
|
||||
}
|
||||
|
||||
@@ -111,7 +113,11 @@ void NodeParamViewItem::Retranslate()
|
||||
{
|
||||
node_->Retranslate();
|
||||
|
||||
title_bar_lbl_->setText(node_->Name());
|
||||
if (node_->GetLabel().isEmpty()) {
|
||||
title_bar_lbl_->setText(node_->Name());
|
||||
} else {
|
||||
title_bar_lbl_->setText(tr("%1 (%2)").arg(node_->GetLabel(), node_->Name()));
|
||||
}
|
||||
|
||||
body_->Retranslate();
|
||||
}
|
||||
|
||||
@@ -129,8 +129,6 @@ protected:
|
||||
virtual void changeEvent(QEvent *e) override;
|
||||
|
||||
private:
|
||||
void Retranslate();
|
||||
|
||||
NodeParamViewItemTitleBar* title_bar_;
|
||||
|
||||
QLabel* title_bar_lbl_;
|
||||
@@ -143,6 +141,9 @@ private:
|
||||
|
||||
rational time_;
|
||||
|
||||
private slots:
|
||||
void Retranslate();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "nodeview.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include "core.h"
|
||||
@@ -208,7 +209,6 @@ void NodeView::Duplicate()
|
||||
Node* copy = n->copy();
|
||||
|
||||
Node::CopyInputs(n, copy, false);
|
||||
copy->SetPosition(n->GetPosition());
|
||||
|
||||
duplicated_nodes.append(copy);
|
||||
|
||||
@@ -401,6 +401,15 @@ void NodeView::ShowContextMenu(const QPoint &pos)
|
||||
m.addSeparator();
|
||||
|
||||
if (itemAt(pos)) {
|
||||
QList<NodeViewItem*> selected = scene_.GetSelectedItems();
|
||||
|
||||
if (selected.size() == 1) {
|
||||
QAction* label_action = m.addAction(tr("Label"));
|
||||
connect(label_action, &QAction::triggered, this, &NodeView::ContextMenuLabelNode);
|
||||
|
||||
m.addSeparator();
|
||||
}
|
||||
|
||||
QAction* autopos = m.addAction(tr("Auto-Position"));
|
||||
connect(autopos, &QAction::triggered, this, &NodeView::AutoPositionDescendents);
|
||||
} else {
|
||||
@@ -462,6 +471,30 @@ void NodeView::AutoPositionDescendents()
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::ContextMenuLabelNode()
|
||||
{
|
||||
QList<Node*> nodes = scene_.GetSelectedNodes();
|
||||
|
||||
if (nodes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Node* n = nodes.first();
|
||||
|
||||
bool ok;
|
||||
|
||||
QString s = QInputDialog::getText(this,
|
||||
tr("Label Node"),
|
||||
tr("Set node label"),
|
||||
QLineEdit::Normal,
|
||||
n->GetLabel(),
|
||||
&ok);
|
||||
|
||||
if (ok) {
|
||||
n->SetLabel(s);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeView::PlaceNode(NodeViewItem *n, const QPointF &pos)
|
||||
{
|
||||
QRectF destination_rect = n->rect();
|
||||
|
||||
@@ -141,6 +141,11 @@ private slots:
|
||||
*/
|
||||
void AutoPositionDescendents();
|
||||
|
||||
/**
|
||||
* @brief Receiver for labelling a node from the context menu
|
||||
*/
|
||||
void ContextMenuLabelNode();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -135,6 +135,11 @@ int NodeViewItem::DefaultItemWidth()
|
||||
return QFontMetricsWidth(QFontMetrics(QFont()), "HHHHHHHHHH");;
|
||||
}
|
||||
|
||||
int NodeViewItem::DefaultMaximumTextWidth()
|
||||
{
|
||||
return QFontMetricsWidth(QFontMetrics(QFont()), "HHHHHHHH");;
|
||||
}
|
||||
|
||||
int NodeViewItem::DefaultItemBorder()
|
||||
{
|
||||
return QFontMetrics(QFont()).height() / 12;
|
||||
@@ -262,8 +267,36 @@ void NodeViewItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
|
||||
painter->setPen(app_pal.color(QPalette::Text));
|
||||
|
||||
QString node_label;
|
||||
|
||||
if (node_->GetLabel().isEmpty()) {
|
||||
node_label = node_->ShortName();
|
||||
} else {
|
||||
node_label = node_->GetLabel();
|
||||
}
|
||||
|
||||
{
|
||||
QFont f;
|
||||
QFontMetrics fm(f);
|
||||
|
||||
int max_text_width = DefaultMaximumTextWidth();
|
||||
|
||||
if (QFontMetricsWidth(fm, node_label) > max_text_width) {
|
||||
QString concatenated;
|
||||
|
||||
do {
|
||||
node_label.chop(1);
|
||||
concatenated = QCoreApplication::translate("NodeViewItem", "%1...").arg(node_label);
|
||||
} while (QFontMetricsWidth(fm, concatenated) > max_text_width);
|
||||
|
||||
node_label = concatenated;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the text in a rect (the rect is sized around text already in the constructor)
|
||||
painter->drawText(title_bar_rect_, Qt::AlignCenter, node_->ShortName());
|
||||
painter->drawText(title_bar_rect_,
|
||||
Qt::AlignCenter,
|
||||
node_label);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ public:
|
||||
|
||||
static int DefaultItemWidth();
|
||||
|
||||
static int DefaultMaximumTextWidth();
|
||||
|
||||
static int DefaultItemBorder();
|
||||
|
||||
qreal DefaultItemHorizontalPadding() const;
|
||||
|
||||
@@ -180,10 +180,12 @@ void NodeViewScene::AddNode(Node* node)
|
||||
}
|
||||
|
||||
connect(node, &Node::PositionChanged, this, &NodeViewScene::NodePositionChanged);
|
||||
connect(node, &Node::LabelChanged, this, &NodeViewScene::NodeLabelChanged);
|
||||
}
|
||||
|
||||
void NodeViewScene::RemoveNode(Node *node)
|
||||
{
|
||||
disconnect(node, &Node::LabelChanged, this, &NodeViewScene::NodeLabelChanged);
|
||||
disconnect(node, &Node::PositionChanged, this, &NodeViewScene::NodePositionChanged);
|
||||
|
||||
delete item_map_.take(node);
|
||||
@@ -243,4 +245,9 @@ void NodeViewScene::NodePositionChanged(const QPointF &pos)
|
||||
item_map_.value(static_cast<Node*>(sender()))->SetNodePosition(pos);
|
||||
}
|
||||
|
||||
void NodeViewScene::NodeLabelChanged()
|
||||
{
|
||||
item_map_.value(static_cast<Node*>(sender()))->update();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -127,6 +127,10 @@ private slots:
|
||||
*/
|
||||
void NodePositionChanged(const QPointF& pos);
|
||||
|
||||
/**
|
||||
* @brief Receiver for when a node's label has changed
|
||||
*/
|
||||
void NodeLabelChanged();
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user