GRadioButton.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #include <LibGUI/GRadioButton.h>
  2. #include <LibGUI/GPainter.h>
  3. #include <SharedGraphics/GraphicsBitmap.h>
  4. static RetainPtr<GraphicsBitmap> s_unfilled_circle_bitmap;
  5. static RetainPtr<GraphicsBitmap> s_filled_circle_bitmap;
  6. static RetainPtr<GraphicsBitmap> s_changing_filled_circle_bitmap;
  7. static RetainPtr<GraphicsBitmap> s_changing_unfilled_circle_bitmap;
  8. GRadioButton::GRadioButton(const String& label, GWidget* parent)
  9. : GWidget(parent)
  10. , m_label(label)
  11. {
  12. if (!s_unfilled_circle_bitmap) {
  13. s_unfilled_circle_bitmap = GraphicsBitmap::load_from_file("/res/icons/unfilled-radio-circle.png");
  14. s_filled_circle_bitmap = GraphicsBitmap::load_from_file("/res/icons/filled-radio-circle.png");
  15. s_changing_filled_circle_bitmap = GraphicsBitmap::load_from_file("/res/icons/changing-filled-radio-circle.png");
  16. s_changing_unfilled_circle_bitmap = GraphicsBitmap::load_from_file("/res/icons/changing-unfilled-radio-circle.png");
  17. }
  18. }
  19. GRadioButton::~GRadioButton()
  20. {
  21. }
  22. Size GRadioButton::circle_size()
  23. {
  24. return s_unfilled_circle_bitmap->size();
  25. }
  26. static const GraphicsBitmap& circle_bitmap(bool checked, bool changing)
  27. {
  28. if (changing)
  29. return checked ? *s_changing_filled_circle_bitmap : *s_changing_unfilled_circle_bitmap;
  30. return checked ? *s_filled_circle_bitmap : *s_unfilled_circle_bitmap;
  31. }
  32. void GRadioButton::paint_event(GPaintEvent& event)
  33. {
  34. GPainter painter(*this);
  35. painter.add_clip_rect(event.rect());
  36. Rect circle_rect { { 2, 0 }, circle_size() };
  37. circle_rect.center_vertically_within(rect());
  38. auto& bitmap = circle_bitmap(m_checked, m_changing);
  39. painter.blit(circle_rect.location(), bitmap, bitmap.rect());
  40. if (!m_label.is_empty()) {
  41. Rect text_rect { circle_rect.right() + 4, 0, font().width(m_label), font().glyph_height() };
  42. text_rect.center_vertically_within(rect());
  43. painter.draw_text(text_rect, m_label, TextAlignment::CenterLeft, foreground_color());
  44. }
  45. }
  46. template<typename Callback>
  47. void GRadioButton::for_each_in_group(Callback callback)
  48. {
  49. if (!parent())
  50. return;
  51. for (auto& object : parent()->children()) {
  52. if (!object->is_widget())
  53. continue;
  54. if (!static_cast<GWidget*>(object)->is_radio_button())
  55. continue;
  56. callback(*static_cast<GRadioButton*>(object));
  57. }
  58. }
  59. void GRadioButton::mousedown_event(GMouseEvent& event)
  60. {
  61. if (event.button() != GMouseButton::Left)
  62. return;
  63. m_changing = rect().contains(event.position());
  64. m_tracking = true;
  65. update();
  66. }
  67. void GRadioButton::mousemove_event(GMouseEvent& event)
  68. {
  69. if (m_tracking) {
  70. bool old_changing = m_changing;
  71. m_changing = rect().contains(event.position());
  72. if (old_changing != m_changing)
  73. update();
  74. }
  75. }
  76. void GRadioButton::mouseup_event(GMouseEvent& event)
  77. {
  78. if (event.button() != GMouseButton::Left)
  79. return;
  80. if (rect().contains(event.position())) {
  81. for_each_in_group([this] (auto& button) {
  82. if (&button != this)
  83. button.set_checked(false);
  84. });
  85. set_checked(true);
  86. }
  87. m_changing = false;
  88. m_tracking = false;
  89. update();
  90. }
  91. void GRadioButton::set_label(const String& label)
  92. {
  93. if (m_label == label)
  94. return;
  95. m_label = label;
  96. update();
  97. }
  98. void GRadioButton::set_checked(bool checked)
  99. {
  100. if (m_checked == checked)
  101. return;
  102. m_checked = checked;
  103. update();
  104. }