summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGUI
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-04-05 14:33:13 +0200
committerAndreas Kling <kling@serenityos.org>2021-04-05 18:09:04 +0200
commit15349a3712dabd4ab314db45d70d9279548a2762 (patch)
treefee0a1221ced696d0c88272a59902055ddde45d4 /Userland/Libraries/LibGUI
parent9b740f218b103a5f3497a666b2655865266c8ff1 (diff)
downloadserenity-15349a3712dabd4ab314db45d70d9279548a2762.zip
LibGUI: Add ability to assign a menu to a GUI::Button
When a button has a menu, it opens the menu on mousedown and the menu gains input focus immediately. While the menu is open, the button is painted in a pressed state.
Diffstat (limited to 'Userland/Libraries/LibGUI')
-rw-r--r--Userland/Libraries/LibGUI/Button.cpp35
-rw-r--r--Userland/Libraries/LibGUI/Button.h6
2 files changed, 36 insertions, 5 deletions
diff --git a/Userland/Libraries/LibGUI/Button.cpp b/Userland/Libraries/LibGUI/Button.cpp
index 17b0f07667..a7172ffc7f 100644
--- a/Userland/Libraries/LibGUI/Button.cpp
+++ b/Userland/Libraries/LibGUI/Button.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,6 +28,7 @@
#include <LibGUI/Action.h>
#include <LibGUI/ActionGroup.h>
#include <LibGUI/Button.h>
+#include <LibGUI/Menu.h>
#include <LibGUI/Painter.h>
#include <LibGfx/Font.h>
#include <LibGfx/FontDatabase.h>
@@ -62,7 +63,9 @@ void Button::paint_event(PaintEvent& event)
Painter painter(*this);
painter.add_clip_rect(event.rect());
- Gfx::StylePainter::paint_button(painter, rect(), palette(), m_button_style, is_being_pressed(), is_hovered(), is_checked(), is_enabled(), is_focused());
+ bool paint_pressed = is_being_pressed() || (m_menu && m_menu->is_visible());
+
+ Gfx::StylePainter::paint_button(painter, rect(), palette(), m_button_style, paint_pressed, is_hovered(), is_checked(), is_enabled(), is_focused());
if (text().is_empty() && !m_icon)
return;
@@ -72,9 +75,9 @@ void Button::paint_event(PaintEvent& event)
if (m_icon && !text().is_empty())
icon_location.set_x(content_rect.x());
- if (is_being_pressed() || is_checked())
+ if (paint_pressed || is_checked()) {
painter.translate(1, 1);
- else if (m_icon && is_enabled() && is_hovered() && button_style() == Gfx::ButtonStyle::CoolBar) {
+ } else if (m_icon && is_enabled() && is_hovered() && button_style() == Gfx::ButtonStyle::CoolBar) {
auto shadow_color = palette().button().darkened(0.7f);
painter.blit_filtered(icon_location.translated(1, 1), *m_icon, m_icon->rect(), [&shadow_color](auto) {
return shadow_color;
@@ -167,4 +170,28 @@ bool Button::is_uncheckable() const
return m_action->group()->is_unchecking_allowed();
}
+void Button::set_menu(RefPtr<GUI::Menu> menu)
+{
+ if (m_menu == menu)
+ return;
+ if (m_menu)
+ m_menu->on_visibility_change = nullptr;
+ m_menu = menu;
+ if (m_menu) {
+ m_menu->on_visibility_change = [&](bool) {
+ update();
+ };
+ }
+}
+
+void Button::mousedown_event(MouseEvent& event)
+{
+ if (m_menu) {
+ m_menu->popup(screen_relative_rect().top_left());
+ update();
+ return;
+ }
+ AbstractButton::mousedown_event(event);
+}
+
}
diff --git a/Userland/Libraries/LibGUI/Button.h b/Userland/Libraries/LibGUI/Button.h
index e16c0dad2e..b45ef9812f 100644
--- a/Userland/Libraries/LibGUI/Button.h
+++ b/Userland/Libraries/LibGUI/Button.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -63,12 +63,16 @@ public:
int icon_spacing() const { return m_icon_spacing; }
void set_icon_spacing(int spacing) { m_icon_spacing = spacing; }
+ void set_menu(RefPtr<GUI::Menu>);
+
protected:
explicit Button(String text = {});
+ virtual void mousedown_event(MouseEvent&) override;
virtual void paint_event(PaintEvent&) override;
private:
RefPtr<Gfx::Bitmap> m_icon;
+ RefPtr<GUI::Menu> m_menu;
Gfx::ButtonStyle m_button_style { Gfx::ButtonStyle::Normal };
Gfx::TextAlignment m_text_alignment { Gfx::TextAlignment::Center };
WeakPtr<Action> m_action;