Allow to scroll though meta-button items #9976

This commit is contained in:
Robin Gareus 2025-08-17 06:29:31 +02:00
parent a83c83aef6
commit 26ca954574
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 60 additions and 0 deletions

View file

@ -30,6 +30,7 @@ using namespace ArdourWidgets;
MetaButton::MetaButton ()
: _active (0)
, _hover_dropdown (false)
, _scrolling_disabled (false)
{
_menu.signal_size_request ().connect (sigc::mem_fun (*this, &MetaButton::menu_size_request));
_menu.set_reserve_toggle_size (false);
@ -76,6 +77,7 @@ MetaButton::add_item (std::string const& label, std::string const & menutext, Gt
{
using namespace Menu_Helpers;
_scrolling_disabled = true; // n/a for submenus
add_sizing_text (label);
MenuList& items = _menu.items ();
items.push_back (MetaElement (label, menutext, cb, sigc::mem_fun (*this, &MetaButton::activate_item), submenu));
@ -123,6 +125,57 @@ MetaButton::on_motion_notify_event (GdkEventMotion* ev)
return false;
}
bool
MetaButton::on_scroll_event (GdkEventScroll* ev)
{
using namespace Menu_Helpers;
if (_scrolling_disabled) {
return false;
}
const MenuItem* current_active = _menu.get_active ();
if (!current_active) {
return true;
}
int c = 0;
const MenuList& items = _menu.items ();
switch (ev->direction) {
case GDK_SCROLL_UP:
for (MenuList::const_reverse_iterator i = items.rbegin (); i != items.rend (); ++i, ++c) {
if (&(*i) != current_active) {
continue;
}
if (++i != items.rend ()) {
c = items.size () - 2 - c;
assert (c >= 0);
_menu.set_active (c);
_menu.activate_item (*i);
}
break;
}
break;
case GDK_SCROLL_DOWN:
for (MenuList::const_iterator i = items.begin (); i != items.end (); ++i, ++c) {
if (&(*i) != current_active) {
continue;
}
if (++i != items.end ()) {
assert (c + 1 < (int) items.size ());
_menu.set_active (c + 1);
_menu.activate_item (*i);
}
break;
}
break;
default:
break;
}
return true;
}
void
MetaButton::activate_item (MetaMenuItem const* e)
{

View file

@ -49,9 +49,15 @@ public:
bool is_menu_popup_event (GdkEventButton* ev) const;
void disable_scrolling ()
{
_scrolling_disabled = true;
}
protected:
bool on_button_press_event (GdkEventButton*);
bool on_motion_notify_event (GdkEventMotion*);
bool on_scroll_event (GdkEventScroll*);
void menu_size_request (Gtk::Requisition*);
void render (Cairo::RefPtr<Cairo::Context> const&, cairo_rectangle_t*);
@ -126,6 +132,7 @@ private:
Gtk::Menu _menu;
guint _active;
bool _hover_dropdown;
bool _scrolling_disabled;
};
} // namespace ArdourWidgets