feat(UI): add skin support

This commit is contained in:
Gary Wang 2024-09-10 08:13:03 +08:00
parent 8ac558ebc6
commit 25eed8066b
No known key found for this signature in database
GPG Key ID: 5D30A4F15EA78760
5 changed files with 102 additions and 15 deletions

BIN
icons/skin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -25,6 +25,10 @@
#include <QCollator> #include <QCollator>
#include <QMimeData> #include <QMimeData>
#include <QWindow> #include <QWindow>
#include <QStandardPaths>
constexpr QSize miniSize(490, 160);
constexpr QSize fullSize(490, 420);
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
@ -45,6 +49,7 @@ MainWindow::MainWindow(QWidget *parent)
this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint);
this->setAttribute(Qt::WA_TranslucentBackground, true); this->setAttribute(Qt::WA_TranslucentBackground, true);
loadSkinData();
initConnections(); initConnections();
initUiAndAnimation(); initUiAndAnimation();
@ -142,10 +147,14 @@ void MainWindow::paintEvent(QPaintEvent * e)
QPainter painter(this); QPainter painter(this);
painter.setPen(Qt::NoPen); painter.setPen(Qt::NoPen);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
// Temp bg if (m_skin.isNull()) {
painter.setBrush(QColor(20, 32, 83)); painter.setBrush(QColor(40, 50, 123));
painter.drawRect(0, 0, width(), height()); painter.drawRect(0, 0, width(), height());
} else {
painter.drawPixmap(0, 0, m_skin);
}
painter.setBrush(QBrush(m_bgLinearGradient)); painter.setBrush(QBrush(m_bgLinearGradient));
painter.drawRect(0, 0, width(), height()); painter.drawRect(0, 0, width(), height());
@ -198,6 +207,11 @@ void MainWindow::dropEvent(QDropEvent *e)
return; return;
} }
if (fileName.endsWith(".png") || fileName.endsWith(".jpg")) {
setSkin(fileName, true);
return;
}
const QModelIndex & modelIndex = m_playlistManager->loadPlaylist(urls); const QModelIndex & modelIndex = m_playlistManager->loadPlaylist(urls);
if (modelIndex.isValid()) { if (modelIndex.isValid()) {
loadByModelIndex(modelIndex); loadByModelIndex(modelIndex);
@ -207,9 +221,11 @@ void MainWindow::dropEvent(QDropEvent *e)
void MainWindow::loadFile() void MainWindow::loadFile()
{ {
QStringList musicFolders(QStandardPaths::standardLocations(QStandardPaths::MusicLocation));
musicFolders.append(QDir::homePath());
QStringList files = QFileDialog::getOpenFileNames(this, QStringList files = QFileDialog::getOpenFileNames(this,
tr("Select songs to play"), tr("Select songs to play"),
QDir::homePath(), musicFolders.first(),
tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)"); tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)");
QList<QUrl> urlList; QList<QUrl> urlList;
for (const QString & fileName : files) { for (const QString & fileName : files) {
@ -230,6 +246,16 @@ void MainWindow::play()
m_mediaPlayer->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() void MainWindow::centerWindow()
{ {
this->setGeometry( this->setGeometry(
@ -336,8 +362,8 @@ void MainWindow::on_minimumWindowBtn_clicked()
void MainWindow::initUiAndAnimation() void MainWindow::initUiAndAnimation()
{ {
m_bgLinearGradient.setColorAt(0, QColor(255, 255, 255, 25)); // a:0 m_bgLinearGradient.setColorAt(0, QColor(0, 0, 0, 25));
m_bgLinearGradient.setColorAt(1, QColor(255, 255, 255, 75)); // a:200 m_bgLinearGradient.setColorAt(1, QColor(0, 0, 0, 80));
m_bgLinearGradient.setStart(0, 0); m_bgLinearGradient.setStart(0, 0);
m_bgLinearGradient.setFinalStop(0, height()); m_bgLinearGradient.setFinalStop(0, height());
@ -346,7 +372,7 @@ void MainWindow::initUiAndAnimation()
m_fadeOutAnimation->setStartValue(1); m_fadeOutAnimation->setStartValue(1);
m_fadeOutAnimation->setEndValue(0); m_fadeOutAnimation->setEndValue(0);
connect(m_fadeOutAnimation, &QPropertyAnimation::finished, this, &QMainWindow::close); connect(m_fadeOutAnimation, &QPropertyAnimation::finished, this, &QMainWindow::close);
setFixedSize(490, 160); setFixedSize(miniSize);
} }
void MainWindow::initConnections() 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() void MainWindow::on_playbackModeBtn_clicked()
{ {
switch (m_playbackMode) { 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() 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) void MainWindow::on_playlistView_activated(const QModelIndex &index)
@ -504,4 +570,3 @@ void MainWindow::on_playlistView_activated(const QModelIndex &index)
loadByModelIndex(index); loadByModelIndex(index);
play(); play();
} }

View File

@ -54,6 +54,8 @@ protected:
void loadByModelIndex(const QModelIndex &index); void loadByModelIndex(const QModelIndex &index);
void play(); void play();
void setSkin(QString imagePath, bool save);
void centerWindow(); void centerWindow();
private slots: private slots:
@ -67,9 +69,8 @@ private slots:
void on_nextBtn_clicked(); void on_nextBtn_clicked();
void on_volumeBtn_clicked(); void on_volumeBtn_clicked();
void on_minimumWindowBtn_clicked(); void on_minimumWindowBtn_clicked();
void on_setSkinBtn_clicked();
void on_playListBtn_clicked(); void on_playListBtn_clicked();
void on_playlistView_activated(const QModelIndex &index); void on_playlistView_activated(const QModelIndex &index);
signals: signals:
@ -79,6 +80,7 @@ private:
bool m_clickedOnWindow = false; bool m_clickedOnWindow = false;
bool m_playbackSliderPressed = false; bool m_playbackSliderPressed = false;
QLinearGradient m_bgLinearGradient; QLinearGradient m_bgLinearGradient;
QPixmap m_skin;
enum PlaybackMode m_playbackMode = CurrentItemInLoop; enum PlaybackMode m_playbackMode = CurrentItemInLoop;
Ui::MainWindow *ui; Ui::MainWindow *ui;
@ -91,6 +93,9 @@ private:
void initUiAndAnimation(); void initUiAndAnimation();
void initConnections(); void initConnections();
void loadSkinData();
void saveSkinData();
static QString ms2str(qint64 ms); static QString ms2str(qint64 ms);
static QList<QUrl> strlst2urllst(QStringList strlst); static QList<QUrl> strlst2urllst(QStringList strlst);
}; };

View File

@ -77,11 +77,11 @@ QPushButton {
} }
QPushButton:hover { QPushButton:hover {
background-color: rgba(255, 255, 255, 220); background-color: rgba(0, 85, 255, 120);
} }
QPushButton:pressed { QPushButton:pressed {
background-color: rgba(255, 255, 255, 250); background-color: rgba(0, 85, 255, 250);
} }
QPushButton#closeWindowBtn { QPushButton#closeWindowBtn {
@ -101,6 +101,12 @@ QLabel {
QLabel#coverLabel { QLabel#coverLabel {
border: 1px solid grey; border: 1px solid grey;
}
/****** ListView ******/
QListView {
background: rgba(0, 0, 0, 50);
}</string> }</string>
</property> </property>
<property name="locale"> <property name="locale">
@ -220,7 +226,7 @@ QLabel#coverLabel {
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="QPushButton" name="miniModeBtn"> <widget class="QPushButton" name="setSkinBtn">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>25</width> <width>25</width>
@ -228,7 +234,17 @@ QLabel#coverLabel {
</size> </size>
</property> </property>
<property name="text"> <property name="text">
<string>^</string> <string/>
</property>
<property name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/icons/skin.png</normaloff>:/icons/icons/skin.png</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property> </property>
</widget> </widget>
</item> </item>

View File

@ -16,6 +16,7 @@
<file>icons/media-playlist-repeat-song.png</file> <file>icons/media-playlist-repeat-song.png</file>
<file>icons/media-playlist-normal.png</file> <file>icons/media-playlist-normal.png</file>
<file>icons/media-repeat-single.png</file> <file>icons/media-repeat-single.png</file>
<file>icons/skin.png</file>
<file>icons/media-album-cover.svg</file> <file>icons/media-album-cover.svg</file>
</qresource> </qresource>
</RCC> </RCC>