feat(UI): add skin support
This commit is contained in:
parent
8ac558ebc6
commit
25eed8066b
BIN
icons/skin.png
Normal file
BIN
icons/skin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user