From 679fc61febb4702a4cb22075409adda6b522ee4e Mon Sep 17 00:00:00 2001 From: Maurice O'Neal Date: Sun, 23 Oct 2016 21:26:58 -0400 Subject: [PATCH] I've updated the icons to a new hallow outline transparent look. added stop, next file, previous file buttons along with the added feasures the buttons represent. i've also added png versions of all of the icons just in case the svg versions are not practical to use. i also fully built out a tray icon functionality so the application can now minimize to system tray. also updated the app logo to a new flat icon type sinewave look. then finally, i've added the restore button to the tray icon so it will restore the window back in front from the tray. --- JustAudio.pro | 12 ++--- app_logo.ico | Bin 23230 -> 3774 bytes gui/icon.cpp | 89 ++++++++++++++++++++++++++++++---- gui/icon.h | 16 ++++++- gui/ui.cpp | 113 ++++++++++++++++++++++++++++++++++---------- gui/ui.h | 16 ++++++- icon_files.qrc | 22 ++++++++- io/aud_file.cpp | 49 +++++++++++++++++-- io/aud_file.h | 18 ++++++- io/conf.cpp | 35 +++++++++----- io/conf.h | 1 + main.cpp | 1 + png/menu.png | Bin 0 -> 2732 bytes png/next.png | Bin 0 -> 3486 bytes png/open.png | Bin 0 -> 2231 bytes png/pause.png | Bin 0 -> 2251 bytes png/play.png | Bin 0 -> 5703 bytes png/prev.png | Bin 0 -> 3499 bytes png/restore.png | Bin 0 -> 2289 bytes png/stop.png | Bin 0 -> 2195 bytes png/volume_down.png | Bin 0 -> 3015 bytes png/volume_up.png | Bin 0 -> 3067 bytes svg/menu.svg | 12 ++--- svg/next.svg | 11 +++++ svg/open.svg | 11 +++-- svg/pause.svg | 14 +++--- svg/play.svg | 11 +++-- svg/prev.svg | 11 +++++ svg/restore.svg | 12 +++++ svg/stop.svg | 11 +++++ svg/volume_down.svg | 12 +++++ svg/volume_up.svg | 12 +++++ 32 files changed, 409 insertions(+), 80 deletions(-) create mode 100644 png/menu.png create mode 100644 png/next.png create mode 100644 png/open.png create mode 100644 png/pause.png create mode 100644 png/play.png create mode 100644 png/prev.png create mode 100644 png/restore.png create mode 100644 png/stop.png create mode 100644 png/volume_down.png create mode 100644 png/volume_up.png create mode 100644 svg/next.svg create mode 100644 svg/prev.svg create mode 100644 svg/restore.svg create mode 100644 svg/stop.svg create mode 100644 svg/volume_down.svg create mode 100644 svg/volume_up.svg diff --git a/JustAudio.pro b/JustAudio.pro index 0ea749c..6edcb5b 100644 --- a/JustAudio.pro +++ b/JustAudio.pro @@ -17,16 +17,16 @@ SOURCES += main.cpp\ gui/ui.cpp\ gui/icon.cpp \ io/aud_file.cpp \ - io/conf.cpp \ - io/idm.cpp \ - io/int.cpp + io/conf.cpp \ + io/idm.cpp \ + io/int.cpp HEADERS += gui/ui.h\ gui/icon.h \ io/aud_file.h \ - io/conf.h \ - io/idm.h \ - io/int.h + io/conf.h \ + io/idm.h \ + io/int.h RESOURCES += icon_files.qrc diff --git a/app_logo.ico b/app_logo.ico index 72d8b75b85834ee580c5f6794e128e190b0b8401..9cfd016b6da49ce7961be1cd02cacfe61d44d039 100644 GIT binary patch literal 3774 zcmZQzU}RuoaBvU+(ku)aTnr3q3=BX%6OhlyV8Ft_&<7OL0Eq!{0}zAM;Q|@gZ5Vi- zpT;FkP+Vy^0YyO|5W?-FQF%!CfKvsQV1k9us5~$PC=VY{YD6&wEqn)qJj4yq2#2{3 z$)`|A*Q`Gz|(D(!v>{nnV({oyiC;Xs{7LW3dU3ij9WAXb6m;5C8xT C_jp$T literal 23230 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 diff --git a/gui/icon.cpp b/gui/icon.cpp index d8146bd..e68c0fd 100644 --- a/gui/icon.cpp +++ b/gui/icon.cpp @@ -17,29 +17,73 @@ Icon::Icon(IconType t, QWidget *parent) : QToolButton(parent) stateChanged(QMediaPlayer::StoppedState); setToolTip(tr("Pause/Play")); - connect(this, SIGNAL(clicked()), this, SLOT(buttonClicked())); - break; } case MENU: { - loadImg(":/menu"); + loadImg(":/svg/menu"); setToolTip(tr("Menu")); break; } case OPEN: { - loadImg(":/open"); + loadImg(":/svg/open"); setToolTip(tr("Open File")); - connect(this, SIGNAL(clicked()), this, SLOT(buttonClicked())); + break; + } + case STOP: + { + loadImg(":/svg/stop"); + setToolTip(tr("Stop")); + + break; + } + case PREV: + { + loadImg(":/svg/prev"); + setToolTip(tr("Previous File")); + + break; + } + case NEXT: + { + loadImg(":/svg/next"); + setToolTip(tr("Next File")); + + break; + } + case VOL_UP: + { + loadImg(":/svg/volume_up"); + setToolTip(tr("Volume Up")); + + break; + } + case VOL_DOWN: + { + loadImg(":/svg/volume_down"); + setToolTip(tr("Volume Down")); + + break; + } + case RESTORE: + { + loadImg(":/svg/restore"); + setToolTip(tr("Restore")); break; } } - type = t; + if (t != MENU) + { + connect(this, SIGNAL(clicked()), this, SLOT(buttonClicked())); + } + + type = t; + volSlider = 0; } void Icon::buttonClicked() @@ -59,6 +103,30 @@ void Icon::buttonClicked() { emit open(); } + else if (type == NEXT) + { + emit next(); + } + else if (type == PREV) + { + emit prev(); + } + else if (type == STOP) + { + emit stop(); + } + else if ((type == VOL_DOWN) && volSlider) + { + volSlider->setValue(volSlider->value() - 1); + } + else if ((type == VOL_UP) && volSlider) + { + volSlider->setValue(volSlider->value() + 1); + } + else if (type == RESTORE) + { + emit restore(); + } } void Icon::paintEvent(QPaintEvent *) @@ -75,11 +143,11 @@ void Icon::stateChanged(QMediaPlayer::State state) if (state == QMediaPlayer::PlayingState) { - loadImg(":/pause"); + loadImg(":/svg/pause"); } else { - loadImg(":/play"); + loadImg(":/svg/play"); } } @@ -89,3 +157,8 @@ void Icon::loadImg(const QString &path) update(); } + +void Icon::setSlider(QSlider *slider) +{ + volSlider = slider; +} diff --git a/gui/icon.h b/gui/icon.h index f0f56f8..0bf6f83 100644 --- a/gui/icon.h +++ b/gui/icon.h @@ -12,6 +12,7 @@ #include #include #include +#include class Icon : public QToolButton { @@ -23,11 +24,19 @@ public: { PAUSE_PLAY, MENU, - OPEN + OPEN, + STOP, + PREV, + NEXT, + VOL_UP, + VOL_DOWN, + RESTORE }; Icon(IconType t, QWidget *parent = 0); + void setSlider(QSlider *slider); + public slots: void stateChanged(QMediaPlayer::State state); @@ -37,6 +46,7 @@ private: IconType type; QMediaPlayer::State playerState; QString svgFile; + QSlider *volSlider; void paintEvent(QPaintEvent *); void loadImg(const QString &path); @@ -51,6 +61,10 @@ signals: void play(); void settings(); void open(); + void next(); + void prev(); + void stop(); + void restore(); }; #endif // ICON_H diff --git a/gui/ui.cpp b/gui/ui.cpp index c51e9ce..4a3df29 100644 --- a/gui/ui.cpp +++ b/gui/ui.cpp @@ -2,10 +2,17 @@ Ui::Ui(const QStringList &args, QWidget *parent) : QWidget(parent) { - QWidget *btnWid = new QWidget(this); - QHBoxLayout *btnLayout = new QHBoxLayout(btnWid); - QVBoxLayout *mainLayout = new QVBoxLayout(this); + QWidget *btnWid = new QWidget(this); + QHBoxLayout *btnLayout = new QHBoxLayout(btnWid); + QVBoxLayout *mainLayout = new QVBoxLayout(this); + Icon *trayPausePlay = new Icon(Icon::PAUSE_PLAY, this); + Icon *trayOpen = new Icon(Icon::OPEN, this); + Icon *trayStop = new Icon(Icon::STOP, this); + Icon *trayNext = new Icon(Icon::NEXT, this); + Icon *trayPrev = new Icon(Icon::PREV, this); + Icon *trayRestore = new Icon(Icon::RESTORE, this); + trayMenu = new QMenu(this); fileName = new QLabel(this); slider = new QSlider(this); menu = new QMenu(this); @@ -13,6 +20,9 @@ Ui::Ui(const QStringList &args, QWidget *parent) : QWidget(parent) settings = new Icon(Icon::MENU, this); pausePlay = new Icon(Icon::PAUSE_PLAY, this); open = new Icon(Icon::OPEN, this); + stop = new Icon(Icon::STOP, this); + next = new Icon(Icon::NEXT, this); + prev = new Icon(Icon::PREV, this); player = new QMediaPlayer(this); ioDev = new AudFile(this); conf = new Conf(this); @@ -29,22 +39,44 @@ Ui::Ui(const QStringList &args, QWidget *parent) : QWidget(parent) fileName->setFont(fnt); slider->setOrientation(Qt::Horizontal); trayIcon->show(); + trayIcon->setContextMenu(trayMenu); conf->populateOptionsMenu(menu, this); player->setVolume(conf->getVolume()); + trayMenu->addAction(new MenuItem(trayPausePlay->toolTip(), trayPausePlay, this)); + trayMenu->addAction(new MenuItem(trayOpen->toolTip(), trayOpen, this)); + trayMenu->addAction(new MenuItem(trayStop->toolTip(), trayStop, this)); + trayMenu->addAction(new MenuItem(trayNext->toolTip(), trayNext, this)); + trayMenu->addAction(new MenuItem(trayPrev->toolTip(), trayPrev, this)); + trayMenu->addAction(new MenuItem(trayRestore->toolTip(), trayRestore, this)); + btnLayout->addWidget(prev); btnLayout->addWidget(pausePlay); + btnLayout->addWidget(stop); + btnLayout->addWidget(next); btnLayout->addWidget(open); btnLayout->addWidget(settings); mainLayout->addWidget(fileName); mainLayout->addWidget(slider); mainLayout->addWidget(btnWid, 0, Qt::AlignCenter); + connect(trayRestore, SIGNAL(restore()), this, SLOT(showNormal())); + connect(trayPausePlay, SIGNAL(pause()), player, SLOT(pause())); + connect(trayPausePlay, SIGNAL(play()), player, SLOT(play())); + connect(trayNext, SIGNAL(next()), this, SLOT(nextFile())); + connect(trayPrev, SIGNAL(prev()), this, SLOT(prevFile())); + connect(trayStop, SIGNAL(stop()), this, SLOT(stopPlayer())); + connect(trayOpen, SIGNAL(open()), this, SLOT(openDialog())); + connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayActivated(QSystemTrayIcon::ActivationReason))); connect(pausePlay, SIGNAL(pause()), player, SLOT(pause())); connect(pausePlay, SIGNAL(play()), player, SLOT(play())); + connect(next, SIGNAL(next()), this, SLOT(nextFile())); + connect(prev, SIGNAL(prev()), this, SLOT(prevFile())); + connect(stop, SIGNAL(stop()), this, SLOT(stopPlayer())); connect(open, SIGNAL(open()), this, SLOT(openDialog())); connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(error(QMediaPlayer::Error))); connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), pausePlay, SLOT(stateChanged(QMediaPlayer::State))); - connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(posChanged(qint64))); - connect(player, SIGNAL(durationChanged(qint64)), this, SLOT(durChanged(qint64))); + connect(player, SIGNAL(stateChanged(QMediaPlayer::State)), trayPausePlay, SLOT(stateChanged(QMediaPlayer::State))); + connect(ioDev, SIGNAL(posChanged(qint64)), this, SLOT(posChanged(qint64))); + connect(ioDev, SIGNAL(endOfPlayback()), this, SLOT(nextFile())); connect(slider, SIGNAL(sliderPressed()), this, SLOT(sliderPressed())); connect(slider, SIGNAL(sliderReleased()), this, SLOT(sliderReleased())); connect(conf, SIGNAL(volume(int)), player, SLOT(setVolume(int))); @@ -57,9 +89,7 @@ Ui::Ui(const QStringList &args, QWidget *parent) : QWidget(parent) void Ui::play(const QString &path) { - player->blockSignals(true); - player->stop(); - pausePlay->stateChanged(QMediaPlayer::StoppedState); + stopPlayer(); if (ioDev->openFile(path)) { @@ -68,9 +98,8 @@ void Ui::play(const QString &path) conf->setLastPath(info.path()); fileName->setText(info.fileName()); player->setMedia(0, ioDev); - slider->setValue(0); - slider->setMinimum(0); - pausePlay->stateChanged(QMediaPlayer::PlayingState); + slider->setMinimum(ioDev->getOffset()); + slider->setMaximum(ioDev->size()); player->play(); adjustSize(); @@ -79,8 +108,14 @@ void Ui::play(const QString &path) { error(QMediaPlayer::ResourceError); } +} - player->blockSignals(false); +void Ui::stopPlayer() +{ + ioDev->blockSignals(true); + player->stop(); + ioDev->blockSignals(false); + slider->setValue(ioDev->getOffset()); } void Ui::openDialog() @@ -139,25 +174,29 @@ void Ui::sliderReleased() { pressed = false; - player->setPosition(slider->value()); + float pos = (float) slider->value() - ioDev->getOffset(); + float max = (float) slider->maximum() - ioDev->getOffset(); + float mul = pos / max; + + player->setPosition(mul * player->duration()); } void Ui::posChanged(qint64 pos) { if (!pressed) slider->setSliderPosition(pos); - - if ((slider->sliderPosition() == slider->maximum()) && conf->nextFile()) - { - QTimer::singleShot(1000, this, SLOT(nextFile())); - } -} - -void Ui::durChanged(qint64 len) -{ - slider->setMaximum(len); } void Ui::nextFile() +{ + fileDir('+'); +} + +void Ui::prevFile() +{ + fileDir('-'); +} + +void Ui::fileDir(char direction) { QDir dir(conf->getLastPath()); @@ -173,7 +212,8 @@ void Ui::nextFile() if (pos != -1) { - pos++; + if (direction == '+') pos++; + else if (direction == '-') pos--; if (pos < list.size()) { @@ -181,3 +221,28 @@ void Ui::nextFile() } } } + +void Ui::trayActivated(QSystemTrayIcon::ActivationReason reason) +{ + Q_UNUSED(reason); + + trayMenu->popup(trayIcon->geometry().center()); +} + +void Ui::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::WindowStateChange) + { + if (windowState() & Qt::WindowMinimized) + { + hide(); + } + } +} + +void Ui::closeEvent(QCloseEvent *event) +{ + Q_UNUSED(event); + + QCoreApplication::exit(); +} diff --git a/gui/ui.h b/gui/ui.h index e3b5b95..fcfb4ef 100644 --- a/gui/ui.h +++ b/gui/ui.h @@ -20,6 +20,10 @@ #include #include #include +#include +#include +#include +#include #include "icon.h" #include "../io/aud_file.h" @@ -39,20 +43,30 @@ private: QSystemTrayIcon *trayIcon; Conf *conf; QMenu *menu; + QMenu *trayMenu; Icon *pausePlay; Icon *open; + Icon *next; + Icon *prev; + Icon *stop; bool pressed; + void fileDir(char direction); + void changeEvent(QEvent *event); + void closeEvent(QCloseEvent *event); + private slots: void error(QMediaPlayer::Error error); void sliderPressed(); void sliderReleased(); void posChanged(qint64 pos); - void durChanged(qint64 len); void openDialog(); void nextFile(); + void prevFile(); + void stopPlayer(); void play(const QString &path); + void trayActivated(QSystemTrayIcon::ActivationReason reason); public: diff --git a/icon_files.qrc b/icon_files.qrc index df5f091..c91a966 100644 --- a/icon_files.qrc +++ b/icon_files.qrc @@ -1,9 +1,29 @@ + app_logo.ico + + svg/open.svg svg/pause.svg svg/play.svg svg/menu.svg - app_logo.ico + svg/next.svg + svg/prev.svg + svg/stop.svg + svg/volume_up.svg + svg/volume_down.svg + svg/restore.svg + + + png/open.png + png/pause.png + png/play.png + png/menu.png + png/next.png + png/prev.png + png/stop.png + png/volume_up.png + png/volume_down.png + png/restore.png diff --git a/io/aud_file.cpp b/io/aud_file.cpp index 50fa46b..3d335fd 100644 --- a/io/aud_file.cpp +++ b/io/aud_file.cpp @@ -2,7 +2,9 @@ AudFile::AudFile(QObject *parent) : QFile(parent) { - offset = 0; + offset = 0; + buffRate = 0; + init = true; } AudFile::~AudFile() @@ -14,6 +16,9 @@ bool AudFile::openFile(const QString &path) { close(); + init = true; + buffRate = 0; + setFileName(path); bool ret = open(QFile::ReadOnly); @@ -57,10 +62,46 @@ bool AudFile::openFile(const QString &path) bool AudFile::seek(qint64 off) { - return QFile::seek(offset + off); + qint64 newPos = offset + off; + + if (init) + { + if ((off) && (!buffRate)) + { + buffRate = off; + + emit duration(getDuration()); + } + + if (newPos >= size()) + { + init = false; + } + } + else + { + emit posChanged(pos()); + + if (newPos >= size()) + { + QTimer::singleShot(2000, this, SLOT(delayFinished())); + } + } + + return QFile::seek(newPos); } -qint64 AudFile::size() const +qint64 AudFile::getOffset() { - return QFile::size() - offset; + return offset; +} + +qint64 AudFile::getDuration() +{ + return ((size() - offset) / buffRate) * 1000; +} + +void AudFile::delayFinished() +{ + emit endOfPlayback(); } diff --git a/io/aud_file.h b/io/aud_file.h index 5ea927a..75e18dd 100644 --- a/io/aud_file.h +++ b/io/aud_file.h @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include class AudFile : public QFile { @@ -13,7 +14,13 @@ class AudFile : public QFile private: + qint64 buffRate; qint64 offset; + bool init; + +private slots: + + void delayFinished(); public: @@ -21,9 +28,16 @@ public: bool openFile(const QString &path); bool seek(qint64 off); - qint64 size() const; + qint64 getOffset(); + qint64 getDuration(); ~AudFile(); + +signals: + + void posChanged(qint64 off); + void endOfPlayback(); + void duration(qint64 msec); }; #endif // AUD_FILE_H diff --git a/io/conf.cpp b/io/conf.cpp index fe62c99..4b588fa 100644 --- a/io/conf.cpp +++ b/io/conf.cpp @@ -8,14 +8,23 @@ MenuItem::MenuItem(const QString &label, QWidget *widget, QObject *parent) : QWi QWidget *MenuItem::createWidget(QWidget *parent) { - QWidget *widget = new QWidget(parent); - QHBoxLayout *layout = new QHBoxLayout(widget); + if (str.isEmpty()) + { + wid->setParent(parent); - layout->addWidget(new QLabel(str, parent)); - layout->addStretch(); - layout->addWidget(wid, 0, Qt::AlignRight); + return wid; + } + else + { + QWidget *widget = new QWidget(parent); + QHBoxLayout *layout = new QHBoxLayout(widget); - return widget; + layout->addWidget(wid); + layout->addWidget(new QLabel(str, parent)); + + return widget; + + } } Conf::Conf(QObject *parent) : QObject(parent) @@ -70,23 +79,27 @@ void Conf::populateOptionsMenu(QMenu *menu, QWidget *parent) QHBoxLayout *volLayout = new QHBoxLayout(volWidget); QSlider *volSlider = new QSlider(parent); QCheckBox *nextBox = new QCheckBox(parent); + Icon *volUp = new Icon(Icon::VOL_UP, parent); + Icon *volDown = new Icon(Icon::VOL_DOWN, parent); + volUp->setSlider(volSlider); + volDown->setSlider(volSlider); volSlider->setMinimum(0); volSlider->setMaximum(100); volSlider->setValue(getVolume()); volSlider->setOrientation(Qt::Horizontal); - volLayout->addWidget(new QLabel("-")); + volLayout->addWidget(volDown); volLayout->addWidget(volSlider); - volLayout->addWidget(new QLabel("+")); - nextBox->setText(""); + volLayout->addWidget(volUp); + nextBox->setText(tr("Auto play next file in directory")); nextBox->setChecked(nextFile()); connect(volSlider, SIGNAL(valueChanged(int)), this, SLOT(setVolume(int))); connect(volSlider, SIGNAL(valueChanged(int)), this, SIGNAL(volume(int))); connect(nextBox, SIGNAL(clicked(bool)), this, SLOT(setNextFile(bool))); - menu->addAction(new MenuItem(tr("Volume"), volWidget, this)); - menu->addAction(new MenuItem(tr("Auto play next file in directory"), nextBox, this)); + menu->addAction(new MenuItem("", volWidget, this)); + menu->addAction(new MenuItem("", nextBox, this)); } void Conf::setLastPath(const QString &path) diff --git a/io/conf.h b/io/conf.h index 97e6ba9..1d57833 100644 --- a/io/conf.h +++ b/io/conf.h @@ -14,6 +14,7 @@ #include #include "idm.h" +#include "../gui/icon.h" class MenuItem : public QWidgetAction { diff --git a/main.cpp b/main.cpp index a8df9ea..77ceec9 100644 --- a/main.cpp +++ b/main.cpp @@ -8,6 +8,7 @@ int main(int argc, char *argv[]) QApplication app(argc, argv); Ui win(app.arguments()); + app.setQuitOnLastWindowClosed(false); win.show(); return app.exec(); diff --git a/png/menu.png b/png/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..25d3bac2df2a97af48dd677ea347909006059949 GIT binary patch literal 2732 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 literal 0 HcmV?d00001 diff --git a/png/pause.png b/png/pause.png new file mode 100644 index 0000000000000000000000000000000000000000..403bf066eeb824cd88ca5bd669d21e140cc215af GIT binary patch literal 2251 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8Y9Be?5)7S2I0V&4fAa^H*b?0PW0y!+{j=qiz z3>*8o|0J>k`J4qFk;M!Qe1|}oQB=dLfq{V|!PCVtq$2L^4acn41|kj@cW_^Qv?cKR zd@d)pgOhjt+&9Pgq_otRN8MZBwzD%7WXHc2XV_ur$lky(%yC1m{Tj)*9>Z%#<`nxf z{8x8;uIpGY^yU1v5Xv? d_x|G#Hpj042gRD-8v+|344$rjF6*2UngGUEO>h7J literal 0 HcmV?d00001 diff --git a/png/play.png b/png/play.png new file mode 100644 index 0000000000000000000000000000000000000000..1a9b4e2d346ff4c8d1fcf004e1dd371de823309d GIT binary patch literal 5703 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 G<$nM+;=C^a literal 0 HcmV?d00001 diff --git a/png/prev.png b/png/prev.png new file mode 100644 index 0000000000000000000000000000000000000000..f6247d1dd57cf15d0583998d1b186b0921458e63 GIT binary patch literal 3499 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 literal 0 HcmV?d00001 diff --git a/png/stop.png b/png/stop.png new file mode 100644 index 0000000000000000000000000000000000000000..39e14987334ea1bf59cb35a5614bbb85893e4635 GIT binary patch literal 2195 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8Y9Be?5)7S2I0V&4fAa^H*b?0PW0y!+{j=qiz z3>*8o|0J>k`J4qFk;M!Qe1|}oQB=dLfq{WT!_&nvq$2L^^^Jvx4Fp^rFSahSF!3_B zcv_-R`6JEz;ChDqcNY5k3=b~WJ!55%^SQvN;4q2_hQR|1{mnZQ*P3!S_}{8N|AbP0l+XkK**HRk literal 0 HcmV?d00001 diff --git a/png/volume_down.png b/png/volume_down.png new file mode 100644 index 0000000000000000000000000000000000000000..27b8b418cfe1da2ccc71c3ecdf7edb6e089a0a49 GIT binary patch literal 3015 zcmeHJZ%`9w9uBvwNeXTf(z8gjH2e##1p>xS%^C{}aRB8{qqaaxQxZkmQLkyTa3~xl zYugQlDkD|HH0nw})Q%R?=}@8CbJOImwnW^{c@`_z289^W(wwD+S}OMo_obhmxz2Rv zKD_hH@7-tLecpF>pXb;9WO>n&`x5UH2n0(?iuD@=f|!};5G{t8;fvqC0T5%`P*fo3 z8&O<`0<9;@NP*yky|HtqMNo?^#nm=}0DnC?VxH@j+XaHyni4&^smb`=zp6L9^I78B zFRx&4d0yBs!c7@YNS+K zg+u!xfW)EI$f&k&2M=meN#SgJm*!DYI2do+3g^-9b6pY>?v)YiaulyR(6uoo#O?FB z5=r3!v-#b1yuD7Ot)sC_(*K^EQdan@?JQC~J$XXU+tZTkAEU7ehxXBUO1aiwy`M$I zaHX8LUl(gdM2IU^==vT~VusPKq&wwpyZ%B)RCSmYm4+pH5R02hlC+SJTt;G9S; zY#pk(dq=o6J;ZhG*`xKtV&e|&SOsr4DgL56X<4b%U%|F_lM=o_i`$*$&6i= zQi1!YC*4`35W8l?F2n4T#!0sX%G99yAyU`~vp>tJ+REukOB|F}pTa(qQMEQzjS7lUS z>-1z!HYxnm6(hD89=RUMCrIHFb!G;(AI^?gogFOlO3nw~78IX-ty1eR;q9-qYyIo_ zn21#*rK()b+LaF>>9`TwCZ|LewGhQs*Pg;o%P6PQiOfqWXIHZ}yqaV_ zA3TVB53`O+ZCFM!V&|y6Uqr-BpY1v$vpKt2FE=)9e^yMyec{8#3VBn`^dy&x;)`K( zx^=us3gw@H&-t*HgRHk5$nT2?m+uqB=swmfj+SCV;rC%TNq$@jIl{1%JMDCBmO)G)+gnTYP_L z+RJ*=zA4BKaz(H;*9#KzWx;sQ)pz?+oj{|Yu^Eez}Z9F%2& z(BiWTdi8#LmY8tm`xoS%1@#^M6}Y2+$E!d5v}ViG#^0ei{Fa8cU_?FL3qG`FI_g8` z>N@5d?`m$$3sb9pigXR_Jc{JEvG*|k{~CUqZ2I*pG&Bs=^c_j~=h8Dw>xjz}i(?b& z9h?#V+}leVOu~;;AxpeL_)%KOk^+ztvaFEn+>1ztbP!>j#t>OUz(8ZWb3MpjDV6Zn zF(d-uJcgW%rxIM^q`}wV*VW^*ovc?6;9$L5O2b?;{Kn~1-1(M=i0uLY;GOC3cI^1~ zhclY-IAh3dKbgm!zf(AdO2ENJ`5v{#zzm3q?WGs&8WC}mLnVqb-c)3~!5L7zQ8mTM zK&<69DwzTIIr|(w+QE7~@Q@@FFR!H+c8~&^|41_3J%OkZ#K96#1Iq`}JK!CgX<<@w zC`T#RS=1zB2U64nN4DX=77yI0`2hEu)KJbN24Slzl#?shg(cvtaLeN~ChJ`=;9QUQ zV=(2?uv>rK()QA0P=Og72<%^5ga!kY}eSQd@NYCMHt zSXWBJyfVZ+ug8OsM`udIIcieaYN8pf7&67c3_-Lc%XR)j-d+JKV-QFB3#RP=epGT5 zGAmovlmJ01ku@Yh{75t&?<$C&rE*;-$=k~uglj!-Kj-@Kna4f5S!8wi8RjbFf2@Jo z4Dhxlqp9jm7CB|BWPTA77LiO```OfMK(ZD8A~DIO(qt z(85J1fJFx8JirpU zuB8sHcxq|I1rRPW)Hl%B7H6Qkhefo#BX6L1aeTwmsiFJ> z;=}tzL|4YtiG1Fk?jV4c=|wAmHY{rZTGhU<2iFHR&vjlcP}>izq^Nn+a literal 0 HcmV?d00001 diff --git a/png/volume_up.png b/png/volume_up.png new file mode 100644 index 0000000000000000000000000000000000000000..e74cb61abe101ca27431937c7b82a4c9dc252fab GIT binary patch literal 3067 zcmdT`ZBSEZ7EXHak{iKGLS`u}xgijR?TQ7;b|hCi5)wc@t?e$0wnD-psiPGd0@6a2 zd$n9XvcOW2pr9AJ9q5i0EIUHBioq~S3k|m;i*cn8Dj(5eNp~wSg|&Nd_s9O;=}hg9 zcb<99dEWP)^S*P>IaM#FCvM#Eiw!&;Z)4I<%}YEU|J(J2d4Oeje5x9NU-(jD9PdNB z^d1mYuS!$#co*wD*K|JvE-cu&r;x`ZD%KZ&U%Q0j@jUC3G^*c}WIg!e6+=L;Z|vtT z{N(YwnxgklBrRk%B>g$idVTM2pS^qQPkZk~&%c+QHMPd)r9L>;dzD{aB_w$$_7hx} zFZWwo`F%HM4VKoUMOU)&L!)a0NbB+bYGq42$Ct_HOvxPoYq!i0sn4ZxcR-xo3niSM zIrcCBNsc`gV8_C6^B-AcEq186kwqpdl~EF7`L-PU0!n0_ep~r-8V^eudPZ#2Cgr66 zfkjdxb2^eaYCopj4<6OX2NI)v*T^1;tgqDsLNU~D3t+3)J`_lC^yr%*Fe9tKarzuS{iN3LbBjjk<9BDS+HT% z;5fx13>@_UtiS9vI2fSfLPs5od<@oq3CZp)tA^+bpl@tp?qX!OQc)azmPO8x&&@0j zN*@Kgta%H=(=jxD=vpOV-|VvXI+|>LC{Y5}V^VWe2hdEQX7P3tMDX$LCR-m$^woej zjiaVM3TM6%lJ3olV)Jnp2?T1vNVg|Y2w?|&Qwd)0Najr;sm;duG+qN?d8n9oERAZ0 zwY3jQ_o9UF@3ZkV8uz>y&OEDP;`;~2 zU|qyWudj#duSyEd@3J=Q!Z1}TB)vYZBuY-OHZ4#+2nPG5C8t=M9O$CR=vOY@?%qe^ zp>XP@U{`_9szI9qv>RxMs~|#Ato5dG!NqXF(k52{4=9ANy>N@5R_^LnL<(wyUERp4 z!TB1E2lRvs>|hP*H8{hCIqMaG+-y81nbSqY;W27XC(prSAYV}qUIw@N3BBU^S3Q5OI- zBh*$Q*%CWKT@aGep?;~O=2izjcrakP?5sL(wgTtDyF8iezgJ{=^>D}hzOGw$suJIx z|L3yhND1ED81N$(wZ{cYd3(J+ojn5esl#&UoBa9go<~xXc6PqrVrfHS%h~^9{pWE; zAGVH8%}-7%b2ARRcp~`|vfTgpZmxJPw`q8`_^ru@Z(V6E*FOo5@k4gF|9RNXzh-sy zO5XeXm&$KnDD>E7jIRIwFZ@!mG1^f&_734V&DxSQgrkAARRL7PpJ#He|9M_{Sr!@1CpwXAvC$0Da{%j7v5H9osbW#h zY;5uW-QwirxbM{aizlM`+H4+^$Eb4;QzkH3NvNy4Eh;~+9X}{BI?SDjUSxDo;+TS8 zs~Ey^0Z9}a9nGCcqR1F+y{#x=cX89POZTl=D1qmp-U}*j8clFp$5A3Z7xg|A&rRn7 z^@Yl!MZL?KSX(TlqKDFW9X?gT+RA|@0v*9*ec*LYj8ml;nF@(^0SscY6%%XA1yLQ) z)y+fPyQnvXH_WT(1@wOung+o0OL0WP`AdQL;kg}AIcOio=EjjurrbDLaN z2CUH4I>0KU@v=|A3fg@d;yP%*0PCwX9s}CzpnVyvpuGuJDQIiNF(ws9rB#wGDIE1# zOVKOaXn{&l?7W2EkQlX3x8paUNpI8FI(0AwEZDP%CFs&YusfT^rEpP83YT>nXeo`i zT*G9Spq(B7x*ez;llAZ7s36FD8QQ*=qNHSU_^UH_{Iz~jiA(1XAO{Q8f{IPmZaSzlS2K$Yi;JpZ9BQ~jLQ-LA zV;_i&+Be(NVd%LWN$ZPYv_f|4GXMhH?IxJ1kOcQg0>|%{-yezN_(#=a%^;l^z|MXy zB&~?1bvM9qO{*9{VsiR__BczP`Q(pXuYaHtk-Av7 - - - - + + + + - - + + \ No newline at end of file diff --git a/svg/next.svg b/svg/next.svg new file mode 100644 index 0000000..d898ca7 --- /dev/null +++ b/svg/next.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/svg/open.svg b/svg/open.svg index 9406a3a..d1d445a 100644 --- a/svg/open.svg +++ b/svg/open.svg @@ -1,10 +1,11 @@ - - - + + + - - + + + \ No newline at end of file diff --git a/svg/pause.svg b/svg/pause.svg index e7b21b1..354d21f 100644 --- a/svg/pause.svg +++ b/svg/pause.svg @@ -1,11 +1,13 @@ - - - - + + + + - - + + + + \ No newline at end of file diff --git a/svg/play.svg b/svg/play.svg index bbdf169..4c4c1c0 100644 --- a/svg/play.svg +++ b/svg/play.svg @@ -1,10 +1,11 @@ - - - + + + - - + + + \ No newline at end of file diff --git a/svg/prev.svg b/svg/prev.svg new file mode 100644 index 0000000..98433bd --- /dev/null +++ b/svg/prev.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/svg/restore.svg b/svg/restore.svg new file mode 100644 index 0000000..952425f --- /dev/null +++ b/svg/restore.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/svg/stop.svg b/svg/stop.svg new file mode 100644 index 0000000..9c1db42 --- /dev/null +++ b/svg/stop.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/svg/volume_down.svg b/svg/volume_down.svg new file mode 100644 index 0000000..a5bd99c --- /dev/null +++ b/svg/volume_down.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/svg/volume_up.svg b/svg/volume_up.svg new file mode 100644 index 0000000..ebc934f --- /dev/null +++ b/svg/volume_up.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file