From 905344d5128adc22c72bddaf61091ef77445408b Mon Sep 17 00:00:00 2001 From: w1z7ard Date: Sun, 4 Oct 2009 02:20:03 +0000 Subject: [PATCH] refactored libprojectM preset rating interface to support generic number of ratings. git-svn-id: https://projectm.svn.sourceforge.net/svnroot/projectm/trunk@1289 6778bc44-b910-0410-a7a0-be141de4315d --- src/libprojectM/CMakeLists.txt | 2 +- src/libprojectM/Common.hpp | 12 +++ src/libprojectM/PresetChooser.hpp | 50 ++++----- src/libprojectM/PresetLoader.cpp | 126 ++++++++-------------- src/libprojectM/PresetLoader.hpp | 41 ++++--- src/libprojectM/projectM.cpp | 33 +++--- src/libprojectM/projectM.hpp | 17 ++- src/projectM-qt/qplaylistmodel.cpp | 51 ++++++--- src/projectM-qt/qplaylistmodel.hpp | 7 +- src/projectM-qt/qprojectm_mainwindow.cpp | 29 +++-- src/projectM-qt/qprojectm_mainwindow.hpp | 6 +- src/projectM-qt/qprojectmconfigdialog.cpp | 4 +- src/projectM-qt/qprojectmconfigdialog.ui | 22 +++- 13 files changed, 211 insertions(+), 189 deletions(-) diff --git a/src/libprojectM/CMakeLists.txt b/src/libprojectM/CMakeLists.txt index 43522c7aa..487079438 100644 --- a/src/libprojectM/CMakeLists.txt +++ b/src/libprojectM/CMakeLists.txt @@ -188,5 +188,5 @@ INSTALL(FILES ${fonts} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/projectM/fonts) INSTALL(FILES ${Renderer_SOURCE_DIR}/projectM.cg ${Renderer_SOURCE_DIR}/blur.cg DESTINATION ${CMAKE_INSTALL_PREFIX}/share/projectM/shaders) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/libprojectM.pc DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/pkgconfig) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/config.inp DESTINATION ${CMAKE_INSTALL_PREFIX}/share/projectM) -INSTALL(FILES projectM.hpp event.h dlldefs.h fatal.h PCM.hpp DESTINATION include/libprojectM) +INSTALL(FILES projectM.hpp event.h dlldefs.h fatal.h PCM.hpp Common.hpp DESTINATION include/libprojectM) INSTALL(TARGETS projectM DESTINATION lib${LIB_SUFFIX}) diff --git a/src/libprojectM/Common.hpp b/src/libprojectM/Common.hpp index 7d4c6f934..c15234a70 100755 --- a/src/libprojectM/Common.hpp +++ b/src/libprojectM/Common.hpp @@ -26,6 +26,7 @@ #ifndef COMMON_HPP #define COMMON_HPP +#include #include #include #include @@ -210,6 +211,17 @@ inline double meanSquaredError(const double & x, const double & y) { } +enum PresetRatingType { + FIRST_RATING_TYPE = 0, + HARD_CUT_RATING_TYPE = FIRST_RATING_TYPE, + SOFT_CUT_RATING_TYPE, + LAST_RATING_TYPE = SOFT_CUT_RATING_TYPE, + TOTAL_RATING_TYPES = SOFT_CUT_RATING_TYPE+1 +}; + + +typedef std::vector RatingList; + #endif diff --git a/src/libprojectM/PresetChooser.hpp b/src/libprojectM/PresetChooser.hpp index 6c8733ce9..ab88b2a6e 100644 --- a/src/libprojectM/PresetChooser.hpp +++ b/src/libprojectM/PresetChooser.hpp @@ -60,7 +60,11 @@ public: /// Initializes a chooser with an established preset loader. /// \param presetLoader an initialized preset loader to choose presets from /// \note The preset loader is refreshed via events or otherwise outside this class's scope - PresetChooser(const PresetLoader & presetLoader); + PresetChooser(const PresetLoader & presetLoader, bool softCutRatingsEnabled); + + inline void setSoftCutRatingsEnabled(bool enabled) { + _softCutRatingsEnabled = enabled; + } /// Choose a preset via the passed in index. Must be between 0 and num valid presets in directory /// \param index An index lying in the interval [0, this->getNumPresets()) @@ -100,14 +104,12 @@ public: private: std::vector sampleWeights; const PresetLoader * _presetLoader; + bool _softCutRatingsEnabled; }; -inline PresetChooser::PresetChooser(const PresetLoader & presetLoader):_presetLoader(&presetLoader) { - - const float breedProb = .80; - sampleWeights.push_back(breedProb); - sampleWeights.push_back(1.0-breedProb); +inline PresetChooser::PresetChooser(const PresetLoader & presetLoader, bool softCutRatingsEnabled):_presetLoader(&presetLoader), _softCutRatingsEnabled(softCutRatingsEnabled) { + } inline std::size_t PresetChooser::size() const { @@ -217,30 +219,22 @@ inline std::auto_ptr PresetChooser::directoryIndex(std::size_t index) co inline PresetChooser::iterator PresetChooser::weightedRandom(bool hardCut) const { - std::size_t index; + + - if (hardCut) { - index = RandomNumberGenerators::weightedRandom - (_presetLoader->getPresetRatings(), _presetLoader->getPresetRatingsSum()); + // TODO make a sophisticated function object interface to determine why a certain rating + // category is chosen, or weighted distribution thereover. + const PresetRatingType ratingType = hardCut || (!_softCutRatingsEnabled) ? + HARD_CUT_RATING_TYPE : SOFT_CUT_RATING_TYPE; - } else { - const std::size_t choice = RandomNumberGenerators::weightedRandomNormalized(sampleWeights); - if (choice == 0) { // use smooth weights - index = RandomNumberGenerators::weightedRandom - (_presetLoader->getPresetBreedabilities(), _presetLoader->getPresetBreedabilitiesSum()); - std::cout << "Using breed weights (sum=" << - _presetLoader->getPresetBreedabilitiesSum() - << ")" << std::endl; - } - else { - index = RandomNumberGenerators::weightedRandom - (_presetLoader->getPresetRatings(), _presetLoader->getPresetRatingsSum()); - std::cout << "Using regular weights (sum=" << - _presetLoader->getPresetRatingsSum() - << ")" << std::endl; - } - - } + const std::size_t ratingsTypeIndex = static_cast(ratingType); + + const std::vector & weights = _presetLoader->getPresetRatings()[ratingsTypeIndex]; + + const std::size_t index = RandomNumberGenerators::weightedRandom + (weights, + _presetLoader->getPresetRatingsSums()[ratingsTypeIndex]); + return begin(index); } diff --git a/src/libprojectM/PresetLoader.cpp b/src/libprojectM/PresetLoader.cpp index 4c6a1a525..744725b53 100644 --- a/src/libprojectM/PresetLoader.cpp +++ b/src/libprojectM/PresetLoader.cpp @@ -35,12 +35,14 @@ extern "C" #include "Common.hpp" -PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname ), _dir ( 0 ), _ratingsSum ( 0 ), _breedabilitiesSum(0) +PresetLoader::PresetLoader (int gx, int gy, std::string dirname = std::string()) :_dirname ( dirname ), _dir ( 0 ) { _presetFactoryManager.initialize(gx,gy); // Do one scan if ( _dirname != std::string() ) rescan(); + else + clear(); } PresetLoader::~PresetLoader() @@ -60,13 +62,8 @@ void PresetLoader::rescan() // std::cerr << "Rescanning..." << std::endl; // Clear the directory entry collection - _entries.clear(); - _presetNames.clear(); - _ratings.clear(); - _breedabilities.clear(); - _ratingsSum = 0; - _breedabilitiesSum = 0; - + clear(); + // If directory already opened, close it first if ( _dir ) { @@ -120,16 +117,11 @@ void PresetLoader::rescan() _presetNames.push_back ( *pos ); // Give all presets equal rating of 3 - why 3? I don't know - _ratings = std::vector ( _presetNames.size(), 3 ); - _ratingsSum = 3 * _ratings.size(); - - // Give all presets equal breedability of 3 - why 3? I don't know - _breedabilities = std::vector ( _presetNames.size(), 3 ); - _breedabilitiesSum = 3 * _breedabilities.size(); + _ratings = std::vector(TOTAL_RATING_TYPES, RatingList( _presetNames.size(), 3 )); + _ratingsSums = std::vector(2, 3 * _ratings.size()); + assert ( _entries.size() == _presetNames.size() ); - assert ( _ratings.size() == _entries.size() ); - assert ( _breedabilities.size() == _entries.size() ); @@ -197,48 +189,35 @@ void PresetLoader::handleDirectoryError() #endif } -void PresetLoader::setRating ( unsigned int index, int rating ) +void PresetLoader::setRating(unsigned int index, int rating, const PresetRatingType ratingType) { assert ( index >=0 ); - assert ( index < _ratings.size() ); + + const unsigned int ratingTypeIndex = static_cast(ratingType); + assert (index < _ratings[ratingTypeIndex].size()); + + _ratingsSums[ratingTypeIndex] -= _ratings[ratingTypeIndex][index]; - _ratingsSum -= _ratings[index]; - _ratings[index] = rating; - _ratingsSum += rating; - - assert ( _entries.size() == _presetNames.size() ); - assert ( _ratings.size() == _entries.size() ); + _ratings[ratingTypeIndex][index] = rating; + _ratingsSums[ratingType] += rating; } -void PresetLoader::setBreedability ( unsigned int index, int breedability) + +unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, const std::vector & ratings) { - assert ( index >=0 ); - assert ( index < _breedabilities.size() ); - - _breedabilitiesSum -= _breedabilities[index]; - _breedabilities[index] = breedability; - _breedabilitiesSum += breedability; - - assert ( _entries.size() == _presetNames.size() ); - assert ( _breedabilities.size() == _entries.size() ); - -} - -unsigned int PresetLoader::addPresetURL ( const std::string & url, const std::string & presetName, int rating, int breedability ) -{ - _entries.push_back ( url ); + _entries.push_back(url); _presetNames.push_back ( presetName ); - _ratings.push_back ( rating ); - _ratingsSum += rating; - _breedabilities.push_back(breedability); - _breedabilitiesSum += breedability; + assert(ratings.size() == TOTAL_RATING_TYPES); + assert(ratings.size() == _ratings.size()); - assert ( _entries.size() == _presetNames.size() ); - assert ( _ratings.size() == _entries.size() ); - assert ( _breedabilities.size() == _breedabilities.size() ); + for (int i = 0; i < _ratings.size(); i++) + _ratings[i].push_back(ratings[i]); + for (int i = 0; i < ratings.size(); i++) + _ratingsSums[i] += ratings[i]; + return _entries.size()-1; } @@ -247,16 +226,12 @@ void PresetLoader::removePreset ( unsigned int index ) _entries.erase ( _entries.begin() + index ); _presetNames.erase ( _presetNames.begin() + index ); - - _ratingsSum -= _ratings[index]; - _ratings.erase ( _ratings.begin() + index ); - - _breedabilitiesSum -= _breedabilities[index]; - _breedabilities.erase ( _breedabilities.begin() + index ); - - assert ( _entries.size() == _presetNames.size() ); - assert ( _ratings.size() == _entries.size() ); - assert ( _breedabilities.size() == _entries.size() ); + + for (int i = 0; i < _ratingsSums.size(); i++) { + _ratingsSums[i] -= _ratings[i][index]; + _ratings[i].erase ( _ratings[i].begin() + index ); + } + } @@ -270,46 +245,37 @@ const std::string & PresetLoader::getPresetName ( unsigned int index ) const return _presetNames[index]; } -int PresetLoader::getPresetRating ( unsigned int index ) const +int PresetLoader::getPresetRating ( unsigned int index, const PresetRatingType ratingType ) const { - return _ratings[index]; + return _ratings[ratingType][index]; } -const std::vector & PresetLoader::getPresetBreedabilities () const -{ - return _breedabilities; -} - - -const std::vector & PresetLoader::getPresetRatings () const +const std::vector & PresetLoader::getPresetRatings () const { return _ratings; } - -int PresetLoader::getPresetBreedabilitiesSum() const { - return _breedabilitiesSum; -} - -int PresetLoader::getPresetRatingsSum () const -{ - return _ratingsSum; +const std::vector & PresetLoader::getPresetRatingsSums() const { + return _ratingsSums; } void PresetLoader::setPresetName(unsigned int index, std::string name) { _presetNames[index] = name; } -void PresetLoader::insertPresetURL ( unsigned int index, const std::string & url, const std::string & presetName, int rating, int breedability ) +void PresetLoader::insertPresetURL ( unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings) { _entries.insert ( _entries.begin() + index, url ); _presetNames.insert ( _presetNames.begin() + index, presetName ); - _ratings.insert ( _ratings.begin() + index, rating ); - _ratingsSum += rating; - _breedabilities.insert ( _breedabilities.begin() + index, rating ); - _breedabilitiesSum += rating; + + + + for (int i = 0; i < _ratingsSums.size();i++) { + _ratingsSums[i] += _ratings[i][index]; + _ratings[i].insert ( _ratings[i].begin() + index, ratings[i] ); + } assert ( _entries.size() == _presetNames.size() ); assert ( _ratings.size() == _entries.size() ); - assert ( _breedabilities.size() == _entries.size() ); + } diff --git a/src/libprojectM/PresetLoader.hpp b/src/libprojectM/PresetLoader.hpp index b6c0703d1..02d43c18f 100644 --- a/src/libprojectM/PresetLoader.hpp +++ b/src/libprojectM/PresetLoader.hpp @@ -24,9 +24,11 @@ class Preset; class PresetFactory; + class PresetLoader { public: - + + /// Initializes the preset loader with the target directory specified PresetLoader(int gx, int gy, std::string dirname); @@ -41,33 +43,38 @@ class PresetLoader { /// \param presetName a name for the preset /// \param rating an integer representing the goodness of the preset /// \returns The unique index assigned to the preset in the collection. Used with loadPreset - unsigned int addPresetURL ( const std::string & url, const std::string & presetName, int rating, int breedability); - - - void setBreedability ( unsigned int index, int breedability); - + unsigned int addPresetURL ( const std::string & url, const std::string & presetName, const RatingList & ratings); + /// Add a preset to the loader's collection. /// \param index insertion index /// \param url an url referencing the preset /// \param presetName a name for the preset /// \param rating an integer representing the goodness of the preset - void insertPresetURL (unsigned int index, const std::string & url, const std::string & presetName, int rating, int breedability); + void insertPresetURL (unsigned int index, const std::string & url, const std::string & presetName, const RatingList & ratings); /// Clears all presets from the collection - inline void clear() { _entries.clear(); _presetNames.clear(); _ratings.clear(); _breedabilities.clear(); _ratingsSum = _breedabilitiesSum = 0; } - int getPresetBreedabilitiesSum() const; - const std::vector & getPresetRatings() const; - int getPresetRatingsSum() const; + inline void clear() { + _entries.clear(); _presetNames.clear(); + _ratings = std::vector(TOTAL_RATING_TYPES, RatingList()); + clearRatingsSum(); + } + + inline void clearRatingsSum() { + _ratingsSums = std::vector(TOTAL_RATING_TYPES, 0); + } + const std::vector & getPresetRatings() const; + const std::vector & getPresetRatingsSums() const; + /// Removes a preset from the loader /// \param index the unique identifier of the preset url to be removed void removePreset(unsigned int index); /// Sets the rating of a preset to a new value - void setRating(unsigned int index, int rating); + void setRating(unsigned int index, int rating, const PresetRatingType ratingType); /// Get a preset rating given an index - int getPresetRating ( unsigned int index) const; + int getPresetRating ( unsigned int index, const PresetRatingType ratingType) const; /// Get a preset url given an index const std::string & getPresetURL ( unsigned int index) const; @@ -87,7 +94,7 @@ class PresetLoader { inline const std::string & directoryName() const { return _dirname; } - const std::vector & getPresetBreedabilities () const; + /// Rescans the active preset directory void rescan(); void setPresetName(unsigned int index, std::string name); @@ -95,13 +102,15 @@ class PresetLoader { void handleDirectoryError(); std::string _dirname; DIR * _dir; - int _ratingsSum, _breedabilitiesSum; + std::vector _ratingsSums; mutable PresetFactoryManager _presetFactoryManager; // vector chosen for speed, but not great for reverse index lookups std::vector _entries; std::vector _presetNames; - std::vector _ratings, _breedabilities; + + // Indexed by ratingType, preset position. + std::vector _ratings; }; diff --git a/src/libprojectM/projectM.cpp b/src/libprojectM/projectM.cpp index 76dbb9d4c..e5c458341 100755 --- a/src/libprojectM/projectM.cpp +++ b/src/libprojectM/projectM.cpp @@ -142,7 +142,7 @@ bool projectM::writeConfig(const std::string & configFile, const Settings & sett config.add("Aspect Correction", settings.aspectCorrection); config.add("Easter Egg Parameter", settings.easterEgg); config.add("Shuffle Enabled", settings.shuffleEnabled); - + config.add("Soft Cut Ratings Enabled", settings.softCutRatingsEnabled); std::fstream file(configFile.c_str()); if (file) { file << config; @@ -206,7 +206,8 @@ void projectM::readConfig (const std::string & configFile ) _settings.shuffleEnabled = config.read ( "Shuffle Enabled", true); _settings.easterEgg = config.read ( "Easter Egg Parameter", 0.0); - + _settings.softCutRatingsEnabled = + config.read ( "Soft Cut Ratings Enabled", false); projectM_init ( _settings.meshX, _settings.meshY, _settings.fps, _settings.textureSize, _settings.windowWidth,_settings.windowHeight); @@ -233,7 +234,7 @@ void projectM::readSettings (const Settings & settings ) _settings.windowHeight = settings.windowHeight; _settings.smoothPresetDuration = settings.smoothPresetDuration; _settings.presetDuration = settings.presetDuration; - + _settings.softCutRatingsEnabled = settings.softCutRatingsEnabled; _settings.presetURL = settings.presetURL; _settings.titleFontURL = settings.titleFontURL; @@ -528,7 +529,7 @@ static void *thread_callback(void *prjm) { return PROJECTM_FAILURE; } - if ( ( m_presetChooser = new PresetChooser ( *m_presetLoader ) ) == 0 ) + if ( ( m_presetChooser = new PresetChooser ( *m_presetLoader, settings().softCutRatingsEnabled ) ) == 0 ) { delete ( m_presetLoader ); @@ -630,14 +631,14 @@ static void *thread_callback(void *prjm) { } - unsigned int projectM::addPresetURL ( const std::string & presetURL, const std::string & presetName, int rating, int breedability ) + unsigned int projectM::addPresetURL ( const std::string & presetURL, const std::string & presetName, const RatingList & ratings) { bool restorePosition = false; if (*m_presetPos == m_presetChooser->end()) restorePosition = true; - int index = m_presetLoader->addPresetURL ( presetURL, presetName, rating, breedability); + int index = m_presetLoader->addPresetURL ( presetURL, presetName, ratings); if (restorePosition) *m_presetPos = m_presetChooser->end(); @@ -666,12 +667,9 @@ static void *thread_callback(void *prjm) { presetSwitchedEvent(hardCut, **m_presetPos); - } - -int projectM::getPresetBreedability(unsigned int index) const { - return m_presetLoader->getPresetBreedabilities()[index]; } + void projectM::selectRandom(const bool hardCut) { if (m_presetChooser->empty()) @@ -769,9 +767,9 @@ void projectM::selectNext(const bool hardCut) { return m_presetLoader->getPresetURL(index); } - int projectM::getPresetRating ( unsigned int index ) const + int projectM::getPresetRating ( unsigned int index, const PresetRatingType ratingType) const { - return m_presetLoader->getPresetRating(index); + return m_presetLoader->getPresetRating(index, ratingType); } std::string projectM::getPresetName ( unsigned int index ) const @@ -809,11 +807,11 @@ void projectM::selectNext(const bool hardCut) { return m_presetLoader->size(); } - void projectM:: changePresetRating (unsigned int index, int rating) { - m_presetLoader->setRating(index, rating); + void projectM:: changePresetRating (unsigned int index, int rating, const PresetRatingType ratingType) { + m_presetLoader->setRating(index, rating, ratingType); } - void projectM::insertPresetURL(unsigned int index, const std::string & presetURL, const std::string & presetName, int rating, int breedability) + void projectM::insertPresetURL(unsigned int index, const std::string & presetURL, const std::string & presetName, const RatingList & ratings) { bool atEndPosition = false; @@ -840,7 +838,7 @@ void projectM::selectNext(const bool hardCut) { newSelectedIndex++; } - m_presetLoader->insertPresetURL (index, presetURL, presetName, rating, breedability); + m_presetLoader->insertPresetURL (index, presetURL, presetName, ratings); if (atEndPosition) *m_presetPos = m_presetChooser->end(); @@ -854,7 +852,4 @@ void projectM::changePresetName ( unsigned int index, std::string name ) { m_presetLoader->setPresetName(index, name); } -void projectM::changePresetBreedability( unsigned int index, int breedability) { - m_presetLoader->setBreedability(index, breedability); -} diff --git a/src/libprojectM/projectM.hpp b/src/libprojectM/projectM.hpp index 60f77531c..8fd7fbea3 100755 --- a/src/libprojectM/projectM.hpp +++ b/src/libprojectM/projectM.hpp @@ -64,8 +64,6 @@ #include "pthread.h" class PipelineContext; -#include - class BeatDetect; class PCM; class Func; @@ -79,6 +77,8 @@ class Pipeline; class RenderItemMatcher; class MasterRenderItemMerge; +#include "Common.hpp" + #include #ifdef WIN32 #pragma warning (disable:4244) @@ -113,7 +113,6 @@ class RandomizerFunctor { const PresetChooser & m_chooser; }; - class DLLEXPORT projectM { public: @@ -136,6 +135,7 @@ public: bool aspectCorrection; float easterEgg; bool shuffleEnabled; + bool softCutRatingsEnabled; }; projectM(std::string config_file, int flags = FLAG_NONE); @@ -201,11 +201,11 @@ public: bool selectedPresetIndex(unsigned int & index) const; /// Add a preset url to the play list. Appended to bottom. Returns index of preset - unsigned int addPresetURL(const std::string & presetURL, const std::string & presetName, int rating, int breedability); + unsigned int addPresetURL(const std::string & presetURL, const std::string & presetName, const RatingList & ratingList); /// Insert a preset url to the play list at the suggested index. void insertPresetURL(unsigned int index, - const std::string & presetURL, const std::string & presetName, int rating, int breedability); + const std::string & presetURL, const std::string & presetName, const RatingList & ratingList); /// Returns true if the selected preset position points to an actual preset in the /// currently loaded playlist @@ -220,12 +220,9 @@ public: void changePresetName ( unsigned int index, std::string name ); /// Returns the rating associated with a preset index - int getPresetRating (unsigned int index) const; + int getPresetRating (unsigned int index, const PresetRatingType ratingType) const; - void changePresetRating (unsigned int index, int rating); - - int getPresetBreedability(unsigned int index) const; - void changePresetBreedability(unsigned int index, int breedability); + void changePresetRating (unsigned int index, int rating, const PresetRatingType ratingType); /// Returns the size of the play list unsigned int getPlaylistSize() const; diff --git a/src/projectM-qt/qplaylistmodel.cpp b/src/projectM-qt/qplaylistmodel.cpp index 9f5e13617..727520f4d 100644 --- a/src/projectM-qt/qplaylistmodel.cpp +++ b/src/projectM-qt/qplaylistmodel.cpp @@ -80,6 +80,10 @@ class XmlWriteFunctor { }; +bool QPlaylistModel::softCutRatingsEnabled() const { + return m_projectM.settings().softCutRatingsEnabled; +} + QPlaylistModel::QPlaylistModel ( projectM & _projectM, QObject * parent ) : QAbstractTableModel ( parent ), m_projectM ( _projectM ) { @@ -99,11 +103,11 @@ bool QPlaylistModel::setData ( const QModelIndex & index, const QVariant & value { if ( role == QPlaylistModel::RatingRole ) { - m_projectM.changePresetRating(index.row(), value.toInt()); + m_projectM.changePresetRating(index.row(), value.toInt(), HARD_CUT_RATING_TYPE); emit ( dataChanged ( index, index ) ); return true; } else if (role == QPlaylistModel::BreedabilityRole) { - m_projectM.changePresetBreedability(index.row(), value.toInt()); + m_projectM.changePresetRating(index.row(), value.toInt(), SOFT_CUT_RATING_TYPE); emit ( dataChanged ( index, index ) ); return true; } else if (role == QPlaylistModel::NameRole) { @@ -251,25 +255,27 @@ QVariant QPlaylistModel::data ( const QModelIndex & index, int role = Qt::Displa case Qt::DisplayRole: if ( index.column() == 0 ) return QVariant ( QString ( m_projectM.getPresetName ( index.row() ).c_str() ) ); + else if (index.column() == 1) + return ratingToIcon ( m_projectM.getPresetRating(index.row(), HARD_CUT_RATING_TYPE) ); else - return ratingToIcon ( m_projectM.getPresetRating(index.row()) ); + return ratingToIcon ( m_projectM.getPresetRating(index.row(), SOFT_CUT_RATING_TYPE) ); case Qt::ToolTipRole: if ( index.column() == 0 ) return QVariant ( QString ( m_projectM.getPresetName ( index.row() ).c_str() ) ); else if (index.column() == 1) - return QString ( getSillyRatingToolTip(m_projectM.getPresetRating(index.row()))); - else return getBreedabilityToolTip(m_projectM.getPresetBreedability(index.row())); + return QString ( getSillyRatingToolTip(m_projectM.getPresetRating(index.row(), HARD_CUT_RATING_TYPE))); + else return getBreedabilityToolTip(m_projectM.getPresetRating(index.row(), SOFT_CUT_RATING_TYPE)); case Qt::DecorationRole: if ( index.column() == 1 ) - return ratingToIcon ( m_projectM.getPresetRating(index.row()) ); + return ratingToIcon ( m_projectM.getPresetRating(index.row(), HARD_CUT_RATING_TYPE) ); else if (index.column() == 2) - return breedabilityToIcon ( m_projectM.getPresetBreedability(index.row()) ); + return breedabilityToIcon ( m_projectM.getPresetRating(index.row(), SOFT_CUT_RATING_TYPE) ); else return QVariant(); case QPlaylistModel::RatingRole: - return QVariant ( m_projectM.getPresetRating(index.row()) ); + return QVariant ( m_projectM.getPresetRating(index.row(), HARD_CUT_RATING_TYPE) ); case QPlaylistModel::BreedabilityRole: - return QVariant ( m_projectM.getPresetBreedability(index.row()) ); + return QVariant ( m_projectM.getPresetRating(index.row(), SOFT_CUT_RATING_TYPE) ); case Qt::BackgroundRole: if (!m_projectM.selectedPresetIndex(pos)) @@ -294,10 +300,15 @@ QVariant QPlaylistModel::headerData ( int section, Qt::Orientation orientation, return QAbstractTableModel::headerData ( section, orientation, role ); if ( ( section == 0 ) && ( role == Qt::DisplayRole ) ) return QString ( tr ( "Preset" ) ); - if ( ( section == 1 ) && ( role == Qt::DisplayRole ) ) - return QString ( tr ( "Rating" ) ); + + /// @bug hack. this should be formalized like it is in libprojectM. + if ( ( section == 1 ) && ( role == Qt::DisplayRole )) + if (columnCount() == 2) + return QString ( tr ( "Rating" ) ); + else + return QString ( tr ( "Hard Rating" ) ); if ( ( section == 2 ) && ( role == Qt::DisplayRole ) ) - return QString ( tr ( "Breediness" ) ); + return QString ( tr ( "Soft Rating" ) ); return QAbstractTableModel::headerData ( section, orientation, role ); } @@ -312,21 +323,29 @@ int QPlaylistModel::columnCount ( const QModelIndex & parent ) const { if ( rowCount() > 0 ) - return 3; + return softCutRatingsEnabled() ? 3 : 2; else return 0; } void QPlaylistModel::appendRow ( const QString & presetURL, const QString & presetName, int rating, int breedability ) { + RatingList ratings; + ratings.push_back(rating); + ratings.push_back(breedability); + beginInsertRows ( QModelIndex(), rowCount(), rowCount() ); - m_projectM.addPresetURL ( presetURL.toStdString(), presetName.toStdString(), rating, breedability ); + m_projectM.addPresetURL ( presetURL.toStdString(), presetName.toStdString(), ratings); endInsertRows(); } void QPlaylistModel::insertRow (int index, const QString & presetURL, const QString & presetName, int rating, int breedability) { + RatingList ratings; + ratings.push_back(rating); + ratings.push_back(breedability); + beginInsertRows ( QModelIndex(), index, index); - m_projectM.insertPresetURL (index, presetURL.toStdString(), presetName.toStdString(), rating, breedability ); + m_projectM.insertPresetURL (index, presetURL.toStdString(), presetName.toStdString(), ratings); endInsertRows(); } @@ -390,7 +409,7 @@ bool QPlaylistModel::readPlaylist ( const QString & file ) foreach (QFileInfo info, QDir(file).entryInfoList()) { if (info.fileName().toLower().endsWith(".prjm") || info.fileName().toLower().endsWith(".milk") || info.fileName().toLower().endsWith(".so")) - appendRow(info.absoluteFilePath(), info.fileName(), 3); + appendRow(info.absoluteFilePath(), info.fileName(), 3,3); } return true; } diff --git a/src/projectM-qt/qplaylistmodel.hpp b/src/projectM-qt/qplaylistmodel.hpp index 8d50d7fa8..f518b2eef 100644 --- a/src/projectM-qt/qplaylistmodel.hpp +++ b/src/projectM-qt/qplaylistmodel.hpp @@ -47,8 +47,8 @@ static const int BreedabilityRole = Qt::UserRole+3; ~QPlaylistModel() { } bool setData(const QModelIndex & index, const QVariant & value, int role=Qt::EditRole); -void appendRow (const QString & presetURL, const QString & presetName, int rating = 3, int breedability=3); -void insertRow (int index, const QString & presetURL, const QString & presetName, int rating = 3, int breedability=3); +void appendRow (const QString & presetURL, const QString & presetName, int rating, int breedability); +void insertRow (int index, const QString & presetURL, const QString & presetName, int rating, int breedability); bool removeRow (int index, const QModelIndex & parent = QModelIndex()); bool removeRows ( int row, int count, const QModelIndex & parent = QModelIndex()); @@ -102,5 +102,8 @@ public slots: projectM & m_projectM; QString m_playlistName; QString m_playlistDesc; + +private: +bool softCutRatingsEnabled() const; }; #endif diff --git a/src/projectM-qt/qprojectm_mainwindow.cpp b/src/projectM-qt/qprojectm_mainwindow.cpp index e574c2fe1..8c0ac6d60 100644 --- a/src/projectM-qt/qprojectm_mainwindow.cpp +++ b/src/projectM-qt/qprojectm_mainwindow.cpp @@ -58,6 +58,7 @@ class PlaylistWriteFunctor { url = data.url; rating = data.rating; name = data.name; + breedability = data.breedability; m_pos++; return true; @@ -609,8 +610,16 @@ void QProjectM_MainWindow::refreshHeaders(QResizeEvent * event) { hHeader->setResizeMode ( 0, QHeaderView::Fixed); hHeader->setResizeMode ( 1, QHeaderView::ResizeToContents); - hHeader->setResizeMode ( 2, QHeaderView::ResizeToContents); - hHeader->resizeSection(0, ui->tableView->size().width()-20-hHeader->sectionSize(1)-hHeader->sectionSize(2)); + + const int numRatings = qprojectM()->settings().softCutRatingsEnabled ? 2 : 1; + + int sizeTotal = 0; + for (int i = 0; i < numRatings; i++) { + // Add 1 to skip the Name column + hHeader->setResizeMode (i+1, QHeaderView::ResizeToContents); + sizeTotal += hHeader->sectionSize(i+1); + } + hHeader->resizeSection(0, ui->tableView->size().width()-20-sizeTotal); @@ -685,7 +694,7 @@ void QProjectM_MainWindow::addPresetsDialog(const QModelIndex & index) else row = index.row()-1; } - loadFile ( *pos, 3, row); + loadFile ( *pos, 3, 3, row); i++; } } @@ -859,10 +868,10 @@ void QProjectM_MainWindow::copyPlaylist() QPlaylistModel::URLInfoRole ).toString(); const QString & name = playlistModel->data ( index, Qt::DisplayRole ).toString(); int rating = playlistModel->data ( index, QPlaylistModel::RatingRole ).toInt(); - + int breed = playlistModel->data ( index, QPlaylistModel::BreedabilityRole).toInt(); items->push_back (playlistItemCounter ); playlistItemMetaDataHash[playlistItemCounter] = - PlaylistItemMetaData ( url, name, rating, playlistItemCounter ); + PlaylistItemMetaData ( url, name, rating, breed, playlistItemCounter ); playlistItemCounter++; @@ -948,7 +957,7 @@ void QProjectM_MainWindow::insertPlaylistItem items->insert(insertIndex, data.id); } - playlistModel->insertRow(targetIndex, data.url, data.name, data.rating); + playlistModel->insertRow(targetIndex, data.url, data.name, data.rating, data.breedability); qprojectMWidget()->releasePresetLock(); } @@ -1111,7 +1120,7 @@ void QProjectM_MainWindow::writeSettings() } -void QProjectM_MainWindow::loadFile ( const QString &fileName, int rating, const Nullable & row) +void QProjectM_MainWindow::loadFile ( const QString &fileName, int rating, int breed, const Nullable & row) { const QString & name = strippedName ( fileName ); @@ -1123,7 +1132,7 @@ void QProjectM_MainWindow::loadFile ( const QString &fileName, int rating, const ui->presetSavePushButton->setEnabled(true); playlistItemMetaDataHash[playlistItemCounter] = - PlaylistItemMetaData ( fileName, name, rating, playlistItemCounter) ; + PlaylistItemMetaData ( fileName, name, rating, breed, playlistItemCounter) ; if (row.hasValue()) @@ -1177,7 +1186,7 @@ void QProjectM_MainWindow::updateFilteredPlaylist ( const QString & text ) { const PlaylistItemMetaData & data = playlistItemMetaDataHash[*pos]; - playlistModel->appendRow ( data.url, data.name, data.rating); + playlistModel->appendRow ( data.url, data.name, data.rating, data.breedability); if (activePresetId.hasValue() && data.id == activePresetId.value()) { qprojectM()->selectPresetPosition(playlistModel->rowCount()-1); @@ -1197,7 +1206,7 @@ void QProjectM_MainWindow::updateFilteredPlaylist ( const QString & text ) if ( ( data.name ).contains ( filter, Qt::CaseInsensitive ) ) { - playlistModel->appendRow ( data.url, data.name, data.rating); + playlistModel->appendRow ( data.url, data.name, data.rating, data.breedability); if (activePresetId.hasValue() && data.id == activePresetId.value()) { qprojectM()->selectPresetPosition(playlistModel->rowCount()-1); presetExistsWithinFilter = true; diff --git a/src/projectM-qt/qprojectm_mainwindow.hpp b/src/projectM-qt/qprojectm_mainwindow.hpp index 8543a5325..a2a45b278 100644 --- a/src/projectM-qt/qprojectm_mainwindow.hpp +++ b/src/projectM-qt/qprojectm_mainwindow.hpp @@ -68,8 +68,8 @@ class QProjectM_MainWindow:public QMainWindow typedef struct PlaylistItemMetaData { PlaylistItemMetaData() {} - PlaylistItemMetaData(const QString & _url, const QString & _name, int _rating, long _id): - url(_url), name(_name), rating(_rating), id(_id) {} + PlaylistItemMetaData(const QString & _url, const QString & _name, int _rating, int _breed, long _id): + url(_url), name(_name), rating(_rating), breedability(_breed), id(_id) {} QString url; QString name; @@ -184,7 +184,7 @@ void presetSoftCut(); void createStatusBar(); void readSettings(); void writeSettings(); - void loadFile(const QString &fileName, int rating ,const Nullable & row); + void loadFile(const QString &fileName, int rating , int breed, const Nullable & row); QString strippedName(const QString &fullFileName); QProjectMWidget * m_QProjectMWidget; diff --git a/src/projectM-qt/qprojectmconfigdialog.cpp b/src/projectM-qt/qprojectmconfigdialog.cpp index 2c3fded4d..e5cb453ec 100644 --- a/src/projectM-qt/qprojectmconfigdialog.cpp +++ b/src/projectM-qt/qprojectmconfigdialog.cpp @@ -141,6 +141,8 @@ void QProjectMConfigDialog::saveConfig() { settings.beatSensitivity = _ui.beatSensitivitySpinBox->value(); settings.easterEgg = _ui.easterEggParameterSpinBox->value(); settings.shuffleEnabled = _ui.shuffleOnStartupCheckBox->checkState() == Qt::Checked; + settings.softCutRatingsEnabled = _ui.softCutRatingsEnabledCheckBox->checkState() == Qt::Checked; + projectM::writeConfig(_configFile, settings); QSettings qSettings("projectM", "qprojectM"); @@ -187,7 +189,7 @@ void QProjectMConfigDialog::loadConfig() { _ui.smoothPresetDurationSpinBox->setValue(settings.smoothPresetDuration); _ui.presetDurationSpinBox->setValue(settings.presetDuration); _ui.easterEggParameterSpinBox->setValue(settings.easterEgg); - + _ui.softCutRatingsEnabledCheckBox->setCheckState(settings.softCutRatingsEnabled ? Qt::Checked : Qt::Unchecked); QSettings qSettings("projectM", "qprojectM"); _ui.fullscreenOnStartupCheckBox->setCheckState(qSettings.value("FullscreenOnStartup", false).toBool() ? Qt::Checked : Qt::Unchecked); diff --git a/src/projectM-qt/qprojectmconfigdialog.ui b/src/projectM-qt/qprojectmconfigdialog.ui index aaf8d5a15..b77dd678f 100644 --- a/src/projectM-qt/qprojectmconfigdialog.ui +++ b/src/projectM-qt/qprojectmconfigdialog.ui @@ -6,8 +6,8 @@ 0 0 - 676 - 372 + 683 + 409 @@ -19,7 +19,7 @@ 8 8 662 - 364 + 385 @@ -419,6 +419,22 @@ p, li { white-space: pre-wrap; } + + + + + 0 + 0 + + + + Enable to turn on a different rating system for soft cuts and hard cuts. + + + Soft Cut Ratings + + +