summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJinwoo Park <jinwoo@jinwoopark.id.au>2021-04-26 03:42:56 +1000
committerGitHub <noreply@github.com>2021-04-25 19:42:56 +0200
commitf47cf7f37c2bae64fc66da32c197b40ab424f4ca (patch)
tree1cc5ca2aec29224753302058d8e1101d07e4054a
parent22fd919ce48e2ff8abb739d1bf31ba827d27fe1b (diff)
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
-rw-r--r--doc/config14
-rw-r--r--doc/ncmpcpp.19
-rw-r--r--src/screens/media_library.cpp30
-rw-r--r--src/screens/playlist_editor.cpp15
-rw-r--r--src/settings.cpp7
-rw-r--r--src/settings.h4
-rw-r--r--src/utility/option_parser.cpp14
-rw-r--r--src/utility/option_parser.h15
8 files changed, 93 insertions, 15 deletions
diff --git a/doc/config b/doc/config
index 57c8f9a9..23720fc7 100644
--- a/doc/config
+++ b/doc/config
@@ -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
diff --git a/doc/ncmpcpp.1 b/doc/ncmpcpp.1
index ff2669ac..e1889f80 100644
--- a/doc/ncmpcpp.1
+++ b/doc/ncmpcpp.1
@@ -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
diff --git a/src/screens/media_library.cpp b/src/screens/media_library.cpp
index 558458d0..df2b5866 100644
--- a/src/screens/media_library.cpp
+++ b/src/screens/media_library.cpp
@@ -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;
}
diff --git a/src/screens/playlist_editor.cpp b/src/screens/playlist_editor.cpp
index 1c00d3b4..7729fdc3 100644
--- a/src/screens/playlist_editor.cpp
+++ b/src/screens/playlist_editor.cpp
@@ -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);
diff --git a/src/settings.cpp b/src/settings.cpp
index f0032683..6fd3558b 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -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")
diff --git a/src/settings.h b/src/settings.h
index b8079ade..bc22b588 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -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;
diff --git a/src/utility/option_parser.cpp b/src/utility/option_parser.cpp
index 826ed937..316d91a2 100644
--- a/src/utility/option_parser.cpp
+++ b/src/utility/option_parser.cpp
@@ -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)
diff --git a/src/utility/option_parser.h b/src/utility/option_parser.h
index b68fd2ab..86b944e7 100644
--- a/src/utility/option_parser.h
+++ b/src/utility/option_parser.h
@@ -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