https://github.com/Alexays/Waybar/issues/1315. Option to display week number on calendar

This commit is contained in:
Viktar Lukashonak 2022-03-24 15:41:50 +03:00
parent d4a07483b2
commit 2d87bcb1ab
No known key found for this signature in database
GPG Key ID: 08A413AA87200A6F
2 changed files with 52 additions and 0 deletions

View File

@ -35,6 +35,8 @@ class Clock : public ALabel {
auto weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void; auto weekdays_header(const date::weekday& first_dow, std::ostream& os) -> void;
auto first_day_of_week() -> date::weekday; auto first_day_of_week() -> date::weekday;
const date::time_zone* current_timezone(); const date::time_zone* current_timezone();
auto print_iso_weeknum(std::ostream& os,
int weeknum) -> void;
bool is_timezone_fixed(); bool is_timezone_fixed();
auto timezones_text(std::chrono::system_clock::time_point *now) -> std::string; auto timezones_text(std::chrono::system_clock::time_point *now) -> std::string;
}; };

View File

@ -1,4 +1,5 @@
#include "modules/clock.hpp" #include "modules/clock.hpp"
#include <iomanip>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
#if FMT_VERSION < 60000 #if FMT_VERSION < 60000
@ -167,12 +168,32 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str
std::stringstream os; std::stringstream os;
const auto first_dow = first_day_of_week(); const auto first_dow = first_day_of_week();
int ws{0}; // weeks-pos: side(1 - left, 2 - right)
int wn{0}; // weeknumber
if (config_["week-pos"].isString()) {
if (config_["week-pos"].asString() == "left") {
ws = 1;
// Add paddings before the header
os << std::string(4, ' ');
} else if (config_["week-pos"].asString() == "right") {
ws = 2;
}
}
if (ws > 0){
wn = (date::sys_days{date::year_month_day{ym / 1}} - date::sys_days{date::year_month_day{ymd.year() / 1 / 1}}).count() / 7 + 1;
}
weekdays_header(first_dow, os); weekdays_header(first_dow, os);
// First week prefixed with spaces if needed. // First week prefixed with spaces if needed.
auto wd = date::weekday(ym / 1); auto wd = date::weekday(ym / 1);
auto empty_days = (wd - first_dow).count(); auto empty_days = (wd - first_dow).count();
if (empty_days > 0) { if (empty_days > 0) {
if (ws == 1) {
print_iso_weeknum(os, wn);
os << ' ';
++wn;
}
os << std::string(empty_days * 3 - 1, ' '); os << std::string(empty_days * 3 - 1, ' ');
} }
auto last_day = (ym / date::literals::last).day(); auto last_day = (ym / date::literals::last).day();
@ -180,7 +201,19 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str
if (wd != first_dow) { if (wd != first_dow) {
os << ' '; os << ' ';
} else if (unsigned(d) != 1) { } else if (unsigned(d) != 1) {
if (ws == 2) {
os << ' ';
print_iso_weeknum(os, wn);
++wn;
}
os << '\n'; os << '\n';
if (ws == 1) {
print_iso_weeknum(os, wn);
os << ' ';
++wn;
}
} }
if (d == curr_day) { if (d == curr_day) {
if (config_["today-format"].isString()) { if (config_["today-format"].isString()) {
@ -192,6 +225,12 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str
} else { } else {
os << date::format("%e", d); os << date::format("%e", d);
} }
/*Print weeks on the right when the endings with spaces*/
if (ws == 2 && d == last_day && wd.c_encoding() < 6) {
empty_days = 6 - wd.c_encoding();
os << std::string(empty_days * 3 + 1, ' ');
print_iso_weeknum(os, wn);
}
} }
auto result = os.str(); auto result = os.str();
@ -239,6 +278,17 @@ auto waybar::modules::Clock::timezones_text(std::chrono::system_clock::time_poin
return os.str(); return os.str();
} }
auto waybar::modules::Clock::print_iso_weeknum(std::ostream& os,
int weeknum) -> void {
std::stringstream res;
res << 'W' << std::setfill('0') << std::setw(2) << weeknum;
if (config_["week-format"].isString()) {
auto week_format = config_["week-format"].asString();
os << fmt::format(week_format, res.str());
} else os << res.str();
}
#ifdef HAVE_LANGINFO_1STDAY #ifdef HAVE_LANGINFO_1STDAY
template <auto fn> template <auto fn>
using deleter_from_fn = std::integral_constant<decltype(fn), fn>; using deleter_from_fn = std::integral_constant<decltype(fn), fn>;