Serenity Operating System
1/*
2 * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
3 * Copyright (c) 2022, the SerenityOS developers.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <LibGUI/Painter.h>
9#include <LibGUI/RadioButton.h>
10#include <LibGfx/Bitmap.h>
11#include <LibGfx/Font/Font.h>
12#include <LibGfx/Palette.h>
13#include <LibGfx/StylePainter.h>
14
15REGISTER_WIDGET(GUI, RadioButton)
16
17namespace GUI {
18
19RadioButton::RadioButton(String text)
20 : AbstractButton(move(text))
21{
22 set_exclusive(true);
23 set_checkable(true);
24 set_min_size(SpecialDimension::Shrink, SpecialDimension::Shrink);
25 set_preferred_size(SpecialDimension::OpportunisticGrow, SpecialDimension::Shrink);
26}
27
28int RadioButton::horizontal_padding()
29{
30 return 2;
31}
32
33Gfx::IntSize RadioButton::circle_size()
34{
35 return { 12, 12 };
36}
37
38void RadioButton::paint_event(PaintEvent& event)
39{
40 Painter painter(*this);
41 painter.add_clip_rect(event.rect());
42
43 if (fill_with_background_color())
44 painter.fill_rect(rect(), palette().window());
45
46 if (is_enabled() && is_hovered())
47 painter.fill_rect(rect(), palette().hover_highlight());
48
49 Gfx::IntRect circle_rect { { horizontal_padding(), 0 }, circle_size() };
50 circle_rect.center_vertically_within(rect());
51
52 Gfx::StylePainter::paint_radio_button(painter, circle_rect, palette(), is_checked(), is_being_pressed());
53
54 Gfx::IntRect text_rect { circle_rect.right() + 5 + horizontal_padding(), 0, static_cast<int>(ceilf(font().width(text()))), font().pixel_size_rounded_up() };
55 text_rect.center_vertically_within(rect());
56 paint_text(painter, text_rect, font(), Gfx::TextAlignment::TopLeft);
57
58 if (is_focused())
59 painter.draw_focus_rect(text_rect.inflated(6, 6), palette().focus_outline());
60}
61
62void RadioButton::click(unsigned)
63{
64 if (!is_enabled())
65 return;
66 set_checked(true);
67}
68
69Optional<UISize> RadioButton::calculated_min_size() const
70{
71 auto const& font = this->font();
72 int width = horizontal_padding() * 2 + circle_size().width() + static_cast<int>(ceilf(font.width(text())));
73 int height = max(22, max(font.pixel_size_rounded_up() + 8, circle_size().height()));
74 return UISize(width, height);
75}
76
77}