| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- #include "StickerPanel.h"
- #include "StickerCache.h"
- #include <QColor>
- #include <QFrame>
- #include <QGraphicsDropShadowEffect>
- #include <QGridLayout>
- #include <QIcon>
- #include <QLabel>
- #include <QPushButton>
- #include <QScrollArea>
- #include <QShowEvent>
- #include <QStackedWidget>
- #include <QTabBar>
- #include <QVBoxLayout>
- 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;
- }
|