// src/MainWindow.h #pragma once #include #include #include #include #include #include #include #include "AudioEngine.h" #include "PlayerControls.h" #include "CommonWidgets.h" #include "Utils.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* parent = nullptr); ~MainWindow(); void loadPath(const QString& path, bool recursive); protected: void closeEvent(QCloseEvent* event) override; private slots: void onOpenFile(); void onOpenFolder(); void onPermissionsResult(bool granted); void onTrackFinished(); void onTrackLoaded(bool success); void onTrackDoubleClicked(QListWidgetItem* item); void onAnalysisReady(float bpm, float confidence); void updateSmoothing(); void play(); void pause(); void nextTrack(); void prevTrack(); void seek(float pos); void onDspChanged(int fft, int hop); void onBinsChanged(int n); void onToggleFullScreen(); void saveSettings(); void onMetadataLoaded(int index, const Utils::Metadata& meta); // Visualizer Pull void onSpectrumAvailable(); // Update Analyzer with new track data void onTrackDataChanged(std::shared_ptr data); private: void initUi(); void loadIndex(int index); void loadSettings(); QStackedWidget* m_stack; WelcomeWidget* m_welcome; PlayerPage* m_playerPage; QDockWidget* m_dock; QTabWidget* m_mobileTabs; QListWidget* m_playlist; // Audio System AudioEngine* m_engine; QThread* m_audioThread; // Analysis System AudioAnalyzer* m_analyzer; QThread* m_analyzerThread; struct TrackInfo { QString path; Utils::Metadata meta; }; QVector m_tracks; int m_currentIndex = -1; enum class PendingAction { None, File, Folder }; PendingAction m_pendingAction = PendingAction::None; QString m_settingsDir; float m_lastBpm = 0.0f; Utils::MetadataLoader* m_metaLoader = nullptr; QThread* m_metaThread = nullptr; bool m_visualizerUpdatePending = false; };