diff --git a/build/CMakeLists.txt b/CMakeLists.txt
similarity index 86%
rename from build/CMakeLists.txt
rename to CMakeLists.txt
index da048ae..03a3086 100755
--- a/build/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,9 +28,9 @@ pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET
)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
-file(GLOB_RECURSE PROJECT_SOURCES ../src/*.cpp)
-file(GLOB_RECURSE PROJECT_HEADERS ../src/*.h)
-file(GLOB_RECURSE PROJECT_RESOURCES ../assets/resources.qrc)
+file(GLOB_RECURSE PROJECT_SOURCES src/*.cpp)
+file(GLOB_RECURSE PROJECT_HEADERS src/*.h)
+file(GLOB_RECURSE PROJECT_RESOURCES assets/resources.qrc)
add_executable(CryliaPlayer
${PROJECT_SOURCES}
@@ -61,4 +61,4 @@ set(DESKTOP_FILE ${CMAKE_CURRENT_BINARY_DIR}/CryliaPlayer.desktop)
configure_file(${DESKTOP_FILE_IN} ${DESKTOP_FILE} @ONLY)
install(FILES ${DESKTOP_FILE} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications)
-install(FILES ../assets/aqua.jpg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
+install(FILES assets/aqua.jpg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons)
diff --git a/build/CryliaPlayer.desktop.in b/CryliaPlayer.desktop.in
similarity index 100%
rename from build/CryliaPlayer.desktop.in
rename to CryliaPlayer.desktop.in
diff --git a/assets/icons/songControl/arrow-expand.svg b/assets/icons/arrow-expand.svg
similarity index 100%
rename from assets/icons/songControl/arrow-expand.svg
rename to assets/icons/arrow-expand.svg
diff --git a/assets/icons/folder-outline.svg b/assets/icons/folder-outline.svg
new file mode 100644
index 0000000..d61f392
--- /dev/null
+++ b/assets/icons/folder-outline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/home-outline.svg b/assets/icons/home-outline.svg
new file mode 100644
index 0000000..f3b66bb
--- /dev/null
+++ b/assets/icons/home-outline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/songControl/magnify.svg b/assets/icons/magnify.svg
similarity index 100%
rename from assets/icons/songControl/magnify.svg
rename to assets/icons/magnify.svg
diff --git a/assets/icons/songControl/nextSong.svg b/assets/icons/nextSong.svg
similarity index 100%
rename from assets/icons/songControl/nextSong.svg
rename to assets/icons/nextSong.svg
diff --git a/assets/icons/songControl/pause.svg b/assets/icons/pause.svg
similarity index 100%
rename from assets/icons/songControl/pause.svg
rename to assets/icons/pause.svg
diff --git a/assets/icons/songControl/play.svg b/assets/icons/play.svg
similarity index 100%
rename from assets/icons/songControl/play.svg
rename to assets/icons/play.svg
diff --git a/assets/icons/playlist-edit.svg b/assets/icons/playlist-edit.svg
new file mode 100644
index 0000000..93a81fe
--- /dev/null
+++ b/assets/icons/playlist-edit.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/playlist-music-outline.svg b/assets/icons/playlist-music-outline.svg
new file mode 100644
index 0000000..77c3776
--- /dev/null
+++ b/assets/icons/playlist-music-outline.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/playlist-plus.svg b/assets/icons/playlist-plus.svg
new file mode 100644
index 0000000..c6c3476
--- /dev/null
+++ b/assets/icons/playlist-plus.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/icons/songControl/prevSong.svg b/assets/icons/prevSong.svg
similarity index 100%
rename from assets/icons/songControl/prevSong.svg
rename to assets/icons/prevSong.svg
diff --git a/assets/icons/songControl/repeat-once.svg b/assets/icons/repeat-once.svg
similarity index 100%
rename from assets/icons/songControl/repeat-once.svg
rename to assets/icons/repeat-once.svg
diff --git a/assets/icons/songControl/shuffle.svg b/assets/icons/shuffle.svg
similarity index 100%
rename from assets/icons/songControl/shuffle.svg
rename to assets/icons/shuffle.svg
diff --git a/assets/icons/songControl/songRepeat.svg b/assets/icons/songRepeat.svg
similarity index 100%
rename from assets/icons/songControl/songRepeat.svg
rename to assets/icons/songRepeat.svg
diff --git a/assets/icons/songControl/volume-high.svg b/assets/icons/volume-high.svg
similarity index 100%
rename from assets/icons/songControl/volume-high.svg
rename to assets/icons/volume-high.svg
diff --git a/assets/icons/songControl/volume-low.svg b/assets/icons/volume-low.svg
similarity index 100%
rename from assets/icons/songControl/volume-low.svg
rename to assets/icons/volume-low.svg
diff --git a/assets/icons/songControl/volume-medium.svg b/assets/icons/volume-medium.svg
similarity index 100%
rename from assets/icons/songControl/volume-medium.svg
rename to assets/icons/volume-medium.svg
diff --git a/assets/icons/songControl/volume-mute.svg b/assets/icons/volume-mute.svg
similarity index 100%
rename from assets/icons/songControl/volume-mute.svg
rename to assets/icons/volume-mute.svg
diff --git a/assets/icons/songControl/volume-off.svg b/assets/icons/volume-off.svg
similarity index 100%
rename from assets/icons/songControl/volume-off.svg
rename to assets/icons/volume-off.svg
diff --git a/assets/resources.qrc b/assets/resources.qrc
index 1c9cbad..94dec68 100755
--- a/assets/resources.qrc
+++ b/assets/resources.qrc
@@ -1,20 +1,6 @@
aqua.jpg
- icons/songControl/shuffle.svg
- icons/songControl/prevSong.svg
- icons/songControl/nextSong.svg
- icons/songControl/play.svg
- icons/songControl/pause.svg
- icons/songControl/songRepeat.svg
- icons/songControl/repeat-once.svg
- icons/songControl/volume-high.svg
- icons/songControl/volume-low.svg
- icons/songControl/volume-mute.svg
- icons/songControl/volume-off.svg
- icons/songControl/volume-medium.svg
- icons/songControl/arrow-expand.svg
- icons/home.svg
- icons/songControl/magnify.svg
+ icons/
diff --git a/src/Controller/MusicPlayer/MusicPlayer.cpp b/src/Controller/MusicPlayer/MusicPlayer.cpp
new file mode 100644
index 0000000..80e0508
--- /dev/null
+++ b/src/Controller/MusicPlayer/MusicPlayer.cpp
@@ -0,0 +1,79 @@
+#include "MusicPlayer.h"
+
+MusicPlayer::~MusicPlayer( ) { }
+
+void MusicPlayer::PlaySong(Song* song) {
+ songHistory->push(songQueue->Top( ));
+ songQueue->SetTop(song);
+
+ audio.PlaySong(songQueue->Top( )->GetPath( ));
+}
+
+void MusicPlayer::NextSong( ) {
+ if (songQueue->IsEmpty( )) {
+ audio.StopMusic( );
+ return;
+ }
+
+ songHistory->push(songQueue->Top( ));
+ songQueue->Next( );
+
+ audio.PlaySong(songQueue->Top( )->GetPath( ));
+}
+
+void MusicPlayer::NextSong(Song* song, bool isPrioQueue) {
+ if (songQueue->IsEmpty( )) {
+ audio.StopMusic( );
+ return;
+ }
+
+ songHistory->push(songQueue->Top( ));
+ songQueue->JumpToSong(song, isPrioQueue);
+
+ audio.PlaySong(songQueue->Top( )->GetPath( ));
+}
+
+void MusicPlayer::PreviousSong( ) {
+ if (songHistory->isEmpty( ))
+ return;
+
+ songQueue->SetTop(songHistory->top( ));
+ songHistory->pop( );
+
+ audio.PlaySong(songQueue->Top( )->GetPath( ));
+}
+
+void MusicPlayer::SkipToTimestamp(unsigned const int& skipTo) {
+ if (audio.IsMusicPlaying( ) == 0) return;
+
+ audio.SetMusicPos(skipTo);
+}
+
+int MusicPlayer::GetSongProgression( ) {
+ return audio.IsMusicPlaying( ) == 1 ? audio.GetMusicPos( ) : 0;
+}
+
+Song* MusicPlayer::GetCurrentlyPlaying( ) {
+ return songQueue->Top( );
+}
+
+//For the PriorityQueue
+void MusicPlayer::AddSongToQueue(Song* song) {
+ songQueue->AddToPriorityQueue(song);
+}
+
+void MusicPlayer::RemoveSongFromQueue(Song* song) {
+ songQueue->RemoveSongFromPriorityQueue(song);
+}
+
+void MusicPlayer::MoveSongInQueue(Song* songToMove, Song* otherSong, bool beforeElseAfter) {
+ songQueue->MoveSongInPriorityQueue(songToMove, otherSong, beforeElseAfter);
+}
+
+void MusicPlayer::shuffleQueue( ) {
+ shuffle ? songQueue->ShufflePlaylist( ) : songQueue->RestorePlaylist( );
+}
+
+void MusicPlayer::setQueueLoop( ) {
+ loop == All ? songQueue->LinkQueue(true) : songQueue->LinkQueue(false);
+}
diff --git a/src/Controller/MusicPlayer/MusicPlayer.h b/src/Controller/MusicPlayer/MusicPlayer.h
new file mode 100644
index 0000000..5a099d9
--- /dev/null
+++ b/src/Controller/MusicPlayer/MusicPlayer.h
@@ -0,0 +1,104 @@
+#pragma once
+
+#include "../../core/audio/audio.h"
+#include "../../core/SongHistory/SongHistory.hpp"
+#include "../../core/SongQueue/SongQueue.h"
+#include "../../core/song/song.h"
+
+enum Loop {
+ None,
+ Once,
+ All
+};
+
+class MusicPlayer {
+public:
+ static MusicPlayer& getInstance( ) {
+ static MusicPlayer instance;
+ return instance;
+ }
+
+private:
+ MusicPlayer( );
+
+ // 0 no shuffle, 1 shuffling
+ int shuffle = 0;
+ // None, Once, All
+ Loop loop = None;
+ // 0 stopped, 1 playing
+ bool playing = 0;
+
+ // Song queue, will be filled with the entire playlist by default
+ SongQueue* songQueue;
+
+ // Contain all played songs
+ SongHistory* songHistory;
+
+ Audio& audio = Audio::getInstance( );
+
+ void shuffleQueue( );
+ void setQueueLoop( );
+
+public:
+ ~MusicPlayer( );
+
+ MusicPlayer(MusicPlayer const&) = delete;
+ void operator=(MusicPlayer const&) = delete;
+
+ /**
+ * @brief Will start playing the given song and put itself at the queue top.
+ *
+ * @param song Song that will start playing
+ */
+ void PlaySong(Song* song);
+
+ /**
+ * @brief Skip the current song and play the next in queue,
+ * if nothing is in queue it will stop playing anything.
+ *
+ */
+ void NextSong( );
+
+ /**
+ * @brief Jumps the queue to the given song keeping the non altered queue intact
+ *
+ * @param song
+ * @param isPrioQueue If the song is in the prio queue or normal queue
+ */
+ void NextSong(Song* song, bool isPrioQueue);
+
+ /**
+ * @brief Rewind the currently playing song to the beginning if playtime >= 5 seconds.
+ * Otherwise play the top song in the history stack
+ *
+ */
+ void PreviousSong( );
+
+ /**
+ * @brief Skip the song to the given timestamp
+ *
+ * @param skipTo time as positive integer
+ */
+ void SkipToTimestamp(unsigned const int& skipTo);
+
+ /**
+ * @brief Get the current Song progression as an positive integer
+ *
+ * @return int current timestamp
+ */
+ int GetSongProgression( );
+
+ /**
+ * @brief Get the Currently Playing Song
+ *
+ * @return Song& Song thats currently playing
+ */
+ Song* GetCurrentlyPlaying( );
+
+ void SetShuffle(bool shuffle) { this->shuffle = shuffle; }
+ void SetLoop(Loop loop) { this->loop = loop; }
+
+ void AddSongToQueue(Song* song);
+ void RemoveSongFromQueue(Song* song);
+ void MoveSongInQueue(Song* songToMove, Song* otherSong, bool beforeElseAfter);
+};
diff --git a/src/Controller/Pages/PageController.hpp b/src/Controller/Pages/PageController.hpp
new file mode 100644
index 0000000..e69de29
diff --git a/src/Public/MainWindow.cpp b/src/Public/MainWindow.cpp
deleted file mode 100755
index 593fb22..0000000
--- a/src/Public/MainWindow.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "MainWindow.h"
-
-void MainWindow::setupMainWindow( ) {
- this->setWindowTitle("Crylia Player");
- this->setWindowIcon(QIcon(":aqua.jpg"));
-
- QWidget* mw = new QWidget(this);
- mw->setContentsMargins(10, 10, 10, 10);
-
- QOverlayout* ol = new QOverlayout(mw);
- mw->setLayout(ol);
-
- Pages* p = new Pages(mw);
- PlaylistPage* pp = new PlaylistPage(mw);
- PlaylistWidget* pw = new PlaylistWidget(mw);
- FloatingControls* fc = new FloatingControls(mw, this->path);
-
- QVBoxLayout* vbox = new QVBoxLayout( );
- vbox->addWidget(fc, 0, Qt::AlignBottom);
-
- QHBoxLayout* hbox = new QHBoxLayout( );
- QVBoxLayout* vbox2 = new QVBoxLayout( );
- vbox2->addWidget(p);
- vbox2->addWidget(pw);
- hbox->addLayout(vbox2);
- hbox->addWidget(pp);
-
- hbox->setSpacing(10);
- vbox2->setSpacing(10);
-
- ol->addItem(vbox);
- ol->addItem(hbox);
-
- this->setCentralWidget(mw);
-}
-
-MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) {
- setupMainWindow( );
-}
-
-MainWindow::MainWindow(std::filesystem::path path, QWidget* parent)
- : QMainWindow(parent), path(path) {
- setupMainWindow( );
-}
-
-MainWindow::~MainWindow( ) { }
diff --git a/src/Public/Modules/PageNavigator/pages.cpp b/src/Public/Modules/PageNavigator/pages.cpp
deleted file mode 100755
index a916f65..0000000
--- a/src/Public/Modules/PageNavigator/pages.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "pages.h"
-
-#include
-#include
-
-Pages::Pages(QWidget* parent) :QFrame(parent) {
-
- this->setStyleSheet(R"(
- background-color: #282828;
- border-radius: 12px;
- )");
-
- this->setFixedSize(300, 180);
-
- QVBoxLayout* layout = new QVBoxLayout(this);
-
- PageNavigator* home = new PageNavigator("Home", ":icons/home.svg");
- PageNavigator* localFiles = new PageNavigator("Local Files", ":icons/home.svg");
- PageNavigator* playlist = new PageNavigator("Playlist", ":icons/songControl/magnify.svg");
-
-
- layout->addWidget(home);
- layout->addWidget(localFiles);
- layout->addWidget(playlist);
-}
-
-Pages::~Pages( ) { }
diff --git a/src/Public/Modules/PageNavigator/pages.h b/src/Public/Modules/PageNavigator/pages.h
deleted file mode 100755
index e9a98c0..0000000
--- a/src/Public/Modules/PageNavigator/pages.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include
-#include
-#include "../../Widgets/PageNavigator/PageNavigator.h"
-
-class Pages : public QFrame {
-
- Q_OBJECT
-
-private:
- //Page[3] pages;
-
-public:
- Pages(QWidget* parent = nullptr);
- ~Pages( );
-};
diff --git a/src/Public/Pages/Playlist/PlaylistPage.cpp b/src/Public/Pages/Playlist/PlaylistPage.cpp
deleted file mode 100755
index 037de2d..0000000
--- a/src/Public/Pages/Playlist/PlaylistPage.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "PlaylistPage.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-PlaylistPage::PlaylistPage(QWidget* parent) : QFrame(parent) {
-
- this->setStyleSheet(R"(
- background-color: #282828;
- border-radius: 12px;
- )");
-}
-
-PlaylistPage::~PlaylistPage( ) { }
diff --git a/src/Public/Tools/SvgToPixmap.hpp b/src/Public/Tools/SvgToPixmap.hpp
deleted file mode 100644
index 417bd5c..0000000
--- a/src/Public/Tools/SvgToPixmap.hpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-#include
-
-static QPixmap RenderSvg(QString path, int w, int h) {
- QSvgRenderer renderer(path);
- QPixmap pixmap(w, h);
- pixmap.fill(Qt::transparent);
- QPainter painter(&pixmap);
- renderer.render(&painter);
-
- return pixmap;
-}
diff --git a/src/Public/Widgets/PageNavigator/PageNavigator.cpp b/src/Public/Widgets/PageNavigator/PageNavigator.cpp
deleted file mode 100644
index 0d96fc8..0000000
--- a/src/Public/Widgets/PageNavigator/PageNavigator.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "PageNavigator.h"
-#include "SelectHandler.hpp"
-
-PageNavigator::PageNavigator(QString text, QString icon, QWidget* parent)
- :m_text(new QLabel(text)), m_icon(new QLabel( )) {
-
- m_icon->setPixmap(icon);
-
- setObjectName("PageNavigator");
- setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- setStyleSheet(R"(
- #PageNavigator{
- border: 4px solid #414141;
- border-radius: 8px;
- color: #E0E0E0;
- }
- )");
-
- QFont font = m_text->font( );
- font.setPointSize(16);
- font.setWeight(QFont::Bold);
- m_text->setFont(font);
-
- QHBoxLayout* layout = new QHBoxLayout(this);
- layout->addWidget(m_icon, 0, Qt::AlignLeft);
- layout->addWidget(m_text, 1, Qt::AlignLeft);
-
- connect(this, &QPushButton::clicked, [this]( ) {
- SelectHandler* sh = SelectHandler::GetInstance( );
-
- sh->setSelected(this);
- });
-
-}
-
-void PageNavigator::unselect( ) {
- setStyleSheet(R"(
- #PageNavigator{
- border: 4px solid #414141;
- border-radius: 6px;
- color: #E0E0E0;
- }
- )");
-}
-
-void PageNavigator::select( ) {
- setStyleSheet(R"(
- #PageNavigator{
- border: 4px solid #81D4FA;
- border-radius: 6px;
- color: #E0E0E0;
- }
- )");
-}
diff --git a/src/Public/Layouts/QOverlayout.cpp b/src/View/Layouts/QOverlayout.cpp
similarity index 100%
rename from src/Public/Layouts/QOverlayout.cpp
rename to src/View/Layouts/QOverlayout.cpp
diff --git a/src/Public/Layouts/QOverlayout.h b/src/View/Layouts/QOverlayout.h
similarity index 100%
rename from src/Public/Layouts/QOverlayout.h
rename to src/View/Layouts/QOverlayout.h
diff --git a/src/View/MainWidget.cpp b/src/View/MainWidget.cpp
new file mode 100644
index 0000000..18b91ce
--- /dev/null
+++ b/src/View/MainWidget.cpp
@@ -0,0 +1,68 @@
+#include "MainWidget.h"
+
+void MainWidget::setupMainWidget( ) {
+ setContentsMargins(10, 10, 10, 10);
+
+ QOverlayout* ol = new QOverlayout(this);
+ setLayout(ol);
+
+ QVBoxLayout* vbox = new QVBoxLayout( );
+ vbox->addWidget(floatingControlls, 0, Qt::AlignBottom);
+
+ QHBoxLayout* hbox = new QHBoxLayout( );
+ QVBoxLayout* vbox2 = new QVBoxLayout( );
+ vbox2->addWidget(pageNav);
+ vbox2->addWidget(playlistNav);
+ hbox->addLayout(vbox2);
+ QHBoxLayout* stackedLayout = new QHBoxLayout( );
+
+ stackedLayout->addWidget(homePage);
+ stackedLayout->addWidget(playlistPage);
+
+ playlistPage->setVisible(false);
+
+ hbox->addLayout(stackedLayout, 0);
+
+ hbox->setSpacing(10);
+ vbox2->setSpacing(10);
+
+ ol->addItem(hbox);
+ ol->addItem(vbox);
+
+ connect(pageNav, &PageNavModule::SelectChanged, [this, stackedLayout](PageNavigator* pn) {
+ if (pn->GetText( ).toStdString( ) == "Home") {
+ //stackedLayout->setCurrentIndex(0);
+ stackedLayout->itemAt(0)->widget( )->setVisible(true);
+ stackedLayout->itemAt(1)->widget( )->setVisible(false);
+ }
+ else if (pn->GetText( ).toStdString( ) == "Playlist") {
+ //stackedLayout->setCurrentIndex(1);
+ stackedLayout->itemAt(0)->widget( )->setVisible(false);
+ stackedLayout->itemAt(1)->widget( )->setVisible(true);
+ }
+ });
+}
+
+void MainWidget::PageChangedAction( ) { }
+
+MainWidget::MainWidget(QWidget* parent)
+ : QWidget(parent),
+ pageNav(new PageNavModule(this)),
+ playlistNav(new PlaylistNavModule(this)),
+ playlistPage(new PlaylistPage(this)),
+ homePage(new HomePage(this)),
+ floatingControlls(new FloatingControls(this)) {
+ setupMainWidget( );
+}
+
+MainWidget::MainWidget(std::filesystem::path path, QWidget* parent)
+ : QWidget(parent),
+ pageNav(new PageNavModule(this)),
+ playlistNav(new PlaylistNavModule(this)),
+ playlistPage(new PlaylistPage(this)),
+ homePage(new HomePage(this)),
+ floatingControlls(new FloatingControls(this, path)) {
+ setupMainWidget( );
+}
+
+MainWidget::~MainWidget( ) { }
diff --git a/src/View/MainWidget.h b/src/View/MainWidget.h
new file mode 100644
index 0000000..de7d766
--- /dev/null
+++ b/src/View/MainWidget.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+#include "Layouts/QOverlayout.h"
+#include "Modules/FloatingControls/FloatingControls.h"
+#include "Modules/PageNavModule/PageNavModule.h"
+#include "Modules/PlaylistNavModule/PlaylistNavModule.h"
+#include "Pages/Playlist/PlaylistPage.h"
+#include "Pages/Home/HomePage.h"
+
+class MainWidget : public QWidget {
+ Q_OBJECT
+private:
+
+ PageNavModule* pageNav;
+ PlaylistNavModule* playlistNav;
+
+ PlaylistPage* playlistPage;
+ HomePage* homePage;
+
+ FloatingControls* floatingControlls;
+
+ void setupMainWidget( );
+
+public:
+ MainWidget(QWidget* parent = nullptr);
+ MainWidget(std::filesystem::path path, QWidget* parent = nullptr);
+ ~MainWidget( );
+
+private slots:
+ void PageChangedAction( );
+
+
+};
diff --git a/src/View/MainWindow.cpp b/src/View/MainWindow.cpp
new file mode 100755
index 0000000..1b957b4
--- /dev/null
+++ b/src/View/MainWindow.cpp
@@ -0,0 +1,27 @@
+#include "MainWindow.h"
+
+void MainWindow::setupMainWindow( ) {
+ this->setWindowTitle("Crylia Player");
+ this->setWindowIcon(QIcon(":aqua.jpg"));
+
+ setObjectName("MainWindow");
+ setStyleSheet(R"(
+ #MainWindow{
+ background-color: #121212;
+ }
+ )");
+
+ this->setCentralWidget(mainWidget);
+}
+
+MainWindow::MainWindow(QWidget* parent)
+ : QMainWindow(parent), mainWidget(new MainWidget(this)) {
+ setupMainWindow( );
+}
+
+MainWindow::MainWindow(std::filesystem::path path, QWidget* parent)
+ : QMainWindow(parent), mainWidget(new MainWidget(path, this)) {
+ setupMainWindow( );
+}
+
+MainWindow::~MainWindow( ) { }
diff --git a/src/Public/MainWindow.h b/src/View/MainWindow.h
similarity index 54%
rename from src/Public/MainWindow.h
rename to src/View/MainWindow.h
index 71d247e..40e89e9 100755
--- a/src/Public/MainWindow.h
+++ b/src/View/MainWindow.h
@@ -7,23 +7,17 @@
#include
#include
-#include "Modules/FloatingControls/FloatingControls.h"
-#include "Layouts/QOverlayout.h"
-#include "Modules/PageNavigator/pages.h"
-#include "Pages/Playlist/PlaylistPage.h"
-#include "Modules/PlaylistNavigator/PlaylistWidget.h"
+#include "MainWidget.h"
class MainWindow : public QMainWindow {
Q_OBJECT
-
public:
MainWindow(QWidget* parent = nullptr);
MainWindow(std::filesystem::path path, QWidget* parent = nullptr);
~MainWindow( );
private:
- // In case the program gets started with a song as an argument
- std::filesystem::path path;
+ MainWidget* mainWidget;
void setupMainWindow( );
};
diff --git a/src/Public/Modules/FloatingControls/FloatingControls.cpp b/src/View/Modules/FloatingControls/FloatingControls.cpp
similarity index 88%
rename from src/Public/Modules/FloatingControls/FloatingControls.cpp
rename to src/View/Modules/FloatingControls/FloatingControls.cpp
index 2b9c257..f4b38c6 100755
--- a/src/Public/Modules/FloatingControls/FloatingControls.cpp
+++ b/src/View/Modules/FloatingControls/FloatingControls.cpp
@@ -20,27 +20,6 @@ enum Repeat : short {
NONE
};
-template
-static void applyShadow(T obj, int blurRadius = 20, int xOffset = 10, int yOffset = 10, QString color = "#000000", int offset = 2) {
- QGraphicsDropShadowEffect* dropShadow = new QGraphicsDropShadowEffect( );
- dropShadow->setBlurRadius(blurRadius);
- dropShadow->setXOffset(xOffset);
- dropShadow->setYOffset(yOffset);
- dropShadow->setColor(color);
- dropShadow->setOffset(offset);
- obj->setGraphicsEffect(dropShadow);
-}
-
-static QPixmap RenderSvg(QString path) {
- QSvgRenderer renderer(path);
- QPixmap pixmap(36, 36);
- pixmap.fill(Qt::transparent);
- QPainter painter(&pixmap);
- renderer.render(&painter);
-
- return pixmap;
-}
-
static QPushButton* makeSongControlButton(QString name, QSize size = QSize(36, 36), QString color = "#D7D7D7") {
QPushButton* button = new QPushButton( );
button->setObjectName(name);
@@ -50,7 +29,7 @@ static QPushButton* makeSongControlButton(QString name, QSize size = QSize(36, 3
border: 0;
}
)");
- button->setIcon(RenderSvg(":/icons/songControl/" + name + ".svg"));
+ button->setIcon(RenderSvg(":/icons/" + name + ".svg", 36, 36));
button->setIconSize(size);
button->setCursor(Qt::PointingHandCursor);
QGraphicsColorizeEffect* colorize = new QGraphicsColorizeEffect( );
@@ -70,7 +49,7 @@ FloatingControls::FloatingControls(QWidget* parent, std::filesystem::path path)
songRepeat(NONE),
artist("Artist"),
songName("Song"),
- song(Audio::getInstance(path)) {
+ song(Audio::getInstance( )) {
this->setFixedHeight(100);
this->setObjectName("main");
this->setStyleSheet(R"(
@@ -145,7 +124,7 @@ FloatingControls::FloatingControls(QWidget* parent, std::filesystem::path path)
QHBoxLayout* songControlsLayout = new QHBoxLayout( );
songControlsLayout->setAlignment(Qt::AlignCenter | Qt::AlignBottom);
- QString buttonNames[5] = { "songRepeat", "prevSong", "play", "nextSong", "shuffle" };
+ QString buttonNames[5] = { "shuffle", "prevSong", "play", "nextSong", "songRepeat" };
QString col = "#D7D7D7";
for (int i = 0; i < 5; i++) {
if (buttonNames[i] == "shuffle" || buttonNames[i] == "songRepeat")
@@ -158,16 +137,16 @@ FloatingControls::FloatingControls(QWidget* parent, std::filesystem::path path)
QObject::connect(pb, &QPushButton::clicked, [pb, this]( ) {
if (!song.IsMusicPlaying( )) {
song.StartMusic( );
- pb->setIcon(RenderSvg(":/icons/songControl/pause.svg"));
+ pb->setIcon(RenderSvg(":/icons/pause.svg", 36, 36));
return;
}
if (GetPlayPause( )) {
song.ResumeMusic( );
- pb->setIcon(RenderSvg(":/icons/songControl/pause.svg"));
+ pb->setIcon(RenderSvg(":/icons/pause.svg", 36, 36));
}
else {
song.PauseMusic( );
- pb->setIcon(RenderSvg(":/icons/songControl/play.svg"));
+ pb->setIcon(RenderSvg(":/icons/play.svg", 36, 36));
}
togglePlayPause( );
});
@@ -279,7 +258,7 @@ FloatingControls::FloatingControls(QWidget* parent, std::filesystem::path path)
QLabel* volumeIcon = new QLabel( );
volumeIcon->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
volumeIcon->setObjectName("volumeIcon");
- volumeIcon->setPixmap(RenderSvg(":icons/songControl//volume-high.svg").scaled(QSize(24, 24), Qt::IgnoreAspectRatio));
+ volumeIcon->setPixmap(RenderSvg(":icons/volume-high.svg", 36, 36).scaled(QSize(24, 24), Qt::IgnoreAspectRatio));
QGraphicsColorizeEffect* colorize = new QGraphicsColorizeEffect( );
colorize->setColor(QColor("#78AB70"));
colorize->setStrength(1);
@@ -344,7 +323,7 @@ FloatingControls::FloatingControls(QWidget* parent, std::filesystem::path path)
QLabel* FullscreenLabel = new QLabel( );
FullscreenLabel->setFixedSize(36, 24);
FullscreenLabel->setObjectName("fullscreenLabel");
- FullscreenLabel->setPixmap(QPixmap(":icons/songControl//arrow-expand.svg").scaled(QSize(24, 24), Qt::IgnoreAspectRatio));
+ FullscreenLabel->setPixmap(QPixmap(":icons/arrow-expand.svg").scaled(QSize(24, 24), Qt::IgnoreAspectRatio));
QVBoxLayout* FullscreenLayout = new QVBoxLayout( );
FullscreenLayout->setAlignment(Qt::AlignCenter);
diff --git a/src/Public/Modules/FloatingControls/FloatingControls.h b/src/View/Modules/FloatingControls/FloatingControls.h
similarity index 96%
rename from src/Public/Modules/FloatingControls/FloatingControls.h
rename to src/View/Modules/FloatingControls/FloatingControls.h
index 9ff0201..29271b2 100755
--- a/src/Public/Modules/FloatingControls/FloatingControls.h
+++ b/src/View/Modules/FloatingControls/FloatingControls.h
@@ -1,12 +1,14 @@
#pragma once
#include "../../../core/audio/audio.h"
+#include "../../Tools/SvgToPixmap.hpp"
#include
#include
#include
#include
#include
+#include
enum Repeat : short;
diff --git a/src/View/Modules/PageNavModule/PageNavModule.cpp b/src/View/Modules/PageNavModule/PageNavModule.cpp
new file mode 100755
index 0000000..405f678
--- /dev/null
+++ b/src/View/Modules/PageNavModule/PageNavModule.cpp
@@ -0,0 +1,32 @@
+#include "PageNavModule.h"
+
+#include
+#include
+
+PageNavModule::PageNavModule(QWidget* parent) :QFrame(parent) {
+
+ this->setStyleSheet(R"(
+ background-color: #282828;
+ border-radius: 12px;
+ )");
+
+ applyShadow(this);
+
+ this->setFixedSize(300, 180);
+
+ QVBoxLayout* layout = new QVBoxLayout(this);
+
+ PageNavigator* home = new PageNavigator("Home", ":icons/home-outline.svg", "#81D4FA");
+ PageNavigator* localFiles = new PageNavigator("Local Files", ":icons/folder-outline.svg", "#FFE082");
+ PageNavigator* playlist = new PageNavigator("Playlist", ":icons/magnify.svg", "#CE93D8");
+
+ layout->addWidget(home);
+ layout->addWidget(localFiles);
+ layout->addWidget(playlist);
+
+ connect(home, &PageNavigator::SelectedChanged, this, &PageNavModule::SelectChanged);
+ connect(localFiles, &PageNavigator::SelectedChanged, this, &PageNavModule::SelectChanged);
+ connect(playlist, &PageNavigator::SelectedChanged, this, &PageNavModule::SelectChanged);
+}
+
+PageNavModule::~PageNavModule( ) { }
diff --git a/src/View/Modules/PageNavModule/PageNavModule.h b/src/View/Modules/PageNavModule/PageNavModule.h
new file mode 100755
index 0000000..2ca68f8
--- /dev/null
+++ b/src/View/Modules/PageNavModule/PageNavModule.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include
+#include
+#include
+#include "../../Widgets/PageNavigator/PageNavigator.h"
+#include "../../Tools/SvgToPixmap.hpp"
+
+class PageNavModule : public QFrame {
+ Q_OBJECT
+private:
+ QVector pages;
+
+public:
+ PageNavModule(QWidget* parent = nullptr);
+ ~PageNavModule( );
+
+signals:
+ void SelectChanged(PageNavigator* pn);
+};
diff --git a/src/Public/Modules/PlaylistNavigator/PlaylistWidget.cpp b/src/View/Modules/PlaylistNavModule/PlaylistNavModule.cpp
similarity index 58%
rename from src/Public/Modules/PlaylistNavigator/PlaylistWidget.cpp
rename to src/View/Modules/PlaylistNavModule/PlaylistNavModule.cpp
index 18d0d57..2b95474 100755
--- a/src/Public/Modules/PlaylistNavigator/PlaylistWidget.cpp
+++ b/src/View/Modules/PlaylistNavModule/PlaylistNavModule.cpp
@@ -1,6 +1,6 @@
-#include "PlaylistWidget.h"
+#include "PlaylistNavModule.h"
-PlaylistWidget::PlaylistWidget(QWidget* parent) : QFrame(parent) {
+PlaylistNavModule::PlaylistNavModule(QWidget* parent) : QFrame(parent) {
this->setStyleSheet(R"(
background-color: #282828;
@@ -14,4 +14,4 @@ PlaylistWidget::PlaylistWidget(QWidget* parent) : QFrame(parent) {
}
-PlaylistWidget::~PlaylistWidget( ) { }
+PlaylistNavModule::~PlaylistNavModule( ) { }
diff --git a/src/Public/Modules/PlaylistNavigator/PlaylistWidget.h b/src/View/Modules/PlaylistNavModule/PlaylistNavModule.h
similarity index 50%
rename from src/Public/Modules/PlaylistNavigator/PlaylistWidget.h
rename to src/View/Modules/PlaylistNavModule/PlaylistNavModule.h
index e90efe7..7ccd4ca 100755
--- a/src/Public/Modules/PlaylistNavigator/PlaylistWidget.h
+++ b/src/View/Modules/PlaylistNavModule/PlaylistNavModule.h
@@ -4,13 +4,13 @@
#include
#include
-class PlaylistWidget : public QFrame {
+class PlaylistNavModule : public QFrame {
Q_OBJECT
private:
public:
- PlaylistWidget(QWidget* parent);
- ~PlaylistWidget( );
+ PlaylistNavModule(QWidget* parent);
+ ~PlaylistNavModule( );
};
diff --git a/src/View/Pages/Home/HomePage.cpp b/src/View/Pages/Home/HomePage.cpp
new file mode 100644
index 0000000..09e3926
--- /dev/null
+++ b/src/View/Pages/Home/HomePage.cpp
@@ -0,0 +1,14 @@
+#include "HomePage.h"
+
+HomePage::HomePage(QWidget* parent)
+ : QFrame(parent) {
+
+ setStyleSheet(R"(
+ background-color: #28FF28;
+ border-radius: 12px;
+ )");
+
+ applyShadow(this);
+}
+
+HomePage::~HomePage( ) { }
diff --git a/src/View/Pages/Home/HomePage.h b/src/View/Pages/Home/HomePage.h
new file mode 100644
index 0000000..c29b873
--- /dev/null
+++ b/src/View/Pages/Home/HomePage.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include
+#include
+#include "../../Tools/SvgToPixmap.hpp"
+
+
+class HomePage : public QFrame {
+ Q_OBJECT
+private:
+ /* data */
+public:
+ HomePage(QWidget* parent = nullptr);
+ ~HomePage( );
+};
diff --git a/src/View/Pages/Playlist/PlaylistPage.cpp b/src/View/Pages/Playlist/PlaylistPage.cpp
new file mode 100755
index 0000000..8992b70
--- /dev/null
+++ b/src/View/Pages/Playlist/PlaylistPage.cpp
@@ -0,0 +1,14 @@
+#include "PlaylistPage.h"
+
+PlaylistPage::PlaylistPage(QWidget* parent)
+ : QFrame(parent) {
+
+ setStyleSheet(R"(
+ background-color: #2828ff;
+ border-radius: 12px;
+ )");
+
+ applyShadow(this);
+}
+
+PlaylistPage::~PlaylistPage( ) { }
diff --git a/src/Public/Pages/Playlist/PlaylistPage.h b/src/View/Pages/Playlist/PlaylistPage.h
similarity index 63%
rename from src/Public/Pages/Playlist/PlaylistPage.h
rename to src/View/Pages/Playlist/PlaylistPage.h
index 445d6d2..17b07d4 100755
--- a/src/Public/Pages/Playlist/PlaylistPage.h
+++ b/src/View/Pages/Playlist/PlaylistPage.h
@@ -2,13 +2,12 @@
#include
#include
+#include "../../Tools/SvgToPixmap.hpp"
class PlaylistPage : public QFrame {
-
Q_OBJECT
-
private:
public:
- PlaylistPage(QWidget* parent);
+ PlaylistPage(QWidget* parent = nullptr);
~PlaylistPage( );
};
diff --git a/src/View/Tools/SvgToPixmap.hpp b/src/View/Tools/SvgToPixmap.hpp
new file mode 100644
index 0000000..f166091
--- /dev/null
+++ b/src/View/Tools/SvgToPixmap.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+static QPixmap RenderSvg(QString path, int w, int h) {
+ QSvgRenderer renderer(path);
+ QPixmap pixmap(w, h);
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ renderer.render(&painter);
+
+ return pixmap;
+}
+
+template
+static void applyShadow(T obj, int blurRadius = 20, int xOffset = 10, int yOffset = 10, QString color = "#000000", int offset = 2) {
+ QGraphicsDropShadowEffect* dropShadow = new QGraphicsDropShadowEffect( );
+ dropShadow->setBlurRadius(blurRadius);
+ dropShadow->setXOffset(xOffset);
+ dropShadow->setYOffset(yOffset);
+ dropShadow->setColor(color);
+ dropShadow->setOffset(offset);
+ obj->setGraphicsEffect(dropShadow);
+}
diff --git a/src/View/Widgets/NavigationButton/NavigationButton.cpp b/src/View/Widgets/NavigationButton/NavigationButton.cpp
new file mode 100644
index 0000000..e5bf25b
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/NavigationButton.cpp
@@ -0,0 +1,11 @@
+#include "NavigationButton.h"
+
+NavigationButton::NavigationButton( ) { }
+
+NavigationButton::~NavigationButton( ) { }
+
+void setSelected(NavigationButton* newSelected);
+NavigationButton getSelected( ) { }
+
+void NavigationButton::select( ) { }
+void NavigationButton::unselect( ) { }
diff --git a/src/View/Widgets/NavigationButton/NavigationButton.h b/src/View/Widgets/NavigationButton/NavigationButton.h
new file mode 100644
index 0000000..2772088
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/NavigationButton.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include
+#include
+#include
+
+class NavigationButton : public QPushButton {
+ Q_OBJECT
+private:
+ QLabel* m_icon;
+ QLabel* m_name;
+ QString* m_colorHex;
+
+ static NavigationButton* m_selected;
+
+public:
+ static void setSelected(NavigationButton* newSelected);
+ static NavigationButton* getSelected( );
+
+ NavigationButton( );
+ ~NavigationButton( );
+
+signals:
+ void unselected( );
+ void selected( );
+
+private slots:
+ void select( );
+ void unselect( );
+
+};
diff --git a/src/View/Widgets/NavigationButton/PagesButton/PagesButton.cpp b/src/View/Widgets/NavigationButton/PagesButton/PagesButton.cpp
new file mode 100644
index 0000000..a7689d5
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/PagesButton/PagesButton.cpp
@@ -0,0 +1,4 @@
+#include "PagesButton.h"
+
+PagesButton::PagesButton( ) { }
+PagesButton::~PagesButton( ) { }
diff --git a/src/View/Widgets/NavigationButton/PagesButton/PagesButton.h b/src/View/Widgets/NavigationButton/PagesButton/PagesButton.h
new file mode 100644
index 0000000..6f72cd1
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/PagesButton/PagesButton.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "../NavigationButton.h"
+
+class PagesButton : NavigationButton {
+private:
+
+public:
+ PagesButton( );
+ ~PagesButton( );
+};
diff --git a/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.cpp b/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.cpp
new file mode 100644
index 0000000..6016e2d
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.cpp
@@ -0,0 +1,4 @@
+#include "PlaylistButton.h"
+
+PlaylistButton::PlaylistButton( ) { }
+PlaylistButton::~PlaylistButton( ) { }
diff --git a/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.h b/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.h
new file mode 100644
index 0000000..43c2584
--- /dev/null
+++ b/src/View/Widgets/NavigationButton/PlaylistButton/PlaylistButton.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "../NavigationButton.h"
+
+class PlaylistButton : NavigationButton {
+private:
+
+public:
+ PlaylistButton( );
+ ~PlaylistButton( );
+};
diff --git a/src/View/Widgets/PageNavigator/PageNavigator.cpp b/src/View/Widgets/PageNavigator/PageNavigator.cpp
new file mode 100644
index 0000000..110aa5b
--- /dev/null
+++ b/src/View/Widgets/PageNavigator/PageNavigator.cpp
@@ -0,0 +1,88 @@
+#include "PageNavigator.h"
+#include "SelectHandler.hpp"
+#include "../../Tools/SvgToPixmap.hpp"
+
+class SquareIcon : public QLabel {
+public:
+ QSize sizeHint( ) const override {
+ QSize hint = QLabel::sizeHint( );
+ int side = qMin(hint.width( ), hint.height( ));
+ return QSize(side, side);
+ }
+};
+
+PageNavigator::PageNavigator(QString text, QString icon, QString color, QWidget* parent)
+ :m_text(new QLabel(text)), m_icon(new SquareIcon( )), m_color(color), m_iconPath(icon) {
+
+
+ QSvgRenderer renderer(icon);
+
+ QPixmap pixmap(32, 32);
+ pixmap.fill(Qt::transparent);
+ QPainter painter(&pixmap);
+ renderer.render(&painter, pixmap.rect( ));
+
+ painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ painter.fillRect(pixmap.rect( ), color);
+ painter.end( );
+
+ m_icon->setPixmap(pixmap);
+
+ m_icon->setObjectName("icon");
+
+ setObjectName("PageNavigator");
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ setStyleSheet(R"(
+ #PageNavigator{
+ border: 4px solid #414141;
+ border-radius: 6px;
+ color: #E0E0E0;
+ }
+ )");
+
+ QFont font = m_text->font( );
+ font.setPointSize(16);
+ font.setWeight(QFont::Bold);
+ m_text->setFont(font);
+
+ QHBoxLayout* layout = new QHBoxLayout(this);
+ layout->addWidget(m_icon, 0, Qt::AlignLeft);
+ layout->addWidget(m_text, 1, Qt::AlignLeft);
+
+ connect(this, &QPushButton::clicked, [this, parent]( ) {
+ SelectHandler* sh = SelectHandler::GetInstance( );
+
+ sh->setSelected(this);
+ emit SelectedChanged(this);
+ });
+
+ // Little hacky but thats how home is the default
+ if (text == "Home") {
+ SelectHandler* sh = SelectHandler::GetInstance( );
+
+ sh->setSelected(this);
+ emit SelectedChanged(this);
+ }
+}
+
+void PageNavigator::unselect( ) {
+ setStyleSheet(R"(
+ #PageNavigator{
+ border: 4px solid #414141;
+ border-radius: 6px;
+ }
+ )");
+}
+
+void PageNavigator::select( ) {
+ setStyleSheet(R"(
+ #PageNavigator{
+ border: 4px solid )" + m_color + R"(;
+ border-radius: 6px;
+ }
+ )");
+}
+
+QString PageNavigator::GetText( ) {
+ return m_text->text( );
+}
diff --git a/src/Public/Widgets/PageNavigator/PageNavigator.h b/src/View/Widgets/PageNavigator/PageNavigator.h
similarity index 50%
rename from src/Public/Widgets/PageNavigator/PageNavigator.h
rename to src/View/Widgets/PageNavigator/PageNavigator.h
index d19d869..63474fc 100644
--- a/src/Public/Widgets/PageNavigator/PageNavigator.h
+++ b/src/View/Widgets/PageNavigator/PageNavigator.h
@@ -5,16 +5,25 @@
#include
#include
#include
+#include
+#include
class PageNavigator :public QPushButton {
Q_OBJECT
private:
QLabel* m_text;
QLabel* m_icon;
+ QString m_iconPath;
+ QString m_color;
public:
- PageNavigator(QString text, QString icon, QWidget* parent = nullptr);
+ PageNavigator(QString text, QString icon, QString color, QWidget* parent = nullptr);
void unselect( );
void select( );
+
+ QString GetText( );
+
+signals:
+ void SelectedChanged(PageNavigator* pn);
};
diff --git a/src/Public/Widgets/PageNavigator/SelectHandler.hpp b/src/View/Widgets/PageNavigator/SelectHandler.hpp
similarity index 95%
rename from src/Public/Widgets/PageNavigator/SelectHandler.hpp
rename to src/View/Widgets/PageNavigator/SelectHandler.hpp
index 3c0a33a..a3933d1 100644
--- a/src/Public/Widgets/PageNavigator/SelectHandler.hpp
+++ b/src/View/Widgets/PageNavigator/SelectHandler.hpp
@@ -1,6 +1,5 @@
#pragma once
-#include
#include "PageNavigator.h"
/*
@@ -40,7 +39,7 @@ void SelectHandler::setSelected(PageNavigator* newSelected) {
if (this->selected == nullptr) {
this->selected = newSelected;
- newSelected->select( );
+ selected->select( );
return;
}
diff --git a/src/core/SongHistory/SongHistory.hpp b/src/core/SongHistory/SongHistory.hpp
new file mode 100644
index 0000000..faaa459
--- /dev/null
+++ b/src/core/SongHistory/SongHistory.hpp
@@ -0,0 +1,47 @@
+#pragma once
+
+#include
+
+template
+class SongHistory {
+private:
+ struct Node {
+ T data;
+ Node* next;
+ };
+
+ Node* topNode = nullptr;
+
+public:
+ SongHistory( ) { }
+ ~SongHistory( ) {
+ while (!isEmpty( ))
+ pop( );
+ }
+
+ void push(const T& value) {
+ Node* newNode = new Node;
+ newNode->data = value;
+ newNode->next = topNode;
+ topNode = newNode;
+ }
+
+ void pop( ) {
+ if (!isEmpty( )) {
+ Node* tmp = topNode;
+ topNode = topNode->next;
+ delete tmp;
+ }
+ else
+ std::cerr << "Stack empty, cannot pop" << std::endl;
+ }
+
+ T top( ) {
+ if (!isEmpty( ))
+ return topNode->data;
+ else
+ return nullptr;
+ }
+
+ bool isEmpty( ) const { return topNode == nullptr; }
+};
diff --git a/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.cpp b/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.cpp
new file mode 100644
index 0000000..61ecffb
--- /dev/null
+++ b/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.cpp
@@ -0,0 +1,186 @@
+#include "ConditionalCircularLinkedList.h"
+
+ConditionalCircularLinkedList::ConditionalCircularLinkedList( ) { }
+
+void ConditionalCircularLinkedList::Append(Song* song) {
+ Node* newNode = new Node(song);
+ if (head == nullptr) {
+ head = newNode;
+
+ // Only link back when its supposed to
+ if (isLinked)
+ head->next = head;
+
+ current = head;
+ }
+ else {
+ Node* tmp = head;
+
+ while (tmp->next != head)
+ tmp = tmp->next;
+
+ tmp->next = newNode;
+
+ // Again make sure to only link when supposed to
+ if (isLinked)
+ newNode->next = head;
+ }
+}
+
+void ConditionalCircularLinkedList::SetListMode(bool isLooping) {
+ if (head == nullptr) {
+ std::cout << "WARN: List is empty, cannot set mode" << std::endl;
+ return;
+ }
+
+ Node* tmp = head;
+ while (tmp->next != head)
+ tmp = tmp->next;
+
+ if (!isLooping)
+ tmp->next = nullptr;
+ else
+ tmp->next = head;
+}
+
+void ConditionalCircularLinkedList::Clear( ) {
+ while (head != nullptr) {
+ Node* tmp = head;
+ head = head->next;
+ delete tmp;
+ delete current;
+ }
+}
+
+void ConditionalCircularLinkedList::Advance( ) {
+ if (current != nullptr)
+ current = current->next;
+}
+
+Song* ConditionalCircularLinkedList::GetNext( ) {
+ if (current != nullptr)
+ return current->data;
+}
+
+void ConditionalCircularLinkedList::AddSongBefore(Song* newSong, Song* addSongBefore) {
+ if (head == nullptr) return;
+
+ Node* newNode = new Node(newSong);
+
+ Node* current = head;
+ Node* prev = nullptr;
+
+ do {
+ if (current->data == addSongBefore) {
+ if (prev == nullptr) {
+ newNode->next = head;
+ head = newNode;
+
+ Node* lastNode = head;
+ while (lastNode->next != head)
+ lastNode = lastNode->next;
+
+ if (isLinked)
+ lastNode->next = head;
+ }
+ else {
+ prev->next = newNode;
+ newNode->next = current;
+ }
+ return;
+ }
+ prev = current;
+ current = current->next;
+
+ } while (current != head);
+}
+
+void ConditionalCircularLinkedList::AddSongAfter(Song* newSong, Song* addSongAfter) {
+ if (head == nullptr) return;
+
+ Node* newNode = new Node(newSong);
+
+ Node* current = head;
+
+ do {
+ if (current->data == addSongAfter) {
+ newNode->next = current->next;
+ current->next = newNode;
+ return;
+ }
+ current = current->next;
+ } while (current != head);
+
+}
+
+Song* ConditionalCircularLinkedList::RemoveSong(Song* removeSong) {
+ if (head == nullptr) return nullptr;
+
+ Node* current = head;
+ Node* prev = nullptr;
+
+ do {
+ if (current->data == removeSong) {
+ if (prev == nullptr) {
+ head = current->next;
+ Node* lastNode = head;
+ while (lastNode->next != current)
+ lastNode = lastNode->next;
+
+ if (isLinked)
+ lastNode->next = head;
+
+ Song* deletedSong = current->data;
+ delete current;
+ return deletedSong;
+ }
+ else {
+ prev->next = current->next;
+
+ Song* deletedSong = current->data;
+ delete current;
+ return deletedSong;
+ }
+ }
+ prev = current;
+ current = current->next;
+ } while (current != head);
+}
+
+bool ConditionalCircularLinkedList::IsEmpty( ) {
+ return current == nullptr;
+}
+
+void ConditionalCircularLinkedList::Shuffle( ) {
+ int cnt = 0;
+ Node* tmp = head;
+
+ while (tmp != nullptr) {
+ cnt++;
+ tmp = tmp->next;
+ }
+
+ Node** nodes = new Node * [cnt];
+
+ tmp = head;
+ for (int i = 0; i < cnt; i++) {
+ nodes[i] = tmp;
+ tmp = tmp->next;
+ }
+
+ for (int i = cnt; i > 0; i--) {
+ int j = rand( ) % (i + 1);
+
+ Node* tmp = nodes[i];
+ nodes[i] = nodes[j];
+ nodes[j] = tmp;
+ }
+
+ head = nodes[0];
+ for (int i = 0; i < cnt - 1; i++)
+ nodes[i]->next = nodes[i + 1];
+
+ nodes[cnt - 1]->next = nullptr;
+
+ delete[] nodes;
+}
diff --git a/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.h b/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.h
new file mode 100644
index 0000000..98ba4d4
--- /dev/null
+++ b/src/core/SongQueue/ConditionalCircularLinkedList/ConditionalCircularLinkedList.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include
+
+#include "../../song/song.h"
+
+class ConditionalCircularLinkedList {
+private:
+
+ struct Node {
+ Node* next;
+ Song* data;
+
+ Node(Song* song) : data(song), next(nullptr) { }
+ };
+
+ Node* head;
+
+ // Variable to keep the current position that we seek
+ Node* current;
+
+ // Variable to either link or unlink the list
+ bool isLinked;
+public:
+ ConditionalCircularLinkedList( );
+ ConditionalCircularLinkedList(bool isLinked) : head(nullptr), isLinked(isLinked) { }
+
+ /**
+ * @brief Append a new song to the queue
+ *
+ * @param song
+ */
+ void Append(Song* song);
+
+ /**
+ * @brief Clear the entire list so its brand spanking new.
+ *
+ */
+ void Clear( );
+
+ /**
+ * @brief Depending on if the queue is supposed to be looping, this will link
+ * up the end of the list, with its beginning to its a circular list.
+ * If its not supposed to loop then we break the link and it will be a normal list.
+ * @param isLooping Will set the list to circular or normal mode
+ */
+ void SetListMode(bool isLooping);
+
+ /**
+ * @brief Advance the circular list by one, this means setting the "current" pointer
+ * to the next element
+ *
+ */
+ void Advance( );
+
+ /**
+ * @brief Get the "current" pointer's data
+ *
+ * @return Song*
+ */
+ Song* GetNext( );
+
+ void AddSongBefore(Song* newSong, Song* addSongBefore);
+
+ void AddSongAfter(Song* newSong, Song* addSongAfter);
+
+ Song* RemoveSong(Song* removeSong);
+
+ bool IsEmpty( );
+
+ void Shuffle( );
+};
diff --git a/src/core/SongQueue/SongQueue.cpp b/src/core/SongQueue/SongQueue.cpp
new file mode 100644
index 0000000..1f0a0e9
--- /dev/null
+++ b/src/core/SongQueue/SongQueue.cpp
@@ -0,0 +1,94 @@
+#include "SongQueue.h"
+
+SongQueue::SongQueue( ) {
+ queue = new ConditionalCircularLinkedList( );
+
+ // Its never going to be linked, I'm just too lazy to make a new implementation thats almost the same
+ priorityQueue = new ConditionalCircularLinkedList(false);
+}
+
+SongQueue::~SongQueue( ) { }
+
+void SongQueue::PopulateQueue(const std::list& songList) {
+ for (Song* song : songList) {
+ queue->Append(song);
+ }
+}
+
+void SongQueue::Next( ) {
+ if (priorityQueue->IsEmpty( )) {
+ topSong = queue->GetNext( );
+ queue->Advance( );
+
+ return;
+ }
+
+ topSong = priorityQueue->GetNext( );
+ priorityQueue->Advance( );
+}
+
+void SongQueue::JumpToSong(Song* song, bool fromPrioQueue) {
+ if (fromPrioQueue) {
+ if (priorityQueue->IsEmpty( ))
+ return;
+
+ while (priorityQueue->GetNext( ) != song) {
+ priorityQueue->Advance( );
+ topSong = song;
+ }
+ }
+
+ if (queue->IsEmpty( ))
+ return;
+
+ while (queue->GetNext( ) != song) {
+ queue->Advance( );
+ topSong = song;
+ }
+}
+
+void SongQueue::AddToPriorityQueue(Song* song) {
+ priorityQueue->Append(song);
+}
+
+bool SongQueue::IsEmpty( ) {
+ return queue->IsEmpty( ) && priorityQueue->IsEmpty( );
+}
+
+Song* SongQueue::Top( ) { return topSong; }
+
+void SongQueue::SetTop(Song* song) { topSong = song; }
+
+void SongQueue::RemoveSongFromPriorityQueue(Song* song) {
+ if (priorityQueue->IsEmpty( ))
+ return;
+
+ priorityQueue->RemoveSong(song);
+}
+
+void SongQueue::MoveSongInPriorityQueue(Song* songToMove, Song* otherSong, bool beforeElseAfter) {
+ if (priorityQueue->IsEmpty( ))
+ return;
+
+ if (beforeElseAfter)
+ priorityQueue->AddSongBefore(songToMove, otherSong);
+ else
+ priorityQueue->AddSongAfter(songToMove, otherSong);
+}
+
+void SongQueue::ShufflePlaylist( ) {
+ //First backup the original list state
+ queue_original = new ConditionalCircularLinkedList(queue);
+
+ queue->Shuffle( );
+}
+
+void SongQueue::RestorePlaylist( ) {
+ if (queue_original == nullptr) return;
+
+ queue = new ConditionalCircularLinkedList(queue_original);
+}
+
+void SongQueue::LinkQueue(bool link) {
+ queue->SetListMode(link);
+}
diff --git a/src/core/SongQueue/SongQueue.h b/src/core/SongQueue/SongQueue.h
new file mode 100644
index 0000000..9522d51
--- /dev/null
+++ b/src/core/SongQueue/SongQueue.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include
+#include
+
+#include "../song/song.h"
+#include "ConditionalCircularLinkedList/ConditionalCircularLinkedList.h"
+
+class SongQueue {
+private:
+
+ // The currently playing song
+ Song* topSong;
+
+ //Regular song queue, can be unlinked for non looping playlists
+ ConditionalCircularLinkedList* queue;
+ //Copy of queue to faster restore when unshuffling
+ ConditionalCircularLinkedList* queue_original;
+
+ //The name is confusing, but its because the queue itself has priority over the normal one
+ ConditionalCircularLinkedList* priorityQueue;
+
+ void setQueue( );
+public:
+ SongQueue( );
+ ~SongQueue( );
+
+ void PopulateQueue(const std::list& songlist);
+
+ /**
+ * @brief Will put the next song from the correct sublist as the topSong.
+ * This will also remove the song from the queue as its not needed anymore.
+ *
+ */
+ void Next( );
+
+ /**
+ * @brief Will put the given song from the priority or normal queue as the top song and remove it
+ * from the list
+ *
+ * @param song
+ */
+ void JumpToSong(Song* song, bool fromPrioQueue);
+
+ void AddToPriorityQueue(Song* song);
+
+ bool IsEmpty( );
+
+ Song* Top( );
+
+ void SetTop(Song* song);
+
+ void RemoveSongFromPriorityQueue(Song* song);
+
+ void MoveSongInPriorityQueue(Song* songToMove, Song* otherSong, bool beforeElseAfter);
+
+ void ShufflePlaylist( );
+ void RestorePlaylist( );
+
+ void LinkQueue(bool link);
+};
diff --git a/src/core/audio/audio.cpp b/src/core/audio/audio.cpp
index 8daf5cf..d95646c 100644
--- a/src/core/audio/audio.cpp
+++ b/src/core/audio/audio.cpp
@@ -1,6 +1,6 @@
#include "audio.h"
-Audio::Audio(const std::string path) :path(path) {
+Audio::Audio( ) {
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
std::cerr << "SDL initialization failed: " << SDL_GetError( ) << std::endl;
return;
@@ -11,14 +11,6 @@ Audio::Audio(const std::string path) :path(path) {
SDL_Quit( );
return;
}
-
- music = Mix_LoadMUS(path.c_str( ));
- if (!music) {
- std::cerr << "Failed to load MP3 file: " << Mix_GetError( ) << std::endl;
- Mix_CloseAudio( );
- SDL_Quit( );
- return;
- }
};
Audio::~Audio( ) {
@@ -34,6 +26,22 @@ void Audio::StartMusic( ) {
}
}
+void Audio::StopMusic( ) {
+ Mix_HaltMusic( );
+}
+
+void Audio::PlaySong(const std::string path) {
+ this->path = path;
+
+ music = Mix_LoadMUS(path.c_str( ));
+ if (!music) {
+ std::cerr << "Failed to load MP3 file: " << Mix_GetError( ) << std::endl;
+ Mix_CloseAudio( );
+ SDL_Quit( );
+ return;
+ }
+}
+
void Audio::PauseMusic( ) {
if (Mix_PlayingMusic( ) == 1) {
Mix_PauseMusic( );
diff --git a/src/core/audio/audio.h b/src/core/audio/audio.h
index ff78741..d203c96 100644
--- a/src/core/audio/audio.h
+++ b/src/core/audio/audio.h
@@ -14,16 +14,16 @@ extern "C" {
class Audio {
public:
- static Audio& getInstance(const std::string path) {
- static Audio instance(path);
+ static Audio& getInstance( ) {
+ static Audio instance;
return instance;
}
private:
- Audio(const std::string path);
+ Audio( );
- const std::string path;
- const std::string artist;
- const std::string album;
+ std::string path;
+ std::string artist;
+ std::string album;
Mix_Music* music;
@@ -43,6 +43,9 @@ public:
QPixmap GetAlbumCover( );
+ void PlaySong(const std::string path);
+
+ void StopMusic( );
void StartMusic( );
void PauseMusic( );
void ResumeMusic( );
diff --git a/src/core/song/song.cpp b/src/core/song/song.cpp
new file mode 100644
index 0000000..2718dd6
--- /dev/null
+++ b/src/core/song/song.cpp
@@ -0,0 +1,36 @@
+#include "song.h"
+
+Song::Song(
+ std::string title,
+ std::string album,
+ std::string artist,
+ std::string codec,
+ std::string comment,
+ std::string copyright,
+ std::string publisher,
+ std::string genre,
+ std::string encoded_by,
+ std::string date,
+ std::string language,
+ std::string albumCoverPath,
+ std::string path,
+ int length,
+ std::string discoveredPath
+) : title(title),
+album(album),
+artist(artist),
+codec(codec),
+comment(comment),
+copyright(copyright),
+publisher(publisher),
+genre(genre),
+encoded_by(encoded_by),
+date(date),
+language(language),
+albumCoverPath(albumCoverPath),
+path(path),
+length(length) {
+
+}
+
+Song::~Song( ) { }
diff --git a/src/core/song/song.h b/src/core/song/song.h
new file mode 100644
index 0000000..f4d095e
--- /dev/null
+++ b/src/core/song/song.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include
+
+class Song {
+private:
+ // Song information
+ const std::string& title;
+ const std::string& album;
+ const std::string& artist;
+ const std::string& codec;
+ const std::string& comment;
+ const std::string& copyright;
+ const std::string& publisher;
+ const std::string& genre;
+ const std::string& encoded_by;
+ const std::string& date;
+ const std::string& language;
+ const std::string& albumCoverPath;
+ const std::string& path;
+ const int& length;
+
+ // Our own Metadata
+ bool favorite = false;
+ int playCount = 0;
+ std::string discovered;
+
+public:
+ Song(
+ std::string title,
+ std::string album,
+ std::string artist,
+ std::string codec,
+ std::string comment,
+ std::string copyright,
+ std::string publisher,
+ std::string genre,
+ std::string encoded_by,
+ std::string date,
+ std::string language,
+ std::string albumCoverPath,
+ std::string path,
+ int length,
+ std::string discoveredPath
+ );
+ ~Song( );
+
+ void SetFavorite(bool fav) { favorite = fav; }
+
+ void IncrementPlayCount( ) { playCount++; }
+
+ std::string GetPath( ) { return path; };
+
+};
diff --git a/src/main.cpp b/src/main.cpp
index cb8fb12..7bf1749 100755
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,4 +1,4 @@
-#include "Public/MainWindow.h"
+#include "View/MainWindow.h"
#include
#include