diff --git a/src/actions.cpp b/src/actions.cpp index 235e90ed..8c437f8c 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -881,7 +881,7 @@ void Delete::Run() for (std::vector::reverse_iterator it = list.rbegin(); it != list.rend(); ++it) { Mpd.Delete(playlist, *it); - myPlaylistEditor->Content->DeleteOption(*it); + myPlaylistEditor->Content->DeleteItem(*it); } Mpd.CommitCommandsList(); ShowMessage("Selected items deleted from playlist \"%s\"", myPlaylistEditor->Playlists->Current().c_str()); @@ -889,7 +889,7 @@ void Delete::Run() else { if (Mpd.Delete(myPlaylistEditor->Playlists->Current(), myPlaylistEditor->Content->Choice())) - myPlaylistEditor->Content->DeleteOption(myPlaylistEditor->Content->Choice()); + myPlaylistEditor->Content->DeleteItem(myPlaylistEditor->Content->Choice()); } } } @@ -2203,7 +2203,7 @@ void ToggleBrowserSortMode::Run() ShowMessage("Sort songs by: Name"); break; } - myBrowser->Main()->Sort(myBrowser->CurrentDir() != "/"); + std::sort(myBrowser->Main()->Begin()+(myBrowser->CurrentDir() != "/"), myBrowser->Main()->End(), CaseInsensitiveSorting()); } bool ToggleLibraryTagType::canBeRun() const diff --git a/src/browser.cpp b/src/browser.cpp index 792644a9..aded1969 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -369,7 +369,7 @@ void Browser::GetDirectory(std::string dir, std::string subdir) MPD::Item parent; parent.name = ".."; parent.type = itDirectory; - w->AddOption(parent); + w->AddItem(parent); } MPD::ItemList list; @@ -397,7 +397,7 @@ void Browser::GetDirectory(std::string dir, std::string subdir) case itPlaylist: { utf_to_locale(it->name); - w->AddOption(*it); + w->AddItem(*it); break; } case itDirectory: @@ -405,7 +405,7 @@ void Browser::GetDirectory(std::string dir, std::string subdir) utf_to_locale(it->name); if (it->name == subdir) highlightme = w->Size(); - w->AddOption(*it); + w->AddItem(*it); break; } case itSong: @@ -419,7 +419,7 @@ void Browser::GetDirectory(std::string dir, std::string subdir) break; } } - w->AddOption(*it, bold); + w->AddItem(*it, bold); break; } } diff --git a/src/media_library.cpp b/src/media_library.cpp index c36830fd..bf900204 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -207,7 +207,7 @@ void MediaLibrary::Update() if (it->empty() && !Config.media_library_display_empty_tag) continue; utf_to_locale(*it); - Artists->AddOption(*it); + Artists->AddItem(*it); } Artists->Window::Clear(); Artists->Refresh(); @@ -237,22 +237,22 @@ void MediaLibrary::Update() utf_to_locale(*album); Mpd.CommitSearchTags([this, &album](std::string &&date) { utf_to_locale(date); - Albums->AddOption(SearchConstraints(*album, date)); + Albums->AddItem(SearchConstraints(*album, date)); }); } else { utf_to_locale(*album); - Albums->AddOption(SearchConstraints(*album, "")); + Albums->AddItem(SearchConstraints(*album, "")); } } utf_to_locale(Artists->Current()); if (!Albums->Empty()) - Albums->Sort(); + std::sort(Albums->Begin(), Albums->End(), SearchConstraintsSorting()); if (Albums->Size() > 1) { Albums->AddSeparator(); - Albums->AddOption(SearchConstraints("", AllTracksMarker)); + Albums->AddItem(SearchConstraints("", AllTracksMarker)); } Albums->Refresh(); Mpd.BlockIdle(0); @@ -286,27 +286,27 @@ void MediaLibrary::Update() utf_to_locale(*album); Mpd.CommitSearchTags([this, &artist, &album](std::string &&tag) { utf_to_locale(tag); - Albums->AddOption(SearchConstraints(*artist, *album, tag)); + Albums->AddItem(SearchConstraints(*artist, *album, tag)); }); } else { utf_to_locale(*artist); utf_to_locale(*album); - Albums->AddOption(SearchConstraints(*artist, *album, *artist)); + Albums->AddItem(SearchConstraints(*artist, *album, *artist)); } } else { utf_to_locale(*artist); utf_to_locale(*album); - Albums->AddOption(SearchConstraints(*artist, *album, "")); + Albums->AddItem(SearchConstraints(*artist, *album, "")); } } } Mpd.BlockIdle(0); if (!Albums->Empty()) - Albums->Sort(); + std::sort(Albums->Begin(), Albums->End(), SearchConstraintsSorting()); Albums->Refresh(); } @@ -320,7 +320,6 @@ void MediaLibrary::Update() if (!(hasTwoColumns ? Albums->Empty() : Artists->Empty()) && Songs->ReallyEmpty()) { Songs->Reset(); - MPD::SongList list; Mpd.StartSearch(1); Mpd.AddSearch(Config.media_lib_primary_tag, locale_to_utf_cpy(hasTwoColumns ? Albums->Current().PrimaryTag : Artists->Current())); @@ -330,17 +329,15 @@ void MediaLibrary::Update() if (Config.media_library_display_date) Mpd.AddSearch(MPD_TAG_DATE, locale_to_utf_cpy(Albums->Current().Date)); } - Mpd.CommitSearchSongs([&list](MPD::Song &&s) { - list.push_back(s); + Mpd.CommitSearchSongs([this](MPD::Song &&s) { + Songs->AddItem(s, myPlaylist->checkForSong(s)); }); if (Albums->Current().Date == AllTracksMarker) - std::sort(list.begin(), list.end(), SortAllTracks); + std::sort(Songs->Begin(), Songs->End(), SortAllTracks); else - std::sort(list.begin(), list.end(), SortSongsByTrack); + std::sort(Songs->Begin(), Songs->End(), SortSongsByTrack); - for (auto it = list.begin(); it != list.end(); ++it) - Songs->AddOption(*it, myPlaylist->checkForSong(*it)); Songs->Window::Clear(); Songs->Refresh(); } diff --git a/src/menu.cpp b/src/menu.cpp index 59d39613..c50ada64 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -22,15 +22,15 @@ using namespace NCurses; -template <> std::string Menu::GetOption(size_t pos) +template <> std::string Menu::GetItem(size_t pos) { std::string result; if (m_options_ptr->at(pos)) { if (m_get_string_helper) - result = m_get_string_helper((*m_options_ptr)[pos]->Item); + result = m_get_string_helper((*m_options_ptr)[pos]->Value); else - result = (*m_options_ptr)[pos]->Item; + result = (*m_options_ptr)[pos]->Value; } return result; } diff --git a/src/menu.h b/src/menu.h index 385a463c..e3776160 100644 --- a/src/menu.h +++ b/src/menu.h @@ -22,8 +22,8 @@ #define _MENU_H #include -#include #include +#include #include #include "error.h" @@ -102,7 +102,7 @@ namespace NCurses /// This template class is generic menu capable of /// holding any std::vector compatible values. /// - template class Menu : public Window, public List + template struct Menu : public Window, public List { /// Function helper prototype used to display each option on the screen. /// If not set by setItemDisplayer(), menu won't display anything. @@ -119,36 +119,94 @@ namespace NCurses /// Struct that holds each item in the list and its attributes /// - struct Option + struct Item { - Option() : isBold(0), isSelected(0), isStatic(0) { } - Option(const T &t, bool is_bold, bool is_static) : - Item(t), isBold(is_bold), isSelected(0), isStatic(is_static) { } + Item() : isBold(0), isSelected(0), isStatic(0) { } + Item(const T &t, bool is_bold, bool is_static) : + Value(t), isBold(is_bold), isSelected(0), isStatic(is_static) { } - T Item; + T Value; bool isBold; bool isSelected; bool isStatic; }; - /// Functor that wraps around the functor passed to Sort() - /// to fit to internal container structure - /// - template class InternalSorting + template class ItemIterator + : public std::iterator { - Comparison cmp; + friend class Menu; - public: - bool operator()(Option *a, Option *b) - { - return cmp(a->Item, b->Item); - } + BaseIterator m_it; + explicit ItemIterator(BaseIterator it) : m_it(it) { } + + static const bool referenceValue = !std::is_same< + ValueT, typename std::remove_pointer< + typename BaseIterator::value_type + >::type + >::value; + template struct getObject { }; + template struct getObject { + static Result &apply(BaseIterator it) { return (*it)->Value; } + }; + template struct getObject { + static Result &apply(BaseIterator it) { return **it; } + }; + + public: + ItemIterator() { } + + ValueT &operator*() const { return getObject::apply(m_it); } + typename BaseIterator::value_type operator->() { return *m_it; } + + ItemIterator &operator++() { ++m_it; return *this; } + ItemIterator operator++(int) { return ItemIterator(m_it++); } + + ItemIterator &operator--() { --m_it; return *this; } + ItemIterator operator--(int) { return ItemIterator(m_it--); } + + ValueT &operator[](ptrdiff_t n) const { + return getObject::apply(&m_it[n]); + } + + ItemIterator &operator+=(ptrdiff_t n) { m_it += n; return *this; } + ItemIterator operator+(ptrdiff_t n) const { return ItemIterator(m_it + n); } + + ItemIterator &operator-=(ptrdiff_t n) { m_it -= n; return *this; } + ItemIterator operator-(ptrdiff_t n) const { return ItemIterator(m_it - n); } + + ptrdiff_t operator-(const ItemIterator &rhs) const { return m_it - rhs.m_it; } + + template + bool operator==(const Iterator &rhs) const { return m_it == rhs.m_it; } + template + bool operator!=(const Iterator &rhs) const { return m_it != rhs.m_it; } + template + bool operator<(const Iterator &rhs) const { return m_it < rhs.m_it; } + template + bool operator<=(const Iterator &rhs) const { return m_it <= rhs.m_it; } + template + bool operator>(const Iterator &rhs) const { return m_it > rhs.m_it; } + template + bool operator>=(const Iterator &rhs) const { return m_it >= rhs.m_it; } + + /// non-const to const conversion + template operator ItemIterator< + typename std::add_const::type, Iterator + >() { return ItemIterator(m_it); } + + const BaseIterator &base() { return m_it; } }; - typedef typename std::vector