mpris: Add dynamic-order and dynamic-separator

This commit allows better handling of ordering and exclusion of the tags in Dynamics tags.
It also becomes possible to choose the separator between the tags.
This commit is contained in:
Erik Rodriguez 2023-06-02 16:14:28 -03:00
parent ca52892ab9
commit 77a8420aaf
No known key found for this signature in database
GPG Key ID: 5979ED35ED299E6D
3 changed files with 91 additions and 24 deletions

View File

@ -66,6 +66,8 @@ class Mpris : public ALabel {
int album_len_;
int title_len_;
int dynamic_len_;
std::string dynamic_separator_;
std::vector<std::string> dynamic_order_;
std::vector<std::string> dynamic_prio_;
bool truncate_hours_;
bool tooltip_len_limits_;

View File

@ -71,12 +71,27 @@ The *mpris* module displays currently playing media via libplayerctl.
something less than or equal to this value, so the title will always be ++
displayed.
*dynamic-order*: ++
typeof: []string ++
default: ["title", "artist", "album", "position", "length"] ++
Order of the tags shown by Dynamic tag. The position and length tags ++
will always be combined in the format [{position}/{length}]. The order ++
of these tags in relation to other tags will be determined based on the ++
declaration of the first among the two tags. Absence in this list means ++
force exclusion.
*dynamic-priority*: ++
typeof: []string ++
default: ["title", "length", "position", "artist", "album"] ++
Priority of the tags when truncating the Dynamic tag (absence in this
list means force inclusion).
*dynamic-separator*: ++
typeof: string ++
default: " - " ++
These characters will be used to separate two different tags, except ++
when one of these tags is position and length.
*truncate-hours*: ++
typeof: bool ++
default: true ++

View File

@ -24,7 +24,9 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
album_len_(-1),
title_len_(-1),
dynamic_len_(-1),
dynamic_prio_({"title", "length", "position", "artist", "album"}),
dynamic_prio_({"title", "artist", "album", "position", "length"}),
dynamic_order_({"title", "artist", "album", "position", "length"}),
dynamic_separator_(" - "),
truncate_hours_(true),
tooltip_len_limits_(false),
// this character is used in Gnome so it's fine to use it here
@ -44,6 +46,9 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
if (config_["ellipsis"].isString()) {
ellipsis_ = config_["ellipsis"].asString();
}
if (config_["dynamic-separator"].isString()) {
dynamic_separator_ = config_["dynamic-separator"].asString();
}
if (tooltipEnabled()) {
if (config_["tooltip-format"].isString()) {
tooltip_ = config_["tooltip-format"].asString();
@ -83,6 +88,14 @@ Mpris::Mpris(const std::string& id, const Json::Value& config)
}
}
}
if (config_["dynamic-order"].isArray()) {
dynamic_order_.clear();
for (auto it = config_["dynamic-order"].begin(); it != config_["dynamic-order"].end(); ++it) {
if (it->isString()) {
dynamic_order_.push_back(it->asString());
}
}
}
if (config_["truncate-hours"].isBool()) {
truncate_hours_ = config["truncate-hours"].asBool();
@ -272,18 +285,28 @@ auto Mpris::getDynamicStr(const PlayerInfo& info, bool truncated, bool html) ->
size_t lengthLen = length.length();
size_t posLen = position.length();
bool showArtist = artistLen != 0;
bool showAlbum = albumLen != 0;
bool showTitle = titleLen != 0;
bool showLength = lengthLen != 0;
bool showPos = posLen != 0;
bool showArtist = (artistLen != 0) && (std::find(dynamic_order_.begin(), dynamic_order_.end(),
"artist") != dynamic_order_.end());
bool showAlbum = (albumLen != 0) && (std::find(dynamic_order_.begin(), dynamic_order_.end(),
"album") != dynamic_order_.end());
bool showTitle = (titleLen != 0) && (std::find(dynamic_order_.begin(), dynamic_order_.end(),
"title") != dynamic_order_.end());
bool showLength = (lengthLen != 0) && (std::find(dynamic_order_.begin(), dynamic_order_.end(),
"length") != dynamic_order_.end());
bool showPos = (posLen != 0) && (std::find(dynamic_order_.begin(), dynamic_order_.end(),
"position") != dynamic_order_.end());
if (truncated && dynamic_len_ >= 0) {
size_t dynamicLen = dynamic_len_;
if (showArtist) artistLen += 3;
if (showAlbum) albumLen += 3;
if (showLength) lengthLen += 3;
if (showPos) posLen += 3;
//Since the first element doesn't present a separator and we don't know a priori which one
//it will be, we add a "virtual separatorLen" to the dynamicLen, since we are adding the
//separatorLen to all the other lengths.
size_t separatorLen = utf8_width(dynamic_separator_);
size_t dynamicLen = dynamic_len_ + separatorLen;
if (showArtist) artistLen += separatorLen;
if (showAlbum) albumLen += separatorLen;
if (showTitle) albumLen += separatorLen;
if (showLength) lengthLen += separatorLen;
if (showPos) posLen += separatorLen;
size_t totalLen = 0;
@ -330,12 +353,34 @@ auto Mpris::getDynamicStr(const PlayerInfo& info, bool truncated, bool html) ->
album = Glib::Markup::escape_text(album);
title = Glib::Markup::escape_text(title);
}
if (showArtist) dynamic << artist << " - ";
if (showAlbum) dynamic << album << " - ";
if (showTitle) dynamic << title;
if (showLength || showPos) {
dynamic << ' ';
bool lengthOrPositionShown = false;
bool previousShown = false;
std::string previousOrder = "";
for (const std::string& order : dynamic_order_) {
if ((order == "artist" && showArtist) ||
(order == "album" && showAlbum) ||
(order == "title" && showTitle)) {
if (previousShown &&
previousOrder != "length" &&
previousOrder != "position") {
dynamic << dynamic_separator_;
}
if (order == "artist") {
dynamic << artist;
} else if (order == "album") {
dynamic << album;
} else if (order == "title") {
dynamic << title;
}
previousShown = true;
} else if (order == "length" || order == "position") {
if (!lengthOrPositionShown && (showLength || showPos)) {
if (html) dynamic << "<small>";
if (previousShown) dynamic << ' ';
dynamic << '[';
if (showPos) {
dynamic << position;
@ -343,7 +388,12 @@ auto Mpris::getDynamicStr(const PlayerInfo& info, bool truncated, bool html) ->
}
if (showLength) dynamic << length;
dynamic << ']';
if (!dynamic.str().empty()) dynamic << ' ';
if (html) dynamic << "</small>";
lengthOrPositionShown = true;
}
}
previousOrder = order;
}
return dynamic.str();
}