support for columns view in playlist
This commit is contained in:
@@ -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"
|
||||
|
||||
164
src/helpers.cpp
164
src/helpers.cpp
@@ -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) : "";
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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!");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 &);
|
||||
|
||||
@@ -87,7 +87,7 @@ string Song::GetLength() const
|
||||
std::stringstream ss;
|
||||
|
||||
if (!GetTotalLength())
|
||||
return "unknown";
|
||||
return "-:--";
|
||||
|
||||
ss << itsMinutesLength << ":";
|
||||
if (!itsSecondsLength)
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user