store expanded status in context
This commit is contained in:
+1
-1
@@ -437,7 +437,7 @@ void Core::CreateNewSequence()
|
||||
|
||||
command->add_child(new NodeAddCommand(active_project, new_sequence));
|
||||
command->add_child(new FolderAddChild(GetSelectedFolderInActiveProject(), new_sequence));
|
||||
command->add_child(new NodeSetPositionCommand(new_sequence, new_sequence, QPointF(0, 0)));
|
||||
command->add_child(new NodeSetPositionCommand(new_sequence, new_sequence, Node::Position()));
|
||||
|
||||
// Create and connect default nodes to new sequence
|
||||
new_sequence->add_default_nodes(command);
|
||||
|
||||
+11
-7
@@ -243,12 +243,16 @@ QIcon Node::icon() const
|
||||
return icon::New;
|
||||
}
|
||||
|
||||
QPointF Node::GetNodePositionInContext(Node *node)
|
||||
bool Node::SetNodePositionInContext(Node *node, const QPointF &pos)
|
||||
{
|
||||
return context_positions_.value(node);
|
||||
Position p = context_positions_.value(node);
|
||||
|
||||
p.position = pos;
|
||||
|
||||
return SetNodePositionInContext(node, p);
|
||||
}
|
||||
|
||||
bool Node::SetNodePositionInContext(Node *node, const QPointF &pos)
|
||||
bool Node::SetNodePositionInContext(Node *node, const Position &pos)
|
||||
{
|
||||
bool added = !ContextContainsNode(node);
|
||||
context_positions_.insert(node, pos);
|
||||
@@ -257,7 +261,7 @@ bool Node::SetNodePositionInContext(Node *node, const QPointF &pos)
|
||||
emit NodeAddedToContext(node);
|
||||
}
|
||||
|
||||
emit NodePositionInContextChanged(node, pos);
|
||||
emit NodePositionInContextChanged(node, pos.position);
|
||||
|
||||
return added;
|
||||
}
|
||||
@@ -2350,13 +2354,13 @@ Project *Node::ArrayResizeCommand::GetRelevantProject() const
|
||||
void NodeSetPositionCommand::redo()
|
||||
{
|
||||
if (!(added_ = !context_->ContextContainsNode(node_))) {
|
||||
old_pos_ = context_->GetNodePositionInContext(node_);
|
||||
old_pos_ = context_->GetNodePositionDataInContext(node_);
|
||||
}
|
||||
|
||||
if (added_) {
|
||||
context_->SetNodePositionInContext(node_, pos_);
|
||||
} else {
|
||||
move(context_, node_, pos_ - old_pos_, move_deps_);
|
||||
move(context_, node_, pos_.position - old_pos_.position, move_deps_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2365,7 +2369,7 @@ void NodeSetPositionCommand::undo()
|
||||
if (added_) {
|
||||
context_->RemoveNodeFromContext(node_);
|
||||
} else {
|
||||
move(context_, node_, old_pos_ - pos_, move_deps_);
|
||||
move(context_, node_, old_pos_.position - pos_.position, move_deps_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+61
-10
@@ -208,21 +208,77 @@ public:
|
||||
return HasInputWithID(id);
|
||||
}
|
||||
|
||||
using PositionMap = QHash<Node*, QPointF>;
|
||||
struct Position
|
||||
{
|
||||
Position(const QPointF &p = QPointF(0, 0), bool e = false)
|
||||
{
|
||||
position = p;
|
||||
expanded = e;
|
||||
}
|
||||
|
||||
QPointF position;
|
||||
bool expanded;
|
||||
|
||||
inline Position &operator+=(const Position &p)
|
||||
{
|
||||
position += p.position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Position &operator-=(const Position &p)
|
||||
{
|
||||
position -= p.position;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend inline const Position operator+(Position a, const Position &b)
|
||||
{
|
||||
a += b;
|
||||
return a;
|
||||
}
|
||||
|
||||
friend inline const Position operator-(Position a, const Position &b)
|
||||
{
|
||||
a -= b;
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
using PositionMap = QHash<Node*, Position>;
|
||||
const PositionMap &GetContextPositions() const
|
||||
{
|
||||
return context_positions_;
|
||||
}
|
||||
|
||||
bool IsNodeExpandedInContext(Node *node) const
|
||||
{
|
||||
return context_positions_.value(node).expanded;
|
||||
}
|
||||
|
||||
bool ContextContainsNode(Node *node) const
|
||||
{
|
||||
return context_positions_.contains(node);
|
||||
}
|
||||
|
||||
QPointF GetNodePositionInContext(Node *node);
|
||||
Position GetNodePositionDataInContext(Node *node)
|
||||
{
|
||||
return context_positions_.value(node);
|
||||
}
|
||||
|
||||
QPointF GetNodePositionInContext(Node *node)
|
||||
{
|
||||
return GetNodePositionDataInContext(node).position;
|
||||
}
|
||||
|
||||
bool SetNodePositionInContext(Node *node, const QPointF &pos);
|
||||
|
||||
bool SetNodePositionInContext(Node *node, const Position &pos);
|
||||
|
||||
void SetNodeExpandedInContext(Node *node, bool e)
|
||||
{
|
||||
context_positions_[node].expanded = e;
|
||||
}
|
||||
|
||||
bool RemoveNodeFromContext(Node *node);
|
||||
|
||||
/**
|
||||
@@ -1006,11 +1062,6 @@ protected:
|
||||
}
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted whenever the position is set through SetPosition()
|
||||
*/
|
||||
void PositionChanged(const QPointF& pos);
|
||||
|
||||
/**
|
||||
* @brief Signal emitted when SetLabel() is called
|
||||
*/
|
||||
@@ -1394,7 +1445,7 @@ using NodePtr = std::shared_ptr<Node>;
|
||||
class NodeSetPositionCommand : public UndoCommand
|
||||
{
|
||||
public:
|
||||
NodeSetPositionCommand(Node* node, Node* context, const QPointF& pos, bool move_dependencies_relatively = false)
|
||||
NodeSetPositionCommand(Node* node, Node* context, const Node::Position& pos, bool move_dependencies_relatively = false)
|
||||
{
|
||||
node_ = node;
|
||||
context_ = context;
|
||||
@@ -1417,8 +1468,8 @@ private:
|
||||
|
||||
Node* node_;
|
||||
Node* context_;
|
||||
QPointF pos_;
|
||||
QPointF old_pos_;
|
||||
Node::Position pos_;
|
||||
Node::Position old_pos_;
|
||||
bool added_;
|
||||
bool move_deps_;
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ QVector<Node *> NodeCopyPasteService::PasteNodesFromClipboard(NodeGraph *graph,
|
||||
|
||||
QVector<Node*> pasted_nodes;
|
||||
XMLNodeData xml_node_data;
|
||||
QMap<quintptr, QMap<quintptr, QPointF> > pasted_contexts;
|
||||
QMap<quintptr, QMap<quintptr, Node::Position> > pasted_contexts;
|
||||
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("olive")) {
|
||||
@@ -131,7 +131,7 @@ QVector<Node *> NodeCopyPasteService::PasteNodesFromClipboard(NodeGraph *graph,
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("context")) {
|
||||
// Get context ptr
|
||||
QMap<quintptr, QPointF> map;
|
||||
QMap<quintptr, Node::Position> map;
|
||||
quintptr context_ptr = 0;
|
||||
XMLAttributeLoop((&reader), attr) {
|
||||
if (attr.name() == QStringLiteral("ptr")) {
|
||||
@@ -144,7 +144,7 @@ QVector<Node *> NodeCopyPasteService::PasteNodesFromClipboard(NodeGraph *graph,
|
||||
while (XMLReadNextStartElement(&reader)) {
|
||||
if (reader.name() == QStringLiteral("node")) {
|
||||
quintptr node_ptr;
|
||||
QPointF node_pos;
|
||||
Node::Position node_pos;
|
||||
|
||||
if (Project::LoadPosition(&reader, &node_ptr, &node_pos)) {
|
||||
map.insert(node_ptr, node_pos);
|
||||
@@ -216,7 +216,7 @@ QVector<Node *> NodeCopyPasteService::PasteNodesFromClipboard(NodeGraph *graph,
|
||||
for (auto it=pasted_contexts.cbegin(); it!=pasted_contexts.cend(); it++) {
|
||||
Node *context = xml_node_data.node_ptrs.value(it.key());
|
||||
if (context) {
|
||||
const QMap<quintptr, QPointF> &map = it.value();
|
||||
auto map = it.value();
|
||||
for (auto jt=map.cbegin(); jt!=map.cend(); jt++) {
|
||||
Node *subnode = xml_node_data.node_ptrs.value(jt.key());
|
||||
if (subnode) {
|
||||
|
||||
@@ -158,7 +158,7 @@ void Project::Load(QXmlStreamReader *reader, MainWindowLayoutInfo* layout, uint
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("node")) {
|
||||
quintptr node_ptr;
|
||||
QPointF node_pos;
|
||||
Node::Position node_pos;
|
||||
|
||||
if (LoadPosition(reader, &node_ptr, &node_pos)) {
|
||||
Node *node = xml_node_data.node_ptrs.value(node_ptr);
|
||||
@@ -350,7 +350,7 @@ void Project::RegenerateUuid()
|
||||
uuid_ = QUuid::createUuid();
|
||||
}
|
||||
|
||||
bool Project::LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, QPointF *pos)
|
||||
bool Project::LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos)
|
||||
{
|
||||
bool got_node_ptr = false;
|
||||
bool got_pos_x = false;
|
||||
@@ -366,11 +366,13 @@ bool Project::LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, QPointF
|
||||
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("x")) {
|
||||
pos->setX(reader->readElementText().toDouble());
|
||||
pos->position.setX(reader->readElementText().toDouble());
|
||||
got_pos_x = true;
|
||||
} else if (reader->name() == QStringLiteral("y")) {
|
||||
pos->setY(reader->readElementText().toDouble());
|
||||
pos->position.setY(reader->readElementText().toDouble());
|
||||
got_pos_y = true;
|
||||
} else if (reader->name() == QStringLiteral("expanded")) {
|
||||
pos->expanded = reader->readElementText().toInt();
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
@@ -379,12 +381,13 @@ bool Project::LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, QPointF
|
||||
return got_node_ptr && got_pos_x && got_pos_y;
|
||||
}
|
||||
|
||||
void Project::SavePosition(QXmlStreamWriter *writer, Node *node, const QPointF &pos)
|
||||
void Project::SavePosition(QXmlStreamWriter *writer, Node *node, const Node::Position &pos)
|
||||
{
|
||||
writer->writeAttribute(QStringLiteral("ptr"), QString::number(reinterpret_cast<quintptr>(node)));
|
||||
|
||||
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.x()));
|
||||
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.y()));
|
||||
writer->writeTextElement(QStringLiteral("x"), QString::number(pos.position.x()));
|
||||
writer->writeTextElement(QStringLiteral("y"), QString::number(pos.position.y()));
|
||||
writer->writeTextElement(QStringLiteral("expanded"), QString::number(pos.expanded));
|
||||
}
|
||||
|
||||
void Project::ColorManagerValueChanged(const NodeInput &input, const TimeRange &range)
|
||||
|
||||
@@ -82,8 +82,8 @@ public:
|
||||
|
||||
void RegenerateUuid();
|
||||
|
||||
static bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, QPointF *pos);
|
||||
static void SavePosition(QXmlStreamWriter *writer, Node *node, const QPointF &pos);
|
||||
static bool LoadPosition(QXmlStreamReader *reader, quintptr *node_ptr, Node::Position *pos);
|
||||
static void SavePosition(QXmlStreamWriter *writer, Node *node, const Node::Position &pos);
|
||||
|
||||
signals:
|
||||
void NameChanged();
|
||||
|
||||
@@ -523,7 +523,6 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
Core::instance()->undo_stack()->pushIfHasChildren(command);
|
||||
return;
|
||||
}
|
||||
|
||||
MultiUndoCommand* command = new MultiUndoCommand();
|
||||
@@ -539,64 +538,63 @@ void NodeView::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
if (!context) {
|
||||
QToolTip::showText(QCursor::pos(), tr("Nodes must be placed inside a context."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (paste_command_) {
|
||||
// We've already "done" this command, but MultiUndoCommand prevents "redoing" twice, so we
|
||||
// add it to this command (which may have extra commands added too) so that it all gets undone
|
||||
// in the same action
|
||||
command->add_child(paste_command_);
|
||||
paste_command_ = nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
MultiUndoCommand *add_command = new MultiUndoCommand();
|
||||
|
||||
foreach (const AttachedItem &ai, attached_items_) {
|
||||
// Add node to the same graph that the context is in
|
||||
add_command->add_child(new NodeAddCommand(context->parent(), ai.item->GetNode()));
|
||||
|
||||
// Add node to the context
|
||||
add_command->add_child(new NodeSetPositionCommand(ai.item->GetNode(), context, scene_.context_map().value(context)->MapScenePosToNodePosInContext(ai.item->pos())));
|
||||
if (context) {
|
||||
if (paste_command_) {
|
||||
// We've already "done" this command, but MultiUndoCommand prevents "redoing" twice, so we
|
||||
// add it to this command (which may have extra commands added too) so that it all gets undone
|
||||
// in the same action
|
||||
command->add_child(paste_command_);
|
||||
paste_command_ = nullptr;
|
||||
}
|
||||
|
||||
if (add_command->child_count()) {
|
||||
add_command->redo_now();
|
||||
command->add_child(add_command);
|
||||
} else {
|
||||
delete add_command;
|
||||
}
|
||||
}
|
||||
{
|
||||
MultiUndoCommand *add_command = new MultiUndoCommand();
|
||||
|
||||
{
|
||||
// Dropped attached item onto an edge, connect it between them
|
||||
MultiUndoCommand *drop_edge_command = new MultiUndoCommand();
|
||||
if (attached_items_.size() == 1) {
|
||||
Node* dropping_node = attached_items_.first().item->GetNode();
|
||||
foreach (const AttachedItem &ai, attached_items_) {
|
||||
// Add node to the same graph that the context is in
|
||||
add_command->add_child(new NodeAddCommand(context->parent(), ai.item->GetNode()));
|
||||
|
||||
if (drop_edge_) {
|
||||
// Remove old edge
|
||||
drop_edge_command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
|
||||
|
||||
// Place new edges
|
||||
drop_edge_command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_));
|
||||
drop_edge_command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input()));
|
||||
// Add node to the context
|
||||
add_command->add_child(new NodeSetPositionCommand(ai.item->GetNode(), context, scene_.context_map().value(context)->MapScenePosToNodePosInContext(ai.item->pos())));
|
||||
}
|
||||
|
||||
drop_edge_ = nullptr;
|
||||
if (add_command->child_count()) {
|
||||
add_command->redo_now();
|
||||
command->add_child(add_command);
|
||||
} else {
|
||||
delete add_command;
|
||||
}
|
||||
}
|
||||
if (drop_edge_command->child_count()) {
|
||||
drop_edge_command->redo_now();
|
||||
command->add_child(drop_edge_command);
|
||||
} else {
|
||||
delete drop_edge_command;
|
||||
}
|
||||
}
|
||||
|
||||
DetachItemsFromCursor();
|
||||
{
|
||||
// Dropped attached item onto an edge, connect it between them
|
||||
MultiUndoCommand *drop_edge_command = new MultiUndoCommand();
|
||||
if (attached_items_.size() == 1) {
|
||||
Node* dropping_node = attached_items_.first().item->GetNode();
|
||||
|
||||
if (drop_edge_) {
|
||||
// Remove old edge
|
||||
drop_edge_command->add_child(new NodeEdgeRemoveCommand(drop_edge_->output(), drop_edge_->input()));
|
||||
|
||||
// Place new edges
|
||||
drop_edge_command->add_child(new NodeEdgeAddCommand(drop_edge_->output(), drop_input_));
|
||||
drop_edge_command->add_child(new NodeEdgeAddCommand(dropping_node, drop_edge_->input()));
|
||||
}
|
||||
|
||||
drop_edge_ = nullptr;
|
||||
}
|
||||
if (drop_edge_command->child_count()) {
|
||||
drop_edge_command->redo_now();
|
||||
command->add_child(drop_edge_command);
|
||||
} else {
|
||||
delete drop_edge_command;
|
||||
}
|
||||
}
|
||||
|
||||
DetachItemsFromCursor();
|
||||
} else {
|
||||
QToolTip::showText(QCursor::pos(), tr("Nodes must be placed inside a context."));
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it=dragging_items_.cbegin(); it!=dragging_items_.cend(); it++) {
|
||||
|
||||
@@ -85,9 +85,8 @@ NodeViewItem::NodeViewItem(Node* n, Node *context, QGraphicsItem *parent) :
|
||||
|
||||
if (context_) {
|
||||
SetNodePosition(context_->GetNodePositionInContext(node_));
|
||||
SetExpanded(context_->IsNodeExpandedInContext(node_));
|
||||
}
|
||||
|
||||
SetExpanded(node_->property("expanded").toBool());
|
||||
}
|
||||
|
||||
QPointF NodeViewItem::GetNodePosition() const
|
||||
@@ -236,7 +235,10 @@ void NodeViewItem::SetExpanded(bool e, bool hide_titlebar)
|
||||
|
||||
expanded_ = e;
|
||||
hide_titlebar_ = hide_titlebar;
|
||||
node_->setProperty("expanded", e);
|
||||
|
||||
if (context_) {
|
||||
context_->SetNodeExpandedInContext(node_, e);
|
||||
}
|
||||
|
||||
if (expanded_ && !node_inputs_.isEmpty()) {
|
||||
// Create new rect
|
||||
|
||||
Reference in New Issue
Block a user