support for columns view in playlist

This commit is contained in:
unK
2008-09-03 11:04:21 +02:00
parent 0658eb1c7c
commit d7b635e276
11 changed files with 223 additions and 23 deletions

View File

@@ -74,12 +74,31 @@
#
#selected_item_suffix = "[/magenta]"
#
##### columns settings #####
##
## syntax of song columns list format is "column column etc."
##
## - syntax for each column is:
##
## (width of column in %)[column's color]{displayed tag}
##
## - color is optional (if it's not present, default window color will be used)
##
#
#song_columns_list_format = "(8)[green]{l} (28)[cyan]{a} (28)[yellow]{b} (50)[red]{t}"
#
##### various settings #####
#
## can be "normal" or "columns"
#
#playlist_display_mode = "normal"
#
#autocenter_mode = "no"
#
#repeat_one_mode = "no"
#
## can be "wrapped" or "normal"
#
#default_find_mode = "wrapped"
#
#default_space_mode = "add"

View File

@@ -332,6 +332,170 @@ string DisplayItem(const Item &item, void *)
}
}
string DisplayColumns(string song_template)
{
vector<string> cols;
for (int i = song_template.find(" "); i != string::npos; i = song_template.find(" "))
{
cols.push_back(song_template.substr(0, i));
song_template = song_template.substr(i+1);
}
cols.push_back(song_template);
string result, v;
for (vector<string>::const_iterator it = cols.begin(); it != cols.end(); it++)
{
int width = StrToInt(GetLineValue(*it, '(', ')'));
char type = GetLineValue(*it, '{', '}')[0];
width *= COLS/100.0;
switch (type)
{
case 'l':
v = "Time";
break;
case 'f':
v = "Filename";
break;
case 'F':
v = "Full filename";
break;
case 'a':
v = "Artist";
break;
case 't':
v = "Title";
break;
case 'b':
v = "Album";
break;
case 'y':
v = "Year";
break;
case 'n':
v = "Track";
break;
case 'g':
v = "Genre";
break;
case 'c':
v = "Composer";
break;
case 'p':
v = "Performer";
break;
case 'd':
v = "Disc";
break;
case 'C':
v = "Comment";
break;
default:
break;
}
v = v.substr(0, width-1);
for (int i = v.length(); i < width; i++, v += " ");
result += v;
}
return result.substr(0, COLS);
}
string DisplaySongInColumns(const Song &s, void *s_template)
{
string song_template = s_template ? *static_cast<string *>(s_template) : "";
vector<string> cols;
for (int i = song_template.find(" "); i != string::npos; i = song_template.find(" "))
{
cols.push_back(song_template.substr(0, i));
song_template = song_template.substr(i+1);
}
cols.push_back(song_template);
ncmpcpp_string_t result, v;
# ifdef UTF8_ENABLED
const wstring space = L" ";
const wstring open_col = L"[.";
const wstring close_col = L"]";
const wstring close_col2 = L"[/red]";
# else
const string space = " ";
const string open_col = "[.";
const string close_col = "]";
const string close_col2 = "[/red]";
# endif
for (vector<string>::const_iterator it = cols.begin(); it != cols.end(); it++)
{
int width = StrToInt(GetLineValue(*it, '(', ')'));
ncmpcpp_string_t color = TO_WSTRING(GetLineValue(*it, '[', ']'));
char type = GetLineValue(*it, '{', '}')[0];
width *= COLS/100.0;
string ss;
switch (type)
{
case 'l':
ss = s.GetLength();
break;
case 'f':
ss = s.GetShortFilename();
break;
case 'F':
ss = s.GetFile();
break;
case 'a':
ss = s.GetArtist();
break;
case 't':
ss = s.GetTitle();
break;
case 'b':
ss = s.GetAlbum();
break;
case 'y':
ss = s.GetYear();
break;
case 'n':
ss = s.GetTrack();
break;
case 'g':
ss = s.GetGenre();
break;
case 'c':
ss = s.GetComposer();
break;
case 'p':
ss = s.GetPerformer();
break;
case 'd':
ss = s.GetDisc();
break;
case 'C':
ss = s.GetComment();
break;
default:
break;
}
v = TO_WSTRING(OmitBBCodes(ss)).substr(0, width-1);
for (int i = v.length(); i < width; i++, v += space);
if (!color.empty())
result += open_col + color + close_col;
result += v;
if (!color.empty())
result += close_col2;
}
return TO_STRING(result);
}
string DisplaySong(const Song &s, void *s_template)
{
const string &song_template = s_template ? *static_cast<string *>(s_template) : "";

View File

@@ -48,6 +48,8 @@ bool CaseInsensitiveComparison(string, string);
void WindowTitle(const string &);
string TotalPlaylistLength();
string DisplayItem(const Item &, void * = NULL);
string DisplayColumns(string);
string DisplaySongInColumns(const Song &, void *);
string DisplaySong(const Song &, void * = &Config.song_list_format);
void ShowMessage(const string &, int = Config.message_delay_time);
bool SortDirectory(const Item &a, const Item &b);

View File

@@ -126,7 +126,6 @@ class Menu : public Window
bool itsHighlightEnabled;
};
template <class T>
Menu<T>::Menu(const Menu &m) : Window(m)
{
@@ -798,5 +797,8 @@ string Menu<T>::DisplayOption(const T &t) const
return itsItemDisplayer ? itsItemDisplayer(t, itsUserdata) : "";
}
template <>
string Menu<string>::DisplayOption(const string &str) const;
#endif

