instAdmin/Cpp/GisDes/SaRibbon/SARibbon.h
2024-10-29 22:24:50 +08:00

3751 lines
119 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 SA_RIBBON_H
#define SA_RIBBON_H
// 定义此宏将SA_RIBBON_EXPORT定义为空
#ifndef SA_RIBBON_BAR_NO_EXPORT
#define SA_RIBBON_BAR_NO_EXPORT
#endif
// 定义此宏将SA_COLOR_WIDGETS_API定义为空
#ifndef SA_COLOR_WIDGETS_NO_DLL
#define SA_COLOR_WIDGETS_NO_DLL
#endif
/*** Start of inlined file: SARibbonAmalgamTemplatePublicHeaders.h ***/
// Global
/*** Start of inlined file: SAColorWidgetsGlobal.h ***/
#ifndef SACOLORWIDGETSGLOBAL_H
#define SACOLORWIDGETSGLOBAL_H
#include <QScopedPointer>
/**
* @def color-widgets的数字版本 MAJ.MIN.PAT
*/
#ifndef SA_COLOR_WIDGETS_VERSION_MAJ
#define SA_COLOR_WIDGETS_VERSION_MAJ 0
#endif
/**
* @def color-widgets的数字版本 MAJ.MIN.PAT
*/
#ifndef SA_COLOR_WIDGETS_VERSION_MIN
#define SA_COLOR_WIDGETS_VERSION_MIN 1
#endif
/**
* @def color-widgets的数字版本 MAJ.MIN.PAT
*/
#ifndef SA_COLOR_WIDGETS_VERSION_PAT
#define SA_COLOR_WIDGETS_VERSION_PAT 0
#endif
/**
* @def 模仿Q_DECLARE_PRIVATE但不用前置声明而是作为一个内部类
*/
#ifndef SA_COLOR_WIDGETS_DECLARE_PRIVATE
#define SA_COLOR_WIDGETS_DECLARE_PRIVATE(classname) \
class PrivateData; \
friend class classname::PrivateData; \
QScopedPointer< PrivateData > d_ptr;
#endif
/**
* @def 模仿Q_DECLARE_PUBLIC
*/
#ifndef SA_COLOR_WIDGETS_DECLARE_PUBLIC
#define SA_COLOR_WIDGETS_DECLARE_PUBLIC(classname) \
friend class classname; \
classname* q_ptr { nullptr };
#endif
#ifndef SA_COLOR_WIDGETS_NO_DLL
#if defined(SA_COLOR_WIDGETS_MAKE_LIB) // 定义此宏将构建library
#ifndef SA_COLOR_WIDGETS_API
#define SA_COLOR_WIDGETS_API Q_DECL_EXPORT
#endif
#else
#ifndef SA_COLOR_WIDGETS_API
#define SA_COLOR_WIDGETS_API Q_DECL_IMPORT
#endif
#endif
#else
#ifndef SA_COLOR_WIDGETS_API
#define SA_COLOR_WIDGETS_API
#endif
#endif
#endif // SACOLORWIDGETSGLOBAL_H
/*** End of inlined file: SAColorWidgetsGlobal.h ***/
/*** Start of inlined file: SARibbonBarVersionInfo.h ***/
#ifndef SARIBBONVERSIONINFO_H
#define SARIBBONVERSIONINFO_H
/**
* @file 此文档由cmake根据SARibbonBarVersionInfo.h.in自动生成任何在此文件上的改动都将覆写
*/
/**
* @def ribbon的数字版本 {MAJ}.MIN.PAT
*/
#ifndef SA_RIBBON_BAR_VERSION_MAJ
#define SA_RIBBON_BAR_VERSION_MAJ 2
#endif
/**
* @def ribbon的数字版本 MAJ.{MIN}.PAT
*/
#ifndef SA_RIBBON_BAR_VERSION_MIN
#define SA_RIBBON_BAR_VERSION_MIN 2
#endif
/**
* @def ribbon的数字版本 MAJ.MIN.{PAT}
*/
#ifndef SA_RIBBON_BAR_VERSION_PAT
#define SA_RIBBON_BAR_VERSION_PAT 5
#endif
/**
* @def 版本号(字符串)
*/
#ifndef SARIBBON_VERSION
#define SARIBBON_VERSION "2.2.5"
#endif
#endif // SARIBBONVERSIONINFO_H
/*** End of inlined file: SARibbonBarVersionInfo.h ***/
/*** Start of inlined file: SARibbonGlobal.h ***/
#ifndef SARIBBONGLOBAL_H
#define SARIBBONGLOBAL_H
#include <memory>
#include <QtGlobal>
#include <QObject>
class QWidget;
#ifndef SA_RIBBON_BAR_NO_EXPORT
#if defined(SA_RIBBON_BAR_MAKE_LIB) // 定义此宏将构建library
#define SA_RIBBON_EXPORT Q_DECL_EXPORT
#else
#define SA_RIBBON_EXPORT Q_DECL_IMPORT
#endif
#endif
#ifndef SA_RIBBON_EXPORT
#define SA_RIBBON_EXPORT
#endif
/**
* @def 模仿Q_DECLARE_PRIVATE但不用前置声明而是作为一个内部类
*/
#ifndef SA_RIBBON_DECLARE_PRIVATE
#define SA_RIBBON_DECLARE_PRIVATE(classname) \
class PrivateData; \
friend class classname::PrivateData; \
std::unique_ptr< PrivateData > d_ptr;
#endif
/**
* @def 模仿Q_DECLARE_PUBLIC
*/
#ifndef SA_RIBBON_DECLARE_PUBLIC
#define SA_RIBBON_DECLARE_PUBLIC(classname) \
friend class classname; \
classname* q_ptr { nullptr }; \
PrivateData(const PrivateData&) = delete; \
PrivateData& operator=(const PrivateData&) = delete;
#endif
/**
* @brief 定义Ribbon的对其方式目前支持左对齐和居中对其
*/
enum class SARibbonAlignment
{
AlignLeft, ///< 左对齐tab栏左对齐同时category也是左对齐
AlignCenter ///< 居中对其tab栏居中对齐同时category也是居中对齐
};
/**
* @brief ribbon主题
*
* 注意由于有些qss的尺寸在C++代码中无法获取到因此针对用户自定义的qss主题有些尺寸是需要手动设置进去的
*
* 例如ribbon tab的margin信息在QTabBar是无法获取到而这个影响了SARibbonContextCategory的绘制
* 因此在设置qss后需要针对margin信息重新设置进SARibbonTabBar中
*/
enum class SARibbonTheme
{
RibbonThemeOffice2013, ///< office2013主题
RibbonThemeOffice2016Blue, ///< office2016-蓝色主题
RibbonThemeOffice2021Blue, ///< office2021-蓝色主题
RibbonThemeWindows7, ///< win7主题
RibbonThemeDark, ///< 暗色主题
RibbonThemeDark2
};
/**
* @def 属性,用于标记是否可以进行自定义,用于动态设置到@ref SARibbonCategory 和@ref SARibbonPannel
* 值为bool在为true时可以通过@ref SARibbonCustomizeWidget 改变这个SARibbonCategory和SARibbonPannel的布局
* 默认不会有此属性仅在有此属性且为true时才会在SARibbonCustomizeWidget中能显示为可设置
*/
#ifndef SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE
#define SA_RIBBON_BAR_PROP_CAN_CUSTOMIZE "_sa_isCanCustomize"
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
#ifndef SA_FONTMETRICS_WIDTH
#define SA_FONTMETRICS_WIDTH(fm, str) fm.horizontalAdvance(str)
#endif
#else
#ifndef SA_FONTMETRICS_WIDTH
#define SA_FONTMETRICS_WIDTH(fm, str) fm.width(str)
#endif
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#ifndef SA_MOUSEEVENT_GLOBALPOS_POINT
#define SA_MOUSEEVENT_GLOBALPOS_POINT(MouseEventPtr) MouseEventPtr->globalPosition().toPoint()
#endif
#else
#ifndef SA_MOUSEEVENT_GLOBALPOS_POINT
#define SA_MOUSEEVENT_GLOBALPOS_POINT(MouseEventPtr) MouseEventPtr->globalPos()
#endif
#endif
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
#ifndef SA_HOVEREVENT_POS_POINT
#define SA_HOVEREVENT_POS_POINT(HoverEventPtr) HoverEventPtr->position().toPoint()
#endif
#else
#ifndef SA_HOVEREVENT_POS_POINT
#define SA_HOVEREVENT_POS_POINT(HoverEventPtr) HoverEventPtr->pos()
#endif
#endif
/**
@def 定义此宏,将打印和尺寸刷新相关的信息
仅用于调试
*/
#ifndef SA_DEBUG_PRINT_SIZE_HINT
#define SA_DEBUG_PRINT_SIZE_HINT 0
#endif
/**
@def 定义此宏,将打印事件
仅用于调试
*/
#ifndef SA_DEBUG_PRINT_EVENT
#define SA_DEBUG_PRINT_EVENT 0
#endif
/**
@def 定义此宏qDebug将支持SARibbonBar的属性打印
仅用于调试
*/
#ifndef SA_DEBUG_PRINT_SARIBBONBAR
#define SA_DEBUG_PRINT_SARIBBONBAR 0
#endif
/**
* @brief 全局的设置ribbon theme函数
*
* 之所以提供此函数是因为在某些情况下SARibbonBar不用在SARibbonMainWindow情况下的时候也需要设置主题
* 但主题设置是在SARibbonMainWindow下的为了能在非SARibbonMainWindow下也能设置主题这里提供@sa sa_set_ribbon_theme函数
* 可以这样使用:
* @code
* @endcode
*
* @param w
* @param theme
*/
void SA_RIBBON_EXPORT sa_set_ribbon_theme(QWidget* w, SARibbonTheme theme);
#endif // SARIBBONGLOBAL_H
/*** End of inlined file: SARibbonGlobal.h ***/
// color widget
/*** Start of inlined file: SAColorMenu.h ***/
#ifndef SACOLORMENU_H
#define SACOLORMENU_H
#include <QMenu>
class QWidgetAction;
class SAColorPaletteGridWidget;
class SAColorGridWidget;
class SAColorToolButton;
/**
* @brief 标准颜色菜单
*/
class SA_COLOR_WIDGETS_API SAColorMenu : public QMenu
{
Q_OBJECT
SA_COLOR_WIDGETS_DECLARE_PRIVATE(SAColorMenu)
public:
explicit SAColorMenu(QWidget* parent = nullptr);
explicit SAColorMenu(const QString& title, QWidget* parent = nullptr);
~SAColorMenu();
// 快速绑定colorbtn
void bindToColorToolButton(SAColorToolButton* btn);
// ThemeColorsPalette对应的action
QWidgetAction* themeColorsPaletteAction() const;
// CustomColorsWidget对应的action
QWidgetAction* getCustomColorsWidgetAction() const;
// 自定义颜色action
QAction* customColorAction() const;
// 获取ThemeColorsPalette
SAColorPaletteGridWidget* colorPaletteGridWidget() const;
// 获取自定义颜色grid
SAColorGridWidget* customColorsWidget() const;
// 构建无颜色action默认无颜色action是没有的
void enableNoneColorAction(bool on = true);
// 获取None Color Action,注意enableNoneColorAction(true),之后才不是nullptr
QAction* noneColorAction() const;
public Q_SLOTS:
// 这是一个辅助槽函数为了让用户自定义的其他action也能关联menu可以调用此槽函数实现selectedColor信号以及menu的隐藏
void emitSelectedColor(const QColor& c);
Q_SIGNALS:
/**
* @brief 选择了颜色触发的信号
* @param c
*/
void selectedColor(const QColor& c);
private Q_SLOTS:
void onCustomColorActionTriggered(bool on);
void onNoneColorActionTriggered(bool on);
private:
void init(const QList< QColor >& themeCls);
};
#endif // SACOLORMENU_H
/*** End of inlined file: SAColorMenu.h ***/
/*** Start of inlined file: SAColorGridWidget.h ***/
#ifndef SACOLORGRIDWIDGET_H
#define SACOLORGRIDWIDGET_H
#include <QWidget>
#include <functional>
class QAbstractButton;
class SAColorToolButton;
/**
* @brief 一个grid的Color布局
*
* 一个形如下面的颜色grid
*
* □□□□□□□□□
*
* □□□□□□□□□
*
* □□□□□□□□□
*/
class SA_COLOR_WIDGETS_API SAColorGridWidget : public QWidget
{
Q_OBJECT
SA_COLOR_WIDGETS_DECLARE_PRIVATE(SAColorGridWidget)
Q_PROPERTY(int spacing READ spacing WRITE setSpacing)
public:
using FunColorBtn = std::function< void(SAColorToolButton*) >;
public:
SAColorGridWidget(QWidget* par = nullptr);
~SAColorGridWidget();
// 设置列数,行数量会根据列数量来匹配,如果设置-1或者0说明不限定列数量这样会只有一行
void setColumnCount(int c);
int columnCount() const;
// 设置当前的颜色列表
void setColorList(const QList< QColor >& cls);
QList< QColor > getColorList() const;
// 间隔
int spacing() const;
void setSpacing(int v);
// 获取颜色的数量
int colorCount() const;
// 图标的尺寸
void setColorIconSize(const QSize& s);
QSize colorIconSize() const;
// 设置颜色是否是checkable
void setColorCheckable(bool on = true);
bool isColorCheckable() const;
// 获取当前选中的颜色
QColor currentCheckedColor() const;
// 获取index对于的colorbutton
SAColorToolButton* colorButton(int index) const;
// 垂直间距
void setVerticalSpacing(int v);
int verticalSpacing() const;
// 水平间距
void setHorizontalSpacing(int v);
int horizontalSpacing() const;
// 清除当前选中状态,这时没有颜色是选中的
void clearCheckedState();
// 对所有的colorbtn就行遍历处理可以通过此函数进行tooltip设置等操作
void iterationColorBtns(FunColorBtn fn);
// 设置行最小高度
void setRowMinimumHeight(int row, int minSize);
// 让颜色块左对齐
void setHorizontalSpacerToRight(bool on = true);
private Q_SLOTS:
void onButtonClicked(QAbstractButton* btn);
void onButtonPressed(QAbstractButton* btn);
void onButtonReleased(QAbstractButton* btn);
void onButtonToggled(QAbstractButton* btn, bool on);
Q_SIGNALS:
/**
* @brief 对于check模式check的颜色触发的信号
* @param c
* @param on
*/
void colorClicked(const QColor& c);
void colorPressed(const QColor& c);
void colorReleased(const QColor& c);
void colorToggled(const QColor& c, bool on);
public:
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
};
namespace SA
{
/**
* @brief 获取标准色列表一共10种颜色
* @return
*/
SA_COLOR_WIDGETS_API QList< QColor > getStandardColorList();
}
#endif // SACOLORGRIDWIDGET_H
/*** End of inlined file: SAColorGridWidget.h ***/
/*** Start of inlined file: SAColorPaletteGridWidget.h ***/
#ifndef SACOLORPALETTEGRIDWIDGET_H
#define SACOLORPALETTEGRIDWIDGET_H
#include <QWidget>
class QMenu;
class SAColorToolButton;
/**
* @brief 类似office的颜色选择窗口有一排标准色下面有一个颜色板有3行浅色有2行深色
*/
class SA_COLOR_WIDGETS_API SAColorPaletteGridWidget : public QWidget
{
Q_OBJECT
SA_COLOR_WIDGETS_DECLARE_PRIVATE(SAColorPaletteGridWidget)
public:
SAColorPaletteGridWidget(QWidget* par = nullptr);
SAColorPaletteGridWidget(const QList< QColor >& cls, QWidget* par = nullptr);
~SAColorPaletteGridWidget();
// 设置窗口维护的colorList
void setColorList(const QList< QColor >& cls);
QList< QColor > colorList() const;
// 设置颜色深浅比例factor默认为{ 180, 160, 140, 75, 50 }
void setFactor(const QList< int >& factor);
QList< int > factor() const;
// 设置iconsize
void setColorIconSize(const QSize& s);
QSize colorIconSize() const;
// 设置颜色是否是checkable
void setColorCheckable(bool on = true);
bool isColorCheckable() const;
private Q_SLOTS:
void onMainColorClicked(const QColor& c);
void onPaletteColorClicked(const QColor& c);
private:
void init();
Q_SIGNALS:
/**
* @brief 对于check模式check的颜色触发的信号
* @param c
* @param on
*/
void colorClicked(const QColor& c);
};
#endif // SACOLORPALETTEGRIDWIDGET_H
/*** End of inlined file: SAColorPaletteGridWidget.h ***/
/*** Start of inlined file: SAColorToolButton.h ***/
#ifndef SACOLORTOOLBUTTON_H
#define SACOLORTOOLBUTTON_H
#include <QToolButton>
class QPaintEvent;
class QResizeEvent;
class QPainter;
class QStylePainter;
class SAColorMenu;
/**
* @brief 这是一个只显示颜色的toolbutton
*
*
* 在ToolButtonIconOnly模式下如果没有setIcon,则颜色占用所有区域,如下图所示
*
* ┌─────┐
* │color│
* └─────┘
*
* 如果在ToolButtonIconOnly模式下有图标图标在上面显示下面显示颜色如下图所示
*
* ┌─────┐
* │icon │
* │color│
* └─────┘
*
* 在ToolButtonTextBesideIconToolButtonTextUnderIcon下setIconSize 可以指定颜色的大小,
* 但只在ToolButtonTextBesideIconToolButtonTextUnderIcon下有效
*
* 如果没有设置图标也就是setIcon(QIcon()),iconSize作为颜色块的大小
*
* ┌─────────┐
* │┌─┐ │
* │└─┘ │
* └─────────┘
*
* 如果有图标颜色条会在图标下方为图标高度的1/4 为图标宽度一致,如若超过控件的大小,会自动缩小体积
*
*/
class SA_COLOR_WIDGETS_API SAColorToolButton : public QToolButton
{
Q_OBJECT
SA_COLOR_WIDGETS_DECLARE_PRIVATE(SAColorToolButton)
public:
/**
* @brief 颜色按钮的内置样式
* @param parent
* @return
*/
enum ColorToolButtonStyle
{
WithColorMenu, ///< 默认会构建一个SAColorMenu
NoColorMenu ///< 没有ColorMenu
};
public:
explicit SAColorToolButton(QWidget* parent = nullptr);
explicit SAColorToolButton(ColorToolButtonStyle style, QWidget* parent = nullptr);
~SAColorToolButton();
// 获取颜色
QColor color() const;
// 设置Margins
void setMargins(const QMargins& mg);
QMargins margins() const;
// 绘制无颜色
static void paintNoneColor(QPainter* p, const QRect& colorRect);
// 设置颜色按钮的样式
void setColorToolButtonStyle(ColorToolButtonStyle s);
ColorToolButtonStyle colorToolButtonStyle() const;
// 获取colorMenu注意这个函数很有可能会返回nullptr如果ColorToolButtonStyle设置为NoColorMenu或者自己设置了菜单此函数返回nullptr
SAColorMenu* colorMenu() const;
// 建立标准的颜色菜单
SAColorMenu* createColorMenu();
public Q_SLOTS:
// 设置颜色,会发射colorChanged信号
void setColor(const QColor& c);
protected:
// 获取关键的三个rect位置
virtual void calcRect(const QStyleOptionToolButton& opt, QRect& iconRect, QRect& textRect, QRect& colorRect);
virtual void paintButton(QStylePainter* p, const QStyleOptionToolButton& opt);
virtual void paintIcon(QStylePainter* p, const QRect& iconRect, const QStyleOptionToolButton& opt);
virtual void paintText(QStylePainter* p, const QRect& textRect, const QStyleOptionToolButton& opt);
virtual void paintColor(QStylePainter* p, const QRect& colorRect, const QColor& color, const QStyleOptionToolButton& opt);
protected:
virtual void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE;
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
private Q_SLOTS:
void onButtonClicked(bool checked = false);
Q_SIGNALS:
/**
* @brief 颜色被点击的响应
* @param color
*/
void colorClicked(const QColor& color, bool checked = false);
/**
* @brief 颜色改变信号
* @param color
*/
void colorChanged(const QColor& color);
};
#endif // SACOLORTOOLBUTTON_H
/*** End of inlined file: SAColorToolButton.h ***/
// sa ribbon
/*** Start of inlined file: SAFramelessHelper.h ***/
#ifndef SAFRAMELESSHELPER_H
#define SAFRAMELESSHELPER_H
#include <QObject>
class QWidget;
class SA_RIBBON_EXPORT SAFramelessHelper : public QObject
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SAFramelessHelper)
friend class SAPrivateFramelessWidgetData;
public:
explicit SAFramelessHelper(QObject* parent);
~SAFramelessHelper();
// 激活窗体
void activateOn(QWidget* topLevelWidget);
// 移除窗体
void removeFrom(QWidget* topLevelWidget);
// 设置窗体移动
void setWidgetMovable(bool movable);
// 设置窗体缩放
void setWidgetResizable(bool resizable);
// 设置橡皮筋移动
void setRubberBandOnMove(bool movable);
// 设置橡皮筋缩放
void setRubberBandOnResize(bool resizable);
// 设置边框的宽度
void setBorderWidth(int width);
// 设置标题栏高度
void setTitleHeight(int height);
bool widgetResizable();
bool widgetMovable();
bool rubberBandOnMove();
bool rubberBandOnResisze();
uint borderWidth();
uint titleHeight();
protected:
// 事件过滤,进行移动、缩放等
virtual bool eventFilter(QObject* obj, QEvent* event);
};
#endif // FRAMELESSHELPER_H
/*** End of inlined file: SAFramelessHelper.h ***/
/*** Start of inlined file: SARibbonApplicationButton.h ***/
#ifndef SARIBBONAPPLICATIONBUTTON_H
#define SARIBBONAPPLICATIONBUTTON_H
#include <QToolButton>
/**
* @brief The SARibbonApplicationButton class
*
* 默认的plicationButton,可以通过样式指定不一样的ApplicationButton
*/
class SA_RIBBON_EXPORT SARibbonApplicationButton : public QToolButton
{
Q_OBJECT
public:
SARibbonApplicationButton(QWidget* parent = nullptr);
SARibbonApplicationButton(const QString& text, QWidget* parent = nullptr);
SARibbonApplicationButton(const QIcon& icon, const QString& text, QWidget* parent = nullptr);
};
#endif // SARIBBONAPPLICATIONBUTTON_H
/*** End of inlined file: SARibbonApplicationButton.h ***/
/*** Start of inlined file: SARibbonSystemButtonBar.h ***/
#ifndef SARIBBONSYSTEMBUTTONBAR_H
#define SARIBBONSYSTEMBUTTONBAR_H
#include <QFrame>
#include <QToolButton>
/**
* @brief 窗口的最大最小化按钮
* @note 内部有个SARibbonButtonGroupWidget其ObjectName = SASystemButtonGroup
* 如果需要qss可以进行特化处理:
*
* @code
* SARibbonButtonGroupWidget#SASystemButtonGroup
* @endcode
*
*/
class SA_RIBBON_EXPORT SARibbonSystemButtonBar : public QFrame
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonSystemButtonBar)
public:
SARibbonSystemButtonBar(QWidget* parent);
SARibbonSystemButtonBar(QWidget* parent, Qt::WindowFlags flags);
~SARibbonSystemButtonBar();
void setupMinimizeButton(bool on);
void setupMaximizeButton(bool on);
void setupCloseButton(bool on);
// 以最顶层的widget的WindowFlag作为WindowFlag
void updateWindowFlag();
void updateWindowFlag(Qt::WindowFlags flags);
// 设置按钮的宽度比例,最终按钮宽度将按照此比例进行设置
void setButtonWidthStretch(int close = 4, int max = 3, int min = 3);
// 标题栏高度
void setWindowTitleHeight(int h);
int windowTitleHeight() const;
// 设置标准系统按钮的宽度
void setWindowButtonWidth(int w);
int windowButtonWidth() const;
// 设置Qt::WindowStates
void setWindowStates(Qt::WindowStates s);
// 仅获取按钮的状态
Qt::WindowFlags windowButtonFlags() const;
// 三个标准系统窗口按钮
QAbstractButton* minimizeButton() const;
QAbstractButton* maximizeButton() const;
QAbstractButton* closeButton() const;
// 图标尺寸
void setIconSize(const QSize& ic);
QSize iconSize() const;
// 生成并添加一个action
QAction* addAction(QAction* a,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::DelayedPopup);
QAction* addAction(const QString& text,
const QIcon& icon,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::DelayedPopup);
QAction* addMenu(QMenu* menu,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
QAction* addSeparator();
QAction* addWidget(QWidget* w);
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
// 捕获mainwindow的事件
bool eventFilter(QObject* obj, QEvent* event) override;
protected:
virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE;
protected Q_SLOTS:
Q_SLOT void closeWindow();
Q_SLOT void minimizeWindow();
Q_SLOT void maximizeWindow();
};
/**
* @brief The SARibbonSystemToolButton class
*/
class SARibbonSystemToolButton : public QToolButton
{
Q_OBJECT
public:
SARibbonSystemToolButton(QWidget* p = nullptr);
};
#endif // SARIBBONSYSTEMBUTTONBAR_H
/*** End of inlined file: SARibbonSystemButtonBar.h ***/
/*** Start of inlined file: SARibbonToolButton.h ***/
#ifndef SARIBBONTOOLBUTTON_H
#define SARIBBONTOOLBUTTON_H
#include <QToolButton>
#include <QDebug>
/**
* @brief Ribbon界面适用的toolButton
*
* 相对于普通toolbutton主要多了两个类型设置@ref setButtonType 和 @ref setLargeButtonType
*
* @note @sa setIconSize 函数不在起作用iconsize是根据当前尺寸动态调整的
*/
class SA_RIBBON_EXPORT SARibbonToolButton : public QToolButton
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonToolButton)
public:
/**
* @brief 按钮样式
*/
enum RibbonButtonType
{
LargeButton,
SmallButton
};
Q_ENUM(RibbonButtonType)
public:
SARibbonToolButton(QWidget* parent = Q_NULLPTR);
SARibbonToolButton(QAction* defaultAction, QWidget* parent = Q_NULLPTR);
~SARibbonToolButton();
// 标记按钮的样式,按钮的样式有不同的渲染方式
RibbonButtonType buttonType() const;
void setButtonType(const RibbonButtonType& buttonType);
// 是否是小按钮
bool isSmallRibbonButton() const;
// 是否是大按钮
bool isLargeRibbonButton() const;
// 最小尺寸提示
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE;
// 获取间距
int spacing() const;
// 更新尺寸
void updateRect();
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
public:
// 在lite模式下是否允许文字换行
static void setEnableWordWrap(bool on);
static bool isEnableWordWrap();
protected:
virtual void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE;
virtual void mouseMoveEvent(QMouseEvent* e) Q_DECL_OVERRIDE;
virtual void mousePressEvent(QMouseEvent* e) Q_DECL_OVERRIDE;
virtual void mouseReleaseEvent(QMouseEvent* e) Q_DECL_OVERRIDE;
virtual void focusOutEvent(QFocusEvent* e) Q_DECL_OVERRIDE;
virtual void leaveEvent(QEvent* e) Q_DECL_OVERRIDE;
virtual bool hitButton(const QPoint& pos) const Q_DECL_OVERRIDE;
virtual bool event(QEvent* e) Q_DECL_OVERRIDE;
// 事件改变 - 主要为了捕获字体的改变
virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE;
virtual void actionEvent(QActionEvent* e) Q_DECL_OVERRIDE;
protected:
// 绘制按钮
virtual void paintButton(QPainter& p, const QStyleOptionToolButton& opt);
// 绘制图标
virtual void paintIcon(QPainter& p, const QStyleOptionToolButton& opt, const QRect& iconDrawRect);
// 绘制文本
virtual void paintText(QPainter& p, const QStyleOptionToolButton& opt, const QRect& textDrawRect);
// 绘制Indicator
virtual void paintIndicator(QPainter& p, const QStyleOptionToolButton& opt, const QRect& indicatorDrawRect);
private:
static void drawArrow(const QStyle* style,
const QStyleOptionToolButton* toolbutton,
const QRect& rect,
QPainter* painter,
const QWidget* widget = 0);
protected:
};
namespace SA
{
QDebug operator<<(QDebug debug, const QStyleOptionToolButton& opt);
}
#endif // SARIBBONTOOLBUTTON_H
/*** End of inlined file: SARibbonToolButton.h ***/
/*** Start of inlined file: SARibbonColorToolButton.h ***/
#ifndef SARIBBONCOLORTOOLBUTTON_H
#define SARIBBONCOLORTOOLBUTTON_H
class SAColorMenu;
/**
* @brief Refer to the color setting button in the office, which can display the color below the icon(参考office的颜色设置按钮可以显示颜色在图标下方)
*/
class SA_RIBBON_EXPORT SARibbonColorToolButton : public SARibbonToolButton
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonColorToolButton)
public:
/**
* @brief 颜色样式
*/
enum ColorStyle
{
ColorUnderIcon, ///< 颜色在icon下方这个要求必须设置icon
ColorFillToIcon ///< 颜色作为icon这个模式下在setColor会自动生成一个颜色icon替换掉原来的icon因此setIcon函数没有作用
};
public:
SARibbonColorToolButton(QWidget* parent = Q_NULLPTR);
SARibbonColorToolButton(QAction* defaultAction, QWidget* parent = Q_NULLPTR);
~SARibbonColorToolButton();
// 获取颜色
QColor color() const;
// 设置颜色显示方案
void setColorStyle(ColorStyle s);
ColorStyle colorStyle() const;
// 建立标准的颜色菜单
SAColorMenu* setupStandardColorMenu();
public Q_SLOTS:
// 设置颜色,会发射colorChanged信号
void setColor(const QColor& c);
private Q_SLOTS:
void onButtonClicked(bool checked = false);
Q_SIGNALS:
/**
* @brief 颜色被点击的响应
* @param color
*/
void colorClicked(const QColor& color, bool checked = false);
/**
* @brief 颜色改变信号
* @param color
*/
void colorChanged(const QColor& color);
protected:
void paintIcon(QPainter& p, const QStyleOptionToolButton& opt, const QRect& iconDrawRect);
};
#endif // SARIBBONCOLORTOOLBUTTON_H
/*** End of inlined file: SARibbonColorToolButton.h ***/
/*** Start of inlined file: SARibbonLineWidgetContainer.h ***/
#ifndef SARIBBONLINEWIDGETCONTAINER_H
#define SARIBBONLINEWIDGETCONTAINER_H
#include <QtCore/qglobal.h>
#include <QWidget>
#include <QLabel>
/**
* @brief 一个窗口容器把窗口放置中间前面后面都可以设置文本主要用于放置在pannel上的小窗口
*
* 实现如下效果:
*
* PrefixLabel|_Widget_|SuffixLabel
*
*/
class SA_RIBBON_EXPORT SARibbonLineWidgetContainer : public QWidget
{
public:
SARibbonLineWidgetContainer(QWidget* par = nullptr);
// 设置widget,不允许设置一个nullptr
void setWidget(QWidget* innerWidget);
// 设置前缀
void setPrefix(const QString& str);
// 设置后缀
void setSuffix(const QString& str);
// 前缀文本框
QLabel* labelPrefix() const;
// 后缀文本框
QLabel* labelSuffix() const;
private:
// 两个文本
QLabel* m_labelPrefix;
QLabel* m_labelSuffix;
QWidget* m_innerWidget;
};
#endif // SARIBBONWIDGETCONTAINER_H
/*** End of inlined file: SARibbonLineWidgetContainer.h ***/
/*** Start of inlined file: SARibbonActionsManager.h ***/
#ifndef SARIBBONACTIONSMANAGER_H
#define SARIBBONACTIONSMANAGER_H
#include <QObject>
#include <QAbstractListModel>
#include <QAction>
#include <QMap>
#include <QString>
#include <QSet>
class SARibbonBar;
class SARibbonCategory;
/**
* @brief 用于管理SARibbon的所有Action
*
* SARibbonActionsManager维护着两个表一个是tag标签对应的Action list
* 一个是所有接受SARibbonActionsManager管理的action list。
*
* SARibbonActionsManager的标签对应一组actions每个标签对应的action可以重复出现
* 但SARibbonActionsManager维护的action list里只有一份action不会重复出现。
*
* tag用于对action list分组每个tag的实体名字通过@ref setTagName 进行设置,在语言变化时需要及时调用
* setTagName设置新的标签对应的文本。
*
* SARibbonActionsManager默认预设了6个常用标签见@ref SARibbonActionsManager::ActionTag ,用户自定义标签需要在
* SARibbonActionsManager::UserDefineActionTag值的基础上进行累加。
*
* @ref filter (等同@ref actions 函数用于提取标签管理的action list@ref allActions 函数返回SARibbonActionsManager
* 管理的所有标签。
*
* 通过@ref autoRegisteActions 函数可以快速的建立action的管理此函数会遍历@ref SARibbonBar下所有@ref SARibbonPannel
* 添加的action,并给予Category建立tag正常使用用户仅需关注此autoRegisteActions函数即可
*
*
*/
class SA_RIBBON_EXPORT SARibbonActionsManager : public QObject
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonActionsManager)
friend class SARibbonActionsManagerModel;
public:
/**
* @brief 定义action的标签
*/
enum ActionTag
{
UnknowActionTag = 0, ///< 未知的tag
CommonlyUsedActionTag = 0x01, ///< 预设tag-常用命令
NotInFunctionalAreaActionTag = 0x02, ///< 预设tag-不在功能区命令
AutoCategoryDistinguishBeginTag = 0x1000, ///< 自动按Category划分的标签起始在@ref autoRegisteActions 函数会用到
AutoCategoryDistinguishEndTag = 0x2000, ///< 自动按Category划分的标签结束在@ref autoRegisteActions 函数会用到
NotInRibbonCategoryTag = 0x2001, ///< 不在功能区的标签@ref autoRegisteActions 函数会遍历所有category的action
UserDefineActionTag = 0x8000 ///< 自定义标签所有用户自定义tag要大于此tag
};
SARibbonActionsManager(SARibbonBar* bar);
~SARibbonActionsManager();
// 设置tag对应的名字
void setTagName(int tag, const QString& name);
// 获取tag对应的名字
QString tagName(int tag) const;
// 移除tag注意这个函数非常耗时
void removeTag(int tag);
// 注册action
bool registeAction(QAction* act, int tag, const QString& key = QString(), bool enableEmit = true);
// 取消action的注册
void unregisteAction(QAction* act, bool enableEmit = true);
// 过滤得到actions对应的引用实际是一个迭代器
QList< QAction* >& filter(int tag);
// 通过tag筛选出系列action
QList< QAction* >& actions(int tag);
const QList< QAction* > actions(int tag) const;
// 获取所有的标签
QList< int > actionTags() const;
// 通过key获取action
QAction* action(const QString& key) const;
// 通过action找到key
QString key(QAction* act) const;
// 返回所有管理的action数
int count() const;
// 返回所有管理的actions
QList< QAction* > allActions() const;
// 自动加载action,返回tag对应的Category指针
QMap< int, SARibbonCategory* > autoRegisteActions(SARibbonBar* bar);
// 自动加载widget下的actions函数返回的action,返回加载的数量,这些
QSet< QAction* > autoRegisteWidgetActions(QWidget* w, int tag, bool enableEmit = false);
// 根据标题查找action
QList< QAction* > search(const QString& text);
// 清除
void clear();
Q_SIGNALS:
/**
* @brief 标签变化触发的信号,变化包括新增和删除
*/
void actionTagChanged(int tag, bool isdelete);
private Q_SLOTS:
void onActionDestroyed(QObject* o);
void onCategoryTitleChanged(const QString& title);
private:
void removeAction(QAction* act, bool enableEmit = true);
};
/**
* @brief SARibbonActionsManager 对应的model
*/
class SA_RIBBON_EXPORT SARibbonActionsManagerModel : public QAbstractListModel
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonActionsManagerModel)
public:
explicit SARibbonActionsManagerModel(QObject* p = nullptr);
explicit SARibbonActionsManagerModel(SARibbonActionsManager* m, QObject* p = nullptr);
~SARibbonActionsManagerModel();
virtual int rowCount(const QModelIndex& parent) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
virtual Qt::ItemFlags flags(const QModelIndex& index) const override;
virtual QVariant data(const QModelIndex& index, int role) const override;
void setFilter(int tag);
void update();
void setupActionsManager(SARibbonActionsManager* m);
void uninstallActionsManager();
QAction* indexToAction(QModelIndex index) const;
void search(const QString& text);
private Q_SLOTS:
void onActionTagChanged(int tag, bool isdelete);
};
#endif // SARIBBONACTIONSMANAGER_H
/*** End of inlined file: SARibbonActionsManager.h ***/
/*** Start of inlined file: SARibbonLineEdit.h ***/
#ifndef SARIBBONLINEEDIT_H
#define SARIBBONLINEEDIT_H
#include <QLineEdit>
/**
* @brief The SARibbonLineEdit class
*/
class SA_RIBBON_EXPORT SARibbonLineEdit : public QLineEdit
{
Q_OBJECT
public:
SARibbonLineEdit(QWidget* parent = Q_NULLPTR);
SARibbonLineEdit(const QString& text, QWidget* parent = Q_NULLPTR);
};
#endif // SARIBBONLINEEDIT_H
/*** End of inlined file: SARibbonLineEdit.h ***/
/*** Start of inlined file: SARibbonCheckBox.h ***/
#ifndef SARIBBONCHECKBOX_H
#define SARIBBONCHECKBOX_H
#include <QCheckBox>
/**
* @brief The SARibbonCheckBox class
*/
class SA_RIBBON_EXPORT SARibbonCheckBox : public QCheckBox
{
Q_OBJECT
public:
SARibbonCheckBox(QWidget* parent = Q_NULLPTR);
SARibbonCheckBox(const QString& text, QWidget* parent = Q_NULLPTR);
};
#endif // SARIBBONCHECKBOX_H
/*** End of inlined file: SARibbonCheckBox.h ***/
/*** Start of inlined file: SARibbonComboBox.h ***/
#ifndef SARIBBONCOMBOBOX_H
#define SARIBBONCOMBOBOX_H
#include <QComboBox>
/**
* @brief QComboBox的Ribbon显示可以显示QIcon和windowTitle在左侧
*/
class SA_RIBBON_EXPORT SARibbonComboBox : public QComboBox
{
Q_OBJECT
public:
SARibbonComboBox(QWidget* parent = Q_NULLPTR);
};
#endif // SARIBBONCOMBOBOX_H
/*** End of inlined file: SARibbonComboBox.h ***/
/*** Start of inlined file: SARibbonButtonGroupWidget.h ***/
#ifndef SARIBBONBUTTONGROUPWIDGET_H
#define SARIBBONBUTTONGROUPWIDGET_H
#include <QToolButton>
#include <QMenu>
#include <QFrame>
class SARibbonControlButton;
/**
* @brief 用于管理一组Action,类似于QToolBar
*/
class SA_RIBBON_EXPORT SARibbonButtonGroupWidget : public QFrame
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonButtonGroupWidget)
public:
using FpButtonIterate = std::function< bool(SARibbonControlButton*) >;
public:
SARibbonButtonGroupWidget(QWidget* parent = Q_NULLPTR);
~SARibbonButtonGroupWidget() Q_DECL_OVERRIDE;
// 图标尺寸
void setIconSize(const QSize& ic);
QSize iconSize() const;
// 生成并添加一个action
QAction* addAction(QAction* a,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::DelayedPopup);
QAction* addAction(const QString& text,
const QIcon& icon,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::DelayedPopup);
QAction* addMenu(QMenu* menu,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
QAction* addSeparator();
QAction* addWidget(QWidget* w);
// 从ButtonGroupWidget中把action对应的button提取出来如果action没有对应的button就返回nullptr
SARibbonControlButton* actionToRibbonControlToolButton(QAction* action);
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSizeHint() const Q_DECL_OVERRIDE;
public:
bool iterate(FpButtonIterate fp);
Q_SIGNALS:
/**
* @brief 参考QToolBar::actionTriggered的信号
* @param action
*/
void actionTriggered(QAction* action);
protected:
virtual void actionEvent(QActionEvent* e) Q_DECL_OVERRIDE;
};
#endif // SARIBBONBUTTONGROUPWIDGET_H
/*** End of inlined file: SARibbonButtonGroupWidget.h ***/
/*** Start of inlined file: SARibbonStackedWidget.h ***/
#ifndef SARIBBONSTACKEDWIDGET_H
#define SARIBBONSTACKEDWIDGET_H
#include <QStackedWidget>
class QHideEvent;
class QResizeEvent;
/**
* @brief 有qdialog功能的stackwidget用于在最小化时stack能像dialog那样弹出来
*/
class SA_RIBBON_EXPORT SARibbonStackedWidget : public QStackedWidget
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonStackedWidget)
public:
SARibbonStackedWidget(QWidget* parent);
~SARibbonStackedWidget();
void setPopupMode();
bool isPopupMode() const;
void setNormalMode();
bool isNormalMode() const;
void exec();
// 设置stacked管理的窗口会随着stacked的大小变化而变化大小
// 就算不激活也调整大小
void setAutoResize(bool autoresize);
bool isAutoResize() const;
// 移动窗口
void moveWidget(int from, int to);
protected:
// void mouseReleaseEvent(QMouseEvent *e);
void hideEvent(QHideEvent* e) Q_DECL_OVERRIDE;
virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE;
Q_SIGNALS:
/**
* @brief hidWindow
*/
void hidWindow();
};
#endif // SARIBBONSTACKEDWIDGET_H
/*** End of inlined file: SARibbonStackedWidget.h ***/
/*** Start of inlined file: SARibbonSeparatorWidget.h ***/
#ifndef SARIBBONSEPARATORWIDGET_H
#define SARIBBONSEPARATORWIDGET_H
#include <QFrame>
#include <QStyleOption>
///
/// \brief 用于显示分割线
///
class SA_RIBBON_EXPORT SARibbonSeparatorWidget : public QFrame
{
Q_OBJECT
public:
SARibbonSeparatorWidget(QWidget* parent = nullptr);
};
#endif // SARIBBONSEPARATORWIDGET_H
/*** End of inlined file: SARibbonSeparatorWidget.h ***/
/*** Start of inlined file: SARibbonCtrlContainer.h ***/
#ifndef SARIBBONCTROLCONTAINER_H
#define SARIBBONCTROLCONTAINER_H
#include <QWidget>
#include <QScopedPointer>
class QStyleOption;
/**
* @brief 用于装载一个窗体的容器这个窗体会布满整个SARibbonCtrlContainer但会预留空间显示icon或者title
*
* ----------------------
* |icon|text| widget |
* ----------------------
*/
class SA_RIBBON_EXPORT SARibbonCtrlContainer : public QWidget
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonCtrlContainer)
public:
SARibbonCtrlContainer(QWidget* parent = Q_NULLPTR);
~SARibbonCtrlContainer();
void setEnableShowIcon(bool b);
void setEnableShowTitle(bool b);
// 判断是否存在容器窗口
bool hasContainerWidget() const;
// 图标
void setIcon(const QIcon& i);
void setIcon(const QPixmap& pixmap);
QIcon icon() const;
// 图标
void setText(const QString& t);
QString text() const;
// 设置窗口
void setContainerWidget(QWidget* w);
QWidget* containerWidget();
const QWidget* containerWidget() const;
// 获取线索icon的窗口
QWidget* iconWidget() const;
};
#endif // SARIBBONCTROLCONTAINER_H
/*** End of inlined file: SARibbonCtrlContainer.h ***/
/*** Start of inlined file: SARibbonQuickAccessBar.h ***/
#ifndef SARIBBONQUICKACCESSBAR_H
#define SARIBBONQUICKACCESSBAR_H
#include <QMenu>
#include <QToolButton>
class SARibbonToolButton;
class SARibbonButtonGroupWidget;
///
/// \brief ribbon左上顶部的快速响应栏
///
class SA_RIBBON_EXPORT SARibbonQuickAccessBar : public SARibbonCtrlContainer
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonQuickAccessBar)
public:
SARibbonQuickAccessBar(QWidget* parent = 0);
~SARibbonQuickAccessBar();
void addSeparator();
void addAction(QAction* act,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::DelayedPopup);
void addWidget(QWidget* w);
void addMenu(QMenu* m,
Qt::ToolButtonStyle buttonStyle = Qt::ToolButtonIconOnly,
QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 获取内部管理的ButtonGroupWidget
SARibbonButtonGroupWidget* buttonGroupWidget();
const SARibbonButtonGroupWidget* buttonGroupWidget() const;
// 设置图标尺寸
void setIconSize(const QSize& s);
QSize iconSize() const;
};
#endif // SARIBBONQUICKACCESSBAR_H
/*** End of inlined file: SARibbonQuickAccessBar.h ***/
/*** Start of inlined file: SARibbonTabBar.h ***/
#ifndef SARIBBONTABBAR_H
#define SARIBBONTABBAR_H
#include <QTabBar>
#include <QMargins>
/**
* @brief The SARibbonTabBar class
*/
class SA_RIBBON_EXPORT SARibbonTabBar : public QTabBar
{
Q_OBJECT
public:
SARibbonTabBar(QWidget* parent = Q_NULLPTR);
const QMargins& tabMargin() const;
void setTabMargin(const QMargins& tabMargin);
protected:
QSize tabSizeHint(int index) const;
private:
QMargins m_tabMargin;
};
#endif // SARIBBONTABBAR_H
/*** End of inlined file: SARibbonTabBar.h ***/
/*** Start of inlined file: SARibbonControlButton.h ***/
#ifndef SARIBBONCONTROLBUTTON_H
#define SARIBBONCONTROLBUTTON_H
#include <QToolButton>
/**
* @brief 用于SARibbonGallery的control button
*
* 为了防止外部qss的影响单独继承一个类
*/
class SA_RIBBON_EXPORT SARibbonControlButton : public QToolButton
{
Q_OBJECT
public:
SARibbonControlButton(QWidget* parent = 0);
};
/**
* @brief 用于SARibbonButtonGroupWidget的control button
*
* 为了防止SARibbonToolButton qss的影响单独继承一个类
*/
class SA_RIBBON_EXPORT SARibbonControlToolButton : public QToolButton
{
Q_OBJECT
public:
SARibbonControlToolButton(QWidget* parent = 0);
};
#endif // SARIBBONPANNELTOOLBUTTON_H
/*** End of inlined file: SARibbonControlButton.h ***/
/*** Start of inlined file: SARibbonMenu.h ***/
#ifndef SARIBBONMENU_H
#define SARIBBONMENU_H
#include <QMenu>
///
/// \brief 用在ribbon的menu
/// 可以通过StyleSheet设置样式而不影响QMenu
///
class SA_RIBBON_EXPORT SARibbonMenu : public QMenu
{
Q_OBJECT
public:
explicit SARibbonMenu(QWidget* parent = Q_NULLPTR);
explicit SARibbonMenu(const QString& title, QWidget* parent = Q_NULLPTR);
QAction* addRibbonMenu(SARibbonMenu* menu);
SARibbonMenu* addRibbonMenu(const QString& title);
SARibbonMenu* addRibbonMenu(const QIcon& icon, const QString& title);
QAction* addWidget(QWidget* w);
};
#endif // SARIBBONMENU_H
/*** End of inlined file: SARibbonMenu.h ***/
/*** Start of inlined file: SARibbonPannelOptionButton.h ***/
#ifndef SARIBBONPANNELOPTIONBUTTON_H
#define SARIBBONPANNELOPTIONBUTTON_H
#include <QToolButton>
class QAction;
/**
* @brief Pannel右下角的操作按钮
*
* 此按钮和一个action关联使用@ref SARibbonPannel::addOptionAction 函数用于生成此按钮,正常来说
* 用户并不需要直接操作此类,仅仅用于样式设计
* 如果一定要重载此按钮,可以通过重载@ref SARibbonElementFactory
* 的 @ref SARibbonElementFactory::createRibbonPannelOptionButton来实现新的OptionButton
*
*/
class SA_RIBBON_EXPORT SARibbonPannelOptionButton : public QToolButton
{
Q_OBJECT
public:
SARibbonPannelOptionButton(QWidget* parent = Q_NULLPTR);
};
#endif // SAROBBONPANNELOPTIONBUTTON_H
/*** End of inlined file: SARibbonPannelOptionButton.h ***/
/*** Start of inlined file: SARibbonPannelItem.h ***/
#ifndef SARIBBONPANNELITEM_H
#define SARIBBONPANNELITEM_H
#include <QWidgetItem>
#include <QAction>
class SARibbonToolButton;
/**
* @brief 是对pannel所有子窗口的抽象参考qt的toolbar
*
* 参考qt的toolbarpannel所有子窗口内容都通过QAction进行抽象包括gallery这些窗口也是通过QAction进行抽象
* QAction最终会转换为SARibbonPannelItem每个SARibbonPannelItem都含有一个widgetSARibbonPannel的布局
* 就基于SARibbonPannelItem
*
* 无窗口的action会在内部生成一个SARibbonToolButton
*/
class SA_RIBBON_EXPORT SARibbonPannelItem : public QWidgetItem
{
public:
/**
* @brief 定义了行的占比ribbon中有largemedia和small三种占比
*/
enum RowProportion
{
None, ///< 为定义占比这时候将会依据expandingDirections来判断如果能有Qt::Vertical就等同于Large否则就是Small
Large, ///< 大占比一个widget的高度会充满整个pannel
Medium, ///< 中占比,在@ref SARibbonPannel::pannelLayoutMode 为 @ref SARibbonPannel::ThreeRowMode 时才会起作用且要同一列里两个都是Medium时会在三行中占据两行
Small ///< 小占比占SARibbonPannel的一行Medium在不满足条件时也会变为Small但不会变为Large
};
SARibbonPannelItem(QWidget* widget);
bool isEmpty() const Q_DECL_OVERRIDE;
short rowIndex; ///< 记录当前item属于第几行hide模式下为-1
int columnIndex; ///< 记录当前item属于第几列hide模式下为-1
QRect itemWillSetGeometry; ///< 在调用SARibbonPannelLayout::updateGeomArray会更新这个此处实际设置的时候会QWidgetItem::setGeometry设置Geometry
QAction* action; /// < 记录action参考QToolBarLayoutItem
bool customWidget; ///< 对于没有窗口的action实际也会有一个SARibbonToolButton在销毁时要delete掉
SARibbonPannelItem::RowProportion rowProportion; ///< 行的占比ribbon中有largemedia和small三种占比,见@ref RowProportion
};
#ifndef SA_ActionPropertyName_RowProportion
#define SA_ActionPropertyName_RowProportion "_sa_RowProportion"
#endif
#ifndef SA_ActionPropertyName_ToolButtonPopupMode
#define SA_ActionPropertyName_ToolButtonPopupMode "_sa_ToolButtonPopupMode"
#endif
#ifndef SA_ActionPropertyName_ToolButtonStyle
#define SA_ActionPropertyName_ToolButtonStyle "_sa_ToolButtonStyle"
#endif
#endif // SARIBBONPANNELITEM_H
/*** End of inlined file: SARibbonPannelItem.h ***/
/*** Start of inlined file: SARibbonPannelLayout.h ***/
#ifndef SARIBBONPANNELLAYOUT_H
#define SARIBBONPANNELLAYOUT_H
#include <QLayout>
class QToolButton;
class SARibbonPannel;
class SARibbonPannelLabel;
/**
* @brief 针对SARibbonPannel的布局
*
* SARibbonPannelLayout实际是一个列布局每一列有2~3行看窗口定占几行
*
* 核心函数: @ref SARibbonPannelLayout::createItem
*
* @note QLayout::contentsMargins 函数不会启作用,如果要设置contentsMargins使用@sa setPannelContentsMargins
*/
class SA_RIBBON_EXPORT SARibbonPannelLayout : public QLayout
{
Q_OBJECT
friend class SARibbonPannel;
public:
SARibbonPannelLayout(QWidget* p = 0);
~SARibbonPannelLayout();
// SARibbonPannelLayout additem 无效
void addItem(QLayoutItem* item) Q_DECL_OVERRIDE;
// QLayout 所必须的重载函数
QLayoutItem* itemAt(int index) const Q_DECL_OVERRIDE;
QLayoutItem* takeAt(int index) Q_DECL_OVERRIDE;
int count() const Q_DECL_OVERRIDE;
bool isEmpty() const Q_DECL_OVERRIDE;
void invalidate() Q_DECL_OVERRIDE;
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
void setGeometry(const QRect& rect) Q_DECL_OVERRIDE;
QSize minimumSize() const Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
// 获取ribbonpannel
SARibbonPannel* ribbonPannel() const;
// SARibbonPannel主要通过此函数来添加action
void insertAction(int index, QAction* act, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::None);
// 设置OptionAction如果要去除传入nullptr指针即可
void setOptionAction(QAction* action);
bool isHaveOptionAction() const;
// 通过action获取SARibbonPannelItem
SARibbonPannelItem* pannelItem(QAction* action) const;
// 获取最后一个添加的item
SARibbonPannelItem* lastItem() const;
// 获取最后生成的窗口
QWidget* lastWidget() const;
// 移动两个item
void move(int from, int to);
// 判断是否需要重新布局
bool isDirty() const;
// 更新尺寸
void updateGeomArray();
// 通过action获取SARibbonPannelItem的索引
int indexByAction(QAction* action) const;
// 标题高度
int pannelTitleHeight() const;
void setPannelTitleHeight(int newTitleHeight);
// 判断是否存在标题
bool isEnableShowPannelTitle() const;
void setEnableShowPannelTitle(bool on);
// 返回大按钮的高度
int largeButtonHeight() const;
// 标题区域和按钮的间隔
int pannelTitleSpace() const;
void setPannelTitleSpace(int newTitleSpace);
// pannel 标题的label
SARibbonPannelLabel* pannelTitleLabel() const;
// 设置按钮的icon尺寸large action不受此尺寸影响
void setToolButtonIconSize(const QSize& s);
QSize toolButtonIconSize() const;
protected:
// 获取optionAction 按钮尺寸
QSize optionActionButtonSize() const;
// 布局action
void doLayout();
// 把action转换为item对于纯Action此函数会创建SARibbonToolButton,
// rp用于告诉Layout生成什么样的窗口详细见SARibbonPannelItem::RowProportion
SARibbonPannelItem* createItem(QAction* action, SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::None);
void updateGeomArray(const QRect& setrect);
// 重新计算扩展条码此函数必须在updateGeomArray函数之后调用
void recalcExpandGeomArray(const QRect& setrect);
// 返回optionActionButton的尺寸
private:
// 根据列数,计算窗口的宽度,以及最大宽度
void columnWidthInfo(int colindex, int& width, int& maximum) const;
// 设置titlelabel
void setPannelTitleLabel(SARibbonPannelLabel* newTitleLabel);
private:
QList< SARibbonPannelItem* > mItems;
int mColumnCount { 0 }; ///< 记录有多少列
bool mExpandFlag { false }; ///< 标记是否是会扩展的
QSize mSizeHint; ///< sizeHint返回的尺寸
QSize mDefaultToolButtonIconSize { 22, 22 }; ///< 记录默认的按钮图标尺寸
bool mDirty { true }; ///< 用于标记是否需要刷新元素参考QToolBarLayout源码
int mLargeHeight { 0 }; ///< 记录大图标的高度
int mTitleHeight { 15 }; ///< 标题区域高度
int mTitleSpace { 2 }; ///< 标题区域和按钮的间隔
bool mEnableShowTitle { true }; ///< 是否运行显示pannel标题
SARibbonPannelLabel* mTitleLabel { nullptr }; ///< titlelabel指针
QRect mTitleLabelGeometry; ///< titlelabel的位置
QToolButton* mOptionActionBtn { nullptr }; ///< optionAction对应的button
QRect mOptionActionBtnGeometry; ///< optionAction的位置
};
#endif // SARIBBONPANNELLAYOUT_H
/*** End of inlined file: SARibbonPannelLayout.h ***/
/*** Start of inlined file: SARibbonPannel.h ***/
#ifndef SARIBBONPANNEL_H
#define SARIBBONPANNEL_H
#include <QLayout>
#include <QWidget>
#include <QLabel>
class SARibbonMenu;
class SARibbonGallery;
class QGridLayout;
class SARibbonPannelOptionButton;
class SARibbonPannelLayout;
class SARibbonCategory;
class SARibbonBar;
/**
* @brief SARibbonPannel的标题label此类用于qss
*/
class SA_RIBBON_EXPORT SARibbonPannelLabel : public QLabel
{
Q_OBJECT
public:
SARibbonPannelLabel(QWidget* parent = nullptr);
};
/**
* @brief pannel页窗口pannel是ribbon的面板用于承放控件
*
* ribbon的pannel分为两行模式和三行模式以office为代表的ribbon为3行模式以WPS为代表的“紧凑派”就是2行模式
* SARibbon可通过SARibbonBar的@ref SARibbonBar::RibbonStyle 来指定模式(通过函数@ref SARibbonBar::setRibbonStyle )
*
* 在pannel中可以通过@ref setExpanding 函数指定pannel水平扩展如果pannel里面没有能水平扩展的控件将会留白因此
* 建议在pannel里面有水平扩展的控件如@ref SARibbonGallery )才指定这个函数
*
* pannel的布局通过@ref SARibbonPannelLayout 来实现,如果有其他布局,可以通过继承@ref
* SARibbonElementCreateDelegate::createRibbonPannel 函数返回带有自己布局的pannel但你必须继承对应的虚函数
*/
class SA_RIBBON_EXPORT SARibbonPannel : public QFrame
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonPannel)
friend class SARibbonCategory;
friend class SARibbonCategoryPrivate;
friend class SARibbonCustomizeWidgetPrivate;
friend class SARibbonPannelLayout;
Q_PROPERTY(bool isCanCustomize READ isCanCustomize WRITE setCanCustomize)
Q_PROPERTY(bool isExpanding READ isExpanding WRITE setExpanding)
Q_PROPERTY(QString pannelName READ pannelName WRITE setPannelName)
public:
enum PannelLayoutMode
{
ThreeRowMode, ///< 三行布局模式office就是三行布局模式pannel能布置3行小toolbutton默认模式
TwoRowMode ///< 两行布局模式wps的后续布局模式就是两行布局模式pannel能布置2行小toolbutton
};
Q_ENUM(PannelLayoutMode)
public:
using FpRibbonToolButtonIterate = std::function< bool(SARibbonToolButton*) >;
public:
SARibbonPannel(QWidget* parent = nullptr);
SARibbonPannel(const QString& name, QWidget* parent = nullptr);
~SARibbonPannel() Q_DECL_OVERRIDE;
using QWidget::addAction;
// 把action加入到pannel
void addAction(QAction* action, SARibbonPannelItem::RowProportion rp);
// 生成并添加一个action
void addAction(QAction* act,
QToolButton::ToolButtonPopupMode popMode,
SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large);
// 把action加入到pannel并以大图标显示
void addLargeAction(QAction* action);
// 把action加入到pannel在三行模式下会以中图标显示
void addMediumAction(QAction* action);
// 把action加入到pannel并以小图标显示
void addSmallAction(QAction* action);
// 把action加入到pannel并以小图标显示
void addSmallAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);
// 把action加入到pannel并以大图标显示
void addLargeAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);
// 把action加入到pannel在三行模式下会以中图标显示
void addMediumAction(QAction* action, QToolButton::ToolButtonPopupMode popMode);
QAction* addAction(const QString& text,
const QIcon& icon,
QToolButton::ToolButtonPopupMode popMode,
SARibbonPannelItem::RowProportion rp = SARibbonPannelItem::Large);
// 添加menu
void addMenu(QMenu* menu,
SARibbonPannelItem::RowProportion rp,
QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加普通大菜单
void addLargeMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加普通小按钮菜单
void addSmallMenu(QMenu* menu, QToolButton::ToolButtonPopupMode popMode = QToolButton::InstantPopup);
// 添加窗口
QAction* addWidget(QWidget* w, SARibbonPannelItem::RowProportion rp);
// 添加窗口,占用ribbon的一行
QAction* addSmallWidget(QWidget* w);
// 添加窗口,占用ribbon的一行
QAction* addMediumWidget(QWidget* w);
// 添加窗口,占用所有行
QAction* addLargeWidget(QWidget* w);
// 添加一个Gallery
SARibbonGallery* addGallery(bool expanding = true);
// 添加分割线
QAction* addSeparator();
// 从pannel中把action对应的button提取出来如果action没有对应的button就返回nullptr
SARibbonToolButton* actionToRibbonToolButton(QAction* action);
// 设置操作action如果要去除传入nullptr指针即可SARibbonPannel不会对QAction的所有权进行管理
// OptionAction也会触发actionTriggered信号
void setOptionAction(QAction* action);
// 判断是否存在OptionAction
bool isHaveOptionAction() const;
// 获取所有的buttons
QList< SARibbonToolButton* > ribbonToolButtons() const;
// 获取PannelLayoutMode
PannelLayoutMode pannelLayoutMode() const;
void setPannelLayoutMode(PannelLayoutMode mode);
// 更新按钮的尺寸这个函数在pannel的布局状态变换后需要调用刷新
void resetToolButtonSize();
// 判断是否为2行模式
bool isTwoRow() const
{
return (TwoRowMode == pannelLayoutMode());
}
// 把pannel设置为扩展模式此时会撑大水平区域
void setExpanding(bool isExpanding = true);
// 是否是扩展模式
bool isExpanding() const;
// 标题栏高度
void setTitleHeight(int h);
int titleHeight() const;
// 是否显示标题显示标题后标题的高度需要设置默认高度为15
bool isEnableShowTitle() const;
void setEnableShowTitle(bool on);
// action对应的布局index此操作一般用于移动moveAction其他意义不大
int actionIndex(QAction* act) const;
// 移动action
void moveAction(int from, int to);
// 判断是否可以自定义
bool isCanCustomize() const;
void setCanCustomize(bool b);
// 标题
QString pannelName() const;
void setPannelName(const QString& title);
// 大图标的高度
int largeButtonHeight() const;
// 获取布局对应的item,此函数目前仅仅在自定义过程中用到
const QList< SARibbonPannelItem* >& ribbonPannelItem() const;
// 获取pannel layout
SARibbonPannelLayout* pannelLayout() const;
// 更新布局
void updateItemGeometry();
// 获取category指针如果没有parent或者不在category管理返回nullptr
SARibbonCategory* category() const;
// 获取ribbonBar指针如果没有返回nullptr
SARibbonBar* ribbonBar() const;
// 设置按钮之间的间隔
void setSpacing(int n);
int spacing() const;
//
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
virtual QSize minimumSizeHint() const Q_DECL_OVERRIDE;
// 设置按钮的icon尺寸large action不受此尺寸影响
void setToolButtonIconSize(const QSize& s);
QSize toolButtonIconSize() const;
// 此函数会遍历SARibbonPannel下的所有RibbonToolButton执行函数指针(bool(SARibbonRibbonToolButton*))函数指针返回false则停止迭代
bool iterate(FpRibbonToolButtonIterate fp);
// 获取最近添加的按钮
SARibbonToolButton* lastAddActionButton();
Q_SIGNALS:
/**
* @brief 等同于QToolBar::actionTriggered
* @param action
*/
void actionTriggered(QAction* action);
/**
* @brief pannel的标题发生了改变
* @param n
*/
void pannelNameChanged(const QString& n);
public:
// pannel高度推荐
static int pannelHeightHint(const QFontMetrics& fm, PannelLayoutMode layMode, int pannelTitleHeight);
// 把action的行属性设置进action中action自身携带了行属性
static void setActionRowProportionProperty(QAction* action, SARibbonPannelItem::RowProportion rp);
// 获取action的行属性
static SARibbonPannelItem::RowProportion getActionRowProportionProperty(QAction* action);
// 把action的PopupMode属性设置进action中action自身携带了PopupMode属性
static void setActionToolButtonPopupModeProperty(QAction* action, QToolButton::ToolButtonPopupMode popMode);
// 获取action的PopupMode属性
static QToolButton::ToolButtonPopupMode getActionToolButtonPopupModeProperty(QAction* action);
// 把action的ToolButtonStyle属性设置进action中action自身携带了ToolButtonStyle属性
static void setActionToolButtonStyleProperty(QAction* action, Qt::ToolButtonStyle buttonStyle);
// 获取action的ToolButtonStyle属性
static Qt::ToolButtonStyle getActionToolButtonStyleProperty(QAction* action);
protected:
virtual bool event(QEvent* e) Q_DECL_OVERRIDE;
virtual void actionEvent(QActionEvent* e) Q_DECL_OVERRIDE;
virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE;
};
#endif // SARIBBONPANNEL_H
/*** End of inlined file: SARibbonPannel.h ***/
/*** Start of inlined file: SARibbonCategory.h ***/
#ifndef SARIBBONCATEGORY_H
#define SARIBBONCATEGORY_H
#include <QFrame>
#include <QScopedPointer>
#include <QPushButton>
#include <QWheelEvent>
class QAction;
class QHBoxLayout;
class QWheelEvent;
class SARibbonBar;
class SARibbonCategoryLayout;
/**
* @brief 一项ribbon tab页
* @note SARibbonCategory的windowTitle影响了其在SARibbonBar的标签显示
* 如果要改标签名字直接调用SARibbonCategory的setWindowTitle函数
*/
class SA_RIBBON_EXPORT SARibbonCategory : public QFrame
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonCategory)
friend class SARibbonBar;
friend class SARibbonContextCategory;
Q_PROPERTY(bool isCanCustomize READ isCanCustomize WRITE setCanCustomize)
Q_PROPERTY(QString categoryName READ categoryName WRITE setCategoryName)
public:
using FpPannelIterate = std::function< bool(SARibbonPannel*) >;
public:
SARibbonCategory(QWidget* p = nullptr);
SARibbonCategory(const QString& name, QWidget* p = nullptr);
~SARibbonCategory();
// category的名字
QString categoryName() const;
// 设置category名字等同setWindowTitle
void setCategoryName(const QString& title);
// 设置pannel的模式
SARibbonPannel::PannelLayoutMode pannelLayoutMode() const;
void setPannelLayoutMode(SARibbonPannel::PannelLayoutMode m);
// 添加pannel
SARibbonPannel* addPannel(const QString& title);
// 添加pannel
void addPannel(SARibbonPannel* pannel);
// qt designer专用
Q_INVOKABLE void addPannel(QWidget* pannel);
// 插入pannel
SARibbonPannel* insertPannel(const QString& title, int index);
// 通过名字查找pannel
SARibbonPannel* pannelByName(const QString& title) const;
// 通过ObjectName查找pannel
SARibbonPannel* pannelByObjectName(const QString& objname) const;
// 通过索引找到pannel如果超过索引范围会返回nullptr
SARibbonPannel* pannelByIndex(int index) const;
// 查找pannel的index
int pannelIndex(SARibbonPannel* p) const;
// 移动一个Pannel从from index到to index
void movePannel(int from, int to);
// 把pannel从Category中移除不会销毁此时pannel的所有权归还操作者
bool takePannel(SARibbonPannel* pannel);
// 移除PannelCategory会直接回收SARibbonPannel内存
bool removePannel(SARibbonPannel* pannel);
bool removePannel(int index);
// 返回所有的Pannel
QList< SARibbonPannel* > pannelList() const;
//
QSize sizeHint() const Q_DECL_OVERRIDE;
// 如果是ContextCategory此函数返回true
bool isContextCategory() const;
// pannel的个数
int pannelCount() const;
// 判断是否可以自定义
bool isCanCustomize() const;
void setCanCustomize(bool b);
// 设置pannel的标题栏高度
int pannelTitleHeight() const;
void setPannelTitleHeight(int h);
// 设置pannel是否显示标题栏
bool isEnableShowPannelTitle() const;
void setEnableShowPannelTitle(bool on);
// 设置Category的对齐方式
void setCategoryAlignment(SARibbonAlignment al);
SARibbonAlignment categoryAlignment() const;
// 设置pannel的spacing
void setPannelSpacing(int n);
int pannelSpacing() const;
// 设置pannel按钮的icon尺寸large action不受此尺寸影响
void setPannelToolButtonIconSize(const QSize& s);
QSize pannelToolButtonIconSize() const;
// 获取对应的ribbonbar如果没有加入ribbonbar的管理此值为null
SARibbonBar* ribbonBar() const;
// 刷新category的尺寸布局
void updateItemGeometry();
// 此函数会遍历Category下的所有pannel,执行函数指针函数指针返回false则停止迭代
bool iterate(FpPannelIterate fp);
Q_SIGNALS:
/**
* @brief category标题发生了改变信号
* @param n
*/
void categoryNameChanged(const QString& n);
/**
* @brief 参考QToolBar::actionTriggered的信号
* @param action
*/
void actionTriggered(QAction* action);
protected:
virtual bool event(QEvent* e) Q_DECL_OVERRIDE;
// 处理滚轮事件
void wheelEvent(QWheelEvent* event) Q_DECL_OVERRIDE;
//
void changeEvent(QEvent* event) Q_DECL_OVERRIDE;
// 标记这个是上下文标签
void markIsContextCategory(bool isContextCategory = true);
// 获取SARibbonCategoryLayoutlayout
SARibbonCategoryLayout* categoryLayout() const;
};
/**
* @brief SARibbonCategory无法完全显示时显示的调整按钮
*
* 重新定义是为了防止被外部的样式影响,同时可以使用SARibbonCategoryScrollButton的样式定义
*/
class SA_RIBBON_EXPORT SARibbonCategoryScrollButton : public QToolButton
{
Q_OBJECT
public:
SARibbonCategoryScrollButton(Qt::ArrowType arr, QWidget* p = nullptr);
};
#endif // SARIBBONCATEGORY_H
/*** End of inlined file: SARibbonCategory.h ***/
/*** Start of inlined file: SARibbonCategoryLayout.h ***/
#ifndef SARIBBONCATEGORYLAYOUT_H
#define SARIBBONCATEGORYLAYOUT_H
#include <QLayout>
#include <QList>
#include <QMap>
class SARibbonPannel;
class SARibbonCategoryLayoutItem;
class SARibbonSeparatorWidget;
/**
* @brief The SARibbonCategoryLayout class
*/
class SA_RIBBON_EXPORT SARibbonCategoryLayout : public QLayout
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonCategoryLayout)
public:
SARibbonCategoryLayout(SARibbonCategory* parent);
~SARibbonCategoryLayout();
SARibbonCategory* ribbonCategory() const;
virtual void addItem(QLayoutItem* item) Q_DECL_OVERRIDE;
virtual QLayoutItem* itemAt(int index) const Q_DECL_OVERRIDE;
virtual QLayoutItem* takeAt(int index) Q_DECL_OVERRIDE;
SARibbonCategoryLayoutItem* takePannelItem(int index);
SARibbonCategoryLayoutItem* takePannelItem(SARibbonPannel* pannel);
bool takePannel(SARibbonPannel* pannel);
virtual int count() const Q_DECL_OVERRIDE;
void setGeometry(const QRect& rect) Q_DECL_OVERRIDE;
QSize sizeHint() const Q_DECL_OVERRIDE;
QSize minimumSize() const Q_DECL_OVERRIDE;
Qt::Orientations expandingDirections() const Q_DECL_OVERRIDE;
void invalidate() Q_DECL_OVERRIDE;
// 追加一个pannel
void addPannel(SARibbonPannel* pannel);
// 插入一个pannel
void insertPannel(int index, SARibbonPannel* pannel);
//
QSize categoryContentSize() const;
// 更新尺寸
void updateGeometryArr();
// 执行位置调整
void doLayout();
// 返回所有pannels
QList< SARibbonPannel* > pannels() const;
// 通过obj name获取pannel
SARibbonPannel* pannelByObjectName(const QString& objname) const;
// 通过pannel name获取pannel
SARibbonPannel* pannelByName(const QString& pannelname) const;
// 通过索引找到pannel如果超过索引范围会返回nullptr
SARibbonPannel* pannelByIndex(int i) const;
// 移动pannel
void movePannel(int from, int to);
// pannel的数量
int pannelCount() const;
// pannel的索引
int pannelIndex(SARibbonPannel* p) const;
// 获取所有的pannel
QList< SARibbonPannel* > pannelList() const;
// 执行滚轮事件
void scroll(int px);
// 判断是否有滚动过
bool isScrolled() const;
// category的总宽度
int categoryTotalWidth() const;
// 设置Category的对齐方式
void setCategoryAlignment(SARibbonAlignment al);
SARibbonAlignment categoryAlignment() const;
private Q_SLOTS:
void onLeftScrollButtonClicked();
void onRightScrollButtonClicked();
};
/**
* @brief SARibbonCategoryLayoutItem用于标识SARibbonCategoryLayout的item
*/
class SA_RIBBON_EXPORT SARibbonCategoryLayoutItem : public QWidgetItem
{
public:
SARibbonCategoryLayoutItem(SARibbonPannel* w);
SARibbonSeparatorWidget* separatorWidget;
// 把内部的widget转换为pannel
SARibbonPannel* toPannelWidget();
QRect mWillSetGeometry; ///< pannel将要设置的Geometry
QRect mWillSetSeparatorGeometry; ///< pannel将要设置的Separator的Geometry
};
#endif // SARIBBONCATEGORYLAYOUT_H
/*** End of inlined file: SARibbonCategoryLayout.h ***/
/*** Start of inlined file: SARibbonContextCategory.h ***/
#ifndef SARIBBONCONTEXTCATEGORY_H
#define SARIBBONCONTEXTCATEGORY_H
#include <QWidget>
/**
* @brief 管理上下文标签的类
*/
class SA_RIBBON_EXPORT SARibbonContextCategory : public QObject
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonContextCategory)
public:
SARibbonContextCategory(QWidget* parent = 0);
~SARibbonContextCategory();
// 上下文目录添加下属目录
SARibbonCategory* addCategoryPage(const QString& title);
void addCategoryPage(SARibbonCategory* category);
// 获取上下文标签下管理的标签个数
int categoryCount() const;
// 设置id
void setId(const QVariant& id);
QVariant id() const;
// 设置上下文颜色
void setContextColor(const QColor color);
QColor contextColor() const;
// 上下文标签的内容
QString contextTitle() const;
void setContextTitle(const QString& contextTitle);
// 获取对应的tab页
SARibbonCategory* categoryPage(int index);
// 获取所有的SARibbonCategory*
QList< SARibbonCategory* > categoryList() const;
// 移除category
bool takeCategory(SARibbonCategory* category);
// 判断上下文是否维护了此SARibbonCategory
bool isHaveCategory(SARibbonCategory* category) const;
Q_SIGNALS:
/**
* @brief 标签加入上下文
* @param category
*/
void categoryPageAdded(SARibbonCategory* category);
/**
* @brief 标签从上下文移除
* @param category
*/
void categoryPageRemoved(SARibbonCategory* category);
/**
* @brief 上下文的标题发生改变
* @param title
*/
void contextTitleChanged(const QString& title);
/**
* @brief 上下文标签维护的标签页名字发生了改变
* @param category 发生改变的上下文标签页
* @param title 新名字
*/
void categoryTitleChanged(SARibbonCategory* category, const QString& title);
private Q_SLOTS:
void onCategoryTitleChanged(const QString& title);
protected:
// 获取父级窗口
QWidget* parentWidget() const;
virtual bool eventFilter(QObject* watched, QEvent* e) override;
};
#endif // SARIBBONCONTEXTCATEGORY_H
/*** End of inlined file: SARibbonContextCategory.h ***/
/*** Start of inlined file: SARibbonGalleryItem.h ***/
#ifndef SARIBBONGALLERYITEM_H
#define SARIBBONGALLERYITEM_H
#include <QIcon>
#include <QVariant>
#include <QMap>
#include <QAction>
class SARibbonGalleryGroup;
///
/// \brief 类似QStandardItem的GalleryItem
///
class SA_RIBBON_EXPORT SARibbonGalleryItem
{
friend class SARibbonGalleryGroupModel;
public:
SARibbonGalleryItem();
SARibbonGalleryItem(const QString& text, const QIcon& icon);
SARibbonGalleryItem(QAction* act);
virtual ~SARibbonGalleryItem();
// 设置角色
void setData(int role, const QVariant& data);
virtual QVariant data(int role) const;
// 设置文字描述
void setText(const QString& text);
QString text() const;
// 设置tooltip
void setToolTip(const QString& text);
QString toolTip() const;
// 设置图标
void setIcon(const QIcon& ico);
QIcon icon() const;
// 设置是否可见
bool isSelectable() const;
void setSelectable(bool isSelectable);
// 设置是否可选
bool isEnable() const;
void setEnable(bool isEnable);
// 设置item的flag
void setFlags(Qt::ItemFlags flag);
virtual Qt::ItemFlags flags() const;
// 设置action
void setAction(QAction* act);
QAction* action();
// 文字对齐方式
void setTextAlignment(Qt::Alignment a);
Qt::Alignment textAlignment() const;
private:
QMap< int, QVariant > mDatas;
Qt::ItemFlags mFlags;
QAction* mAction;
};
#endif // SARIBBONGALLERYITEM_H
/*** End of inlined file: SARibbonGalleryItem.h ***/
/*** Start of inlined file: SARibbonGalleryGroup.h ***/
#ifndef SARIBBONGALLERYGROUP_H
#define SARIBBONGALLERYGROUP_H
#include <QList>
#include <QListView>
#include <QStyledItemDelegate>
///
/// \brief SARibbonGalleryGroup对应的显示代理
///
class SA_RIBBON_EXPORT SARibbonGalleryGroupItemDelegate : public QStyledItemDelegate
{
public:
SARibbonGalleryGroupItemDelegate(SARibbonGalleryGroup* group, QObject* parent = Q_NULLPTR);
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE;
virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const Q_DECL_OVERRIDE;
virtual void paintIconOnly(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual void paintIconWithText(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual void
paintIconWithTextWordWrap(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
private:
SARibbonGalleryGroup* mGroup;
};
///
/// \brief SARibbonGalleryGroup对应的model
///
class SA_RIBBON_EXPORT SARibbonGalleryGroupModel : public QAbstractListModel
{
Q_OBJECT
public:
SARibbonGalleryGroupModel(QObject* parent = Q_NULLPTR);
~SARibbonGalleryGroupModel();
virtual int rowCount(const QModelIndex& parent) const Q_DECL_OVERRIDE;
virtual Qt::ItemFlags flags(const QModelIndex& index) const Q_DECL_OVERRIDE;
virtual QVariant data(const QModelIndex& index, int role) const Q_DECL_OVERRIDE;
virtual QModelIndex index(int row, int column, const QModelIndex& parent) const Q_DECL_OVERRIDE;
virtual bool setData(const QModelIndex& index, const QVariant& value, int role) Q_DECL_OVERRIDE;
void clear();
SARibbonGalleryItem* at(int row) const;
void insert(int row, SARibbonGalleryItem* item);
SARibbonGalleryItem* take(int row);
void append(SARibbonGalleryItem* item);
private:
QList< SARibbonGalleryItem* > mItems;
};
/**
* @brief Gallery的组
*
* 组负责显示管理Gallery Item
*/
class SA_RIBBON_EXPORT SARibbonGalleryGroup : public QListView
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonGalleryGroup)
public:
/**
* @brief GalleryGroup显示的样式
*/
enum GalleryGroupStyle
{
IconWithText, ///< 图标带文字
IconWithWordWrapText, ///< 图标带文字,文字会换行显示此模式只会对DisplayOneRow生效如果不是DisplayOneRow等同IconWithText
IconOnly ///< 只有图标
};
/**
* @brief 定义Gallery在一个pannel下面显示的图标行数
*/
enum DisplayRow
{
DisplayOneRow = 1, ///< 显示1行默认
DisplayTwoRow = 2,
DisplayThreeRow = 3
};
SARibbonGalleryGroup(QWidget* w = 0);
virtual ~SARibbonGalleryGroup();
// 重新计算grid尺寸
void setRecalcGridSizeBlock(bool on = true);
bool isRecalcGridSizeBlock() const;
void recalcGridSize();
void recalcGridSize(int galleryHeight);
// 设置显示的样式
void setGalleryGroupStyle(GalleryGroupStyle style);
GalleryGroupStyle galleryGroupStyle() const;
// 添加一个item
void addItem(const QString& text, const QIcon& icon);
void addItem(SARibbonGalleryItem* item);
// 以一个aciton作为item添加
void addActionItem(QAction* act);
void addActionItemList(const QList< QAction* >& acts);
// 构建一个model这个model的父类是SARibbonGalleryGroup如果要共享model需要手动处理model的父类
void setupGroupModel();
SARibbonGalleryGroupModel* groupModel();
// 标题
void setGroupTitle(const QString& title);
QString groupTitle() const;
void selectByIndex(int i);
// 设置显示的行数
void setDisplayRow(DisplayRow r);
DisplayRow displayRow() const;
// 设置grid最小的宽度默认为0不限制可以限定grid的宽度
void setGridMinimumWidth(int w);
int gridMinimumWidth() const;
// 设置grid最大的宽度默认为0不限制可以限定grid的宽度
void setGridMaximumWidth(int w);
int gridMaximumWidth() const;
// 获取SARibbonGalleryGroup管理的actiongroup
QActionGroup* actionGroup() const;
private Q_SLOTS:
void onItemClicked(const QModelIndex& index);
void onItemEntered(const QModelIndex& index);
Q_SIGNALS:
void groupTitleChanged(const QString& title);
/**
* @brief 等同QActionGroup的triggered
* 所有加入SARibbonGalleryGroup的action都会被一个QActionGroup管理,可以通过@sa getActionGroup 获取到对应的actiongroup
* @param action
*/
void triggered(QAction* action);
/**
* @brief 等同QActionGroup的triggered
* 所有加入SARibbonGalleryGroup的action都会被一个QActionGroup管理,可以通过@sa getActionGroup 获取到对应的actiongroup
* @note 此属性需要通过QAbstractItemView::entered(const QModelIndex &index)激活因此要保证设置了setMouseTracking(true)
* @param action
*/
void hovered(QAction* action);
};
#endif // SARIBBONGALLERYGROUP_H
/*** End of inlined file: SARibbonGalleryGroup.h ***/
/*** Start of inlined file: SARibbonGallery.h ***/
#ifndef SARIBBONGALLERY_H
#define SARIBBONGALLERY_H
#include <QFrame>
#include <QToolButton>
#include <QSizeGrip>
class QLabel;
class QVBoxLayout;
class SARibbonGalleryViewport;
/**
* @brief 针对SARibbonGallery控件的按钮
*/
class SA_RIBBON_EXPORT SARibbonGalleryButton : public QToolButton
{
Q_OBJECT
public:
SARibbonGalleryButton(QWidget* parent = 0);
};
/**
* @brief Gallery控件
*
* Gallery控件是由一个当前激活的@sa SARibbonGalleryGroup 和弹出的 @sa SARibbonGalleryViewport 组成
*
* @sa SARibbonGalleryGroup 是继承@sa QListView actions通过icon展示出来相关的属性可以按照QListView设置
*
* @sa SARibbonGalleryViewport 是一个内部有垂直布局的窗体在弹出激活时把管理的SARibbonGalleryGroup都展示出来
*
* 示例如下:
* @code
* SARibbonGallery* gallery = pannel1->addGallery();
* QList< QAction* > galleryActions;
* ...create many actions ...
* SARibbonGalleryGroup* group1 = gallery->addCategoryActions(tr("Files"), galleryActions);
* galleryActions.clear();
* ...create many actions ...
* gallery->addCategoryActions(tr("Apps"), galleryActions);
* gallery->setCurrentViewGroup(group1);
* @endcode
*/
class SA_RIBBON_EXPORT SARibbonGallery : public QFrame
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonGallery)
public:
SARibbonGallery(QWidget* parent = 0);
virtual ~SARibbonGallery();
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
// 添加一个GalleryGroup
SARibbonGalleryGroup* addGalleryGroup();
// 添加一个GalleryGroup
void addGalleryGroup(SARibbonGalleryGroup* group);
// 快速添加一组actions
SARibbonGalleryGroup* addCategoryActions(const QString& title, QList< QAction* > actions);
// 设置当前显示的SARibbonGalleryGroup
void setCurrentViewGroup(SARibbonGalleryGroup* group);
// 获取当前显示的SARibbonGalleryGroup
SARibbonGalleryGroup* currentViewGroup() const;
// 获取弹出窗口指针
SARibbonGalleryViewport* getPopupViewPort() const;
public:
// 设置最右边三个控制按钮的最大宽度默认15
static void setGalleryButtonMaximumWidth(int w);
Q_SIGNALS:
/**
* @brief 转发管理的SARibbonGalleryGroup::triggered
* 所有加入SARibbonGallery的action都会被一个QActionGroup管理,可以通过@sa getActionGroup 获取到对应的actiongroup
* @param action
*/
void triggered(QAction* action);
/**
* @brief 转发管理的SARibbonGalleryGroup::hovered
* @note 此属性需要确保SARibbonGalleryGroup::setMouseTracking(true)
* @param action
*/
void hovered(QAction* action);
public Q_SLOTS:
// 上翻页
virtual void pageUp();
// 下翻页
virtual void pageDown();
// 显示更多触发默认弹出内部管理的SARibbonGalleryViewport用户可重载此函数实现自定义的弹出
virtual void showMoreDetail();
protected Q_SLOTS:
void onItemClicked(const QModelIndex& index);
virtual void onTriggered(QAction* action);
private:
SARibbonGalleryViewport* ensureGetPopupViewPort();
protected:
void resizeEvent(QResizeEvent* event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
};
///
/// \brief SARibbonGallery的Viewport class
///
class SARibbonGalleryViewport : public QWidget
{
Q_OBJECT
public:
SARibbonGalleryViewport(QWidget* parent);
// 添加窗口不带标题
void addWidget(QWidget* w);
// 添加窗口,带标题
void addWidget(QWidget* w, const QString& title);
// 通过SARibbonGalleryGroup获取对应的标题用户可以通过此函数设置QLabel的属性
QLabel* titleLabel(QWidget* w);
// 移除窗口
void removeWidget(QWidget* w);
public Q_SLOTS:
void onTitleChanged(QWidget* w, const QString& title);
private:
QVBoxLayout* m_layout;
QMap< QWidget*, QLabel* > _widgetToTitleLable; ///< QWidget和lable的对应
};
#endif // SARIBBONGALLERY_H
/*** End of inlined file: SARibbonGallery.h ***/
/*** Start of inlined file: SARibbonBar.h ***/
#ifndef SARIBBONBAR_H
#define SARIBBONBAR_H
#include <QMenuBar>
#include <QScopedPointer>
#include <QVariant>
class QAction;
class QAbstractButton;
class SARibbonElementFactory;
class SARibbonTabBar;
class SARibbonButtonGroupWidget;
class SARibbonQuickAccessBar;
class SARibbonStackedWidget;
/**
@brief SARibbonBar继承于QMenuBar,在SARibbonMainWindow中直接替换了原来的QMenuBar
通过setRibbonStyle函数设置ribbon的风格:
@code
void setRibbonStyle(RibbonStyles v);
@endcode
SARibbonBar参考office和wps提供了四种风格的Ribbon模式,@ref SARibbonBar::RibbonStyles
如果想ribbon占用的空间足够小WpsLiteStyleTwoRow模式能比OfficeStyle节省35%的高度空间
如何生成ribbon?先看看一个传统的Menu/ToolBar是如何生成的
@code
void MainWindow::MainWindow()
{
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
QToolBar *fileToolBar = addToolBar(tr("File"));
//生成action
QAction *newAct = new QAction(newIcon, tr("&New"), this);
fileMenu->addAction(newAct);
fileToolBar->addAction(newAct);
QAction *openAct = new QAction(openIcon, tr("&Open..."), this);
fileMenu->addAction(openAct);
fileToolBar->addAction(openAct);
}
@endcode
传统的Menu/ToolBar主要通过QMenu的addMenu添加菜单,通过QMainWindow::addToolBar生成QToolBar,
再把QAction设置进QMenu和QToolBar中
SARibbonBar和传统方法相似不过相对于传统的Menu/ToolBar QMenu和QToolBar是平级的
Ribbon是有明显的层级关系SARibbonBar下面是 @ref SARibbonCategory
SARibbonCategory下面是@ref SARibbonPannel SARibbonPannel下面是@ref SARibbonToolButton
SARibbonToolButton管理着QAction
因此生成一个ribbon只需以下几个函数
@code
SARibbonCategory * SARibbonBar::addCategoryPage(const QString& title);
SARibbonPannel * SARibbonCategory::addPannel(const QString& title);
SARibbonToolButton * SARibbonPannel::addLargeAction(QAction *action);
SARibbonToolButton * SARibbonPannel::addSmallAction(QAction *action);
@endcode
因此生成步骤如下:
@code
//成员变量
SARibbonCategory* categoryMain;
SARibbonPannel* FilePannel;
//建立ui
void setupRibbonUi()
{
......
//ribbonwindow为SARibbonMainWindow
SARibbonBar* ribbon = ribbonwindow->ribbonBar();
ribbon->setRibbonStyle(SARibbonBar::WpsLiteStyle);
//添加一个Main标签
categoryMain = ribbon->addCategoryPage(QStringLiteral("Main"));
//Main标签下添加一个File Pannel
FilePannel = categoryMain->addPannel(QStringLiteral("FilePannel"));
//开始为File Pannel添加action
FilePannel->addLargeAction(actionNew);
FilePannel->addLargeAction(actionOpen);
FilePannel->addLargeAction(actionSave);
FilePannel->addSmallAction(actionImportMesh);
FilePannel->addSmallAction(actionImportGeometry);
}
@endcode
*/
class SA_RIBBON_EXPORT SARibbonBar : public QMenuBar
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonBar)
friend class SARibbonMainWindow;
friend class SARibbonSystemButtonBar;
Q_PROPERTY(RibbonStyles ribbonStyle READ currentRibbonStyle WRITE setRibbonStyle)
Q_PROPERTY(bool minimumMode READ isMinimumMode WRITE setMinimumMode)
Q_PROPERTY(bool minimumModeButton READ haveShowMinimumModeButton WRITE showMinimumModeButton)
Q_PROPERTY(QColor windowTitleTextColor READ windowTitleTextColor WRITE setWindowTitleTextColor)
Q_PROPERTY(QColor tabBarBaseLineColor READ tabBarBaseLineColor WRITE setTabBarBaseLineColor)
Q_PROPERTY(Qt::Alignment windowTitleAligment READ windowTitleAligment WRITE setWindowTitleAligment)
Q_PROPERTY(bool enableWordWrap READ isEnableWordWrap WRITE setEnableWordWrap)
Q_PROPERTY(bool enableShowPannelTitle READ isEnableShowPannelTitle WRITE setEnableShowPannelTitle)
Q_PROPERTY(bool tabOnTitle READ isTabOnTitle WRITE setTabOnTitle)
Q_PROPERTY(SARibbonPannel::PannelLayoutMode pannelLayoutMode READ pannelLayoutMode WRITE setPannelLayoutMode)
public:
enum RibbonStyleFlag
{
RibbonStyleLoose = 0x0001, // bit:0000 0001
RibbonStyleCompact = 0x0002, // bit:0000 0010
RibbonStyleThreeRow = 0x0010, // bit:0001 0000
RibbonStyleTwoRow = 0x0020, // bit:0010 0000
RibbonStyleLooseThreeRow = RibbonStyleLoose | RibbonStyleThreeRow, ///< 宽松结构3行模式
RibbonStyleCompactThreeRow = RibbonStyleCompact | RibbonStyleThreeRow, ///< 紧凑结构3行模式
RibbonStyleLooseTwoRow = RibbonStyleLoose | RibbonStyleTwoRow, ///< 宽松结构2行模式
RibbonStyleCompactTwoRow = RibbonStyleCompact | RibbonStyleTwoRow ///< 紧凑结构2行模式
};
Q_ENUM(RibbonStyleFlag)
Q_DECLARE_FLAGS(RibbonStyles, RibbonStyleFlag)
Q_FLAG(RibbonStyles)
/**
* @brief 定义当前ribbon 的状态
*/
enum RibbonMode
{
MinimumRibbonMode, ///< 缩小模式
NormalRibbonMode ///< 正常模式
};
Q_ENUM(RibbonMode)
using FpCategoryIterate = std::function< bool(SARibbonCategory*) >;
using FpPannelIterate = SARibbonCategory::FpPannelIterate;
public:
// 判断RibbonStyle是否为2行模式
static bool isTwoRowStyle(RibbonStyles s);
static bool isThreeRowStyle(RibbonStyles s);
// 判断是否是office样式
static bool isLooseStyle(RibbonStyles s);
static bool isCompactStyle(RibbonStyles s);
// 获取版本信息
static QString versionString();
// 获取默认的上下文标签颜色列表
static QList< QColor > defaultContextCategoryColorList();
//
static void initHighDpi();
public:
// 构造函数
SARibbonBar(QWidget* parent = nullptr);
~SARibbonBar() Q_DECL_OVERRIDE;
// 获取applicationButton
QAbstractButton* applicationButton();
// 设置applicationButton
void setApplicationButton(QAbstractButton* btn);
// 获取tabbar
SARibbonTabBar* ribbonTabBar();
// 添加一个标签
SARibbonCategory* addCategoryPage(const QString& title);
void addCategoryPage(SARibbonCategory* category);
// 为了支持Qt designer,添加的一个重载函数
Q_INVOKABLE void addCategoryPage(QWidget* category);
// 添加一个categorycategory的位置在index如果当前category数量少于index将插入到最后
SARibbonCategory* insertCategoryPage(const QString& title, int index);
void insertCategoryPage(SARibbonCategory* category, int index);
// 通过名字查找Category
SARibbonCategory* categoryByName(const QString& title) const;
// 通过ObjectName查找Category
SARibbonCategory* categoryByObjectName(const QString& objname) const;
// 通过索引找到category如果超过索引范围会返回nullptr
SARibbonCategory* categoryByIndex(int index) const;
// 隐藏category,并不会删除或者取走,只是隐藏
void hideCategory(SARibbonCategory* category);
// 显示被隐藏的category
void showCategory(SARibbonCategory* category);
// 判断这个category是否在显示状态也就是tabbar有这个category
bool isCategoryVisible(const SARibbonCategory* c) const;
// 获取category的索引
int categoryIndex(const SARibbonCategory* c) const;
// 移动一个Category从from index到to index
void moveCategory(int from, int to);
// 获取当前显示的所有的SARibbonCategory包含未显示的SARibbonContextCategory的SARibbonCategory也一并返回
QList< SARibbonCategory* > categoryPages(bool getAll = true) const;
// 移除SARibbonCategory
void removeCategory(SARibbonCategory* category);
// 添加一个上下文标签
SARibbonContextCategory*
addContextCategory(const QString& title, const QColor& color = QColor(), const QVariant& id = QVariant());
void addContextCategory(SARibbonContextCategory* context);
// 显示一个上下文标签
void showContextCategory(SARibbonContextCategory* context);
// 隐藏一个上下文标签
void hideContextCategory(SARibbonContextCategory* context);
// 判断上下文是否是在显示状态
bool isContextCategoryVisible(SARibbonContextCategory* context);
// 设置上下文标签的显示或隐藏
void setContextCategoryVisible(SARibbonContextCategory* context, bool visible);
// 获取所有的上下文标签
QList< SARibbonContextCategory* > contextCategoryList() const;
// 移除ContextCategory
void destroyContextCategory(SARibbonContextCategory* context);
// 设置为隐藏模式
void setMinimumMode(bool isHide);
// 当前Ribbon是否是隐藏模式
bool isMinimumMode() const;
// 设置显示隐藏ribbon按钮
void showMinimumModeButton(bool isShow = true);
// 是否显示隐藏ribbon按钮
bool haveShowMinimumModeButton() const;
// 隐藏ribbon对应的action
QAction* minimumModeAction() const;
// 当前的模式
RibbonMode currentRibbonState() const;
// ribbon tab的高度
int tabBarHeight() const;
void setTabBarHeight(int h, bool resizeByNow = true);
// 标题栏的高度
int titleBarHeight() const;
void setTitleBarHeight(int h, bool resizeByNow = true);
// category的高度
int categoryHeight() const;
void setCategoryHeight(int h, bool resizeByNow = true);
// 获取正常模式下的mainBar的高度
int normalModeMainBarHeight() const;
// 最小模式下的MainBar高度
int minimumModeMainBarHeight() const;
// 激活tabbar右边的按钮群
SARibbonButtonGroupWidget* activeRightButtonGroup();
// 右侧按钮群
SARibbonButtonGroupWidget* rightButtonGroup();
// 激活QuickAccessBar
SARibbonQuickAccessBar* activeQuickAccessBar();
// 快速响应栏
SARibbonQuickAccessBar* quickAccessBar();
// 设置ribbon的风格
void setRibbonStyle(RibbonStyles v);
RibbonStyles currentRibbonStyle() const;
// 设置当前ribbon的index
void setCurrentIndex(int index);
// 返回当前的tab索引
int currentIndex();
// 确保标签显示出来
void raiseCategory(SARibbonCategory* category);
// 判断当前的行数
bool isTwoRowStyle() const;
bool isThreeRowStyle() const;
// 判断当前的样式
bool isLooseStyle() const;
bool isCompactStyle() const;
// 更新ribbon的布局数据此函数适用于一些关键性尺寸变化换起ribbon下面元素的布局,在发现刷新问题时,可以调用此函数
void updateRibbonGeometry();
// 设置pannel的模式
SARibbonPannel::PannelLayoutMode pannelLayoutMode() const;
void setPannelLayoutMode(SARibbonPannel::PannelLayoutMode m);
// 设置tab在title上面这样可以省略title区域
void setTabOnTitle(bool on);
bool isTabOnTitle() const;
// tabbar 底部会绘制一条线条,此接口定义线条颜色
void setTabBarBaseLineColor(const QColor& clr);
QColor tabBarBaseLineColor() const;
// 设置标题颜色,如果不设置标题颜色默认是SARibbonBar的qss的color属性
void setWindowTitleTextColor(const QColor& clr);
QColor windowTitleTextColor() const;
// 设置标题的对齐方式
void setWindowTitleAligment(Qt::Alignment al);
Qt::Alignment windowTitleAligment() const;
// 设置按钮允许换行,注意图标大小是由文字决定的,两行文字会让图标变小,如果想图标变大,文字不换行是最好的
void setEnableWordWrap(bool on);
bool isEnableWordWrap() const;
// 设置pannel的标题栏高度
int pannelTitleHeight() const;
void setPannelTitleHeight(int h);
// 设置pannel是否显示标题栏
bool isEnableShowPannelTitle() const;
void setEnableShowPannelTitle(bool on);
// 设置pannel的spacing
void setPannelSpacing(int n);
int pannelSpacing() const;
// 设置pannel按钮的icon尺寸large action不受此尺寸影响
void setPannelToolButtonIconSize(const QSize& s);
QSize pannelToolButtonIconSize() const;
// 获取SARibbonStackedWidget谨慎使用此函数
SARibbonStackedWidget* ribbonStackedWidget();
// 设置是否显示标题
void setTitleVisible(bool on = false);
bool isTitleVisible() const;
// 上下文标签的颜色列表,上下文标签显示的时候,会从颜色列表中取颜色进行标签的渲染
void setContextCategoryColorList(const QList< QColor >& cls);
QList< QColor > contextCategoryColorList() const;
// 设置context category 标题的文字颜色
void setContextCategoryTitleTextColor(const QColor& clr);
QColor contextCategoryTitleTextColor() const;
// 设置ribbon的对齐方式
void setRibbonAlignment(SARibbonAlignment al);
SARibbonAlignment ribbonAlignment() const;
// 此函数会遍历SARibbonBar下的所有Category执行函数指针(bool(SARibbonCategory*))函数指针返回false则停止迭代
bool iterate(FpCategoryIterate fp);
// 此函数会遍历SARibbonBar下的所有Category,并迭代所有的pannel执行函数指针(bool(SARibbonPannel*))函数指针返回false则停止迭代
bool iterate(FpPannelIterate fp);
// 设置边角widget可见性对于mdi窗口会出现TopLeftCorner和TopRightCorner两个corner widget
void setCornerWidgetVisible(bool on, Qt::Corner c = Qt::TopLeftCorner);
Q_SIGNALS:
/**
@brief 应用按钮点击响应 - 左上角的按钮,通过关联此信号触发应用按钮点击的效果
例如想点击按钮后弹出一个全屏的窗口如office这些
*/
void applicationButtonClicked();
/**
@brief 标签页变化触发的信号
@param index
*/
void currentRibbonTabChanged(int index);
/**
@brief ribbon的状态发生了变化后触发此信号
@param nowState 变更之后的ribbon状态
*/
void ribbonModeChanged(SARibbonBar::RibbonMode nowState);
/**
@brief ribbon的状态发生了变化后触发此信号
@param nowStyle 变更之后的ribbon样式
*/
void ribbonStyleChanged(SARibbonBar::RibbonStyles nowStyle);
/**
@brief 标题栏高度发生了变化的信号
@param oldHeight
@param newHeight
*/
void titleBarHeightChanged(int oldHeight, int newHeight);
/**
* @brief 参考QToolBar::actionTriggered的信号
* @param action
*/
void actionTriggered(QAction* action);
protected:
bool eventFilter(QObject* obj, QEvent* e) override;
// 根据情况重置tabbar的宽度主要针对wps模式
int calcMinTabBarWidth() const;
// 更新
void updateCategoryTitleToTabName();
// 告知WindowButtonGroup的尺寸
void setWindowButtonGroupSize(const QSize& s);
protected Q_SLOTS:
void onWindowTitleChanged(const QString& title);
void onWindowIconChanged(const QIcon& i);
void onCategoryWindowTitleChanged(const QString& title);
void onStackWidgetHided();
virtual void onCurrentRibbonTabChanged(int index);
virtual void onCurrentRibbonTabClicked(int index);
virtual void onCurrentRibbonTabDoubleClicked(int index);
void onContextsCategoryPageAdded(SARibbonCategory* category);
void onContextsCategoryCategoryNameChanged(SARibbonCategory* category, const QString& title);
void onTabMoved(int from, int to);
private:
int tabIndex(SARibbonCategory* obj);
void resizeAll();
void resizeInLooseStyle();
void resizeInCompactStyle();
void paintInLooseStyle();
void paintInCompactStyle();
void resizeStackedContainerWidget();
// 刷新所有ContextCategoryManagerData这个在单独一个Category删除时调用
void updateContextCategoryManagerData();
void synchronousCategoryData(bool autoUpdate = true);
protected:
virtual void paintEvent(QPaintEvent* e) Q_DECL_OVERRIDE;
virtual void resizeEvent(QResizeEvent* e) Q_DECL_OVERRIDE;
virtual void moveEvent(QMoveEvent* e) Q_DECL_OVERRIDE;
virtual void changeEvent(QEvent* e) Q_DECL_OVERRIDE;
virtual bool event(QEvent* e) Q_DECL_OVERRIDE;
virtual void paintTabbarBaseLine(QPainter& painter);
virtual void paintWindowTitle(QPainter& painter, const QString& title, const QRect& titleRegion);
virtual void
paintContextCategoryTab(QPainter& painter, const QString& title, const QRect& contextRect, const QColor& color);
#if SA_DEBUG_PRINT_SARIBBONBAR
SA_RIBBON_EXPORT friend QDebug operator<<(QDebug debug, const SARibbonBar& ribbon);
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS(SARibbonBar::RibbonStyles)
#endif // SARIBBONBAR_H
/*** End of inlined file: SARibbonBar.h ***/
/*** Start of inlined file: SARibbonElementFactory.h ***/
#ifndef SARIBBONELEMENTFACTORY_H
#define SARIBBONELEMENTFACTORY_H
#include <QColor>
#include <QMargins>
#include <QSize>
#include <QScopedPointer>
class QWidget;
class SARibbonBar;
class SARibbonTabBar;
class SARibbonApplicationButton;
class SARibbonCategory;
class SARibbonContextCategory;
class SARibbonPannel;
class SARibbonSeparatorWidget;
class SARibbonGallery;
class SARibbonGalleryGroup;
class SARibbonToolButton;
class SARibbonControlButton;
class SARibbonControlToolButton;
class SARibbonButtonGroupWidget;
class SARibbonStackedWidget;
class SARibbonQuickAccessBar;
class SARibbonPannelOptionButton;
class SARibbonSystemButtonBar;
///
/// \brief SARibbon的子元素创建的工厂SARibbon内部创建子元素都通过SARibbonElementFactory来创建
///
/// 由于SARibbonBar是一个复合控件很多子窗口组合而成有些部件的创建如果想继承那么就需要这个工厂类来处理
/// 如SARibbonCategory可以重载此类的createRibbonCategory,返回重载的类的实例
///
class SA_RIBBON_EXPORT SARibbonElementFactory
{
public:
SARibbonElementFactory();
virtual ~SARibbonElementFactory();
virtual SARibbonBar* createRibbonBar(QWidget* parent);
virtual SARibbonTabBar* createRibbonTabBar(QWidget* parent);
virtual SARibbonApplicationButton* createRibbonApplicationButton(QWidget* parent);
virtual SARibbonCategory* createRibbonCategory(QWidget* parent);
virtual SARibbonContextCategory* createRibbonContextCategory(QWidget* parent);
virtual SARibbonPannel* createRibbonPannel(QWidget* parent);
virtual SARibbonSeparatorWidget* createRibbonSeparatorWidget(QWidget* parent);
virtual SARibbonGallery* createRibbonGallery(QWidget* parent);
virtual SARibbonGalleryGroup* createRibbonGalleryGroup(QWidget* parent);
virtual SARibbonToolButton* createRibbonToolButton(QWidget* parent);
virtual SARibbonControlButton* createRibbonControlButton(QWidget* parent);
virtual SARibbonControlToolButton* createRibbonControlToolButton(QWidget* parent);
virtual SARibbonStackedWidget* createRibbonStackedWidget(SARibbonBar* parent);
virtual SARibbonButtonGroupWidget* craeteButtonGroupWidget(QWidget* parent);
virtual SARibbonQuickAccessBar* createQuickAccessBar(QWidget* parent);
virtual SARibbonSystemButtonBar* createWindowButtonGroup(QWidget* parent);
virtual SARibbonPannelOptionButton* createRibbonPannelOptionButton(SARibbonPannel* pannel);
};
#endif // SARIBBONELEMENTFACTORY_H
/*** End of inlined file: SARibbonElementFactory.h ***/
/*** Start of inlined file: SARibbonElementManager.h ***/
#ifndef SARIBBONELEMENTMANAGER_H
#define SARIBBONELEMENTMANAGER_H
/**
@brief 此类是一个全局单例用于管理SARibbonElementFactory
如果你有自己的某个部件要重写首先你需要有自己的ElementFactory
@code
class MyRibbonElementFactory : public SARibbonElementFactory{
public:
...
virtual SARibbonPannel* createRibbonPannel(QWidget* parent){
return new MyRibbonPannel(parent);
}
};
@endcode
然后你需要在ribbonbar创建之前把自己的ElementFactory设置进去
这个一般会在main函数中进行
@code
SARibbonElementManager::instance()->setupFactory(new MyRibbonElementFactory);
@endcode
这样SARibbon创建的pannel就是你自己重写的MyRibbonPannel
*/
class SA_RIBBON_EXPORT SARibbonElementManager
{
protected:
SARibbonElementManager();
public:
virtual ~SARibbonElementManager();
static SARibbonElementManager* instance();
SARibbonElementFactory* factory();
void setupFactory(SARibbonElementFactory* fac);
private:
QScopedPointer< SARibbonElementFactory > mFactory;
};
#ifndef RibbonSubElementMgr
#define RibbonSubElementMgr SARibbonElementManager::instance()
#endif
#ifndef RibbonSubElementFactory
#define RibbonSubElementFactory SARibbonElementManager::instance()->factory()
#endif
#endif // SARIBBONELEMENTMANAGER_H
/*** End of inlined file: SARibbonElementManager.h ***/
/*** Start of inlined file: SARibbonCustomizeData.h ***/
#ifndef SARIBBONCUSTOMIZEDATA_H
#define SARIBBONCUSTOMIZEDATA_H
#include <QList>
class SARibbonBar;
class SARibbonMainWindow;
/**
* @brief 记录所有自定义操作的数据类
* @note 此数据依赖于@ref SARibbonActionsManager 要在SARibbonActionsManager之后使用此类
*/
class SA_RIBBON_EXPORT SARibbonCustomizeData
{
public:
enum ActionType
{
UnknowActionType = 0, ///< 未知操作
AddCategoryActionType, ///< 添加category操作(1)
AddPannelActionType, ///< 添加pannel操作(2)
AddActionActionType, ///< 添加action操作(3)
RemoveCategoryActionType, ///< 删除category操作(4)
RemovePannelActionType, ///< 删除pannel操作(5)
RemoveActionActionType, ///< 删除action操作(6)
ChangeCategoryOrderActionType, ///< 改变category顺序的操作(7)
ChangePannelOrderActionType, ///< 改变pannel顺序的操作(8)
ChangeActionOrderActionType, ///< 改变action顺序的操作(9)
RenameCategoryActionType, ///< 对category更名操作(10)
RenamePannelActionType, ///< 对Pannel更名操作(11)
VisibleCategoryActionType ///< 对category执行隐藏/显示操作(12)
};
SARibbonCustomizeData();
SARibbonCustomizeData(ActionType type, SARibbonActionsManager* mgr = nullptr);
// 获取CustomizeData的action type
ActionType actionType() const;
// 设置CustomizeData的action type
void setActionType(ActionType a);
// 判断是否是一个正常的CustomizeData
bool isValid() const;
// 应用SARibbonCustomizeData
bool apply(SARibbonBar* bar) const;
// 获取actionmanager指针
SARibbonActionsManager* actionManager();
// 设置ActionsManager
void setActionsManager(SARibbonActionsManager* mgr);
// 对应AddCategoryActionType
static SARibbonCustomizeData makeAddCategoryCustomizeData(const QString& title, int index, const QString& objName);
// 对应AddPannelActionType
static SARibbonCustomizeData
makeAddPannelCustomizeData(const QString& title, int index, const QString& categoryobjName, const QString& objName);
// 对应AddActionActionType
static SARibbonCustomizeData makeAddActionCustomizeData(const QString& key,
SARibbonActionsManager* mgr,
SARibbonPannelItem::RowProportion rp,
const QString& categoryObjName,
const QString& pannelObjName);
// 对应RenameCategoryActionType
static SARibbonCustomizeData makeRenameCategoryCustomizeData(const QString& newname, const QString& categoryobjName);
// 对应RenamePannelActionType
static SARibbonCustomizeData
makeRenamePannelCustomizeData(const QString& newname, const QString& categoryobjName, const QString& pannelObjName);
// 对应RemoveCategoryActionType
static SARibbonCustomizeData makeRemoveCategoryCustomizeData(const QString& categoryobjName);
// 对应ChangeCategoryOrderActionType
static SARibbonCustomizeData makeChangeCategoryOrderCustomizeData(const QString& categoryobjName, int moveindex);
// 对应ChangePannelOrderActionType
static SARibbonCustomizeData
makeChangePannelOrderCustomizeData(const QString& categoryobjName, const QString& pannelObjName, int moveindex);
// 对应ChangeActionOrderActionType
static SARibbonCustomizeData makeChangeActionOrderCustomizeData(const QString& categoryobjName,
const QString& pannelObjName,
const QString& key,
SARibbonActionsManager* mgr,
int moveindex);
// 对应RemovePannelActionType
static SARibbonCustomizeData makeRemovePannelCustomizeData(const QString& categoryobjName, const QString& pannelObjName);
// 对应RemoveActionActionType
static SARibbonCustomizeData makeRemoveActionCustomizeData(const QString& categoryobjName,
const QString& pannelObjName,
const QString& key,
SARibbonActionsManager* mgr);
// 对应VisibleCategoryActionType
static SARibbonCustomizeData makeVisibleCategoryCustomizeData(const QString& categoryobjName, bool isShow);
// 判断是否可以自定义,如果某个action不想被编辑可以通过此函数设置
static bool isCanCustomize(QObject* obj);
static void setCanCustomize(QObject* obj, bool canbe = true);
// 对QList<SARibbonCustomizeData>进行简化
static QList< SARibbonCustomizeData > simplify(const QList< SARibbonCustomizeData >& csd);
public:
/**
* @brief 记录顺序的参数
*
* 在actionType==AddCategoryActionType时此参数记录Category的insert位置,
* 在actionType==AddPannelActionType时此参数记录pannel的insert位置,
* 在actionType==AddActionActionType时此参数记录pannel的insert位置
*/
int indexValue;
/**
* @brief 记录标题、索引等参数
*
* 在actionType==AddCategoryActionType时key为category标题
* 在actionType==AddPannelActionType时key为pannel标题
* 在actionType==AddActionActionType时key为action的查询依据基于SARibbonActionsManager::action查询
*/
QString keyValue;
/**
* @brief 记录categoryObjName用于定位Category
*/
QString categoryObjNameValue;
/**
* @brief 记录pannelObjNamesaribbon的Customize索引大部分基于objname
*/
QString pannelObjNameValue;
SARibbonPannelItem::RowProportion actionRowProportionValue; ///< 行的占比ribbon中有largemedia和small三种占比,见@ref RowProportion
private:
ActionType mType; ///< 标记这个data是category还是pannel亦或是action
SARibbonActionsManager* mActionsManagerPointer;
};
Q_DECLARE_METATYPE(SARibbonCustomizeData)
typedef QList< SARibbonCustomizeData > SARibbonCustomizeDataList;
#endif // SARIBBONCUSTOMIZEDATA_H
/*** End of inlined file: SARibbonCustomizeData.h ***/
/*** Start of inlined file: SARibbonCustomizeWidget.h ***/
#ifndef SARIBBONCUSTOMIZEWIDGET_H
#define SARIBBONCUSTOMIZEWIDGET_H
#include <QWidget>
// SARibbonCustomizeWidget 特有
class SARibbonCustomizeWidgetUi;
class SARibbonMainWindow;
class SARibbonBar;
//
class QStandardItemModel;
class QStandardItem;
class QAbstractButton;
//
class QXmlStreamWriter;
class QXmlStreamReader;
/**
* @brief 自定义界面窗口
*
* @note SARibbon的自定义是基于步骤的如果在窗口生成前调用了@ref sa_apply_customize_from_xml_file 类似函数
* 那么在对话框生成前为了保证同步需要调用@ref SARibbonCustomizeWidget::fromXml 同步配置文件,这样再次修改后的配置文件就一致
*/
class SA_RIBBON_EXPORT SARibbonCustomizeWidget : public QWidget
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonCustomizeWidget)
public:
// 保留接口
SARibbonCustomizeWidget(SARibbonMainWindow* ribbonWindow,
QWidget* parent = nullptr,
Qt::WindowFlags f = Qt::WindowFlags());
// 对于不使用SARibbonMainWindow的情况使用此构造函数
SARibbonCustomizeWidget(SARibbonBar* ribbonbar, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
~SARibbonCustomizeWidget();
/**
* @brief 定义ribbon树的显示类型
*/
enum RibbonTreeShowType
{
ShowAllCategory, ///< 显示所有Category包括contextcategory
ShowMainCategory ///< 显示主要的category不包含上下文
};
/**
* @brief QStandardItem对应的role
*/
enum ItemRole
{
LevelRole = Qt::UserRole + 1, ///< 代表这是层级有0category 1pannel 2item
PointerRole = Qt::UserRole + 2, ///< 代表这是存放指针。根据LevelRole来进行转
CanCustomizeRole = Qt::UserRole + 3, ///< 代表个item是可以自定义的.bool
CustomizeRole = Qt::UserRole + 4, ///< 代表这个是自定义的item,bool,主要用于那些自己添加的标签和pannel有此角色必有CanCustomizeRole
CustomizeObjNameRole = Qt::UserRole + 5 ///< 记录了临时的自定义内容的obj名 QString
};
// 设置action管理器
void setupActionsManager(SARibbonActionsManager* mgr);
// 判断用户是否有要存储的内容对应save动作
bool isApplied() const;
// 判断用户是否有改动内容对应apply动作
bool isCached() const;
// 获取model
const QStandardItemModel* model() const;
// 根据当前的radiobutton选项来更新model
void updateModel();
// 更新model
void updateModel(RibbonTreeShowType type);
// 应用所有的设定
bool applys();
// 转换为xml
bool toXml(QXmlStreamWriter* xml) const;
bool toXml(const QString& xmlpath) const;
// 从xml中加载QList<SARibbonCustomizeData>,对于基于配置文件的设置,对话框显示前建议调用此函数,保证叠加设置的正确记录
void fromXml(QXmlStreamReader* xml);
void fromXml(const QString& xmlpath);
// 应用xml配置可以结合customize_datas_from_xml和customize_datas_apply函数
static bool fromXml(QXmlStreamReader* xml, SARibbonBar* bar, SARibbonActionsManager* mgr);
// 缓存应用的动作,这些动作不会被clear清除用于本地存储
void makeActionsApplied();
// 清除applied的动作cancel操作后需要清空已应用的动作
void clearApplied();
// 清除缓存动作在执行applys函数后如果要继续调用应该clear否则会导致异常
void clearCache();
// 清除所有动作,不包含本地读取的数据
void clear();
protected:
// 把QList<SARibbonCustomizeData>进行裁剪,把一些动作合并
void simplify();
SARibbonPannelItem::RowProportion selectedRowProportion() const;
QAction* selectedAction() const;
QAction* itemToAction(QStandardItem* item) const;
QStandardItem* selectedItem() const;
// 获取选中的ribbon tree 的level
int selectedRibbonLevel() const;
// 根据选中的item判断
int itemLevel(QStandardItem* item) const;
// 设置某个item被选中
void setSelectItem(QStandardItem* item, bool ensureVisible = true);
// 判断itemn能否改动可以改动返回true
bool isItemCanCustomize(QStandardItem* item) const;
bool isSelectedItemCanCustomize() const;
// 判断item是否是自定义的item
bool isCustomizeItem(QStandardItem* item) const;
bool isSelectedItemIsCustomize() const;
// 删除一个item
void removeItem(QStandardItem* item);
private Q_SLOTS:
void onComboBoxActionIndexCurrentIndexChanged(int index);
void onRadioButtonGroupButtonClicked(QAbstractButton* b);
void onPushButtonNewCategoryClicked();
void onPushButtonNewPannelClicked();
void onPushButtonRenameClicked();
void onPushButtonAddClicked();
void onPushButtonDeleteClicked();
void onListViewSelectClicked(const QModelIndex& index);
void onTreeViewResultClicked(const QModelIndex& index);
void onToolButtonUpClicked();
void onToolButtonDownClicked();
void onItemChanged(QStandardItem* item);
void onLineEditSearchActionTextEdited(const QString& text);
void onPushButtonResetClicked();
private:
void init(SARibbonBar* ribbonbar);
void initConnection();
private:
SARibbonCustomizeWidgetUi* ui;
};
/**
* @brief 转换为xml
*
* 此函数仅会写element不会写document相关内容因此如果需要写document
* 需要在此函数前调用QXmlStreamWriter::writeStartDocument(),在此函数后调用QXmlStreamWriter::writeEndDocument()
* @param xml QXmlStreamWriter指针
* @note 注意在传入QXmlStreamWriter之前需要设置编码为utf-8:xml->setCodec("utf-8");
* @note 由于QXmlStreamWriter在QString作为io时是不支持编码的而此又无法保证自定义过程不出现中文字符
* 因此QXmlStreamWriter不应该通过QString进行构造如果需要用到string也需要通过QByteArray构造
* @param cds 基于QList<SARibbonCustomizeData>生成的步骤
* @return 如果出现异常返回false,如果没有自定义数据也会返回false
*/
bool SA_RIBBON_EXPORT sa_customize_datas_to_xml(QXmlStreamWriter* xml, const QList< SARibbonCustomizeData >& cds);
/**
* @brief 通过xml获取QList<SARibbonCustomizeData>
* @param xml
* @return QList<SARibbonCustomizeData>
*/
QList< SARibbonCustomizeData > SA_RIBBON_EXPORT sa_customize_datas_from_xml(QXmlStreamReader* xml,
SARibbonActionsManager* mgr);
/**
* @brief 应用QList<SARibbonCustomizeData>
* @param cds
* @param w SARibbonBar指针
* @return 成功应用的个数
*/
int SA_RIBBON_EXPORT sa_customize_datas_apply(const QList< SARibbonCustomizeData >& cds, SARibbonBar* w);
/**
* @brief 反向取消应用
* @param cds
* @param w SARibbonBar指针
* @return 成功应用的个数
*/
int SA_RIBBON_EXPORT sa_customize_datas_reverse(const QList< SARibbonCustomizeData >& cds, SARibbonBar* w);
/**
* @brief 直接加载xml自定义ribbon配置文件用于ribbon的自定义显示
* @param filePath xml配置文件
* @param w 主窗体
* @param mgr action管理器
* @return 成功返回true
* @note 重复加载一个配置文件会发生异常,为了避免此类事件发生,一般通过一个变量保证只加载一次,如:
* @code
* static bool has_call = false;
* if (!has_call) {
* has_call = sa_apply_customize_from_xml_file("customize.xml", this, m_actMgr);
* }
* @endcode
*/
bool SA_RIBBON_EXPORT sa_apply_customize_from_xml_file(const QString& filePath, SARibbonBar* bar, SARibbonActionsManager* mgr);
#endif // SARIBBONCUSTOMIZEWIDGET_H
/*** End of inlined file: SARibbonCustomizeWidget.h ***/
/*** Start of inlined file: SARibbonCustomizeDialog.h ***/
#ifndef SARIBBONCUSTOMIZEDIALOG_H
#define SARIBBONCUSTOMIZEDIALOG_H
#include <QDialog>
class SARibbonActionsManager;
class SARibbonCustomizeDialogUi;
class QXmlStreamWriter;
/**
* @brief SARibbonCustomizeWidget的对话框封装
*
* 此功能依赖于@ref SARibbonActionsManager SARibbonActionsManager建议作为mianwindow的成员变量
* SARibbonActionsManager可以快速绑定所有QAction详细见SARibbonActionsManager的说明
*
* @note SARibbon的自定义是基于步骤的如果在窗口生成前调用了@ref sa_apply_customize_from_xml_file 类似函数
* 那么在对话框生成前为了保证同步需要调用@ref SARibbonCustomizeDialog::fromXml 同步配置文件,这样再次修改后的配置文件就一致
*/
class SA_RIBBON_EXPORT SARibbonCustomizeDialog : public QDialog
{
Q_OBJECT
public:
SARibbonCustomizeDialog(SARibbonMainWindow* ribbonWindow, QWidget* p = nullptr, Qt::WindowFlags f = Qt::WindowFlags());
// 设置action管理器
void setupActionsManager(SARibbonActionsManager* mgr);
// 判断用户是否有要存储的内容对应save动作
bool isApplied() const;
// 判断用户是否有改动内容对应apply动作
bool isCached() const;
// 应用所有的设定
bool applys();
// 清除所有动作
void clear();
// 转换为xml
bool toXml(QXmlStreamWriter* xml) const;
bool toXml(const QString& xmlpath) const;
// 从xml中加载QList<SARibbonCustomizeData>,对于基于配置文件的设置,对话框显示前建议调用此函数,保证叠加设置的正确记录
void fromXml(QXmlStreamReader* xml);
void fromXml(const QString& xmlpath);
// 返回SARibbonCustomizeWidget窗口指针
SARibbonCustomizeWidget* customizeWidget() const;
private:
void initConnection();
SARibbonCustomizeDialogUi* ui;
};
#endif // SARIBBONCUSTOMIZEDIALOG_H
/*** End of inlined file: SARibbonCustomizeDialog.h ***/
/*** Start of inlined file: SARibbonMainWindow.h ***/
#ifndef SARIBBONMAINWINDOW_H
#define SARIBBONMAINWINDOW_H
#include <QMainWindow>
#if !SARIBBON_USE_3RDPARTY_FRAMELESSHELPER
class SAFramelessHelper;
#endif
class QAction;
class SARibbonBar;
class SARibbonSystemButtonBar;
class QScreen;
/**
* @brief 如果要使用SARibbonBar必须使用此类代替QMainWindow
*
* 由于ribbon的风格和传统的Toolbar风格差异较大
* SARibbonBar使用需要把原有的QMainWindow替换为SARibbonMainWindow,
* SARibbonMainWindow是个无边框窗体继承自QMainWindow目前使用第三方的无边框方案https://github.com/wangwenx190/framelesshelper
* 其构造函数的参数useRibbon用于指定是否使用ribbon风格默认为true
*
* @code
* SARibbonMainWindow(QWidget* parent = nullptr,bool useRibbon = true);
* @endcode
*
* 如果想换回非ribbon风格只需要把useRibbon设置为false即可,
* 成员函数isUseRibbon用于判断当前是否为ribbon模式这个函数在兼容传统Toolbar风格和ribbon风格时非常有用
*
* 但这个不支持动态切换,因此,实际工程中,你若要进行切换,需要写配置文件,程序在构造时传入模式,
* 并且你的程序要做好判断因为非Ribbon模式下所有Ribbon相关的接口都会返回空指针
*
* @code
* bool isUseRibbon() const;
* @endcode
*
* @ref SARibbonMainWindow 提供了几种常用的ribbon样式
* 通过@ref setRibbonTheme 可改变ribbon的样式用户也可通过qss自己定义自己的样式
*
* 如果你自己继承了SARibbonBar你可以通过@ref setRibbonBar 设置自己的ribbonbar进去
*
* 另外有个一个更加高效的方法来实现自定义的Ribbon就是继承一个@ref SARibbonElementFactory
*
* @code
* class MyRibbonFactory:public SARibbonElementFactory{
* ...
* virtual SARibbonBar* createRibbonBar(QWidget* parent){
* return new MyRibbonBar(parent);
* }
* };
* @endcode
*
* SARibbonMainWindow生成之前(一般在main函数设置元件工厂
*
* @code
* SARibbonElementManager::instance()->setupFactory(new MyRibbonFactory());
* @endcode
*
* 此时Ribbon的元素会通过MyRibbonFactory的接口来生成
*/
class SA_RIBBON_EXPORT SARibbonMainWindow : public QMainWindow
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonMainWindow)
friend class SARibbonBar;
Q_PROPERTY(SARibbonTheme ribbonTheme READ ribbonTheme WRITE setRibbonTheme)
public:
SARibbonMainWindow(QWidget* parent = nullptr, bool useRibbon = true, const Qt::WindowFlags flags = {});
~SARibbonMainWindow() Q_DECL_OVERRIDE;
// 返回SARibbonBar
SARibbonBar* ribbonBar() const;
// 设置ribbonbar
void setRibbonBar(SARibbonBar* ribbon);
#if !SARIBBON_USE_3RDPARTY_FRAMELESSHELPER
// 返回SAFramelessHelper
SAFramelessHelper* framelessHelper();
#else
// 如果ribbon中有自定义的窗口在标题栏等非点击区域加入后想能点击需要调用此接口告知可点击
void setFramelessHitTestVisible(QWidget* w, bool visible = true);
#endif
// 此函数仅用于控制最小最大化和关闭按钮的显示
void updateWindowFlag(Qt::WindowFlags flags);
// 注意主题在构造函数设置主题会不完全生效使用QTimer投放到队列最后执行即可
// QTimer::singleShot(0, this, [ this ]() { this->setRibbonTheme(SARibbonMainWindow::RibbonThemeDark); });
void setRibbonTheme(SARibbonTheme theme);
SARibbonTheme ribbonTheme() const;
// 判断当前是否使用ribbon模式
bool isUseRibbon() const;
// 把ribbonbar的事件传递到frameless
virtual bool eventFilter(QObject* obj, QEvent* e) Q_DECL_OVERRIDE;
// 获取最大化最小化关闭按钮所在的bar。可以通过此函数在最大最小化按钮旁边设置内容
SARibbonSystemButtonBar* windowButtonBar() const;
protected:
// 创建ribbonbar的工厂函数
SARibbonBar* createRibbonBar();
private Q_SLOTS:
void onPrimaryScreenChanged(QScreen* screen);
};
class SA_RIBBON_EXPORT SARibbonMainWindowEventFilter : public QObject
{
Q_OBJECT
public:
SARibbonMainWindowEventFilter(QObject* par);
virtual bool eventFilter(QObject* obj, QEvent* e) Q_DECL_OVERRIDE;
};
#endif // SARIBBONMAINWINDOW_H
/*** End of inlined file: SARibbonMainWindow.h ***/
/*** Start of inlined file: SARibbonWidget.h ***/
#ifndef SARIBBONWIDGET_H
#define SARIBBONWIDGET_H
#include <QWidget>
class SARibbonBar;
class QScreen;
/**
* @brief 带SARibbonBar的Widget
*
* @note 注意SARibbonWidget利用了布局来把ribbonbar放到最顶部不要给此widget添加布局否则会导致布局异常
* 正确的做法是把布局的窗口通过setWidget设置进SARibbonWidget
*
*/
class SA_RIBBON_EXPORT SARibbonWidget : public QWidget
{
Q_OBJECT
SA_RIBBON_DECLARE_PRIVATE(SARibbonWidget)
friend class SARibbonBar;
Q_PROPERTY(SARibbonTheme ribbonTheme READ ribbonTheme WRITE setRibbonTheme)
public:
SARibbonWidget(QWidget* parent = nullptr);
~SARibbonWidget() Q_DECL_OVERRIDE;
// 返回SARibbonBar
SARibbonBar* ribbonBar() const;
// 设置ribbonbar
void setRibbonBar(SARibbonBar* bar);
// 注意主题在构造函数设置主题会不完全生效使用QTimer投放到队列最后执行即可
// QTimer::singleShot(0, this, [ this ]() { this->setRibbonTheme(SARibbonTheme::RibbonThemeDark); });
void setRibbonTheme(SARibbonTheme theme);
SARibbonTheme ribbonTheme() const;
// 判断当前是否使用ribbon模式
bool isUseRibbon() const;
// 设置窗口
void setWidget(QWidget* w);
QWidget* widget() const;
//
QWidget* takeWidget();
private Q_SLOTS:
void onPrimaryScreenChanged(QScreen* screen);
};
#endif // SARIBBONWIDGET_H
/*** End of inlined file: SARibbonWidget.h ***/
/*** End of inlined file: SARibbonAmalgamTemplatePublicHeaders.h ***/
#endif