Re: UIManager and dynamic menus



On 4/4/07, Paul Davis <paul linuxaudiosystems com> wrote:
On Wed, 2007-04-04 at 11:27 -0500, Paul Davis wrote:
> Hi list,
>
> I've been working with UIManager quite a bit lately and I've come up
> against two issues that are fairly related.
>
> What is the 'UIManager' way of having dynamic menus. I need this when
> adding a list of recent documents to the File menu or when creating a
> list of windows for a View menu.
>
> I've looked at the merge operations presented by UIManager, but they
> appear to be a bit heavier weight than I would expect for something
> like this.
>
> If this merge/unmerge functionality is the way to go, does someone
> have a good example of doing this.  I'm fairly certain I get the
> basics, but having a good example is always nice too.

if one of us hasn't been there already, i'm not sure what we would do :)

personally, i have found it *extremely* hard to use the UIManager for
dynamic menus. the problems have been subtle, and i gave up. my approach
now is to use UIManager for the static menus (including a dangling menu
item where the dynamic one will be "hung"), and then do this:

Gtk::Menu*
SequencerUI::get_trigger_submenu ()
{
        Widget* foo = ActionManager::get_widget ("/Main/Triggers/Edit");
        Gtk::MenuItem* foomi = dynamic_cast<MenuItem*>(foo);
        return foomi->get_submenu ();
}

after that, i use the very nice Menu_Helpers function to rebuild the
item list for the return menu (including a clear):

int
SequencerUI::add_trigger_item (Trigger &trigger)
{
        using namespace Menu_Helpers;
        Gtk::Menu* trigger_menu = get_trigger_submenu();
        MenuList& trigger_list = trigger_menu->items();

        trigger_list.push_back (MenuElem (trigger.name().c_str(), bind (mem_fun
(*this, &SequencerUI::edit_trigger), &trigger)));
        trigger_list.back().set_data ("trigger_ptr", &trigger);

        return 0;
}

void
SequencerUI::rebuild_trigger_submenu ()
{
        using namespace Menu_Helpers;
        Gtk::Menu* trigger_menu = get_trigger_submenu();
        MenuList& items = trigger_menu->items();

        items.clear ();

        _sequencer->foreach_trigger (*this, &SequencerUI::add_trigger_item);

        trigger_menu->show_all ();
}

i just couldn't figure out a way to smoothly accomplish the same thing
with readable and grokkable code.

--p




Other me,

Yeah you were right in that this was extremely frustrating.  I think
it'd be possible to get this working if if I fiddled with the
UIManager or wrote some stuff on top of it to make it behave the way I
thought it should, but right now its just too irritating to work with.

In other news, how did you set up your ui_info string that you pass to
Gtk::UIManager::add_ui_from_string() ; ?

If I don't do something like this:

       "       <menu action='ViewMenu'>"
       "           <menuitem action='ViewDefaultSize' />"
       "           <menuitem action='ViewFullScreen' />"
       "           <separator />"
       "           <menu action='ViewWindowsMenu'>"
       "               <menuitem action='TestItem' />"
       "           </menu>"
       "       </menu>"

If I don't have a menuitem in the 'ViewWindowsMenu' then it doesn't
show up at all.  I tried calling show() on it and everything, but I
have the sneaking suspicion that its just not added to the parent menu
till you add a child.

Anyway its working, but its kinda hackish.

Perhaps we might think about trying to add some better dynamic
functionality to this in the future when we're planning an API/ABI
break, but it just doesn't seem worth it right now.

Thanks,
Paul Davis



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