diff --git a/SimsWorld/BehaviorEditor.cpp b/SimsWorld/BehaviorEditor.cpp index af4c1b6..d83944e 100644 --- a/SimsWorld/BehaviorEditor.cpp +++ b/SimsWorld/BehaviorEditor.cpp @@ -2,6 +2,7 @@ NodePresent::NodePresent(QWidget* pwidget, double& width_bind, std::shared_ptr bind) : _widget_p(pwidget), _node_bind(bind), _column_width(width_bind) { + this->setAcceptDrops(true); } QRectF NodePresent::contentMeasure() const @@ -10,6 +11,48 @@ QRectF NodePresent::contentMeasure() const return metrics.boundingRect(this->_node_bind->rtName()); } +AcceptType NodePresent::testAccept(const QPointF& local_pos) const +{ + return AcceptType::PREV_LEVEL; +} + +#include +#include +#include +void NodePresent::dragEnterEvent(QGraphicsSceneDragDropEvent* e) +{ + if (e->mimeData()->hasFormat("application/drag-node")) { + e->acceptProposedAction(); + } +} + +void NodePresent::dragLeaveEvent(QGraphicsSceneDragDropEvent* event) +{ + QGraphicsItem::dragLeaveEvent(event); + this->_drop_target = AcceptType::NONE; +} + +void NodePresent::dragMoveEvent(QGraphicsSceneDragDropEvent* e) +{ + if (e->mimeData()->hasFormat("application/drag-node")) { + auto local_pos = this->mapToItem(this, e->pos()); + this->_drop_target = this->testAccept(local_pos); + if (_drop_target != AcceptType::NONE) + e->acceptProposedAction(); + } +} + +void NodePresent::dropEvent(QGraphicsSceneDragDropEvent* e) +{ + qDebug() << QString::fromUtf8(e->mimeData()->data("application/drag-node")); + + + + + + this->_drop_target = AcceptType::NONE; +} + QRectF NodePresent::boundingRect() const { auto rect = contentMeasure(); @@ -34,6 +77,8 @@ BehaviorsPresent::BehaviorsPresent(QWidget* parent /*= nullptr*/) : QGraphicsView(parent) { this->setScene(&_bind_scene); + this->setAcceptDrops(true); + auto font = this->font(); font.setPixelSize(20); this->setFont(font); @@ -180,9 +225,25 @@ uint qHash(const std::shared_ptr data, uint seed) noexcept } #include +#include +#include +#include +#include + +void BehaviorEditor::open_behavior_map() +{ + auto url = QFileDialog::getOpenFileUrl(this, u8"打开行为树文件", QUrl(), "*.behw"); + + this->_logical_present->setRoot(_map_root); + + if (!url.isValid()) + return; + qDebug() << url; +} + BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) : QMainWindow(parent), - _type_view(new QListView(this)), + _type_view(new NodeTypesView(this)), _type_model(new QStandardItemModel(this)), _logical_present(new BehaviorsPresent(this)), _logs_present(new QTextBrowser(this)) @@ -191,6 +252,12 @@ BehaviorEditor::BehaviorEditor(QWidget* parent /*= nullptr*/) _global_kernal = std::make_shared(_global_loader); _global_kernal->initial(); + this->_map_root = std::make_shared(_global_kernal); + + auto mbar = this->menuBar(); + auto _file = mbar->addMenu(u8"文件"); + _file->addAction(u8"打开", this, &BehaviorEditor::open_behavior_map); + auto font = this->font(); font.setPixelSize(20); _type_view->setFont(font); @@ -220,3 +287,46 @@ void BehaviorEditor::nodeTypesViewInit(QStandardItemModel* m) m->appendRow(row_item); } } + +NodeTypesView::NodeTypesView(QWidget* parent /*= nullptr*/) + : QListView(parent) +{ + this->setDragEnabled(true); + this->setDragDropMode(QAbstractItemView::DragOnly); + this->setSelectionBehavior(QAbstractItemView::SelectRows); + this->setSelectionMode(QAbstractItemView::SingleSelection); +} + +#include +#include +#include +#include +void NodeTypesView::startDrag(Qt::DropActions supported) +{ + auto selected = this->selectedIndexes(); + if (selected.size() && selected.first().isValid()) { + auto val = this->model()->data(selected.first(), Qt::DisplayRole); + auto type_name = val.toString(); + + // 创建自定义MIME数据 + auto mime_data = new QMimeData(); + mime_data->setData("application/drag-node", type_name.toUtf8()); + + auto view_rect = this->visualRect(selected.first()); + QPixmap pixmap(view_rect.size()); + pixmap.fill(Qt::transparent); + QPainter p(&pixmap); + this->render(&p, QPoint(), QRegion(view_rect)); + p.end(); + + // 创建拖动对象 + auto drag = new QDrag(this); + drag->setMimeData(mime_data); + drag->setPixmap(pixmap); + + auto result = drag->exec(supported); + if (result == Qt::CopyAction) { + qDebug() << __FILE__ << __LINE__; + } + } +} diff --git a/SimsWorld/BehaviorEditor.h b/SimsWorld/BehaviorEditor.h index c93358d..607b6f8 100644 --- a/SimsWorld/BehaviorEditor.h +++ b/SimsWorld/BehaviorEditor.h @@ -6,23 +6,35 @@ uint qHash(const std::shared_ptr data, uint seed) noexcept; +enum class AcceptType { + NONE, PREV_LEVEL, NEXT_LEVEL, PREV_SIBLING, NEXT_SIBLING +}; /// /// 节点显示代理 /// class NodePresent : public QGraphicsItem { private: - QWidget *const _widget_p; + QWidget* const _widget_p; std::shared_ptr _node_bind; - double &_column_width; + double& _column_width; + + AcceptType _drop_target = AcceptType::NONE; public: - NodePresent(QWidget *pwidget, double &width_bind, std::shared_ptr bind); + NodePresent(QWidget* pwidget, double& width_bind, std::shared_ptr bind); QRectF contentMeasure() const; + AcceptType testAccept(const QPointF& local_pos) 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); }; @@ -83,26 +95,39 @@ public: /// 左上角 /// 左下角 QPointF nodeRelayout(QHash, std::pair>& _outline_occupy, - std::shared_ptr ins, const QPointF &origin_offset); + std::shared_ptr ins, const QPointF& origin_offset); }; #include +class NodeTypesView : public QListView { +public: + NodeTypesView(QWidget* parent = nullptr); + +protected: + virtual void startDrag(Qt::DropActions supported) override; +}; + + #include #include #include class BehaviorEditor : public QMainWindow { private: - QListView *const _type_view; - QStandardItemModel *const _type_model; - BehaviorsPresent *const _logical_present; - QTextBrowser *const _logs_present; - std::shared_ptr _global_loader; std::shared_ptr _global_kernal; -public: - BehaviorEditor(QWidget *parent = nullptr); + NodeTypesView* const _type_view; + QStandardItemModel* const _type_model; + BehaviorsPresent* const _logical_present; + QTextBrowser* const _logs_present; - void nodeTypesViewInit(QStandardItemModel *m); + std::shared_ptr _map_root; + + void open_behavior_map(); + +public: + BehaviorEditor(QWidget* parent = nullptr); + + void nodeTypesViewInit(QStandardItemModel* m); }; \ No newline at end of file