DesktopStatusWindow.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2021, Peter Elliott <pelliott@ualberta.ca>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include "DesktopStatusWindow.h"
  7. #include <LibGUI/Desktop.h>
  8. #include <LibGUI/Painter.h>
  9. #include <LibGUI/Widget.h>
  10. #include <LibGUI/WindowManagerServerConnection.h>
  11. #include <LibGfx/Palette.h>
  12. class DesktopStatusWidget : public GUI::Widget {
  13. C_OBJECT(DesktopStatusWidget);
  14. public:
  15. virtual ~DesktopStatusWidget() override
  16. {
  17. }
  18. Gfx::IntRect rect_for_desktop(unsigned row, unsigned col) const
  19. {
  20. auto& desktop = GUI::Desktop::the();
  21. auto vcols = desktop.virtual_desktop_columns();
  22. auto vrows = desktop.virtual_desktop_rows();
  23. auto desktop_width = (width() - gap() * (vcols - 1)) / vcols;
  24. auto desktop_height = (height() - gap() * (vrows - 1)) / vrows;
  25. return {
  26. col * (desktop_width + gap()), row * (desktop_height + gap()),
  27. desktop_width, desktop_height
  28. };
  29. }
  30. virtual void paint_event(GUI::PaintEvent& event) override
  31. {
  32. GUI::Widget::paint_event(event);
  33. GUI::Painter painter(*this);
  34. painter.add_clip_rect(event.rect());
  35. painter.fill_rect({ 0, 0, width(), height() }, palette().button());
  36. auto& desktop = GUI::Desktop::the();
  37. auto active_color = palette().active_window_border1();
  38. auto inactive_color = palette().inactive_window_border1();
  39. for (unsigned row = 0; row < desktop.virtual_desktop_rows(); ++row) {
  40. for (unsigned col = 0; col < desktop.virtual_desktop_columns(); ++col) {
  41. painter.fill_rect(rect_for_desktop(row, col),
  42. (row == current_row() && col == current_col()) ? active_color : inactive_color);
  43. }
  44. }
  45. }
  46. virtual void mousedown_event(GUI::MouseEvent& event) override
  47. {
  48. auto base_rect = rect_for_desktop(0, 0);
  49. auto row = event.y() / (base_rect.height() + gap());
  50. auto col = event.x() / (base_rect.width() + gap());
  51. // Handle case where divider is clicked.
  52. if (rect_for_desktop(row, col).contains(event.position()))
  53. GUI::WindowManagerServerConnection::the().async_set_virtual_desktop(row, col);
  54. }
  55. unsigned current_row() const { return m_current_row; }
  56. void set_current_row(unsigned row) { m_current_row = row; }
  57. unsigned current_col() const { return m_current_col; }
  58. void set_current_col(unsigned col) { m_current_col = col; }
  59. unsigned gap() const { return m_gap; }
  60. private:
  61. DesktopStatusWidget()
  62. {
  63. }
  64. unsigned m_gap { 1 };
  65. unsigned m_current_row;
  66. unsigned m_current_col;
  67. };
  68. DesktopStatusWindow::DesktopStatusWindow()
  69. {
  70. GUI::Desktop::the().on_receive_screen_rects([&](GUI::Desktop&) {
  71. update();
  72. });
  73. set_window_type(GUI::WindowType::Applet);
  74. set_has_alpha_channel(true);
  75. m_widget = &set_main_widget<DesktopStatusWidget>();
  76. }
  77. DesktopStatusWindow::~DesktopStatusWindow()
  78. {
  79. }
  80. void DesktopStatusWindow::wm_event(GUI::WMEvent& event)
  81. {
  82. if (event.type() == GUI::Event::WM_VirtualDesktopChanged) {
  83. auto& changed_event = static_cast<GUI::WMVirtualDesktopChangedEvent&>(event);
  84. m_widget->set_current_row(changed_event.current_row());
  85. m_widget->set_current_col(changed_event.current_column());
  86. update();
  87. }
  88. }