diff --git a/doc/ncmpcpprc b/doc/ncmpcpprc index 571a3dfe..632c38ad 100644 --- a/doc/ncmpcpprc +++ b/doc/ncmpcpprc @@ -40,6 +40,7 @@ ## %p - performer ## %d - disc ## %C - comment +## %r - begin right align ## ## you can also put them in { } and then it will be displayed ## only if all requested values are available and/or define alternate diff --git a/src/helpers.cpp b/src/helpers.cpp index 6210e1c3..02a0e9a3 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -215,12 +215,12 @@ string TotalPlaylistLength() return result; } -string DisplayStringPair(const StringPair &pair, void *null) +string DisplayStringPair(const StringPair &pair, void *, const Menu *) { return pair.first; } -string DisplayItem(const Item &item, void *) +string DisplayItem(const Item &item, void *, const Menu *menu) { switch (item.type) { @@ -232,7 +232,8 @@ string DisplayItem(const Item &item, void *) return "[" + (slash != string::npos ? item.name.substr(slash+1) : item.name) + "]"; } case itSong: - return DisplaySong(*item.song); + // I know casting that way is ugly etc., but it works. + return DisplaySong(*item.song, &Config.song_list_format, (const Menu *)menu); case itPlaylist: return Config.browser_playlist_prefix + item.name; } @@ -310,7 +311,7 @@ string DisplayColumns(string song_template) return result.substr(0, COLS); } -string DisplaySongInColumns(const Song &s, void *s_template) +string DisplaySongInColumns(const Song &s, void *s_template, const Menu *) { string song_template = s_template ? *static_cast(s_template) : ""; @@ -402,12 +403,14 @@ string DisplaySongInColumns(const Song &s, void *s_template) return TO_STRING(result); } -string DisplaySong(const Song &s, void *s_template) +string DisplaySong(const Song &s, void *s_template, const Menu *menu) { const string &song_template = s_template ? *static_cast(s_template) : ""; string result; + string lresult; bool link_tags = 0; bool tags_present = 0; + bool right = 0; int i = 0; for (string::const_iterator it = song_template.begin(); it != song_template.end(); it++) @@ -656,10 +659,24 @@ string DisplaySong(const Song &s, void *s_template) result += s.GetTitle(); break; } + case 'r': + { + if (!right) + { + right = 1; + lresult = result; + result = ""; + i = 0; + } + } } } } + if (right && menu) + { + result = lresult + "[." + IntoStr(menu->GetWidth()-Window::RealLength(result)) + "]" + result; + } return result; } diff --git a/src/helpers.h b/src/helpers.h index 132c0472..2bf08630 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -48,11 +48,11 @@ bool Keypressed(int, const int *); void WindowTitle(const string &); string TotalPlaylistLength(); -string DisplayStringPair(const StringPair &, void * = NULL); -string DisplayItem(const Item &, void * = NULL); +string DisplayStringPair(const StringPair &, void *, const Menu *); +string DisplayItem(const Item &, void *, const Menu *); string DisplayColumns(string); -string DisplaySongInColumns(const Song &, void *); -string DisplaySong(const Song &, void * = &Config.song_list_format); +string DisplaySongInColumns(const Song &, void *, const Menu *); +string DisplaySong(const Song &, void * = &Config.song_list_format, const Menu * = NULL); string GetInfo(Song &); void ShowMessage(const string &, int = Config.message_delay_time); void GetDirectory(string, string = "/"); diff --git a/src/menu.h b/src/menu.h index 21638aea..be198c2a 100644 --- a/src/menu.h +++ b/src/menu.h @@ -45,7 +45,7 @@ class Menu : public Window { typedef typename vector *>::iterator T_iterator; typedef typename vector *>::const_iterator T_const_iterator; - typedef string (*ItemDisplayer) (const T &, void *); + typedef string (*ItemDisplayer) (const T &, void *, const Menu *); public: Menu(int startx, int starty, int width, int height, string title, Color color, Border border) : itsItemDisplayer(0), itsItemDisplayerUserdata(0), Window(startx, starty, width, height, title, color, border), itsSelectedPrefix("[.r]"), itsSelectedSuffix("[/r]"), itsStaticsNumber(0), itsBeginning(0), itsHighlight(0), itsHighlightColor(itsBaseColor), itsHighlightEnabled(1) { } @@ -100,6 +100,7 @@ class Menu : public Window const T & at(int i) const { return itsOptions.at(i)->item; } const T & operator[](int i) const { return itsOptions[i]->item; } T & operator[](int i) { return itsOptions[i]->item; } + protected: string DisplayOption(const T &t) const; ItemDisplayer itsItemDisplayer; @@ -112,7 +113,6 @@ class Menu : public Window string itsSelectedSuffix; int itsStaticsNumber; - int count_length(string); void redraw_screen(); bool is_static() { return itsOptions[itsHighlight]->is_static; } @@ -152,49 +152,6 @@ Menu::~Menu() delete *it; } -template -int Menu::count_length(string str) -{ - if (str.empty()) - return 0; - - bool collect = false; - int length = 0; - -#ifdef UTF8_ENABLED - wstring str2 = ToWString(str); - wstring tmp; -#else - string &str2 = str; - string tmp; -#endif - - for (int i = 0; i < str2.length(); i++, length++) - { - if (str2[i] == '[' && (str2[i+1] == '.' || str2[i+1] == '/')) - collect = 1; - - if (collect) - { - if (str2[i] != '[') - tmp += str2[i]; - else - tmp = str2[i]; - } - - if (str2[i] == ']') - collect = 0; - - if (!collect && !tmp.empty()) - { - if (IsValidColor(TO_STRING(tmp))) - length -= tmp.length(); - tmp.clear(); - } - } - return length; -} - template void Menu::AddOption(const T &item, bool bold, bool is_static, bool separator, Location location) { @@ -399,7 +356,7 @@ void Menu::Refresh(bool redraw_whole_window) string option = DisplayOption(itsOptions[*it]->item); - int strlength = itsOptions[*it]->location != lLeft && BBEnabled ? count_length(option) : option.length(); + int strlength = itsOptions[*it]->location != lLeft && BBEnabled ? Window::RealLength(option) : option.length(); if (strlength) { @@ -733,7 +690,7 @@ Window * Menu::EmptyClone() const template string Menu::DisplayOption(const T &t) const { - return itsItemDisplayer ? itsItemDisplayer(t, itsItemDisplayerUserdata) : ""; + return itsItemDisplayer ? itsItemDisplayer(t, itsItemDisplayerUserdata, this) : ""; } template <> diff --git a/src/search_engine.cpp b/src/search_engine.cpp index 99fc2784..a5683c74 100644 --- a/src/search_engine.cpp +++ b/src/search_engine.cpp @@ -28,7 +28,7 @@ extern Menu< std::pair > *mSearcher; bool search_match_to_pattern = 1; bool search_case_sensitive = 1; -string SearchEngineDisplayer(const std::pair &pair, void *null) +string SearchEngineDisplayer(const std::pair &pair, void *, const Menu< std::pair > *) { return pair.first == "." ? DisplaySong(pair.second) : pair.first; } diff --git a/src/search_engine.h b/src/search_engine.h index 40d50a90..9ff0121c 100644 --- a/src/search_engine.h +++ b/src/search_engine.h @@ -26,7 +26,7 @@ const int search_engine_static_options = 17; -string SearchEngineDisplayer(const std::pair &, void * = NULL); +string SearchEngineDisplayer(const std::pair &, void *, const Menu< std::pair > *); void UpdateFoundList(); void PrepareSearchEngine(Song &s); void Search(Song &); diff --git a/src/tag_editor.cpp b/src/tag_editor.cpp index f67c396e..f68fcbe2 100644 --- a/src/tag_editor.cpp +++ b/src/tag_editor.cpp @@ -60,7 +60,7 @@ string FindSharedDir(const SongList &v) return result; } -string DisplayTag(const Song &s, void *data) +string DisplayTag(const Song &s, void *data, const Menu *null) { switch (static_cast *>(data)->GetChoice()) { diff --git a/src/tag_editor.h b/src/tag_editor.h index aa46a540..1f5f62ec 100644 --- a/src/tag_editor.h +++ b/src/tag_editor.h @@ -36,7 +36,7 @@ typedef void (Song::*SongSetFunction)(const string &); string FindSharedDir(Menu *); string FindSharedDir(const SongList &); -string DisplayTag(const Song &, void *); +string DisplayTag(const Song &, void *, const Menu *); bool GetSongTags(Song &); bool WriteTags(Song &); diff --git a/src/window.cpp b/src/window.cpp index cc285ed5..51279915 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -740,6 +740,48 @@ string Window::OmitBBCodes(const string &str) return result; } +int Window::RealLength(const string &str) +{ + if (str.empty()) + return 0; + + bool collect = false; + int length = 0; + +#ifdef UTF8_ENABLED + wstring str2 = ToWString(str); + wstring tmp; +#else + const string &str2 = str; + string tmp; +#endif + + for (int i = 0; i < str2.length(); i++, length++) + { + if (str2[i] == '[' && (str2[i+1] == '.' || str2[i+1] == '/')) + collect = 1; + + if (collect) + { + if (str2[i] != '[') + tmp += str2[i]; + else + tmp = str2[i]; + } + + if (str2[i] == ']') + collect = 0; + + if (!collect && !tmp.empty()) + { + if (isdigit(tmp[2]) || IsValidColor(TO_STRING(tmp))) + length -= tmp.length(); + tmp.clear(); + } + } + return length; +} + /*int CountBBCodes(const string &str) { if (str.empty()) diff --git a/src/window.h b/src/window.h index 8e1d4431..2f7b3083 100644 --- a/src/window.h +++ b/src/window.h @@ -130,6 +130,7 @@ class Window static Coordinates IntoCoordinates(const string &); static bool IsValidColor(const string &); static string OmitBBCodes(const string &); + static int RealLength(const string &); protected: virtual void Recreate();