From 25eed8066b69b03470d37942e853b4c134928274 Mon Sep 17 00:00:00 2001 From: Gary Wang Date: Tue, 10 Sep 2024 08:13:03 +0800 Subject: [PATCH] feat(UI): add skin support --- icons/skin.png | Bin 0 -> 3064 bytes mainwindow.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++------ mainwindow.h | 9 ++++-- mainwindow.ui | 24 +++++++++++--- resources.qrc | 1 + 5 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 icons/skin.png diff --git a/icons/skin.png b/icons/skin.png new file mode 100644 index 0000000000000000000000000000000000000000..9bce49bcafcf61882e89dc62394b00727ce470be GIT binary patch literal 3064 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 #include #include +#include + +constexpr QSize miniSize(490, 160); +constexpr QSize fullSize(490, 420); MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) @@ -45,6 +49,7 @@ MainWindow::MainWindow(QWidget *parent) this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); this->setAttribute(Qt::WA_TranslucentBackground, true); + loadSkinData(); initConnections(); initUiAndAnimation(); @@ -142,10 +147,14 @@ void MainWindow::paintEvent(QPaintEvent * e) QPainter painter(this); painter.setPen(Qt::NoPen); + painter.setRenderHint(QPainter::SmoothPixmapTransform); - // Temp bg - painter.setBrush(QColor(20, 32, 83)); - painter.drawRect(0, 0, width(), height()); + if (m_skin.isNull()) { + painter.setBrush(QColor(40, 50, 123)); + painter.drawRect(0, 0, width(), height()); + } else { + painter.drawPixmap(0, 0, m_skin); + } painter.setBrush(QBrush(m_bgLinearGradient)); painter.drawRect(0, 0, width(), height()); @@ -198,6 +207,11 @@ void MainWindow::dropEvent(QDropEvent *e) return; } + if (fileName.endsWith(".png") || fileName.endsWith(".jpg")) { + setSkin(fileName, true); + return; + } + const QModelIndex & modelIndex = m_playlistManager->loadPlaylist(urls); if (modelIndex.isValid()) { loadByModelIndex(modelIndex); @@ -207,9 +221,11 @@ void MainWindow::dropEvent(QDropEvent *e) void MainWindow::loadFile() { + QStringList musicFolders(QStandardPaths::standardLocations(QStandardPaths::MusicLocation)); + musicFolders.append(QDir::homePath()); QStringList files = QFileDialog::getOpenFileNames(this, tr("Select songs to play"), - QDir::homePath(), + musicFolders.first(), tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)"); QList urlList; for (const QString & fileName : files) { @@ -230,6 +246,16 @@ void MainWindow::play() m_mediaPlayer->play(); } +void MainWindow::setSkin(QString imagePath, bool save) +{ + m_skin = QPixmap(imagePath); + if (save) { + saveSkinData(); + } + m_skin = m_skin.scaled(fullSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + update(); +} + void MainWindow::centerWindow() { this->setGeometry( @@ -336,8 +362,8 @@ void MainWindow::on_minimumWindowBtn_clicked() void MainWindow::initUiAndAnimation() { - m_bgLinearGradient.setColorAt(0, QColor(255, 255, 255, 25)); // a:0 - m_bgLinearGradient.setColorAt(1, QColor(255, 255, 255, 75)); // a:200 + m_bgLinearGradient.setColorAt(0, QColor(0, 0, 0, 25)); + m_bgLinearGradient.setColorAt(1, QColor(0, 0, 0, 80)); m_bgLinearGradient.setStart(0, 0); m_bgLinearGradient.setFinalStop(0, height()); @@ -346,7 +372,7 @@ void MainWindow::initUiAndAnimation() m_fadeOutAnimation->setStartValue(1); m_fadeOutAnimation->setEndValue(0); connect(m_fadeOutAnimation, &QPropertyAnimation::finished, this, &QMainWindow::close); - setFixedSize(490, 160); + setFixedSize(miniSize); } void MainWindow::initConnections() @@ -476,6 +502,34 @@ void MainWindow::initConnections() }); } +void MainWindow::loadSkinData() +{ + QFile file(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation) + "/skin.dat"); + bool canOpen = file.open(QIODevice::ReadOnly); + if (!canOpen) return; + QDataStream stream(&file); + quint32 magic; + stream >> magic; + if (magic == 0x78297000) { + stream >> m_skin; + m_skin = m_skin.scaled(fullSize, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + } + file.close(); +} + +void MainWindow::saveSkinData() +{ + QDir configDir(QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation)); + if (!configDir.exists()) { + configDir.mkpath("."); + } + QFile file(configDir.absoluteFilePath("skin.dat")); + file.open(QIODevice::WriteOnly); + QDataStream stream(&file); + stream << (quint32)0x78297000 << m_skin; + file.close(); +} + void MainWindow::on_playbackModeBtn_clicked() { switch (m_playbackMode) { @@ -493,9 +547,21 @@ void MainWindow::on_playbackModeBtn_clicked() } } +void MainWindow::on_setSkinBtn_clicked() +{ + QStringList imageFolders(QStandardPaths::standardLocations(QStandardPaths::PicturesLocation)); + imageFolders.append(QDir::homePath()); + QString image = QFileDialog::getOpenFileName(this, tr("Select image as background skin"), + imageFolders.first(), + tr("Image files (*.jpg *.jpeg *.png)")); + if(!image.isEmpty()) { + setSkin(image, true); + } +} + void MainWindow::on_playListBtn_clicked() { - setFixedHeight(size().height() < 200 ? 420 : 160); + setFixedSize(size().height() < 200 ? fullSize : miniSize); } void MainWindow::on_playlistView_activated(const QModelIndex &index) @@ -504,4 +570,3 @@ void MainWindow::on_playlistView_activated(const QModelIndex &index) loadByModelIndex(index); play(); } - diff --git a/mainwindow.h b/mainwindow.h index 54929dd..21fc21f 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -54,6 +54,8 @@ protected: void loadByModelIndex(const QModelIndex &index); void play(); + void setSkin(QString imagePath, bool save); + void centerWindow(); private slots: @@ -67,9 +69,8 @@ private slots: void on_nextBtn_clicked(); void on_volumeBtn_clicked(); void on_minimumWindowBtn_clicked(); - + void on_setSkinBtn_clicked(); void on_playListBtn_clicked(); - void on_playlistView_activated(const QModelIndex &index); signals: @@ -79,6 +80,7 @@ private: bool m_clickedOnWindow = false; bool m_playbackSliderPressed = false; QLinearGradient m_bgLinearGradient; + QPixmap m_skin; enum PlaybackMode m_playbackMode = CurrentItemInLoop; Ui::MainWindow *ui; @@ -91,6 +93,9 @@ private: void initUiAndAnimation(); void initConnections(); + void loadSkinData(); + void saveSkinData(); + static QString ms2str(qint64 ms); static QList strlst2urllst(QStringList strlst); }; diff --git a/mainwindow.ui b/mainwindow.ui index 8660b7a..3ca70e7 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -77,11 +77,11 @@ QPushButton { } QPushButton:hover { - background-color: rgba(255, 255, 255, 220); + background-color: rgba(0, 85, 255, 120); } QPushButton:pressed { - background-color: rgba(255, 255, 255, 250); + background-color: rgba(0, 85, 255, 250); } QPushButton#closeWindowBtn { @@ -101,6 +101,12 @@ QLabel { QLabel#coverLabel { border: 1px solid grey; +} + +/****** ListView ******/ + +QListView { + background: rgba(0, 0, 0, 50); } @@ -220,7 +226,7 @@ QLabel#coverLabel { - + 25 @@ -228,7 +234,17 @@ QLabel#coverLabel { - ^ + + + + + :/icons/icons/skin.png:/icons/icons/skin.png + + + + 24 + 24 + diff --git a/resources.qrc b/resources.qrc index 0a8fa44..9b34525 100644 --- a/resources.qrc +++ b/resources.qrc @@ -16,6 +16,7 @@ icons/media-playlist-repeat-song.png icons/media-playlist-normal.png icons/media-repeat-single.png + icons/skin.png icons/media-album-cover.svg