feat: 添加ElaWidgetTool库
This commit is contained in:
332
ElaWidgetTools/DeveloperComponents/ElaToolButtonStyle.cpp
Normal file
332
ElaWidgetTools/DeveloperComponents/ElaToolButtonStyle.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
#include "ElaToolButtonStyle.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStyleOption>
|
||||
#include <QtMath>
|
||||
|
||||
#include "ElaTheme.h"
|
||||
ElaToolButtonStyle::ElaToolButtonStyle(QStyle* style)
|
||||
{
|
||||
_pIsSelected = false;
|
||||
_pIsTransparent = true;
|
||||
_pExpandIconRotate = 0;
|
||||
_pBorderRadius = 4;
|
||||
_themeMode = eTheme->getThemeMode();
|
||||
connect(eTheme, &ElaTheme::themeModeChanged, this, [=](ElaThemeType::ThemeMode themeMode) {
|
||||
_themeMode = themeMode;
|
||||
});
|
||||
}
|
||||
|
||||
ElaToolButtonStyle::~ElaToolButtonStyle()
|
||||
{
|
||||
}
|
||||
|
||||
void ElaToolButtonStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const
|
||||
{
|
||||
switch (control)
|
||||
{
|
||||
case QStyle::CC_ToolButton:
|
||||
{
|
||||
// 内容绘制
|
||||
if (const QStyleOptionToolButton* bopt = qstyleoption_cast<const QStyleOptionToolButton*>(option))
|
||||
{
|
||||
if (bopt->arrowType != Qt::NoArrow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
QRect toolButtonRect = bopt->rect;
|
||||
if (!_pIsTransparent)
|
||||
{
|
||||
// 边框距离
|
||||
toolButtonRect.adjust(1, 1, -1, -1);
|
||||
}
|
||||
painter->save();
|
||||
painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
|
||||
painter->setPen(_pIsTransparent ? Qt::transparent : ElaThemeColor(_themeMode, BasicBorder));
|
||||
// 背景绘制
|
||||
if (bopt->state.testFlag(QStyle::State_Enabled))
|
||||
{
|
||||
if (bopt->state.testFlag(QStyle::State_Sunken))
|
||||
{
|
||||
painter->setBrush(_pIsTransparent ? ElaThemeColor(_themeMode, BasicPressAlpha) : ElaThemeColor(_themeMode, BasicPress));
|
||||
painter->drawRoundedRect(toolButtonRect, _pBorderRadius, _pBorderRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_pIsSelected)
|
||||
{
|
||||
painter->setBrush(_pIsTransparent ? ElaThemeColor(_themeMode, BasicSelectedAlpha) : ElaThemeColor(_themeMode, BasicHover));
|
||||
painter->drawRoundedRect(toolButtonRect, _pBorderRadius, _pBorderRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bopt->state.testFlag(QStyle::State_MouseOver) || bopt->state.testFlag(QStyle::State_On))
|
||||
{
|
||||
painter->setBrush(_pIsTransparent ? ElaThemeColor(_themeMode, BasicHoverAlpha) : ElaThemeColor(_themeMode, BasicHover));
|
||||
painter->drawRoundedRect(toolButtonRect, _pBorderRadius, _pBorderRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_pIsTransparent)
|
||||
{
|
||||
painter->setBrush(ElaThemeColor(_themeMode, BasicBase));
|
||||
painter->drawRoundedRect(toolButtonRect, _pBorderRadius, _pBorderRadius);
|
||||
// 底边线绘制
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicBaseLine));
|
||||
painter->drawLine(toolButtonRect.x() + _pBorderRadius, toolButtonRect.y() + toolButtonRect.height(), toolButtonRect.x() + toolButtonRect.width() - _pBorderRadius, toolButtonRect.y() + toolButtonRect.height());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 指示器绘制
|
||||
_drawIndicator(painter, bopt, widget);
|
||||
|
||||
// 图标绘制
|
||||
QRect contentRect = subControlRect(control, bopt, QStyle::SC_ScrollBarAddLine, widget);
|
||||
int heightOffset = contentRect.height() * 0.05;
|
||||
contentRect.adjust(0, heightOffset, 0, -heightOffset);
|
||||
_drawIcon(painter, contentRect, bopt, widget);
|
||||
|
||||
// 文字绘制
|
||||
_drawText(painter, contentRect, bopt);
|
||||
painter->restore();
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
||||
}
|
||||
|
||||
QSize ElaToolButtonStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const
|
||||
{
|
||||
if (type == QStyle::CT_ToolButton)
|
||||
{
|
||||
if (const QStyleOptionToolButton* bopt = qstyleoption_cast<const QStyleOptionToolButton*>(option))
|
||||
{
|
||||
QSize toolButtonSize = QProxyStyle::sizeFromContents(type, option, size, widget);
|
||||
if (bopt->features.testFlag(QStyleOptionToolButton::HasMenu) && !bopt->features.testFlag(QStyleOptionToolButton::MenuButtonPopup))
|
||||
{
|
||||
toolButtonSize.setWidth(toolButtonSize.width() + _contentMargin + 0.65 * std::min(bopt->iconSize.width(), bopt->iconSize.height()));
|
||||
}
|
||||
return toolButtonSize;
|
||||
}
|
||||
}
|
||||
return QProxyStyle::sizeFromContents(type, option, size, widget);
|
||||
}
|
||||
|
||||
void ElaToolButtonStyle::_drawIndicator(QPainter* painter, const QStyleOptionToolButton* bopt, const QWidget* widget) const
|
||||
{
|
||||
if (bopt->features.testFlag(QStyleOptionToolButton::MenuButtonPopup))
|
||||
{
|
||||
QRect indicatorRect = subControlRect(QStyle::CC_ToolButton, bopt, QStyle::SC_ScrollBarSubLine, widget);
|
||||
// 指示器区域
|
||||
if (bopt->state.testFlag(QStyle::State_Enabled) && bopt->activeSubControls.testFlag(QStyle::SC_ScrollBarSubLine))
|
||||
{
|
||||
painter->setBrush(ElaThemeColor(_themeMode, BasicIndicator));
|
||||
QPainterPath path;
|
||||
path.moveTo(indicatorRect.topLeft());
|
||||
path.lineTo(indicatorRect.right() - 4, indicatorRect.y());
|
||||
path.arcTo(QRect(indicatorRect.right() - 8, indicatorRect.y(), 8, 8), 90, -90);
|
||||
path.lineTo(indicatorRect.right(), indicatorRect.bottom() - 4);
|
||||
path.arcTo(QRect(indicatorRect.right() - 8, indicatorRect.bottom() - 8, 8, 8), 0, -90);
|
||||
path.lineTo(indicatorRect.bottomLeft());
|
||||
path.closeSubpath();
|
||||
painter->drawPath(path);
|
||||
}
|
||||
// 指示器
|
||||
painter->setBrush(bopt->state.testFlag(QStyle::State_Enabled) ? ElaThemeColor(_themeMode, BasicText) : ElaThemeColor(_themeMode, BasicTextDisable));
|
||||
QPainterPath indicatorPath;
|
||||
qreal indicatorHeight = qCos(30 * M_PI / 180.0) * indicatorRect.width() * 0.85;
|
||||
indicatorPath.moveTo(indicatorRect.x() + indicatorRect.width() * 0.15, indicatorRect.center().y());
|
||||
indicatorPath.lineTo(indicatorRect.right() - indicatorRect.width() * 0.15, indicatorRect.center().y());
|
||||
indicatorPath.lineTo(indicatorRect.center().x(), indicatorRect.center().y() + indicatorHeight / 2);
|
||||
indicatorPath.closeSubpath();
|
||||
painter->drawPath(indicatorPath);
|
||||
}
|
||||
else if (bopt->features.testFlag(QStyleOptionToolButton::HasMenu))
|
||||
{
|
||||
// 展开指示器
|
||||
QSize iconSize = bopt->iconSize;
|
||||
painter->save();
|
||||
QRect toolButtonRect = bopt->rect;
|
||||
QFont iconFont = QFont("ElaAwesome");
|
||||
iconFont.setPixelSize(0.75 * std::min(iconSize.width(), iconSize.height()));
|
||||
painter->setFont(iconFont);
|
||||
int indicatorWidth = painter->fontMetrics().horizontalAdvance(QChar((unsigned short)ElaIconType::AngleDown));
|
||||
QRect expandIconRect(toolButtonRect.right() - _contentMargin - indicatorWidth, toolButtonRect.y() + 1, indicatorWidth, toolButtonRect.height());
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicText));
|
||||
painter->translate(expandIconRect.center().x(), expandIconRect.y() + (qreal)expandIconRect.height() / 2);
|
||||
painter->rotate(_pExpandIconRotate);
|
||||
painter->translate(-expandIconRect.center().x() - 1, -expandIconRect.y() - (qreal)expandIconRect.height() / 2);
|
||||
painter->drawText(expandIconRect, Qt::AlignCenter, QChar((unsigned short)ElaIconType::AngleDown));
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
void ElaToolButtonStyle::_drawIcon(QPainter* painter, QRectF iconRect, const QStyleOptionToolButton* bopt, const QWidget* widget) const
|
||||
{
|
||||
if (bopt->toolButtonStyle != Qt::ToolButtonTextOnly)
|
||||
{
|
||||
QSize iconSize = bopt->iconSize;
|
||||
if (widget->property("ElaIconType").toString().isEmpty())
|
||||
{
|
||||
// 绘制QIcon
|
||||
QIcon icon = bopt->icon;
|
||||
if (!icon.isNull())
|
||||
{
|
||||
QPixmap iconPix = icon.pixmap(iconSize,
|
||||
(bopt->state & State_Enabled) ? QIcon::Normal
|
||||
: QIcon::Disabled,
|
||||
(bopt->state & State_Selected) ? QIcon::On
|
||||
: QIcon::Off);
|
||||
switch (bopt->toolButtonStyle)
|
||||
{
|
||||
case Qt::ToolButtonIconOnly:
|
||||
{
|
||||
painter->drawPixmap(QRect(QPoint(iconRect.x(), iconRect.center().y() - iconSize.height() / 2), iconSize), iconPix);
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonFollowStyle:
|
||||
case Qt::ToolButtonTextBesideIcon:
|
||||
{
|
||||
painter->drawPixmap(QRect(QPoint(iconRect.x() + _contentMargin, iconRect.center().y() - iconSize.height() / 2), iconSize), iconPix);
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonTextUnderIcon:
|
||||
{
|
||||
if (bopt->features.testFlag(QStyleOptionToolButton::HasMenu) && !bopt->features.testFlag(QStyleOptionToolButton::MenuButtonPopup))
|
||||
{
|
||||
iconRect.setRight(iconRect.right() - _calculateExpandIndicatorWidth(bopt, painter));
|
||||
}
|
||||
painter->drawPixmap(QRect(QPoint(iconRect.center().x() - iconSize.width() / 2, iconRect.y()), iconSize), iconPix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 绘制ElaIcon
|
||||
painter->save();
|
||||
if (bopt->state.testFlag(QStyle::State_Enabled))
|
||||
{
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicText));
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicTextDisable));
|
||||
}
|
||||
QFont iconFont = QFont("ElaAwesome");
|
||||
switch (bopt->toolButtonStyle)
|
||||
{
|
||||
case Qt::ToolButtonIconOnly:
|
||||
{
|
||||
iconFont.setPixelSize(0.75 * std::min(iconSize.width(), iconSize.height()));
|
||||
painter->setFont(iconFont);
|
||||
painter->drawText(iconRect, Qt::AlignCenter, widget->property("ElaIconType").toString());
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonFollowStyle:
|
||||
case Qt::ToolButtonTextBesideIcon:
|
||||
{
|
||||
QRect adjustIconRect(iconRect.x() + _contentMargin, iconRect.y(), iconSize.width(), iconRect.height());
|
||||
iconFont.setPixelSize(0.75 * std::min(iconSize.width(), iconSize.height()));
|
||||
painter->setFont(iconFont);
|
||||
painter->drawText(adjustIconRect, Qt::AlignCenter, widget->property("ElaIconType").toString());
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonTextUnderIcon:
|
||||
{
|
||||
if (bopt->features.testFlag(QStyleOptionToolButton::HasMenu) && !bopt->features.testFlag(QStyleOptionToolButton::MenuButtonPopup))
|
||||
{
|
||||
iconRect.setRight(iconRect.right() - _calculateExpandIndicatorWidth(bopt, painter));
|
||||
}
|
||||
QRect adjustIconRect(iconRect.center().x() - iconSize.width() / 2, iconRect.y() + 0.2 * std::min(iconSize.width(), iconSize.height()), iconSize.width(), iconSize.height());
|
||||
iconFont.setPixelSize(0.8 * std::min(iconSize.width(), iconSize.height()));
|
||||
painter->setFont(iconFont);
|
||||
painter->drawText(adjustIconRect, Qt::AlignHCenter, widget->property("ElaIconType").toString());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ElaToolButtonStyle::_drawText(QPainter* painter, QRect contentRect, const QStyleOptionToolButton* bopt) const
|
||||
{
|
||||
if (!bopt->text.isEmpty())
|
||||
{
|
||||
if (bopt->state.testFlag(QStyle::State_Enabled))
|
||||
{
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicText));
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen(ElaThemeColor(_themeMode, BasicTextDisable));
|
||||
}
|
||||
switch (bopt->toolButtonStyle)
|
||||
{
|
||||
case Qt::ToolButtonTextOnly:
|
||||
{
|
||||
contentRect.setLeft(contentRect.left() + _contentMargin);
|
||||
painter->drawText(contentRect, Qt::AlignLeft | Qt::AlignVCenter, bopt->text);
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonTextBesideIcon:
|
||||
{
|
||||
painter->drawText(QRect(contentRect.x() + _contentMargin * 2 + bopt->iconSize.width(), contentRect.y(), contentRect.width() - bopt->iconSize.width(), contentRect.height()), Qt::AlignLeft | Qt::AlignVCenter, bopt->text);
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonTextUnderIcon:
|
||||
{
|
||||
if (bopt->features.testFlag(QStyleOptionToolButton::HasMenu) && !bopt->features.testFlag(QStyleOptionToolButton::MenuButtonPopup))
|
||||
{
|
||||
contentRect.setLeft(contentRect.left() + _contentMargin);
|
||||
painter->drawText(contentRect, Qt::AlignBottom | Qt::AlignLeft, bopt->text);
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->drawText(contentRect, Qt::AlignBottom | Qt::AlignHCenter, bopt->text);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Qt::ToolButtonFollowStyle:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qreal ElaToolButtonStyle::_calculateExpandIndicatorWidth(const QStyleOptionToolButton* bopt, QPainter* painter) const
|
||||
{
|
||||
// 展开指示器
|
||||
QSize iconSize = bopt->iconSize;
|
||||
painter->save();
|
||||
QFont iconFont = QFont("ElaAwesome");
|
||||
iconFont.setPixelSize(0.75 * std::min(iconSize.width(), iconSize.height()));
|
||||
painter->setFont(iconFont);
|
||||
int indicatorWidth = painter->fontMetrics().horizontalAdvance(QChar((unsigned short)ElaIconType::AngleDown));
|
||||
painter->restore();
|
||||
return indicatorWidth;
|
||||
}
|
||||
Reference in New Issue
Block a user