View File

@@ -189,11 +189,11 @@ int main(int argc, char *argv[])
if (!Config.statusbar_visibility)
main_height++;
mPlaylist = new Menu<Song>(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
mPlaylist = new Menu<Song>(0, main_start_y, COLS, main_height, Config.columns_in_playlist ? DisplayColumns(Config.song_columns_list_format) : "", Config.main_color, brNone);
mPlaylist->SetSelectPrefix(Config.selected_item_prefix);
mPlaylist->SetSelectSuffix(Config.selected_item_suffix);
mPlaylist->SetItemDisplayer(DisplaySong);
mPlaylist->SetItemDisplayerUserData(&Config.song_list_format);
mPlaylist->SetItemDisplayer(Config.columns_in_playlist ? DisplaySongInColumns : DisplaySong);
mPlaylist->SetItemDisplayerUserData(Config.columns_in_playlist ? &Config.song_columns_list_format : &Config.song_list_format);
mBrowser = new Menu<Item>(0, main_start_y, COLS, main_height, "", Config.main_color, brNone);
mBrowser->SetSelectPrefix(Config.selected_item_prefix);
@@ -339,8 +339,6 @@ int main(int argc, char *argv[])
wCurrent = mPlaylist;
current_screen = csPlaylist;
wCurrent->Display();
int input;
timer = time(NULL);
@@ -431,7 +429,7 @@ int main(int argc, char *argv[])
if (current_screen == csBrowser)
{
int max_length_without_scroll = wHeader->GetWidth()-volume_state.length()-title.length();
ncmpcpp_string_t wbrowseddir = NCMPCPP_TO_WSTRING(browsed_dir);
ncmpcpp_string_t wbrowseddir = TO_WSTRING(browsed_dir);
wHeader->Bold(1);
if (browsed_dir.length() > max_length_without_scroll)
{
@@ -626,7 +624,10 @@ int main(int argc, char *argv[])
// playlist editor end
wCurrent->Refresh(redraw_me);
if (Config.columns_in_playlist && wCurrent == mPlaylist)
wCurrent->Display(redraw_me);
else
wCurrent->Refresh(redraw_me);
redraw_me = 0;
wCurrent->ReadKey(input);
@@ -722,6 +723,7 @@ int main(int argc, char *argv[])
sHelp->Resize(COLS, main_height);
sHelp->Timeout(ncmpcpp_window_timeout);
mPlaylist->Resize(COLS, main_height);
mPlaylist->SetTitle(Config.columns_in_playlist ? DisplayColumns(Config.song_columns_list_format) : "");
mBrowser->Resize(COLS, main_height);
mTagEditor->Resize(COLS, main_height);
mSearcher->Resize(COLS, main_height);
@@ -926,13 +928,13 @@ int main(int argc, char *argv[])
{
ShowMessage("Updating tags...");
s.GetEmptyFields(1);
f.tag()->setTitle(NCMPCPP_TO_WSTRING(s.GetTitle()));
f.tag()->setArtist(NCMPCPP_TO_WSTRING(s.GetArtist()));
f.tag()->setAlbum(NCMPCPP_TO_WSTRING(s.GetAlbum()));
f.tag()->setTitle(TO_WSTRING(s.GetTitle()));
f.tag()->setArtist(TO_WSTRING(s.GetArtist()));
f.tag()->setAlbum(TO_WSTRING(s.GetAlbum()));
f.tag()->setYear(StrToInt(s.GetYear()));
f.tag()->setTrack(StrToInt(s.GetTrack()));
f.tag()->setGenre(NCMPCPP_TO_WSTRING(s.GetGenre()));
f.tag()->setComment(NCMPCPP_TO_WSTRING(s.GetComment()));
f.tag()->setGenre(TO_WSTRING(s.GetGenre()));
f.tag()->setComment(TO_WSTRING(s.GetComment()));
s.GetEmptyFields(0);
f.save();
ShowMessage("Tags updated!");

View File

@@ -27,12 +27,8 @@
#ifdef UTF8_ENABLED
const bool UNICODE = 1;
# define ncmpcpp_string_t wstring
# define NCMPCPP_TO_WSTRING(x) ToWString(x)
#else
const bool UNICODE = 0;
# define ncmpcpp_string_t string
# define NCMPCPP_TO_WSTRING(x) (x)
#endif
#ifdef HAVE_TAGLIB_H

View File

@@ -144,6 +144,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
{
conf.mpd_music_dir = "/var/lib/mpd/music";
conf.song_list_format = "{[.green](%l)[/green] }{%a - }{%t}|{[.white]%f[/white]}";
conf.song_columns_list_format = "(8)[green]{l} (28)[cyan]{a} (28){b} (50)[red]{t}";
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}";
@@ -161,6 +162,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.statusbar_color = clDefault;
conf.active_column_color = clRed;
conf.colors_enabled = true;
conf.columns_in_playlist = false;
conf.header_visibility = true;
conf.statusbar_visibility = true;
conf.autocenter_mode = false;
@@ -197,13 +199,13 @@ void GetKeys(string line, int *key)
key[1] = !two.empty() && two[0] == '\'' ? two[1] : (atoi(two.c_str()) == 0 ? null_key : atoi(two.c_str()));
}
string GetConfigLineValue(const string &line)
string GetLineValue(const string &line, char a, char b)
{
int i = 0;
int begin = -1, end = -1;
for (string::const_iterator it = line.begin(); it != line.end(); i++, it++)
{
if (*it == '"')
if (*it == a || *it == b)
{
if (begin < 0)
begin = i+1;
@@ -414,7 +416,7 @@ void ReadConfiguration(ncmpcpp_config &conf)
}
for (vector<string>::const_iterator it = config_sets.begin(); it != config_sets.end(); it++)
{
v = GetConfigLineValue(*it);
v = GetLineValue(*it);
if (it->find("mpd_music_dir") != string::npos)
{
@@ -446,6 +448,11 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (!v.empty())
conf.song_list_format = v;
}
else if (it->find("song_columns_list_format") != string::npos)
{
if (!v.empty())
conf.song_columns_list_format = v;
}
else if (it->find("song_status_format") != string::npos)
{
if (!v.empty())
@@ -473,6 +480,8 @@ void ReadConfiguration(ncmpcpp_config &conf)
}
else if (it->find("colors_enabled") != string::npos)
conf.colors_enabled = v == "yes";
else if (it->find("playlist_display_mode") != string::npos)
conf.columns_in_playlist = v == "columns";
else if (it->find("header_visibility") != string::npos)
conf.header_visibility = v == "yes";
else if (it->find("statusbar_visibility") != string::npos)

View File

@@ -90,6 +90,7 @@ struct ncmpcpp_config
{
string mpd_music_dir;
string song_list_format;
string song_columns_list_format;
string song_status_format;
string song_window_title_format;
string song_library_format;
@@ -110,6 +111,7 @@ struct ncmpcpp_config
Color active_column_color;
bool colors_enabled;
bool columns_in_playlist;
bool set_window_title;
bool header_visibility;
bool statusbar_visibility;
@@ -127,7 +129,7 @@ struct ncmpcpp_config
void DefaultKeys(ncmpcpp_keys &);
void DefaultConfiguration(ncmpcpp_config &);
void GetKeys(string, int *);
string GetLineValue(const string &);
string GetLineValue(const string &, char = '"', char = '"');
string IntoStr(Color);
Color IntoColor(const string &);
void ReadKeys(ncmpcpp_keys &);

View File

@@ -87,7 +87,7 @@ string Song::GetLength() const
std::stringstream ss;
if (!GetTotalLength())
return "unknown";
return "-:--";
ss << itsMinutesLength << ":";
if (!itsSecondsLength)

View File

@@ -312,7 +312,7 @@ void NcmpcppStatusChanged(MPDConnection *Mpd, MPDStatusChanges changed, void *da
tracklength = " [" + ShowTime(elapsed) + "/" + s.GetLength() + "]";
else
tracklength = " [" + ShowTime(elapsed) + "]";
ncmpcpp_string_t playing_song = NCMPCPP_TO_WSTRING(OmitBBCodes(DisplaySong(s, &Config.song_status_format)));
ncmpcpp_string_t playing_song = TO_WSTRING(OmitBBCodes(DisplaySong(s, &Config.song_status_format)));
int max_length_without_scroll = wFooter->GetWidth()-player_state.length()-tracklength.length();

View File

@@ -30,9 +30,13 @@
#include <cstring>
#ifdef UTF8_ENABLED
# define ncmpcpp_string_t wstring
# define TO_STRING(x) ToString(x)
# define TO_WSTRING(x) ToWString(x)
#else
# define ncmpcpp_string_t string
# define TO_STRING(x) x
# define TO_WSTRING(x) x
#endif
using std::string;