1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-23 06:57:42 +00:00

LibGUI: Add an auto-repeat interval to GAbstractButton.

Use this in GSpinBox to implement auto-increment / auto-decrement while you
are pressing down the respective buttons. :^)
This commit is contained in:
Andreas Kling 2019-07-13 10:27:19 +02:00
parent c53f6a52e0
commit b425de18cc
5 changed files with 35 additions and 2 deletions

View file

@ -2,7 +2,7 @@
#include <LibGUI/GPainter.h> #include <LibGUI/GPainter.h>
GAbstractButton::GAbstractButton(GWidget* parent) GAbstractButton::GAbstractButton(GWidget* parent)
: GWidget(parent) : GAbstractButton({}, parent)
{ {
} }
@ -10,6 +10,9 @@ GAbstractButton::GAbstractButton(const StringView& text, GWidget* parent)
: GWidget(parent) : GWidget(parent)
, m_text(text) , m_text(text)
{ {
m_auto_repeat_timer.on_timeout = [this] {
click();
};
} }
GAbstractButton::~GAbstractButton() GAbstractButton::~GAbstractButton()
@ -65,6 +68,12 @@ void GAbstractButton::mousemove_event(GMouseEvent& event)
bool being_pressed = is_over; bool being_pressed = is_over;
if (being_pressed != m_being_pressed) { if (being_pressed != m_being_pressed) {
m_being_pressed = being_pressed; m_being_pressed = being_pressed;
if (m_auto_repeat_interval) {
if (!m_being_pressed)
m_auto_repeat_timer.stop();
else
m_auto_repeat_timer.start(m_auto_repeat_interval);
}
update(); update();
} }
} }
@ -81,6 +90,11 @@ void GAbstractButton::mousedown_event(GMouseEvent& event)
if (is_enabled()) { if (is_enabled()) {
m_being_pressed = true; m_being_pressed = true;
update(); update();
if (m_auto_repeat_interval) {
click();
m_auto_repeat_timer.start(m_auto_repeat_interval);
}
} }
} }
GWidget::mousedown_event(event); GWidget::mousedown_event(event);
@ -92,11 +106,13 @@ void GAbstractButton::mouseup_event(GMouseEvent& event)
dbgprintf("GAbstractButton::mouse_up_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button()); dbgprintf("GAbstractButton::mouse_up_event: x=%d, y=%d, button=%u\n", event.x(), event.y(), (unsigned)event.button());
#endif #endif
if (event.button() == GMouseButton::Left) { if (event.button() == GMouseButton::Left) {
bool was_auto_repeating = m_auto_repeat_timer.is_active();
m_auto_repeat_timer.stop();
if (is_enabled()) { if (is_enabled()) {
bool was_being_pressed = m_being_pressed; bool was_being_pressed = m_being_pressed;
m_being_pressed = false; m_being_pressed = false;
update(); update();
if (was_being_pressed) if (was_being_pressed && !was_auto_repeating)
click(); click();
} }
} }

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <LibCore/CTimer.h>
#include <LibGUI/GWidget.h> #include <LibGUI/GWidget.h>
#include <SharedGraphics/TextAlignment.h> #include <SharedGraphics/TextAlignment.h>
@ -32,6 +33,9 @@ public:
virtual bool supports_keyboard_activation() const override { return true; } virtual bool supports_keyboard_activation() const override { return true; }
virtual bool is_uncheckable() const { return true; } virtual bool is_uncheckable() const { return true; }
int auto_repeat_interval() const { return m_auto_repeat_interval; }
void set_auto_repeat_interval(int interval) { m_auto_repeat_interval = interval; }
protected: protected:
explicit GAbstractButton(GWidget* parent); explicit GAbstractButton(GWidget* parent);
GAbstractButton(const StringView&, GWidget* parent); GAbstractButton(const StringView&, GWidget* parent);
@ -55,6 +59,9 @@ private:
bool m_hovered { false }; bool m_hovered { false };
bool m_being_pressed { false }; bool m_being_pressed { false };
bool m_exclusive { false }; bool m_exclusive { false };
int m_auto_repeat_interval { 0 };
CTimer m_auto_repeat_timer;
}; };
template<> template<>

View file

@ -15,5 +15,9 @@ public:
virtual const char* class_name() const override { return "GCheckBox"; } virtual const char* class_name() const override { return "GCheckBox"; }
private: private:
// These don't make sense for a check box, so hide them.
using GAbstractButton::auto_repeat_interval;
using GAbstractButton::set_auto_repeat_interval;
virtual void paint_event(GPaintEvent&) override; virtual void paint_event(GPaintEvent&) override;
}; };

View file

@ -15,6 +15,10 @@ protected:
virtual void paint_event(GPaintEvent&) override; virtual void paint_event(GPaintEvent&) override;
private: private:
// These don't make sense for a radio button, so hide them.
using GAbstractButton::auto_repeat_interval;
using GAbstractButton::set_auto_repeat_interval;
virtual bool is_radio_button() const final { return true; } virtual bool is_radio_button() const final { return true; }
template<typename Callback> template<typename Callback>

View file

@ -19,10 +19,12 @@ GSpinBox::GSpinBox(GWidget* parent)
m_increment_button->set_focusable(false); m_increment_button->set_focusable(false);
m_increment_button->set_text("\xf6"); m_increment_button->set_text("\xf6");
m_increment_button->on_click = [this](GButton&) { set_value(m_value + 1); }; m_increment_button->on_click = [this](GButton&) { set_value(m_value + 1); };
m_increment_button->set_auto_repeat_interval(150);
m_decrement_button = new GButton(this); m_decrement_button = new GButton(this);
m_decrement_button->set_focusable(false); m_decrement_button->set_focusable(false);
m_decrement_button->set_text("\xf7"); m_decrement_button->set_text("\xf7");
m_decrement_button->on_click = [this](GButton&) { set_value(m_value - 1); }; m_decrement_button->on_click = [this](GButton&) { set_value(m_value - 1); };
m_decrement_button->set_auto_repeat_interval(150);
} }
GSpinBox::~GSpinBox() GSpinBox::~GSpinBox()