Configurable Column Widths (#360)

* add configurable column widths

* reorder to match config file

* fix possibly misleading documentation

* fix crash when integer out of bounds

* parse config string during initial processing

* use std::bind with length of list

* fix division by zero error

* use list_of

* change escaped_list_separator variable names
This commit is contained in:
Jinwoo Park
2021-04-26 03:42:56 +10:00
committed by GitHub
parent 22fd919ce4
commit f47cf7f37c
8 changed files with 93 additions and 15 deletions

View File

@@ -465,6 +465,20 @@
#
#ask_for_locked_screen_width_part = yes
#
##
## Width of media_library screen columns
##
#
#media_library_column_width_ratio_two = 1:1
#
#media_library_column_width_ratio_three = 1:1:1
#
##
## Width of playlist_editor screen columns
##
#
#playlist_editor_column_width_ratio = 1:2
#
#jump_to_now_playing_song_at_start = yes
#
#ask_before_clearing_playlists = yes

View File

@@ -335,6 +335,15 @@ If you want to lock a screen, ncmpcpp asks for % of locked screen's width to be
.B ask_for_locked_screen_width_part = yes/no
If enabled, ncmpcpp will ask for % of locked screen's width each time you want to lock a screen. If you disable that, it'll silently attempt to use default value.
.TP
.B media_library_column_width_ratio_two = a:b
The ratio of the column widths in the media library, when there are two columns.
.TP
.B media_library_column_width_ratio_three = a:b:c
The ratio of the column widths in the media library, when there are three columns.
.TP
.B playlist_editor_column_width_ratio = a:b
The ratio of the column widths in the playlist editor.
.TP
.B jump_to_now_playing_song_at_start = yes/no
If enabled, ncmpcpp will jump at start to now playing song if mpd is playing or paused.
.TP

View File

@@ -191,11 +191,16 @@ MediaLibrary::MediaLibrary()
{
hasTwoColumns = 0;
isAlbumOnly = 0;
itsLeftColWidth = COLS/3-1;
itsMiddleColWidth = COLS/3;
size_t ra = Config.media_library_column_width_ratio_three[0];
size_t rb = Config.media_library_column_width_ratio_three[1];
size_t rc = Config.media_library_column_width_ratio_three[2];
itsLeftColWidth = COLS*ra/(ra+rb+rc)-1;
itsMiddleColStartX = itsLeftColWidth+1;
itsRightColWidth = COLS-COLS/3*2-1;
itsRightColStartX = itsLeftColWidth+itsMiddleColWidth+2;
itsMiddleColWidth = COLS*rb/(ra+rb+rc);
itsRightColStartX = itsMiddleColStartX+itsMiddleColWidth+1;
itsRightColWidth = COLS-itsLeftColWidth-itsMiddleColWidth-2;
Tags = NC::Menu<PrimaryTag>(0, MainStartY, itsLeftColWidth, MainHeight, Config.titles_visibility ? tagTypeToString(Config.media_lib_primary_tag) + "s" : "", Config.main_color, NC::Border());
setHighlightFixes(Tags);
@@ -240,18 +245,25 @@ void MediaLibrary::resize()
getWindowResizeParams(x_offset, width);
if (!hasTwoColumns)
{
size_t ra = Config.media_library_column_width_ratio_three[0];
size_t rb = Config.media_library_column_width_ratio_three[1];
size_t rc = Config.media_library_column_width_ratio_three[2];
itsLeftColStartX = x_offset;
itsLeftColWidth = width/3-1;
itsLeftColWidth = width*ra/(ra+rb+rc)-1;
itsMiddleColStartX = itsLeftColStartX+itsLeftColWidth+1;
itsMiddleColWidth = width/3;
itsMiddleColWidth = width*rb/(ra+rb+rc);
itsRightColStartX = itsMiddleColStartX+itsMiddleColWidth+1;
itsRightColWidth = width-width/3*2-1;
itsRightColWidth = width-itsLeftColWidth-itsMiddleColWidth-2;
}
else
{
size_t ra = Config.media_library_column_width_ratio_two[0];
size_t rb = Config.media_library_column_width_ratio_two[1];
itsMiddleColStartX = x_offset;
itsMiddleColWidth = width/2;
itsRightColStartX = x_offset+itsMiddleColWidth+1;
itsMiddleColWidth = width*ra/(ra+rb);
itsRightColStartX = itsMiddleColStartX+itsMiddleColWidth+1;
itsRightColWidth = width-itsMiddleColWidth-1;
}

View File

@@ -66,10 +66,14 @@ PlaylistEditor::PlaylistEditor()
, m_window_timeout(Config.data_fetching_delay ? 250 : BaseScreen::defaultWindowTimeout)
, m_fetching_delay(boost::posix_time::milliseconds(Config.data_fetching_delay ? 250 : -1))
{
LeftColumnWidth = COLS/3-1;
size_t ra = Config.playlist_editor_column_width_ratio[0];
size_t rb = Config.playlist_editor_column_width_ratio[1];
LeftColumnWidth = COLS*ra/(ra+rb)-1;
RightColumnStartX = LeftColumnWidth+1;
RightColumnWidth = COLS-LeftColumnWidth-1;
Playlists = NC::Menu<MPD::Playlist>(0, MainStartY, LeftColumnWidth, MainHeight, Config.titles_visibility ? "Playlists" : "", Config.main_color, NC::Border());
setHighlightFixes(Playlists);
Playlists.cyclicScrolling(Config.use_cyclic_scrolling);
@@ -108,11 +112,14 @@ void PlaylistEditor::resize()
size_t x_offset, width;
getWindowResizeParams(x_offset, width);
size_t ra = Config.playlist_editor_column_width_ratio[0];
size_t rb = Config.playlist_editor_column_width_ratio[1];
LeftColumnStartX = x_offset;
LeftColumnWidth = width/3-1;
LeftColumnWidth = width*ra/(ra+rb)-1;
RightColumnStartX = LeftColumnStartX+LeftColumnWidth+1;
RightColumnWidth = width-LeftColumnWidth-1;
Playlists.resize(LeftColumnWidth, MainHeight);
Content.resize(RightColumnWidth, MainHeight);

View File

@@ -534,6 +534,12 @@ bool Configuration::read(const std::vector<std::string> &config_paths, bool igno
});
p.add("ask_for_locked_screen_width_part", &ask_for_locked_screen_width_part,
"yes", yes_no);
p.add("media_library_column_width_ratio_two", &media_library_column_width_ratio_two,
"1:1", std::bind(parse_ratio, ph::_1, 2));
p.add("media_library_column_width_ratio_three", &media_library_column_width_ratio_three,
"1:1:1", std::bind(parse_ratio, ph::_1, 3));
p.add("playlist_editor_column_width_ratio", &playlist_editor_column_width_ratio,
"1:2", std::bind(parse_ratio, ph::_1, 2));
p.add("jump_to_now_playing_song_at_start", &jump_to_now_playing_song_at_start,
"yes", yes_no);
p.add("ask_before_clearing_playlists", &ask_before_clearing_playlists,
@@ -549,6 +555,7 @@ bool Configuration::read(const std::vector<std::string> &config_paths, bool igno
return boost::regex::icase | boost::regex::literal;
else if (v == "basic")
return boost::regex::icase | boost::regex::basic;
else if (v == "extended")
return boost::regex::icase | boost::regex::extended;
else if (v == "perl")

View File

@@ -93,6 +93,10 @@ struct Configuration
std::string pattern;
std::vector<size_t> playlist_editor_column_width_ratio;
std::vector<size_t> media_library_column_width_ratio_two;
std::vector<size_t> media_library_column_width_ratio_three;
std::vector<Column> columns;
DisplayMode playlist_display_mode;

View File

@@ -45,6 +45,20 @@ bool yes_no(const std::string &v)
invalid_value(v);
}
std::vector<size_t> parse_ratio(const std::string &v, const std::vector<size_t>::size_type length)
{
std::vector<size_t> ret = list_of<size_t>(v, verbose_lexical_cast<size_t>, length, "", ":", "");
size_t total = 0;
for (auto i : ret)
total += i;
if (total == 0)
invalid_value(v);
return ret;
}
////////////////////////////////////////////////////////////////////////////////
bool option_parser::run(std::istream &is, bool ignore_errors)

View File

@@ -56,17 +56,26 @@ DestT verbose_lexical_cast(const std::string &v)
}
template <typename ValueT, typename ConvertT>
std::vector<ValueT> list_of(const std::string &v, ConvertT convert)
std::vector<ValueT> list_of(const std::string &v, ConvertT convert, const typename std::vector<ValueT>::size_type length, const std::string &escape, const std::string &sep, const std::string &quote)
{
std::vector<ValueT> result;
boost::tokenizer<boost::escaped_list_separator<char>> elems(v);
boost::escaped_list_separator<char> esq(escape, sep, quote);
boost::tokenizer<boost::escaped_list_separator<char>> elems(v, esq);
for (auto &value : elems)
result.push_back(convert(boost::trim_copy(value)));
if (result.empty())
throw std::runtime_error("empty list");
if (length > 0 && result.size() != length)
throw std::runtime_error("invalid list length");
return result;
}
template <typename ValueT, typename ConvertT>
std::vector<ValueT> list_of(const std::string &v, ConvertT convert)
{
return list_of<ValueT>(v, convert, 0, "\\", ",", "\"");
}
template <typename ValueT>
std::vector<ValueT> list_of(const std::string &v)
{
@@ -75,6 +84,8 @@ std::vector<ValueT> list_of(const std::string &v)
bool yes_no(const std::string &v);
std::vector<size_t> parse_ratio(const std::string &v, const std::vector<size_t>::size_type length);
////////////////////////////////////////////////////////////////////////////////
class option_parser