clean structure

This commit is contained in:
2026-06-11 14:03:35 +02:00
parent 326424f6fa
commit 677f263648
29 changed files with 119 additions and 82 deletions
+23 -19
View File
@@ -26,20 +26,21 @@ pkg_check_modules(FFTW REQUIRED IMPORTED_TARGET fftw3)
# sources # sources
set(SOURCES set(SOURCES
src/main.cpp src/main.cpp
src/MetadataReader.cpp src/config/Config.cpp
src/Config.cpp
src/MusicLibrary.cpp src/gui/CoverArtWidget.cpp
src/CoverArtWidget.cpp src/gui/SpectrogramWidget.cpp
src/SpectrogramWidget.cpp src/gui/GradientDialog.cpp
src/GradientDialog.cpp src/gui/EqualizerWidget.cpp
src/EqualizerWidget.cpp src/gui/TrackDelegate.cpp
src/TrackDelegate.cpp src/gui/MainWindow.cpp
src/MainWindow.cpp
# engine # engine
src/engine/AudioEngine.cpp src/engine/AudioEngine.cpp
src/engine/EqProcessor.cpp src/engine/EqProcessor.cpp
src/engine/SpectrumAnalyzer.cpp src/engine/SpectrumAnalyzer.cpp
src/engine/MusicLibrary.cpp
src/engine/MetadataReader.cpp
# ffmpeg # ffmpeg
src/engine/ffmpeg/FormatContext.cpp src/engine/ffmpeg/FormatContext.cpp
@@ -55,22 +56,23 @@ set(SOURCES
) )
set(HEADERS set(HEADERS
src/Track.h src/config/Config.h
src/MetadataReader.h
src/Config.h src/gui/CoverArtWidget.h
src/MusicLibrary.h src/gui/SpectrogramWidget.h
src/CoverArtWidget.h src/gui/GradientDialog.h
src/SpectrogramWidget.h src/gui/EqualizerWidget.h
src/GradientDialog.h src/gui/TrackDelegate.h
src/EqualizerWidget.h src/gui/MainWindow.h
src/TrackDelegate.h
src/MainWindow.h
# engine # engine
src/engine/AudioEngine.h src/engine/AudioEngine.h
src/engine/EqProcessor.h src/engine/EqProcessor.h
src/engine/SpectrumAnalyzer.h src/engine/SpectrumAnalyzer.h
src/engine/AudioBuffer.h src/engine/AudioBuffer.h
src/engine/Track.h
src/engine/MetadataReader.h
src/engine/MusicLibrary.h
# ffmpeg wrapper # ffmpeg wrapper
src/engine/ffmpeg/FormatContext.h src/engine/ffmpeg/FormatContext.h
@@ -97,9 +99,11 @@ add_executable(SubWave ${SOURCES} ${HEADERS} ${RESOURCES})
# headers # headers
target_include_directories(SubWave PRIVATE target_include_directories(SubWave PRIVATE
src src
src/config
src/engine src/engine
src/engine/ffmpeg src/engine/ffmpeg
src/playlists src/playlists
src/gui
) )
# link to qt and ffmpeg and fftw # link to qt and ffmpeg and fftw
-7
View File
@@ -1,7 +0,0 @@
#pragma once
#include "Track.h"
class MetadataReader {
public:
static void populate(Track &track);
};
View File
+2 -1
View File
@@ -27,7 +27,7 @@ void AudioEngine::setVolume(float v) {
if (m_sink) m_sink->setVolume(m_volume); if (m_sink) m_sink->setVolume(m_volume);
} }
void AudioEngine::play(const Track &track) { void AudioEngine::play(const engine::Track &track) {
stop(); stop();
m_stopReq = false; m_stopReq = false;
m_pauseReq = false; m_pauseReq = false;
@@ -197,3 +197,4 @@ void AudioEngine::playbackLoop() {
if (natural) if (natural)
emit trackEnded(); emit trackEnded();
} }
+2 -2
View File
@@ -29,7 +29,7 @@ public:
int sampleRate() const; int sampleRate() const;
void setVolume(float v); void setVolume(float v);
void play(const Track &track); void play(const engine::Track &track);
void togglePause(); void togglePause();
void stop(); void stop();
void seekFraction(double fraction); void seekFraction(double fraction);
@@ -68,7 +68,7 @@ private:
QMutex m_pauseMtx; QMutex m_pauseMtx;
QWaitCondition m_pauseCv; QWaitCondition m_pauseCv;
Track m_track; engine::Track m_track;
engine::EqProcessor m_eq; engine::EqProcessor m_eq;
float m_eqGainDb[EQ_BANDS] {}; float m_eqGainDb[EQ_BANDS] {};
@@ -5,7 +5,9 @@ extern "C" {
#include <libavutil/dict.h> #include <libavutil/dict.h>
} }
void MetadataReader::populate(Track &track) { namespace engine {
void MetadataReader::populate(engine::Track &track) {
AVFormatContext *fmt = nullptr; AVFormatContext *fmt = nullptr;
if (avformat_open_input(&fmt, track.filePath.toUtf8().constData(), if (avformat_open_input(&fmt, track.filePath.toUtf8().constData(),
nullptr, nullptr) < 0) return; nullptr, nullptr) < 0) return;
@@ -75,3 +77,4 @@ void MetadataReader::populate(Track &track) {
avformat_close_input(&fmt); avformat_close_input(&fmt);
} }
}
+11
View File
@@ -0,0 +1,11 @@
#pragma once
#include "Track.h"
namespace engine {
class MetadataReader {
public:
static void populate(engine::Track &track);
};
}
@@ -3,9 +3,11 @@
#include <QDirIterator> #include <QDirIterator>
#include <QFileInfo> #include <QFileInfo>
namespace engine {
MusicLibrary::MusicLibrary(QObject *parent) : QObject(parent) {} MusicLibrary::MusicLibrary(QObject *parent) : QObject(parent) {}
const QList<Track> &MusicLibrary::tracks() const { return m_tracks; } const QList<engine::Track> &MusicLibrary::tracks() const { return m_tracks; }
const QString &MusicLibrary::rootPath() const { return m_root; } const QString &MusicLibrary::rootPath() const { return m_root; }
void MusicLibrary::setRootPath(const QString &path) { m_root = path; } void MusicLibrary::setRootPath(const QString &path) { m_root = path; }
@@ -27,7 +29,7 @@ void MusicLibrary::scan() {
while (it.hasNext() && !QThread::currentThread()->isInterruptionRequested()) { while (it.hasNext() && !QThread::currentThread()->isInterruptionRequested()) {
QString path = it.next(); QString path = it.next();
Track t; engine::Track t;
t.filePath = path; t.filePath = path;
QString ext = QFileInfo(path).suffix().toLower(); QString ext = QFileInfo(path).suffix().toLower();
t.format = ext.toUpper(); t.format = ext.toUpper();
@@ -48,7 +50,7 @@ void MusicLibrary::scan() {
void MusicLibrary::sortByArtistTitle() { void MusicLibrary::sortByArtistTitle() {
QMutexLocker lk(&m_mtx); QMutexLocker lk(&m_mtx);
std::sort(m_tracks.begin(), m_tracks.end(), [](const Track &a, const Track &b){ std::sort(m_tracks.begin(), m_tracks.end(), [](const engine::Track &a, const engine::Track &b){
int c = a.artist.compare(b.artist, Qt::CaseInsensitive); int c = a.artist.compare(b.artist, Qt::CaseInsensitive);
return c != 0 ? c < 0 : a.title.compare(b.title, Qt::CaseInsensitive) < 0; return c != 0 ? c < 0 : a.title.compare(b.title, Qt::CaseInsensitive) < 0;
}); });
@@ -57,3 +59,5 @@ void MusicLibrary::sortByArtistTitle() {
void MusicLibrary::shutdown() { void MusicLibrary::shutdown() {
if (m_scanThread) { m_scanThread->requestInterruption(); m_scanThread->wait(); } if (m_scanThread) { m_scanThread->requestInterruption(); m_scanThread->wait(); }
} }
}
@@ -5,6 +5,8 @@
#include <QMutex> #include <QMutex>
#include "Track.h" #include "Track.h"
namespace engine {
class MusicLibrary : public QObject { class MusicLibrary : public QObject {
Q_OBJECT Q_OBJECT
public: public:
@@ -12,7 +14,7 @@ public:
{ "mp3", "flac", "wav", "ogg", "aac", "m4a", "opus", "wma" }; { "mp3", "flac", "wav", "ogg", "aac", "m4a", "opus", "wma" };
explicit MusicLibrary(QObject *parent = nullptr); explicit MusicLibrary(QObject *parent = nullptr);
const QList<Track> &tracks() const; const QList<engine::Track> &tracks() const;
const QString &rootPath() const; const QString &rootPath() const;
void setRootPath(const QString &path); void setRootPath(const QString &path);
void scan(); void scan();
@@ -21,12 +23,14 @@ public:
signals: signals:
void scanStarted(); void scanStarted();
void trackFound(const Track &track); void trackFound(const engine::Track &track);
void scanComplete(int count); void scanComplete(int count);
private: private:
QString m_root; QString m_root;
QList<Track> m_tracks; QList<engine::Track> m_tracks;
QThread *m_scanThread { nullptr }; QThread *m_scanThread { nullptr };
QMutex m_mtx; QMutex m_mtx;
}; };
}
+4
View File
@@ -3,6 +3,8 @@
#include <QImage> #include <QImage>
#include <QFileInfo> #include <QFileInfo>
namespace engine {
struct Track { struct Track {
QString filePath; QString filePath;
QString title; QString title;
@@ -29,3 +31,5 @@ struct Track {
return artist + " \u2014 " + title; return artist + " \u2014 " + title;
} }
}; };
}
@@ -7,7 +7,7 @@ CoverArtWidget::CoverArtWidget(QWidget *parent) : QWidget(parent) {
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
} }
void CoverArtWidget::setTrack(const Track *t) { void CoverArtWidget::setTrack(const engine::Track *t) {
m_cover = (t && !t->coverArt.isNull()) ? t->coverArt : QImage{}; m_cover = (t && !t->coverArt.isNull()) ? t->coverArt : QImage{};
m_title = t ? t->displayTitle() : "No track"; m_title = t ? t->displayTitle() : "No track";
m_artist = t ? t->artist : QString{}; m_artist = t ? t->artist : QString{};
@@ -1,13 +1,13 @@
#pragma once #pragma once
#include <QWidget> #include <QWidget>
#include <QImage> #include <QImage>
#include "Track.h" #include "engine/Track.h"
class CoverArtWidget : public QWidget { class CoverArtWidget : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit CoverArtWidget(QWidget *parent = nullptr); explicit CoverArtWidget(QWidget *parent = nullptr);
void setTrack(const Track *t); void setTrack(const engine::Track *t);
protected: protected:
void paintEvent(QPaintEvent *) override; void paintEvent(QPaintEvent *) override;
private: private:
+11 -12
View File
@@ -1,6 +1,6 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "AudioEngine.h" #include "AudioEngine.h"
#include "MusicLibrary.h" #include "engine/MusicLibrary.h"
#include "PlaylistModel.h" #include "PlaylistModel.h"
#include "TrackDelegate.h" #include "TrackDelegate.h"
#include "CoverArtWidget.h" #include "CoverArtWidget.h"
@@ -31,7 +31,7 @@ MainWindow::MainWindow(QWidget *parent)
setMinimumSize(700, 760); setMinimumSize(700, 760);
m_engine = new AudioEngine(this); m_engine = new AudioEngine(this);
m_library = new MusicLibrary(this); m_library = new engine::MusicLibrary(this);
m_model = new PlaylistModel(this); m_model = new PlaylistModel(this);
m_library->setRootPath(Config::loadMusicRoot()); m_library->setRootPath(Config::loadMusicRoot());
@@ -258,7 +258,7 @@ void MainWindow::wireSignals()
connect(m_engine, &AudioEngine::durationKnown, connect(m_engine, &AudioEngine::durationKnown,
this, [this](qint64 secs){ this, [this](qint64 secs){
if (m_currentIndex >= 0) { if (m_currentIndex >= 0) {
Track *t = m_model->trackAt(m_currentIndex); engine::Track *t = m_model->trackAt(m_currentIndex);
if (t && t->durationSecs == 0) { if (t && t->durationSecs == 0) {
t->durationSecs = secs; t->durationSecs = secs;
m_model->refreshRow(m_currentIndex); m_model->refreshRow(m_currentIndex);
@@ -267,15 +267,15 @@ void MainWindow::wireSignals()
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
// Library scanning // Library scanning
connect(m_library, &MusicLibrary::scanStarted, this, [this]{ connect(m_library, &engine::MusicLibrary::scanStarted, this, [this]{
m_model->setTracks({}); m_model->setTracks({});
m_lblStatus->setText("Scanning..."); m_lblStatus->setText("Scanning...");
}); });
connect(m_library, &MusicLibrary::trackFound, this, [this](const Track &t){ connect(m_library, &engine::MusicLibrary::trackFound, this, [this](const engine::Track &t){
m_model->appendTrack(t); m_model->appendTrack(t);
m_lblStatus->setText(QString("%1 tracks found").arg(m_model->rowCount({}))); m_lblStatus->setText(QString("%1 tracks found").arg(m_model->rowCount({})));
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
connect(m_library, &MusicLibrary::scanComplete, this, [this](int n){ connect(m_library, &engine::MusicLibrary::scanComplete, this, [this](int n){
m_model->setTracks(m_library->tracks()); // sorted version m_model->setTracks(m_library->tracks()); // sorted version
m_lblStatus->setText(QString("%1 tracks.").arg(n)); m_lblStatus->setText(QString("%1 tracks.").arg(n));
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@@ -290,7 +290,7 @@ void MainWindow::reloadLibrary()
void MainWindow::playTrack(int index) void MainWindow::playTrack(int index)
{ {
Track *t = m_model->trackAt(index); engine::Track *t = m_model->trackAt(index);
if (!t) return; if (!t) return;
m_currentIndex = index; m_currentIndex = index;
m_model->setCurrentIndex(index); m_model->setCurrentIndex(index);
@@ -351,15 +351,14 @@ void MainWindow::onUiTimer()
qint64 posF = m_engine->positionFrames(); qint64 posF = m_engine->positionFrames();
qint64 totF = m_engine->totalFrames(); qint64 totF = m_engine->totalFrames();
qint64 posSec = qint64(posF / sr); qint64 posSec = qint64(posF / sr);
engine::Track *currentTrack = (m_currentIndex >= 0) ? m_model->trackAt(m_currentIndex) : nullptr;
qint64 totSec = totF > 0 ? qint64(totF / sr) qint64 totSec = totF > 0 ? qint64(totF / sr)
: (m_currentIndex >= 0 : (currentTrack ? currentTrack->durationSecs : 0);
? (m_model->trackAt(m_currentIndex)
? m_model->trackAt(m_currentIndex)->durationSecs : 0)
: 0);
// Write back duration if we now know it // Write back duration if we now know it
if (totF > 0 && m_currentIndex >= 0) { if (totF > 0 && m_currentIndex >= 0) {
Track *t = m_model->trackAt(m_currentIndex); engine::Track *t = m_model->trackAt(m_currentIndex);
if (t && t->durationSecs == 0) { if (t && t->durationSecs == 0) {
t->durationSecs = totSec; t->durationSecs = totSec;
m_model->refreshRow(m_currentIndex); m_model->refreshRow(m_currentIndex);
+6 -3
View File
@@ -9,10 +9,13 @@
#include <QTimer> #include <QTimer>
#include <QTabWidget> #include <QTabWidget>
#include <QGroupBox> #include <QGroupBox>
#include <QHBoxLayout> // needed for buildTransportRow() return type #include <QHBoxLayout>
// Forward declarations
class AudioEngine; class AudioEngine;
class MusicLibrary; namespace engine {
class MusicLibrary;
}
class PlaylistModel; class PlaylistModel;
class CoverArtWidget; class CoverArtWidget;
class SpectrogramWidget; class SpectrogramWidget;
@@ -51,7 +54,7 @@ private:
// Core // Core
AudioEngine *m_engine; AudioEngine *m_engine;
MusicLibrary *m_library; engine::MusicLibrary *m_library;
PlaylistModel *m_model; PlaylistModel *m_model;
// Transport plain ASCII labels now // Transport plain ASCII labels now
@@ -1,5 +1,6 @@
#include "SpectrogramWidget.h" #include "SpectrogramWidget.h"
#include "GradientDialog.h" #include "GradientDialog.h"
#include <QTimer>
#include <QSurfaceFormat> #include <QSurfaceFormat>
#include <QFile> #include <QFile>
#include <QMouseEvent> #include <QMouseEvent>
@@ -27,10 +28,15 @@ SpectrogramWidget::SpectrogramWidget(QWidget *parent)
setMinimumSize(400, 200); setMinimumSize(400, 200);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_barHeights .resize(BAR_COUNT); m_barHeights.resize(BAR_COUNT);
m_barPeaksVec.resize(BAR_COUNT); m_barPeaksVec.resize(BAR_COUNT);
loadBarColors(); loadBarColors();
auto *timer = new QTimer(this);
connect(timer, &QTimer::timeout,
this, QOverload<>::of(&SpectrogramWidget::update));
timer->start(16);
} }
SpectrogramWidget::~SpectrogramWidget() SpectrogramWidget::~SpectrogramWidget()
@@ -287,6 +293,4 @@ void SpectrogramWidget::paintGL()
glBindVertexArray(0); glBindVertexArray(0);
m_barsProg.release(); m_barsProg.release();
} }
update();
} }
+4 -4
View File
@@ -77,7 +77,7 @@ void PlaylistCreatorDialog::onAddFiles()
// Check if already in playlist // Check if already in playlist
bool alreadyAdded = false; bool alreadyAdded = false;
for (const Track &t : m_playlist.tracks) { for (const engine::Track &t : m_playlist.tracks) {
if (t.filePath == filePath) { if (t.filePath == filePath) {
alreadyAdded = true; alreadyAdded = true;
break; break;
@@ -85,7 +85,7 @@ void PlaylistCreatorDialog::onAddFiles()
} }
if (!alreadyAdded) { if (!alreadyAdded) {
Track track; engine::Track track;
track.filePath = filePath; track.filePath = filePath;
// Set default metadata // Set default metadata
@@ -96,7 +96,7 @@ void PlaylistCreatorDialog::onAddFiles()
track.album = "Unknown Album"; track.album = "Unknown Album";
// Extract actual metadata and cover art // Extract actual metadata and cover art
MetadataReader::populate(track); engine::MetadataReader::populate(track);
m_playlist.tracks.append(track); m_playlist.tracks.append(track);
} }
@@ -145,7 +145,7 @@ void PlaylistCreatorDialog::updateTrackList()
{ {
m_trackList->clear(); m_trackList->clear();
for (const Track &track : m_playlist.tracks) { for (const engine::Track &track : m_playlist.tracks) {
QString display = track.displayTitle(); QString display = track.displayTitle();
if (!track.artist.isEmpty()) { if (!track.artist.isEmpty()) {
display = track.artist + " - " + display; display = track.artist + " - " + display;
+4 -4
View File
@@ -111,7 +111,7 @@ QStringList PlaylistManager::listPlaylists()
return result; return result;
} }
void PlaylistManager::addTrackToPlaylist(Playlist &playlist, const Track &track) void PlaylistManager::addTrackToPlaylist(Playlist &playlist, const engine::Track &track)
{ {
playlist.tracks.append(track); playlist.tracks.append(track);
} }
@@ -144,7 +144,7 @@ PlaylistManager::Playlist PlaylistManager::parsePlaylistJson(const QString &json
for (int i = 0; i < tracksArray.size(); ++i) { for (int i = 0; i < tracksArray.size(); ++i) {
QJsonObject trackObj = tracksArray[i].toObject(); QJsonObject trackObj = tracksArray[i].toObject();
Track track; engine::Track track;
track.filePath = trackObj["filePath"].toString(); track.filePath = trackObj["filePath"].toString();
track.title = trackObj["title"].toString(); track.title = trackObj["title"].toString();
track.artist = trackObj["artist"].toString(); track.artist = trackObj["artist"].toString();
@@ -157,7 +157,7 @@ PlaylistManager::Playlist PlaylistManager::parsePlaylistJson(const QString &json
if (!track.filePath.isEmpty()) { if (!track.filePath.isEmpty()) {
// Re-extract metadata and cover art from the file // Re-extract metadata and cover art from the file
// in case it has changed or cover art wasn't saved // in case it has changed or cover art wasn't saved
MetadataReader::populate(track); engine::MetadataReader::populate(track);
playlist.tracks.append(track); playlist.tracks.append(track);
} }
} }
@@ -171,7 +171,7 @@ QString PlaylistManager::playlistToJson(const Playlist &playlist)
QJsonObject root; QJsonObject root;
QJsonArray tracksArray; QJsonArray tracksArray;
for (const Track &track : playlist.tracks) { for (const engine::Track &track : playlist.tracks) {
QJsonObject trackObj; QJsonObject trackObj;
trackObj["filePath"] = track.filePath; trackObj["filePath"] = track.filePath;
trackObj["title"] = track.title; trackObj["title"] = track.title;
+3 -3
View File
@@ -2,13 +2,13 @@
#include <QString> #include <QString>
#include <QList> #include <QList>
#include "Track.h" #include "engine/Track.h"
class PlaylistManager { class PlaylistManager {
public: public:
struct Playlist { struct Playlist {
QString name; QString name;
QList<Track> tracks; QList<engine::Track> tracks;
QString filePath; QString filePath;
}; };
@@ -22,7 +22,7 @@ public:
static QStringList listPlaylists(); static QStringList listPlaylists();
// Track management // Track management
static void addTrackToPlaylist(Playlist &playlist, const Track &track); static void addTrackToPlaylist(Playlist &playlist, const engine::Track &track);
static void removeTrackFromPlaylist(Playlist &playlist, int index); static void removeTrackFromPlaylist(Playlist &playlist, int index);
static void clearPlaylist(Playlist &playlist); static void clearPlaylist(Playlist &playlist);
+10 -4
View File
@@ -3,13 +3,13 @@
PlaylistModel::PlaylistModel(QObject *parent) PlaylistModel::PlaylistModel(QObject *parent)
: QAbstractListModel(parent) {} : QAbstractListModel(parent) {}
void PlaylistModel::setTracks(const QList<Track> &tracks) { void PlaylistModel::setTracks(const QList<engine::Track> &tracks) {
beginResetModel(); beginResetModel();
m_tracks = tracks; m_tracks = tracks;
endResetModel(); endResetModel();
} }
void PlaylistModel::appendTrack(const Track &t) { void PlaylistModel::appendTrack(const engine::Track &t) {
beginInsertRows({}, m_tracks.size(), m_tracks.size()); beginInsertRows({}, m_tracks.size(), m_tracks.size());
m_tracks.append(t); m_tracks.append(t);
endInsertRows(); endInsertRows();
@@ -27,11 +27,17 @@ void PlaylistModel::refreshRow(int idx) {
emit dataChanged(index(idx), index(idx)); emit dataChanged(index(idx), index(idx));
} }
Track *PlaylistModel::trackAt(int idx) { engine::Track *PlaylistModel::trackAt(int idx) {
if (idx < 0 || idx >= m_tracks.size()) return nullptr; if (idx < 0 || idx >= m_tracks.size()) return nullptr;
return &m_tracks[idx]; return &m_tracks[idx];
} }
const engine::Track &PlaylistModel::trackAt(int idx) const {
static const engine::Track s_invalid;
if (idx < 0 || idx >= m_tracks.size()) return s_invalid;
return m_tracks[idx];
}
int PlaylistModel::rowCount(const QModelIndex &) const { int PlaylistModel::rowCount(const QModelIndex &) const {
return m_tracks.size(); return m_tracks.size();
} }
@@ -39,7 +45,7 @@ int PlaylistModel::rowCount(const QModelIndex &) const {
QVariant PlaylistModel::data(const QModelIndex &idx, int role) const { QVariant PlaylistModel::data(const QModelIndex &idx, int role) const {
if (!idx.isValid() || idx.row() >= m_tracks.size()) if (!idx.isValid() || idx.row() >= m_tracks.size())
return {}; return {};
const Track &t = m_tracks[idx.row()]; const engine::Track &t = m_tracks[idx.row()];
switch (role) { switch (role) {
case Qt::DisplayRole: case Qt::DisplayRole:
return t.displayTitle(); return t.displayTitle();
+6 -5
View File
@@ -1,22 +1,23 @@
#pragma once #pragma once
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QList> #include <QList>
#include "Track.h" #include "engine/Track.h"
class PlaylistModel : public QAbstractListModel { class PlaylistModel : public QAbstractListModel {
Q_OBJECT Q_OBJECT
public: public:
explicit PlaylistModel(QObject *parent=nullptr); explicit PlaylistModel(QObject *parent=nullptr);
void setTracks(const QList<Track> &tracks); void setTracks(const QList<engine::Track> &tracks);
void appendTrack(const Track &t); void appendTrack(const engine::Track &t);
void setCurrentIndex(int idx); void setCurrentIndex(int idx);
void refreshRow(int idx); void refreshRow(int idx);
Track *trackAt(int idx); engine::Track *trackAt(int idx);
const engine::Track &trackAt(int idx) const;
int rowCount(const QModelIndex &) const override; int rowCount(const QModelIndex &) const override;
QVariant data(const QModelIndex &idx, int role) const override; QVariant data(const QModelIndex &idx, int role) const override;
int currentIndex() const; int currentIndex() const;
private: private:
QList<Track> m_tracks; QList<engine::Track> m_tracks;
int m_current { -1 }; int m_current { -1 };
}; };