API changes to MetaButton, mostly to allow submenus to be hung from the built menu

This commit is contained in:
Paul Davis 2025-02-07 23:09:02 -07:00
parent 683d2a8c2e
commit fbc55a75b4
2 changed files with 66 additions and 4 deletions

View file

@ -71,16 +71,39 @@ MetaButton::add_item (std::string const& label, std::string const& menutext, sig
}
}
void
MetaButton::add_item (std::string const& label, std::string const & menutext, Gtk::Menu& submenu, sigc::slot<void> const & cb)
{
using namespace Menu_Helpers;
add_sizing_text (label);
MenuList& items = _menu.items ();
items.push_back (MetaElement (label, menutext, cb, sigc::mem_fun (*this, &MetaButton::activate_item), submenu));
if (items.size () == 1) {
_menu.set_active (0);
update_button (dynamic_cast<MetaMenuItem*> (&items.back ()));
set_text (label);
}
}
bool
MetaButton::is_menu_popup_event (GdkEventButton* ev) const
{
return ((ev->type == GDK_BUTTON_PRESS && ev->button == 3) ||
(ev->type == GDK_BUTTON_PRESS && ev->button == 1 && ev->x > (get_width () - _diameter - 7)));
}
bool
MetaButton::on_button_press_event (GdkEventButton* ev)
{
MetaMenuItem const* current_active = dynamic_cast<MetaMenuItem*> (_menu.get_active ());
if (ev->type == GDK_BUTTON_PRESS && ev->button == 3) {
if (is_menu_popup_event (ev)) {
Gtkmm2ext::anchored_menu_popup (&_menu, this, current_active ? current_active->menutext () : "", ev->button, ev->time);
} else if (ev->type == GDK_BUTTON_PRESS && ev->button == 1 && ev->x > (get_width () - _diameter - 7)) {
Gtkmm2ext::anchored_menu_popup (&_menu, this, current_active ? current_active->menutext () : "", ev->button, ev->time);
} else if (ev->type == GDK_BUTTON_PRESS && ev->button == 1) {
return true;
}
if (ev->type == GDK_BUTTON_PRESS && ev->button == 1) {
if (current_active) {
current_active->activate ();
}
@ -136,6 +159,21 @@ MetaButton::set_active (std::string const& menulabel)
}
}
void
MetaButton::set_by_menutext (std::string const & mt)
{
guint c = 0;
for (auto & i : _menu.items()) {
if (i.get_label() == mt) {
_menu.set_active (c);
_active = c;
update_button (dynamic_cast<MetaMenuItem*> (&i));
break;
}
++c;
}
}
void
MetaButton::set_index (guint index)
{

View file

@ -33,16 +33,22 @@ public:
virtual ~MetaButton ();
void add_item (std::string const& label, std::string const& menutext, sigc::slot<void> const&);
void add_item (std::string const& label, std::string const& menutext, Gtk::Menu&, sigc::slot<void> const&);
void clear_items ();
void set_active (std::string const&);
void set_index (guint);
void set_by_menutext (std::string const & mt);
guint index () const
{
return _active;
}
Gtk::Menu& menu() { return _menu; }
bool is_menu_popup_event (GdkEventButton* ev) const;
protected:
bool on_button_press_event (GdkEventButton*);
bool on_motion_notify_event (GdkEventMotion*);
@ -60,6 +66,14 @@ private:
{
}
MetaMenuItem (std::string const& label, std::string const& menutext, sigc::slot<void> const & cb, Gtk::Menu& submenu)
: Gtk::MenuItem (menutext, false)
, _label (label)
, _cb (cb)
{
set_submenu (submenu);
}
void activate () const
{
_cb ();
@ -94,6 +108,16 @@ private:
child_->signal_activate ().connect (sigc::bind (wrap, mmi));
child_->show ();
}
MetaElement (std::string const& label, std::string const & menutext, sigc::slot<void> const & cb, SlotActivate const & wrap, Gtk::Menu& submenu)
: Gtk::Menu_Helpers::MenuElem ("")
{
MetaMenuItem* mmi = manage (new MetaMenuItem (label, menutext, cb, submenu));
child_->unreference ();
set_child (mmi);
child_->signal_activate ().connect (sigc::bind (wrap, mmi));
child_->show ();
}
};
void activate_item (MetaMenuItem const*);