This commit is contained in:
codeboss 2025-07-03 21:29:09 +08:00
commit a8bcd68355
2 changed files with 155 additions and 23 deletions

View File

@ -8,7 +8,9 @@ NodePresent::NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::sha
QRectF NodePresent::contentMeasure() const QRectF NodePresent::contentMeasure() const
{ {
auto metrics = this->_widget_p->fontMetrics(); auto metrics = this->_widget_p->fontMetrics();
return metrics.boundingRect(this->_node_bind->rtName()); auto rect = metrics.boundingRect(this->_node_bind->rtName());
rect.moveTopLeft(QPoint(0, 0));
return rect;
} }
#include <QDebug> #include <QDebug>
@ -111,7 +113,7 @@ void NodePresent::dropEvent(QGraphicsSceneDragDropEvent* e)
auto this_node = this->_node_bind; auto this_node = this->_node_bind;
auto appoint_index = 0; auto appoint_index = 0;
if(parent_node) if (parent_node)
appoint_index = parent_node->children().indexOf(this_node); appoint_index = parent_node->children().indexOf(this_node);
switch (_drop_target) { switch (_drop_target) {
@ -153,7 +155,7 @@ void NodePresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* optio
painter->save(); painter->save();
painter->drawRect(boundingRect()); painter->drawRect(boundingRect());
painter->fillRect(option->rect - QMargins(8, 8, 8, 8), Qt::gray); painter->fillRect(option->rect - QMargins(padding, padding, padding, padding), Qt::gray);
auto outline = this->boundingRect(); auto outline = this->boundingRect();
auto width = outline.width(); auto width = outline.width();
@ -203,38 +205,51 @@ BehaviorsPresent::BehaviorsPresent(QWidget* parent /*= nullptr*/)
void BehaviorsPresent::setRoot(std::shared_ptr<BehaviorMapNode> root) void BehaviorsPresent::setRoot(std::shared_ptr<BehaviorMapNode> root)
{ {
this->_bind_maproot = root;
// 清除显示节点
qDeleteAll(_present_peers); qDeleteAll(_present_peers);
_present_peers.clear(); _present_peers.clear();
this->_bind_maproot = root; // 清空分支
qDeleteAll(this->_branch_list);
this->_branch_list.clear();
relayout(); relayout();
} }
void BehaviorsPresent::presentAllocate(std::shared_ptr<LogicalNode> ins) NodePresent* BehaviorsPresent::presentAllocate(std::shared_ptr<LogicalNode> ins)
{ {
switch (ins->nodeKind()) 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: case NodeKind::MAPNODE:
case NodeKind::PARALLELNODE: case NodeKind::PARALLELNODE:
case NodeKind::SEQUENCENODE: case NodeKind::SEQUENCENODE:
case NodeKind::SELECTORNODE: case NodeKind::SELECTORNODE:
if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) { if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) {
auto type = ins->nodeKind(); for (auto it : ins->children()) {
for (auto it : ins->children()) auto child_graph = presentAllocate(it);
presentAllocate(it); if (child_graph) _children_set << child_graph;
}
} }
default: default:
if (_present_peers.contains(ins)) if (_present_peers.contains(ins)) {
return; for (auto child : _children_set) {
_branch_list << new BranchPresent(_present_peers[ins], current_width, child);
this->_bind_scene.addItem(_branch_list.last());
}
return nullptr;
}
for (auto idx = _column_aligns.size(); idx < ins->depth() + 1; ++idx)
_column_aligns.append(0);
auto& current_width = _column_aligns[ins->depth()];
_present_peers[ins] = new NodePresent(this, current_width, ins); _present_peers[ins] = new NodePresent(this, current_width, ins);
this->_bind_scene.addItem(_present_peers[ins]); this->_bind_scene.addItem(_present_peers[ins]);
break;
return _present_peers[ins];
} }
} }
@ -258,6 +273,7 @@ void BehaviorsPresent::presentRelease(std::shared_ptr<LogicalNode> ins)
} }
} }
const double NodePresent::padding = 8;
void BehaviorsPresent::relayout() void BehaviorsPresent::relayout()
{ {
if (!_bind_maproot) if (!_bind_maproot)
@ -269,8 +285,26 @@ void BehaviorsPresent::relayout()
QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>> results; QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>> results;
// ³ß´ç²âÁ¿ // ³ß´ç²âÁ¿
outlineMeasure(_bind_maproot, results); outlineMeasure(_bind_maproot, results);
// ÔªËØÅŲ¼ // ÔªËØÅŲ¼
nodeRelayout(results, _bind_maproot, QPointF()); nodeRelayout(results, _bind_maproot, QPointF());
// 调整分支图形位置
for (auto ins : this->_branch_list) {
auto rect_s = ins->startNodeOutline();
auto rect_e = ins->endNodeOutline();
qDebug() << __FILE__ << __LINE__ << rect_s << rect_e;
auto start_pos = rect_s.bottomRight() - QPoint(NodePresent::padding, rect_s.height() / 2);
auto end_pos = rect_e.topLeft() + QPoint(NodePresent::padding, rect_e.height() / 2);
auto left_val = std::min(start_pos.x(), end_pos.x());
auto top_val = std::min(start_pos.y(), end_pos.y());
ins->setPos(left_val, top_val);
ins->resetArrow(start_pos, end_pos);
}
} }
QSizeF BehaviorsPresent::outlineMeasure(std::shared_ptr<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy) QSizeF BehaviorsPresent::outlineMeasure(std::shared_ptr<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy)
@ -357,7 +391,6 @@ void BehaviorEditor::open_behavior_map()
if (!url.isValid()) if (!url.isValid())
return; return;
qDebug() << url;
} }
BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/)
@ -448,3 +481,76 @@ 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) {
}
QRectF BranchPresent::startNodeOutline() const
{
auto _start_pos = _start_node->pos();
auto _s_rect = _start_node->boundingRect();
_s_rect.moveTopLeft(_start_pos);
return _s_rect;
}
QRectF BranchPresent::endNodeOutline() const
{
auto _end_pos = _end_node->pos();
auto _e_rect = _end_node->boundingRect();
_e_rect.moveTopLeft(_end_pos);
return _e_rect;
}
void BranchPresent::resetArrow(const QPointF& start, const QPointF& end)
{
this->_arrow_start = start;
this->_arrow_end = end;
qDebug() << __FILE__ << __LINE__ << _arrow_start << _arrow_end;
this->update();
}
QRectF BranchPresent::boundingRect() const
{
auto leftv = std::min(_arrow_start.x(), _arrow_end.x());
auto topv = std::min(_arrow_start.y(), _arrow_end.y());
auto width = std::abs(_arrow_start.x() - _arrow_end.x());
auto height = std::abs(_arrow_start.y() - _arrow_end.y());
return QRectF(0, 0, width, height);
}
void BranchPresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
QPointF start(0, 0);
auto vtarget = _arrow_end - _arrow_start;
if (vtarget.y() < 0) {
start -= QPointF(0, vtarget.y());
vtarget -= QPointF(0, vtarget.y());
}
auto pt1 = start + QPointF(vtarget.x() / 2, 0);
auto pt2 = vtarget - QPointF(vtarget.x() / 2, 0);
QPainterPath bezier_curve;
bezier_curve.moveTo(start);
bezier_curve.cubicTo(pt1, pt2, vtarget);
QPen p(Qt::black);
p.setWidth(2);
painter->setPen(p);
painter->drawPath(bezier_curve);
//p.setColor(Qt::red);
//painter->setPen(p);
//painter->drawLine(start, pt1);
//painter->drawLine(pt1, pt2);
//painter->drawLine(pt1, vtarget);
painter->restore();
}

