diff --git a/src/gui/widgets/menu-button.cpp b/src/gui/widgets/menu-button.cpp index 853c07474..8f7d1f0b2 100644 --- a/src/gui/widgets/menu-button.cpp +++ b/src/gui/widgets/menu-button.cpp @@ -26,8 +26,11 @@ using namespace Gtk; +using namespace Glib; using namespace sigc; +#define POPUP_SLUG "TheMenu" +#define POPUP_PATH "/" POPUP_SLUG const int CaptionPadding = 4; namespace gui { @@ -38,7 +41,9 @@ const ShadowType shadowType = SHADOW_NONE; MenuButton::MenuButton() : ToggleButton(), - arrow(arrowType, shadowType) + arrow(arrowType, shadowType), + uimanager(UIManager::create()), + actions(ActionGroup::create()) { setup_button(); } @@ -52,9 +57,7 @@ MenuButton::MenuButton(const StockID& stock_id) : StockItem stock_item; REQUIRE(StockItem::lookup(stock_id, stock_item)); caption.set_text_with_mnemonic(stock_item.get_label()); - hBox.pack_start(image); - setup_button(); } @@ -66,24 +69,61 @@ MenuButton::MenuButton(cuString& label, bool mnemonic) : setup_button(); } -Gtk::Menu& +Menu& MenuButton::get_menu() { - return menu; + uString path ("/"); + path.append (POPUP_SLUG); + Menu* p_menu = dynamic_cast( + uimanager->get_widget(path)); + REQUIRE (p_menu); + return *p_menu; +} + +void +MenuButton::append (uString &slug, uString &title, + sigc::slot &callback) +{ + actions->add(Action::create(slug, title), callback); + uimanager->add_ui(uimanager->new_merge_id(), + ustring("ui/").append(POPUP_SLUG), + title,slug, Gtk::UI_MANAGER_MENUITEM, + false); + uimanager->ensure_update(); +} + +void +MenuButton::append (const char *slug, const char* title, + sigc::slot& callback) +{ + uString uSlug (slug); + uString uTitle (_(title)); + append (uSlug, uTitle, callback); } void MenuButton::popup() { - menu.popup( mem_fun(this, &MenuButton::on_menu_position), + get_menu().popup( mem_fun(this, &MenuButton::on_menu_position), 0, gtk_get_current_event_time()); set_active(); + dump_xml(); } void MenuButton::setup_button() { - menu.signal_deactivate().connect(mem_fun( + uimanager = UIManager::create(); + actions = ActionGroup::create(); + uimanager->insert_action_group(actions); + + // Setup the UIManager with a popup menu + const guint rootId = uimanager->new_merge_id(); + uimanager->add_ui(rootId, "ui", + POPUP_SLUG, POPUP_SLUG, + Gtk::UI_MANAGER_POPUP); + + get_menu().signal_deactivate().connect(mem_fun( this, &MenuButton::on_menu_deactivated)); arrow.set(ARROW_DOWN, SHADOW_NONE); diff --git a/src/gui/widgets/menu-button.hpp b/src/gui/widgets/menu-button.hpp index 25d343a4a..0197ecb96 100644 --- a/src/gui/widgets/menu-button.hpp +++ b/src/gui/widgets/menu-button.hpp @@ -28,49 +28,58 @@ #include "gui/gtk-base.hpp" +#include + + +using namespace Gtk; + namespace gui { namespace widgets { /** * A button that display a menu when clicked on. */ -class MenuButton : public Gtk::ToggleButton +class MenuButton : public ToggleButton { public: /** * Create an empty button. - * @remarks With an empty button, you can Gtk::Button::add() a widget - * such as a Gtk::Pixmap or Gtk::Box. If you just wish to add a - * Gtk::Label, you may want to use the - * Gtk::MenuButton(cuString& label) ctor directly instead. + * @remarks With an empty button, you can Button::add() a widget + * such as a Pixmap or Box. If you just wish to add a + * Label, you may want to use the + * MenuButton(cuString& label) ctor directly instead. */ MenuButton(); /** * Creates a new Button containing the image and text from a stock * item. - * @remarks Stock ids have identifiers like Gtk::Stock::OK and - * Gtk::Stock::APPLY. + * @remarks Stock ids have identifiers like Stock::OK and + * Stock::APPLY. */ - MenuButton(const Gtk::StockID& stock_id); + MenuButton(const StockID& stock_id); /** * Creates a simple Push Button with label. * @remarks Create a button with the given label inside. You won't be * able to add a widget in this button since it already has a - * Gtk::Label in it + * Label in it */ MenuButton(cuString& label, bool mnemonic=false); + void dump_xml() { std::cout << uimanager->get_ui() << std::endl; } /** * Gets the menu which will be displayed when the button is clicked * on. * @return Returns a reference to the menu that will be clicked on. * This reference can be used to populate the menu with items. */ - Gtk::Menu& get_menu(); + Menu& get_menu(); + void append (uString &slug, uString &title, sigc::slot& callback); + void append (const char *slug, const char* title, sigc::slot& callback); + /** * Pops up the menu. */ @@ -79,7 +88,7 @@ public: protected: /** - * An internal method which sets up the button at creat time. + * An internal method which sets up the button at create time. */ void setup_button(); @@ -112,28 +121,31 @@ private: /** * The hBox for the layout of image, caption and arrow. */ - Gtk::HBox hBox; + HBox hBox; /** * The image that will optionally display an icon. */ - Gtk::Image image; + Image image; /** * The caption text label to show on the button. */ - Gtk::Label caption; + Label caption; /** * The arrow widget that will be displayed to hint the user that this * button is a drop-down. */ - Gtk::Arrow arrow; + Arrow arrow; /** * The internal menu object which is the popup menu of this widget. */ - Gtk::Menu menu; + Menu menu; + + Glib::RefPtr uimanager; + Glib::RefPtr actions; };