拖动编辑行为树

This commit is contained in:
codeboss 2025-07-04 00:59:12 +08:00
parent a8bcd68355
commit bc304b325e
3 changed files with 69 additions and 28 deletions

View File

@ -412,8 +412,11 @@ void LogicalNode::insert(std::shared_ptr<LogicalNode> 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<LogicalNode> node)

View File

@ -1,8 +1,14 @@
#include "BehaviorEditor.h"
NodePresent::NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::shared_ptr<LogicalNode> bind)
: _widget_p(pwidget), _node_bind(bind), _column_width(width_bind) {
NodePresent::NodePresent(BehaviorsPresent* pwidget, QVector<double>& columns_set, std::shared_ptr<LogicalNode> bind)
: _widget_p(pwidget), _columns_width_seqs(columns_set), _node_bind(bind) {
this->setAcceptDrops(true);
this->setCacheMode(QGraphicsItem::NoCache);
}
std::shared_ptr<LogicalNode> 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<BehaviorMapNode>(this->_node_bind)->getKernal()->getNode(kind_string);
auto new_node = std::dynamic_pointer_cast<LogicalNode>(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<LogicalNode> ins)
for (auto idx = _column_aligns.size(); idx < ins->depth() + 1; ++idx)
_column_aligns.append(0);
auto& current_width = _column_aligns[ins->depth()];
QList<NodePresent*> _children_set;
switch (ins->nodeKind()) {
case NodeKind::MAPNODE:
@ -240,13 +253,13 @@ NodePresent* BehaviorsPresent::presentAllocate(std::shared_ptr<LogicalNode> 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<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy)
@ -381,7 +396,6 @@ uint qHash(const std::shared_ptr<LogicalNode> data, uint seed) noexcept
#include <QMenuBar>
#include <QMenu>
#include <QFileDialog>
#include <QDebug>
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<std::shared_ptr<LogicalNode>, 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();
}

View File

@ -17,14 +17,19 @@ class BehaviorsPresent;
class NodePresent : public QGraphicsItem {
private:
BehaviorsPresent* const _widget_p;
double& _column_width;
QVector<double> &_columns_width_seqs;
std::shared_ptr<LogicalNode> _node_bind;
AcceptType _drop_target = AcceptType::NONE;
public:
std::shared_ptr<LogicalNode> _node_bind;
static const double padding;
NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::shared_ptr<LogicalNode> bind);
NodePresent(BehaviorsPresent* pwidget, QVector<double> &columns_set, std::shared_ptr<LogicalNode> bind);
/// <summary>
/// °ó¶¨µÄÂß¼­½Úµã
/// </summary>
/// <returns></returns>
std::shared_ptr<LogicalNode> 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);
};
/// <summary>
@ -45,17 +51,16 @@ protected:
/// </summary>
class BranchPresent : public QGraphicsItem {
private:
NodePresent* const _start_node;
double& _start_node_width;
NodePresent* const _end_node;
const QHash<std::shared_ptr<LogicalNode>, 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<std::shared_ptr<LogicalNode>, 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:
/// <returns>×óϽÇ</returns>
QPointF nodeRelayout(QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy,
std::shared_ptr<LogicalNode> ins, const QPointF& origin_offset);
};