Re: [gtkmm] Menu accel API review



On Thu, 2002-08-01 at 20:12, Murray Cumming wrote:
> On Wed, 2002-07-31 at 23:47, Andreas Holzmann wrote:
> > I've reverted Menu::popup() to its old state. You have to call
> > accelerate() manually for popup menus. One reason is, as someone also
> > mentioned, you don't always have a window pointer when calling
> > popup(). But most important, as the current implementation calls
> > accelerate in popup(), the accelerators do only work if the user
> > already has opened the popup with the mouse. Only then he can use the
> > keyboard shortcut. This would be very confusing for users.

The whole point is, that you need an AccelGroup to initialize the
accelerators. The AccelGroup must be bound to a window. (In Gtkmm
an AccelGroup is even stored in the Window object.) 

> So there really is no way around calling acclerate() just before calling
> popup()? Because:
> - We can't call it in the constructor because the menu items haven't
> been added yet.

Which constructor? Of the Menu object? It doesn't know the window
it will be opened in. 

> - We can't call it after adding menu items because they the Window might
> not have been realized (not sure about this one).

This works. This is how it is done in the examples. The Window doesn't
need to be realized.

> - We can't call it during popup() because the whole point of
> acceleration is that it works _before_ the menu has been shown.

Yes.

> So what is the best time to call acclerate()?

After you've build the popup menu.

e.g.
Gtk::Menu* menu = manage(new Gtk::Menu());
menu->items().push_back(MenuElem("Quit", AccelKey("<control>q")));
menu->items().push_back(MenuElem("Close", AccelKey("<control>w")));
menu->accelerate(window->get_accel_group());
... later
menu->popup(...)

You can see accelerate() as convenience method. A more direct c->c++
implementation would be:

Gtk::Menu* menu = manage(new Gtk::Menu());
menu->items().push_back(MenuElem("Quit"));
menu->items().back().add_accelerator("activate",
                                     window->get_accel_group(),
                                     'q', Gdk::CONTROL_MASK,
                                     Gtk::ACCEL_VISIBLE);
menu->items().push_back(MenuElem("Close"));
menu->items().back().add_accelerator("activate",
                                     window->get_accel_group(),
                                     'q', Gdk::CONTROL_MASK,
                                     Gtk::ACCEL_VISIBLE);
... later
menu->popup(...)

This is how a C developer would build accelerated menues if he doesn't
use gtkitemfactory. As you see you need an AccelGroup each time. This is
also used in demos/gtk-demo/example_menus.cc to setup "locked"
accelerators.

 Andreas




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