Re: dynamic accelerators



On Tue, 2008-07-29 at 12:05 -0700, Wesley Smith wrote:
> Hi John,
> Thanks for the code and link.  This was definitely a step in the right
> direction.  One issue though is you're using a GtkUIManager and
> loading in structure via strings.  I'm generating the entire menu
> procedurally depending on user input so I can't do this.  From looking
> at your code, this leaves a gap between a GtkActionGroup and a
> GtkAccelGroup that I don't know how to mediate.
> 
> Let's say I already have a window with a menu bar and menus with
> submenus attached to them.  How can I use the GtkActionGroup and
> GtkAccelGroup classes to generate accelerators for the menu?  I'm
> still not seeing any straightforward way of doing this.
> 
> For example, I have a GtkMenuItem object and I know it should have the
> accelerator Control+q.  I also have a GtkWindow which the menu item is
> attached to via the menu bar.  What API call(s) can I use to say "For
> this window with this menu item, attach the accelerator control+q"?
> It seems there are only very roundabout ways of doing this and I'm not
> familiar enough with how the GTK system is structured to see that path
> yet.  Any pointers on this one?

its going to be a mess one way or another. GTK's handling of key events
and bindings is very fragmented and messy, and you will find that things
done one way work, and another way do not work. sometimes :)

it will be less of a mess, and you'll probably have less issues long
term, if you move away from constructing menu items etc, and instead
build Actions and then strings to feed to the UI manager and then fetch
a menu/menubar/whatever from it.

below is some code i use to combine AccelMaps (bindings stored outside
the program and loaded at runtime) with a key-binding editor dialog. the
user can select a named action (any action that exists in the program,
anywhere) and press a key to rebind. it may provide a few clues to
things you should read about and play around with.


bool
KeyEditor::on_key_release_event (GdkEventKey* ev)
{
	if (ARDOUR::Profile->get_sae() || !can_bind || ev->state != last_state)
{
		return false;
	}

	TreeModel::iterator i = view.get_selection()->get_selected();

	if (i != model->children().end()) {
		string path = (*i)[columns.path];
		
		if (!(*i)[columns.bindable]) {
			goto out;
		} 

		possibly_translate_keyval_to_make_legal_accelerator (ev->keyval);

		bool result = AccelMap::change_entry (path,
						      ev->keyval,
						      (ModifierType) ev->state,
						      true);

		if (result) {
			bool known;
			AccelKey key;

			known = ActionManager::lookup_entry (path, key);
			
			if (known) {
				(*i)[columns.binding] =
ActionManager::ui_manager->get_accel_group()->name (key.get_key(),
Gdk::ModifierType (key.get_mod()));
			} else {
				(*i)[columns.binding] = string();
			}
		}
	}

  out:
	can_bind = false;
	return true;
}



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