display: get rid of reinterpret_casts

master
Andrzej Rybczak 14 years ago
parent d8b2d20bdb
commit c3d04b866f
  1. 268
      src/display.cpp

@ -31,10 +31,10 @@
using Global::myScreen; using Global::myScreen;
namespace namespace {//
const my_char_t *toColumnName(char c)
{ {
const my_char_t *toColumnName(char c)
{
switch (c) switch (c)
{ {
case 'l': case 'l':
@ -70,95 +70,90 @@ namespace
default: default:
return U("?"); return U("?");
} }
}
} }
std::string Display::Columns(size_t list_width) template <typename T>
void setProperties(Menu<T> &menu, const MPD::Song &s, BasicScreen &screen, bool &separate_albums,
bool &is_now_playing, bool &is_selected, bool &discard_colors)
{ {
if (Config.columns.empty()) separate_albums = false;
return ""; if (Config.playlist_separate_albums && menu.CurrentlyDrawedPosition()+1 < menu.Size())
std::string result;
int width;
int remained_width = list_width;
std::vector<Column>::const_iterator it, last = Config.columns.end() - 1;
for (it = Config.columns.begin(); it != Config.columns.end(); ++it)
{ {
// column has relative width and all after it have fixed width, MPD::Song *next = screen.GetSong(menu.CurrentlyDrawedPosition()+1);
// so stretch it so it fills whole screen along with these after. if (next && next->getAlbum() != s.getAlbum())
if (it->stretch_limit >= 0) // (*) separate_albums = true;
width = remained_width - it->stretch_limit; }
else if (separate_albums)
width = it->fixed ? it->width : it->width * list_width * 0.01; menu << fmtUnderline;
// columns with relative width may shrink to 0, omit them
if (width == 0)
continue;
// if column is not last, we need to have spacing between it
// and next column, so we substract it now and restore later.
if (it != last)
--width;
// if column doesn't fit into screen, discard it and any other after it. int song_pos = menu.isFiltered() ? s.getPosition() : menu.CurrentlyDrawedPosition();
if (remained_width-width < 0 || width < 0 /* this one may come from (*) */) is_now_playing = song_pos == myPlaylist->NowPlaying && s.getID() > 0; // playlist
break; is_selected = menu[menu.CurrentlyDrawedPosition()].isSelected();
discard_colors = Config.discard_colors_if_item_is_selected && is_selected;
}
std::basic_string<my_char_t> name; template <typename T>
if (it->name.empty()) void showSongs(Menu<T> &menu, const MPD::Song &s, BasicScreen &screen, const std::string &format)
{
bool separate_albums, is_now_playing, is_selected, discard_colors;
setProperties(menu, s, screen, separate_albums, is_now_playing, is_selected, discard_colors);
std::string line = s.toString(format, "$");
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it)
{ {
for (size_t j = 0; j < it->type.length(); ++j) if (*it == '$')
{ {
name += toColumnName(it->type[j]); if (++it == line.end()) // end of format
name += '/'; {
} menu << '$';
name.resize(name.length()-1); break;
} }
else else if (isdigit(*it)) // color
name = it->name;
Window::Cut(name, width);
int x_off = std::max(0, width - int(Window::Length(name)));
if (it->right_alignment)
{ {
result += std::string(x_off, KEY_SPACE); if (!discard_colors)
result += TO_STRING(name); menu << Color(*it-'0');
} }
else else if (*it == 'R') // right align
{ {
result += TO_STRING(name); basic_buffer<my_char_t> buf;
result += std::string(x_off, KEY_SPACE); 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[menu.CurrentlyDrawedPosition()].isSelected() ? 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
if (it != last) menu << *--it;
}
else if (*it == MPD::Song::FormatEscapeCharacter)
{ {
// add missing width's part and restore the value. // treat '$' as a normal character if song format escape char is prepended to it
remained_width -= width+1; if (++it == line.end() || *it != '$')
result += ' '; --it;
menu << *it;
} }
else
menu << *it;
} }
if (is_now_playing)
return result; menu << Config.now_playing_suffix;
if (separate_albums)
menu << fmtUnderlineEnd;
} }
void Display::SongsInColumns(Menu<MPD::Song> &menu, const MPD::Song &s, BasicScreen &screen) template <typename T>
void showSongsInColumns(Menu<T> &menu, const MPD::Song &s, BasicScreen &screen)
{ {
if (Config.columns.empty()) if (Config.columns.empty())
return; return;
bool separate_albums = false; bool separate_albums, is_now_playing, is_selected, discard_colors;
if (Config.playlist_separate_albums && menu.CurrentlyDrawedPosition()+1 < menu.Size()) setProperties(menu, s, screen, separate_albums, is_now_playing, is_selected, discard_colors);
{
MPD::Song *next = screen.GetSong(menu.CurrentlyDrawedPosition()+1);
if (next && next->getAlbum() != s.getAlbum())
separate_albums = true;
}
if (separate_albums)
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[menu.CurrentlyDrawedPosition()].isSelected();
bool discard_colors = Config.discard_colors_if_item_is_selected && is_selected;
if (is_now_playing) if (is_now_playing)
menu << Config.now_playing_prefix; menu << Config.now_playing_prefix;
@ -268,74 +263,83 @@ void Display::SongsInColumns(Menu<MPD::Song> &menu, const MPD::Song &s, BasicScr
menu << fmtUnderlineEnd; menu << fmtUnderlineEnd;
} }
void Display::Songs(Menu<MPD::Song> &menu, const MPD::Song &s, BasicScreen &screen, const std::string &format) }
std::string Display::Columns(size_t list_width)
{ {
bool is_now_playing = &menu == myPlaylist->Items && (menu.isFiltered() ? s.getPosition() : menu.CurrentlyDrawedPosition()) == size_t(myPlaylist->NowPlaying); if (Config.columns.empty())
if (is_now_playing) return "";
menu << Config.now_playing_prefix;
bool separate_albums = false; std::string result;
if (Config.playlist_separate_albums && menu.CurrentlyDrawedPosition()+1 < menu.Size())
{ int width;
MPD::Song *next = screen.GetSong(menu.CurrentlyDrawedPosition()+1); int remained_width = list_width;
if (next && next->getAlbum() != s.getAlbum()) std::vector<Column>::const_iterator it, last = Config.columns.end() - 1;
separate_albums = true; for (it = Config.columns.begin(); it != Config.columns.end(); ++it)
}
if (separate_albums)
{ {
menu << fmtUnderline; // column has relative width and all after it have fixed width,
mvwhline(menu.Raw(), menu.Y(), 0, ' ', menu.GetWidth()); // 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 * list_width * 0.01;
// columns with relative width may shrink to 0, omit them
if (width == 0)
continue;
// if column is not last, we need to have spacing between it
// and next column, so we substract it now and restore later.
if (it != last)
--width;
bool discard_colors = Config.discard_colors_if_item_is_selected // if column doesn't fit into screen, discard it and any other after it.
&& menu[menu.CurrentlyDrawedPosition()].isSelected(); if (remained_width-width < 0 || width < 0 /* this one may come from (*) */)
break;
std::string line = s.toString(format, "$"); std::basic_string<my_char_t> name;
for (std::string::const_iterator it = line.begin(); it != line.end(); ++it) if (it->name.empty())
{
if (*it == '$')
{ {
if (++it == line.end()) // end of format for (size_t j = 0; j < it->type.length(); ++j)
{ {
menu << '$'; name += toColumnName(it->type[j]);
break; name += '/';
} }
else if (isdigit(*it)) // color name.resize(name.length()-1);
{
if (!discard_colors)
menu << Color(*it-'0');
} }
else if (*it == 'R') // right align else
name = it->name;
Window::Cut(name, width);
int x_off = std::max(0, width - int(Window::Length(name)));
if (it->right_alignment)
{ {
basic_buffer<my_char_t> buf; result += std::string(x_off, KEY_SPACE);
buf << U(" "); result += TO_STRING(name);
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[menu.CurrentlyDrawedPosition()].isSelected() ? 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 else
menu << *--it; {
result += TO_STRING(name);
result += std::string(x_off, KEY_SPACE);
} }
else if (*it == MPD::Song::FormatEscapeCharacter)
if (it != last)
{ {
// treat '$' as a normal character if song format escape char is prepended to it // add missing width's part and restore the value.
if (++it == line.end() || *it != '$') remained_width -= width+1;
--it; result += ' ';
menu << *it;
} }
else
menu << *it;
} }
if (is_now_playing)
menu << Config.now_playing_suffix; return result;
if (separate_albums) }
menu << fmtUnderlineEnd;
void Display::SongsInColumns(Menu<MPD::Song> &menu, const MPD::Song &s, BasicScreen &screen)
{
showSongsInColumns(menu, s, screen);
}
void Display::Songs(Menu<MPD::Song> &menu, const MPD::Song &s, BasicScreen &screen, const std::string &format)
{
showSongs(menu, s, screen, format);
} }
void Display::Tags(Menu<MPD::MutableSong> &menu, const MPD::MutableSong &s) void Display::Tags(Menu<MPD::MutableSong> &menu, const MPD::MutableSong &s)
@ -364,21 +368,17 @@ void Display::Items(Menu<MPD::Item> &menu, const MPD::Item &item)
switch (item.type) switch (item.type)
{ {
case MPD::itDirectory: case MPD::itDirectory:
{
menu << "[" << getBasename(item.name) << "]"; menu << "[" << getBasename(item.name) << "]";
return; break;
}
case MPD::itSong: case MPD::itSong:
if (!Config.columns_in_browser) if (!Config.columns_in_browser)
Display::Songs(reinterpret_cast<Menu<MPD::Song> &>(menu), *item.song, *myBrowser, Config.song_list_format); showSongs(menu, *item.song, *myBrowser, Config.song_list_format);
else else
Display::SongsInColumns(reinterpret_cast<Menu<MPD::Song> &>(menu), *item.song, *myBrowser); showSongsInColumns(menu, *item.song, *myBrowser);
return; break;
case MPD::itPlaylist: case MPD::itPlaylist:
menu << Config.browser_playlist_prefix << getBasename(item.name); menu << Config.browser_playlist_prefix << getBasename(item.name);
return; break;
default:
return;
} }
} }
@ -387,9 +387,9 @@ void Display::SearchEngine(Menu<SEItem> &menu, const SEItem &ei)
if (ei.isSong()) if (ei.isSong())
{ {
if (!Config.columns_in_search_engine) if (!Config.columns_in_search_engine)
Display::Songs(reinterpret_cast<Menu<MPD::Song> &>(menu), ei.song(), *mySearcher, Config.song_list_format); showSongs(menu, ei.song(), *mySearcher, Config.song_list_format);
else else
Display::SongsInColumns(reinterpret_cast<Menu<MPD::Song> &>(menu), ei.song(), *mySearcher); showSongsInColumns(menu, ei.song(), *mySearcher);
} }
else else
menu << ei.buffer(); menu << ei.buffer();

Loading…
Cancel
Save