ClockWidget.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "ClockWidget.h"
  7. #include <LibCore/Process.h>
  8. #include <LibGUI/Painter.h>
  9. #include <LibGUI/SeparatorWidget.h>
  10. #include <LibGUI/Window.h>
  11. #include <LibGfx/FontDatabase.h>
  12. #include <LibGfx/Palette.h>
  13. namespace Taskbar {
  14. ClockWidget::ClockWidget()
  15. {
  16. set_frame_shape(Gfx::FrameShape::Box);
  17. set_frame_shadow(Gfx::FrameShadow::Sunken);
  18. set_frame_thickness(1);
  19. m_time_width = font().width("22:22:22");
  20. set_fixed_size(m_time_width + 20, 21);
  21. m_timer = add<Core::Timer>(1000, [this] {
  22. static time_t last_update_time;
  23. time_t now = time(nullptr);
  24. if (now != last_update_time) {
  25. tick_clock();
  26. last_update_time = now;
  27. set_tooltip(Core::DateTime::now().to_string("%Y-%m-%d"));
  28. }
  29. });
  30. m_calendar_window = add<GUI::Window>(window());
  31. m_calendar_window->resize(152, 186);
  32. m_calendar_window->set_frameless(true);
  33. m_calendar_window->set_resizable(false);
  34. m_calendar_window->set_minimizable(false);
  35. m_calendar_window->on_active_input_change = [this](bool is_active_input) {
  36. if (!is_active_input)
  37. close();
  38. };
  39. auto& root_container = m_calendar_window->set_main_widget<GUI::Label>();
  40. root_container.set_fill_with_background_color(true);
  41. root_container.set_layout<GUI::VerticalBoxLayout>();
  42. root_container.layout()->set_margins({ 2, 0 });
  43. root_container.layout()->set_spacing(0);
  44. root_container.set_frame_thickness(2);
  45. root_container.set_frame_shape(Gfx::FrameShape::Container);
  46. root_container.set_frame_shadow(Gfx::FrameShadow::Raised);
  47. auto& navigation_container = root_container.add<GUI::Widget>();
  48. navigation_container.set_fixed_height(24);
  49. navigation_container.set_layout<GUI::HorizontalBoxLayout>();
  50. navigation_container.layout()->set_margins({ 2, 3, 2, 2 });
  51. m_prev_date = navigation_container.add<GUI::Button>();
  52. m_prev_date->set_button_style(Gfx::ButtonStyle::Coolbar);
  53. m_prev_date->set_fixed_size(24, 24);
  54. m_prev_date->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-back.png"));
  55. m_prev_date->on_click = [&](auto) {
  56. unsigned view_month = m_calendar->view_month();
  57. unsigned view_year = m_calendar->view_year();
  58. if (m_calendar->mode() == GUI::Calendar::Month) {
  59. view_month--;
  60. if (m_calendar->view_month() == 1) {
  61. view_month = 12;
  62. view_year--;
  63. }
  64. } else {
  65. view_year--;
  66. }
  67. m_calendar->update_tiles(view_year, view_month);
  68. if (m_calendar->mode() == GUI::Calendar::Year)
  69. m_selected_calendar_button->set_text(m_calendar->formatted_date(GUI::Calendar::YearOnly));
  70. else
  71. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  72. };
  73. m_selected_calendar_button = navigation_container.add<GUI::Button>();
  74. m_selected_calendar_button->set_button_style(Gfx::ButtonStyle::Coolbar);
  75. m_selected_calendar_button->set_fixed_height(24);
  76. m_selected_calendar_button->on_click = [&](auto) {
  77. m_calendar->toggle_mode();
  78. if (m_calendar->mode() == GUI::Calendar::Year)
  79. m_selected_calendar_button->set_text(m_calendar->formatted_date(GUI::Calendar::YearOnly));
  80. else
  81. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  82. };
  83. m_next_date = navigation_container.add<GUI::Button>();
  84. m_next_date->set_button_style(Gfx::ButtonStyle::Coolbar);
  85. m_next_date->set_fixed_size(24, 24);
  86. m_next_date->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/go-forward.png"));
  87. m_next_date->on_click = [&](auto) {
  88. unsigned view_month = m_calendar->view_month();
  89. unsigned view_year = m_calendar->view_year();
  90. if (m_calendar->mode() == GUI::Calendar::Month) {
  91. view_month++;
  92. if (m_calendar->view_month() == 12) {
  93. view_month = 1;
  94. view_year++;
  95. }
  96. } else {
  97. view_year++;
  98. }
  99. m_calendar->update_tiles(view_year, view_month);
  100. if (m_calendar->mode() == GUI::Calendar::Year)
  101. m_selected_calendar_button->set_text(m_calendar->formatted_date(GUI::Calendar::YearOnly));
  102. else
  103. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  104. };
  105. auto& separator1 = root_container.add<GUI::HorizontalSeparator>();
  106. separator1.set_fixed_height(2);
  107. auto& calendar_container = root_container.add<GUI::Widget>();
  108. calendar_container.set_layout<GUI::HorizontalBoxLayout>();
  109. calendar_container.layout()->set_margins({ 4, 5, 4, 4 });
  110. m_calendar = calendar_container.add<GUI::Calendar>();
  111. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  112. m_calendar->on_tile_click = [&] {
  113. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  114. };
  115. m_calendar->on_month_click = [&] {
  116. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  117. };
  118. auto& separator2 = root_container.add<GUI::HorizontalSeparator>();
  119. separator2.set_fixed_height(2);
  120. auto& settings_container = root_container.add<GUI::Widget>();
  121. settings_container.set_fixed_height(24);
  122. settings_container.set_layout<GUI::HorizontalBoxLayout>();
  123. settings_container.layout()->set_margins({ 2, 3, 2, 2 });
  124. settings_container.layout()->add_spacer();
  125. m_jump_to_button = settings_container.add<GUI::Button>();
  126. m_jump_to_button->set_button_style(Gfx::ButtonStyle::Coolbar);
  127. m_jump_to_button->set_fixed_size(24, 24);
  128. m_jump_to_button->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/calendar-date.png"));
  129. m_jump_to_button->set_tooltip("Jump to today");
  130. m_jump_to_button->on_click = [this](auto) {
  131. jump_to_current_date();
  132. };
  133. m_calendar_launcher = settings_container.add<GUI::Button>();
  134. m_calendar_launcher->set_button_style(Gfx::ButtonStyle::Coolbar);
  135. m_calendar_launcher->set_fixed_size(24, 24);
  136. m_calendar_launcher->set_icon(Gfx::Bitmap::try_load_from_file("/res/icons/16x16/app-calendar.png"));
  137. m_calendar_launcher->set_tooltip("Calendar");
  138. m_calendar_launcher->on_click = [](auto) {
  139. Core::Process::spawn("/bin/Calendar"sv);
  140. };
  141. }
  142. ClockWidget::~ClockWidget()
  143. {
  144. }
  145. void ClockWidget::paint_event(GUI::PaintEvent& event)
  146. {
  147. GUI::Frame::paint_event(event);
  148. auto time_text = Core::DateTime::now().to_string("%T");
  149. GUI::Painter painter(*this);
  150. painter.add_clip_rect(frame_inner_rect());
  151. painter.draw_text(frame_inner_rect().translated(0, 1), time_text, Gfx::FontDatabase::default_font(), Gfx::TextAlignment::Center, palette().window_text());
  152. }
  153. void ClockWidget::mousedown_event(GUI::MouseEvent& event)
  154. {
  155. if (event.button() != GUI::MouseButton::Left) {
  156. return;
  157. } else {
  158. if (!m_calendar_window->is_visible())
  159. open();
  160. else
  161. close();
  162. }
  163. }
  164. void ClockWidget::open()
  165. {
  166. jump_to_current_date();
  167. position_calendar_window();
  168. m_calendar_window->show();
  169. }
  170. void ClockWidget::close()
  171. {
  172. m_calendar_window->hide();
  173. }
  174. void ClockWidget::position_calendar_window()
  175. {
  176. m_calendar_window->set_rect(
  177. screen_relative_rect().right() - m_calendar_window->width() + 4,
  178. screen_relative_rect().top() - m_calendar_window->height() - 3,
  179. 152,
  180. 186);
  181. }
  182. void ClockWidget::jump_to_current_date()
  183. {
  184. if (m_calendar->mode() == GUI::Calendar::Year)
  185. m_calendar->toggle_mode();
  186. m_calendar->set_selected_date(Core::DateTime::now());
  187. m_calendar->update_tiles(Core::DateTime::now().year(), Core::DateTime::now().month());
  188. m_selected_calendar_button->set_text(m_calendar->formatted_date());
  189. }
  190. }