diff --git a/QtNovelDesc.pro.user b/QtNovelDesc.pro.user index 6c2470b..112a888 100644 --- a/QtNovelDesc.pro.user +++ b/QtNovelDesc.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/SplitView/splitview.cpp b/SplitView/splitview.cpp index da666c3..f97c3b5 100644 --- a/SplitView/splitview.cpp +++ b/SplitView/splitview.cpp @@ -14,28 +14,6 @@ using namespace SplitFrame; using namespace Config; -class ViewDragDrapCommon { -public: - BaseView *target; - static QString type_sign; - - ViewDragDrapCommon(BaseView *inst) : target(inst) {} - ViewDragDrapCommon() : target(nullptr) {} -}; -QString ViewDragDrapCommon::type_sign = "application/x-qt-windows-mime;value=\"ViewDragDrapCommon\""; - -Q_DECLARE_METATYPE(ViewDragDrapCommon) -QDataStream &operator<<(QDataStream &out, const ViewDragDrapCommon &myObj) { - out << myObj.target; - return out; -} -QDataStream &operator>>(QDataStream &in, ViewDragDrapCommon &myObj) { - qint64 handle; - in >> handle; - myObj.target = (BaseView *)handle; - return in; -} - BaseView::BaseView(const QString &title, QWidget *view, bool empty, QWidget *parent) : QWidget(parent), title_header(nullptr), parent_store(nullptr) { auto layout = new QVBoxLayout(this); layout->setMargin(0); @@ -126,15 +104,18 @@ void BaseView::installPerceptionHandle(ViewPresent *obj) { void BaseView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); } -void BaseView::retrieveComp(SplitRect *child_inst) { throw new SimpleException("非法操作", "BaseView不支持retrieveComp操作"); } +void BaseView::remove(SplitRect *child_inst) { throw new SimpleException("非法操作", "BaseView不支持retrieveComp操作"); } -DockPanel::DockPanel(ViewPresent *host) : QWidget(host->bind()), size_host(host) { setWindowOpacity(50); } +AttachPanel::AttachPanel(ViewPresent *host) : QWidget(), size_host(host) { + setWindowOpacity(50); + setAcceptDrops(true); +} -void DockPanel::bind(BaseView *widget) { this->current_target = widget; } +void AttachPanel::bind(BaseView *widget) { this->current_target = widget; } -BaseView *DockPanel::target() const { return this->current_target; } +BaseView *AttachPanel::attachTarget() const { return this->current_target; } -void DockPanel::paintEvent(QPaintEvent *event) { +void AttachPanel::paintEvent(QPaintEvent *event) { QWidget::paintEvent(event); QPainter p(this); @@ -172,7 +153,11 @@ void DockPanel::paintEvent(QPaintEvent *event) { p.drawRoundRect(QRectF(lt1, QSizeF(300, 100))); } -void DockPanel::mouseMoveEvent(QMouseEvent *event) { +void AttachPanel::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); } + +void AttachPanel::dragMoveEvent(QDragMoveEvent *event) { + QWidget::dragMoveEvent(event); + auto tuple_list = view_rects(); if (std::get<0>(tuple_list).contains(event->pos())) { this->active_comp = ActiveArea::LEFT; @@ -194,7 +179,53 @@ void DockPanel::mouseMoveEvent(QMouseEvent *event) { this->update(); } -std::tuple DockPanel::view_rects() const { +void AttachPanel::dragEnterEvent(QDragEnterEvent *event) { + QWidget::dragEnterEvent(event); + + if (size_host->adjustState()) + event->acceptProposedAction(); +} + +void AttachPanel::dropEvent(QDropEvent *event) { + QWidget::dropEvent(event); + + auto xsource = size_host->adjustView(); + xsource->parentRect()->remove(xsource); + auto target = this->attachTarget(); + auto ptarget = target->parentRect(); + + SplitRect *newsplit = nullptr; + switch (this->active_comp) { + case ActiveArea::LEFT: { + newsplit = new SplitView(xsource, target, size_host); + newsplit->setSplitInfo(SplitType::SPLIT_H, target->outline().width() / 2, size_host->splitterWidth()); + } break; + case ActiveArea::RIGHT: { + newsplit = new SplitView(target, xsource, size_host); + newsplit->setSplitInfo(SplitType::SPLIT_H, target->outline().width() / 2, size_host->splitterWidth()); + } break; + case ActiveArea::TOP: { + newsplit = new SplitView(xsource, target, size_host); + newsplit->setSplitInfo(SplitType::SPLIT_V, target->outline().height() / 2, size_host->splitterWidth()); + } break; + case ActiveArea::BOTTOM: { + newsplit = new SplitView(target, xsource, size_host); + newsplit->setSplitInfo(SplitType::SPLIT_V, target->outline().height() / 2, size_host->splitterWidth()); + } break; + case ActiveArea::CENTER: { + newsplit = xsource; + } break; + default: + return; + } + + ptarget->replace(newsplit, target); + this->setVisible(false); + + event->acceptProposedAction(); +} + +std::tuple AttachPanel::view_rects() const { auto rect = this->rect(); auto lt0 = rect.center() - QPoint(50, 150); auto lt1 = rect.center() - QPoint(150, 50); @@ -203,17 +234,17 @@ std::tuple DockPanel::view_rects() const QRectF(lt0 + QPointF(0, 200), QSizeF(100, 100)), QRectF(lt1 + QPointF(100, 0), QSizeF(100, 100))); } -ViewPresent::ViewPresent(SplitRect *initial_view, QWidget *parent) : QWidget(parent), accept_panel(new DockPanel(this)) { +ViewPresent::ViewPresent(SplitRect *initial_view, QWidget *parent) : QWidget(parent), accept_panel(new AttachPanel(this)) { accept_panel->hide(); this->split_info_store = std::make_tuple(SplitType::SPLIT_H, 100, 7, 1); initial_view->setParentRect(this); setMouseTracking(true); view_anchors << initial_view; - - qRegisterMetaTypeStreamOperators("ViewDragDrapCommon"); } +ViewPresent::~ViewPresent() { accept_panel->deleteLater(); } + void ViewPresent::registViewComp(BaseView *it) { if (this->all_sep_views.contains(it)) return; @@ -264,19 +295,18 @@ void ViewPresent::append(SplitRect *inst, uint index) { bool ViewPresent::eventFilter(QObject *watched, QEvent *event) { 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->setWindowFlag(Qt::FramelessWindowHint); + accept_panel->show(); + accept_panel->setGeometry(QRect(gpos, outline.size().toSize())); accept_panel->setVisible(true); + accept_panel->bind(v); event->accept(); return true; } @@ -311,16 +341,7 @@ void ViewPresent::replace(SplitRect *view, SplitRect *old) { if (view_anchors.contains(view)) return; - if (old) { - old->bind()->setVisible(false); - old->setParentRect(nullptr); - } - view_anchors.replace(view_anchors.indexOf(old), view); - if (view) { - view->setParentRect(this); - view->bind()->setVisible(true); - } relayout(); } @@ -354,7 +375,7 @@ void ViewPresent::paintEvent(QPaintEvent *ev) { it->bind()->update(); } -void ViewPresent::retrieveComp(SplitRect *child_inst) { +void ViewPresent::remove(SplitRect *child_inst) { if (!view_anchors.contains(child_inst)) throw new SimpleException("参数非法", "回收的指定视图不属于本ViewPresent"); @@ -417,10 +438,17 @@ void ViewPresent::relayout() { auto rects = viewRects(); if (view_anchors.size() == 2) { + view_anchors[0]->setParentRect(this); view_anchors[0]->relayout(rects.first.toRect()); + view_anchors[0]->bind()->setVisible(true); + + view_anchors[1]->setParentRect(this); view_anchors[1]->relayout(rects.second.toRect()); + view_anchors[1]->bind()->setVisible(true); } else if (view_anchors.size() == 1) { + view_anchors[0]->setParentRect(this); view_anchors[0]->relayout(this->rect()); + view_anchors[0]->bind()->setVisible(true); } update(); @@ -520,9 +548,6 @@ void SplitView::replace(SplitRect *view, SplitRect *old) { if (child_store.contains(old) && !child_store.contains(view)) { auto index = child_store.indexOf(old); child_store.replace(index, view); - - old->setParentRect(nullptr); - view->setParentRect(this); } relayout(); @@ -535,7 +560,7 @@ void SplitView::relayout(const QRectF &outlinex) { update(); } -void SplitView::retrieveComp(SplitRect *child_inst) { +void SplitView::remove(SplitRect *child_inst) { auto pinst = parentRect(); auto sib = this->child().first; @@ -627,15 +652,15 @@ void SplitView::relayout() { auto rects = viewRects(); auto pair = child(); + pair.first->setParentRect(this); + pair.first->relayout(std::get<0>(rects)); + pair.second->setParentRect(this); + pair.second->relayout(std::get<1>(rects)); + auto awidget = dynamic_cast(pair.first); auto bwidget = dynamic_cast(pair.second); - if (!awidget->isVisible()) - awidget->setVisible(true); - if (!bwidget->isVisible()) - bwidget->setVisible(true); - - pair.first->relayout(std::get<0>(rects)); - pair.second->relayout(std::get<1>(rects)); + awidget->setVisible(true); + bwidget->setVisible(true); update(); } @@ -706,7 +731,7 @@ DragHeader::DragHeader(BaseView *bind) : QFrame(bind->bind()), icon_store(new QL connect(hide, &QPushButton::clicked, [=]() { auto con = this->view_core->parentRect(); - con->retrieveComp(view_core); + con->remove(view_core); }); connect(close, &QPushButton::clicked, [=]() { diff --git a/SplitView/splitview.h b/SplitView/splitview.h index 1df785e..56bdb52 100644 --- a/SplitView/splitview.h +++ b/SplitView/splitview.h @@ -15,17 +15,20 @@ namespace SplitFrame { /** * @brief 承接堆放操作及设定摆放位置 */ - class SPLITVIEW_EXPORT DockPanel : public QWidget { + class SPLITVIEW_EXPORT AttachPanel : public QWidget { enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE }; public: - DockPanel(ViewPresent *host); + AttachPanel(ViewPresent *host); void bind(BaseView *widget); - BaseView *target() const; + BaseView *attachTarget() const; virtual void paintEvent(QPaintEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override; + virtual void dragMoveEvent(QDragMoveEvent *event) override; + virtual void dragEnterEvent(QDragEnterEvent *event) override; + virtual void dropEvent(QDropEvent *event) override; private: ViewPresent *const size_host; @@ -59,7 +62,7 @@ namespace SplitFrame { virtual QRectF outline() const = 0; virtual void relayout(const QRectF &outline) = 0; - virtual void retrieveComp(SplitRect *child) = 0; + virtual void remove(SplitRect *child) = 0; virtual void paintEvent(QPaintEvent *ev) = 0; }; @@ -85,7 +88,7 @@ namespace SplitFrame { virtual QRectF outline() const override; virtual void relayout(const QRectF &outline) override; - virtual void retrieveComp(SplitRect *child_inst) override; + virtual void remove(SplitRect *child_inst) override; // QWidget interface protected: @@ -167,7 +170,7 @@ namespace SplitFrame { virtual void relayout(const QRectF &outline) override; virtual void paintEvent(QPaintEvent *ev) override; - virtual void retrieveComp(SplitRect *child_inst) override; + virtual void remove(SplitRect *child_inst) override; private: DragHeader *title_header; @@ -185,6 +188,7 @@ namespace SplitFrame { class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect { public: ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr); + virtual ~ViewPresent(); void registViewComp(BaseView *it); @@ -217,7 +221,7 @@ namespace SplitFrame { virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override; virtual QRectF outline() const override; virtual void relayout(const QRectF &outline) override; - virtual void retrieveComp(SplitRect *child_inst) override; + virtual void remove(SplitRect *child_inst) override; // QWidget interface protected: @@ -228,7 +232,7 @@ namespace SplitFrame { virtual void mouseMoveEvent(QMouseEvent *event) override; private: - DockPanel *const accept_panel; + AttachPanel *const accept_panel; BaseView *adjust_view_store; bool press_flags = false; bool adjust_state = false;