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:
##
## (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 [])
##
#
#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 #####
#

View File

@@ -51,7 +51,7 @@ const char *Browser::SupportedExtensions[] =
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->SetTimeout(ncmpcpp_window_timeout);
w->CyclicScrolling(Config.use_cyclic_scrolling);
@@ -626,7 +626,7 @@ std::string Browser::ItemToString(const MPD::Item &item, void *)
if (!Config.columns_in_browser)
return item.song->toString(Config.song_list_format);
else
return Playlist::SongInColumnsToString(*item.song, &Config.song_columns_list_format);
return Playlist::SongInColumnsToString(*item.song, 0);
}
case MPD::itPlaylist:
{

View File

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

View File

@@ -27,7 +27,7 @@
namespace Display
{
std::string Columns(std::string);
std::string Columns();
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)
{
myPlaylist->Main()->SetItemDisplayer(Display::SongsInColumns);
myPlaylist->Main()->SetItemDisplayerUserData(&Config.song_columns_list_format);
myPlaylist->Main()->SetTitle(Display::Columns(Config.song_columns_list_format));
myPlaylist->Main()->SetTitle(Display::Columns());
myPlaylist->Main()->SetGetStringFunction(Playlist::SongInColumnsToString);
myPlaylist->Main()->SetGetStringFunctionUserData(&Config.song_columns_list_format);
}
else
{
myPlaylist->Main()->SetItemDisplayer(Display::Songs);
myPlaylist->Main()->SetItemDisplayerUserData(&Config.song_list_format);
myPlaylist->Main()->SetTitle("");
myPlaylist->Main()->SetGetStringFunction(Playlist::SongToString);
myPlaylist->Main()->SetGetStringFunctionUserData(&Config.song_list_format);
}
}
else if (myScreen == myBrowser)
{
Config.columns_in_browser = !Config.columns_in_browser;
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)
@@ -1126,7 +1122,7 @@ int main(int argc, char *argv[])
Config.columns_in_search_engine = !Config.columns_in_search_engine;
ShowMessage("Search engine display mode: %s", Config.columns_in_search_engine ? "Columns" : "Classic");
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

View File

@@ -47,16 +47,16 @@ size_t Playlist::SortDialogHeight;
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->CyclicScrolling(Config.use_cyclic_scrolling);
w->HighlightColor(Config.main_highlight_color);
w->SetSelectPrefix(&Config.selected_item_prefix);
w->SetSelectSuffix(&Config.selected_item_suffix);
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->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);
@@ -105,7 +105,7 @@ void Playlist::SwitchTo()
void Playlist::Resize()
{
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);
if (MainHeight > 6)
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));
}
std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *data)
std::string Playlist::SongInColumnsToString(const MPD::Song &s, void *)
{
std::string result;
std::string fmt = *static_cast<std::string *>(data);
for (std::string i = GetLineValue(fmt, '{', '}', 1); !i.empty(); i = GetLineValue(fmt, '{', '}', 1))
for (std::vector<Column>::const_iterator it = Config.columns.begin(); it != Config.columns.end(); ++it)
{
if (i == "t")
if (it->type == 't')
{
result += "{%t}|{%f}";
}
else
{
result += "%";
result += i;
result += it->type;
}
result += " ";
}

View File

@@ -195,7 +195,7 @@ void SearchEngine::EnterPressed()
if (!w->Back().first)
{
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;
found += 3; // don't count options inserted below
w->InsertSeparator(ResetButton+1);
@@ -645,6 +645,6 @@ std::string SearchEngine::SearchEngineOptionToString(const std::pair<Buffer *, M
if (!Config.columns_in_search_engine)
return pair.second->toString(Config.song_list_format);
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.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_columns_list_format = "(7)[green]{l} (25)[cyan]{a} (40)[]{t} (30)[red]{b}";
conf.song_status_format = "{(%l) }{%a - }{%t}|{%f}";
conf.song_window_title_format = "{%a - }{%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::string cl, v;
if (!f.is_open())
return;
while (!f.eof())
while (f.is_open() && !f.eof())
{
getline(f, cl);
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)
{
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)
{
@@ -784,6 +781,15 @@ void ReadConfiguration(ncmpcpp_config &conf)
}
}
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
#include <limits>
#include <vector>
#include "home.h"
#include "libmpdclient.h"
@@ -36,6 +37,14 @@
const std::string config_dir = home_path + HOME_FOLDER;
const int null_key = std::numeric_limits<int>::max();
struct Column
{
unsigned width;
Color color;
char type;
bool fixed;
};
struct ncmpcpp_keys
{
int Up[2];
@@ -113,8 +122,8 @@ struct ncmpcpp_config
std::string mpd_host;
std::string mpd_music_dir;
std::string empty_tag;
std::string song_list_columns_format;
std::string song_list_format;
std::string song_columns_list_format;
std::string song_status_format;
std::string song_window_title_format;
std::string song_library_format;
@@ -125,6 +134,8 @@ struct ncmpcpp_config
std::string pattern;
std::vector<Column> columns;
Buffer browser_playlist_prefix;
Buffer selected_item_prefix;
Buffer selected_item_suffix;