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
Notes: sideshowbarker 2024-07-19 13:18:32 +09:00
5 changed files with 35 additions and 2 deletions

View file

@ -2,7 +2,7 @@
#include <LibGUI/GPainter.h>
GAbstractButton::GAbstractButton(GWidget* parent)
: GWidget(parent)
: GAbstractButton({}, parent)
{
}
@ -10,6 +10,9 @@ GAbstractButton::GAbstractButton(const StringView& text, GWidget* parent)
: GWidget(parent)
, m_text(text)
{
m_auto_repeat_timer.on_timeout = [this] {
click();
};
}
GAbstractButton::~GAbstractButton()
@ -65,6 +68,12 @@ void GAbstractButton::mousemove_event(GMouseEvent& event)
bool being_pressed = is_over;
if (being_pressed != m_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();
}
}
@ -81,6 +90,11 @@ void GAbstractButton::mousedown_event(GMouseEvent& event)
if (is_enabled()) {
m_being_pressed = true;
update();
if (m_auto_repeat_interval) {
click();
m_auto_repeat_timer.start(m_auto_repeat_interval);
}
}
}
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());
#endif
if (event.button() == GMouseButton::Left) {
bool was_auto_repeating = m_auto_repeat_timer.is_active();
m_auto_repeat_timer.stop();
if (is_enabled()) {
bool was_being_pressed = m_being_pressed;
m_being_pressed = false;
update();
if (was_being_pressed)
if (was_being_pressed && !was_auto_repeating)
click();
}
}

View file

@ -1,5 +1,6 @@
#pragma once
#include <LibCore/CTimer.h>
#include <LibGUI/GWidget.h>
#include <SharedGraphics/TextAlignment.h>
@ -32,6 +33,9 @@ public:
virtual bool supports_keyboard_activation() const override { 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:
explicit GAbstractButton(GWidget* parent);
GAbstractButton(const StringView&, GWidget* parent);
@ -55,6 +59,9 @@ private:
bool m_hovered { false };
bool m_being_pressed { false };
bool m_exclusive { false };
int m_auto_repeat_interval { 0 };
CTimer m_auto_repeat_timer;
};
template<>

View file

@ -15,5 +15,9 @@ public:
virtual const char* class_name() const override { return "GCheckBox"; }
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;
};

View file

@ -15,6 +15,10 @@ protected:
virtual void paint_event(GPaintEvent&) override;
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; }
template<typename Callback>

View file

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