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

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() : 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)
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->setSpacing(0);
registComp(this);
if (!empty) {
title_header = new DragHeader(this);
title_header->setText(title);
title_header->setMaximumHeight(22);
layout->addWidget(title_header, 0);
registComp(title_header);
}
registComp(view);
layout->addWidget(view, 1);
setMouseTracking(true);
}
@ -71,16 +75,15 @@ void BaseView::registComp(QWidget *child) {
}
ViewPresent *BaseView::viewPanel() const {
const SplitRect *tnode = this;
while (!tnode->parentRect()) {
tnode = tnode->parentRect();
}
return static_cast<ViewPresent *>(const_cast<SplitRect *>(tnode));
if (!parentRect())
return nullptr;
return parentRect()->viewPanel();
}
void BaseView::closeView() {}
bool BaseView::contains(QWidget *ptr) const { return comps_list.contains(ptr); }
QWidget *BaseView::bind() const { return const_cast<BaseView *>(this); }
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::insertPerceptionHandle(ViewPresent *obj) {
void BaseView::installPerceptionHandle(ViewPresent *obj) {
for (auto &it : comps_list) {
it->setAcceptDrops(true);
it->removeEventFilter(obj);
it->installEventFilter(obj);
}
@ -210,9 +214,25 @@ ViewPresent::ViewPresent(SplitRect *initial_view, QWidget *parent) : QWidget(par
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) {
auto pos = splitterPos();
@ -242,9 +262,25 @@ void ViewPresent::append(SplitRect *inst, uint index) {
}
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
if (adjustState()) {
qDebug() << "adjust-move";
return true;
auto adjust_state = adjustState();
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);
@ -252,6 +288,8 @@ bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); }
ViewPresent *ViewPresent::viewPanel() const { return const_cast<ViewPresent *>(this); }
SplitRect *ViewPresent::parentRect() const { return nullptr; }
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); }
ViewPresent *SplitView::viewPanel() const {
if (parentRect() == nullptr)
return nullptr;
return parentRect()->viewPanel();
}
SplitRect *SplitView::parentRect() const { return parent_inst; }
void SplitView::setParentRect(SplitRect *pinst) {
@ -697,7 +741,8 @@ void DragHeader::mouseReleaseEvent(QMouseEvent *event) {
void DragHeader::mouseMoveEvent(QMouseEvent *event) {
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);
auto pix = view_core->grab();
@ -705,13 +750,7 @@ void DragHeader::mouseMoveEvent(QMouseEvent *event) {
drag->setHotSpot(QPoint(20, 20));
QMimeData *mimeData = new QMimeData;
ViewDragDrapCommon wrap(view_core);
QByteArray buff;
QDataStream out(&buff, QIODevice::WriteOnly);
out << wrap;
mimeData->setData(ViewDragDrapCommon::type_sign, buff);
mimeData->setText("移动视图:" + view_core->title());
drag->setMimeData(mimeData);
drag->exec();

View File

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

View File

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