QtNovelUI/SplitView/splitview.h

302 lines
9.9 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 SPLITVIEW_H
#define SPLITVIEW_H
#include "SplitView_global.h"
#include <QHash>
#include <QIcon>
#include <QLabel>
#include <QWidget>
namespace SplitFrame {
class SplitRect;
class ViewPresent;
class BaseView;
/**
* @brief 承接堆放操作及设定摆放位置
*/
class SPLITVIEW_EXPORT AttachPanel : public QWidget {
enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE };
public:
AttachPanel(ViewPresent *host);
void bindAttachment(BaseView *widget);
BaseView *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;
BaseView *current_target;
ActiveArea active_comp;
std::tuple<QRectF, QRectF, QRectF, QRectF, QRectF> view_rects() const;
};
enum class SplitType { SPLIT_H = 0, SPLIT_V = 1 };
class RectCom {
public:
virtual ~RectCom() = default;
virtual ViewPresent *viewPanel() const = 0;
virtual QWidget *bind() const = 0;
virtual bool contains(QWidget *ptr) const = 0;
virtual QRectF outline() const = 0;
virtual void relayout(const QRectF &outline) = 0;
virtual void setParentRect(SplitRect *inst) = 0;
virtual SplitRect *parentRect() const = 0;
virtual void paintEvent(QPaintEvent *ev) = 0;
};
class ResManager {
public:
virtual ~ResManager() = default;
virtual void objsRelateRebuild() = 0;
virtual void markFreedom(BaseView *view) = 0;
virtual void markUnused(SplitRect *item) = 0;
virtual void unusedResRelease() = 0;
};
/**
* @brief 分裂视图规划和约束组件
*/
class SplitRect : public RectCom {
public:
virtual ~SplitRect() = default;
virtual std::pair<RectCom *, RectCom *> child() const = 0;
virtual void removeComp(BaseView *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;
};
/**
* @brief 分割视图
*/
class SPLITVIEW_EXPORT SplitView : public QWidget, public SplitRect {
public:
SplitView(RectCom *first, RectCom *next, QWidget *parent = nullptr);
virtual ~SplitView();
// RectCom interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void setParentRect(SplitRect *inst) override;
virtual SplitRect *parentRect() const override;
virtual void paintEvent(QPaintEvent *ev) override;
virtual bool contains(QWidget *ptr) const override;
// SplitRect interface
public:
virtual std::pair<RectCom *, RectCom *> child() const override;
virtual void removeComp(BaseView *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 mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
virtual void resizeEvent(QResizeEvent *event) override;
private:
SplitRect *parent_inst;
QList<RectCom *> child_store;
// type, pos, width
std::tuple<SplitType, float, float> split_info_value;
bool press_flags = false, drags_flag = false;
virtual void relayout();
std::pair<QRectF, QRectF> viewRects();
QRectF handleRect() const;
};
class DragHeader : public QFrame {
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;
std::tuple<bool, QPointF> press_flag = std::make_tuple(false, QPointF());
// QWidget interface
protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
};
/**
* @brief 基础内容视图组件
*/
class SPLITVIEW_EXPORT BaseView : public QWidget, public RectCom {
friend class ViewPresent;
public:
BaseView(const QString &title, QWidget *view, bool empty = false, QWidget *parent = nullptr);
virtual void setTitle(const QString &title);
virtual QString title() const;
virtual void setIcon(const QIcon &icon);
virtual QIcon viewIcon() const;
virtual void closeView();
virtual bool contains(QWidget *inst) const override;
// RectCom interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void setParentRect(SplitRect *inst) override;
virtual SplitRect *parentRect() const override;
virtual void paintEvent(QPaintEvent *ev) override;
private:
DragHeader *title_header;
SplitRect *parent_store;
QList<QWidget *> comps_list;
protected:
virtual void installPerceptionHandle(ViewPresent *obj);
virtual void registComp(QWidget *child);
};
class FreedomViewsListener {
public:
virtual ~FreedomViewsListener() = default;
/**
* @brief 闲置视图增加
* @param ins
*/
virtual void freedomAppended(RectCom *ins) = 0;
/**
* @brief 闲置视图减少
* @param ins
*/
virtual void freedomRemoved(RectCom *ins) = 0;
};
/**
* @brief 分裂视图呈现组件
*/
class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect, public ResManager {
public:
ViewPresent(QWidget *parent = nullptr);
virtual ~ViewPresent();
void addListener(FreedomViewsListener *lsn);
void removeListener(FreedomViewsListener *lsn);
//======================================================
void registViewComp(BaseView *it);
//======================================================
virtual void markFreedom(BaseView *view) override;
void setTempVisible(BaseView *target = nullptr);
/**
* @brief 切换视图调整状态
* @param state 状态开关
*/
void setViewAdjust(BaseView *one = nullptr);
bool adjustState() const;
BaseView *adjustView() const;
void resetViews(RectCom *center, RectCom *extend = nullptr);
// RectCom interface
public:
virtual ViewPresent *viewPanel() const override;
virtual QWidget *bind() const override;
virtual bool contains(QWidget *ptr) const override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void setParentRect(SplitRect *) override;
virtual SplitRect *parentRect() const override;
// ResManager interface
public:
virtual void objsRelateRebuild() override;
virtual void markUnused(SplitRect *item) override;
virtual void unusedResRelease() override;
// SplitRect interface
public:
virtual std::pair<RectCom *, RectCom *> child() const override;
virtual void removeComp(BaseView *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:
AttachPanel *const accept_panel;
QList<SplitRect *> unused_splits;
BaseView *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 *> view_anchors;
QList<BaseView *> all_sep_views;
QList<FreedomViewsListener *> lsn_list;
QList<RectCom *> freedom_views;
RectCom *temp_visible_view = nullptr;
virtual void relayout();
std::pair<QRectF, QRectF> viewRects();
QRectF handleRect() const;
};
} // namespace SplitFrame
#endif // SPLITVIEW_H