diff --git a/src/modules/clock.cpp b/src/modules/clock.cpp index e0d63e2..a40d412 100644 --- a/src/modules/clock.cpp +++ b/src/modules/clock.cpp @@ -113,8 +113,12 @@ auto waybar::modules::Clock::update() -> void { if (config_["tooltip-format"].isString()) { std::string calendar_lines{""}; std::string timezoned_time_lines{""}; - if (is_calendar_in_tooltip_) calendar_lines = calendar_text(wtime); - if (is_timezoned_list_in_tooltip_) timezoned_time_lines = timezones_text(&now); + if (is_calendar_in_tooltip_) { + calendar_lines = calendar_text(wtime); + } + if (is_timezoned_list_in_tooltip_) { + timezoned_time_lines = timezones_text(&now); + } auto tooltip_format = config_["tooltip-format"].asString(); text = fmt::format(tooltip_format, wtime, fmt::arg(kCalendarPlaceholder.c_str(), calendar_lines), @@ -168,72 +172,77 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str const auto daypoint = date::floor(wtime.ztime.get_local_time()); const auto ymd{date::year_month_day{daypoint}}; - if (calendar_cached_ymd_ == ymd) return calendar_cached_text_; + if (calendar_cached_ymd_ == ymd) { + return calendar_cached_text_; + } const auto curr_day{(calendar_shift_init_.count() != 0 && calendar_shift_.count() != 0) ? date::day{0} : ymd.day()}; const date::year_month ym{ymd.year(), ymd.month()}; - const auto week_format{config_["format-calendar-weekdays"].isString() - ? config_["format-calendar-weekdays"].asString() - : ""}; - const auto wn_format{config_["format-calendar-weeks"].isString() - ? config_["format-calendar-weeks"].asString() - : ""}; + const auto weeks_format{config_["format-calendar-weeks"].isString() + ? config_["format-calendar-weeks"].asString() + : ""}; std::stringstream os; - const auto first_dow = first_day_of_week(); - int ws{0}; // weeks-pos: side(1 - left, 2 - right) + const date::weekday first_week_day = first_day_of_week(); + + enum class WeeksPlacement { + LEFT, + RIGHT, + HIDDEN, + }; + WeeksPlacement weeks_pos = WeeksPlacement::HIDDEN; if (config_["calendar-weeks-pos"].isString()) { if (config_["calendar-weeks-pos"].asString() == "left") { - ws = 1; + weeks_pos = WeeksPlacement::LEFT; // Add paddings before the header os << std::string(4, ' '); } else if (config_["calendar-weeks-pos"].asString() == "right") { - ws = 2; + weeks_pos = WeeksPlacement::RIGHT; } } - weekdays_header(first_dow, os); + weekdays_header(first_week_day, os); // First week prefixed with spaces if needed. - auto wd = date::weekday(ym / 1); - auto empty_days = (wd - first_dow).count(); - date::sys_days lwd{static_cast(ym / 1) + date::days{7 - empty_days}}; + auto first_month_day = date::weekday(ym / 1); + int empty_days = (first_week_day - first_month_day).count() + 1; + date::sys_days last_week_day{static_cast(ym / 1) + date::days{7 - empty_days}}; - if (first_dow == date::Monday) { - lwd -= date::days{1}; + if (first_week_day == date::Monday) { + last_week_day -= date::days{1}; } /* Print weeknumber on the left for the first row*/ - if (ws == 1) { - os << fmt::format(wn_format, lwd); - os << ' '; - lwd += date::weeks{1}; + if (weeks_pos == WeeksPlacement::LEFT) { + os << fmt::format(weeks_format, date::format("%U", last_week_day)) << ' '; + last_week_day += date::weeks{1}; } if (empty_days > 0) { os << std::string(empty_days * 3 - 1, ' '); } - auto last_day = (ym / date::literals::last).day(); - for (auto d = date::day(1); d <= last_day; ++d, ++wd) { - if (wd != first_dow) { + const auto last_day = (ym / date::literals::last).day(); + auto weekday = first_month_day; + for (auto d = date::day(1); d <= last_day; ++d, ++weekday) { + if (weekday != first_week_day) { os << ' '; } else if (unsigned(d) != 1) { - if (ws == 2) { + last_week_day -= date::days{1}; + if (weeks_pos == WeeksPlacement::RIGHT) { os << ' '; - os << fmt::format(wn_format, lwd); - lwd += date::weeks{1}; + os << fmt::format(weeks_format, date::format("%U", last_week_day)); } - os << '\n'; + os << "\n"; - if (ws == 1) { - os << fmt::format(wn_format, lwd); + if (weeks_pos == WeeksPlacement::LEFT) { + os << fmt::format(weeks_format, date::format("%U", last_week_day)); os << ' '; - lwd += date::weeks{1}; } + last_week_day += date::weeks{1} + date::days{1}; } if (d == curr_day) { if (config_["today-format"].isString()) { @@ -244,15 +253,16 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str } } else if (config_["format-calendar"].isString()) { os << fmt::format(config_["format-calendar"].asString(), date::format("%e", d)); - } else + } else { os << date::format("%e", d); + } /*Print weeks on the right when the endings with spaces*/ - if (ws == 2 && d == last_day) { - empty_days = 6 - (wd.c_encoding() - first_dow.c_encoding()); - if (empty_days > 0) { - os << std::string(empty_days * 3 + 1, ' '); - os << fmt::format(wn_format, lwd); - } + if (weeks_pos == WeeksPlacement::RIGHT && d == last_day) { + last_week_day -= date::days{1}; + empty_days = 6 - (weekday - first_week_day).count(); + os << std::string(empty_days * 3 + 1, ' '); + os << fmt::format(weeks_format, date::format("%U", last_week_day)); + last_week_day += date::days{1}; } } @@ -262,12 +272,14 @@ auto waybar::modules::Clock::calendar_text(const waybar_time& wtime) -> std::str return result; } -auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std::ostream& os) +auto waybar::modules::Clock::weekdays_header(const date::weekday& first_week_day, std::ostream& os) -> void { std::stringstream res; - auto wd = first_dow; + auto wd = first_week_day; do { - if (wd != first_dow) res << ' '; + if (wd != first_week_day) { + res << ' '; + } Glib::ustring wd_ustring(date::format(locale_, "%a", wd)); auto clen = ustring_clen(wd_ustring); auto wd_len = wd_ustring.length(); @@ -278,7 +290,7 @@ auto waybar::modules::Clock::weekdays_header(const date::weekday& first_dow, std } const std::string pad(2 - clen, ' '); res << pad << wd_ustring; - } while (++wd != first_dow); + } while (++wd != first_week_day); res << "\n"; if (config_["format-calendar-weekdays"].isString()) {