mirror of https://github.com/polybar/polybar.git
100 lines
3.1 KiB
C++
100 lines
3.1 KiB
C++
#include "drawtypes/layouticonset.hpp"
|
|
|
|
POLYBAR_NS
|
|
|
|
namespace drawtypes {
|
|
layouticonset::layouticonset(label_t&& default_icon) : m_default_icon(default_icon) {}
|
|
|
|
bool layouticonset::add(const string& layout, const string& variant, label_t&& icon) {
|
|
if (layout == VARIANT_ANY && variant == VARIANT_ANY) {
|
|
return false;
|
|
}
|
|
m_layout_icons.emplace_back(layout, variant, icon);
|
|
return true;
|
|
}
|
|
|
|
label_t layouticonset::get(const string& layout, const string& variant) const {
|
|
// The layout, variant are matched against defined icons in that order:
|
|
// 1. perfect match on layout and perfect match on variant (ex: us;Colemak;<icon>)
|
|
// 2. perfect match on layout and case insensitive search on variant (ex: us;coLEmAk;<icon>)
|
|
// 3. perfect match on layout and the any variant '_' (ex: us;<icon> or us;_;<icon>)
|
|
// 4. any layout for icon and perfect match on variant (ex: _;Colemak;<icon>)
|
|
// 5. any layout for icon and case insensitive search on variant (ex: _;coLEmAk;<icon>)
|
|
// 6. no match at all => default icon if defined
|
|
|
|
/*
|
|
* The minimal case that was matched.
|
|
* Once a case is matched, this is updated and no case with the same or higher number can be matched again.
|
|
*/
|
|
int min_case = 6;
|
|
|
|
// Case 6: initializing with default
|
|
label_t icon = m_default_icon;
|
|
|
|
for (auto it : m_layout_icons) {
|
|
const string& icon_layout = std::get<0>(it);
|
|
const string& icon_variant = std::get<1>(it);
|
|
label_t icon_label = std::get<2>(it);
|
|
|
|
bool is_variant_match = icon_variant == variant;
|
|
|
|
bool is_variant_any = icon_variant == VARIANT_ANY;
|
|
|
|
bool is_variant_match_fuzzy =
|
|
!is_variant_any && !icon_variant.empty() && string_util::contains_ignore_case(variant, icon_variant);
|
|
|
|
// Which of the 6 match cases is matched here.
|
|
int current_case = 6;
|
|
|
|
if (icon_layout == layout) {
|
|
if (is_variant_match) {
|
|
// Case 1
|
|
current_case = 1;
|
|
} else if (is_variant_match_fuzzy) {
|
|
// Case 2
|
|
current_case = 2;
|
|
} else if (is_variant_any) {
|
|
// Case 3
|
|
current_case = 3;
|
|
}
|
|
} else if (icon_layout == VARIANT_ANY) {
|
|
if (is_variant_match) {
|
|
// Case 4
|
|
current_case = 4;
|
|
} else if (is_variant_match_fuzzy) {
|
|
// Case 5
|
|
current_case = 5;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* We matched with a higher priority than before -> update icon.
|
|
*/
|
|
if (current_case < min_case) {
|
|
icon = icon_label;
|
|
min_case = current_case;
|
|
}
|
|
|
|
if (current_case == 1) {
|
|
// Case 1: perfect match, we can break early
|
|
break;
|
|
}
|
|
}
|
|
|
|
return icon;
|
|
}
|
|
|
|
bool layouticonset::contains(const string& layout, const string& variant) const {
|
|
for (auto it : m_layout_icons) {
|
|
const string& icon_layout = std::get<0>(it);
|
|
const string& icon_variant = std::get<1>(it);
|
|
if (icon_layout == layout && icon_variant == variant) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
} // namespace drawtypes
|
|
|
|
POLYBAR_NS_END
|