Serenity Operating System
at master 77 lines 2.2 kB view raw
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}