绘制节点联系
This commit is contained in:
parent
8a27ca60e5
commit
be67b5ef03
|
@ -8,7 +8,9 @@ NodePresent::NodePresent(BehaviorsPresent* pwidget, double& width_bind, std::sha
|
|||
QRectF NodePresent::contentMeasure() const
|
||||
{
|
||||
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>
|
||||
|
@ -21,7 +23,7 @@ AcceptType NodePresent::testAccept(const QPointF& local_pos, const QString& kind
|
|||
auto left_rect = QRectF(origin + QPointF(0, 0), QSizeF(width / 3, outline.height()));
|
||||
auto right_rect = QRectF(origin + QPointF(width * 2 / 3, 0), QSizeF(width / 3, outline.height()));
|
||||
auto top_rect = QRectF(origin + QPointF(width / 3, outline.height() / 2), QSizeF(width / 3, outline.height() / 2));
|
||||
auto bottom_rect = QRectF(origin + QPointF(width / 3, 0), QSizeF(width / 3, outline.height() / 2));
|
||||
auto bottom_rect = QRectF(origin + QPointF(width / 3, 0), QSizeF(width / 3, outline.height() / 2));
|
||||
|
||||
QList<NodeKind> no_child{ NodeKind::ACTIONNODE, NodeKind::COMPARENODE };
|
||||
auto pnode = this->_node_bind->parent().lock();
|
||||
|
@ -111,7 +113,7 @@ void NodePresent::dropEvent(QGraphicsSceneDragDropEvent* e)
|
|||
|
||||
auto this_node = this->_node_bind;
|
||||
auto appoint_index = 0;
|
||||
if(parent_node)
|
||||
if (parent_node)
|
||||
appoint_index = parent_node->children().indexOf(this_node);
|
||||
|
||||
switch (_drop_target) {
|
||||
|
@ -153,7 +155,7 @@ void NodePresent::paint(QPainter* painter, const QStyleOptionGraphicsItem* optio
|
|||
painter->save();
|
||||
|
||||
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 width = outline.width();
|
||||
|
@ -203,38 +205,51 @@ BehaviorsPresent::BehaviorsPresent(QWidget* parent /*= nullptr*/)
|
|||
|
||||
void BehaviorsPresent::setRoot(std::shared_ptr<BehaviorMapNode> root)
|
||||
{
|
||||
this->_bind_maproot = root;
|
||||
|
||||
// 清除显示节点
|
||||
qDeleteAll(_present_peers);
|
||||
_present_peers.clear();
|
||||
|
||||
this->_bind_maproot = root;
|
||||
// 清空分支
|
||||
qDeleteAll(this->_branch_list);
|
||||
this->_branch_list.clear();
|
||||
|
||||
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::PARALLELNODE:
|
||||
case NodeKind::SEQUENCENODE:
|
||||
case NodeKind::SELECTORNODE:
|
||||
if (ins->nodeKind() != NodeKind::MAPNODE || !ins->bindMap()) {
|
||||
auto type = ins->nodeKind();
|
||||
for (auto it : ins->children())
|
||||
presentAllocate(it);
|
||||
for (auto it : ins->children()) {
|
||||
auto child_graph = presentAllocate(it);
|
||||
if (child_graph) _children_set << child_graph;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
if (_present_peers.contains(ins))
|
||||
return;
|
||||
if (_present_peers.contains(ins)) {
|
||||
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);
|
||||
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()
|
||||
{
|
||||
if (!_bind_maproot)
|
||||
|
@ -269,8 +285,26 @@ void BehaviorsPresent::relayout()
|
|||
QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>> results;
|
||||
// ³ß´ç²âÁ¿
|
||||
outlineMeasure(_bind_maproot, results);
|
||||
|
||||
// ÔªËØÅŲ¼
|
||||
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)
|
||||
|
@ -357,7 +391,6 @@ void BehaviorEditor::open_behavior_map()
|
|||
|
||||
if (!url.isValid())
|
||||
return;
|
||||
qDebug() << url;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -17,16 +17,17 @@ class BehaviorsPresent;
|
|||
class NodePresent : public QGraphicsItem {
|
||||
private:
|
||||
BehaviorsPresent* const _widget_p;
|
||||
std::shared_ptr<LogicalNode> _node_bind;
|
||||
double& _column_width;
|
||||
|
||||
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);
|
||||
|
||||
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 继承
|
||||
QRectF boundingRect() const override;
|
||||
|
@ -39,6 +40,30 @@ protected:
|
|||
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>
|
||||
/// 行为树编辑展示
|
||||
|
@ -48,9 +73,10 @@ class BehaviorsPresent : public QGraphicsView
|
|||
private:
|
||||
QGraphicsScene _bind_scene;
|
||||
|
||||
const double _space_h = 120;
|
||||
const double _space_h = 30;
|
||||
QVector<double> _column_aligns;
|
||||
QHash<std::shared_ptr<LogicalNode>, NodePresent*> _present_peers;
|
||||
QList<BranchPresent*> _branch_list;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定行为树节点
|
||||
|
@ -72,7 +98,7 @@ public:
|
|||
/// </summary>
|
||||
/// <param name="_present_peers"></param>
|
||||
/// <param name="ins"></param>
|
||||
void presentAllocate(std::shared_ptr<LogicalNode> ins);
|
||||
NodePresent* presentAllocate(std::shared_ptr<LogicalNode> ins);
|
||||
/// <summary>
|
||||
/// 递归释放显示节点
|
||||
/// </summary>
|
||||
|
|
Loading…
Reference in New Issue