完善拖放框架

This commit is contained in:
codeboss 2025-07-02 00:14:25 +08:00
parent dcef59b2ac
commit 3fcf823369
2 changed files with 148 additions and 13 deletions

View File

@ -2,6 +2,7 @@
NodePresent::NodePresent(QWidget* pwidget, double& width_bind, std::shared_ptr<LogicalNode> 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 <QGraphicsSceneDragDropEvent>
#include <QMimeData>
#include <QDebug>
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<LogicalNode> data, uint seed) noexcept
}
#include <QSplitter>
#include <QMenuBar>
#include <QMenu>
#include <QFileDialog>
#include <QDebug>
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<MapKernal>(_global_loader);
_global_kernal->initial();
this->_map_root = std::make_shared<BehaviorMapNode>(_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 <QMimeData>
#include <QVariant>
#include <QDrag>
#include <QPainter>
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__;
}
}
}

View File

@ -6,23 +6,35 @@
uint qHash(const std::shared_ptr<LogicalNode> data, uint seed) noexcept;
enum class AcceptType {
NONE, PREV_LEVEL, NEXT_LEVEL, PREV_SIBLING, NEXT_SIBLING
};
/// <summary>
/// 节点显示代理
/// </summary>
class NodePresent : public QGraphicsItem {
private:
QWidget *const _widget_p;
QWidget* const _widget_p;
std::shared_ptr<LogicalNode> _node_bind;
double &_column_width;
double& _column_width;
AcceptType _drop_target = AcceptType::NONE;
public:
NodePresent(QWidget *pwidget, double &width_bind, std::shared_ptr<LogicalNode> bind);
NodePresent(QWidget* pwidget, double& width_bind, std::shared_ptr<LogicalNode> 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:
/// <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);
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:
QListView *const _type_view;
QStandardItemModel *const _type_model;
BehaviorsPresent *const _logical_present;
QTextBrowser *const _logs_present;
std::shared_ptr<MessageLoader> _global_loader;
std::shared_ptr<MapKernal> _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<BehaviorMapNode> _map_root;
void open_behavior_map();
public:
BehaviorEditor(QWidget* parent = nullptr);
void nodeTypesViewInit(QStandardItemModel* m);
};