new feature: allow for fixed size columns

This commit is contained in:
Andrzej Rybczak
2009-07-10 19:17:12 +02:00
parent 209f5337ee
commit c20d8694ae
9 changed files with 90 additions and 54 deletions

View File

@@ -101,12 +101,18 @@
## ##
## - syntax for each column is: ## - syntax for each column is:
## ##
## (width of column in %)[column's color]{displayed tag} ## (width of column)[column's color]{displayed tag}
##
## Note: Width is by default in %, if you want a column to
## have fixed size, add 'f' after the value, e.g. (10)[white]{a}
## will be the column that take 10% of screen (so the real column's
## width will depend on actual screen size), whereas (10f)[white]{a}
## will take 10 terminal cells, no matter how wide the screen is.
## ##
## - color is optional (if you want the default one, type []) ## - color is optional (if you want the default one, type [])
## ##
# #
#song_columns_list_format = "(7)[green]{l} (28)[cyan]{a} (28)[]{b} (50)[red]{t}" #song_columns_list_format = "(7f)[green]{l} (25)[cyan]{a} (40)[]{t} (30)[red]{b}"
# #
##### various settings ##### ##### various settings #####
# #

View File

@@ -51,7 +51,7 @@ const char *Browser::SupportedExtensions[] =
void Browser::Init() void Browser::Init()
{ {
w = new Menu<Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser ? Display::Columns(Config.song_columns_list_format) : "", Config.main_color, brNone); w = new Menu<Item>(0, MainStartY, COLS, MainHeight, Config.columns_in_browser ? Display::Columns() : "", Config.main_color, brNone);
w->HighlightColor(Config.main_highlight_color); w->HighlightColor(Config.main_highlight_color);
w->SetTimeout(ncmpcpp_window_timeout); w->SetTimeout(ncmpcpp_window_timeout);
w->CyclicScrolling(Config.use_cyclic_scrolling); w->CyclicScrolling(Config.use_cyclic_scrolling);
@@ -626,7 +626,7 @@ std::string Browser::ItemToString(const MPD::Item &item, void *)
if (!Config.columns_in_browser) if (!Config.columns_in_browser)
return item.song->toString(Config.song_list_format); return item.song->toString(Config.song_list_format);
else else
return Playlist::SongInColumnsToString(*item.song, &Config.song_columns_list_format); return Playlist::SongInColumnsToString(*item.song, 0);
} }
case MPD::itPlaylist: case MPD::itPlaylist:
{ {

View File

@@ -23,17 +23,25 @@
#include "helpers.h" #include "helpers.h"
#include "playlist.h" #include "playlist.h"
std::string Display::Columns(std::string st) std::string Display::Columns()
{ {
if (Config.columns.empty())
return "";
std::string result; std::string result;
size_t where = 0; size_t where = 0;
int width;
for (int width = StrToInt(GetLineValue(st, '(', ')', 1)); width; width = StrToInt(GetLineValue(st, '(', ')', 1))) std::vector<Column>::const_iterator next2last;
bool last_fixed = Config.columns.back().fixed;
if (Config.columns.size() > 1)
next2last = Config.columns.end()-2;
for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it)
{ {
width *= COLS/100.0; width = it->width*(it->fixed ? 1 : COLS/100.0);
char type = GetLineValue(st, '{', '}', 1)[0];
switch (type) switch (it->type)
{ {
case 'l': case 'l':
result += "Time"; result += "Time";
@@ -77,7 +85,10 @@ std::string Display::Columns(std::string st)
default: default:
break; break;
} }
where += width; if (last_fixed && it == next2last)
where = COLS-(++next2last)->width;
else
where += width;
if (result.length() > where) if (result.length() > where)
result = result.substr(0, where); result = result.substr(0, where);
@@ -87,32 +98,36 @@ std::string Display::Columns(std::string st)
return result; return result;
} }
void Display::SongsInColumns(const MPD::Song &s, void *s_template, Menu<MPD::Song> *menu) void Display::SongsInColumns(const MPD::Song &s, void *, Menu<MPD::Song> *menu)
{ {
if (!s.Localized()) if (!s.Localized())
const_cast<MPD::Song *>(&s)->Localize(); const_cast<MPD::Song *>(&s)->Localize();
std::string st = s_template ? *static_cast<std::string *>(s_template) : ""; if (Config.columns.empty())
size_t where = 0; return;
Color color = clDefault;
for (int width = StrToInt(GetLineValue(st, '(', ')', 1)); width; width = StrToInt(GetLineValue(st, '(', ')', 1))) std::vector<Column>::const_iterator next2last, it;
size_t where = 0;
int width;
bool last_fixed = Config.columns.back().fixed;
if (Config.columns.size() > 1)
next2last = Config.columns.end()-2;
for (it = Config.columns.begin(); it != Config.columns.end(); ++it)
{ {
if (where) if (where)
{ {
menu->GotoXY(where, menu->Y()); menu->GotoXY(where, menu->Y());
*menu << ' '; *menu << ' ';
if (color != clDefault) if ((it-1)->color != clDefault)
*menu << clEnd; *menu << clEnd;
} }
width *= COLS/100.0; width = it->width*(it->fixed ? 1 : COLS/100.0);
color = IntoColor(GetLineValue(st, '[', ']', 1));
char type = GetLineValue(st, '{', '}', 1)[0];
MPD::Song::GetFunction get = 0; MPD::Song::GetFunction get = 0;
switch (type) switch (it->type)
{ {
case 'l': case 'l':
get = &MPD::Song::GetLength; get = &MPD::Song::GetLength;
@@ -159,17 +174,20 @@ void Display::SongsInColumns(const MPD::Song &s, void *s_template, Menu<MPD::Son
default: default:
break; break;
} }
if (color != clDefault) if (it->color != clDefault)
*menu << color; *menu << it->color;
whline(menu->Raw(), 32, menu->GetWidth()-where); whline(menu->Raw(), 32, menu->GetWidth()-where);
std::string tag = (s.*get)(); std::string tag = (s.*get)();
if (!tag.empty()) if (!tag.empty())
*menu << tag; *menu << tag;
else else
*menu << Config.empty_tag; *menu << Config.empty_tag;
where += width; if (last_fixed && it == next2last)
where = COLS-(++next2last)->width;
else
where += width;
} }
if (color != clDefault) if ((--it)->color != clDefault)
*menu << clEnd; *menu << clEnd;
} }
@@ -461,7 +479,7 @@ void Display::Items(const MPD::Item &item, void *, Menu<MPD::Item> *menu)
if (!Config.columns_in_browser) if (!Config.columns_in_browser)
Display::Songs(*item.song, &Config.song_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu)); Display::Songs(*item.song, &Config.song_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu));
else else
Display::SongsInColumns(*item.song, &Config.song_columns_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu)); Display::SongsInColumns(*item.song, 0, reinterpret_cast<Menu<MPD::Song> *>(menu));
return; return;
case MPD::itPlaylist: case MPD::itPlaylist:
*menu << Config.browser_playlist_prefix << item.name; *menu << Config.browser_playlist_prefix << item.name;
@@ -478,7 +496,7 @@ void Display::SearchEngine(const std::pair<Buffer *, MPD::Song *> &pair, void *,
if (!Config.columns_in_search_engine) if (!Config.columns_in_search_engine)
Display::Songs(*pair.second, &Config.song_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu)); Display::Songs(*pair.second, &Config.song_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu));
else else
Display::SongsInColumns(*pair.second, &Config.song_columns_list_format, reinterpret_cast<Menu<MPD::Song> *>(menu)); Display::SongsInColumns(*pair.second, 0, reinterpret_cast<Menu<MPD::Song> *>(menu));
} }
else else

