SimsWorld/SimsWorld/BehaviorEditor.h

167 lines
4.4 KiB
C++

#pragma once
#include <QMainWindow>
#include "BehaviorPerform.h"
#include <QGraphicsItem>
#include <QGraphicsView>
uint qHash(const std::shared_ptr<LogicalNode> data, uint seed) noexcept;
enum class AcceptType {
NONE = 0, PREV_LEVEL, NEXT_LEVEL, PREV_SIBLING, NEXT_SIBLING
};
class BehaviorsPresent;
/// <summary>
/// 节点显示代理
/// </summary>
class NodePresent : public QGraphicsItem {
private:
BehaviorsPresent* const _widget_p;
QVector<double> &_columns_width_seqs;
std::shared_ptr<LogicalNode> _node_bind;
AcceptType _drop_target = AcceptType::NONE;
public:
static const double padding;
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;
// 通过 QGraphicsItem 继承
QRectF boundingRect() const override;
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
protected:
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent* event);
virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent* event);
virtual void dragMoveEvent(QGraphicsSceneDragDropEvent* event);
virtual void dropEvent(QGraphicsSceneDragDropEvent* event);
};
/// <summary>
/// 分支图形代理
/// </summary>
class BranchPresent : public QGraphicsItem {
private:
const QHash<std::shared_ptr<LogicalNode>, NodePresent*> &_present_set_bind;
NodePresent* const _head_node;
QPointF _arrow_start, _arrow_end;
public:
BranchPresent(const QHash<std::shared_ptr<LogicalNode>, NodePresent*> &present_set, NodePresent* head_anchor);
std::shared_ptr<LogicalNode> headNode() const;
QRectF startOutline() const;
QRectF endOutline() 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>
class BehaviorsPresent : public QGraphicsView
{
private:
QGraphicsScene _bind_scene;
const double _space_h = 30;
QVector<double> _column_aligns;
QHash<std::shared_ptr<LogicalNode>, NodePresent*> _present_peers;
QList<BranchPresent*> _branch_list;
/// <summary>
/// 绑定行为树节点
/// </summary>
std::shared_ptr<BehaviorMapNode> _bind_maproot = nullptr;
public:
uint64_t _node_id_max = 0;
BehaviorsPresent(QWidget* parent = nullptr);
/// <summary>
/// 替换行为树
/// </summary>
/// <param name="root"></param>
void setRoot(std::shared_ptr<BehaviorMapNode> root);
/// <summary>
/// 显示节点分配
/// </summary>
/// <param name="_present_peers"></param>
/// <param name="ins"></param>
NodePresent* presentAllocate(std::shared_ptr<LogicalNode> ins);
/// <summary>
/// 内容重新布局
/// </summary>
void relayout();
/// <summary>
/// 尺寸测量
/// </summary>
/// <param name="ins"></param>
/// <param name="_outline_occupy"></param>
/// <returns></returns>
QSizeF outlineMeasure(std::shared_ptr<LogicalNode> ins, QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy);
/// <summary>
/// 节点布局
/// </summary>
/// <param name="_outline_occupy">尺寸记录</param>
/// <param name="ins">指定节点</param>
/// <param name="origin_offset">左上角</param>
/// <returns>左下角</returns>
QPointF nodeRelayout(QHash<std::shared_ptr<LogicalNode>, std::pair<QSizeF, QSizeF>>& _outline_occupy,
std::shared_ptr<LogicalNode> ins, const QPointF& origin_offset);
};
#include <QListView>
class NodeTypesView : public QListView {
public:
NodeTypesView(QWidget* parent = nullptr);
protected:
virtual void startDrag(Qt::DropActions supported) override;
};
#include <QStandardItemModel>
#include <QTextBrowser>
#include <MessageLoader.h>
class BehaviorEditor : public QMainWindow {
private:
std::shared_ptr<MessageLoader> _global_loader;
std::shared_ptr<MapKernal> _global_kernal;
NodeTypesView* const _type_view;
QStandardItemModel* const _type_model;
BehaviorsPresent* const _logical_present;
QTextBrowser* const _logs_present;
std::shared_ptr<BehaviorMapNode> _map_root;
QUrl _current_fileurl;
void open_behavior_map();
void new_behavior_map();
public:
BehaviorEditor(QWidget* parent = nullptr);
void nodeTypesViewInit(QStandardItemModel* m);
};