From 22586c9cc6e7f8eca565ac4d29d640506d8c7775 Mon Sep 17 00:00:00 2001 From: ronak69 Date: Wed, 6 Mar 2024 06:23:23 +0000 Subject: [PATCH] AnalogClock: Add feature to change and show time zone The said time zone is local to each instance of the AnalogClock and is separate from the system time zone. This allows user to have clocks that use different time zones simultaneously. --- .../Applications/AnalogClock/AnalogClock.cpp | 15 ++++++- .../Applications/AnalogClock/AnalogClock.h | 6 +++ Userland/Applications/AnalogClock/main.cpp | 43 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/Userland/Applications/AnalogClock/AnalogClock.cpp b/Userland/Applications/AnalogClock/AnalogClock.cpp index 54524fe2846..5a0ad02ba15 100644 --- a/Userland/Applications/AnalogClock/AnalogClock.cpp +++ b/Userland/Applications/AnalogClock/AnalogClock.cpp @@ -10,6 +10,7 @@ #include #include #include +#include void AnalogClock::draw_graduations(GUI::Painter& painter, Gfx::IntRect rect, int x, int y) { @@ -112,9 +113,21 @@ void AnalogClock::paint_event(GUI::PaintEvent& event) GUI::Painter painter(*this); painter.clear_rect(event.rect(), m_show_window_frame ? palette().window() : Gfx::Color::Transparent); + if (m_show_time_zone) { + painter.draw_text( + Gfx::IntRect { { event.rect().width() / 2, (int)(event.rect().height() - m_clock_face_radius) / 2 }, {} }, + m_time_zone, + Gfx::FontDatabase::default_font().bold_variant(), + Gfx::TextAlignment::Center); + } + draw_face(painter); - auto time = Core::DateTime::now(); + auto now_seconds = Core::DateTime::now().timestamp(); + auto maybe_time_zone_offset = TimeZone::get_time_zone_offset(m_time_zone, UnixDateTime::from_seconds_since_epoch(now_seconds)); + VERIFY(maybe_time_zone_offset.has_value()); + + auto time = Core::DateTime::from_timestamp(now_seconds + maybe_time_zone_offset.value().seconds); auto minute = time.minute() * (2 * M_PI) / 60; auto hour = (minute + (2 * M_PI) * time.hour()) / 12; auto seconds = time.second() * (2 * M_PI) / 60; diff --git a/Userland/Applications/AnalogClock/AnalogClock.h b/Userland/Applications/AnalogClock/AnalogClock.h index 11915bf878c..e5ff954aa2f 100644 --- a/Userland/Applications/AnalogClock/AnalogClock.h +++ b/Userland/Applications/AnalogClock/AnalogClock.h @@ -18,6 +18,9 @@ public: Function on_context_menu_request; + void set_time_zone(StringView time_zone) { m_time_zone = time_zone; } + void set_show_time_zone(bool value) { m_show_time_zone = value; } + private: AnalogClock() : m_small_graduation_square(Gfx::IntRect({}, { 3, 3 })) @@ -38,6 +41,9 @@ private: bool m_show_window_frame { true }; + StringView m_time_zone; + bool m_show_time_zone { false }; + protected: void context_menu_event(GUI::ContextMenuEvent& event) override; void paint_event(GUI::PaintEvent&) override; diff --git a/Userland/Applications/AnalogClock/main.cpp b/Userland/Applications/AnalogClock/main.cpp index 5f356feee79..824261fb6df 100644 --- a/Userland/Applications/AnalogClock/main.cpp +++ b/Userland/Applications/AnalogClock/main.cpp @@ -8,12 +8,14 @@ #include "AnalogClock.h" #include #include +#include #include #include #include #include #include #include +#include ErrorOr serenity_main(Main::Arguments arguments) { @@ -40,6 +42,47 @@ ErrorOr serenity_main(Main::Arguments arguments) auto menu = GUI::Menu::construct(); menu->add_action(*show_window_frame_action); + menu->add_separator(); + + menu->add_action(GUI::Action::create_checkable( + "Show Time Zone", + [&clock](auto& action) { + clock->set_show_time_zone(action.is_checked()); + })); + + auto timezone_submenu = menu->add_submenu("Time Zone"_string); + + GUI::ActionGroup timezone_action_group; + timezone_action_group.set_exclusive(true); + + for (auto time_zone : TimeZone::all_time_zones()) { + auto timezone_action = GUI::Action::create_checkable( + time_zone.name, + [&clock](auto& action) { + clock->set_time_zone(action.text()); + }); + + timezone_action_group.add_action(timezone_action); + timezone_submenu->add_action(timezone_action); + } + + auto reset_to_system_time_zone_action = GUI::Action::create( + "Reset to System Time Zone", + [&timezone_action_group](auto&) { + auto system_time_zone = TimeZone::system_time_zone(); + + timezone_action_group.for_each_action([&system_time_zone](auto& action) { + if (action.text() == system_time_zone) { + action.activate(); + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + }); + + menu->add_action(reset_to_system_time_zone_action); + reset_to_system_time_zone_action->activate(); + clock->on_context_menu_request = [&](auto& event) { menu->popup(event.screen_position()); };