#include "StickerPanel.h" #include "StickerCache.h" #include #include #include #include #include #include #include #include #include #include #include #include StickerPanel::StickerPanel(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_TranslucentBackground, true); setAutoFillBackground(false); setFixedSize(376, 276); auto *outer = new QVBoxLayout(this); outer->setContentsMargins(8, 8, 8, 8); outer->setSpacing(0); auto *card = new QFrame(this); card->setObjectName(QStringLiteral("stickerCard")); card->setAttribute(Qt::WA_StyledBackground, true); card->setStyleSheet(QStringLiteral( "#stickerCard { background:#FFFFFF; border:1px solid #E8E8E8; border-radius:4px; }")); auto *shadow = new QGraphicsDropShadowEffect(card); shadow->setBlurRadius(22); shadow->setOffset(0, 3); shadow->setColor(QColor(0, 0, 0, 50)); card->setGraphicsEffect(shadow); auto *lay = new QVBoxLayout(card); lay->setContentsMargins(0, 0, 0, 0); lay->setSpacing(0); m_tabs = new QTabBar(card); m_tabs->setDrawBase(false); m_tabs->setExpanding(false); m_tabs->setStyleSheet(QStringLiteral( "QTabBar { background:#FFFFFF; }" "QTabBar::tab { height:32px; padding:0 12px; color:#666; background:#FFFFFF; border:none; }" "QTabBar::tab:selected { color:#07C160; background:#FFFFFF; }")); m_pages = new QStackedWidget(card); m_pages->setStyleSheet(QStringLiteral("QStackedWidget { background:#FFFFFF; border:none; }")); lay->addWidget(m_tabs); lay->addWidget(m_pages, 1); outer->addWidget(card); connect(m_tabs, &QTabBar::currentChanged, m_pages, &QStackedWidget::setCurrentIndex); connect(&StickerCache::instance(), &StickerCache::ready, this, &StickerPanel::rebuild); connect(&StickerCache::instance(), &StickerCache::stickerReady, this, [this](qint64, const QString &) { rebuild(); }); } void StickerPanel::showEvent(QShowEvent *event) { QWidget::showEvent(event); reload(); } void StickerPanel::reload() { if (StickerCache::instance().packs().isEmpty()) StickerCache::instance().sync(); else rebuild(); } void StickerPanel::rebuild() { const int keep = m_tabs->currentIndex(); while (m_tabs->count() > 0) m_tabs->removeTab(0); while (m_pages->count() > 0) { QWidget *w = m_pages->widget(0); m_pages->removeWidget(w); w->deleteLater(); } const auto packs = StickerCache::instance().packs(); for (int i = 0; i < packs.size(); ++i) { m_tabs->addTab(packs[i].name); m_pages->addWidget(buildPackPage(i)); } if (packs.isEmpty()) { auto *empty = new QLabel(QStringLiteral("表情包加载中…"), m_pages); empty->setAlignment(Qt::AlignCenter); empty->setStyleSheet(QStringLiteral("color:#B0B0B0; background:#FFFFFF;")); m_pages->addWidget(empty); } if (keep >= 0 && keep < m_tabs->count()) m_tabs->setCurrentIndex(keep); } QWidget *StickerPanel::buildPackPage(int packIndex) { const auto packs = StickerCache::instance().packs(); auto *page = new QWidget(m_pages); page->setStyleSheet(QStringLiteral("background:#FFFFFF;")); auto *outer = new QVBoxLayout(page); outer->setContentsMargins(0, 0, 0, 0); auto *scroll = new QScrollArea(page); scroll->setWidgetResizable(true); scroll->setFrameShape(QFrame::NoFrame); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setStyleSheet(QStringLiteral( "QScrollArea { background:#FFFFFF; border:none; }" "QScrollBar:vertical { background:#FFFFFF; width:8px; }" "QScrollBar::handle:vertical { background:#D0D0D0; border-radius:4px; }" "QScrollBar:horizontal { height:0px; }")); auto *host = new QWidget(scroll); host->setStyleSheet(QStringLiteral("background:#FFFFFF;")); auto *grid = new QGridLayout(host); grid->setContentsMargins(8, 8, 8, 8); grid->setSpacing(4); if (packIndex >= 0 && packIndex < packs.size()) { const auto &pack = packs[packIndex]; int col = 0; int row = 0; for (const auto &s : pack.stickers) { auto *btn = new QPushButton(host); btn->setFlat(true); btn->setCursor(Qt::PointingHandCursor); btn->setFixedSize(50, 50); btn->setStyleSheet(QStringLiteral( "QPushButton { background:#FFFFFF; border:none; border-radius:4px; }" "QPushButton:hover { background:#F5F5F5; }")); const QPixmap pm = StickerCache::instance().pixmap(pack.id, s.code, 44); if (!pm.isNull()) btn->setIcon(QIcon(pm)); btn->setIconSize(QSize(44, 44)); const qint64 packId = pack.id; const QString code = s.code; connect(btn, &QPushButton::clicked, this, [this, packId, code]() { emit stickerPicked(packId, code); }); grid->addWidget(btn, row, col); if (++col >= 6) { col = 0; ++row; } } } scroll->setWidget(host); outer->addWidget(scroll); return page; }