213 lines
6.4 KiB
C++
213 lines
6.4 KiB
C++
#include "splitview.h"
|
|
#include "baseview.h"
|
|
#include <QPainter>
|
|
#include <libConfig.h>
|
|
|
|
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<QWidget *>(it);
|
|
if (widget) {
|
|
widget->setParent(nullptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
QWidget *SplitView::bind() const { return const_cast<SplitView *>(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<bool>("非法操作", "SplitView当前不支持registElement操作"); }
|
|
|
|
void SplitView::pRelease() { throw new SimpleException<bool>("非法操作", "SplitView当前不支持pRelease操作"); }
|
|
|
|
void SplitView::pClose() { throw new SimpleException<bool>("非法操作", "SplitView当前不支持pClose操作"); }
|
|
|
|
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 (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<QString>("参数非法", "要替换的视图不属于本构件,或者新视图本就属于本构件");
|
|
}
|
|
|
|
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<SplitRect *>(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<QRectF, QRectF> 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;
|
|
}
|