View File

@@ -27,7 +27,7 @@
namespace Display namespace Display
{ {
std::string Columns(std::string); std::string Columns();
template <typename T> void Generic(const T &t, void *, Menu<T> *menu) template <typename T> void Generic(const T &t, void *, Menu<T> *menu)
{ {

View File

@@ -1100,25 +1100,21 @@ int main(int argc, char *argv[])
if (Config.columns_in_playlist) if (Config.columns_in_playlist)
{ {
myPlaylist->Main()->SetItemDisplayer(Display::SongsInColumns); myPlaylist->Main()->SetItemDisplayer(Display::SongsInColumns);
myPlaylist->Main()->SetItemDisplayerUserData(&Config.song_columns_list_format); myPlaylist->Main()->SetTitle(Display::Columns());
myPlaylist->Main()->SetTitle(Display::Columns(Config.song_columns_list_format));
myPlaylist->Main()->SetGetStringFunction(Playlist::SongInColumnsToString); myPlaylist->Main()->SetGetStringFunction(Playlist::SongInColumnsToString);
myPlaylist->Main()->SetGetStringFunctionUserData(&Config.song_columns_list_format);
} }
else else
{ {
myPlaylist->Main()->SetItemDisplayer(Display::Songs); myPlaylist->Main()->SetItemDisplayer(Display::Songs);
myPlaylist->Main()->SetItemDisplayerUserData(&Config.song_list_format);
myPlaylist->Main()->SetTitle(""); myPlaylist->Main()->SetTitle("");
myPlaylist->Main()->SetGetStringFunction(Playlist::SongToString); myPlaylist->Main()->SetGetStringFunction(Playlist::SongToString);
myPlaylist->Main()->SetGetStringFunctionUserData(&Config.song_list_format);
} }
} }
else if (myScreen == myBrowser) else if (myScreen == myBrowser)
{ {
Config.columns_in_browser = !Config.columns_in_browser; Config.columns_in_browser = !Config.columns_in_browser;
ShowMessage("Browser display mode: %s", Config.columns_in_browser ? "Columns" : "Classic"); ShowMessage("Browser display mode: %s", Config.columns_in_browser ? "Columns" : "Classic");
myBrowser->Main()->SetTitle(Config.columns_in_browser ? Display::Columns(Config.song_columns_list_format) : ""); myBrowser->Main()->SetTitle(Config.columns_in_browser ? Display::Columns() : "");
} }
else if (myScreen == mySearcher) else if (myScreen == mySearcher)
@@ -1126,7 +1122,7 @@ int main(int argc, char *argv[])
Config.columns_in_search_engine = !Config.columns_in_search_engine; Config.columns_in_search_engine = !Config.columns_in_search_engine;
ShowMessage("Search engine display mode: %s", Config.columns_in_search_engine ? "Columns" : "Classic"); ShowMessage("Search engine display mode: %s", Config.columns_in_search_engine ? "Columns" : "Classic");
if (mySearcher->Main()->Size() > SearchEngine::StaticOptions) if (mySearcher->Main()->Size() > SearchEngine::StaticOptions)
mySearcher->Main()->SetTitle(Config.columns_in_search_engine ? Display::Columns(Config.song_columns_list_format) : ""); mySearcher->Main()->SetTitle(Config.columns_in_search_engine ? Display::Columns() : "");
} }
} }
# ifdef HAVE_CURL_CURL_H # ifdef HAVE_CURL_CURL_H

