2016-11-25 12:55:15 +00:00
|
|
|
#include <utility>
|
|
|
|
|
2016-11-20 22:04:31 +00:00
|
|
|
#include "components/types.hpp"
|
2016-11-24 18:24:47 +00:00
|
|
|
#include "x11/color.hpp"
|
2016-11-20 22:04:31 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
#include "drawtypes/progressbar.hpp"
|
|
|
|
#include "utils/math.hpp"
|
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS
|
2016-11-02 19:22:45 +00:00
|
|
|
|
|
|
|
namespace drawtypes {
|
2016-11-25 12:55:15 +00:00
|
|
|
progressbar::progressbar(const bar_settings& bar, int width, string format)
|
|
|
|
: m_builder(make_unique<builder>(bar)), m_format(move(format)), m_width(width) {}
|
2016-11-24 18:24:47 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
void progressbar::set_fill(icon_t&& fill) {
|
|
|
|
m_fill = forward<decltype(fill)>(fill);
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressbar::set_empty(icon_t&& empty) {
|
|
|
|
m_empty = forward<decltype(empty)>(empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressbar::set_indicator(icon_t&& indicator) {
|
2016-11-25 12:55:15 +00:00
|
|
|
if (!m_indicator && indicator.get()) {
|
2016-11-02 19:22:45 +00:00
|
|
|
m_width--;
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
m_indicator = forward<decltype(indicator)>(indicator);
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressbar::set_gradient(bool mode) {
|
|
|
|
m_gradient = mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressbar::set_colors(vector<string>&& colors) {
|
|
|
|
m_colors = forward<decltype(colors)>(colors);
|
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
if (m_colors.empty()) {
|
2016-11-02 19:22:45 +00:00
|
|
|
m_colorstep = 1;
|
2016-11-25 12:55:15 +00:00
|
|
|
} else {
|
2016-11-02 19:22:45 +00:00
|
|
|
m_colorstep = m_width / m_colors.size();
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string progressbar::output(float percentage) {
|
|
|
|
string output{m_format};
|
|
|
|
|
|
|
|
// Get fill/empty widths based on percentage
|
|
|
|
unsigned int perc = math_util::cap(percentage, 0.0f, 100.0f);
|
|
|
|
unsigned int fill_width = math_util::percentage_to_value(perc, m_width);
|
|
|
|
unsigned int empty_width = m_width - fill_width;
|
|
|
|
|
|
|
|
// Output fill icons
|
|
|
|
fill(perc, fill_width);
|
|
|
|
output = string_util::replace_all(output, "%fill%", m_builder->flush());
|
|
|
|
|
|
|
|
// Output indicator icon
|
|
|
|
m_builder->node(m_indicator);
|
|
|
|
output = string_util::replace_all(output, "%indicator%", m_builder->flush());
|
|
|
|
|
|
|
|
// Output empty icons
|
2016-11-25 12:55:15 +00:00
|
|
|
while (empty_width--) {
|
|
|
|
m_builder->node(m_empty);
|
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
output = string_util::replace_all(output, "%empty%", m_builder->flush());
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
void progressbar::fill(unsigned int perc, unsigned int fill_width) {
|
|
|
|
if (m_colors.empty()) {
|
|
|
|
for (size_t i = 0; i < fill_width; i++) {
|
|
|
|
m_builder->node(m_fill);
|
|
|
|
}
|
|
|
|
} else if (m_gradient) {
|
|
|
|
size_t color = 0;
|
|
|
|
for (size_t i = 0; i < fill_width; i++) {
|
2016-11-25 12:55:15 +00:00
|
|
|
if (i % m_colorstep == 0 && color < m_colors.size()) {
|
2016-11-02 19:22:45 +00:00
|
|
|
m_fill->m_foreground = m_colors[color++];
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
m_builder->node(m_fill);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
size_t color = math_util::percentage_to_value<size_t>(perc, m_colors.size() - 1);
|
|
|
|
m_fill->m_foreground = m_colors[color];
|
|
|
|
for (size_t i = 0; i < fill_width; i++) {
|
|
|
|
m_builder->node(m_fill);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a progressbar by loading values
|
|
|
|
* from the configuration
|
|
|
|
*/
|
2016-11-25 12:55:15 +00:00
|
|
|
progressbar_t load_progressbar(const bar_settings& bar, const config& conf, const string& section, string name) {
|
2016-11-02 19:22:45 +00:00
|
|
|
// Remove the start and end tag from the name in case a format tag is passed
|
|
|
|
name = string_util::ltrim(string_util::rtrim(name, '>'), '<');
|
|
|
|
|
|
|
|
string format = "%fill%%indicator%%empty%";
|
|
|
|
unsigned int width;
|
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
if ((format = conf.get<decltype(format)>(section, name + "-format", format)).empty()) {
|
2016-11-02 19:22:45 +00:00
|
|
|
throw application_error("Invalid format defined at [" + conf.build_path(section, name) + "]");
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
|
|
|
if ((width = conf.get<decltype(width)>(section, name + "-width")) < 1) {
|
2016-11-02 19:22:45 +00:00
|
|
|
throw application_error("Invalid width defined at [" + conf.build_path(section, name) + "]");
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
|
|
|
|
progressbar_t progressbar{new progressbar_t::element_type(bar, width, format)};
|
|
|
|
progressbar->set_gradient(conf.get<bool>(section, name + "-gradient", true));
|
|
|
|
progressbar->set_colors(conf.get_list<string>(section, name + "-foreground", {}));
|
|
|
|
|
|
|
|
icon_t icon_empty;
|
|
|
|
icon_t icon_fill;
|
|
|
|
icon_t icon_indicator;
|
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
if (format.find("%empty%") != string::npos) {
|
2016-11-02 19:22:45 +00:00
|
|
|
icon_empty = load_icon(conf, section, name + "-empty");
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
|
|
|
if (format.find("%fill%") != string::npos) {
|
2016-11-02 19:22:45 +00:00
|
|
|
icon_fill = load_icon(conf, section, name + "-fill");
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
|
|
|
if (format.find("%indicator%") != string::npos) {
|
2016-11-02 19:22:45 +00:00
|
|
|
icon_indicator = load_icon(conf, section, name + "-indicator");
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
|
|
|
|
// If a foreground/background color is defined for the indicator
|
|
|
|
// but not for the empty icon we use the bar's default colors to
|
|
|
|
// avoid color bleed
|
|
|
|
if (icon_empty && icon_indicator) {
|
2016-11-25 12:55:15 +00:00
|
|
|
if (!icon_indicator->m_background.empty() && icon_empty->m_background.empty()) {
|
2016-11-21 14:07:00 +00:00
|
|
|
icon_empty->m_background = color_util::hex<uint16_t>(bar.background);
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
|
|
|
if (!icon_indicator->m_foreground.empty() && icon_empty->m_foreground.empty()) {
|
2016-11-21 14:07:00 +00:00
|
|
|
icon_empty->m_foreground = color_util::hex<uint16_t>(bar.foreground);
|
2016-11-25 12:55:15 +00:00
|
|
|
}
|
2016-11-02 19:22:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
progressbar->set_empty(move(icon_empty));
|
|
|
|
progressbar->set_fill(move(icon_fill));
|
|
|
|
progressbar->set_indicator(move(icon_indicator));
|
|
|
|
|
|
|
|
return progressbar;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS_END
|