初步完成视图拖拽

This commit is contained in:
玉宇清音 2023-08-21 22:04:20 +08:00
parent 3a8ada4681
commit cd6ff24d0e
3 changed files with 97 additions and 68 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.0, 2023-08-20T21:48:18. --> <!-- Written by QtCreator 4.15.0, 2023-08-21T11:28:09. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>

View File

@ -14,28 +14,6 @@
using namespace SplitFrame; using namespace SplitFrame;
using namespace Config; 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) { BaseView::BaseView(const QString &title, QWidget *view, bool empty, QWidget *parent) : QWidget(parent), title_header(nullptr), parent_store(nullptr) {
auto layout = new QVBoxLayout(this); auto layout = new QVBoxLayout(this);
layout->setMargin(0); layout->setMargin(0);
@ -126,15 +104,18 @@ void BaseView::installPerceptionHandle(ViewPresent *obj) {
void BaseView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); } void BaseView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); }
void BaseView::retrieveComp(SplitRect *child_inst) { throw new SimpleException<QString>("非法操作", "BaseView不支持retrieveComp操作"); } void BaseView::remove(SplitRect *child_inst) { throw new SimpleException<QString>("非法操作", "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); QWidget::paintEvent(event);
QPainter p(this); QPainter p(this);
@ -172,7 +153,11 @@ void DockPanel::paintEvent(QPaintEvent *event) {
p.drawRoundRect(QRectF(lt1, QSizeF(300, 100))); 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(); auto tuple_list = view_rects();
if (std::get<0>(tuple_list).contains(event->pos())) { if (std::get<0>(tuple_list).contains(event->pos())) {
this->active_comp = ActiveArea::LEFT; this->active_comp = ActiveArea::LEFT;
@ -194,7 +179,53 @@ void DockPanel::mouseMoveEvent(QMouseEvent *event) {
this->update(); this->update();
} }
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> 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<QRectF, QRectF, QRectF, QRectF, QRectF> AttachPanel::view_rects() const {
auto rect = this->rect(); auto rect = this->rect();
auto lt0 = rect.center() - QPoint(50, 150); auto lt0 = rect.center() - QPoint(50, 150);
auto lt1 = rect.center() - QPoint(150, 50); auto lt1 = rect.center() - QPoint(150, 50);
@ -203,17 +234,17 @@ std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> DockPanel::view_rects() const
QRectF(lt0 + QPointF(0, 200), QSizeF(100, 100)), QRectF(lt1 + QPointF(100, 0), QSizeF(100, 100))); 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(); accept_panel->hide();
this->split_info_store = std::make_tuple(SplitType::SPLIT_H, 100, 7, 1); this->split_info_store = std::make_tuple(SplitType::SPLIT_H, 100, 7, 1);
initial_view->setParentRect(this); initial_view->setParentRect(this);
setMouseTracking(true); setMouseTracking(true);
view_anchors << initial_view; view_anchors << initial_view;
qRegisterMetaTypeStreamOperators<ViewDragDrapCommon>("ViewDragDrapCommon");
} }
ViewPresent::~ViewPresent() { accept_panel->deleteLater(); }
void ViewPresent::registViewComp(BaseView *it) { void ViewPresent::registViewComp(BaseView *it) {
if (this->all_sep_views.contains(it)) if (this->all_sep_views.contains(it))
return; return;
@ -264,19 +295,18 @@ void ViewPresent::append(SplitRect *inst, uint index) {
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) { bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
auto adjust_state = adjustState(); auto adjust_state = adjustState();
qDebug() << event->type();
if (adjust_state && event->type() == QEvent::DragEnter) { if (adjust_state && event->type() == QEvent::DragEnter) {
for (auto &v : all_sep_views) { for (auto &v : all_sep_views) {
if (v->contains((QWidget *)watched)) { if (v->contains((QWidget *)watched)) {
auto outline = v->outline(); auto outline = v->outline();
QPoint gpos(v->bind()->mapToGlobal(outline.topLeft().toPoint())); 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->setVisible(true);
accept_panel->bind(v);
event->accept(); event->accept();
return true; return true;
} }
@ -311,16 +341,7 @@ void ViewPresent::replace(SplitRect *view, SplitRect *old) {
if (view_anchors.contains(view)) if (view_anchors.contains(view))
return; return;
if (old) {
old->bind()->setVisible(false);
old->setParentRect(nullptr);
}
view_anchors.replace(view_anchors.indexOf(old), view); view_anchors.replace(view_anchors.indexOf(old), view);
if (view) {
view->setParentRect(this);
view->bind()->setVisible(true);
}
relayout(); relayout();
} }
@ -354,7 +375,7 @@ void ViewPresent::paintEvent(QPaintEvent *ev) {
it->bind()->update(); it->bind()->update();
} }
void ViewPresent::retrieveComp(SplitRect *child_inst) { void ViewPresent::remove(SplitRect *child_inst) {
if (!view_anchors.contains(child_inst)) if (!view_anchors.contains(child_inst))
throw new SimpleException<QString>("参数非法", "回收的指定视图不属于本ViewPresent"); throw new SimpleException<QString>("参数非法", "回收的指定视图不属于本ViewPresent");
@ -417,10 +438,17 @@ void ViewPresent::relayout() {
auto rects = viewRects(); auto rects = viewRects();
if (view_anchors.size() == 2) { if (view_anchors.size() == 2) {
view_anchors[0]->setParentRect(this);
view_anchors[0]->relayout(rects.first.toRect()); 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]->relayout(rects.second.toRect());
view_anchors[1]->bind()->setVisible(true);
} else if (view_anchors.size() == 1) { } else if (view_anchors.size() == 1) {
view_anchors[0]->setParentRect(this);
view_anchors[0]->relayout(this->rect()); view_anchors[0]->relayout(this->rect());
view_anchors[0]->bind()->setVisible(true);
} }
update(); update();
@ -520,9 +548,6 @@ void SplitView::replace(SplitRect *view, SplitRect *old) {
if (child_store.contains(old) && !child_store.contains(view)) { if (child_store.contains(old) && !child_store.contains(view)) {
auto index = child_store.indexOf(old); auto index = child_store.indexOf(old);
child_store.replace(index, view); child_store.replace(index, view);
old->setParentRect(nullptr);
view->setParentRect(this);
} }
relayout(); relayout();
@ -535,7 +560,7 @@ void SplitView::relayout(const QRectF &outlinex) {
update(); update();
} }
void SplitView::retrieveComp(SplitRect *child_inst) { void SplitView::remove(SplitRect *child_inst) {
auto pinst = parentRect(); auto pinst = parentRect();
auto sib = this->child().first; auto sib = this->child().first;
@ -627,15 +652,15 @@ void SplitView::relayout() {
auto rects = viewRects(); auto rects = viewRects();
auto pair = child(); 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<QWidget *>(pair.first); auto awidget = dynamic_cast<QWidget *>(pair.first);
auto bwidget = dynamic_cast<QWidget *>(pair.second); auto bwidget = dynamic_cast<QWidget *>(pair.second);
if (!awidget->isVisible()) awidget->setVisible(true);
awidget->setVisible(true); bwidget->setVisible(true);
if (!bwidget->isVisible())
bwidget->setVisible(true);
pair.first->relayout(std::get<0>(rects));
pair.second->relayout(std::get<1>(rects));
update(); update();
} }
@ -706,7 +731,7 @@ DragHeader::DragHeader(BaseView *bind) : QFrame(bind->bind()), icon_store(new QL
connect(hide, &QPushButton::clicked, [=]() { connect(hide, &QPushButton::clicked, [=]() {
auto con = this->view_core->parentRect(); auto con = this->view_core->parentRect();
con->retrieveComp(view_core); con->remove(view_core);
}); });
connect(close, &QPushButton::clicked, [=]() { connect(close, &QPushButton::clicked, [=]() {

View File

@ -15,17 +15,20 @@ namespace SplitFrame {
/** /**
* @brief * @brief
*/ */
class SPLITVIEW_EXPORT DockPanel : public QWidget { class SPLITVIEW_EXPORT AttachPanel : public QWidget {
enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE }; enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE };
public: public:
DockPanel(ViewPresent *host); AttachPanel(ViewPresent *host);
void bind(BaseView *widget); void bind(BaseView *widget);
BaseView *target() const; BaseView *attachTarget() const;
virtual void paintEvent(QPaintEvent *event) override; virtual void paintEvent(QPaintEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *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: private:
ViewPresent *const size_host; ViewPresent *const size_host;
@ -59,7 +62,7 @@ namespace SplitFrame {
virtual QRectF outline() const = 0; virtual QRectF outline() const = 0;
virtual void relayout(const QRectF &outline) = 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; virtual void paintEvent(QPaintEvent *ev) = 0;
}; };
@ -85,7 +88,7 @@ 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 retrieveComp(SplitRect *child_inst) override; virtual void remove(SplitRect *child_inst) override;
// QWidget interface // QWidget interface
protected: protected:
@ -167,7 +170,7 @@ namespace SplitFrame {
virtual void relayout(const QRectF &outline) override; virtual void relayout(const QRectF &outline) override;
virtual void paintEvent(QPaintEvent *ev) override; virtual void paintEvent(QPaintEvent *ev) override;
virtual void retrieveComp(SplitRect *child_inst) override; virtual void remove(SplitRect *child_inst) override;
private: private:
DragHeader *title_header; DragHeader *title_header;
@ -185,6 +188,7 @@ namespace SplitFrame {
class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect { class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect {
public: public:
ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr); ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr);
virtual ~ViewPresent();
void registViewComp(BaseView *it); void registViewComp(BaseView *it);
@ -217,7 +221,7 @@ namespace SplitFrame {
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override; virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
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 retrieveComp(SplitRect *child_inst) override; virtual void remove(SplitRect *child_inst) override;
// QWidget interface // QWidget interface
protected: protected:
@ -228,7 +232,7 @@ namespace SplitFrame {
virtual void mouseMoveEvent(QMouseEvent *event) override; virtual void mouseMoveEvent(QMouseEvent *event) override;
private: private:
DockPanel *const accept_panel; AttachPanel *const accept_panel;
BaseView *adjust_view_store; BaseView *adjust_view_store;
bool press_flags = false; bool press_flags = false;
bool adjust_state = false; bool adjust_state = false;