diff --git a/ComponentBasic/BehaviorPerform.cpp b/ComponentBasic/BehaviorPerform.cpp index 16f56ea..2977f4e 100644 --- a/ComponentBasic/BehaviorPerform.cpp +++ b/ComponentBasic/BehaviorPerform.cpp @@ -412,8 +412,11 @@ void LogicalNode::insert(std::shared_ptr node, int index /*= -1*/) if (it->getID() == node->getID()) return; - node->_set_parent_node(this->shared_from_this()); + if(node->parent().lock()) + node->parent().lock()->remove(node); + _child_list.insert(index, node); + node->_set_parent_node(this->shared_from_this()); } void LogicalNode::remove(std::shared_ptr node) diff --git a/SimsWorld/BehaviorEditor.cpp b/SimsWorld/BehaviorEditor.cpp index c4668fd..ea93bea 100644 --- a/SimsWorld/BehaviorEditor.cpp +++ b/SimsWorld/BehaviorEditor.cpp @@ -1,8 +1,14 @@ #include "BehaviorEditor.h" -NodePresent::NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::shared_ptr bind) - : _widget_p(pwidget), _node_bind(bind), _column_width(width_bind) { +NodePresent::NodePresent(BehaviorsPresent* pwidget, QVector& columns_set, std::shared_ptr bind) + : _widget_p(pwidget), _columns_width_seqs(columns_set), _node_bind(bind) { this->setAcceptDrops(true); + this->setCacheMode(QGraphicsItem::NoCache); +} + +std::shared_ptr NodePresent::logicalBind() const +{ + return _node_bind; } QRectF NodePresent::contentMeasure() const @@ -108,11 +114,12 @@ void NodePresent::dropEvent(QGraphicsSceneDragDropEvent* e) new_type = this->_node_bind->bindMap()->getKernal()->getNode(kind_string); else new_type = std::dynamic_pointer_cast(this->_node_bind)->getKernal()->getNode(kind_string); + auto new_node = std::dynamic_pointer_cast(new_type->newDefault()); new_node->setID(++_widget_p->_node_id_max); - auto this_node = this->_node_bind; auto appoint_index = 0; + if (parent_node) appoint_index = parent_node->children().indexOf(this_node); @@ -135,16 +142,22 @@ void NodePresent::dropEvent(QGraphicsSceneDragDropEvent* e) break; } - _widget_p->relayout(); this->_drop_target = AcceptType::NONE; + _widget_p->relayout(); this->update(); } + QRectF NodePresent::boundingRect() const { auto rect = contentMeasure(); - rect.setWidth(std::max(_column_width, rect.width())); - _column_width = rect.width(); + auto depth = this->_node_bind->depth(); + if(_columns_width_seqs.size() <= depth) + _columns_width_seqs.resize(depth + 1); + + auto width_col = _columns_width_seqs[depth]; + rect.setWidth(std::max(width_col, rect.width())); + _columns_width_seqs[depth] = rect.width(); return rect + QMargins(0, 0, 30, 30); } @@ -154,7 +167,7 @@ void NodePresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* optio { painter->save(); - painter->drawRect(boundingRect()); + //painter->drawRect(boundingRect()); painter->fillRect(option->rect - QMargins(padding, padding, padding, padding), Qt::gray); auto outline = this->boundingRect(); @@ -197,6 +210,7 @@ BehaviorsPresent::BehaviorsPresent(QWidget* parent /*= nullptr*/) this->setScene(&_bind_scene); this->setAcceptDrops(true); + this->setViewportUpdateMode(QGraphicsView::FullViewportUpdate); auto font = this->font(); font.setPixelSize(20); @@ -223,7 +237,6 @@ NodePresent* BehaviorsPresent::presentAllocate(std::shared_ptr ins) for (auto idx = _column_aligns.size(); idx < ins->depth() + 1; ++idx) _column_aligns.append(0); - auto& current_width = _column_aligns[ins->depth()]; QList _children_set; switch (ins->nodeKind()) { case NodeKind::MAPNODE: @@ -240,13 +253,13 @@ NodePresent* BehaviorsPresent::presentAllocate(std::shared_ptr ins) default: if (_present_peers.contains(ins)) { for (auto child : _children_set) { - _branch_list << new BranchPresent(_present_peers[ins], current_width, child); + _branch_list << new BranchPresent(_present_peers, child); this->_bind_scene.addItem(_branch_list.last()); } return nullptr; } - _present_peers[ins] = new NodePresent(this, current_width, ins); + _present_peers[ins] = new NodePresent(this, _column_aligns, ins); this->_bind_scene.addItem(_present_peers[ins]); return _present_peers[ins]; @@ -291,8 +304,8 @@ void BehaviorsPresent::relayout() // 调整分支图形位置 for (auto ins : this->_branch_list) { - auto rect_s = ins->startNodeOutline(); - auto rect_e = ins->endNodeOutline(); + auto rect_s = ins->startOutline(); + auto rect_e = ins->endOutline(); qDebug() << __FILE__ << __LINE__ << rect_s << rect_e; @@ -305,6 +318,8 @@ void BehaviorsPresent::relayout() ins->setPos(left_val, top_val); ins->resetArrow(start_pos, end_pos); } + + this->update(); } QSizeF BehaviorsPresent::outlineMeasure(std::shared_ptr ins, QHash, std::pair>& _outline_occupy) @@ -381,7 +396,6 @@ uint qHash(const std::shared_ptr data, uint seed) noexcept #include #include #include -#include void BehaviorEditor::open_behavior_map() { @@ -420,11 +434,15 @@ BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) auto split_h = new QSplitter(Qt::Horizontal, this); split_v->addWidget(split_h); split_v->addWidget(_logs_present); + split_v->setStretchFactor(0, 1); + split_v->setStretchFactor(1, 0); split_h->addWidget(_logical_present); split_h->addWidget(_type_view); - _type_view->setModel(_type_model); + split_h->setStretchFactor(0, 1); + split_h->setStretchFactor(1, 0); + _type_view->setModel(_type_model); nodeTypesViewInit(_type_model); } @@ -482,12 +500,17 @@ void NodeTypesView::startDrag(Qt::DropActions supported) } } -BranchPresent::BranchPresent(NodePresent* a, double& a_width, NodePresent* b) - :_start_node(a), _start_node_width(a_width), _end_node(b) { +BranchPresent::BranchPresent(const QHash, NodePresent*>& present_set, NodePresent* head_anchor) + :_present_set_bind(present_set), _head_node(head_anchor) { } -QRectF BranchPresent::startNodeOutline() const +QRectF BranchPresent::startOutline() const { + auto parent_node = _head_node->logicalBind()->parent().lock(); + if (!parent_node) + return QRectF(); + + auto _start_node = _present_set_bind[parent_node]; auto _start_pos = _start_node->pos(); auto _s_rect = _start_node->boundingRect(); _s_rect.moveTopLeft(_start_pos); @@ -495,8 +518,13 @@ QRectF BranchPresent::startNodeOutline() const return _s_rect; } -QRectF BranchPresent::endNodeOutline() const +QRectF BranchPresent::endOutline() const { + auto parent_node = _head_node->logicalBind()->parent().lock(); + if (!parent_node) + return QRectF(); + + auto _end_node = this->_head_node; auto _end_pos = _end_node->pos(); auto _e_rect = _end_node->boundingRect(); _e_rect.moveTopLeft(_end_pos); @@ -552,5 +580,9 @@ void BranchPresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* opt //painter->drawLine(pt1, pt2); //painter->drawLine(pt1, vtarget); + //p.setColor(Qt::green); + //painter->setPen(p); + //painter->drawRect(option->rect); + painter->restore(); } diff --git a/SimsWorld/BehaviorEditor.h b/SimsWorld/BehaviorEditor.h index a36931d..cb81550 100644 --- a/SimsWorld/BehaviorEditor.h +++ b/SimsWorld/BehaviorEditor.h @@ -17,14 +17,19 @@ class BehaviorsPresent; class NodePresent : public QGraphicsItem { private: BehaviorsPresent* const _widget_p; - double& _column_width; + QVector &_columns_width_seqs; + std::shared_ptr _node_bind; AcceptType _drop_target = AcceptType::NONE; public: - std::shared_ptr _node_bind; static const double padding; - NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::shared_ptr bind); + NodePresent(BehaviorsPresent* pwidget, QVector &columns_set, std::shared_ptr bind); + /// + /// 绑定的逻辑节点 + /// + /// + std::shared_ptr logicalBind() const; QRectF contentMeasure() const; AcceptType testAccept(const QPointF& local_pos, const QString& kind_str) const; @@ -38,6 +43,7 @@ protected: virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent* event); virtual void dragMoveEvent(QGraphicsSceneDragDropEvent* event); virtual void dropEvent(QGraphicsSceneDragDropEvent* event); + }; /// @@ -45,17 +51,16 @@ protected: /// class BranchPresent : public QGraphicsItem { private: - NodePresent* const _start_node; - double& _start_node_width; - NodePresent* const _end_node; + const QHash, NodePresent*> &_present_set_bind; + NodePresent* const _head_node; QPointF _arrow_start, _arrow_end; public: - BranchPresent(NodePresent* a, double& a_width, NodePresent* b); + BranchPresent(const QHash, NodePresent*> &present_set, NodePresent* head_anchor); - QRectF startNodeOutline() const; - QRectF endNodeOutline() const; + QRectF startOutline() const; + QRectF endOutline() const; void resetArrow(const QPointF& start, const QPointF& end); // 通过 QGraphicsItem 继承 @@ -125,6 +130,7 @@ public: /// 左下角 QPointF nodeRelayout(QHash, std::pair>& _outline_occupy, std::shared_ptr ins, const QPointF& origin_offset); + };