解决了拖动操作的接收问题

This commit is contained in:
玉宇清音 2023-08-21 11:28:03 +08:00
parent b6bae9980b
commit 3a8ada4681
3 changed files with 78 additions and 28 deletions

View File

@ -22,7 +22,7 @@ public:
ViewDragDrapCommon(BaseView *inst) : target(inst) {} ViewDragDrapCommon(BaseView *inst) : target(inst) {}
ViewDragDrapCommon() : target(nullptr) {} ViewDragDrapCommon() : target(nullptr) {}
}; };
QString ViewDragDrapCommon::type_sign = "custom/drag-drop-view"; QString ViewDragDrapCommon::type_sign = "application/x-qt-windows-mime;value=\"ViewDragDrapCommon\"";
Q_DECLARE_METATYPE(ViewDragDrapCommon) Q_DECLARE_METATYPE(ViewDragDrapCommon)
QDataStream &operator<<(QDataStream &out, const ViewDragDrapCommon &myObj) { QDataStream &operator<<(QDataStream &out, const ViewDragDrapCommon &myObj) {
@ -41,14 +41,18 @@ BaseView::BaseView(const QString &title, QWidget *view, bool empty, QWidget *par
layout->setMargin(0); layout->setMargin(0);
layout->setSpacing(0); layout->setSpacing(0);
registComp(this);
if (!empty) { if (!empty) {
title_header = new DragHeader(this); title_header = new DragHeader(this);
title_header->setText(title); title_header->setText(title);
title_header->setMaximumHeight(22); title_header->setMaximumHeight(22);
layout->addWidget(title_header, 0); layout->addWidget(title_header, 0);
registComp(title_header);
} }
registComp(view);
layout->addWidget(view, 1); layout->addWidget(view, 1);
setMouseTracking(true); setMouseTracking(true);
} }
@ -71,16 +75,15 @@ void BaseView::registComp(QWidget *child) {
} }
ViewPresent *BaseView::viewPanel() const { ViewPresent *BaseView::viewPanel() const {
const SplitRect *tnode = this; if (!parentRect())
while (!tnode->parentRect()) { return nullptr;
tnode = tnode->parentRect(); return parentRect()->viewPanel();
}
return static_cast<ViewPresent *>(const_cast<SplitRect *>(tnode));
} }
void BaseView::closeView() {} void BaseView::closeView() {}
bool BaseView::contains(QWidget *ptr) const { return comps_list.contains(ptr); }
QWidget *BaseView::bind() const { return const_cast<BaseView *>(this); } QWidget *BaseView::bind() const { return const_cast<BaseView *>(this); }
SplitRect *BaseView::parentRect() const { return parent_store; } SplitRect *BaseView::parentRect() const { return parent_store; }
@ -113,8 +116,9 @@ QRectF BaseView::outline() const { return this->rect(); }
void BaseView::relayout(const QRectF &outline) { this->setGeometry(outline.toRect()); } void BaseView::relayout(const QRectF &outline) { this->setGeometry(outline.toRect()); }
void BaseView::insertPerceptionHandle(ViewPresent *obj) { void BaseView::installPerceptionHandle(ViewPresent *obj) {
for (auto &it : comps_list) { for (auto &it : comps_list) {
it->setAcceptDrops(true);
it->removeEventFilter(obj); it->removeEventFilter(obj);
it->installEventFilter(obj); it->installEventFilter(obj);
} }
@ -210,9 +214,25 @@ ViewPresent::ViewPresent(SplitRect *initial_view, QWidget *parent) : QWidget(par
qRegisterMetaTypeStreamOperators<ViewDragDrapCommon>("ViewDragDrapCommon"); qRegisterMetaTypeStreamOperators<ViewDragDrapCommon>("ViewDragDrapCommon");
} }
void ViewPresent::setViewAdjust(bool state) { this->dragdrop_state = state; } void ViewPresent::registViewComp(BaseView *it) {
if (this->all_sep_views.contains(it))
return;
bool ViewPresent::adjustState() const { return this->dragdrop_state; } it->installPerceptionHandle(this);
all_sep_views << it;
}
void ViewPresent::setViewAdjust(bool state, BaseView *one) {
this->adjust_state = state;
if (!state)
one = nullptr;
this->adjust_view_store = one;
}
bool ViewPresent::adjustState() const { return this->adjust_state; }
BaseView *ViewPresent::adjustView() const { return this->adjust_view_store; }
void ViewPresent::append(SplitRect *inst, uint index) { void ViewPresent::append(SplitRect *inst, uint index) {
auto pos = splitterPos(); auto pos = splitterPos();
@ -242,9 +262,25 @@ void ViewPresent::append(SplitRect *inst, uint index) {
} }
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) { bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
if (adjustState()) { auto adjust_state = adjustState();
qDebug() << "adjust-move";
return true; qDebug() << event->type();
if (adjust_state && event->type() == QEvent::DragEnter) {
for (auto &v : all_sep_views) {
if (v->contains((QWidget *)watched)) {
auto outline = v->outline();
QPoint gpos(v->bind()->mapToGlobal(outline.topLeft().toPoint()));
QPoint local_pos(mapFromGlobal(gpos));
QRectF local_geom(local_pos, outline.size());
accept_panel->setGeometry(local_geom.toRect());
accept_panel->setVisible(true);
event->accept();
return true;
}
}
} }
return QWidget::eventFilter(watched, event); return QWidget::eventFilter(watched, event);
@ -252,6 +288,8 @@ bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); } QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); }
ViewPresent *ViewPresent::viewPanel() const { return const_cast<ViewPresent *>(this); }
SplitRect *ViewPresent::parentRect() const { return nullptr; } SplitRect *ViewPresent::parentRect() const { return nullptr; }
void ViewPresent::setParentRect(SplitRect *pinst) { throw new SimpleException<QString>("非法操作", "不允许对ViewPresent调用setParentRect"); } void ViewPresent::setParentRect(SplitRect *pinst) { throw new SimpleException<QString>("非法操作", "不允许对ViewPresent调用setParentRect"); }
@ -446,6 +484,12 @@ SplitView::SplitView(SplitRect *first, SplitRect *next, QWidget *parent) : QWidg
QWidget *SplitView::bind() const { return const_cast<SplitView *>(this); } QWidget *SplitView::bind() const { return const_cast<SplitView *>(this); }
ViewPresent *SplitView::viewPanel() const {
if (parentRect() == nullptr)
return nullptr;
return parentRect()->viewPanel();
}
SplitRect *SplitView::parentRect() const { return parent_inst; } SplitRect *SplitView::parentRect() const { return parent_inst; }
void SplitView::setParentRect(SplitRect *pinst) { void SplitView::setParentRect(SplitRect *pinst) {
@ -697,7 +741,8 @@ void DragHeader::mouseReleaseEvent(QMouseEvent *event) {
void DragHeader::mouseMoveEvent(QMouseEvent *event) { void DragHeader::mouseMoveEvent(QMouseEvent *event) {
if (std::get<0>(press_flag) && QLineF(std::get<1>(press_flag), event->pos()).length() > QApplication::startDragDistance()) { if (std::get<0>(press_flag) && QLineF(std::get<1>(press_flag), event->pos()).length() > QApplication::startDragDistance()) {
view_core->viewPanel()->setViewAdjust(true); auto panel = view_core->viewPanel();
panel->setViewAdjust(true, view_core);
QDrag *drag = new QDrag(this); QDrag *drag = new QDrag(this);
auto pix = view_core->grab(); auto pix = view_core->grab();
@ -705,13 +750,7 @@ void DragHeader::mouseMoveEvent(QMouseEvent *event) {
drag->setHotSpot(QPoint(20, 20)); drag->setHotSpot(QPoint(20, 20));
QMimeData *mimeData = new QMimeData; QMimeData *mimeData = new QMimeData;
mimeData->setText("移动视图:" + view_core->title());
ViewDragDrapCommon wrap(view_core);
QByteArray buff;
QDataStream out(&buff, QIODevice::WriteOnly);
out << wrap;
mimeData->setData(ViewDragDrapCommon::type_sign, buff);
drag->setMimeData(mimeData); drag->setMimeData(mimeData);
drag->exec(); drag->exec();

View File

@ -45,6 +45,7 @@ namespace SplitFrame {
virtual ~SplitRect() = default; virtual ~SplitRect() = default;
virtual QWidget *bind() const = 0; virtual QWidget *bind() const = 0;
virtual ViewPresent *viewPanel() const = 0;
virtual SplitRect *parentRect() const = 0; virtual SplitRect *parentRect() const = 0;
virtual void setParentRect(SplitRect *pinst) = 0; virtual void setParentRect(SplitRect *pinst) = 0;
@ -71,6 +72,7 @@ namespace SplitFrame {
// SplitRect interface // SplitRect interface
public: public:
virtual QWidget *bind() const override; virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override; virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override; virtual void setParentRect(SplitRect *pinst) override;
@ -135,6 +137,8 @@ namespace SplitFrame {
* @brief * @brief
*/ */
class SPLITVIEW_EXPORT BaseView : public QWidget, public SplitRect { class SPLITVIEW_EXPORT BaseView : public QWidget, public SplitRect {
friend class ViewPresent;
public: public:
BaseView(const QString &title, QWidget *view, bool empty = false, QWidget *parent = nullptr); BaseView(const QString &title, QWidget *view, bool empty = false, QWidget *parent = nullptr);
@ -144,12 +148,13 @@ namespace SplitFrame {
virtual void setIcon(const QIcon &icon); virtual void setIcon(const QIcon &icon);
virtual QIcon viewIcon() const; virtual QIcon viewIcon() const;
ViewPresent *viewPanel() const;
virtual void closeView(); virtual void closeView();
virtual bool contains(QWidget *ptr) const;
// SplitRect interface // SplitRect interface
public: public:
virtual QWidget *bind() const override; virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override; virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override; virtual void setParentRect(SplitRect *pinst) override;
virtual std::pair<SplitRect *, SplitRect *> child() const override; virtual std::pair<SplitRect *, SplitRect *> child() const override;
@ -161,7 +166,6 @@ namespace SplitFrame {
virtual QRectF outline() const override; virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override; virtual void relayout(const QRectF &outline) override;
virtual void insertPerceptionHandle(ViewPresent *obj);
virtual void paintEvent(QPaintEvent *ev) override; virtual void paintEvent(QPaintEvent *ev) override;
virtual void retrieveComp(SplitRect *child_inst) override; virtual void retrieveComp(SplitRect *child_inst) override;
@ -171,6 +175,7 @@ namespace SplitFrame {
QList<QWidget *> comps_list; QList<QWidget *> comps_list;
protected: protected:
virtual void installPerceptionHandle(ViewPresent *obj);
virtual void registComp(QWidget *child); virtual void registComp(QWidget *child);
}; };
@ -181,12 +186,15 @@ namespace SplitFrame {
public: public:
ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr); ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr);
void registViewComp(BaseView *it);
/** /**
* @brief * @brief
* @param state * @param state
*/ */
void setViewAdjust(bool state); void setViewAdjust(bool state, BaseView *one = nullptr);
bool adjustState() const; bool adjustState() const;
BaseView *adjustView() const;
void append(SplitRect *inst, uint index); void append(SplitRect *inst, uint index);
@ -197,6 +205,7 @@ namespace SplitFrame {
// SplitRect interface // SplitRect interface
public: public:
virtual QWidget *bind() const override; virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override; virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override; virtual void setParentRect(SplitRect *pinst) override;
@ -220,11 +229,13 @@ namespace SplitFrame {
private: private:
DockPanel *const accept_panel; DockPanel *const accept_panel;
BaseView *adjust_view_store;
bool press_flags = false; bool press_flags = false;
bool dragdrop_state = false; bool adjust_state = false;
QList<SplitRect *> view_anchors; QList<SplitRect *> view_anchors;
// 方向splitter位置splitter宽度extend索引 // 方向splitter位置splitter宽度extend索引
std::tuple<SplitType, float, float, uint> split_info_store; std::tuple<SplitType, float, float, uint> split_info_store;
QList<BaseView *> all_sep_views;
virtual void relayout(); virtual void relayout();
std::pair<QRectF, QRectF> viewRects(); std::pair<QRectF, QRectF> viewRects();

View File

@ -41,9 +41,9 @@ int main(int argc, char *argv[]) {
win->setCentralWidget(conv); win->setCentralWidget(conv);
conv->append(cview, 0); conv->append(cview, 0);
aview->installEventFilter(conv); conv->registViewComp(aview);
bview->installEventFilter(conv); conv->registViewComp(bview);
cview->installEventFilter(conv); conv->registViewComp(cview);
win->show(); win->show();