This commit is contained in:
itsmattkc
2021-07-24 09:37:17 -07:00
29 changed files with 426 additions and 115 deletions
+120 -40
View File
@@ -353,42 +353,12 @@ void NodeView::CopySelected(bool cut)
void NodeView::Paste()
{
if (!graph_) {
return;
}
paste_command_ = new MultiUndoCommand();
QVector<Node*> pasted_nodes = PasteNodesFromClipboard(graph_, paste_command_);
if (!pasted_nodes.isEmpty()) {
paste_command_->add_child(new NodeViewAttachNodesToCursor(this, pasted_nodes));
}
paste_command_->redo();
PasteNodesInternal();
}
void NodeView::Duplicate()
{
if (!graph_) {
return;
}
QVector<Node*> selected = scene_.GetSelectedNodes();
if (selected.isEmpty()) {
return;
}
paste_command_ = new MultiUndoCommand();
QVector<Node*> duplicated_nodes = Node::CopyDependencyGraph(selected, paste_command_);
if (!duplicated_nodes.isEmpty()) {
paste_command_->add_child(new NodeViewAttachNodesToCursor(this, duplicated_nodes));
}
paste_command_->redo();
PasteNodesInternal(scene_.GetSelectedNodes());
}
void NodeView::SetColorLabel(int index)
@@ -1005,6 +975,10 @@ void NodeView::ShowContextMenu(const QPoint &pos)
void NodeView::CreateNodeSlot(QAction *action)
{
if (!graph_) {
return;
}
Node* new_node = NodeFactory::CreateFromMenuAction(action);
if (new_node) {
@@ -1067,6 +1041,13 @@ void NodeView::OpenSelectedNodeInViewer()
void NodeView::RemoveNode(Node *node)
{
for (const Node::OutputConnection &oc : node->output_connections()) {
scene_.RemoveEdge(oc.first, oc.second);
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
scene_.RemoveEdge(it->second, it->first);
}
positions_.remove(scene_.item_map().value(node));
scene_.RemoveNode(node);
}
@@ -1126,14 +1107,7 @@ void NodeView::RemoveNodePosition(Node *node, Node *relative)
}
if (!found) {
for (const Node::OutputConnection &oc : node->output_connections()) {
scene_.RemoveEdge(oc.first, oc.second);
}
for (auto it=node->input_connections().cbegin(); it!=node->input_connections().cend(); it++) {
scene_.RemoveEdge(it->second, it->first);
}
positions_.remove(item);
scene_.RemoveNode(node);
RemoveNode(node);
}
}
@@ -1294,6 +1268,65 @@ bool NodeView::eventFilter(QObject *object, QEvent *event)
return super::eventFilter(object, event);
}
void NodeView::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node *> &nodes, void *userdata)
{
writer->writeStartElement(QStringLiteral("pos"));
for (Node *n : nodes) {
NodeViewItem *item = scene_.item_map().value(n);
QPointF pos = item->GetNodePosition();
writer->writeStartElement(QStringLiteral("node"));
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(n)));
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.x()));
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.y()));
writer->writeEndElement(); // node
}
writer->writeEndElement(); // pos
}
void NodeView::PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void *userdata)
{
NodeGraph::PositionMap *map = static_cast<NodeGraph::PositionMap *>(userdata);
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("pos")) {
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("node")) {
Node *n = nullptr;
QPointF pos;
XMLAttributeLoop(reader, attr) {
if (attr.name() == QStringLiteral("ptr")) {
n = xml_node_data.node_ptrs.value(attr.value().toULongLong());
break;
}
}
while (XMLReadNextStartElement(reader)) {
if (reader->name() == QStringLiteral("x")) {
pos.setX(reader->readElementText().toDouble());
} else if (reader->name() == QStringLiteral("y")) {
pos.setY(reader->readElementText().toDouble());
} else {
reader->skipCurrentElement();
}
}
if (n) {
map->insert(n, pos);
}
} else {
reader->skipCurrentElement();
}
}
} else {
reader->skipCurrentElement();
}
}
}
void NodeView::ZoomFromKeyboard(double multiplier)
{
QPoint cursor_pos = mapFromGlobal(QCursor::pos());
@@ -1596,6 +1629,53 @@ NodeViewItem *NodeView::UpdateNodeItem(Node *node, bool ignore_own_context)
return item;
}
void NodeView::PasteNodesInternal(const QVector<Node *> &duplicate_nodes)
{
// If no graph, do nothing
if (!graph_) {
return;
}
paste_command_ = new MultiUndoCommand();
// If duplicating nodes, duplicate, otherwise paste
QVector<Node*> new_nodes;
NodeGraph::PositionMap map;
if (duplicate_nodes.isEmpty()) {
new_nodes = PasteNodesFromClipboard(graph_, paste_command_, &map);
for (auto it=new_nodes.cbegin(); it!=new_nodes.cend(); it++) {
for (Node *context : qAsConst(filter_nodes_)) {
paste_command_->add_child(new NodeSetPositionCommand(*it, context, map.value(*it), false));
}
}
} else {
new_nodes = Node::CopyDependencyGraph(duplicate_nodes, paste_command_);
for (int i=0; i<duplicate_nodes.size(); i++) {
Node *src = duplicate_nodes.at(i);
Node *copy = new_nodes.at(i);
for (Node *context : qAsConst(filter_nodes_)) {
QPointF p = scene_.item_map().value(src)->GetNodePosition();
paste_command_->add_child(new NodeSetPositionCommand(copy, context, p, false));
}
}
}
// If no nodes were retrieved, do nothing
if (new_nodes.isEmpty()) {
delete paste_command_;
paste_command_ = nullptr;
return;
}
// Attach nodes to cursor
paste_command_->add_child(new NodeViewAttachNodesToCursor(this, new_nodes));
paste_command_->redo();
}
NodeView::NodeViewAttachNodesToCursor::NodeViewAttachNodesToCursor(NodeView *view, const QVector<Node *> &nodes) :
view_(view),
nodes_(nodes)
+5
View File
@@ -112,6 +112,9 @@ protected:
virtual bool eventFilter(QObject *object, QEvent *event) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node*> &nodes, void* userdata) override;
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
private:
void AttachNodesToCursor(const QVector<Node *> &nodes);
@@ -142,6 +145,8 @@ private:
NodeViewItem *UpdateNodeItem(Node *node, bool ignore_own_context = false);
void PasteNodesInternal(const QVector<Node*> &duplicate_nodes = QVector<Node *>());
class NodeViewAttachNodesToCursor : public UndoCommand
{
public:
@@ -30,6 +30,7 @@
#include "common/define.h"
#include "core.h"
#include "dialog/nodeproperties/nodepropertiesdialog.h"
#include "dialog/sequence/sequence.h"
#include "projectexplorerundo.h"
#include "task/precache/precachetask.h"
@@ -439,11 +440,12 @@ void ProjectExplorer::ShowItemPropertiesDialog()
// FIXME: Support for multiple items
if (dynamic_cast<Footage*>(sel)) {
Core::instance()->LabelNodes({static_cast<Footage*>(sel)});
NodePropertiesDialog npd(sel, static_cast<Footage*>(sel)->GetVideoParams().time_base(), this);
npd.exec();
} else if (dynamic_cast<Folder*>(sel)) {
Core::instance()->LabelNodes({static_cast<Folder*>(sel)});
Core::instance()->LabelNodes(context_menu_items_);
} else if (dynamic_cast<Sequence*>(sel)) {
+1 -1
View File
@@ -74,7 +74,7 @@ void ScopeBase::OnPaint()
if (!managed_tex_ || !managed_tex_up_to_date_
|| managed_tex_->params() != texture_->params()) {
managed_tex_ = renderer()->CreateTexture(texture_->params());
renderer()->BlitColorManaged(color_service(), texture_, true, managed_tex_.get());
renderer()->BlitColorManaged(color_service(), texture_, Renderer::kAlphaNone, managed_tex_.get());
}
DrawScope(managed_tex_, pipeline_);
+4 -2
View File
@@ -28,6 +28,7 @@
#include "core.h"
#include "common/range.h"
#include "common/timecodefunctions.h"
#include "dialog/nodeproperties/nodepropertiesdialog.h"
#include "dialog/sequence/sequence.h"
#include "node/block/transition/transition.h"
#include "tool/add.h"
@@ -295,7 +296,7 @@ void TimelineWidget::DisconnectNodeEvent(ViewerOutput *n)
}
}
void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata)
void TimelineWidget::CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node *> &nodes, void* userdata)
{
// Cache the earliest in point so all copied clips have a "relative" in point that can be pasted anywhere
QVector<Block*>& selected = *static_cast<QVector<Block*>*>(userdata);
@@ -992,7 +993,8 @@ void TimelineWidget::ShowContextMenu()
nodes.append(i);
}
Core::instance()->LabelNodes(nodes);
NodePropertiesDialog npd(nodes, timebase(), this);
npd.exec();
});
}
+1 -1
View File
@@ -248,7 +248,7 @@ protected:
virtual void ConnectNodeEvent(ViewerOutput* n) override;
virtual void DisconnectNodeEvent(ViewerOutput* n) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, void* userdata) override;
virtual void CopyNodesToClipboardInternal(QXmlStreamWriter *writer, const QVector<Node*> &nodes, void* userdata) override;
virtual void PasteNodesFromClipboardInternal(QXmlStreamReader *reader, XMLNodeData &xml_node_data, void* userdata) override;
struct BlockPasteData {
@@ -589,6 +589,10 @@ void TimelineView::ConnectTrackList(TrackList *list)
void TimelineView::SetBeamCursor(const TimelineCoordinate &coord)
{
if (!connected_track_list_) {
return;
}
bool update_required = coord.GetTrack().type() == connected_track_list_->type()
|| cursor_coord_.GetTrack().type() == connected_track_list_->type();
+1 -1
View File
@@ -390,7 +390,7 @@ void ViewerDisplayWidget::OnPaint()
texture_to_draw = deinterlace_texture_;
}
renderer()->BlitColorManaged(color_service(), texture_to_draw, true, device_params, false,
renderer()->BlitColorManaged(color_service(), texture_to_draw, Renderer::kAlphaNone, device_params, false,
combined_matrix_flipped_, crop_matrix_);
}
}