mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:57:35 +00:00
LibGUI: Allow Buttons to set themselves as default
Several apps were implementing this behavior ad hoc. This provides a standard API as well as a comfy visual cue for default return key behavior.
This commit is contained in:
parent
aefe3ef539
commit
f77ac3a73c
6 changed files with 42 additions and 10 deletions
|
@ -10,6 +10,7 @@
|
||||||
#include <LibGUI/Button.h>
|
#include <LibGUI/Button.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
|
#include <LibGUI/Window.h>
|
||||||
#include <LibGfx/Font.h>
|
#include <LibGfx/Font.h>
|
||||||
#include <LibGfx/Palette.h>
|
#include <LibGfx/Palette.h>
|
||||||
#include <LibGfx/StylePainter.h>
|
#include <LibGfx/StylePainter.h>
|
||||||
|
@ -25,6 +26,16 @@ Button::Button(String text)
|
||||||
set_fixed_height(22);
|
set_fixed_height(22);
|
||||||
set_focus_policy(GUI::FocusPolicy::StrongFocus);
|
set_focus_policy(GUI::FocusPolicy::StrongFocus);
|
||||||
|
|
||||||
|
on_focus_change = [this](bool has_focus, auto) {
|
||||||
|
if (!is_default())
|
||||||
|
return;
|
||||||
|
if (!has_focus && is<Button>(window()->focused_widget()))
|
||||||
|
m_another_button_has_focus = true;
|
||||||
|
else
|
||||||
|
m_another_button_has_focus = false;
|
||||||
|
update();
|
||||||
|
};
|
||||||
|
|
||||||
REGISTER_ENUM_PROPERTY(
|
REGISTER_ENUM_PROPERTY(
|
||||||
"button_style", button_style, set_button_style, Gfx::ButtonStyle,
|
"button_style", button_style, set_button_style, Gfx::ButtonStyle,
|
||||||
{ Gfx::ButtonStyle::Normal, "Normal" },
|
{ Gfx::ButtonStyle::Normal, "Normal" },
|
||||||
|
@ -46,7 +57,7 @@ void Button::paint_event(PaintEvent& event)
|
||||||
|
|
||||||
bool paint_pressed = is_being_pressed() || (m_menu && m_menu->is_visible());
|
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());
|
Gfx::StylePainter::paint_button(painter, rect(), palette(), m_button_style, paint_pressed, is_hovered(), is_checked(), is_enabled(), is_focused(), is_default() & !another_button_has_focus());
|
||||||
|
|
||||||
if (text().is_empty() && !m_icon)
|
if (text().is_empty() && !m_icon)
|
||||||
return;
|
return;
|
||||||
|
@ -193,4 +204,19 @@ void Button::mousemove_event(MouseEvent& event)
|
||||||
AbstractButton::mousemove_event(event);
|
AbstractButton::mousemove_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Button::is_default() const
|
||||||
|
{
|
||||||
|
if (!window())
|
||||||
|
return false;
|
||||||
|
return this == window()->default_return_key_widget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Button::set_default(bool default_button)
|
||||||
|
{
|
||||||
|
deferred_invoke([this, default_button] {
|
||||||
|
VERIFY(window());
|
||||||
|
window()->set_default_return_key_widget(default_button ? this : nullptr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,11 @@ public:
|
||||||
|
|
||||||
void set_menu(RefPtr<GUI::Menu>);
|
void set_menu(RefPtr<GUI::Menu>);
|
||||||
|
|
||||||
|
bool is_default() const;
|
||||||
|
void set_default(bool);
|
||||||
|
|
||||||
|
bool another_button_has_focus() const { return m_another_button_has_focus; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Button(String text = {});
|
explicit Button(String text = {});
|
||||||
virtual void mousedown_event(MouseEvent&) override;
|
virtual void mousedown_event(MouseEvent&) override;
|
||||||
|
@ -61,6 +66,7 @@ private:
|
||||||
Gfx::TextAlignment m_text_alignment { Gfx::TextAlignment::Center };
|
Gfx::TextAlignment m_text_alignment { Gfx::TextAlignment::Center };
|
||||||
WeakPtr<Action> m_action;
|
WeakPtr<Action> m_action;
|
||||||
int m_icon_spacing { 4 };
|
int m_icon_spacing { 4 };
|
||||||
|
bool m_another_button_has_focus { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,7 @@ void ClassicStylePainter::paint_tab_button(Painter& painter, IntRect const& rect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paint_button_new(Painter& painter, IntRect const& a_rect, Palette const& palette, ButtonStyle style, bool pressed, bool checked, bool hovered, bool enabled, bool focused)
|
static void paint_button_new(Painter& painter, IntRect const& a_rect, Palette const& palette, ButtonStyle style, bool pressed, bool checked, bool hovered, bool enabled, bool focused, bool default_button)
|
||||||
{
|
{
|
||||||
Color button_color = palette.button();
|
Color button_color = palette.button();
|
||||||
Color highlight_color = palette.threed_highlight();
|
Color highlight_color = palette.threed_highlight();
|
||||||
|
@ -111,7 +111,7 @@ static void paint_button_new(Painter& painter, IntRect const& a_rect, Palette co
|
||||||
PainterStateSaver saver(painter);
|
PainterStateSaver saver(painter);
|
||||||
|
|
||||||
auto rect = a_rect;
|
auto rect = a_rect;
|
||||||
if (focused) {
|
if (focused || default_button) {
|
||||||
painter.draw_rect(a_rect, palette.threed_shadow2());
|
painter.draw_rect(a_rect, palette.threed_shadow2());
|
||||||
rect.shrink(2, 2);
|
rect.shrink(2, 2);
|
||||||
}
|
}
|
||||||
|
@ -165,10 +165,10 @@ static void paint_button_new(Painter& painter, IntRect const& a_rect, Palette co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicStylePainter::paint_button(Painter& painter, IntRect const& rect, Palette const& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled, bool focused)
|
void ClassicStylePainter::paint_button(Painter& painter, IntRect const& rect, Palette const& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled, bool focused, bool default_button)
|
||||||
{
|
{
|
||||||
if (button_style == ButtonStyle::Normal || button_style == ButtonStyle::ThickCap)
|
if (button_style == ButtonStyle::Normal || button_style == ButtonStyle::ThickCap)
|
||||||
return paint_button_new(painter, rect, palette, button_style, pressed, checked, hovered, enabled, focused);
|
return paint_button_new(painter, rect, palette, button_style, pressed, checked, hovered, enabled, focused, default_button);
|
||||||
|
|
||||||
if (button_style == ButtonStyle::Coolbar && !enabled)
|
if (button_style == ButtonStyle::Coolbar && !enabled)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace Gfx {
|
||||||
|
|
||||||
class ClassicStylePainter : public BaseStylePainter {
|
class ClassicStylePainter : public BaseStylePainter {
|
||||||
public:
|
public:
|
||||||
virtual void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false) override;
|
virtual void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false, bool default_button = false) override;
|
||||||
virtual void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window) override;
|
virtual void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window) override;
|
||||||
virtual void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) override;
|
virtual void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) override;
|
||||||
virtual void paint_window_frame(Painter&, IntRect const&, Palette const&) override;
|
virtual void paint_window_frame(Painter&, IntRect const&, Palette const&) override;
|
||||||
|
|
|
@ -23,9 +23,9 @@ void StylePainter::paint_tab_button(Painter& painter, const IntRect& rect, const
|
||||||
current().paint_tab_button(painter, rect, palette, active, hovered, enabled, top, in_active_window);
|
current().paint_tab_button(painter, rect, palette, active, hovered, enabled, top, in_active_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StylePainter::paint_button(Painter& painter, const IntRect& rect, const Palette& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled, bool focused)
|
void StylePainter::paint_button(Painter& painter, const IntRect& rect, const Palette& palette, ButtonStyle button_style, bool pressed, bool hovered, bool checked, bool enabled, bool focused, bool default_button)
|
||||||
{
|
{
|
||||||
current().paint_button(painter, rect, palette, button_style, pressed, hovered, checked, enabled, focused);
|
current().paint_button(painter, rect, palette, button_style, pressed, hovered, checked, enabled, focused, default_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StylePainter::paint_frame(Painter& painter, const IntRect& rect, const Palette& palette, FrameShape shape, FrameShadow shadow, int thickness, bool skip_vertical_lines)
|
void StylePainter::paint_frame(Painter& painter, const IntRect& rect, const Palette& palette, FrameShape shape, FrameShadow shadow, int thickness, bool skip_vertical_lines)
|
||||||
|
|
|
@ -37,7 +37,7 @@ class BaseStylePainter {
|
||||||
public:
|
public:
|
||||||
virtual ~BaseStylePainter() { }
|
virtual ~BaseStylePainter() { }
|
||||||
|
|
||||||
virtual void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false) = 0;
|
virtual void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false, bool default_button = false) = 0;
|
||||||
virtual void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window) = 0;
|
virtual void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window) = 0;
|
||||||
virtual void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) = 0;
|
virtual void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false) = 0;
|
||||||
virtual void paint_window_frame(Painter&, IntRect const&, Palette const&) = 0;
|
virtual void paint_window_frame(Painter&, IntRect const&, Palette const&) = 0;
|
||||||
|
@ -56,7 +56,7 @@ public:
|
||||||
static BaseStylePainter& current();
|
static BaseStylePainter& current();
|
||||||
|
|
||||||
// FIXME: These are here for API compatibility, we should probably remove them and move BaseStylePainter into here
|
// FIXME: These are here for API compatibility, we should probably remove them and move BaseStylePainter into here
|
||||||
static void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false);
|
static void paint_button(Painter&, IntRect const&, Palette const&, ButtonStyle, bool pressed, bool hovered = false, bool checked = false, bool enabled = true, bool focused = false, bool default_button = false);
|
||||||
static void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window);
|
static void paint_tab_button(Painter&, IntRect const&, Palette const&, bool active, bool hovered, bool enabled, bool top, bool in_active_window);
|
||||||
static void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false);
|
static void paint_frame(Painter&, IntRect const&, Palette const&, FrameShape, FrameShadow, int thickness, bool skip_vertical_lines = false);
|
||||||
static void paint_window_frame(Painter&, IntRect const&, Palette const&);
|
static void paint_window_frame(Painter&, IntRect const&, Palette const&);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue