void Display::Songs(const MPD::Song &s, void *data, Menu<MPD::Song> *menu) { if (!s.Localized()) const_cast<MPD::Song *>(&s)->Localize(); 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; assert(data); bool separate_albums = false; if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size()) { MPD::Song *next = static_cast<ScreenFormat *>(data)->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()); } bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition()); std::string line = s.toString(*static_cast<ScreenFormat *>(data)->format, "$"); for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) { if (*it == '$') { if (++it == line.end()) // end of format { *menu << '$'; break; } else if (isdigit(*it)) // color { if (!discard_colors) *menu << Color(*it-'0'); } else if (*it == 'R') // right align { basic_buffer<my_char_t> buf; buf << U(" "); String2Buffer(TO_WSTRING(line.substr(it-line.begin()+1)), buf); if (discard_colors) 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; if (separate_albums) *menu << fmtUnderlineEnd; return; } else // not a color nor right align, just a random character *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; } else *menu << *it; } if (is_now_playing) *menu << Config.now_playing_suffix; if (separate_albums) *menu << fmtUnderlineEnd; }
void Display::SongsInColumns(const MPD::Song &s, void *data, Menu<MPD::Song> *menu) { if (!s.Localized()) const_cast<MPD::Song *>(&s)->Localize(); /// FIXME: This function is pure mess, it needs to be /// rewritten and unified with Display::Columns() a bit. 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; if (Config.columns.empty()) return; assert(data); bool separate_albums = false; if (Config.playlist_separate_albums && menu->CurrentlyDrawedPosition()+1 < menu->Size()) { MPD::Song *next = static_cast<ScreenFormat *>(data)->screen->GetSong(menu->CurrentlyDrawedPosition()+1); if (next && next->GetAlbum() != s.GetAlbum()) separate_albums = true; } if (separate_albums) *menu << fmtUnderline; std::vector<Column>::const_iterator next2last, last, it; size_t where = 0; int width; bool last_fixed = Config.columns.back().fixed; if (Config.columns.size() > 1) next2last = Config.columns.end()-2; last = Config.columns.end()-1; bool discard_colors = Config.discard_colors_if_item_is_selected && menu->isSelected(menu->CurrentlyDrawedPosition()); for (it = Config.columns.begin(); it != Config.columns.end(); ++it) { if (where) { menu->GotoXY(where, menu->Y()); *menu << ' '; if (!discard_colors && (it-1)->color != clDefault) *menu << clEnd; } if (it == Config.columns.end()-1) width = menu->GetWidth()-where; else if (last_fixed && it == next2last) width = menu->GetWidth()-where-1-(++next2last)->width; else width = it->width*(it->fixed ? 1 : menu->GetWidth()/100.0); MPD::Song::GetFunction get = 0; std::string tag; for (size_t i = 0; i < it->type.length(); ++i) { get = toGetFunction(it->type[i]); tag = get ? s.GetTags(get) : ""; if (!tag.empty()) break; } if (!discard_colors && it->color != clDefault) *menu << it->color; whline(menu->Raw(), 32, menu->GetWidth()-where); // last column might need to be shrinked to make space for np/sel suffixes if (it == last) { if (menu->isSelected(menu->CurrentlyDrawedPosition())) width -= Config.selected_item_suffix_length; if (is_now_playing) width -= Config.now_playing_suffix_length; } if (it->right_alignment) { if (width > 0 && (!tag.empty() || it->display_empty_tag)) { int x, y; menu->GetXY(x, y); my_string_t wtag = TO_WSTRING(tag.empty() ? Config.empty_tag : tag).substr(0, width-!!x); *menu << XY(x+width-Window::Length(wtag)-!!x, y) << wtag; } } else { if (it == last) { if (width > 0) { my_string_t str; if (!tag.empty()) str = TO_WSTRING(tag).substr(0, width-1); else if (it->display_empty_tag) str = TO_WSTRING(Config.empty_tag).substr(0, width-1); *menu << str; } } else { if (!tag.empty()) *menu << tag; else if (it->display_empty_tag) *menu << Config.empty_tag; } } where += width; } if (!discard_colors && (--it)->color != clDefault) *menu << clEnd; if (is_now_playing) *menu << Config.now_playing_suffix; if (separate_albums) *menu << fmtUnderlineEnd; }