#ifndef SPLITVIEW_H #define SPLITVIEW_H #include "SplitView_global.h" #include #include #include #include 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 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 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 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 child_store; // type, pos, width std::tuple split_info_value; bool press_flags = false, drags_flag = false; virtual void relayout(); std::pair 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 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 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 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 unused_splits; BaseView *adjust_view_temp; // 拖拽中转 bool press_flags = false; // 空间调整标志 // 方向,splitter位置,splitter宽度 std::tuple split_info_store = std::make_tuple(SplitType::SPLIT_H, 200, 8); QList view_anchors; QList all_sep_views; QList lsn_list; QList freedom_views; RectCom *temp_visible_view = nullptr; virtual void relayout(); std::pair viewRects(); QRectF handleRect() const; }; } // namespace SplitFrame #endif // SPLITVIEW_H