first commit
This commit is contained in:
283
widgets/appicon.cpp
Normal file
283
widgets/appicon.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
#include "appicon.h"
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QMouseEvent>
|
||||
#include <QLinearGradient>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
|
||||
AppIcon::AppIcon(const AppIconData &data, QWidget *parent)
|
||||
: QWidget(parent), m_data(data), m_scale(1.0), m_isPressed(false), m_longPressTimerId(0)
|
||||
{
|
||||
qDebug() << "AppIcon constructor:" << data.name << "(" << data.id << ")";
|
||||
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setAttribute(Qt::WA_Hover);
|
||||
|
||||
setupUI();
|
||||
qDebug() << "AppIcon created successfully:" << data.name;
|
||||
}
|
||||
|
||||
AppIcon::~AppIcon()
|
||||
{
|
||||
if (m_longPressTimerId)
|
||||
{
|
||||
killTimer(m_longPressTimerId);
|
||||
}
|
||||
}
|
||||
|
||||
void AppIcon::setupUI()
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(3, 3, 3, 3);
|
||||
layout->setSpacing(5);
|
||||
layout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
// Android风格图标尺寸 - 10英寸屏幕优化
|
||||
int iconSize = 80;
|
||||
int borderRadius = 16;
|
||||
|
||||
QWidget *iconContainer = new QWidget(this);
|
||||
iconContainer->setFixedSize(iconSize, iconSize);
|
||||
iconContainer->setObjectName("iconContainer");
|
||||
|
||||
// 设置阴影效果 - 更明显的阴影
|
||||
m_shadowEffect = new QGraphicsDropShadowEffect(this);
|
||||
m_shadowEffect->setBlurRadius(16);
|
||||
m_shadowEffect->setColor(QColor(0, 0, 0, 60));
|
||||
m_shadowEffect->setOffset(0, 4);
|
||||
iconContainer->setGraphicsEffect(m_shadowEffect);
|
||||
|
||||
// 图标标签
|
||||
m_iconLabel = new QLabel(iconContainer);
|
||||
m_iconLabel->setAlignment(Qt::AlignCenter);
|
||||
m_iconLabel->setFixedSize(iconSize, iconSize);
|
||||
m_iconLabel->move(0, 0);
|
||||
|
||||
// 设置图标样式
|
||||
QString gradientStart = m_data.gradient.size() > 0 ? m_data.gradient[0] : m_data.color;
|
||||
QString gradientEnd = m_data.gradient.size() > 1 ? m_data.gradient[1] : m_data.color;
|
||||
|
||||
QString iconStyle = QString(R"(
|
||||
QLabel {
|
||||
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
|
||||
stop:0 %1, stop:1 %2);
|
||||
border-radius: %3px;
|
||||
font-size: 36px;
|
||||
color: white;
|
||||
}
|
||||
)")
|
||||
.arg(gradientStart, gradientEnd)
|
||||
.arg(borderRadius);
|
||||
|
||||
m_iconLabel->setStyleSheet(iconStyle);
|
||||
|
||||
// 设置 SVG 图标
|
||||
QString iconPath = getIconSymbol(m_data.id);
|
||||
if (!iconPath.isEmpty())
|
||||
{
|
||||
QPixmap pixmap(iconPath);
|
||||
if (!pixmap.isNull())
|
||||
{
|
||||
// 缩放图标到合适大小
|
||||
int svgSize = iconSize - 24; // 留出边距
|
||||
pixmap = pixmap.scaled(svgSize, svgSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
m_iconLabel->setPixmap(pixmap);
|
||||
}
|
||||
}
|
||||
|
||||
// 徽章标签 - 过滤掉emoji,只显示纯文字badge
|
||||
if (!m_data.badge.isEmpty())
|
||||
{
|
||||
QString badgeText = m_data.badge;
|
||||
// 过滤掉emoji字符(保留ASCII和常见中文字符)
|
||||
QString filteredBadge;
|
||||
for (const QChar &ch : badgeText)
|
||||
{
|
||||
ushort unicode = ch.unicode();
|
||||
// 保留基本ASCII(32-126)、中文字符(0x4E00-0x9FFF)、以及一些常用符号
|
||||
if ((unicode >= 32 && unicode <= 126) ||
|
||||
(unicode >= 0x4E00 && unicode <= 0x9FFF) ||
|
||||
ch == QChar(0xB1) || // ±
|
||||
ch == QChar(0x394) || // Δ
|
||||
ch == QChar(0x3A9))
|
||||
{ // Ω
|
||||
filteredBadge += ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (!filteredBadge.isEmpty())
|
||||
{
|
||||
m_badgeLabel = new QLabel(iconContainer);
|
||||
m_badgeLabel->setText(filteredBadge);
|
||||
m_badgeLabel->setFixedSize(26, 16);
|
||||
m_badgeLabel->setAlignment(Qt::AlignCenter);
|
||||
m_badgeLabel->move(iconSize - 28, iconSize - 18);
|
||||
m_badgeLabel->setStyleSheet(R"(
|
||||
QLabel {
|
||||
background-color: rgba(255, 255, 255, 0.95);
|
||||
color: #333;
|
||||
border-radius: 4px;
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
}
|
||||
)");
|
||||
}
|
||||
}
|
||||
|
||||
layout->addWidget(iconContainer, 0, Qt::AlignCenter);
|
||||
|
||||
// 名称标签 - Android风格白色文字带阴影
|
||||
m_nameLabel = new QLabel(m_data.name, this);
|
||||
m_nameLabel->setAlignment(Qt::AlignCenter);
|
||||
m_nameLabel->setFixedWidth(150);
|
||||
m_nameLabel->setWordWrap(false);
|
||||
m_nameLabel->setStyleSheet(R"(
|
||||
QLabel {
|
||||
color: white;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
background: transparent;
|
||||
}
|
||||
)");
|
||||
layout->addWidget(m_nameLabel, 0, Qt::AlignCenter);
|
||||
}
|
||||
|
||||
QString AppIcon::getIconSymbol(const QString &id) const
|
||||
{
|
||||
// 返回对应的SVG图标路径
|
||||
static QMap<QString, QString> iconMap = {
|
||||
{"rtd", ":/icons/ic_rtd.svg"},
|
||||
{"rtd_measure", ":/icons/ic_rtd.svg"},
|
||||
{"rtd_output", ":/icons/ic_rtd_output.svg"},
|
||||
{"thermocouple", ":/icons/ic_thermocouple.svg"},
|
||||
{"insulation", ":/icons/ic_insulation.svg"},
|
||||
{"dc_current", ":/icons/ic_dc_current.svg"},
|
||||
{"dc_voltage", ":/icons/ic_dc_voltage.svg"},
|
||||
{"frequency", ":/icons/ic_frequency.svg"},
|
||||
{"ac_voltage", ":/icons/ic_ac_voltage.svg"},
|
||||
{"switch_detect", ":/icons/ic_switch.svg"},
|
||||
{"ripple", ":/icons/ic_ripple.svg"},
|
||||
{"ramp", ":/icons/ic_ramp.svg"},
|
||||
{"waveform", ":/icons/ic_waveform.svg"},
|
||||
{"dual_channel", ":/icons/ic_dual_channel.svg"},
|
||||
{"trim", ":/icons/ic_trim.svg"},
|
||||
{"data_management", ":/icons/ic_data.svg"},
|
||||
{"wireless", ":/icons/ic_wireless.svg"},
|
||||
{"sop", ":/icons/ic_sop.svg"},
|
||||
{"rcp63", ":/icons/ic_rcp63.svg"},
|
||||
{"settings", ":/icons/ic_settings.svg"},
|
||||
{"network_test", ":/icons/ic_network_test.svg"},
|
||||
{"dock_sop", ":/icons/ic_sop.svg"},
|
||||
{"dock_rcp63", ":/icons/ic_rcp63.svg"},
|
||||
{"dock_network", ":/icons/ic_network_test.svg"},
|
||||
{"dock_settings", ":/icons/ic_settings.svg"}};
|
||||
|
||||
return iconMap.value(id, "");
|
||||
}
|
||||
|
||||
void AppIcon::setScale(qreal scale)
|
||||
{
|
||||
if (qFuzzyCompare(m_scale, scale))
|
||||
return;
|
||||
m_scale = scale;
|
||||
update();
|
||||
}
|
||||
|
||||
void AppIcon::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
|
||||
if (!qFuzzyCompare(m_scale, 1.0))
|
||||
{
|
||||
// 应用缩放变换
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
QTransform transform;
|
||||
transform.translate(width() / 2, height() / 2);
|
||||
transform.scale(m_scale, m_scale);
|
||||
transform.translate(-width() / 2, -height() / 2);
|
||||
|
||||
painter.setTransform(transform);
|
||||
}
|
||||
|
||||
QWidget::paintEvent(event);
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void AppIcon::enterEvent(QEnterEvent *event)
|
||||
#else
|
||||
void AppIcon::enterEvent(QEvent *event)
|
||||
#endif
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
m_shadowEffect->setBlurRadius(20);
|
||||
m_shadowEffect->setColor(QColor(0, 0, 0, 60));
|
||||
}
|
||||
|
||||
void AppIcon::leaveEvent(QEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
m_shadowEffect->setBlurRadius(16);
|
||||
m_shadowEffect->setColor(QColor(0, 0, 0, 40));
|
||||
}
|
||||
|
||||
void AppIcon::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_isPressed = true;
|
||||
animateScale(0.95);
|
||||
|
||||
// 启动长按计时器
|
||||
m_longPressTimerId = startTimer(LONG_PRESS_DELAY);
|
||||
}
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void AppIcon::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_longPressTimerId)
|
||||
{
|
||||
killTimer(m_longPressTimerId);
|
||||
m_longPressTimerId = 0;
|
||||
}
|
||||
|
||||
if (m_isPressed && event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_isPressed = false;
|
||||
animateScale(1.0);
|
||||
|
||||
if (rect().contains(event->pos()))
|
||||
{
|
||||
emit clicked(m_data.id);
|
||||
}
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void AppIcon::timerEvent(QTimerEvent *event)
|
||||
{
|
||||
if (event->timerId() == m_longPressTimerId)
|
||||
{
|
||||
killTimer(m_longPressTimerId);
|
||||
m_longPressTimerId = 0;
|
||||
|
||||
if (m_isPressed)
|
||||
{
|
||||
emit longPressed(m_data.id);
|
||||
}
|
||||
}
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
|
||||
void AppIcon::animateScale(qreal targetScale, int duration)
|
||||
{
|
||||
QPropertyAnimation *anim = new QPropertyAnimation(this, "scale", this);
|
||||
anim->setDuration(duration);
|
||||
anim->setStartValue(m_scale);
|
||||
anim->setEndValue(targetScale);
|
||||
anim->setEasingCurve(QEasingCurve::OutCubic);
|
||||
anim->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
Reference in New Issue
Block a user