259 lines
9.3 KiB
C++
259 lines
9.3 KiB
C++
#include "ElaComboBoxStyle.h"
|
|
|
|
#include <QDebug>
|
|
#include <QPainter>
|
|
#include <QPainterPath>
|
|
#include <QStyleOption>
|
|
|
|
#include "ElaTheme.h"
|
|
ElaComboBoxStyle::ElaComboBoxStyle(QStyle* style)
|
|
{
|
|
_pExpandIconRotate = 0;
|
|
_pExpandMarkWidth = 0;
|
|
_themeMode = eTheme->getThemeMode();
|
|
connect(eTheme, &ElaTheme::themeModeChanged, this, [=](ElaThemeType::ThemeMode themeMode) {
|
|
_themeMode = themeMode;
|
|
});
|
|
}
|
|
|
|
ElaComboBoxStyle::~ElaComboBoxStyle()
|
|
{
|
|
}
|
|
|
|
void ElaComboBoxStyle::drawPrimitive(PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
|
|
{
|
|
switch (element)
|
|
{
|
|
case QStyle::PE_Widget:
|
|
case QStyle::PE_PanelLineEdit:
|
|
{
|
|
return;
|
|
}
|
|
#ifndef Q_OS_WIN
|
|
case PE_PanelMenu:
|
|
{
|
|
return;
|
|
}
|
|
case PE_IndicatorArrowDown:
|
|
{
|
|
return;
|
|
}
|
|
#endif
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
QProxyStyle::drawPrimitive(element, option, painter, widget);
|
|
}
|
|
|
|
void ElaComboBoxStyle::drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
|
|
{
|
|
switch (element)
|
|
{
|
|
case QStyle::CE_ComboBoxLabel:
|
|
{
|
|
return;
|
|
}
|
|
case QStyle::CE_ShapedFrame:
|
|
{
|
|
//container区域
|
|
if (widget->objectName() == "ElaComboBoxContainer")
|
|
{
|
|
QRect viewRect = option->rect;
|
|
painter->save();
|
|
painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
|
|
eTheme->drawEffectShadow(painter, viewRect, _shadowBorderWidth, 6);
|
|
QRect foregroundRect(viewRect.x() + _shadowBorderWidth, viewRect.y(), viewRect.width() - 2 * _shadowBorderWidth, viewRect.height() - _shadowBorderWidth);
|
|
painter->setPen(ElaThemeColor(_themeMode, PopupBorder));
|
|
painter->setBrush(ElaThemeColor(_themeMode, PopupBase));
|
|
painter->drawRoundedRect(foregroundRect, 3, 3);
|
|
painter->restore();
|
|
}
|
|
return;
|
|
}
|
|
case QStyle::CE_ItemViewItem:
|
|
{
|
|
//覆盖高亮
|
|
if (const QStyleOptionViewItem* vopt = qstyleoption_cast<const QStyleOptionViewItem*>(option))
|
|
{
|
|
int margin = 2;
|
|
painter->save();
|
|
painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
|
painter->setPen(Qt::NoPen);
|
|
QPainterPath path;
|
|
QRect optionRect = option->rect;
|
|
optionRect.adjust(margin, margin, -margin, -margin);
|
|
#ifndef Q_OS_WIN
|
|
optionRect.adjust(6, 0, -6, 0);
|
|
#endif
|
|
path.addRoundedRect(optionRect, 5, 5);
|
|
if (option->state & QStyle::State_Selected)
|
|
{
|
|
if (option->state & QStyle::State_MouseOver)
|
|
{
|
|
// 选中时覆盖
|
|
painter->setBrush(ElaThemeColor(_themeMode, BasicSelectedHoverAlpha));
|
|
painter->drawPath(path);
|
|
}
|
|
else
|
|
{
|
|
// 选中
|
|
painter->setBrush(ElaThemeColor(_themeMode, BasicSelectedAlpha));
|
|
painter->drawPath(path);
|
|
}
|
|
//选中Mark
|
|
painter->setPen(Qt::NoPen);
|
|
painter->setBrush(ElaThemeColor(_themeMode, PrimaryNormal));
|
|
painter->drawRoundedRect(QRectF(optionRect.x() + 3, optionRect.y() + optionRect.height() * 0.2, 3, optionRect.height() - +optionRect.height() * 0.4), 2, 2);
|
|
}
|
|
else
|
|
{
|
|
if (option->state & QStyle::State_MouseOver)
|
|
{
|
|
// 覆盖时颜色
|
|
painter->setBrush(ElaThemeColor(_themeMode, BasicHoverAlpha));
|
|
painter->drawPath(path);
|
|
}
|
|
}
|
|
// 文字绘制
|
|
painter->setPen(ElaThemeColor(_themeMode, BasicText));
|
|
painter->drawText(QRect(option->rect.x() + 15, option->rect.y(), option->rect.width() - 15, option->rect.height()), Qt::AlignVCenter, vopt->text);
|
|
painter->restore();
|
|
}
|
|
return;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
QProxyStyle::drawControl(element, option, painter, widget);
|
|
}
|
|
|
|
void ElaComboBoxStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const
|
|
{
|
|
switch (control)
|
|
{
|
|
case QStyle::CC_ComboBox:
|
|
{
|
|
//主体显示绘制
|
|
if (const QStyleOptionComboBox* copt = qstyleoption_cast<const QStyleOptionComboBox*>(option))
|
|
{
|
|
painter->save();
|
|
painter->setRenderHints(QPainter::SmoothPixmapTransform | QPainter::Antialiasing | QPainter::TextAntialiasing);
|
|
//背景绘制
|
|
bool isEnabled = copt->state.testFlag(QStyle::State_Enabled);
|
|
painter->setPen(ElaThemeColor(_themeMode, BasicBorder));
|
|
painter->setBrush(isEnabled ? (copt->state.testFlag(QStyle::State_HasFocus) && copt->editable)
|
|
? ElaThemeColor(_themeMode, DialogBase)
|
|
: copt->state.testFlag(QStyle::State_MouseOver)
|
|
? ElaThemeColor(_themeMode, BasicHover)
|
|
: ElaThemeColor(_themeMode, BasicBase)
|
|
: ElaThemeColor(_themeMode, BasicDisable));
|
|
QRect comboBoxRect = copt->rect;
|
|
comboBoxRect.adjust(_shadowBorderWidth, 1, -_shadowBorderWidth, -1);
|
|
painter->drawRoundedRect(comboBoxRect, 3, 3);
|
|
// 底边线绘制
|
|
painter->setPen(ElaThemeColor(_themeMode, BasicBaseLine));
|
|
painter->drawLine(comboBoxRect.x() + 3, comboBoxRect.y() + comboBoxRect.height(), comboBoxRect.x() + comboBoxRect.width() - 3, comboBoxRect.y() + comboBoxRect.height());
|
|
|
|
//文字绘制
|
|
if (!copt->editable)
|
|
{
|
|
QRect textRect = subControlRect(QStyle::CC_ComboBox, copt, QStyle::SC_ScrollBarSubLine, widget);
|
|
painter->setPen(isEnabled ? ElaThemeColor(_themeMode, BasicText) : ElaThemeColor(_themeMode, BasicTextDisable));
|
|
painter->drawText(textRect, Qt::AlignVCenter | Qt::AlignLeft, copt->currentText);
|
|
}
|
|
//展开指示器绘制
|
|
painter->setPen(Qt::NoPen);
|
|
painter->setBrush(ElaThemeColor(_themeMode, PrimaryNormal));
|
|
painter->drawRoundedRect(QRectF(comboBoxRect.center().x() - _pExpandMarkWidth, comboBoxRect.y() + comboBoxRect.height() - 3, _pExpandMarkWidth * 2, 3), 2, 2);
|
|
// 展开图标绘制
|
|
QRect expandIconRect = subControlRect(QStyle::CC_ComboBox, copt, QStyle::SC_ScrollBarAddPage, widget);
|
|
if (expandIconRect.isValid())
|
|
{
|
|
QFont iconFont = QFont("ElaAwesome");
|
|
iconFont.setPixelSize(17);
|
|
painter->setFont(iconFont);
|
|
painter->setPen(isEnabled ? ElaThemeColor(_themeMode, BasicText) : ElaThemeColor(_themeMode, BasicTextDisable));
|
|
painter->translate(expandIconRect.x() + (qreal)expandIconRect.width() / 2, expandIconRect.y() + (qreal)expandIconRect.height() / 2);
|
|
painter->rotate(_pExpandIconRotate);
|
|
painter->translate(-expandIconRect.x() - (qreal)expandIconRect.width() / 2, -expandIconRect.y() - (qreal)expandIconRect.height() / 2);
|
|
painter->drawText(expandIconRect, Qt::AlignCenter, QChar((unsigned short)ElaIconType::AngleDown));
|
|
painter->restore();
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
QProxyStyle::drawComplexControl(control, option, painter, widget);
|
|
}
|
|
|
|
QRect ElaComboBoxStyle::subControlRect(ComplexControl cc, const QStyleOptionComplex* opt, SubControl sc, const QWidget* widget) const
|
|
{
|
|
switch (cc)
|
|
{
|
|
case QStyle::CC_ComboBox:
|
|
{
|
|
switch (sc)
|
|
{
|
|
case QStyle::SC_ScrollBarSubLine:
|
|
{
|
|
//文字区域
|
|
QRect textRect = QProxyStyle::subControlRect(cc, opt, sc, widget);
|
|
textRect.setLeft(16);
|
|
textRect.setRight(textRect.right() - 15);
|
|
return textRect;
|
|
}
|
|
case QStyle::SC_ScrollBarAddPage:
|
|
{
|
|
//展开图标区域
|
|
QRect expandIconRect = QProxyStyle::subControlRect(cc, opt, sc, widget);
|
|
expandIconRect.setLeft(expandIconRect.left() - 25);
|
|
return expandIconRect;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
return QProxyStyle::subControlRect(cc, opt, sc, widget);
|
|
}
|
|
|
|
QSize ElaComboBoxStyle::sizeFromContents(ContentsType type, const QStyleOption* option, const QSize& size, const QWidget* widget) const
|
|
{
|
|
switch (type)
|
|
{
|
|
case QStyle::CT_ItemViewItem:
|
|
{
|
|
QSize itemSize = QProxyStyle::sizeFromContents(type, option, size, widget);
|
|
itemSize.setHeight(35);
|
|
return itemSize;
|
|
}
|
|
case QStyle::CT_ComboBox:
|
|
{
|
|
QSize comboBoxSize = QProxyStyle::sizeFromContents(type, option, size, widget);
|
|
comboBoxSize.setWidth(comboBoxSize.width() + 26);
|
|
return comboBoxSize;
|
|
}
|
|
default:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return QProxyStyle::sizeFromContents(type, option, size, widget);
|
|
}
|