#include "splitview.h" #include "baseview.h" #include #include using namespace SplitFrame; using namespace Config; 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() { for (auto &it : children()) { auto widget = qobject_cast(it); if (widget) { widget->setParent(nullptr); } } } QWidget *SplitView::bind() const { return const_cast(this); } ViewPresent *SplitView::viewPanel() const { return parentRes()->viewPanel(); } ViewRes *SplitView::parentRes() const { return parent_inst; } void SplitView::setParentRes(ViewRes *pinst) { this->parent_inst = pinst; QWidget::setParent(pinst != nullptr ? pinst->bind() : nullptr); for (auto &c : child_store) c->setParentRes(this); } void SplitView::registElement(QWidget *) { throw new SimpleException("非法操作", "SplitView当前不支持registElement操作"); } void SplitView::pRelease() { throw new SimpleException("非法操作", "SplitView当前不支持pRelease操作"); } void SplitView::pClose() { throw new SimpleException("非法操作", "SplitView当前不支持pClose操作"); } std::pair 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 (type == SplitType::SPLIT_H) setCursor(Qt::CursorShape::SplitHCursor); else setCursor(Qt::CursorShape::SplitVCursor); if (relayout) this->relayout(); } void SplitView::replaceComp(RectCom *view, RectCom *old) { if (!child_store.contains(old) || child_store.contains(view)) { throw new SimpleException("参数非法", "要替换的视图不属于本构件,或者新视图本就属于本构件"); } auto index = child_store.indexOf(old); child_store.replace(index, view); view->setParentRes(this); viewPanel()->objsRelateRebuild(); } QRectF SplitView::outline() const { return this->rect(); } void SplitView::relayout(const QRectF &outlinex) { this->setGeometry(outlinex.toRect()); this->relayout(); } void SplitView::removeComp(RectCom *child_inst) { auto pinst = parentRes(); auto prev_childs = child(); prev_childs.first->setParentRes(nullptr); prev_childs.second->setParentRes(nullptr); this->child_store.clear(); this->setParentRes(nullptr); auto sib = prev_childs.first; if (child_inst == sib) sib = prev_childs.second; static_cast(pinst)->replaceComp(sib, this); delete this; } void SplitView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); QPainter p(this); QRectF rect = handle_rect(); p.fillRect(rect, QBrush(Qt::gray, Qt::BrushStyle::SolidPattern)); for (auto &it : child_store) { it->bind()->setVisible(true); it->bind()->update(); } } bool SplitView::contains(QWidget *) const { return false; } QString SplitView::title() const { return ""; } bool SplitView::canReplace() const { return true; } void SplitView::resizeEvent(QResizeEvent *ev) { QWidget::resizeEvent(ev); relayout(); } void SplitView::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); if (event->button() == Qt::MouseButton::LeftButton) { if (handle_rect().contains(event->pos())) drags_state = true; } } void SplitView::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); if (event->button() == Qt::MouseButton::LeftButton) { drags_state = false; } } void SplitView::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); if (drags_state) { 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(); } } void SplitView::relayout() { auto rects = view_rects(); auto pair = child(); pair.first->relayout(std::get<0>(rects)); pair.second->relayout(std::get<1>(rects)); update(); } std::pair SplitView::view_rects() { 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::handle_rect() 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; }