feat: 添加ElaWidgetTool库

This commit is contained in:
sleepwithoutbz
2025-09-19 22:40:52 +08:00
parent 5f93e8caf6
commit 4eef5c7fd5
407 changed files with 36325 additions and 7 deletions

View File

@@ -0,0 +1,266 @@
#include "ElaFooterDelegate.h"
#include <QPainter>
#include <QPainterPath>
#include <QPropertyAnimation>
#include "ElaBaseListView.h"
#include "ElaFooterModel.h"
#include "ElaNavigationNode.h"
#include "ElaTheme.h"
ElaFooterDelegate::ElaFooterDelegate(QObject* parent)
: QStyledItemDelegate{parent}
{
_pElaListView = nullptr;
_themeMode = eTheme->getThemeMode();
connect(eTheme, &ElaTheme::themeModeChanged, this, [=](ElaThemeType::ThemeMode themeMode) {
_themeMode = themeMode;
});
setProperty("lastSelectMarkTop", 10.0);
setProperty("lastSelectMarkBottom", 10.0);
setProperty("selectMarkTop", 10.0);
setProperty("selectMarkBottom", 10.0);
// Mark向上
_lastSelectMarkTopAnimation = new QPropertyAnimation(this, "lastSelectMarkTop");
connect(_lastSelectMarkTopAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
_lastSelectMarkTop = value.toReal();
_pElaListView->viewport()->update(); });
_lastSelectMarkTopAnimation->setDuration(300);
_lastSelectMarkTopAnimation->setEasingCurve(QEasingCurve::InOutSine);
_selectMarkBottomAnimation = new QPropertyAnimation(this, "selectMarkBottom");
connect(_selectMarkBottomAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
_selectMarkBottom = value.toReal();
_pElaListView->viewport()->update(); });
_selectMarkBottomAnimation->setDuration(300);
_selectMarkBottomAnimation->setEasingCurve(QEasingCurve::InOutSine);
connect(_lastSelectMarkTopAnimation, &QPropertyAnimation::finished, this, [=]() {
_isSelectMarkDisplay = true;
_lastSelectedNode = nullptr;
_selectMarkBottomAnimation->setStartValue(0);
_selectMarkBottomAnimation->setEndValue(10);
_selectMarkBottomAnimation->start(); });
// Mark向下
_lastSelectMarkBottomAnimation = new QPropertyAnimation(this, "lastSelectMarkBottom");
connect(_lastSelectMarkBottomAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
_lastSelectMarkBottom = value.toReal();
_pElaListView->viewport()->update(); });
_lastSelectMarkBottomAnimation->setDuration(300);
_lastSelectMarkBottomAnimation->setEasingCurve(QEasingCurve::InOutSine);
_selectMarkTopAnimation = new QPropertyAnimation(this, "selectMarkTop");
connect(_selectMarkTopAnimation, &QPropertyAnimation::valueChanged, this, [=](const QVariant& value) {
_selectMarkTop = value.toReal();
_pElaListView->viewport()->update(); });
_selectMarkTopAnimation->setDuration(300);
_selectMarkTopAnimation->setEasingCurve(QEasingCurve::InOutSine);
connect(_lastSelectMarkBottomAnimation, &QPropertyAnimation::finished, this, [=]() {
_isSelectMarkDisplay = true;
_lastSelectedNode = nullptr;
_selectMarkTopAnimation->setStartValue(0);
_selectMarkTopAnimation->setEndValue(10);
_selectMarkTopAnimation->start(); });
}
ElaFooterDelegate::~ElaFooterDelegate()
{
}
void ElaFooterDelegate::navigationNodeStateChange(QVariantMap data)
{
if (data.contains("SelectMarkChanged"))
{
_lastSelectedNode = data.value("LastSelectedNode").value<ElaNavigationNode*>();
ElaNavigationNode* selectedNode = data.value("SelectedNode").value<ElaNavigationNode*>();
bool direction = _compareItemY(selectedNode, _lastSelectedNode);
_lastSelectMarkTop = 10;
_lastSelectMarkBottom = 10;
_selectMarkTop = 10;
_selectMarkBottom = 10;
if (direction)
{
_lastSelectMarkTopAnimation->setStartValue(10);
_lastSelectMarkTopAnimation->setEndValue(0);
_lastSelectMarkTopAnimation->start();
_lastSelectMarkBottomAnimation->stop();
_selectMarkTopAnimation->stop();
_isSelectMarkDisplay = false;
}
else
{
_lastSelectMarkBottomAnimation->setStartValue(10);
_lastSelectMarkBottomAnimation->setEndValue(0);
_lastSelectMarkBottomAnimation->start();
_lastSelectMarkTopAnimation->stop();
_selectMarkBottomAnimation->stop();
_isSelectMarkDisplay = false;
}
}
}
void ElaFooterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QStyleOptionViewItem viewOption(option);
initStyleOption(&viewOption, index);
ElaFooterModel* model = dynamic_cast<ElaFooterModel*>(const_cast<QAbstractItemModel*>(index.model()));
ElaNavigationNode* node = index.data(Qt::UserRole).value<ElaNavigationNode*>();
if (option.state.testFlag(QStyle::State_HasFocus))
{
viewOption.state &= ~QStyle::State_HasFocus;
}
QStyledItemDelegate::paint(painter, viewOption, index);
// 背景绘制
QRect itemRect = option.rect;
painter->save();
painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
itemRect.setTop(itemRect.top() + 2);
itemRect.setBottom(itemRect.bottom() - 2);
QPainterPath path;
path.addRoundedRect(itemRect, 8, 8);
if (option.state & QStyle::State_Selected)
{
if (index == _pPressIndex)
{
// 选中时点击
painter->fillPath(path, ElaThemeColor(_themeMode, BasicHoverAlpha));
}
else
{
if (option.state & QStyle::State_MouseOver)
{
// 选中时覆盖
painter->fillPath(path, ElaThemeColor(_themeMode, BasicSelectedHoverAlpha));
}
else
{
// 选中
painter->fillPath(path, ElaThemeColor(_themeMode, BasicSelectedAlpha));
}
}
}
else
{
if (index == _pPressIndex)
{
// 点击时颜色
painter->fillPath(path, ElaThemeColor(_themeMode, BasicSelectedHoverAlpha));
}
else
{
if (option.state & QStyle::State_MouseOver)
{
// 覆盖时颜色
painter->fillPath(path, ElaThemeColor(_themeMode, BasicHoverAlpha));
}
}
}
painter->restore();
painter->save();
painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing);
itemRect = option.rect;
//顶边线绘制
if (index.row() == 0)
{
painter->setPen(ElaThemeColor(_themeMode, BasicBaseLine));
painter->drawLine(option.rect.x(), itemRect.y() + 1, option.rect.x() + option.rect.width(), itemRect.y() + 1);
}
// 图标绘制
painter->setPen(index == _pPressIndex ? ElaThemeColor(_themeMode, BasicTextPress) : ElaThemeColor(_themeMode, BasicText));
if (node->getAwesome() != ElaIconType::None)
{
painter->save();
QFont iconFont = QFont("ElaAwesome");
iconFont.setPixelSize(17);
painter->setFont(iconFont);
painter->drawText(QRect(itemRect.x(), itemRect.y(), _iconAreaWidth, itemRect.height()), Qt::AlignCenter, QChar((unsigned short)node->getAwesome()));
painter->restore();
}
int keyPoints = node->getKeyPoints();
if (keyPoints)
{
// KeyPoints
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::white);
painter->drawEllipse(QPoint(255, itemRect.y() + itemRect.height() / 2), 10, 10);
painter->setBrush(ElaThemeColor(_themeMode, StatusDanger));
painter->drawEllipse(QPoint(255, itemRect.y() + itemRect.height() / 2), 9, 9);
painter->setPen(QPen(Qt::white, 2));
QFont font = painter->font();
font.setBold(true);
if (keyPoints > 99)
{
keyPoints = 99;
}
if (keyPoints > 9)
{
font.setPixelSize(11);
}
else
{
font.setPixelSize(12);
}
painter->setFont(font);
painter->drawText(keyPoints > 9 ? 248 : 251, itemRect.y() + itemRect.height() / 2 + 4, QString::number(keyPoints));
painter->restore();
}
// 文字绘制
painter->setPen(index == _pPressIndex ? ElaThemeColor(_themeMode, BasicTextPress) : ElaThemeColor(_themeMode, BasicText));
QRect textRect;
if (node->getAwesome() != ElaIconType::None)
{
textRect = QRect(itemRect.x() + _iconAreaWidth, itemRect.y(), itemRect.width() - _textRightSpacing - _indicatorIconAreaWidth - _iconAreaWidth, itemRect.height());
}
else
{
textRect = QRect(itemRect.x() + _leftPadding, itemRect.y(), itemRect.width() - _textRightSpacing - _indicatorIconAreaWidth - _leftPadding, itemRect.height());
}
QString text = painter->fontMetrics().elidedText(node->getNodeTitle(), Qt::ElideRight, textRect.width());
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
// 选中特效
if (_isSelectMarkDisplay && (node == model->getSelectedNode()))
{
painter->setPen(Qt::NoPen);
painter->setBrush(ElaThemeColor(_themeMode, PrimaryNormal));
painter->drawRoundedRect(QRectF(itemRect.x() + 3, itemRect.y() + _selectMarkTop, 3, itemRect.height() - _selectMarkTop - _selectMarkBottom), 3, 3);
}
if (node == _lastSelectedNode)
{
painter->setPen(Qt::NoPen);
painter->setBrush(ElaThemeColor(_themeMode, PrimaryNormal));
painter->drawRoundedRect(QRectF(itemRect.x() + 3, itemRect.y() + _lastSelectMarkTop, 3, itemRect.height() - _lastSelectMarkTop - _lastSelectMarkBottom), 3, 3);
}
painter->restore();
}
QSize ElaFooterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{
QSize size = QStyledItemDelegate::sizeHint(option, index);
size.setHeight(40);
return size;
}
bool ElaFooterDelegate::_compareItemY(ElaNavigationNode* node1, ElaNavigationNode* node2)
{
if (!node1)
{
return true;
}
if (!node2)
{
return false;
}
if (node1->getModelIndex().row() < node2->getModelIndex().row())
{
return true;
}
else
{
return false;
}
}