View File

@@ -47,16 +47,16 @@ size_t Playlist::SortDialogHeight;
void Playlist::Init() void Playlist::Init()
{ {
w = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist ? Display::Columns(Config.song_columns_list_format) : "", Config.main_color, brNone); w = new Menu<MPD::Song>(0, MainStartY, COLS, MainHeight, Config.columns_in_playlist ? Display::Columns() : "", Config.main_color, brNone);
w->SetTimeout(ncmpcpp_window_timeout); w->SetTimeout(ncmpcpp_window_timeout);
w->CyclicScrolling(Config.use_cyclic_scrolling); w->CyclicScrolling(Config.use_cyclic_scrolling);
w->HighlightColor(Config.main_highlight_color); w->HighlightColor(Config.main_highlight_color);
w->SetSelectPrefix(&Config.selected_item_prefix); w->SetSelectPrefix(&Config.selected_item_prefix);
w->SetSelectSuffix(&Config.selected_item_suffix); w->SetSelectSuffix(&Config.selected_item_suffix);
w->SetItemDisplayer(Config.columns_in_playlist ? Display::SongsInColumns : Display::Songs); w->SetItemDisplayer(Config.columns_in_playlist ? Display::SongsInColumns : Display::Songs);
w->SetItemDisplayerUserData(Config.columns_in_playlist ? &Config.song_columns_list_format : &Config.song_list_format); w->SetItemDisplayerUserData(&Config.song_list_format);
w->SetGetStringFunction(Config.columns_in_playlist ? SongInColumnsToString : SongToString); w->SetGetStringFunction(Config.columns_in_playlist ? SongInColumnsToString : SongToString);
w->SetGetStringFunctionUserData(Config.columns_in_playlist ? &Config.song_columns_list_format : &Config.song_list_format); w->SetGetStringFunctionUserData(&Config.song_list_format);
SortDialogHeight = std::min(int(MainHeight-2), 18); SortDialogHeight = std::min(int(MainHeight-2), 18);
@@ -105,7 +105,7 @@ void Playlist::SwitchTo()
void Playlist::Resize() void Playlist::Resize()
{ {
w->Resize(COLS, MainHeight); w->Resize(COLS, MainHeight);
w->SetTitle(Config.columns_in_playlist ? Display::Columns(Config.song_columns_list_format) : ""); w->SetTitle(Config.columns_in_playlist ? Display::Columns() : "");
SortDialogHeight = std::min(int(MainHeight-2), 18); SortDialogHeight = std::min(int(MainHeight-2), 18);
if (MainHeight > 6) if (MainHeight > 6)
SortDialog->Resize(SortDialogWidth, SortDialogHeight); SortDialog->Resize(SortDialogWidth, SortDialogHeight);
@@ -448,20 +448,19 @@ std::string Playlist::SongToString(const MPD::Song &s, void *data)
return s.toString(*static_cast<std::string *>(data)); return s.toString(*static_cast<std::string *>(data));
} }
std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *data) std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *)
{ {
std::string result; std::string result;
std::string fmt = *static_cast<std::string *>(data); for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it)
for (std::string i = GetLineValue(fmt, '{', '}', 1); !i.empty(); i = GetLineValue(fmt, '{', '}', 1))
{ {
if (i == "t") if (it->type == 't')
{ {
result += "{%t}|{%f}"; result += "{%t}|{%f}";
} }
else else
{ {
result += "%"; result += "%";
result += i; result += it->type;
} }
result += " "; result += " ";
} }

View File

@@ -195,7 +195,7 @@ void SearchEngine::EnterPressed()
if (!w->Back().first) if (!w->Back().first)
{ {
if (Config.columns_in_search_engine) if (Config.columns_in_search_engine)
w->SetTitle(Display::Columns(Config.song_columns_list_format)); w->SetTitle(Display::Columns());
size_t found = w->Size()-SearchEngine::StaticOptions; size_t found = w->Size()-SearchEngine::StaticOptions;
found += 3; // don't count options inserted below found += 3; // don't count options inserted below
w->InsertSeparator(ResetButton+1); w->InsertSeparator(ResetButton+1);
@@ -645,6 +645,6 @@ std::string SearchEngine::SearchEngineOptionToString(const std::pair<Buffer *, M
if (!Config.columns_in_search_engine) if (!Config.columns_in_search_engine)
return pair.second->toString(Config.song_list_format); return pair.second->toString(Config.song_list_format);
else else
return Playlist::SongInColumnsToString(*pair.second, &Config.song_columns_list_format); return Playlist::SongInColumnsToString(*pair.second, 0);
} }

View File

@@ -230,8 +230,8 @@ void DefaultConfiguration(ncmpcpp_config &conf)
{ {
conf.mpd_host = "localhost"; conf.mpd_host = "localhost";
conf.empty_tag = "<empty>"; conf.empty_tag = "<empty>";
conf.song_list_columns_format = "(7f)[green]{l} (25)[cyan]{a} (40)[]{t} (30)[red]{b}";
conf.song_list_format = "{%a - }{%t}|{$8%f$9}%r{$3(%l)$9}"; conf.song_list_format = "{%a - }{%t}|{$8%f$9}%r{$3(%l)$9}";
conf.song_columns_list_format = "(7)[green]{l} (25)[cyan]{a} (40)[]{t} (30)[red]{b}";
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}"; conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
conf.song_window_title_format = "{%a - }{%t}|{%f}"; conf.song_window_title_format = "{%a - }{%t}|{%f}";
conf.song_library_format = "{%n - }{%t}|{%f}"; conf.song_library_format = "{%n - }{%t}|{%f}";
@@ -453,10 +453,7 @@ void ReadConfiguration(ncmpcpp_config &conf)
std::ifstream f(config_file.c_str()); std::ifstream f(config_file.c_str());
std::string cl, v; std::string cl, v;
if (!f.is_open()) while (f.is_open() && !f.eof())
return;
while (!f.eof())
{ {
getline(f, cl); getline(f, cl);
if (!cl.empty() && cl[0] != '#') if (!cl.empty() && cl[0] != '#')
@@ -515,7 +512,7 @@ void ReadConfiguration(ncmpcpp_config &conf)
else if (cl.find("song_columns_list_format") != std::string::npos) else if (cl.find("song_columns_list_format") != std::string::npos)
{ {
if (!v.empty()) if (!v.empty())
conf.song_columns_list_format = v; conf.song_list_columns_format = v;
} }
else if (cl.find("song_status_format") != std::string::npos) else if (cl.find("song_status_format") != std::string::npos)
{ {
@@ -784,6 +781,15 @@ void ReadConfiguration(ncmpcpp_config &conf)
} }
} }
f.close(); f.close();
for (std::string width = GetLineValue(conf.song_list_columns_format, '(', ')', 1); !width.empty(); width = GetLineValue(conf.song_list_columns_format, '(', ')', 1))
{
Column col;
col.color = IntoColor(GetLineValue(conf.song_list_columns_format, '[', ']', 1));
col.type = GetLineValue(conf.song_list_columns_format, '{', '}', 1)[0];
col.fixed = *width.rbegin() == 'f';
col.width = StrToInt(width);
conf.columns.push_back(col);
}
} }

View File

@@ -22,6 +22,7 @@
#define _SETTINGS_H #define _SETTINGS_H
#include <limits> #include <limits>
#include <vector>
#include "home.h" #include "home.h"
#include "libmpdclient.h" #include "libmpdclient.h"
@@ -36,6 +37,14 @@
const std::string config_dir = home_path + HOME_FOLDER; const std::string config_dir = home_path + HOME_FOLDER;
const int null_key = std::numeric_limits<int>::max(); const int null_key = std::numeric_limits<int>::max();
struct Column
{
unsigned width;
Color color;
char type;
bool fixed;
};
struct ncmpcpp_keys struct ncmpcpp_keys
{ {
int Up[2]; int Up[2];
@@ -113,8 +122,8 @@ struct ncmpcpp_config
std::string mpd_host; std::string mpd_host;
std::string mpd_music_dir; std::string mpd_music_dir;
std::string empty_tag; std::string empty_tag;
std::string song_list_columns_format;
std::string song_list_format; std::string song_list_format;
std::string song_columns_list_format;
std::string song_status_format; std::string song_status_format;
std::string song_window_title_format; std::string song_window_title_format;
std::string song_library_format; std::string song_library_format;
@@ -125,6 +134,8 @@ struct ncmpcpp_config
std::string pattern; std::string pattern;
std::vector<Column> columns;
Buffer browser_playlist_prefix; Buffer browser_playlist_prefix;
Buffer selected_item_prefix; Buffer selected_item_prefix;
Buffer selected_item_suffix; Buffer selected_item_suffix;