diff options
author | Jinwoo Park <jinwoo@jinwoopark.id.au> | 2021-04-26 03:42:56 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-25 19:42:56 +0200 |
commit | f47cf7f37c2bae64fc66da32c197b40ab424f4ca (patch) | |
tree | 1cc5ca2aec29224753302058d8e1101d07e4054a | |
parent | 22fd919ce48e2ff8abb739d1bf31ba827d27fe1b (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/config | 14 | ||||
-rw-r--r-- | doc/ncmpcpp.1 | 9 | ||||
-rw-r--r-- | src/screens/media_library.cpp | 30 | ||||
-rw-r--r-- | src/screens/playlist_editor.cpp | 15 | ||||
-rw-r--r-- | src/settings.cpp | 7 | ||||
-rw-r--r-- | src/settings.h | 4 | ||||
-rw-r--r-- | src/utility/option_parser.cpp | 14 | ||||
-rw-r--r-- | src/utility/option_parser.h | 15 |
8 files changed, 93 insertions, 15 deletions
@@ -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 "e) { 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 |