完全重构
This commit is contained in:
parent
7dbba0a46a
commit
a97829ddd2
|
@ -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>
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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 =============================================
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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() {}
|
|
@ -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
|
|
@ -11,8 +11,8 @@
|
|||
#include <QStyle>
|
||||
#include <QToolBar>
|
||||
#include <baseview.h>
|
||||
#include <splitwindow.h>
|
||||
#include <splitpanel.h>
|
||||
#include <splitview.h>
|
||||
|
||||
using namespace SplitFrame;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue