diff --git a/src/actions.cpp b/src/actions.cpp index 0cf98fbb..235e90ed 100644 --- a/src/actions.cpp +++ b/src/actions.cpp @@ -1161,15 +1161,15 @@ void ToggleDisplayMode::Run() if (Config.columns_in_playlist) { - myPlaylist->Items->setItemDisplayer(Display::SongsInColumns); + myPlaylist->Items->setItemDisplayer(std::bind(Display::SongsInColumns, _1, _2, *myPlaylist)); myPlaylist->Items->SetTitle(Config.titles_visibility ? Display::Columns(myPlaylist->Items->GetWidth()) : ""); - myPlaylist->Items->SetGetStringFunction(Playlist::SongInColumnsToString); + myPlaylist->Items->SetItemStringifier(Playlist::SongInColumnsToString); } else { - myPlaylist->Items->setItemDisplayer(Display::Songs); + myPlaylist->Items->setItemDisplayer(std::bind(Display::Songs, _1, _2, *myPlaylist, Config.song_list_format)); myPlaylist->Items->SetTitle(""); - myPlaylist->Items->SetGetStringFunction(Playlist::SongToString); + myPlaylist->Items->SetItemStringifier(Playlist::SongToString); } } else if (myScreen == myBrowser) @@ -1191,13 +1191,13 @@ void ToggleDisplayMode::Run() ShowMessage("Playlist editor display mode: %s", Config.columns_in_playlist_editor ? "Columns" : "Classic"); if (Config.columns_in_playlist_editor) { - myPlaylistEditor->Content->setItemDisplayer(Display::SongsInColumns); - myPlaylistEditor->Content->SetGetStringFunction(Playlist::SongInColumnsToString); + myPlaylistEditor->Content->setItemDisplayer(std::bind(Display::SongsInColumns, _1, _2, *myPlaylistEditor)); + myPlaylistEditor->Content->SetItemStringifier(Playlist::SongInColumnsToString); } else { - myPlaylistEditor->Content->setItemDisplayer(Display::Songs); - myPlaylistEditor->Content->SetGetStringFunction(Playlist::SongToString); + myPlaylistEditor->Content->setItemDisplayer(std::bind(Display::Songs, _1, _2, *myPlaylistEditor, Config.song_list_format)); + myPlaylistEditor->Content->SetItemStringifier(Playlist::SongToString); } } } diff --git a/src/browser.cpp b/src/browser.cpp index 00b02a06..792644a9 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -52,17 +52,14 @@ std::set Browser::SupportedExtensions; void Browser::Init() { - static Display::ScreenFormat sf = { this, &Config.song_list_format }; - w = new Menu(0, MainStartY, COLS, MainHeight, Config.columns_in_browser && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, brNone); w->HighlightColor(Config.main_highlight_color); w->CyclicScrolling(Config.use_cyclic_scrolling); w->CenteredCursor(Config.centered_cursor); w->SetSelectPrefix(&Config.selected_item_prefix); w->SetSelectSuffix(&Config.selected_item_suffix); - w->setItemDisplayer(Display::Items); - w->setItemDisplayerData(&sf); - w->SetGetStringFunction(ItemToString); + w->setItemDisplayer(std::bind(Display::Items, _1, _2)); + w->SetItemStringifier(ItemToString); if (SupportedExtensions.empty()) Mpd.GetSupportedExtensions(SupportedExtensions); @@ -576,29 +573,22 @@ void Browser::UpdateItemList() w->Refresh(); } -std::string Browser::ItemToString(const MPD::Item &item, void *) +std::string Browser::ItemToString(const MPD::Item &item) { + std::string result; switch (item.type) { case MPD::itDirectory: - { - return "[" + getBasename(item.name) + "]"; - } + result = "[" + getBasename(item.name) + "]"; + break; case MPD::itSong: - { if (!Config.columns_in_browser) - return item.song->toString(Config.song_list_format_dollar_free); + result = item.song->toString(Config.song_list_format_dollar_free); else - return Playlist::SongInColumnsToString(*item.song, 0); - } + result = Playlist::SongInColumnsToString(*item.song); case MPD::itPlaylist: - { - return Config.browser_playlist_prefix.Str() + getBasename(item.name); - } - default: - { - return ""; - } + result = Config.browser_playlist_prefix.Str() + getBasename(item.name); } + return result; } diff --git a/src/browser.h b/src/browser.h index 5fe0b90e..fcc6e946 100644 --- a/src/browser.h +++ b/src/browser.h @@ -73,7 +73,7 @@ class Browser : public Screen< Menu > private: static bool hasSupportedExtension(const std::string &); - static std::string ItemToString(const MPD::Item &, void *); + static std::string ItemToString(const MPD::Item &item); static std::set SupportedExtensions; diff --git a/src/display.cpp b/src/display.cpp index 57db5fc8..4eeb5063 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -20,11 +20,13 @@ #include +#include "browser.h" #include "display.h" #include "helpers.h" #include "song_info.h" #include "playlist.h" #include "global.h" +#include "tag_editor.h" #include "utility/type_conversions.h" using Global::myScreen; @@ -138,44 +140,43 @@ std::string Display::Columns(size_t list_width) return result; } -void Display::SongsInColumns(const MPD::Song &s, void *data, Menu *menu) +void Display::SongsInColumns(Menu &menu, const MPD::Song &s, BasicScreen &screen) { if (Config.columns.empty()) return; - assert(data); bool separate_albums = false; - if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size()) + if (Config.playlist_separate_albums && menu.CurrentlyDrawedPosition()+1 < menu.Size()) { - MPD::Song *next = static_cast(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1); + MPD::Song *next = screen.GetSong(menu.CurrentlyDrawedPosition()+1); if (next && next->getAlbum() != s.getAlbum()) separate_albums = true; } if (separate_albums) - *menu << fmtUnderline; + menu << fmtUnderline; - int song_pos = menu->isFiltered() ? s.getPosition() : menu->CurrentlyDrawedPosition(); - bool is_now_playing = menu == myPlaylist->Items && song_pos == myPlaylist->NowPlaying; - bool is_selected = menu->isSelected(menu->CurrentlyDrawedPosition()); + int song_pos = menu.isFiltered() ? s.getPosition() : menu.CurrentlyDrawedPosition(); + bool is_now_playing = &menu == myPlaylist->Items && song_pos == myPlaylist->NowPlaying; + bool is_selected = menu.isSelected(menu.CurrentlyDrawedPosition()); bool discard_colors = Config.discard_colors_if_item_is_selected && is_selected; if (is_now_playing) - *menu << Config.now_playing_prefix; + menu << Config.now_playing_prefix; int width; - int y = menu->Y(); - int remained_width = menu->GetWidth(); + int y = menu.Y(); + int remained_width = menu.GetWidth(); std::vector::const_iterator it, last = Config.columns.end() - 1; for (it = Config.columns.begin(); it != Config.columns.end(); ++it) { // check current X coordinate - int x = menu->X(); + int x = menu.X(); // column has relative width and all after it have fixed width, // so stretch it so it fills whole screen along with these after. if (it->stretch_limit >= 0) // (*) width = remained_width - it->stretch_limit; else - width = it->fixed ? it->width : it->width * menu->GetWidth() * 0.01; + width = it->fixed ? it->width : it->width * menu.GetWidth() * 0.01; // columns with relative width may shrink to 0, omit them if (width == 0) continue; @@ -200,8 +201,8 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu *me if (width-offset < 0) { remained_width -= width + 1; - menu->GotoXY(width, y); - *menu << ' '; + menu.GotoXY(width, y); + menu << ' '; continue; } width -= offset; @@ -225,7 +226,7 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu *me Window::Cut(tag, width); if (!discard_colors && it->color != clDefault) - *menu << it->color; + menu << it->color; int x_off = 0; // if column uses right alignment, calculate proper offset. @@ -233,19 +234,19 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu *me if (it->right_alignment) x_off = std::max(0, width - int(Window::Length(tag))); - whline(menu->Raw(), KEY_SPACE, width); - menu->GotoXY(x + x_off, y); - *menu << tag; - menu->GotoXY(x + width, y); + whline(menu.Raw(), KEY_SPACE, width); + menu.GotoXY(x + x_off, y); + menu << tag; + menu.GotoXY(x + width, y); if (it != last) { // add missing width's part and restore the value. - *menu << ' '; + menu << ' '; remained_width -= width+1; } if (!discard_colors && it->color != clDefault) - *menu << clEnd; + menu << clEnd; } // here comes the shitty part, second chapter. here we apply @@ -254,55 +255,54 @@ void Display::SongsInColumns(const MPD::Song &s, void *data, Menu *me // returns there). if (is_now_playing) { - int np_x = menu->GetWidth() - Config.now_playing_suffix_length; + int np_x = menu.GetWidth() - Config.now_playing_suffix_length; if (is_selected) np_x -= Config.selected_item_suffix_length; - menu->GotoXY(np_x, y); - *menu << Config.now_playing_suffix; + menu.GotoXY(np_x, y); + menu << Config.now_playing_suffix; } if (is_selected) - menu->GotoXY(menu->GetWidth() - Config.selected_item_suffix_length, y); + menu.GotoXY(menu.GetWidth() - Config.selected_item_suffix_length, y); if (separate_albums) - *menu << fmtUnderlineEnd; + menu << fmtUnderlineEnd; } -void Display::Songs(const MPD::Song &s, void *data, Menu *menu) +void Display::Songs(Menu &menu, const MPD::Song &s, BasicScreen &screen, const std::string &format) { - bool is_now_playing = menu == myPlaylist->Items && (menu->isFiltered() ? s.getPosition() : menu->CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying); + bool is_now_playing = &menu == myPlaylist->Items && (menu.isFiltered() ? s.getPosition() : menu.CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying); if (is_now_playing) - *menu << Config.now_playing_prefix; + menu << Config.now_playing_prefix; - assert(data); bool separate_albums = false; - if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size()) + if (Config.playlist_separate_albums && menu.CurrentlyDrawedPosition()+1 < menu.Size()) { - MPD::Song *next = static_cast(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1); + MPD::Song *next = screen.GetSong(menu.CurrentlyDrawedPosition()+1); if (next && next->getAlbum() != s.getAlbum()) separate_albums = true; } if (separate_albums) { - *menu << fmtUnderline; - mvwhline(menu->Raw(), menu->Y(), 0, ' ', menu->GetWidth()); + menu << fmtUnderline; + mvwhline(menu.Raw(), menu.Y(), 0, ' ', menu.GetWidth()); } - bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition()); + bool discard_colors = Config.discard_colors_if_item_is_selected && menu.isSelected(menu.CurrentlyDrawedPosition()); - std::string line = s.toString(*static_cast(data)->format, "$"); + std::string line = s.toString(format, "$"); for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) { if (*it == '$') { if (++it == line.end()) // end of format { - *menu << '$'; + menu << '$'; break; } else if (isdigit(*it)) // color { if (!discard_colors) - *menu << Color(*it-'0'); + menu << Color(*it-'0'); } else if (*it == 'R') // right align { @@ -313,83 +313,83 @@ void Display::Songs(const MPD::Song &s, void *data, Menu *menu) buf.RemoveFormatting(); if (is_now_playing) buf << Config.now_playing_suffix; - *menu << XY(menu->GetWidth()-buf.Str().length()-(menu->isSelected(menu->CurrentlyDrawedPosition()) ? Config.selected_item_suffix_length : 0), menu->Y()) << buf; + menu << XY(menu.GetWidth()-buf.Str().length()-(menu.isSelected(menu.CurrentlyDrawedPosition()) ? Config.selected_item_suffix_length : 0), menu.Y()) << buf; if (separate_albums) - *menu << fmtUnderlineEnd; + menu << fmtUnderlineEnd; return; } else // not a color nor right align, just a random character - *menu << *--it; + menu << *--it; } else if (*it == MPD::Song::FormatEscapeCharacter) { // treat '$' as a normal character if song format escape char is prepended to it if (++it == line.end() || *it != '$') --it; - *menu << *it; + menu << *it; } else - *menu << *it; + menu << *it; } if (is_now_playing) - *menu << Config.now_playing_suffix; + menu << Config.now_playing_suffix; if (separate_albums) - *menu << fmtUnderlineEnd; + menu << fmtUnderlineEnd; } -void Display::Tags(const MPD::MutableSong &s, void *data, Menu *menu) +void Display::Tags(Menu &menu, const MPD::MutableSong &s) { - size_t i = static_cast *>(data)->Choice(); + size_t i = myTagEditor->TagTypes->Choice(); if (i < 11) { - ShowTag(*menu, s.getTags(SongInfo::Tags[i].Get)); + ShowTag(menu, s.getTags(SongInfo::Tags[i].Get)); } else if (i == 12) { if (s.getNewURI().empty()) - *menu << s.getName(); + menu << s.getName(); else - *menu << s.getName() << Config.color2 << " -> " << clEnd << s.getNewURI(); + menu << s.getName() << Config.color2 << " -> " << clEnd << s.getNewURI(); } } -void Display::Outputs(const MPD::Output &o, void * , Menu< MPD::Output > *menu) +void Display::Outputs(Menu< MPD::Output > &menu, const MPD::Output &o) { - *menu << o.name(); + menu << o.name(); } -void Display::Items(const MPD::Item &item, void *data, Menu *menu) +void Display::Items(Menu &menu, const MPD::Item &item) { switch (item.type) { case MPD::itDirectory: { - *menu << "[" << getBasename(item.name) << "]"; + menu << "[" << getBasename(item.name) << "]"; return; } case MPD::itSong: if (!Config.columns_in_browser) - Display::Songs(*item.song, data, reinterpret_cast *>(menu)); + Display::Songs(reinterpret_cast &>(menu), *item.song, *myBrowser, Config.song_list_format); else - Display::SongsInColumns(*item.song, data, reinterpret_cast *>(menu)); + Display::SongsInColumns(reinterpret_cast &>(menu), *item.song, *myBrowser); return; case MPD::itPlaylist: - *menu << Config.browser_playlist_prefix << getBasename(item.name); + menu << Config.browser_playlist_prefix << getBasename(item.name); return; default: return; } } -void Display::SearchEngine(const SEItem &ei, void *data, Menu *menu) +void Display::SearchEngine(Menu &menu, const SEItem &ei) { if (ei.isSong()) { if (!Config.columns_in_search_engine) - Display::Songs(ei.song(), data, reinterpret_cast *>(menu)); + Display::Songs(reinterpret_cast &>(menu), ei.song(), *mySearcher, Config.song_list_format); else - Display::SongsInColumns(ei.song(), data, reinterpret_cast *>(menu)); + Display::SongsInColumns(reinterpret_cast &>(menu), ei.song(), *mySearcher); } else - *menu << ei.buffer(); + menu << ei.buffer(); } diff --git a/src/display.h b/src/display.h index 2463bf3b..10b6b3fa 100644 --- a/src/display.h +++ b/src/display.h @@ -30,35 +30,29 @@ namespace Display { - struct ScreenFormat - { - BasicScreen *screen; - std::string *format; - }; - std::string Columns(size_t); - template void Default(const T &t, void *, Menu *menu) + template void Default(Menu &menu, const T &t) { - *menu << t; + menu << t; } - template void Pair(const std::pair &pair, void *, Menu< std::pair > *menu) + template void Pair(Menu< std::pair > &menu, const std::pair &pair) { - *menu << pair.first; + menu << pair.first; } - void SongsInColumns(const MPD::Song &, void *, Menu *); + void SongsInColumns(Menu &menu, const MPD::Song &s, BasicScreen &screen); - void Songs(const MPD::Song &, void *, Menu *); + void Songs(Menu &menu, const MPD::Song &s, BasicScreen &screen, const std::string &format); - void Tags(const MPD::MutableSong &, void *, Menu *); + void Tags(Menu &menu, const MPD::MutableSong &s); - void Outputs(const MPD::Output &, void *, Menu *); + void Outputs(Menu &menu, const MPD::Output &o); - void SearchEngine(const SEItem &, void *, Menu *); + void SearchEngine(Menu &menu, const SEItem &si); - void Items(const MPD::Item &, void *, Menu *); + void Items(Menu &menu, const MPD::Item &item); } #endif diff --git a/src/helpers.cpp b/src/helpers.cpp index 5fc8d586..6fb813aa 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -39,11 +39,6 @@ #include "outputs.h" #include "visualizer.h" -std::string StringPairToString(const std::pair &pair, void *) -{ - return pair.first; -} - void ParseArgv(int argc, char **argv) { bool quit = 0; @@ -275,6 +270,11 @@ void ParseArgv(int argc, char **argv) exit(0); } +std::string StringPairToString(const std::pair &pair) +{ + return pair.first; +} + std::string Timestamp(time_t t) { char result[32]; diff --git a/src/helpers.h b/src/helpers.h index 912a6c68..335dadc7 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -28,7 +28,7 @@ void ParseArgv(int, char **); -std::string StringPairToString(const std::pair &pair, void *); +std::string StringPairToString(const std::pair &pair); template struct StringConverter { const char *operator()(const char *s) { return s; } diff --git a/src/media_library.cpp b/src/media_library.cpp index 5fe8cae0..c36830fd 100644 --- a/src/media_library.cpp +++ b/src/media_library.cpp @@ -76,10 +76,7 @@ void MediaLibrary::Init() Albums->SetSelectPrefix(&Config.selected_item_prefix); Albums->SetSelectSuffix(&Config.selected_item_suffix); Albums->setItemDisplayer(DisplayAlbums); - Albums->SetGetStringFunction(AlbumToString); - Albums->SetGetStringFunctionUserData(this); - - static Display::ScreenFormat sf = { this, &Config.song_library_format }; + Albums->SetItemStringifier(AlbumToString); Songs = new Menu(itsRightColStartX, MainStartY, itsRightColWidth, MainHeight, Config.titles_visibility ? "Songs" : "", Config.main_color, brNone); Songs->HighlightColor(Config.main_highlight_color); @@ -87,9 +84,8 @@ void MediaLibrary::Init() Songs->CenteredCursor(Config.centered_cursor); Songs->SetSelectPrefix(&Config.selected_item_prefix); Songs->SetSelectSuffix(&Config.selected_item_suffix); - Songs->setItemDisplayer(Display::Songs); - Songs->setItemDisplayerData(&sf); - Songs->SetGetStringFunction(SongToString); + Songs->setItemDisplayer(std::bind(Display::Songs, _1, _2, *this, Config.song_library_format)); + Songs->SetItemStringifier(SongToString); w = Artists; isInitialized = 1; @@ -749,32 +745,35 @@ void MediaLibrary::AddToPlaylist(bool add_n_play) } } -std::string MediaLibrary::SongToString(const MPD::Song &s, void *) +std::string MediaLibrary::SongToString(const MPD::Song &s) { return s.toString(Config.song_library_format); } -std::string MediaLibrary::AlbumToString(const SearchConstraints &sc, void *ptr) +std::string MediaLibrary::AlbumToString(const SearchConstraints &sc) { if (sc.Date == AllTracksMarker) return "All tracks"; std::string result; - if (static_cast(ptr)->hasTwoColumns) + if (myLibrary->hasTwoColumns) (result += sc.PrimaryTag.empty() ? Config.empty_tag : sc.PrimaryTag) += " - "; - if ((!static_cast(ptr)->hasTwoColumns || Config.media_lib_primary_tag != MPD_TAG_DATE) && !sc.Date.empty()) + if ((!myLibrary || Config.media_lib_primary_tag != MPD_TAG_DATE) && !sc.Date.empty()) ((result += "(") += sc.Date) += ") "; result += sc.Album.empty() ? "" : sc.Album; return result; } -void MediaLibrary::DisplayAlbums(const SearchConstraints &sc, void *, Menu *menu) +void MediaLibrary::DisplayAlbums(Menu &menu, const SearchConstraints &sc) { - *menu << AlbumToString(sc, 0); + menu << AlbumToString(sc); } -void MediaLibrary::DisplayPrimaryTags(const std::string &tag, void *, Menu *menu) +void MediaLibrary::DisplayPrimaryTags(Menu &menu, const std::string &tag) { - *menu << (!tag.empty() ? tag : Config.empty_tag); + if (tag.empty()) + menu << Config.empty_tag; + else + menu << tag; } bool MediaLibrary::SearchConstraintsSorting::operator()(const SearchConstraints &a, const SearchConstraints &b) const diff --git a/src/media_library.h b/src/media_library.h index 6e6622ec..3eae6404 100644 --- a/src/media_library.h +++ b/src/media_library.h @@ -87,11 +87,10 @@ class MediaLibrary : public Screen private: void AddToPlaylist(bool); - static std::string SongToString(const MPD::Song &s, void *); - - static std::string AlbumToString(const SearchConstraints &, void *); - static void DisplayAlbums(const SearchConstraints &, void *, Menu *); - static void DisplayPrimaryTags(const std::string &artist, void *, Menu *menu); + static std::string SongToString(const MPD::Song &s); + static std::string AlbumToString(const SearchConstraints &); + static void DisplayAlbums(Menu &menu, const SearchConstraints &sc); + static void DisplayPrimaryTags(Menu &menu, const std::string &tag); static bool SortSongsByTrack(const MPD::Song &, const MPD::Song &); static bool SortAllTracks(const MPD::Song &, const MPD::Song &); diff --git a/src/menu.cpp b/src/menu.cpp index b0ffc1a1..59d39613 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -24,13 +24,13 @@ using namespace NCurses; template <> std::string Menu::GetOption(size_t pos) { + std::string result; if (m_options_ptr->at(pos)) { if (m_get_string_helper) - return m_get_string_helper((*m_options_ptr)[pos]->Item, m_get_string_helper_data); + result = m_get_string_helper((*m_options_ptr)[pos]->Item); else - return (*m_options_ptr)[pos]->Item; + result = (*m_options_ptr)[pos]->Item; } - else - return ""; + return result; } diff --git a/src/menu.h b/src/menu.h index ba46b99b..385a463c 100644 --- a/src/menu.h +++ b/src/menu.h @@ -23,6 +23,7 @@ #include #include +#include #include #include "error.h" @@ -107,14 +108,14 @@ namespace NCurses /// If not set by setItemDisplayer(), menu won't display anything. /// @see setItemDisplayer() /// - typedef std::function *)> ItemDisplayer; + typedef std::function &, const T &)> ItemDisplayer; /// Function helper prototype used for converting items to strings. - /// If not set by SetGetStringFunction(), searching and filtering + /// If not set by SetItemStringifier(), searching and filtering /// won't work (note that Menu doesn't need this) - /// @see SetGetStringFunction() + /// @see SetItemStringifier() /// - typedef std::function GetStringFunction; + typedef std::function ItemStringifier; /// Struct that holds each item in the list and its attributes /// @@ -175,22 +176,10 @@ namespace NCurses /// void setItemDisplayer(ItemDisplayer ptr) { m_item_displayer = ptr; } - /// Sets optional user data, that is passed to - /// ItemDisplayer function each time it's invoked - /// @param data void pointer to userdata - /// - void setItemDisplayerData(void *data) { m_item_displayer_data = data; } - /// Sets helper function that is responsible for converting items to strings - /// @param f function pointer that matches the GetStringFunction prototype + /// @param f function pointer that matches the ItemStringifier prototype /// - void SetGetStringFunction(GetStringFunction f) { m_get_string_helper = f; } - - /// Sets optional user data, that is passed to - /// GetStringFunction function each time it's invoked - /// @param data void pointer to user data - /// - void SetGetStringFunctionUserData(void *data) { m_get_string_helper_data = data; } + void SetItemStringifier(ItemStringifier f) { m_get_string_helper = f; } /// Reserves the size for internal container (this just calls std::vector::reserve()) /// @param size requested size @@ -326,7 +315,7 @@ namespace NCurses /// size_t RealChoice() const; - /// Searches the list for a given contraint. It uses GetStringFunction to convert stored items + /// Searches the list for a given contraint. It uses ItemStringifier to convert stored items /// into strings and then performs pattern matching. Note that this supports regular expressions. /// @param constraint a search constraint to be used /// @param beginning beginning of range that has to be searched through @@ -352,7 +341,7 @@ namespace NCurses virtual void PrevFound(bool wrap); /// Filters the list, showing only the items that matches the pattern. It uses - /// GetStringFunction to convert stored items into strings and then performs + /// ItemStringifier to convert stored items into strings and then performs /// pattern matching. Note that this supports regular expressions. /// @param filter a pattern to be used in pattern matching /// @param beginning beginning of range that has to be filtered @@ -376,7 +365,7 @@ namespace NCurses /// void ShowFiltered() { m_options_ptr = &m_filtered_options; } - /// Converts given position in list to string using GetStringFunction + /// Converts given position in list to string using ItemStringifier /// if specified and an empty string otherwise /// @param pos position to be converted /// @return item converted to string @@ -473,7 +462,7 @@ namespace NCurses /// defined only within drawing function that is called by Refresh() /// @see Refresh() /// - size_t CurrentlyDrawedPosition() const { return m_currently_drawn_positions; } + size_t CurrentlyDrawedPosition() const { return m_drawn_position; } /// @return reference to last item on the list /// @throw List::InvalidItem if requested item is separator @@ -527,9 +516,7 @@ namespace NCurses void ClearFiltered(); ItemDisplayer m_item_displayer; - void *m_item_displayer_data; - GetStringFunction m_get_string_helper; - void *m_get_string_helper_data; + ItemStringifier m_get_string_helper; std::string m_filter; std::string m_search_constraint; @@ -549,7 +536,7 @@ namespace NCurses bool m_autocenter_cursor; - size_t m_currently_drawn_positions; + size_t m_drawn_position; Buffer *m_selected_prefix; Buffer *m_selected_suffix; @@ -570,9 +557,7 @@ template NCurses::Menu::Menu(size_t startx, Border border) : Window(startx, starty, width, height, title, color, border), m_item_displayer(0), - m_item_displayer_data(0), m_get_string_helper(0), - m_get_string_helper_data(0), m_options_ptr(&m_options), itsBeginning(0), itsHighlight(0), @@ -587,9 +572,7 @@ template NCurses::Menu::Menu(size_t startx, template NCurses::Menu::Menu(const Menu &m) : Window(m), m_item_displayer(m.m_item_displayer), - m_item_displayer_data(m.m_item_displayer_data), m_get_string_helper(m.m_get_string_helper), - m_get_string_helper_data(m.m_get_string_helper_data), m_options_ptr(m.m_options_ptr), itsBeginning(m.itsBeginning), itsHighlight(m.itsHighlight), @@ -745,7 +728,7 @@ template void NCurses::Menu::Refresh() } size_t line = 0; - for (size_t &i = (m_currently_drawn_positions = itsBeginning); i < itsBeginning+itsHeight; ++i) + for (size_t &i = (m_drawn_position = itsBeginning); i < itsBeginning+itsHeight; ++i) { GotoXY(0, line); if (i >= m_options_ptr->size()) @@ -770,7 +753,7 @@ template void NCurses::Menu::Refresh() if ((*m_options_ptr)[i]->isSelected && m_selected_prefix) *this << *m_selected_prefix; if (m_item_displayer) - m_item_displayer((*m_options_ptr)[i]->Item, m_item_displayer_data, this); + m_item_displayer(*this, (*m_options_ptr)[i]->Item); if ((*m_options_ptr)[i]->isSelected && m_selected_suffix) *this << *m_selected_suffix; if (m_highlight_enabled && int(i) == itsHighlight) @@ -1096,7 +1079,7 @@ template const std::string &NCurses::Menu::GetFilter() template std::string NCurses::Menu::GetOption(size_t pos) { if (m_options_ptr->at(pos) && m_get_string_helper) - return m_get_string_helper((*m_options_ptr)[pos]->Item, m_get_string_helper_data); + return m_get_string_helper((*m_options_ptr)[pos]->Item); else return ""; } diff --git a/src/mutable_song.cpp b/src/mutable_song.cpp index ebe72c09..b11bc465 100644 --- a/src/mutable_song.cpp +++ b/src/mutable_song.cpp @@ -25,27 +25,27 @@ namespace MPD {// std::string MutableSong::getArtist(unsigned idx) const { - return getTag(MPD_TAG_ARTIST, [this, idx](){ return Song::getArtist(idx); }, idx); + return getTag(MPD_TAG_ARTIST, [this, idx](){ return this->Song::getArtist(idx); }, idx); } std::string MutableSong::getTitle(unsigned idx) const { - return getTag(MPD_TAG_TITLE, [this, idx](){ return Song::getTitle(idx); }, idx); + return getTag(MPD_TAG_TITLE, [this, idx](){ return this->Song::getTitle(idx); }, idx); } std::string MutableSong::getAlbum(unsigned idx) const { - return getTag(MPD_TAG_ALBUM, [this, idx](){ return Song::getAlbum(idx); }, idx); + return getTag(MPD_TAG_ALBUM, [this, idx](){ return this->Song::getAlbum(idx); }, idx); } std::string MutableSong::getAlbumArtist(unsigned idx) const { - return getTag(MPD_TAG_ALBUM_ARTIST, [this, idx](){ return Song::getAlbumArtist(idx); }, idx); + return getTag(MPD_TAG_ALBUM_ARTIST, [this, idx](){ return this->Song::getAlbumArtist(idx); }, idx); } std::string MutableSong::getTrack(unsigned idx) const { - std::string track = getTag(MPD_TAG_TRACK, [this, idx](){ return Song::getTrack(idx); }, idx); + std::string track = getTag(MPD_TAG_TRACK, [this, idx](){ return this->Song::getTrack(idx); }, idx); if ((track.length() == 1 && track[0] != '0') || (track.length() > 3 && track[1] == '/')) return "0"+track; @@ -55,32 +55,32 @@ std::string MutableSong::getTrack(unsigned idx) const std::string MutableSong::getDate(unsigned idx) const { - return getTag(MPD_TAG_DATE, [this, idx](){ return Song::getDate(idx); }, idx); + return getTag(MPD_TAG_DATE, [this, idx](){ return this->Song::getDate(idx); }, idx); } std::string MutableSong::getGenre(unsigned idx) const { - return getTag(MPD_TAG_GENRE, [this, idx](){ return Song::getGenre(idx); }, idx); + return getTag(MPD_TAG_GENRE, [this, idx](){ return this->Song::getGenre(idx); }, idx); } std::string MutableSong::getComposer(unsigned idx) const { - return getTag(MPD_TAG_COMPOSER, [this, idx](){ return Song::getComposer(idx); }, idx); + return getTag(MPD_TAG_COMPOSER, [this, idx](){ return this->Song::getComposer(idx); }, idx); } std::string MutableSong::getPerformer(unsigned idx) const { - return getTag(MPD_TAG_PERFORMER, [this, idx](){ return Song::getPerformer(idx); }, idx); + return getTag(MPD_TAG_PERFORMER, [this, idx](){ return this->Song::getPerformer(idx); }, idx); } std::string MutableSong::getDisc(unsigned idx) const { - return getTag(MPD_TAG_DISC, [this, idx](){ return Song::getDisc(idx); }, idx); + return getTag(MPD_TAG_DISC, [this, idx](){ return this->Song::getDisc(idx); }, idx); } std::string MutableSong::getComment(unsigned idx) const { - return getTag(MPD_TAG_COMMENT, [this, idx](){ return Song::getComment(idx); }, idx); + return getTag(MPD_TAG_COMMENT, [this, idx](){ return this->Song::getComment(idx); }, idx); } void MutableSong::setArtist(const std::string &value, unsigned idx) diff --git a/src/ncmpcpp.h b/src/ncmpcpp.h index 40b10af2..61e465da 100644 --- a/src/ncmpcpp.h +++ b/src/ncmpcpp.h @@ -26,6 +26,7 @@ #include "scrollpad.h" using namespace NCurses; +using namespace std::placeholders; typedef std::pair string_pair; diff --git a/src/playlist.cpp b/src/playlist.cpp index 42250ed2..ce3a1bab 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -45,18 +45,22 @@ Menu< std::pair > *Playlist::SortDialog = 0 void Playlist::Init() { - static Display::ScreenFormat sf = { this, &Config.song_list_format }; - Items = new Menu(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist && Config.titles_visibility ? Display::Columns(COLS) : "", Config.main_color, brNone); Items->CyclicScrolling(Config.use_cyclic_scrolling); Items->CenteredCursor(Config.centered_cursor); Items->HighlightColor(Config.main_highlight_color); Items->SetSelectPrefix(&Config.selected_item_prefix); Items->SetSelectSuffix(&Config.selected_item_suffix); - Items->setItemDisplayer(Config.columns_in_playlist ? Display::SongsInColumns : Display::Songs); - Items->setItemDisplayerData(&sf); - Items->SetGetStringFunction(Config.columns_in_playlist ? SongInColumnsToString : SongToString); - Items->SetGetStringFunctionUserData(&Config.song_list_format_dollar_free); + if (Config.columns_in_playlist) + { + Items->setItemDisplayer(std::bind(Display::SongsInColumns, _1, _2, *this)); + Items->SetItemStringifier(SongInColumnsToString); + } + else + { + Items->setItemDisplayer(std::bind(Display::Songs, _1, _2, *this, Config.song_list_format)); + Items->SetItemStringifier(SongToString); + } if (!SortDialog) { @@ -499,12 +503,12 @@ const MPD::Song *Playlist::NowPlayingSong() return s; } -std::string Playlist::SongToString(const MPD::Song &s, void *data) +std::string Playlist::SongToString(const MPD::Song &s) { - return s.toString(*static_cast(data)); + return s.toString(Config.song_list_format_dollar_free); } -std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *) +std::string Playlist::SongInColumnsToString(const MPD::Song &s) { return s.toString(Config.song_in_columns_to_string_format); } diff --git a/src/playlist.h b/src/playlist.h index 5beba09c..02c3202d 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -81,8 +81,8 @@ class Playlist : public Screen bool checkForSong(const MPD::Song &s); - static std::string SongToString(const MPD::Song &, void *); - static std::string SongInColumnsToString(const MPD::Song &, void *); + static std::string SongToString(const MPD::Song &s); + static std::string SongInColumnsToString(const MPD::Song &s); Menu< MPD::Song > *Items; diff --git a/src/playlist_editor.cpp b/src/playlist_editor.cpp index cc1397f2..f90bc331 100644 --- a/src/playlist_editor.cpp +++ b/src/playlist_editor.cpp @@ -54,18 +54,22 @@ void PlaylistEditor::Init() Playlists->CenteredCursor(Config.centered_cursor); Playlists->setItemDisplayer(Display::Default); - static Display::ScreenFormat sf = { this, &Config.song_list_format }; - Content = new Menu(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Playlist's content" : "", Config.main_color, brNone); Content->HighlightColor(Config.main_highlight_color); Content->CyclicScrolling(Config.use_cyclic_scrolling); Content->CenteredCursor(Config.centered_cursor); Content->SetSelectPrefix(&Config.selected_item_prefix); Content->SetSelectSuffix(&Config.selected_item_suffix); - Content->setItemDisplayer(Config.columns_in_playlist_editor ? Display::SongsInColumns : Display::Songs); - Content->setItemDisplayerData(&sf); - Content->SetGetStringFunction(Config.columns_in_playlist_editor ? Playlist::SongInColumnsToString : Playlist::SongToString); - Content->SetGetStringFunctionUserData(&Config.song_list_format_dollar_free); + if (Config.columns_in_playlist_editor) + { + Content->setItemDisplayer(std::bind(Display::SongsInColumns, _1, _2, *this)); + Content->SetItemStringifier(Playlist::SongInColumnsToString); + } + else + { + Content->setItemDisplayer(std::bind(Display::Songs, _1, _2, *this, Config.song_list_format)); + Content->SetItemStringifier(Playlist::SongToString); + } w = Playlists; isInitialized = 1; diff --git a/src/search_engine.cpp b/src/search_engine.cpp index 51450e33..6630e998 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -63,17 +63,14 @@ size_t SearchEngine::SearchButton = 15; void SearchEngine::Init() { - static Display::ScreenFormat sf = { this, &Config.song_list_format }; - w = new Menu(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone); w->HighlightColor(Config.main_highlight_color); w->CyclicScrolling(Config.use_cyclic_scrolling); w->CenteredCursor(Config.centered_cursor); w->setItemDisplayer(Display::SearchEngine); - w->setItemDisplayerData(&sf); w->SetSelectPrefix(&Config.selected_item_prefix); w->SetSelectSuffix(&Config.selected_item_suffix); - w->SetGetStringFunction(SearchEngineOptionToString); + w->SetItemStringifier(SearchEngineOptionToString); SearchMode = &SearchModes[Config.search_engine_default_search_mode]; isInitialized = 1; } @@ -545,15 +542,15 @@ void SearchEngine::Search() } } -std::string SearchEngine::SearchEngineOptionToString(const SEItem &ei, void *) +std::string SearchEngine::SearchEngineOptionToString(const SEItem &ei) { + std::string result; if (!ei.isSong()) { - if (!Config.columns_in_search_engine) - return ei.song().toString(Config.song_list_format_dollar_free); + if (Config.columns_in_search_engine) + result = Playlist::SongInColumnsToString(ei.song()); else - return Playlist::SongInColumnsToString(ei.song(), 0); + result = ei.song().toString(Config.song_list_format_dollar_free); } - else - return ""; + return result; } diff --git a/src/search_engine.h b/src/search_engine.h index 2a7357c1..50dd006e 100644 --- a/src/search_engine.h +++ b/src/search_engine.h @@ -116,7 +116,7 @@ class SearchEngine : public Screen< Menu > const char **SearchMode; - static std::string SearchEngineOptionToString(const SEItem &, void *); + static std::string SearchEngineOptionToString(const SEItem &); static const char *SearchModes[]; diff --git a/src/song.cpp b/src/song.cpp index 46ce3605..a0e864e5 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -258,7 +258,7 @@ bool Song::isStream() const bool Song::empty() const { - return m_song == 0; + return m_song.get() == 0; } std::string Song::toString(const std::string &fmt, const std::string &tag_separator, const std::string &escape_chars) const diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index cabdedf9..1ad6ff03 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -73,14 +73,14 @@ void TagEditor::Init() Albums->CyclicScrolling(Config.use_cyclic_scrolling); Albums->CenteredCursor(Config.centered_cursor); Albums->setItemDisplayer(Display::Pair); - Albums->SetGetStringFunction(StringPairToString); + Albums->SetItemStringifier(StringPairToString); Dirs = new Menu(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Directories" : "", Config.main_color, brNone); Dirs->HighlightColor(Config.active_column_color); Dirs->CyclicScrolling(Config.use_cyclic_scrolling); Dirs->CenteredCursor(Config.centered_cursor); Dirs->setItemDisplayer(Display::Pair); - Dirs->SetGetStringFunction(StringPairToString); + Dirs->SetItemStringifier(StringPairToString); LeftColumn = Config.albums_in_tag_editor ? Albums : Dirs; @@ -111,9 +111,7 @@ void TagEditor::Init() Tags->SetSelectPrefix(&Config.selected_item_prefix); Tags->SetSelectSuffix(&Config.selected_item_suffix); Tags->setItemDisplayer(Display::Tags); - Tags->setItemDisplayerData(TagTypes); - Tags->SetGetStringFunction(TagToString); - Tags->SetGetStringFunctionUserData(TagTypes); + Tags->SetItemStringifier(TagToString); FParserDialog = new Menu((COLS-FParserDialogWidth)/2, (MainHeight-FParserDialogHeight)/2+MainStartY, FParserDialogWidth, FParserDialogHeight, "", Config.main_color, Config.window_border); FParserDialog->CyclicScrolling(Config.use_cyclic_scrolling); @@ -1147,10 +1145,10 @@ void TagEditor::GetTagList(TagLib::StringList &list, const MPD::MutableSong &s, list.append(ToWString(value)); } -std::string TagEditor::TagToString(const MPD::MutableSong &s, void *data) +std::string TagEditor::TagToString(const MPD::MutableSong &s) { std::string result; - size_t i = static_cast *>(data)->Choice(); + size_t i = myTagEditor->TagTypes->Choice(); if (i < 11) result = (s.*SongInfo::Tags[i].Get)(0); else if (i == 12) diff --git a/src/tag_editor.h b/src/tag_editor.h index 6171286e..dd192115 100644 --- a/src/tag_editor.h +++ b/src/tag_editor.h @@ -113,7 +113,7 @@ class TagEditor : public Screen static std::string GenerateFilename(const MPD::MutableSong &, const std::string &); static std::string ParseFilename(MPD::MutableSong &, std::string, bool); - static std::string TagToString(const MPD::MutableSong &, void *); + static std::string TagToString(const MPD::MutableSong &); std::string itsBrowsedDir; std::string itsHighlightedDir;