完全重构

This commit is contained in:
玉宇清音 2023-12-30 13:04:51 +08:00
parent 7dbba0a46a
commit a97829ddd2
27 changed files with 466 additions and 1259 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.15.0, 2023-12-22T22:09:13. -->
<!-- Written by QtCreator 4.15.0, 2023-12-29T18:05:56. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@ -31,7 +31,7 @@ MainWindow::MainWindow(XApp *core, const QString &layout, QWidget *parent)
: QMainWindow(parent),
layout_name_store(layout),
core_bind(core),
present_host(new SplitFrame::ViewPresent(this)),
present_host(new SplitFrame::SplitPanel(this)),
session_service(new ViewSession(XApp::gconfig, this)),
actions_stack(new QToolBar(this)),
views_bar(new ViewStackedBar(present_host, this)),
@ -58,7 +58,7 @@ MainWindow::MainWindow(XApp *core, const QString &layout, QWidget *parent)
MainWindow::~MainWindow() { core_bind->docsManager()->removePresent(center_frame); }
SplitFrame::ViewPresent *MainWindow::bindPresent() const { return present_host; }
SplitFrame::SplitPanel *MainWindow::bindPresent() const { return present_host; }
QString MainWindow::layoutName() const { return layout_name_store; }

View File

@ -17,7 +17,7 @@
#include <QTableView>
#include <QTreeView>
#include <libProjectManager.h>
#include <splitpanel.h>
#include <splitwindow.h>
class MainWindow : public QMainWindow , public Project::ManagerListener{
Q_OBJECT
@ -26,7 +26,7 @@ public:
MainWindow(XApp *core, const QString &layout, QWidget *parent = nullptr);
virtual ~MainWindow();
SplitFrame::ViewPresent *bindPresent() const;
SplitFrame::SplitPanel *bindPresent() const;
QString layoutName() const;
void resetLayoutName(const QString &name);
@ -34,7 +34,7 @@ private:
QString layout_name_store;
// model ============================================
XApp *const core_bind;
SplitFrame::ViewPresent *const present_host;
SplitFrame::SplitPanel *const present_host;
Core::ViewSession *const session_service;
// view =============================================

View File

@ -5,9 +5,9 @@
using namespace Components;
using namespace SplitFrame;
QHash<SplitFrame::ViewPresent *, MessageView *> MessageView::panel_map;
QHash<SplitFrame::SplitPanel *, MessageView *> MessageView::panel_map;
MessageView::MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base)
MessageView::MessageView(SplitFrame::SplitPanel *ins, QStandardItemModel *base)
: FnWrap<MessageView, false>(ins), ui_present(new QTableView(this)), items_present(base) {
auto layout = new QVBoxLayout(this);
layout->setMargin(0);
@ -18,7 +18,7 @@ MessageView::MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base)
ui_present->setMouseTracking(true);
}
MessageView *MessageView::gen(SplitFrame::ViewPresent *host, QStandardItemModel *base) {
MessageView *MessageView::gen(SplitFrame::SplitPanel *host, QStandardItemModel *base) {
if (panel_map.contains(host))
return panel_map[host];

View File

@ -5,7 +5,7 @@
#include <QHash>
#include <QStandardItemModel>
#include <QTableView>
#include <splitpanel.h>
#include <splitwindow.h>
namespace Components {
/**
@ -15,14 +15,14 @@ namespace Components {
public:
virtual ~MessageView() = default;
static MessageView *gen(SplitFrame::ViewPresent *host, QStandardItemModel *base);
static MessageView *gen(SplitFrame::SplitPanel *host, QStandardItemModel *base);
private:
MessageView(SplitFrame::ViewPresent *ins, QStandardItemModel *base);
MessageView(SplitFrame::SplitPanel *ins, QStandardItemModel *base);
QTableView *const ui_present;
QStandardItemModel *const items_present;
static QHash<SplitFrame::ViewPresent *, MessageView *> panel_map;
static QHash<SplitFrame::SplitPanel *, MessageView *> panel_map;
};
} // namespace Components

View File

@ -13,7 +13,7 @@ using namespace Core;
using namespace SplitFrame;
using namespace Presents;
PresentContainerView::PresentContainerView(ViewPresent *host)
PresentContainerView::PresentContainerView(SplitPanel *host)
: FnWrap<PresentContainerView, true>(host),
title_store(new QComboBox(this)),
stack_container(new QStackedWidget(this)),

View File

@ -6,7 +6,7 @@
#include <QPushButton>
#include <QStackedLayout>
#include <QStackedWidget>
#include <splitpanel.h>
#include <splitwindow.h>
namespace Presents {
class WelcomePanel;
@ -20,7 +20,7 @@ namespace Components {
class PresentContainerView : public SplitFrame::FnWrap<PresentContainerView, true>, public Presents::PresentHost {
Q_OBJECT
public:
PresentContainerView(SplitFrame::ViewPresent *host);
PresentContainerView(SplitFrame::SplitPanel *host);
// PresentContainer interface
public:

View File

@ -11,7 +11,7 @@ using namespace Schedule;
using namespace SplitFrame;
using namespace Core;
ProjectView::ProjectView(ViewPresent *host, CommandsDispatcher *core, Core::DocumentsManager *mgr)
ProjectView::ProjectView(SplitPanel *host, CommandsDispatcher *core, Core::DocumentsManager *mgr)
: FnWrap<ProjectView, false>(host), project_manager(mgr), source(core), view_present(new QTreeView(this)) {
auto layout = new QVBoxLayout(this);
layout->addWidget(view_present);

View File

@ -8,7 +8,7 @@
#include <QWidget>
#include <commandsdispatcher.h>
#include <libProjectManager.h>
#include <splitpanel.h>
#include <splitwindow.h>
namespace Components {
/**
@ -17,7 +17,7 @@ namespace Components {
class ProjectView : public SplitFrame::FnWrap<ProjectView, false> {
Q_OBJECT
public:
explicit ProjectView(SplitFrame::ViewPresent *host, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr);
explicit ProjectView(SplitFrame::SplitPanel *host, Schedule::CommandsDispatcher *core, Core::DocumentsManager *mgr);
QModelIndex currentIndex() const;

View File

@ -57,7 +57,7 @@ void views_state_store(Config::Configration *port, const QList<QString> &base_pa
}
}
void ViewSession::viewStatesSave(QMainWindow *win, SplitFrame::ViewPresent *root) {
void ViewSession::viewStatesSave(QMainWindow *win, SplitFrame::SplitPanel *root) {
recover_port->deleteX(base_path);
auto childs = root->child();
@ -73,7 +73,7 @@ void ViewSession::viewStatesSave(QMainWindow *win, SplitFrame::ViewPresent *root
}
RectCom *ViewSession::views_state_restore(const QHash<QString, SplitFrame::RectCom *> &cache, const QList<QString> &target_path,
Config::Configration *port, SplitFrame::ViewPresent *host) {
Config::Configration *port, SplitFrame::SplitPanel *host) {
auto values = port->getMap(target_path);
if (!values.size())
return nullptr;
@ -126,7 +126,7 @@ bool ViewSession::eventFilter(QObject *watched, QEvent *event) {
return QObject::eventFilter(watched, event);
}
void ViewSession::viewStatesRestore(QMainWindow *win, SplitFrame::ViewPresent *root) {
void ViewSession::viewStatesRestore(QMainWindow *win, SplitFrame::SplitPanel *root) {
auto key_path0 = base_path;
key_path0 << "rect_0";
auto rect = views_state_restore(this->view_store, key_path0, recover_port, root);

View File

@ -8,7 +8,7 @@
#include <QStandardItemModel>
#include <libConfig.h>
#include <presentcontainerview.h>
#include <splitpanel.h>
#include <splitwindow.h>
class MainWindow;
@ -20,12 +20,12 @@ namespace Core {
void initPresentView(Components::PresentContainerView *center_frame, Components::ProjectView *project_present, QStandardItemModel *model);
void viewStatesSave(QMainWindow *win, SplitFrame::ViewPresent *root);
void viewStatesRestore(QMainWindow *win, SplitFrame::ViewPresent *root);
void viewStatesSave(QMainWindow *win, SplitFrame::SplitPanel *root);
void viewStatesRestore(QMainWindow *win, SplitFrame::SplitPanel *root);
private:
QList<QString> base_path;
SplitFrame::ViewPresent *host;
SplitFrame::SplitPanel *host;
SplitFrame::RectCom *edit_panel = nullptr;
Config::Configration *const recover_port;
QHash<QString, SplitFrame::RectCom *> view_store;
@ -35,7 +35,7 @@ namespace Core {
std::map<SplitFrame::SplitView *, std::tuple<SplitFrame::SplitType, split_pos, split_width>> split_infos;
SplitFrame::RectCom *views_state_restore(const QHash<QString, SplitFrame::RectCom *> &cache, const QList<QString> &target_path,
Config::Configration *port, SplitFrame::ViewPresent *host);
Config::Configration *port, SplitFrame::SplitPanel *host);
void relayout_cascade(SplitFrame::RectCom *root);

View File

@ -6,7 +6,7 @@
using namespace Components;
using namespace SplitFrame;
ViewStackedBar::ViewStackedBar(ViewPresent *host, QWidget *parent) : QToolBar(parent), host_ptr(host) {
ViewStackedBar::ViewStackedBar(SplitPanel *host, QWidget *parent) : QToolBar(parent), host_ptr(host) {
setToolButtonStyle(Qt::ToolButtonStyle::ToolButtonIconOnly);
setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea | Qt::TopToolBarArea | Qt::BottomToolBarArea);
setContextMenuPolicy(Qt::CustomContextMenu);

View File

@ -3,13 +3,13 @@
#include <QHash>
#include <QToolBar>
#include <splitpanel.h>
#include <splitwindow.h>
namespace Components {
class ViewStackedBar : public QToolBar, public SplitFrame::FreedomViewsListener {
public:
ViewStackedBar(SplitFrame::ViewPresent *host, QWidget *parent = nullptr);
ViewStackedBar(SplitFrame::SplitPanel *host, QWidget *parent = nullptr);
// FreedomViewsListener interface
public:
@ -17,7 +17,7 @@ namespace Components {
virtual void freedomRemoved(SplitFrame::RectCom *ins) override;
private:
SplitFrame::ViewPresent *const host_ptr;
SplitFrame::SplitPanel *const host_ptr;
QHash<SplitFrame::RectCom *, QAction *> freedom_views;
};
} // namespace Components

View File

@ -8,174 +8,34 @@
#include <QMouseEvent>
#include <QPushButton>
using namespace SplitFrame;
using namespace base_view;
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);");
BaseView::BaseView(bool replace, bool retrieve, bool close) : QWidget(nullptr), m_replace(replace), m_retrieve(retrieve), m_close(close) {}
auto layout = new QHBoxLayout(this);
layout->setMargin(1);
layout->setSpacing(2);
layout->addWidget(icon_store, 0);
layout->addWidget(title_store, 1);
void BaseView::setParent(ViewRes *pinst) { this->parent_res = pinst; }
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, [=]() { view_core->pRelease(); });
connect(close, &QPushButton::clicked, [=]() { view_core->pClose(); });
split_frame::ResManager *BaseView::splitManager() const {
if(this->parent_res)
return this->parent_res->splitManager();
return nullptr;
}
void DragHeader::setIcon(const QIcon &icon) {
icon_inst = icon;
auto len = this->height() - 2;
this->icon_store->setPixmap(icon.pixmap(QSize(len, len)));
}
split_frame::ViewRes *BaseView::parentRes() const { return this->parent_res; }
QIcon DragHeader::icon() const { return this->icon_inst; }
QWidget *BaseView::widget() const { return const_cast<BaseView *>(this); }
void DragHeader::setText(const QString &title) { this->title_store->setText(title); }
bool BaseView::canRetrieve() const { return m_retrieve; }
QString DragHeader::text() const { return title_store->text(); }
bool BaseView::canClose() const { return m_close; }
void DragHeader::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton && !std::get<0>(press_flag)) {
this->press_flag = std::make_tuple(true, event->pos());
}
}
bool BaseView::canReplace() const { return m_replace; }
void DragHeader::mouseReleaseEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
this->press_flag = std::make_tuple(false, QPointF());
}
}
QIcon BaseView::icon() const { return QWidget::windowIcon(); }
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->setAdjustView(view_core);
QString BaseView::title() const { return QWidget::windowTitle(); }
QDrag *drag = new QDrag(this);
auto pix = view_core->bind()->grab();
drag->setPixmap(pix);
drag->setHotSpot(QPoint(20, 20));
QSizeF BaseView::viewSize() const { return this->size(); }
QMimeData *mimeData = new QMimeData;
mimeData->setText("移动视图:" + view_core->title());
drag->setMimeData(mimeData);
void BaseView::resizeView(const QSizeF &outline) { QWidget::resize(outline.toSize()); }
drag->exec();
}
}
BaseView::BaseView(const QString &title, QWidget *view, bool empty, bool replaceable, QWidget *parent)
: QWidget(parent), replace_able(replaceable), title_header(nullptr), parent_store(nullptr) {
auto layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
registElement(this);
setCursor(Qt::CursorShape::ArrowCursor);
if (!empty) {
title_header = new DragHeader(this);
title_header->setText(title);
title_header->setMaximumHeight(22);
layout->addWidget(title_header, 0);
registElement(title_header);
}
registElement(view);
layout->addWidget(view, 1);
setMouseTracking(true);
}
BaseView::~BaseView() {}
void BaseView::setTitle(const QString &title) {
QWidget::setWindowTitle(title);
title_store = title;
if (title_header)
title_header->setText(title);
}
QString BaseView::title() const { return title_store; }
void BaseView::setIcon(const QIcon &icon) {
this->icon_store = icon;
if (this->title_header)
this->title_header->setIcon(icon);
}
QIcon BaseView::viewIcon() const { return this->icon_store; }
bool BaseView::canReplace() const { return replace_able; }
void BaseView::registElement(QWidget *child) {
if (this->comps_list.contains(child))
return;
comps_list << child;
child->setMouseTracking(true);
if (child != this) {
child->setParent(this);
}
}
ViewPresent *BaseView::viewPanel() const {
auto parent_inst = parentRes();
return parent_inst->viewPanel();
}
bool BaseView::contains(QWidget *ptr) const { return comps_list.contains(ptr); }
QWidget *BaseView::bind() const { return const_cast<BaseView *>(this); }
ViewRes *BaseView::parentRes() const { return parent_store; }
void BaseView::pRelease() {
auto parent = parentRes();
if (parent) {
auto host_ptr = viewPanel();
dynamic_cast<SplitView *>(parent)->removeComp(this);
host_ptr->markFreedom(this);
}
}
void BaseView::pClose() {
auto ptr = viewPanel();
pRelease();
ptr->purge(this);
}
void BaseView::setParentRes(ViewRes *pinst) {
this->parent_store = pinst;
this->setParent(pinst != nullptr ? pinst->bind() : nullptr);
}
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->globalEventFilter());
it->installEventFilter(obj->globalEventFilter());
}
}
void BaseView::paintEvent(QPaintEvent *ev) { QWidget::paintEvent(ev); }
DragHeader::DragHeader(BaseView *bind) : QLabel(bind->widget()), view_core(bind) {}

View File

@ -1,31 +1,24 @@
#ifndef BASEVIEW_H
#define BASEVIEW_H
#include "splitpanel.h"
#include "splitview_interface.h"
#include <QFrame>
#include <QIcon>
#include <QLabel>
#include <QString>
namespace SplitFrame {
namespace base_view {
class BaseView;
/**
* @brief
*/
class DragHeader : public QFrame {
class SPLITVIEW_EXPORT DragHeader : public QLabel {
public:
DragHeader(BaseView *bind);
void setIcon(const QIcon &icon);
QIcon icon() const;
void setText(const QString &title);
QString text() const;
private:
QIcon icon_inst;
QLabel *const icon_store, *const title_store;
BaseView *const view_core;
BaseView *view_core;
std::tuple<bool, QPointF> press_flag = std::make_tuple(false, QPointF());
// QWidget interface
@ -38,48 +31,32 @@ namespace SplitFrame {
/**
* @brief
*/
class SPLITVIEW_EXPORT BaseView : private QWidget, public RectCom {
friend class ViewPresent;
class SPLITVIEW_EXPORT BaseView : public QWidget, public split_frame::ViewBase {
public:
BaseView(const QString &title, QWidget *view, bool empty = false, bool replaceable = false, QWidget *parent = nullptr);
virtual ~BaseView();
BaseView(bool replace, bool retrieve, bool close);
virtual void setTitle(const QString &title);
virtual QString title() const override;
void setParent(ViewRes *pinst);
virtual void setIcon(const QIcon &icon);
virtual QIcon viewIcon() const;
virtual bool canReplace() const override;
virtual bool contains(QWidget *inst) const override;
// ViewRes interface
public:
virtual ViewPresent *viewPanel() const override;
virtual void setParentRes(ViewRes *inst) override;
virtual ViewRes *parentRes() const override;
virtual void pRelease() override;
virtual void pClose() override;
virtual void registElement(QWidget *child) override;
virtual split_frame::ResManager *splitManager() const override;
virtual split_frame::ViewRes *parentRes() const override;
virtual QWidget *widget() const override;
virtual bool canRetrieve() const override;
virtual bool canClose() const override;
virtual bool canReplace() const override;
// RectCom interface
// ViewBase interface
public:
virtual QWidget *bind() const override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void paintEvent(QPaintEvent *ev) override;
virtual QIcon icon() const override;
virtual QString title() const override;
virtual QSizeF viewSize() const override;
virtual void resizeView(const QSizeF &outline) override;
private:
bool replace_able;
QIcon icon_store;
QString title_store;
DragHeader *title_header;
ViewRes *parent_store;
QList<QWidget *> comps_list;
protected:
virtual void installPerceptionHandle(ViewPresent *obj);
ViewRes *parent_res = nullptr;
bool m_replace = false, m_retrieve = false, m_close = false;
};
} // namespace SplitFrame

View File

@ -17,13 +17,13 @@ msvc{
SOURCES += \
baseview.cpp \
splitpanel.cpp \
splitview.cpp
splitwindow.cpp
HEADERS += \
baseview.h \
splitpanel.h \
splitpanel_global.h \
splitview.h
splitview_interface.h \
splitwindow.h
# Default rules for deployment.
unix {

View File

@ -1,531 +1,147 @@
#include "splitpanel.h"
#include "baseview.h"
#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>
namespace SplitFrame {
/**
* @brief
*/
class SPLITVIEW_EXPORT AttachPanel : public QWidget {
enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE };
public:
AttachPanel(ViewPresent *host);
void bindAttachment(RectCom *widget);
RectCom *attachmentTarget() const;
virtual void paintEvent(QPaintEvent *event) override;
virtual void dragMoveEvent(QDragMoveEvent *event) override;
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
private:
ViewPresent *const adjust_host;
RectCom *current_target;
ActiveArea active_comp;
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> view_rects() const;
};
} // namespace SplitFrame
using namespace SplitFrame;
using namespace split_frame;
using namespace split_panel;
using namespace Config;
AttachPanel::AttachPanel(ViewPresent *host) : QWidget(host->bind()), adjust_host(host) {
setWindowOpacity(50);
setAcceptDrops(true);
SplitPanel::SplitPanel(ViewBase *first, ViewBase *next, ViewRes *parent)
: QWidget(parent->widget()), parent_inst(parent)
{
this->split_member = std::make_tuple(first, next, SplitType::SPLIT_H);
}
void AttachPanel::bindAttachment(RectCom *widget) { this->current_target = widget; }
SplitPanel::~SplitPanel()
{
RectCom *AttachPanel::attachmentTarget() const { return this->current_target; }
}
void AttachPanel::paintEvent(QPaintEvent *event) {
QWidget::paintEvent(event);
ResManager *SplitPanel::splitManager() const { return this->parent_inst->splitManager(); }
QPainter p(this);
p.setBrush(Qt::lightGray);
p.fillRect(this->rect(), Qt::lightGray);
ViewRes *SplitPanel::parentRes() const
{
return parent_inst;
}
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:
if (attachmentTarget()->canReplace())
p.fillRect(rect, Qt::gray);
break;
default:
break;
bool SplitPanel::canRetrieve() const
{
return true;
}
bool SplitPanel::canClose() const
{
return true;
}
bool SplitPanel::canReplace() const
{
return true;
}
QIcon SplitPanel::icon() const
{
return QIcon();
}
QString SplitPanel::title() const
{
return QString("split-view%1").arg((int64_t)this);
}
QWidget *SplitPanel::widget() const
{
return const_cast<SplitPanel*>(this);
}
QSizeF SplitPanel::viewSize() const
{
return this->size();
}
void SplitPanel::resizeView(const QSizeF &outline)
{
if(outline != this->size()){
this->resize(outline.toSize());
}
p.setBrush(Qt::transparent);
p.setPen(QPen(Qt::black, 1));
auto x_views = view_rects();
QVector<QRectF> rects;
rects << std::get<0>(x_views);
rects << std::get<1>(x_views);
rects << std::get<2>(x_views);
rects << std::get<3>(x_views);
if (attachmentTarget()->canReplace())
rects << std::get<4>(x_views);
p.drawRects(rects);
}
auto tuple_values = this->child();
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;
if(view_list().size() == 1){
view_list().first()->resizeView(this->viewSize());
}
else{
switch (std::get<2>(tuple_values)) {
case SplitType::SPLIT_H: {
auto width_value = QWidget::width() * this->splitterPos();
std::get<0>(tuple_values)->widget()->setGeometry(0, 0, width_value, QWidget::height());
this->update();
}
auto second_pos = width_value + splitterWidth();
auto second_width = QWidget::width() - second_pos;
std::get<1>(tuple_values)->widget()->setGeometry(second_pos, 0, second_width, QWidget::height());
} break;
case SplitType::SPLIT_V: {
auto height_value = QWidget::height() * this->splitterPos();
std::get<0>(tuple_values)->widget()->setGeometry(0, 0, QWidget::width(), height_value);
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) {
if (active_comp == ActiveArea::CENTER && !target->canReplace()) {
} else {
static_cast<SplitRect *>(xfrom->parentRes())->removeComp(xfrom);
adjust_host->objsRelateRebuild();
auto ptarget = static_cast<SplitRect *>(target->parentRes());
auto target_rect = target->outline();
RectCom *new_split = nullptr;
switch (this->active_comp) {
case ActiveArea::LEFT: {
new_split = new SplitView(xfrom, target, adjust_host->bind());
static_cast<SplitView *>(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false);
} break;
case ActiveArea::RIGHT: {
new_split = new SplitView(target, xfrom, adjust_host->bind());
static_cast<SplitView *>(new_split)->setSplitInfo(SplitType::SPLIT_H, target_rect.width() / 2, adjust_host->splitterWidth(), false);
} break;
case ActiveArea::TOP: {
new_split = new SplitView(xfrom, target, adjust_host->bind());
static_cast<SplitView *>(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false);
} break;
case ActiveArea::BOTTOM: {
new_split = new SplitView(target, xfrom, adjust_host->bind());
static_cast<SplitView *>(new_split)->setSplitInfo(SplitType::SPLIT_V, target_rect.height() / 2, adjust_host->splitterWidth(), false);
} break;
case ActiveArea::CENTER: {
new_split = xfrom;
adjust_host->markFreedom(target);
} break;
default:
return;
}
ptarget->replaceComp(new_split, target);
new_split->relayout(target_rect);
adjust_host->objsRelateRebuild();
}
}
adjust_host->setAdjustView();
this->setVisible(false);
}
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> AttachPanel::view_rects() const {
auto rect = this->rect();
auto boder_len = std::min(rect.width() - 4, rect.height() - 4);
auto rect_length = std::min(boder_len * 4 / 5, 300);
auto rect_height = rect_length / 3;
auto lt0 = rect.center() - QPoint(rect_height / 2, rect_length / 2);
auto lt1 = rect.center() - QPoint(rect_length / 2, rect_height / 2);
return std::make_tuple(QRectF(lt1 - QPointF(3, 0), QSizeF(rect_height, rect_height)),
QRectF(lt1 + QPoint(rect_height * 2 + 3, 0), QSizeF(rect_height, rect_height)),
QRectF(lt0 - QPointF(0, 3), QSizeF(rect_height, rect_height)),
QRectF(lt0 + QPointF(0, rect_height * 2 + 3), QSizeF(rect_height, rect_height)),
QRectF(lt1 + QPointF(rect_height, 0), QSizeF(rect_height, rect_height)));
}
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::regist_basepanel(RectCom *it) {
if (this->all_func_views.contains(it))
return;
dynamic_cast<BaseView *>(it)->installPerceptionHandle(this);
all_func_views << it;
}
void ViewPresent::markFreedom(ViewRes *view, bool add) {
if (!view)
return;
auto cinst = static_cast<RectCom *>(view);
if (add) {
if (!freedom_views.contains(cinst)) {
freedom_views << cinst;
auto fview = static_cast<BaseView *>(view);
for (auto &lsn : lsn_list)
lsn->freedomAppended(cinst, fview->viewIcon(), fview->title());
}
cinst->bind()->setVisible(false);
cinst->setParentRes(nullptr);
} else {
if (freedom_views.contains(cinst)) {
freedom_views.removeAll(cinst);
for (auto &lsn : lsn_list)
lsn->freedomRemoved(cinst);
auto second_pos = height_value + splitterWidth();
auto second_height = QWidget::height() - second_pos;
std::get<1>(tuple_values)->widget()->setGeometry(0, second_pos, QWidget::width(), second_height);
} break;
}
}
}
void ViewPresent::purge(ViewRes *target) {
if (!target)
return;
auto cinst = static_cast<RectCom *>(target);
if (!all_func_views.contains(cinst))
throw new SimpleException<bool>("参数非法", "目标实例不属于本ViewPresent");
cinst->bind()->setVisible(false);
target->setParentRes(nullptr);
if (temp_visible_view.second == cinst)
temp_visible_view.second = nullptr;
all_func_views.removeAll(cinst);
freedom_views.removeAll(cinst);
display_members = nullptr;
objsRelateRebuild();
delete cinst;
std::tuple<ViewBase *, ViewBase *, SplitType> SplitPanel::child() const
{
return this->split_member;
}
void ViewPresent::temporaryVisible(DockType t, RectCom *target) {
if (target != nullptr && !this->freedom_views.contains(target))
throw new SimpleException<QString>("参数异常", "非闲置视图不可以设置为临时视图");
void SplitPanel::replaceComp(ViewBase *view, ViewBase *old)
{
QList<ViewBase*> mbrs = view_list();
if (this->temp_visible_view.second) {
markFreedom(temp_visible_view.second);
}
temp_visible_view = std::make_pair(t, target);
if (temp_visible_view.second) {
temp_visible_view.second->setParentRes(this);
temp_visible_view.second->bind()->setVisible(true);
objsRelateRebuild();
} else
relayout();
}
bool ViewPresent::isTemporaryView(RectCom *view) { return this->temp_visible_view.second == view; }
void ViewPresent::setAdjustView(RectCom *one) {
if (one) {
this->adjust_view_temp = one;
dynamic_cast<ViewRes *>(adjust_view_temp)->bind()->setVisible(false);
dynamic_cast<ViewRes *>(adjust_view_temp)->bind()->repaint();
} else {
dynamic_cast<ViewRes *>(adjust_view_temp)->bind()->setVisible(true);
dynamic_cast<ViewRes *>(adjust_view_temp)->bind()->repaint();
this->adjust_view_temp = one;
}
}
bool ViewPresent::adjustState() const { return this->adjust_view_temp != nullptr; }
RectCom *ViewPresent::adjustView() const { return this->adjust_view_temp; }
QObject *ViewPresent::globalEventFilter() const { return dynamic_cast<QObject *>(const_cast<ViewPresent *>(this)); }
SplitRect *ViewPresent::createSplit(RectCom *first, RectCom *next) {
auto inst = new SplitView(first, next, this);
return inst;
}
const QList<RectCom *> ViewPresent::freedomViews() const {
QList<RectCom *> ret_list;
for (auto &vit : freedom_views)
ret_list << vit;
return ret_list;
}
void ViewPresent::resetEngross(RectCom *view) {
for (auto &vit : all_func_views)
vit->pRelease();
temp_visible_view = std::make_pair(DockType::LEFT, nullptr);
display_members = nullptr;
if (freedom_views.contains(view))
freedom_views.removeAll(view);
view->setParentRes(this);
view->bind()->setVisible(true);
display_members = view;
objsRelateRebuild();
}
bool ViewPresent::eventFilter(QObject *watched, QEvent *event) {
auto adjust_state = adjustState();
if (adjust_state && event->type() == QEvent::DragEnter) {
for (auto &v : all_func_views) {
if (v->contains((QWidget *)watched) && !isTemporaryView(v)) {
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(!mbrs.contains(view) && mbrs.contains(old)){
if(std::get<1>(split_member) == old){
this->split_member = std::make_tuple(std::get<0>(split_member), view, std::get<2>(split_member));
}
}
if (event->type() == QEvent::Drop) {
accept_panel->hide();
accept_panel->lower();
}
if (this->temp_visible_view.second && event->type() == QEvent::MouseButtonPress) {
if (!temp_visible_view.second->contains((QWidget *)watched)) {
temporaryVisible(DockType::LEFT, nullptr);
}
}
return QWidget::eventFilter(watched, event);
}
QWidget *ViewPresent::bind() const { return const_cast<ViewPresent *>(this); }
bool ViewPresent::contains(QWidget *) const { return false; }
ViewPresent *ViewPresent::viewPanel() const { return const_cast<ViewPresent *>(this); }
void ViewPresent::objsRelateRebuild() {
setParentRes();
relayout();
update();
}
std::pair<RectCom *, RectCom *> ViewPresent::child() const { return std::make_pair(display_members, nullptr); }
void ViewPresent::replaceComp(RectCom *view, RectCom *old) {
if (display_members != old)
throw new SimpleException<QString>("参数错误", "指定替换的界面不属于此界面");
if (display_members == view)
return;
view->setParentRes(this);
display_members = view;
objsRelateRebuild();
}
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());
relayout();
}
QString ViewPresent::title() const { return ""; }
bool ViewPresent::canReplace() const { return true; }
void ViewPresent::pRelease() { throw new SimpleException<bool>("非法操作", "不允许对ViewPanel调用pRelease"); }
void ViewPresent::pClose() { throw new SimpleException<bool>("非法操作", "不允许对ViewPanel调用pClose"); }
void ViewPresent::registElement(QWidget *) { throw new SimpleException<bool>("非法操作", "不允许对ViewPanel调用registElement"); }
void ViewPresent::setParentRes(ViewRes *) {
if (display_members) {
display_members->setParentRes(this);
}
if (temp_visible_view.second) {
temp_visible_view.second->setParentRes(this);
}
}
ViewRes *ViewPresent::parentRes() const { return nullptr; }
void ViewPresent::paintEvent(QPaintEvent *ev) {
QWidget::paintEvent(ev);
if (display_members) {
display_members->bind()->setVisible(true);
display_members->bind()->update();
}
if (temp_visible_view.second) {
temp_visible_view.second->bind()->setVisible(true);
temp_visible_view.second->bind()->update();
}
for (auto &it : freedom_views) {
if (it == temp_visible_view.second)
return;
it->bind()->setVisible(false);
it->bind()->update();
}
}
void ViewPresent::removeComp(RectCom *child_inst) {
if (!child_inst)
return;
if (temp_visible_view.second == child_inst) {
temp_visible_view = std::make_pair(DockType::LEFT, nullptr);
freedom_views.removeAll(child_inst);
for (auto &lsn : lsn_list)
lsn->freedomRemoved(child_inst);
} else {
if (display_members != child_inst)
throw new SimpleException<QString>("参数非法", "不允许移除隐藏的自由视图");
display_members = nullptr;
}
child_inst->setParentRes(nullptr);
objsRelateRebuild();
}
void ViewPresent::resizeEvent(QResizeEvent *ev) {
QWidget::resizeEvent(ev);
relayout();
}
void ViewPresent::mousePressEvent(QMouseEvent *event) { QWidget::mousePressEvent(event); }
void ViewPresent::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); }
void ViewPresent::mouseMoveEvent(QMouseEvent *event) { QWidget::mouseMoveEvent(event); }
void ViewPresent::relayout() {
if (display_members) {
display_members->relayout(this->rect());
}
if (temp_visible_view.second) {
auto vrect = this->rect();
QRectF cube;
switch (temp_visible_view.first) {
case DockType::LEFT:
cube = QRectF(QPointF(), QSizeF(300, this->height()));
break;
case DockType::RIGHT:
cube = QRectF(vrect.topRight() - QPointF(300, 0), QSizeF(300, this->height()));
break;
case DockType::TOP:
cube = QRectF(QPointF(), QSizeF(this->width(), 300));
break;
case DockType::BOTTOM:
cube = QRectF(vrect.bottomLeft() - QPointF(0, 300), QSizeF(this->width(), 300));
break;
else if(std::get<0>(split_member) == old){
this->split_member = std::make_tuple(view, std::get<1>(split_member), std::get<2>(split_member));
}
temp_visible_view.second->relayout(cube);
old->widget()->setParent(nullptr);
view->widget()->setParent(this);
this->resizeView(this->viewSize());
}
update();
}
RectCom *ViewPresent::create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag, bool replace_flag) {
auto vinst = new BaseView(title, bview, empty_flag, replace_flag);
bview->setParent(vinst);
bview->setMouseTracking(true);
vinst->setTitle(title);
vinst->setIcon(icon);
return vinst;
float SplitPanel::splitterWidth() const
{
return std::get<1>(split_info_value);
}
float SplitPanel::splitterPos() const
{
return std::get<0>(split_info_value);
}
void SplitPanel::setSplitInfo(split_frame::SplitType type, float pos, float width)
{
this->split_member = std::make_tuple(std::get<0>(split_member), std::get<1>(split_member), type);
this->split_info_value = std::make_tuple(pos, width);
}
QList<ViewBase *> SplitPanel::view_list() const
{
QList<ViewBase*> items;
if(std::get<0>(split_member))
items << std::get<0>(split_member);
if(std::get<1>(split_member))
items << std::get<1>(split_member);
return items;
}

View File

@ -1,255 +1,54 @@
#ifndef SPLITPANEL_H
#define SPLITPANEL_H
#ifndef SPLITPANEL
#define SPLITPANEL
#include "splitpanel_global.h"
#include "splitwindow.h"
#include <QWidget>
#include <libConfig.h>
namespace SplitFrame {
class SplitView;
namespace split_panel {
/**
* @brief
* @brief
*/
enum class SplitType { SPLIT_H = 0, SPLIT_V = 1 };
/**
* @brief
*/
enum class DockType { LEFT = 0, RIGHT = 1, TOP = 2, BOTTOM = 3 };
class SPLITVIEW_EXPORT SplitPanel : public QWidget, public split_frame::SplitView {
typedef float split_pos;
typedef float split_width;
/**
* @brief
*/
class ViewRes {
public:
virtual ~ViewRes() = default;
/**
* @brief viewPanel
* @return
*/
virtual SplitView *splitRoot() const = 0;
/**
* @brief
*/
virtual void doRetrieve() = 0;
/**
* @brief
*/
virtual void canRetrieve() const = 0;
/**
* @brief
*/
virtual void doClose() = 0;
/**
* @brief
*/
virtual void canClose() const = 0;
/**
* @brief canReplace
* @return
*/
virtual bool canReplace() const = 0;
};
/**
* @brief
*/
class ViewBase : public QWidget, public ViewRes {
public:
virtual ~ViewBase() = default;
/**
* @brief
* @return
*/
virtual QIcon icon() const = 0;
/**
* @brief
* @return
*/
virtual QString title() const = 0;
/**
* @brief
* @return
*/
virtual QRectF outline() const = 0;
/**
* @brief
* @param outline
*/
virtual void relayout(const QRectF &outline) = 0;
};
/**
* @brief
*/
class SplitView : public ViewBase {
public:
virtual ~SplitView() = default;
/**
* @brief
* @return
*/
virtual std::tuple<ViewBase *, ViewBase *, SplitType> child() const = 0;
/**
* @brief
* @param child
*/
virtual void removeComp(ViewBase *child) = 0;
/**
* @brief
* @param view
* @param old
*/
virtual void replaceComp(ViewBase *view, ViewBase *old) = 0;
/**
* @brief
* @return
*/
virtual float splitterWidth() const = 0;
/**
* @brief
* @return
*/
virtual float splitterPos() const = 0;
/**
* @brief
* @param type
* @param pos
* @param width
*/
virtual void setSplitInfo(SplitType type, float pos, float width) = 0;
};
class FreedomViewsListener {
public:
virtual ~FreedomViewsListener() = default;
/**
* @brief
* @param ins
*/
virtual void freedomAppended(ViewBase *ins) = 0;
/**
* @brief
* @param ins
*/
virtual void freedomRemoved(ViewBase *ins) = 0;
};
/**
* @brief
*/
class SPLITVIEW_EXPORT ViewPresent : public SplitView {
public:
ViewPresent(QWidget *parent = nullptr);
virtual ~ViewPresent();
void addListener(FreedomViewsListener *lsn);
void removeListener(FreedomViewsListener *lsn);
//======================================================
const QList<RectCom *> freedomViews() const;
void resetEngross(RectCom *view = nullptr);
void temporaryVisible(DockType t, RectCom *target = nullptr);
bool isTemporaryView(RectCom *view);
QObject *globalEventFilter() const;
/**
* @brief
* @param state
*/
void setAdjustView(RectCom *one = nullptr);
bool adjustState() const;
RectCom *adjustView() const;
SplitView *createSplit(RectCom *first, RectCom *next);
template <class FnView, bool _blank> RectCom *appendView(FnWrap<FnView, _blank> *view_inst, const QIcon &icon, const QString &title) {
if (view_inst->bindHost() != this)
throw new Config::SimpleException<QString>("非法操作", "不允许混用不同ViewPresent的成员");
auto panel = create_base_panel(view_inst, icon, title, _blank, !_blank);
regist_basepanel(panel);
return panel;
}
// RectCom interface
public:
virtual QWidget *bind() const override;
virtual bool contains(QWidget *) const override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual QString title() const override;
virtual bool canReplace() const override;
SplitPanel(split_frame::ViewBase *first, split_frame::ViewBase *next, ViewRes *parent);
virtual ~SplitPanel();
// ViewRes interface
public:
virtual ViewPresent *viewPanel() const override;
virtual void setParentRes(ViewRes *p = nullptr) override;
virtual split_frame::ResManager *splitManager() const override;
virtual ViewRes *parentRes() const override;
virtual void pRelease() override;
virtual void pClose() override;
virtual void registElement(QWidget *) override;
virtual bool canRetrieve() const override;
virtual bool canClose() const override;
virtual bool canReplace() const override;
// ResManager interface
// ViewBase interface
public:
virtual void objsRelateRebuild() override;
virtual void markFreedom(ViewRes *view, bool add = true) override;
virtual void purge(ViewRes *target) override;
virtual QIcon icon() const override;
virtual QString title() const override;
virtual QWidget* widget() const override;
virtual QSizeF viewSize() const override;
virtual void resizeView(const QSizeF &outline) override;
// SplitRect interface
// SplitView interface
public:
virtual std::pair<RectCom *, RectCom *> child() const override;
virtual void removeComp(RectCom *child) override;
virtual void replaceComp(RectCom *view, RectCom *old) override;
virtual std::tuple<split_frame::ViewBase *, split_frame::ViewBase *, split_frame::SplitType> child() const override;
virtual void replaceComp(ViewBase *view, ViewBase *old) override;
virtual float splitterWidth() const override;
virtual float splitterPos() const override;
virtual SplitType splitType() const override;
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
// QWidget interface
protected:
virtual void paintEvent(QPaintEvent *ev) override;
virtual void resizeEvent(QResizeEvent *ev) override;
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void setSplitInfo(split_frame::SplitType type, float pos, float width) override;
private:
QList<FreedomViewsListener *> lsn_list;
AttachPanel *const accept_panel;
ViewRes *parent_inst;
std::tuple<split_frame::ViewBase*, split_frame::ViewBase*, split_frame::SplitType> split_member;
// type, pos, width
std::tuple<split_pos, split_width> split_info_value;
// 拖拽属性===================================
RectCom *adjust_view_temp; // 拖拽中转
// 方向splitter位置splitter宽度
std::tuple<SplitType, float, float> split_info_store = std::make_tuple(SplitType::SPLIT_H, 200, 8);
// 视图展现堆栈===============================
QList<RectCom *> all_func_views;
QList<RectCom *> freedom_views;
RectCom *display_members = nullptr;
std::pair<DockType, RectCom *> temp_visible_view = std::make_pair(DockType::LEFT, nullptr);
virtual void relayout();
RectCom *create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag = false, bool replace_flag = true);
void regist_basepanel(RectCom *it);
QList<split_frame::ViewBase*> view_list() const;
};
} // namespace SplitFrame
#endif // SPLITPANEL_H
#endif // SPLITPANEL

View File

@ -1,12 +0,0 @@
#ifndef SPLITPANEL_GLOBAL_H
#define SPLITPANEL_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(SPLITVIEW_LIBRARY)
# define SPLITVIEW_EXPORT Q_DECL_EXPORT
#else
# define SPLITVIEW_EXPORT Q_DECL_IMPORT
#endif
#endif // SPLITPANEL_GLOBAL_H

View File

@ -1,212 +0,0 @@
#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<SplitView *>(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;
}

View File

@ -1,67 +0,0 @@
#ifndef SPLITVIEW_H
#define SPLITVIEW_H
#include "splitpanel.h"
namespace SplitFrame {
/**
* @brief
*/
class SPLITVIEW_EXPORT SplitView : private QWidget, public SplitView {
public:
SplitView(RectCom *first, RectCom *next, QWidget *parent = nullptr);
virtual ~SplitView();
// ViewRes interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual void setParentRes(ViewRes *inst) override;
virtual ViewRes *parentRes() const override;
virtual void registElement(QWidget *child) override;
virtual void pRelease() override;
virtual void pClose() override;
// RectCom interface
public:
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void paintEvent(QPaintEvent *ev) override;
virtual bool contains(QWidget *) const override;
virtual QString title() const override;
virtual bool canReplace() const override;
// SplitRect interface
public:
virtual std::pair<RectCom *, RectCom *> child() const override;
virtual void removeComp(RectCom *child) override;
virtual void replaceComp(RectCom *view, RectCom *old) override;
virtual float splitterWidth() const override;
virtual float splitterPos() const override;
virtual SplitType splitType() const override;
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout) override;
// QWidget interface
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
private:
ViewRes *parent_inst;
QList<RectCom *> child_store;
// type, pos, width
std::tuple<SplitType, float, float> split_info_value;
bool drags_state = false;
virtual void relayout();
std::pair<QRectF, QRectF> view_rects();
QRectF handle_rect() const;
};
} // namespace SplitFrame
#endif // SPLITVIEW_H

View File

@ -0,0 +1,188 @@
#ifndef SPLITVIEW_INTERFACE_H
#define SPLITVIEW_INTERFACE_H
#include <QtCore/qglobal.h>
#if defined(SPLITVIEW_LIBRARY)
# define SPLITVIEW_EXPORT Q_DECL_EXPORT
#else
# define SPLITVIEW_EXPORT Q_DECL_IMPORT
#endif
#include <QWidget>
namespace split_frame {
class SplitView;
class ResManager;
/**
* @brief
*/
enum class SplitType { SPLIT_H = 0, SPLIT_V = 1 };
/**
* @brief
*/
enum class DockType { LEFT = 0, RIGHT = 1, TOP = 2, BOTTOM = 3 };
/**
* @brief
*/
class ViewRes {
public:
virtual ~ViewRes() = default;
/**
* @brief
* @return
*/
virtual ResManager *splitManager() const = 0;
/**
* @brief
* @return
*/
virtual ViewRes *parentRes() const = 0;
/**
* @brief
* @return
*/
virtual QWidget *widget() const = 0;
/**
* @brief
*/
virtual bool canRetrieve() const = 0;
/**
* @brief
*/
virtual bool canClose() const = 0;
/**
* @brief canReplace
* @return
*/
virtual bool canReplace() const = 0;
};
/**
* @brief
*/
class ViewBase : public ViewRes {
public:
virtual ~ViewBase() = default;
/**
* @brief
* @return
*/
virtual QIcon icon() const = 0;
/**
* @brief
* @return
*/
virtual QString title() const = 0;
/**
* @brief
* @return
*/
virtual QSizeF viewSize() const = 0;
/**
* @brief
* @param outline
*/
virtual void resizeView(const QSizeF &outline) = 0;
};
/**
* @brief
*/
class SplitView : public ViewBase {
public:
virtual ~SplitView() = default;
/**
* @brief
* @return
*/
virtual std::tuple<ViewBase *, ViewBase *, SplitType> child() const = 0;
/**
* @brief
* @param view
* @param old
*/
virtual void replaceComp(ViewBase *view, ViewBase *old) = 0;
/**
* @brief
* @return
*/
virtual float splitterWidth() const = 0;
/**
* @brief
* @return
*/
virtual float splitterPos() const = 0;
/**
* @brief
* @param type
* @param pos
* @param width
*/
virtual void setSplitInfo(SplitType type, float pos, float width) = 0;
};
/**
* @brief
*/
class FreedomViewsListener {
public:
virtual ~FreedomViewsListener() = default;
/**
* @brief
* @param ins
*/
virtual void freedomAppended(ViewBase *ins) = 0;
/**
* @brief
* @param ins
*/
virtual void freedomRemoved(ViewBase *ins) = 0;
};
/**
* @brief
*/
class ResManager {
public:
virtual ~ResManager() = default;
virtual void addListener(FreedomViewsListener *lsn) = 0;
virtual void removeListener(FreedomViewsListener *lsn) = 0;
virtual void setAdjustView(ViewBase *inst) = 0;
virtual ViewBase* adjustView() const = 0;
/**
* @brief
* @param inst
*/
virtual void doRetrieve(ViewRes *inst);
/**
* @brief
*/
virtual void doClose(ViewRes *inst) = 0;
/**
* @brief
* @param view
* @param old
*/
virtual void doReplace(ViewRes *view, ViewRes *old) = 0;
};
} // namespace SplitFrame
#endif // SPLITVIEW_INTERFACE_H

View File

@ -0,0 +1,21 @@
#include "splitwindow.h"
#include "baseview.h"
#include "splitpanel.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 split_panel;
using namespace split_frame;
SplitWindow::SplitWindow(QWidget *parent) : QMainWindow(parent) {}
SplitWindow::~SplitWindow() {}

View File

@ -0,0 +1,37 @@
#ifndef SPLITWINDOW_H
#define SPLITWINDOW_H
#include "splitview_interface.h"
#include <QMainWindow>
#include <QWidget>
#include <libConfig.h>
namespace split_panel {
/**
* @brief
*/
class SPLITVIEW_EXPORT SplitWindow : public QMainWindow, public split_frame::SplitView {
typedef float pos;
typedef float width;
public:
SplitWindow(QWidget *parent = nullptr);
virtual ~SplitWindow();
//======================================================
/**
* @brief
* @param t
* @param target
*/
void tempShow(split_frame::DockType t, split_frame::ViewBase *target);
};
} // namespace split_panel
#endif // SPLITWINDOW_H

View File

@ -11,8 +11,8 @@
#include <QStyle>
#include <QToolBar>
#include <baseview.h>
#include <splitwindow.h>
#include <splitpanel.h>
#include <splitview.h>
using namespace SplitFrame;

View File

@ -3,7 +3,7 @@
#include <QPainter>
using namespace SplitFrame;
XWidget::XWidget(ViewPresent *host, Qt::GlobalColor c, QWidget *parent) : FnWrap<XWidget, false>(host), c_store(c) {}
XWidget::XWidget(SplitPanel *host, Qt::GlobalColor c, QWidget *parent) : FnWrap<XWidget, false>(host), c_store(c) {}
void XWidget::paintEvent(QPaintEvent *ev) {
QPainter p(this);
@ -12,7 +12,7 @@ void XWidget::paintEvent(QPaintEvent *ev) {
void XWidget::closeProcess() {}
YWidget::YWidget(ViewPresent *host, QWidget *parent) : FnWrap<XWidget, true>(host) {}
YWidget::YWidget(SplitPanel *host, QWidget *parent) : FnWrap<XWidget, true>(host) {}
void YWidget::paintEvent(QPaintEvent *ev) {
QPainter p(this);

View File

@ -3,11 +3,11 @@
#include <QString>
#include <QWidget>
#include <splitpanel.h>
#include <splitwindow.h>
class XWidget : public SplitFrame::FnWrap<XWidget, false> {
public:
XWidget(SplitFrame::ViewPresent *host, Qt::GlobalColor c, QWidget *parent = nullptr);
XWidget(SplitFrame::SplitPanel *host, Qt::GlobalColor c, QWidget *parent = nullptr);
virtual void paintEvent(QPaintEvent *ev) override;
// FnWrap interface
@ -20,7 +20,7 @@ private:
class YWidget : public SplitFrame::FnWrap<XWidget, true> {
public:
YWidget(SplitFrame::ViewPresent *host, QWidget *parent = nullptr);
YWidget(SplitFrame::SplitPanel *host, QWidget *parent = nullptr);
virtual void paintEvent(QPaintEvent *ev) override;
// FnWrap interface
public: