mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 01:20:25 +00:00
LibGUI: Add a GAbstractButton base class for button widgets.
This patch moves GButton and GRadioButton to inherit from it. This allows them to share code for mouse event handling, etc.
This commit is contained in:
parent
abbcdba72e
commit
21c56477b0
Notes:
sideshowbarker
2024-07-19 13:58:24 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/21c56477b04
18 changed files with 202 additions and 211 deletions
|
@ -46,7 +46,7 @@ int main(int argc, char** argv)
|
|||
version_label->set_preferred_size({ 0, 11 });
|
||||
|
||||
auto* quit_button = new GButton(widget);
|
||||
quit_button->set_caption("Okay");
|
||||
quit_button->set_text("Okay");
|
||||
quit_button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
||||
quit_button->set_preferred_size({ 100, 20 });
|
||||
quit_button->on_click = [] (GButton&) {
|
||||
|
|
|
@ -50,7 +50,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RetainPtr<Font>&& edited_
|
|||
};
|
||||
|
||||
auto* save_button = new GButton(this);
|
||||
save_button->set_caption("Save");
|
||||
save_button->set_text("Save");
|
||||
save_button->set_relative_rect({ 5, 300, 105, 20 });
|
||||
save_button->on_click = [this] (GButton&) {
|
||||
dbgprintf("write to file: '%s'\n", m_path.characters());
|
||||
|
@ -58,7 +58,7 @@ FontEditorWidget::FontEditorWidget(const String& path, RetainPtr<Font>&& edited_
|
|||
};
|
||||
|
||||
auto* quit_button = new GButton(this);
|
||||
quit_button->set_caption("Quit");
|
||||
quit_button->set_text("Quit");
|
||||
quit_button->set_relative_rect({ 110, 300, 105, 20 });
|
||||
quit_button->on_click = [] (GButton&) {
|
||||
exit(0);
|
||||
|
|
|
@ -125,10 +125,10 @@ void TaskbarWindow::wm_event(GWMEvent& event)
|
|||
window.set_minimized(changed_event.is_minimized());
|
||||
if (window.is_minimized()) {
|
||||
window.button()->set_foreground_color(Color::DarkGray);
|
||||
window.button()->set_caption(String::format("[%s]", changed_event.title().characters()));
|
||||
window.button()->set_text(String::format("[%s]", changed_event.title().characters()));
|
||||
} else {
|
||||
window.button()->set_foreground_color(Color::Black);
|
||||
window.button()->set_caption(changed_event.title());
|
||||
window.button()->set_text(changed_event.title());
|
||||
}
|
||||
window.button()->set_checked(changed_event.is_active());
|
||||
break;
|
||||
|
|
|
@ -123,7 +123,7 @@ void VBWidget::setup_properties()
|
|||
}
|
||||
|
||||
if (m_type == VBWidgetType::GButton) {
|
||||
VB_ADD_PROPERTY(GButton, "caption", caption, set_caption, string);
|
||||
VB_ADD_PROPERTY(GButton, "text", text, set_text, string);
|
||||
}
|
||||
|
||||
if (m_type == VBWidgetType::GGroupBox) {
|
||||
|
|
|
@ -44,7 +44,7 @@ static GWidget* build_gwidget(VBWidgetType type, GWidget* parent)
|
|||
}
|
||||
case VBWidgetType::GButton: {
|
||||
auto* button = new GButton(parent);
|
||||
button->set_caption("button_1");
|
||||
button->set_text("button_1");
|
||||
return button;
|
||||
}
|
||||
case VBWidgetType::GSpinBox: {
|
||||
|
|
106
LibGUI/GAbstractButton.cpp
Normal file
106
LibGUI/GAbstractButton.cpp
Normal file
|
@ -0,0 +1,106 @@
|
|||
#include <LibGUI/GAbstractButton.h>
|
||||
|
||||
GAbstractButton::GAbstractButton(GWidget* parent)
|
||||
: GWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GAbstractButton::GAbstractButton(const String& text, GWidget* parent)
|
||||
: GWidget(parent)
|
||||
, m_text(text)
|
||||
{
|
||||
}
|
||||
|
||||
GAbstractButton::~GAbstractButton()
|
||||
{
|
||||
}
|
||||
|
||||
void GAbstractButton::set_text(const String& text)
|
||||
{
|
||||
if (m_text == text)
|
||||
return;
|
||||
m_text = text;
|
||||
update();
|
||||
}
|
||||
|
||||
void GAbstractButton::set_checked(bool checked)
|
||||
{
|
||||
if (m_checked == checked)
|
||||
return;
|
||||
m_checked = checked;
|
||||
update();
|
||||
}
|
||||
|
||||
void GAbstractButton::set_checkable(bool checkable)
|
||||
{
|
||||
if (m_checkable == checkable)
|
||||
return;
|
||||
m_checkable = checkable;
|
||||
update();
|
||||
}
|
||||
|
||||
void GAbstractButton::mousemove_event(GMouseEvent& event)
|
||||
{
|
||||
bool is_over = rect().contains(event.position());
|
||||
m_hovered = is_over;
|
||||
if (event.buttons() & GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
bool being_pressed = is_over;
|
||||
if (being_pressed != m_being_pressed) {
|
||||
m_being_pressed = being_pressed;
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
GWidget::mousemove_event(event);
|
||||
}
|
||||
|
||||
void GAbstractButton::mousedown_event(GMouseEvent& event)
|
||||
{
|
||||
#ifdef GABSTRACTBUTTON_DEBUG
|
||||
dbgprintf("GAbstractButton::mouse_down_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
|
||||
#endif
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
m_being_pressed = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
GWidget::mousedown_event(event);
|
||||
}
|
||||
|
||||
void GAbstractButton::mouseup_event(GMouseEvent& event)
|
||||
{
|
||||
#ifdef GABSTRACTBUTTON_DEBUG
|
||||
dbgprintf("GAbstractButton::mouse_up_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
|
||||
#endif
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
bool was_being_pressed = m_being_pressed;
|
||||
m_being_pressed = false;
|
||||
update();
|
||||
if (was_being_pressed)
|
||||
click();
|
||||
}
|
||||
}
|
||||
GWidget::mouseup_event(event);
|
||||
}
|
||||
|
||||
void GAbstractButton::enter_event(CEvent&)
|
||||
{
|
||||
m_hovered = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void GAbstractButton::leave_event(CEvent&)
|
||||
{
|
||||
m_hovered = false;
|
||||
update();
|
||||
}
|
||||
|
||||
void GAbstractButton::keydown_event(GKeyEvent& event)
|
||||
{
|
||||
if (event.key() == KeyCode::Key_Return)
|
||||
click();
|
||||
GWidget::keydown_event(event);
|
||||
}
|
42
LibGUI/GAbstractButton.h
Normal file
42
LibGUI/GAbstractButton.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/GWidget.h>
|
||||
|
||||
class GAbstractButton : public GWidget {
|
||||
public:
|
||||
virtual ~GAbstractButton() override;
|
||||
|
||||
void set_text(const String&);
|
||||
const String& text() const { return m_text; }
|
||||
|
||||
bool is_checked() const { return m_checked; }
|
||||
void set_checked(bool);
|
||||
|
||||
bool is_checkable() const { return m_checkable; }
|
||||
void set_checkable(bool);
|
||||
|
||||
bool is_hovered() const { return m_hovered; }
|
||||
bool is_being_pressed() const { return m_being_pressed; }
|
||||
|
||||
virtual void click() = 0;
|
||||
|
||||
virtual const char* class_name() const override { return "GAbstractButton"; }
|
||||
|
||||
protected:
|
||||
explicit GAbstractButton(GWidget* parent);
|
||||
GAbstractButton(const String&, GWidget* parent);
|
||||
|
||||
virtual void mousedown_event(GMouseEvent&) override;
|
||||
virtual void mousemove_event(GMouseEvent&) override;
|
||||
virtual void mouseup_event(GMouseEvent&) override;
|
||||
virtual void keydown_event(GKeyEvent&) override;
|
||||
virtual void enter_event(CEvent&) override;
|
||||
virtual void leave_event(CEvent&) override;
|
||||
|
||||
private:
|
||||
String m_text;
|
||||
bool m_checked { false };
|
||||
bool m_checkable { false };
|
||||
bool m_hovered { false };
|
||||
bool m_being_pressed { false };
|
||||
};
|
|
@ -5,10 +5,8 @@
|
|||
#include <LibGUI/GAction.h>
|
||||
#include <Kernel/KeyCode.h>
|
||||
|
||||
//#define GBUTTON_DEBUG
|
||||
|
||||
GButton::GButton(GWidget* parent)
|
||||
: GWidget(parent)
|
||||
: GAbstractButton(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -18,37 +16,21 @@ GButton::~GButton()
|
|||
m_action->unregister_button({ }, *this);
|
||||
}
|
||||
|
||||
void GButton::set_caption(const String& caption)
|
||||
{
|
||||
if (caption == m_caption)
|
||||
return;
|
||||
m_caption = caption;
|
||||
update();
|
||||
}
|
||||
|
||||
void GButton::set_checked(bool checked)
|
||||
{
|
||||
if (m_checked == checked)
|
||||
return;
|
||||
m_checked = checked;
|
||||
update();
|
||||
}
|
||||
|
||||
void GButton::paint_event(GPaintEvent& event)
|
||||
{
|
||||
GPainter painter(*this);
|
||||
painter.add_clip_rect(event.rect());
|
||||
|
||||
StylePainter::paint_button(painter, rect(), m_button_style, m_being_pressed, m_hovered, m_checkable && m_checked, is_enabled());
|
||||
StylePainter::paint_button(painter, rect(), m_button_style, is_being_pressed(), is_hovered(), is_checkable() && is_checked(), is_enabled());
|
||||
|
||||
if (m_caption.is_empty() && !m_icon)
|
||||
if (text().is_empty() && !m_icon)
|
||||
return;
|
||||
|
||||
auto content_rect = rect().shrunken(10, 2);
|
||||
auto icon_location = m_icon ? content_rect.center().translated(-(m_icon->width() / 2), -(m_icon->height() / 2)) : Point();
|
||||
if (m_icon && !m_caption.is_empty())
|
||||
if (m_icon && !text().is_empty())
|
||||
icon_location.set_x(content_rect.x());
|
||||
if (m_being_pressed)
|
||||
if (is_being_pressed())
|
||||
painter.translate(1, 1);
|
||||
if (m_icon) {
|
||||
if (is_enabled())
|
||||
|
@ -56,57 +38,27 @@ void GButton::paint_event(GPaintEvent& event)
|
|||
else
|
||||
painter.blit_dimmed(icon_location, *m_icon, m_icon->rect());
|
||||
}
|
||||
auto& font = (m_checkable && m_checked) ? Font::default_bold_font() : this->font();
|
||||
if (m_icon && !m_caption.is_empty()) {
|
||||
auto& font = (is_checkable() && is_checked()) ? Font::default_bold_font() : this->font();
|
||||
if (m_icon && !text().is_empty()) {
|
||||
content_rect.move_by(m_icon->width() + 4, 0);
|
||||
content_rect.set_width(content_rect.width() - m_icon->width() - 4);
|
||||
}
|
||||
if (is_enabled()) {
|
||||
if (!m_caption.is_empty()) {
|
||||
painter.draw_text(content_rect, m_caption, font, text_alignment(), foreground_color(), TextElision::Right);
|
||||
if (!text().is_empty()) {
|
||||
painter.draw_text(content_rect, text(), font, text_alignment(), foreground_color(), TextElision::Right);
|
||||
if (is_focused()) {
|
||||
Rect focus_rect = { 0, 0, font.width(m_caption), font.glyph_height() };
|
||||
Rect focus_rect = { 0, 0, font.width(text()), font.glyph_height() };
|
||||
focus_rect.inflate(6, 4);
|
||||
focus_rect.center_within(content_rect);
|
||||
painter.draw_rect(focus_rect, Color(140, 140, 140));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
painter.draw_text(content_rect.translated(1, 1), m_caption, font, text_alignment(), Color::White, TextElision::Right);
|
||||
painter.draw_text(content_rect, m_caption, font, text_alignment(), Color::from_rgb(0x808080), TextElision::Right);
|
||||
painter.draw_text(content_rect.translated(1, 1), text(), font, text_alignment(), Color::White, TextElision::Right);
|
||||
painter.draw_text(content_rect, text(), font, text_alignment(), Color::from_rgb(0x808080), TextElision::Right);
|
||||
}
|
||||
}
|
||||
|
||||
void GButton::mousemove_event(GMouseEvent& event)
|
||||
{
|
||||
bool is_over = rect().contains(event.position());
|
||||
m_hovered = is_over;
|
||||
if (event.buttons() & GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
bool being_pressed = is_over;
|
||||
if (being_pressed != m_being_pressed) {
|
||||
m_being_pressed = being_pressed;
|
||||
update();
|
||||
}
|
||||
}
|
||||
}
|
||||
GWidget::mousemove_event(event);
|
||||
}
|
||||
|
||||
void GButton::mousedown_event(GMouseEvent& event)
|
||||
{
|
||||
#ifdef GBUTTON_DEBUG
|
||||
dbgprintf("GButton::mouse_down_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
|
||||
#endif
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
m_being_pressed = true;
|
||||
update();
|
||||
}
|
||||
}
|
||||
GWidget::mousedown_event(event);
|
||||
}
|
||||
|
||||
void GButton::click()
|
||||
{
|
||||
if (!is_enabled())
|
||||
|
@ -115,35 +67,6 @@ void GButton::click()
|
|||
on_click(*this);
|
||||
}
|
||||
|
||||
void GButton::mouseup_event(GMouseEvent& event)
|
||||
{
|
||||
#ifdef GBUTTON_DEBUG
|
||||
dbgprintf("GButton::mouse_up_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
|
||||
#endif
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
if (is_enabled()) {
|
||||
bool was_being_pressed = m_being_pressed;
|
||||
m_being_pressed = false;
|
||||
update();
|
||||
if (was_being_pressed)
|
||||
click();
|
||||
}
|
||||
}
|
||||
GWidget::mouseup_event(event);
|
||||
}
|
||||
|
||||
void GButton::enter_event(CEvent&)
|
||||
{
|
||||
m_hovered = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void GButton::leave_event(CEvent&)
|
||||
{
|
||||
m_hovered = false;
|
||||
update();
|
||||
}
|
||||
|
||||
void GButton::set_action(GAction& action)
|
||||
{
|
||||
m_action = action.make_weak_ptr();
|
||||
|
@ -161,10 +84,3 @@ void GButton::set_icon(RetainPtr<GraphicsBitmap>&& icon)
|
|||
m_icon = move(icon);
|
||||
update();
|
||||
}
|
||||
|
||||
void GButton::keydown_event(GKeyEvent& event)
|
||||
{
|
||||
if (event.key() == KeyCode::Key_Return)
|
||||
click();
|
||||
GWidget::keydown_event(event);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/GWidget.h>
|
||||
#include <SharedGraphics/StylePainter.h>
|
||||
#include <AK/AKString.h>
|
||||
#include <AK/Function.h>
|
||||
#include <LibGUI/GAbstractButton.h>
|
||||
#include <SharedGraphics/GraphicsBitmap.h>
|
||||
#include <SharedGraphics/StylePainter.h>
|
||||
#include <SharedGraphics/TextAlignment.h>
|
||||
|
||||
class GAction;
|
||||
|
||||
class GButton : public GWidget {
|
||||
class GButton : public GAbstractButton {
|
||||
public:
|
||||
explicit GButton(GWidget* parent);
|
||||
virtual ~GButton() override;
|
||||
|
||||
String caption() const { return m_caption; }
|
||||
void set_caption(const String&);
|
||||
|
||||
void set_icon(RetainPtr<GraphicsBitmap>&&);
|
||||
const GraphicsBitmap* icon() const { return m_icon.ptr(); }
|
||||
GraphicsBitmap* icon() { return m_icon.ptr(); }
|
||||
|
||||
bool is_checkable() const { return m_checkable; }
|
||||
void set_checkable(bool checkable) { m_checkable = checkable; }
|
||||
|
||||
bool is_checked() const { return m_checked; }
|
||||
void set_checked(bool);
|
||||
|
||||
void set_text_alignment(TextAlignment text_alignment) { m_text_alignment = text_alignment; }
|
||||
TextAlignment text_alignment() const { return m_text_alignment; }
|
||||
|
||||
|
@ -35,7 +26,7 @@ public:
|
|||
void set_button_style(ButtonStyle style) { m_button_style = style; }
|
||||
ButtonStyle button_style() const { return m_button_style; }
|
||||
|
||||
void click();
|
||||
virtual void click() override;
|
||||
|
||||
void set_action(GAction&);
|
||||
|
||||
|
@ -44,22 +35,11 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void paint_event(GPaintEvent&) override;
|
||||
virtual void mousedown_event(GMouseEvent&) override;
|
||||
virtual void mouseup_event(GMouseEvent&) override;
|
||||
virtual void mousemove_event(GMouseEvent&) override;
|
||||
virtual void enter_event(CEvent&) override;
|
||||
virtual void leave_event(CEvent&) override;
|
||||
virtual void keydown_event(GKeyEvent&) override;
|
||||
|
||||
private:
|
||||
String m_caption;
|
||||
RetainPtr<GraphicsBitmap> m_icon;
|
||||
ButtonStyle m_button_style { ButtonStyle::Normal };
|
||||
TextAlignment m_text_alignment { TextAlignment::Center };
|
||||
WeakPtr<GAction> m_action;
|
||||
bool m_being_pressed { false };
|
||||
bool m_hovered { false };
|
||||
bool m_checkable { false };
|
||||
bool m_checked { false };
|
||||
};
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ GFilePicker::GFilePicker(const String& path, CObject* parent)
|
|||
auto* cancel_button = new GButton(button_container);
|
||||
cancel_button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
|
||||
cancel_button->set_preferred_size({ 80, 0 });
|
||||
cancel_button->set_caption("Cancel");
|
||||
cancel_button->set_text("Cancel");
|
||||
cancel_button->on_click = [this] (auto&) {
|
||||
done(ExecCancel);
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ GFilePicker::GFilePicker(const String& path, CObject* parent)
|
|||
auto* ok_button = new GButton(button_container);
|
||||
ok_button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fill);
|
||||
ok_button->set_preferred_size({ 80, 0 });
|
||||
ok_button->set_caption("OK");
|
||||
ok_button->set_text("OK");
|
||||
ok_button->on_click = [this, filename_textbox] (auto&) {
|
||||
FileSystemPath path(String::format("%s/%s", m_model->path().characters(), filename_textbox->text().characters()));
|
||||
m_selected_file = path.string();
|
||||
|
|
|
@ -54,7 +54,7 @@ void GInputBox::build()
|
|||
m_cancel_button = new GButton(button_container_inner);
|
||||
m_cancel_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||
m_cancel_button->set_preferred_size({ 0, 20 });
|
||||
m_cancel_button->set_caption("Cancel");
|
||||
m_cancel_button->set_text("Cancel");
|
||||
m_cancel_button->on_click = [this] (auto&) {
|
||||
dbgprintf("GInputBox: Cancel button clicked\n");
|
||||
done(ExecCancel);
|
||||
|
@ -63,7 +63,7 @@ void GInputBox::build()
|
|||
m_ok_button = new GButton(button_container_inner);
|
||||
m_ok_button->set_size_policy(SizePolicy::Fill, SizePolicy::Fixed);
|
||||
m_ok_button->set_preferred_size({ 0, 20 });
|
||||
m_ok_button->set_caption("OK");
|
||||
m_ok_button->set_text("OK");
|
||||
m_ok_button->on_click = [this] (auto&) {
|
||||
dbgprintf("GInputBox: OK button clicked\n");
|
||||
m_text_value = m_text_editor->text();
|
||||
|
|
|
@ -72,7 +72,7 @@ void GMessageBox::build()
|
|||
auto* button = new GButton(widget);
|
||||
button->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
||||
button->set_preferred_size({ 100, 20 });
|
||||
button->set_caption("OK");
|
||||
button->set_text("OK");
|
||||
button->on_click = [this] (auto&) {
|
||||
dbgprintf("GMessageBox: OK button clicked\n");
|
||||
done(0);
|
||||
|
|
|
@ -7,9 +7,8 @@ static RetainPtr<GraphicsBitmap> s_filled_circle_bitmap;
|
|||
static RetainPtr<GraphicsBitmap> s_changing_filled_circle_bitmap;
|
||||
static RetainPtr<GraphicsBitmap> s_changing_unfilled_circle_bitmap;
|
||||
|
||||
GRadioButton::GRadioButton(const String& label, GWidget* parent)
|
||||
: GWidget(parent)
|
||||
, m_label(label)
|
||||
GRadioButton::GRadioButton(const String& text, GWidget* parent)
|
||||
: GAbstractButton(text, parent)
|
||||
{
|
||||
if (!s_unfilled_circle_bitmap) {
|
||||
s_unfilled_circle_bitmap = GraphicsBitmap::load_from_file("/res/icons/unfilled-radio-circle.png");
|
||||
|
@ -43,13 +42,13 @@ void GRadioButton::paint_event(GPaintEvent& event)
|
|||
Rect circle_rect { { 2, 0 }, circle_size() };
|
||||
circle_rect.center_vertically_within(rect());
|
||||
|
||||
auto& bitmap = circle_bitmap(m_checked, m_changing);
|
||||
auto& bitmap = circle_bitmap(is_checked(), is_being_pressed());
|
||||
painter.blit(circle_rect.location(), bitmap, bitmap.rect());
|
||||
|
||||
if (!m_label.is_empty()) {
|
||||
Rect text_rect { circle_rect.right() + 4, 0, font().width(m_label), font().glyph_height() };
|
||||
if (!text().is_empty()) {
|
||||
Rect text_rect { circle_rect.right() + 4, 0, font().width(text()), font().glyph_height() };
|
||||
text_rect.center_vertically_within(rect());
|
||||
painter.draw_text(text_rect, m_label, TextAlignment::CenterLeft, foreground_color());
|
||||
painter.draw_text(text_rect, text(), TextAlignment::CenterLeft, foreground_color());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,56 +66,13 @@ void GRadioButton::for_each_in_group(Callback callback)
|
|||
}
|
||||
}
|
||||
|
||||
void GRadioButton::mousedown_event(GMouseEvent& event)
|
||||
void GRadioButton::click()
|
||||
{
|
||||
if (event.button() != GMouseButton::Left)
|
||||
if (!is_enabled())
|
||||
return;
|
||||
|
||||
m_changing = rect().contains(event.position());
|
||||
m_tracking = true;
|
||||
update();
|
||||
}
|
||||
|
||||
void GRadioButton::mousemove_event(GMouseEvent& event)
|
||||
{
|
||||
if (m_tracking) {
|
||||
bool old_changing = m_changing;
|
||||
m_changing = rect().contains(event.position());
|
||||
if (old_changing != m_changing)
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void GRadioButton::mouseup_event(GMouseEvent& event)
|
||||
{
|
||||
if (event.button() != GMouseButton::Left)
|
||||
return;
|
||||
|
||||
if (rect().contains(event.position())) {
|
||||
for_each_in_group([this] (auto& button) {
|
||||
if (&button != this)
|
||||
button.set_checked(false);
|
||||
});
|
||||
set_checked(true);
|
||||
}
|
||||
|
||||
m_changing = false;
|
||||
m_tracking = false;
|
||||
update();
|
||||
}
|
||||
|
||||
void GRadioButton::set_label(const String& label)
|
||||
{
|
||||
if (m_label == label)
|
||||
return;
|
||||
m_label = label;
|
||||
update();
|
||||
}
|
||||
|
||||
void GRadioButton::set_checked(bool checked)
|
||||
{
|
||||
if (m_checked == checked)
|
||||
return;
|
||||
m_checked = checked;
|
||||
update();
|
||||
for_each_in_group([this] (auto& button) {
|
||||
if (&button != this)
|
||||
button.set_checked(false);
|
||||
});
|
||||
set_checked(true);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGUI/GWidget.h>
|
||||
#include <LibGUI/GAbstractButton.h>
|
||||
|
||||
class GRadioButton : public GWidget {
|
||||
class GRadioButton : public GAbstractButton {
|
||||
public:
|
||||
GRadioButton(const String& label, GWidget* parent);
|
||||
GRadioButton(const String& text, GWidget* parent);
|
||||
virtual ~GRadioButton() override;
|
||||
|
||||
void set_label(const String&);
|
||||
String label() const { return m_label; }
|
||||
virtual const char* class_name() const override { return "GRadioButton"; }
|
||||
|
||||
bool is_checked() const { return m_checked; }
|
||||
void set_checked(bool);
|
||||
virtual void click() override;
|
||||
|
||||
protected:
|
||||
virtual void paint_event(GPaintEvent&) override;
|
||||
virtual void mousedown_event(GMouseEvent&) override;
|
||||
virtual void mousemove_event(GMouseEvent&) override;
|
||||
virtual void mouseup_event(GMouseEvent&) override;
|
||||
|
||||
private:
|
||||
virtual bool is_radio_button() const final { return true; }
|
||||
|
||||
template<typename Callback> void for_each_in_group(Callback);
|
||||
static Size circle_size();
|
||||
|
||||
String m_label;
|
||||
bool m_checked { false };
|
||||
bool m_changing { false };
|
||||
bool m_tracking { false };
|
||||
};
|
||||
|
|
|
@ -15,10 +15,10 @@ GSpinBox::GSpinBox(GWidget* parent)
|
|||
m_editor->set_text(String::format("%d", m_value));
|
||||
};
|
||||
m_increment_button = new GButton(this);
|
||||
m_increment_button->set_caption("\xf6");
|
||||
m_increment_button->set_text("\xf6");
|
||||
m_increment_button->on_click = [this] (GButton&) { set_value(m_value + 1); };
|
||||
m_decrement_button = new GButton(this);
|
||||
m_decrement_button->set_caption("\xf7");
|
||||
m_decrement_button->set_text("\xf7");
|
||||
m_decrement_button->on_click = [this] (GButton&) { set_value(m_value - 1); };
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ void GToolBar::add_action(Retained<GAction>&& action)
|
|||
if (item->action->icon())
|
||||
button->set_icon(item->action->icon());
|
||||
else
|
||||
button->set_caption(item->action->text());
|
||||
button->set_text(item->action->text());
|
||||
button->on_click = [raw_action_ptr] (const GButton&) {
|
||||
raw_action_ptr->activate();
|
||||
};
|
||||
|
|
|
@ -58,6 +58,7 @@ LIBGUI_OBJS = \
|
|||
GResizeCorner.o \
|
||||
GTabWidget.o \
|
||||
GRadioButton.o \
|
||||
GAbstractButton.o \
|
||||
GWindow.o
|
||||
|
||||
OBJS = $(SHAREDGRAPHICS_OBJS) $(LIBGUI_OBJS)
|
||||
|
|
|
@ -67,7 +67,7 @@ GWindow* make_launcher_window()
|
|||
|
||||
auto* terminal_button = new GButton(widget);
|
||||
terminal_button->set_relative_rect({ 5, 20, 90, 20 });
|
||||
terminal_button->set_caption("Terminal");
|
||||
terminal_button->set_text("Terminal");
|
||||
|
||||
terminal_button->on_click = [label] (GButton&) {
|
||||
pid_t child_pid = fork();
|
||||
|
@ -83,7 +83,7 @@ GWindow* make_launcher_window()
|
|||
|
||||
auto* guitest_button = new GButton(widget);
|
||||
guitest_button->set_relative_rect({ 5, 50, 90, 20 });
|
||||
guitest_button->set_caption("guitest");
|
||||
guitest_button->set_text("guitest");
|
||||
|
||||
guitest_button->on_click = [label] (GButton&) {
|
||||
pid_t child_pid = fork();
|
||||
|
@ -99,7 +99,7 @@ GWindow* make_launcher_window()
|
|||
|
||||
auto* dummy_button = new GButton(widget);
|
||||
dummy_button->set_relative_rect({ 5, 80, 90, 20 });
|
||||
dummy_button->set_caption("Dummy");
|
||||
dummy_button->set_text("Dummy");
|
||||
|
||||
auto* textbox = new GTextBox(widget);
|
||||
textbox->set_relative_rect({ 5, 110, 90, 20 });
|
||||
|
@ -119,7 +119,7 @@ GWindow* make_launcher_window()
|
|||
|
||||
auto* close_button = new GButton(widget);
|
||||
close_button->set_relative_rect({ 5, 200, 90, 20 });
|
||||
close_button->set_caption("Close");
|
||||
close_button->set_text("Close");
|
||||
close_button->on_click = [window] (GButton&) {
|
||||
window->close();
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue