From 3a8ada4681c403f59ad0c5dd6f923bdb99cd82e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=89=E5=AE=87=E6=B8=85=E9=9F=B3?= <2422523675@qq.com> Date: Mon, 21 Aug 2023 11:28:03 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E6=8B=96=E5=8A=A8?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=9A=84=E6=8E=A5=E6=94=B6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SplitView/splitview.cpp | 81 ++++++++++++++++++++++++++++++----------- SplitView/splitview.h | 19 ++++++++-- u_test/main.cpp | 6 +-- 3 files changed, 78 insertions(+), 28 deletions(-) diff --git a/SplitView/splitview.cpp b/SplitView/splitview.cpp index 9a58e6d..da666c3 100644 --- a/SplitView/splitview.cpp +++ b/SplitView/splitview.cpp @@ -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(const_cast(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(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"); } -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(this); } +ViewPresent *ViewPresent::viewPanel() const { return const_cast(this); } + SplitRect *ViewPresent::parentRect() const { return nullptr; } void ViewPresent::setParentRect(SplitRect *pinst) { throw new SimpleException("非法操作", "不允许对ViewPresent调用setParentRect!"); } @@ -446,6 +484,12 @@ SplitView::SplitView(SplitRect *first, SplitRect *next, QWidget *parent) : QWidg QWidget *SplitView::bind() const { return const_cast(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(); diff --git a/SplitView/splitview.h b/SplitView/splitview.h index ff2fd3a..1df785e 100644 --- a/SplitView/splitview.h +++ b/SplitView/splitview.h @@ -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 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 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 view_anchors; // 方向,splitter位置,splitter宽度,extend索引 std::tuple split_info_store; + QList all_sep_views; virtual void relayout(); std::pair viewRects(); diff --git a/u_test/main.cpp b/u_test/main.cpp index ba3a718..f41d246 100644 --- a/u_test/main.cpp +++ b/u_test/main.cpp @@ -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();