View File

@ -17,16 +17,17 @@ class BehaviorsPresent;
class NodePresent : public QGraphicsItem { class NodePresent : public QGraphicsItem {
private: private:
BehaviorsPresent* const _widget_p; BehaviorsPresent* const _widget_p;
std::shared_ptr<LogicalNode> _node_bind;
double& _column_width; double& _column_width;
AcceptType _drop_target = AcceptType::NONE; AcceptType _drop_target = AcceptType::NONE;
public: 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, double& width_bind, std::shared_ptr<LogicalNode> bind);
QRectF contentMeasure() const; QRectF contentMeasure() const;
AcceptType testAccept(const QPointF& local_pos, const QString &kind_str) const; AcceptType testAccept(const QPointF& local_pos, const QString& kind_str) const;
// 通过 QGraphicsItem 继承 // 通过 QGraphicsItem 继承
QRectF boundingRect() const override; QRectF boundingRect() const override;
@ -39,6 +40,30 @@ protected:
virtual void dropEvent(QGraphicsSceneDragDropEvent* event); virtual void dropEvent(QGraphicsSceneDragDropEvent* event);
}; };
/// <summary>
/// ·Ö֧ͼÐδúÀí
/// </summary>
class BranchPresent : public QGraphicsItem {
private:
NodePresent* const _start_node;
double& _start_node_width;
NodePresent* const _end_node;
QPointF _arrow_start, _arrow_end;
public:
BranchPresent(NodePresent* a, double& a_width, NodePresent* b);
QRectF startNodeOutline() const;
QRectF endNodeOutline() const;
void resetArrow(const QPointF& start, const QPointF& end);
// ͨ¹ý QGraphicsItem ¼Ì³Ð
QRectF boundingRect() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
};
/// <summary> /// <summary>
/// 行为树编辑展示 /// 行为树编辑展示
@ -48,9 +73,10 @@ class BehaviorsPresent : public QGraphicsView
private: private:
QGraphicsScene _bind_scene; QGraphicsScene _bind_scene;
const double _space_h = 120; const double _space_h = 30;
QVector<double> _column_aligns; QVector<double> _column_aligns;
QHash<std::shared_ptr<LogicalNode>, NodePresent*> _present_peers; QHash<std::shared_ptr<LogicalNode>, NodePresent*> _present_peers;
QList<BranchPresent*> _branch_list;
/// <summary> /// <summary>
/// 绑定行为树节点 /// 绑定行为树节点
@ -72,7 +98,7 @@ public:
/// </summary> /// </summary>
/// <param name="_present_peers"></param> /// <param name="_present_peers"></param>
/// <param name="ins"></param> /// <param name="ins"></param>
void presentAllocate(std::shared_ptr<LogicalNode> ins); NodePresent* presentAllocate(std::shared_ptr<LogicalNode> ins);
/// <summary> /// <summary>
/// 递归释放显示节点 /// 递归释放显示节点
/// </summary> /// </summary>