GMenu, GAction and GtkBuilder



Here is a description of the gtkmm menu API that should replace
GtkUIManager. I'll reply with some opinions about the API and reasons
why I don't think we should actually deprecate UIManager yet.

For a fairly complete example, just look here:
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus/main_menu/examplewindow.cc

* Actions:

We can replace Gtk::Action/Gtk::ToggleAction/Gtk::RadioAction instances
with Gio::Action. You'll actually want to use Gio::SimpleAction in most
cases, because it has useful API.
See
https://developer.gnome.org/glibmm/unstable/classGio_1_1SimpleAction.html

We replace Gtk::ActionGroup with Gio::ActionGroup, though you'll want to
actually use Gio::SimpleActionGroup because you can add actions to it.
See
https://developer.gnome.org/glibmm/unstable/classGio_1_1SimpleActionGroup.html

We replace calls to
  Gtk::ActionGroup::add("action-name", "Action Title", signal_handler)
with
  Gio::SimpleActionGroup::add_action("action-name", signal_handler)

The Action Title now becomes just a menu item title and is specified in
the XML.

We replace GtkUIManager with GtkBuilder, using its <menu> syntax instead
of the old <ui> syntax.


* Toggle and Radio items:

Toggle items and Radio items are a bit strange. Both are demonstrated
here, and are not as simple as the old GtkToggleAction and
GtkRadioAction:
https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/menus/main_menu/examplewindow.cc


** Toggle items:
For a toggle item we add a "bool" action, which is just a regular
GAction with a boolean "state". For instance, with gtkmm:
  m_refToggle = refActionGroup->add_action_bool("sometoggle",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_toggle),
    false); //false is the default value
And we would lay that out in the glade file like any other menu item.

Unlike with GtkAction, in the signal handler, we must now explicitly
toggle that state. Otherwise clicking the menu item won't change it's
appearance at all. For instance:
  void ExampleWindow::on_menu_toggle()
  {
    bool active = false;
    m_refToggle->get_state(active);
    m_refToggle->change_state(!active);

Obviously, it's good that this gives you the chance to reject the change
and complain to the user, though I feel that that's the unusual case and
shouldn't be the default.


** Radio items:

Radio items are even stranger. Unlike GtkRadioAction, we now have just
one GAction to represent, for instance, 3 radio menu items. That GAction
has a state, whose type you must choose. gtkmm has convenience methods
to create string-based or integer-based radio actions. For instance:
  m_refChoice = refActionGroup->add_action_radio_string("choice",
    sigc::mem_fun(*this, &ExampleWindow::on_menu_choices),
    "a"); //"a" is the default value.

Unlike with toggle items, we get the chosen state via the action's
"parameter". Like toggle items, we need to actually set the state to see
any visual effect. For instance:
   void ExampleWindow::on_menu_choices(const Glib::ustring& parameter)
   {
     m_refChoice->change_state(parameter);

Again, I find this a bit tedious.

We specify the possible states in the XML, as "target" values for an
<item>. Several radio items can have the same action name, but different
target values. 


* Summary

As a complete porting example, this commit replaces the use of UIManager
+GtkMenu with Builder+GMenu in one of our examples:
https://git.gnome.org/browse/gtkmm-documentation/commit/?id=9ce75deddf75822fe06406f1b86123661c64b02d
And this one adds back the toolbar:
https://git.gnome.org/browse/gtkmm-documentation/commit/?id=8ffa9a16fc773a472f6fa13d262cc20a9a31c318


-- 
Murray Cumming
murrayc murrayc com
www.murrayc.com
www.openismus.com



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]