QtNovelUI/libSplitView/splitpanel.h

235 lines
7.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef SPLITPANEL_H
#define SPLITPANEL_H
#include "splitpanel_global.h"
#include <QWidget>
#include <libConfig.h>
namespace SplitFrame {
class ViewPresent;
class AttachPanel;
/**
* @brief 面板分割方向
*/
enum class SplitType { SPLIT_H = 0, SPLIT_V = 1 };
/**
* @brief 临时视图贴附方位
*/
enum class DockType { LEFT = 0, RIGHT, TOP, BOTTOM };
/**
* @brief 视图资源基类
*/
class ViewRes {
public:
virtual ~ViewRes() = default;
virtual void registElement(QWidget *child) = 0;
virtual QWidget *bind() const = 0;
virtual QString title() const = 0;
virtual ViewPresent *viewPanel() const = 0;
/**
* @brief 关闭视图显示,转换视图为自由(闲置)状态
*/
virtual void pRelease() = 0;
/**
* @brief 回收视图,清除内存实例
*/
virtual void pClose() = 0;
virtual void setParentRes(ViewRes *inst) = 0;
virtual ViewRes *parentRes() const = 0;
};
/**
* @brief 资源管理接口
*/
class ResManager {
public:
virtual ~ResManager() = default;
virtual ViewPresent *viewPanel() const = 0;
virtual void objsRelateRebuild() = 0;
virtual void markFreedom(ViewRes *view) = 0;
virtual void purge(ViewRes *target) = 0;
};
/**
* @brief 视图展示接口
*/
class RectCom : public ViewRes {
public:
virtual ~RectCom() = default;
virtual bool contains(QWidget *ptr) const = 0;
virtual QRectF outline() const = 0;
virtual void relayout(const QRectF &outline) = 0;
virtual void paintEvent(QPaintEvent *ev) = 0;
};
/**
* @brief 功能视图基板
*/
template <class FnVType, bool _blank> class FnWrap : public QWidget {
private:
static bool type_blank_blank;
ViewPresent *const host_store;
public:
explicit FnWrap(ViewPresent *bind, QWidget *parent = nullptr) : QWidget(parent), host_store(bind) {}
virtual ~FnWrap() { this->closeProcess(); }
ViewPresent *bindHost() const { return host_store; }
virtual void closeProcess(){};
};
/**
* @brief 分裂视图规划和约束组件
*/
class SplitRect : public RectCom {
public:
virtual ~SplitRect() = default;
virtual std::pair<RectCom *, RectCom *> child() const = 0;
virtual void removeComp(RectCom *child) = 0;
virtual void replaceComp(RectCom *view, RectCom *old) = 0;
virtual float splitterWidth() const = 0;
virtual float splitterPos() const = 0;
virtual SplitType splitType() const = 0;
virtual void setSplitInfo(SplitType type, float pos, float width, bool relayout = true) = 0;
};
class FreedomViewsListener {
public:
virtual ~FreedomViewsListener() = default;
/**
* @brief 闲置视图增加
* @param ins
*/
virtual void freedomAppended(RectCom *ins, const QIcon &icon, const QString &title) = 0;
/**
* @brief 闲置视图减少
* @param ins
*/
virtual void freedomRemoved(RectCom *ins) = 0;
};
/**
* @brief 分裂视图呈现组件
*/
class SPLITVIEW_EXPORT ViewPresent : private QWidget, public SplitRect, public ResManager {
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;
SplitRect *createSplit(RectCom *first, RectCom *next, SplitType sp, float pos = 20, float split_width = 8);
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);
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;
// ViewRes interface
public:
virtual ViewPresent *viewPanel() const override;
virtual void setParentRes(ViewRes *p = nullptr) override;
virtual ViewRes *parentRes() const override;
virtual void pRelease() override;
virtual void pClose() override;
virtual void registElement(QWidget *) override;
// ResManager interface
public:
virtual void objsRelateRebuild() override;
virtual void markFreedom(ViewRes *view) override;
virtual void purge(ViewRes *target) 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;
// 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;
private:
QList<FreedomViewsListener *> lsn_list;
AttachPanel *const accept_panel;
// 拖拽属性===================================
RectCom *adjust_view_temp; // 拖拽中转
bool press_flags = false; // 空间调整标志
// 方向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);
std::pair<QRectF, QRectF> view_rects();
QRectF handle_rect() const;
virtual void relayout();
RectCom *create_base_panel(QWidget *bview, const QIcon &icon, const QString &title, bool empty_flag = false);
void regist_basepanel(RectCom *it);
};
} // namespace SplitFrame
#endif // SPLITPANEL_H