QtNovelUI/SplitView/splitview.h

248 lines
8.4 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 DockPanel : public QWidget {
enum class ActiveArea { LEFT, RIGHT, TOP, BOTTOM, CENTER, NONE };
public:
DockPanel(ViewPresent *host);
void bind(BaseView *widget);
BaseView *target() const;
virtual void paintEvent(QPaintEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
private:
ViewPresent *const size_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 };
/**
* @brief 分裂视图规划和约束组件
*/
class SplitRect {
public:
virtual ~SplitRect() = default;
virtual QWidget *bind() const = 0;
virtual ViewPresent *viewPanel() const = 0;
virtual SplitRect *parentRect() const = 0;
virtual void setParentRect(SplitRect *pinst) = 0;
virtual std::pair<SplitRect *, SplitRect *> child() const = 0;
virtual void replace(SplitRect *view, SplitRect *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;
virtual QRectF outline() const = 0;
virtual void relayout(const QRectF &outline) = 0;
virtual void retrieveComp(SplitRect *child) = 0;
virtual void paintEvent(QPaintEvent *ev) = 0;
};
class SPLITVIEW_EXPORT SplitView : public QWidget, public SplitRect {
public:
SplitView(SplitRect *first, SplitRect *next, QWidget *parent = nullptr);
// SplitRect interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override;
virtual std::pair<SplitRect *, SplitRect *> child() const 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;
virtual void replace(SplitRect *view, SplitRect *old) override;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void retrieveComp(SplitRect *child_inst) 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;
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
private:
SplitRect *parent_inst;
QList<SplitRect *> 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 SplitRect {
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 *ptr) const;
// SplitRect interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override;
virtual std::pair<SplitRect *, SplitRect *> child() const override;
virtual void replace(SplitRect *view, SplitRect *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;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void paintEvent(QPaintEvent *ev) override;
virtual void retrieveComp(SplitRect *child_inst) override;
private:
DragHeader *title_header;
SplitRect *parent_store;
QList<QWidget *> comps_list;
protected:
virtual void installPerceptionHandle(ViewPresent *obj);
virtual void registComp(QWidget *child);
};
/**
* @brief 分裂视图呈现组件
*/
class SPLITVIEW_EXPORT ViewPresent : public QWidget, public SplitRect {
public:
ViewPresent(SplitRect *initial_view, QWidget *parent = nullptr);
void registViewComp(BaseView *it);
/**
* @brief 切换视图调整状态
* @param state 状态开关
*/
void setViewAdjust(bool state, BaseView *one = nullptr);
bool adjustState() const;
BaseView *adjustView() const;
void append(SplitRect *inst, uint index);
// QObject interface
public:
virtual bool eventFilter(QObject *watched, QEvent *event) override;
// SplitRect interface
public:
virtual QWidget *bind() const override;
virtual ViewPresent *viewPanel() const override;
virtual SplitRect *parentRect() const override;
virtual void setParentRect(SplitRect *pinst) override;
virtual std::pair<SplitRect *, SplitRect *> child() const override;
virtual void replace(SplitRect *view, SplitRect *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;
virtual QRectF outline() const override;
virtual void relayout(const QRectF &outline) override;
virtual void retrieveComp(SplitRect *child_inst) 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:
DockPanel *const accept_panel;
BaseView *adjust_view_store;
bool press_flags = false;
bool adjust_state = false;
QList<SplitRect *> view_anchors;
// 方向splitter位置splitter宽度extend索引
std::tuple<SplitType, float, float, uint> split_info_store;
QList<BaseView *> all_sep_views;
virtual void relayout();
std::pair<QRectF, QRectF> viewRects();
QRectF handleRect() const;
};
} // namespace SplitFrame
#endif // SPLITVIEW_H