QtNovelUI/SplitView/splitview.cpp

903 lines
24 KiB
C++

#include "splitview.h"
#include <QApplication>
#include <QDebug>
#include <QDrag>
#include <QHBoxLayout>
#include <QLineF>
#include <QMimeData>
#include <QPainter>
#include <QPushButton>
#include <QResizeEvent>
#include <QStyleOption>
#include <libConfig.h>
using namespace SplitFrame;
using namespace Config;
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);
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);
}
void BaseView::setTitle(const QString &title) {
QWidget::setWindowTitle(title);
title_header->setText(title);
}
QString BaseView::title() const {
return this->title_header->text();
}
void BaseView::setIcon(const QIcon &icon) {
this->title_header->setIcon(icon);
}
QIcon BaseView::viewIcon() const {
return title_header->icon();
}
void BaseView::registComp(QWidget *child) {
if (this->comps_list.contains(child))
return;
comps_list << child;
if (child != this)
child->setParent(this);
}
ViewPresent *BaseView::viewPanel() const { 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;
}
void BaseView::setParentRect(SplitRect *pinst) {
this->parent_store = pinst;
this->setParent(pinst->bind());
}
QRectF BaseView::outline() const {
return this->rect();
}
void BaseView::relayout(const QRectF &outline) {
this->setGeometry(outline.toRect());
update();
}
void BaseView::installPerceptionHandle(ViewPresent *obj) {
for (auto &it : comps_list) {
it->setAcceptDrops(true);
it->removeEventFilter(obj);
it->installEventFilter(obj);
}
}
void BaseView::paintEvent(QPaintEvent *ev) {
QWidget::paintEvent(ev);
}
AttachPanel::AttachPanel(ViewPresent *host) : QWidget(host->bind()), adjust_host(host) {
setWindowOpacity(50);
setAcceptDrops(true);
}
void AttachPanel::bindAttachment(BaseView *widget) { this->current_target = widget; }
BaseView *AttachPanel::attachmentTarget() const { return this->current_target; }
void AttachPanel::paintEvent(QPaintEvent *event) {
QWidget::paintEvent(event);
QPainter p(this);
p.setBrush(Qt::lightGray);
p.fillRect(this->rect(), Qt::lightGray);
auto rect = this->rect();
p.setPen(QPen(Qt::black, 4));
switch (active_comp) {
case ActiveArea::LEFT:
p.fillRect(QRectF(rect.topLeft(), QSizeF(rect.width() / 2, rect.height())), Qt::gray);
break;
case ActiveArea::RIGHT:
p.fillRect(QRectF(rect.center() - QPointF(0, rect.height() / 2), QSizeF(rect.width() / 2, rect.height())), Qt::gray);
break;
case ActiveArea::TOP:
p.fillRect(QRectF(rect.topLeft(), QSizeF(rect.width(), rect.height() / 2)), Qt::gray);
break;
case ActiveArea::BOTTOM:
p.fillRect(QRectF(rect.center() - QPointF(rect.width() / 2, 0), QSizeF(rect.width(), rect.height() / 2)), Qt::gray);
break;
case ActiveArea::CENTER:
p.fillRect(rect, Qt::gray);
break;
default:
break;
}
p.setBrush(Qt::transparent);
auto lt0 = rect.center() - QPoint(50, 150);
p.drawRoundRect(QRectF(lt0, QSizeF(100, 300)));
auto lt1 = rect.center() - QPoint(150, 50);
p.drawRoundRect(QRectF(lt1, QSizeF(300, 100)));
}
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;
}
else if (std::get<1>(tuple_list).contains(event->pos())) {
this->active_comp = ActiveArea::RIGHT;
}
else if (std::get<2>(tuple_list).contains(event->pos())) {
this->active_comp = ActiveArea::TOP;
}
else if (std::get<3>(tuple_list).contains(event->pos())) {
this->active_comp = ActiveArea::BOTTOM;
}
else if (std::get<4>(tuple_list).contains(event->pos())) {
this->active_comp = ActiveArea::CENTER;
}
else {
this->active_comp = ActiveArea::NONE;
}
this->update();
}
void AttachPanel::dragEnterEvent(QDragEnterEvent *event) {
QWidget::dragEnterEvent(event);
if (adjust_host->adjustState())
event->acceptProposedAction();
}
void AttachPanel::dropEvent(QDropEvent *event) {
QWidget::dropEvent(event);
event->acceptProposedAction();
auto xfrom = adjust_host->adjustView();
auto target = this->attachmentTarget();
if (target != xfrom && active_comp != ActiveArea::NONE) {
RectCom *newsplit = nullptr;
xfrom->parentRect()->removeComp(xfrom);
adjust_host->objsRelateRebuild();
auto ptarget = target->parentRect();
auto target_rect = target->outline();
switch (this->active_comp) {
case ActiveArea::LEFT: {
newsplit = new SplitView(xfrom, target, adjust_host);
newsplit->relayout(target_rect);
static_cast<SplitView *>(newsplit)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), true);
} break;
case ActiveArea::RIGHT: {
newsplit = new SplitView(target, xfrom, adjust_host);
newsplit->relayout(target_rect);
static_cast<SplitView *>(newsplit)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), true);
} break;
case ActiveArea::TOP: {
newsplit = new SplitView(xfrom, target, adjust_host);
newsplit->relayout(target_rect);
static_cast<SplitView *>(newsplit)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), true);
} break;
case ActiveArea::BOTTOM: {
newsplit = new SplitView(target, xfrom, adjust_host);
newsplit->relayout(target_rect);
static_cast<SplitView *>(newsplit)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), true);
} break;
case ActiveArea::CENTER: {
newsplit = xfrom;
} break;
default:
return;
}
ptarget->replaceComp(newsplit, target);
adjust_host->objsRelateRebuild();
adjust_host->unusedResRelease();
}
adjust_host->setViewAdjust();
this->setVisible(false);
}
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> AttachPanel::view_rects() const {
auto rect = this->rect();
auto lt0 = rect.center() - QPoint(50, 150);
auto lt1 = rect.center() - QPoint(150, 50);
return std::make_tuple(QRectF(lt1, QSizeF(100, 100)), QRectF(lt1 + QPoint(200, 0), QSizeF(100, 100)), QRectF(lt0, QSizeF(100, 100)),
QRectF(lt0 + QPointF(0, 200), QSizeF(100, 100)), QRectF(lt1 + QPointF(100, 0), QSizeF(100, 100)));
}
ViewPresent::ViewPresent(QWidget *parent) : QWidget(parent), accept_panel(new AttachPanel(this)) {
accept_panel->hide();
setMouseTracking(true);
}
ViewPresent::~ViewPresent() {
accept_panel->deleteLater();
}
void ViewPresent::addListener(FreedomViewsListener *lsn) {
if (lsn_list.contains(lsn))
return;
lsn_list << lsn;
}
void ViewPresent::removeListener(FreedomViewsListener *lsn) {
lsn_list.removeAll(lsn);
}
void ViewPresent::registViewComp(BaseView *it) {
if (this->all_sep_views.contains(it))
return;
it->installPerceptionHandle(this);
all_sep_views << it;
}
void ViewPresent::markFreedom(BaseView *view) {
if (!freedom_views.contains(view))
freedom_views << view;
}
// void ViewPresent::collectFreedomView(BaseView *invisible) {
// if (!freedom_views.contains(invisible)) {
// freedom_views << invisible;
// for (auto &it : lsn_list)
// it->freedomAppended(invisible);
// }
// invisible->setParentRect(nullptr);
// invisible->bind()->setVisible(false);
//}
void ViewPresent::setTempVisible(BaseView *target) {
if (target != nullptr && !this->freedom_views.contains(target))
throw new SimpleException<QString>("参数异常", "非闲置视图不可以设置为临时视图");
if (this->temp_visible_view) {
// collectFreedomView(temp_visible_view);
}
temp_visible_view = target;
if (temp_visible_view) {
temp_visible_view->setParentRect(this);
temp_visible_view->bind()->setVisible(true);
temp_visible_view->bind()->raise();
}
relayout();
}
void ViewPresent::setViewAdjust(BaseView *one) {
this->adjust_view_temp = one;
}
bool ViewPresent::adjustState() const {
return this->adjust_view_temp != nullptr;
}
BaseView *ViewPresent::adjustView() const {
return this->adjust_view_temp;
}
void ViewPresent::resetViews(RectCom *center, RectCom *extend) {
view_anchors << center;
if (extend) {
view_anchors << extend;
}
this->objsRelateRebuild();
this->relayout();
}
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
auto adjust_state = adjustState();
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 localpos(mapFromGlobal(gpos));
accept_panel->raise();
accept_panel->setGeometry(QRect(localpos, outline.size().toSize()));
accept_panel->setVisible(true);
accept_panel->bindAttachment(v);
event->accept();
return true;
}
}
}
if (event->type() == QEvent::Drop) {
accept_panel->hide();
accept_panel->lower();
}
if (this->temp_visible_view && event->type() == QEvent::MouseButtonPress) {
if (!temp_visible_view->contains((QWidget *)watched)) {
setTempVisible(nullptr);
}
}
return QWidget::eventFilter(watched, event);
}
QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); }
bool ViewPresent::contains(QWidget *ptr) const { return false; }
ViewPresent *ViewPresent::viewPanel() const {
return const_cast<ViewPresent *>(this);
}
SplitRect *ViewPresent::parentRect() const { return nullptr; }
void ViewPresent::objsRelateRebuild() { setParentRect(nullptr); }
void ViewPresent::markUnused(SplitRect *item) {
if (!this->unused_splits.contains(item))
unused_splits << item;
}
void ViewPresent::unusedResRelease() {
for (auto &it : unused_splits)
delete it;
unused_splits.clear();
}
void ViewPresent::setParentRect(SplitRect *) {
auto pair = child();
pair.first->setParentRect(this);
if (pair.second)
pair.second->setParentRect(this);
}
std::pair<RectCom *, RectCom *> ViewPresent::child() const {
RectCom *inst0 = nullptr, *inst1 = nullptr;
if (view_anchors.size() > 1)
inst1 = view_anchors[1];
if (view_anchors.size() > 0)
inst0 = view_anchors[0];
return std::make_pair(inst0, inst1);
}
void ViewPresent::replaceComp(RectCom *view, RectCom *old) {
if (!view_anchors.contains(old))
throw new SimpleException<QString>("参数错误", "指定替换的界面不属于此界面");
if (view_anchors.contains(view))
return;
view_anchors.replace(view_anchors.indexOf(old), view);
objsRelateRebuild();
update();
}
float ViewPresent::splitterWidth() const {
return std::get<2>(split_info_store);
}
float ViewPresent::splitterPos() const {
return std::get<1>(split_info_store);
}
SplitType ViewPresent::splitType() const {
return std::get<0>(split_info_store);
}
void ViewPresent::setSplitInfo(SplitType type, float pos, float width, bool relayout) {
this->split_info_store = std::make_tuple(type, pos, width);
if (relayout)
this->relayout();
}
QRectF ViewPresent::outline() const {
return this->rect();
}
void ViewPresent::relayout(const QRectF &outline) {
setGeometry(outline.toRect());
}
void ViewPresent::paintEvent(QPaintEvent *ev) {
QWidget::paintEvent(ev);
if (view_anchors.size() == 2) {
QPainter p(this);
auto handle_rect = handleRect();
p.fillRect(handle_rect, QBrush(Qt::gray));
}
for (auto &it : view_anchors) {
it->bind()->setVisible(true);
it->bind()->update();
}
if (temp_visible_view) {
temp_visible_view->bind()->setVisible(true);
temp_visible_view->bind()->update();
}
for (auto &it : freedom_views) {
it->bind()->setVisible(false);
it->bind()->update();
}
}
void ViewPresent::removeComp(BaseView *child_inst) {
if (temp_visible_view == child_inst) {
temp_visible_view = nullptr;
freedom_views.removeAll(child_inst);
for (auto &lsn : lsn_list)
lsn->freedomRemoved(static_cast<BaseView *>(child_inst));
} else {
if (!view_anchors.contains(child_inst))
throw new SimpleException<QString>("参数非法", "回收的指定视图不属于本ViewPresent");
markFreedom(child_inst);
view_anchors.removeAll(child_inst);
}
viewPanel()->objsRelateRebuild();
viewPanel()->unusedResRelease();
update();
}
void ViewPresent::resizeEvent(QResizeEvent *ev) {
QWidget::resizeEvent(ev);
relayout();
}
void ViewPresent::mousePressEvent(QMouseEvent *event) {
QWidget::mousePressEvent(event);
if (event->button() == Qt::MouseButton::LeftButton) {
if (handleRect().contains(event->pos()))
this->press_flags = true;
}
}
void ViewPresent::mouseReleaseEvent(QMouseEvent *event) {
QWidget::mouseReleaseEvent(event);
if (event->button() == Qt::MouseButton::LeftButton) {
this->press_flags = false;
}
}
void ViewPresent::mouseMoveEvent(QMouseEvent *event) {
QWidget::mouseMoveEvent(event);
auto drag_rect = handleRect();
if (drag_rect.contains(event->pos())) {
if (splitType() == SplitType::SPLIT_H)
setCursor(QCursor(Qt::CursorShape::SplitHCursor));
else
setCursor(QCursor(Qt::CursorShape::SplitVCursor));
}
else {
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
}
if (this->press_flags) {
auto pos = this->mapFromGlobal(event->globalPos());
auto split_margin = splitterWidth();
if (std::get<0>(split_info_store) == SplitType::SPLIT_H) {
setSplitInfo(splitType(), pos.x() - split_margin / 2, split_margin, true);
}
else {
setSplitInfo(splitType(), pos.y() - split_margin / 2, split_margin, true);
}
update();
}
}
void ViewPresent::relayout() {
auto rects = viewRects();
if (view_anchors.size() == 2) {
view_anchors[0]->relayout(rects.first.toRect());
view_anchors[1]->relayout(rects.second.toRect());
} else if (view_anchors.size() == 1) {
view_anchors[0]->relayout(this->rect());
}
if (temp_visible_view) {
temp_visible_view->relayout(QRectF(QPointF(), QSizeF(300, this->height())));
}
update();
}
std::pair<QRectF, QRectF> ViewPresent::viewRects() {
auto xrect = this->rect();
auto type = (int)splitType();
if (!type) {
auto width0 = splitterPos();
if (width0 + splitterWidth() > xrect.width())
width0 = xrect.width() - splitterWidth();
if (width0 < 0)
width0 = 0;
setSplitInfo(splitType(), width0, splitterWidth(), false);
auto rect0 = QRectF(xrect.topLeft(), QSizeF(width0, xrect.height()));
auto rect1 = QRectF(xrect.topLeft() + QPointF(rect0.width() + splitterWidth(), 0),
QSizeF(xrect.width() - rect0.width() - splitterWidth(), xrect.height()));
return std::make_pair(rect0, rect1);
}
else {
auto height0 = splitterPos();
if (height0 + splitterWidth() > xrect.height())
height0 = xrect.height() - splitterWidth();
if (height0 < 0)
height0 = 0;
setSplitInfo(splitType(), height0, splitterWidth(), false);
auto rect0 = QRectF(xrect.topLeft(), QSizeF(xrect.width(), height0));
auto rect1 = QRectF(xrect.topLeft() + QPointF(0, rect0.height() + splitterWidth()),
QSizeF(xrect.width(), xrect.height() - splitterWidth() - rect0.height()));
return std::make_pair(rect0, rect1);
}
}
QRectF ViewPresent::handleRect() const {
QRectF rect;
auto width_middle = splitterWidth() - 2;
if (splitType() == SplitType::SPLIT_H) {
rect = QRectF(splitterPos() + 1, 0, width_middle, outline().height());
}
else {
rect = QRectF(0, splitterPos() + 1, outline().width(), width_middle);
}
return rect;
}
SplitView::SplitView(RectCom *first, RectCom *next, QWidget *parent) : QWidget(parent) {
this->split_info_value = std::make_tuple(SplitType::SPLIT_H, 100, 7);
this->child_store << first;
this->child_store << next;
setMouseTracking(true);
}
SplitFrame::SplitView::~SplitView() {
}
QWidget *SplitView::bind() const {
return const_cast<SplitView *>(this);
}
ViewPresent *SplitView::viewPanel() const { return parentRect()->viewPanel(); }
SplitRect *SplitView::parentRect() const {
return parent_inst;
}
void SplitView::setParentRect(SplitRect *pinst) {
QWidget::setParent(pinst->bind());
auto pair = child();
pair.first->setParentRect(this);
pair.second->setParentRect(this);
}
std::pair<RectCom *, RectCom *> SplitView::child() const { return std::make_pair(child_store[0], child_store[1]); }
float SplitView::splitterWidth() const {
return std::get<2>(split_info_value);
}
float SplitView::splitterPos() const {
return std::get<1>(split_info_value);
}
SplitType SplitView::splitType() const {
return std::get<0>(split_info_value);
}
void SplitView::setSplitInfo(SplitType type, float pos, float width, bool relayout) {
this->split_info_value = std::make_tuple(type, pos, width);
if (relayout)
this->relayout();
}
void SplitView::replaceComp(RectCom *view, RectCom *old) {
if (!child_store.contains(old) || child_store.contains(view)) {
throw new SimpleException<QString>("参数非法", "要替换的视图不属于本构件,或者新视图本就属于本构件");
}
auto index = child_store.indexOf(old);
child_store.replace(index, view);
viewPanel()->objsRelateRebuild();
}
QRectF SplitView::outline() const {
return this->rect();
}
void SplitView::relayout(const QRectF &outlinex) {
this->setGeometry(outlinex.toRect());
update();
}
void SplitView::removeComp(BaseView *child_inst) {
auto pinst = parentRect();
auto sib = this->child().first;
if (child_inst == sib)
sib = this->child().second;
pinst->replaceComp(sib, this);
viewPanel()->markUnused(this);
viewPanel()->markFreedom(child_inst);
viewPanel()->objsRelateRebuild();
viewPanel()->unusedResRelease();
}
void SplitView::paintEvent(QPaintEvent *ev) {
QWidget::paintEvent(ev);
QPainter p(this);
QRectF rect = handleRect();
p.fillRect(rect, QBrush(Qt::gray, Qt::BrushStyle::SolidPattern));
for (auto &it : child_store)
it->bind()->update();
}
bool SplitView::contains(QWidget *ptr) const { return false; }
void SplitView::resizeEvent(QResizeEvent *ev) {
QWidget::resizeEvent(ev);
relayout();
}
void SplitView::mousePressEvent(QMouseEvent *event) {
QWidget::mousePressEvent(event);
if (event->button() == Qt::MouseButton::LeftButton) {
if (handleRect().contains(event->pos()))
this->press_flags = true;
}
}
void SplitView::mouseReleaseEvent(QMouseEvent *event) {
QWidget::mouseReleaseEvent(event);
if (event->button() == Qt::MouseButton::LeftButton) {
this->press_flags = false;
}
}
void SplitView::mouseMoveEvent(QMouseEvent *event) {
QWidget::mouseMoveEvent(event);
auto drag_rect = handleRect() + QMargins(2, 2, 2, 2);
if (drag_rect.contains(event->pos())) {
if (splitType() == SplitType::SPLIT_H)
setCursor(QCursor(Qt::CursorShape::SplitHCursor));
else
setCursor(QCursor(Qt::CursorShape::SplitVCursor));
drags_flag = true;
} else {
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
}
if (this->press_flags) {
auto pos = this->mapFromGlobal(event->globalPos());
auto split_margin = splitterWidth();
if (std::get<0>(split_info_value) == SplitType::SPLIT_H) {
setSplitInfo(splitType(), pos.x() - split_margin / 2, split_margin, true);
} else {
setSplitInfo(splitType(), pos.y() - split_margin / 2, split_margin, true);
}
update();
}
}
bool SplitView::eventFilter(QObject *watched, QEvent *event) {
if (watched != this && this->drags_flag && event->type() == QEvent::MouseMove) {
auto x = static_cast<QMouseEvent *>(event);
auto pos = mapFromGlobal(x->globalPos());
if (!handleRect().contains(pos)) {
setCursor(QCursor(Qt::CursorShape::ArrowCursor));
this->drags_flag = false;
}
return true;
}
return QWidget::eventFilter(watched, event);
}
void SplitView::relayout() {
auto rects = viewRects();
auto pair = child();
pair.first->relayout(std::get<0>(rects));
pair.second->relayout(std::get<1>(rects));
update();
}
std::pair<QRectF, QRectF> SplitView::viewRects() {
auto xrect = this->rect();
auto type = (int)splitType();
if (!type) {
auto width0 = splitterPos();
if (width0 + splitterWidth() > xrect.width())
width0 = xrect.width() - splitterWidth();
if (width0 < 0)
width0 = 0;
setSplitInfo(splitType(), width0, splitterWidth(), false);
auto rect0 = QRectF(xrect.topLeft(), QSizeF(width0, xrect.height()));
auto rect1 = QRectF(xrect.topLeft() + QPointF(rect0.width() + splitterWidth(), 0),
QSizeF(xrect.width() - rect0.width() - splitterWidth(), xrect.height()));
return std::make_pair(rect0, rect1);
}
else {
auto height0 = splitterPos();
if (height0 + splitterWidth() > xrect.height())
height0 = xrect.height() - splitterWidth();
if (height0 < 0)
height0 = 0;
setSplitInfo(splitType(), height0, splitterWidth(), false);
auto rect0 = QRectF(xrect.topLeft(), QSizeF(xrect.width(), height0));
auto rect1 = QRectF(xrect.topLeft() + QPointF(0, rect0.height() + splitterWidth()),
QSizeF(xrect.width(), xrect.height() - splitterWidth() - rect0.height()));
return std::make_pair(rect0, rect1);
}
}
QRectF SplitView::handleRect() const {
QRectF rect;
auto width_middle = splitterWidth() - 2;
if (splitType() == SplitType::SPLIT_H) {
rect = QRectF(splitterPos() + 1, 0, width_middle, outline().height());
}
else {
rect = QRectF(0, splitterPos() + 1, outline().width(), width_middle);
}
return rect;
}
DragHeader::DragHeader(BaseView *bind) : QFrame(bind->bind()), icon_store(new QLabel(this)), title_store(new QLabel(this)), view_core(bind) {
setFrameShadow(QFrame::Shadow::Raised);
setFrameShape(QFrame::Shape::Box);
setStyleSheet("background-color: rgb(200, 200, 255);");
auto layout = new QHBoxLayout(this);
layout->setMargin(1);
layout->setSpacing(2);
layout->addWidget(icon_store, 0);
layout->addWidget(title_store, 1);
auto hide = new QPushButton("-", this);
layout->addWidget(hide, 0);
hide->setMaximumSize(20, 20);
auto close = new QPushButton("X", this);
layout->addWidget(close, 0);
close->setMaximumSize(20, 20);
connect(hide, &QPushButton::clicked, [=]() {
auto con = this->view_core->parentRect();
con->removeComp(view_core);
});
connect(close, &QPushButton::clicked, [=]() {
hide->click();
view_core->closeView();
});
}
void DragHeader::setIcon(const QIcon &icon) {
icon_inst = icon;
auto len = this->height() - 2;
this->icon_store->setPixmap(icon.pixmap(QSize(len, len)));
}
QIcon DragHeader::icon() const {
return this->icon_inst;
}
void DragHeader::setText(const QString &title) {
this->title_store->setText(title);
}
QString DragHeader::text() const {
return title_store->text();
}
void DragHeader::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton && !std::get<0>(press_flag)) {
this->press_flag = std::make_tuple(true, event->pos());
}
}
void DragHeader::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
this->press_flag = std::make_tuple(false, QPointF());
}
}
void DragHeader::mouseMoveEvent(QMouseEvent *event) {
auto distance = QLineF(std::get<1>(press_flag), event->pos()).length();
if (std::get<0>(press_flag) && distance > QApplication::startDragDistance()) {
auto panel = view_core->viewPanel();
panel->setViewAdjust(view_core);
QDrag *drag = new QDrag(this);
auto pix = view_core->grab();
drag->setPixmap(pix);
drag->setHotSpot(QPoint(20, 20));
QMimeData *mimeData = new QMimeData;
mimeData->setText("移动视图:" + view_core->title());
drag->setMimeData(mimeData);
drag->exec();
}
}