QtNovelUI/libSplitView/splitpanel.h

256 lines
7.5 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 SplitView;
/**
* @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 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;
// 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, bool add = true) 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; // 拖拽中转
// 方向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);
};
} // namespace SplitFrame
#endif // SPLITPANEL_H