How to tell which popup menu item is selected?

For help with general CEGUI usage:
- Questions about the usage of CEGUI and its features, if not explained in the documentation.
- Problems with the CMAKE configuration or problems occuring during the build process/compilation.
- Errors or unexpected behaviour.

Moderators: CEGUI MVP, CEGUI Team

some_name
Just popping in
Just popping in
Posts: 15
Joined: Sat Mar 10, 2007 00:12

How to tell which popup menu item is selected?

Postby some_name » Mon Apr 23, 2007 00:26

I'm trying to figure out how to get told when a popup menu item is selected.

I believe there must be some event that tells me that an item was picked. However, the collaboration diagram in the documentation doesn't list any event that seems like a likely candidate.

I also called menu->EventSet::getIterator() to try to iterate over all the possible events, to find a likely candidate, but this only returns a single event name before the iterator claims it's at the end (RemovedChild). Is the event collection the set of subscribed events, rather than the set of possible events, perhaps?

So, two questions:

1) How do I tell which item is selected in a popup menu?
2) Separately, how can I tell what all the possible events are for a given window? (preferably programatically)

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Postby lindquist » Tue Apr 24, 2007 13:41

1) You subscribe to the MenuItem Clicked event

2) You don't. Since 0.5 the eventset is sparse and only subscribed events are present.
That being said you can look in the API docs for static EventXXX members. Be sure to look all the way to the base class...

HTH

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Tue Apr 24, 2007 15:16

Q1) How do I tell which item is selected in a popup menu?
A1) You subscribe to the MenuItem Clicked event

I think some_name wants to know when a menu is highlighted, much like the behavior of an MFC application where navigating through the menu via the keyboard will display appropriate text in the status bar. For an example of this behavior look at Wordpad.

In Cegui, a FrameWindow would possess a menu bar (which I need to add to WidgetGalore). Does the ALT key automatically open that menu bar or does the window need to subscribe to keyboard events and react to the ALT key by programmatically opening the menu bar? Similarly, how is the navigation through each menu item, via the up/down/right/left keys, handled? I haven't fiddled with these. Not yet anyway. But I see a need for this, soon.

And what about displaying more than just text, such as an image instead of text, an image or any other widget (checkmark)? I guess I'm researching menus in order to properly update WidgetGalore.

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Tue Apr 24, 2007 16:50

Rackle wrote:And what about displaying more than just text, such as an image instead of text, an image or any other widget (checkmark)? I guess I'm researching menus in order to properly update WidgetGalore.


I guess this an be done the same way you do it for listbox and co. write a derived menuitem class ?

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Tue Apr 24, 2007 18:21

On my lunch break I experimented a little and came up with this code. It subscribes to the mouse enters and leaves events of the menu. With those events I know when the mouse "enters" a menuitem, and set the title of the FrameWindow with the name/ID of that menu item. I think this is what the original poster was seeking.

The code also uses the "A" to open/close the menu. The ALT key does not work well in windowed mode; the Windows window captures that key and highlights the system menu (press ALT and then SPACE).

This is a beginning only.


Code has been Wikied
Last edited by Rackle on Wed May 02, 2007 19:39, edited 2 times in total.

User avatar
lindquist
CEGUI Team (Retired)
Posts: 770
Joined: Mon Jan 24, 2005 21:20
Location: Copenhagen, Denmark

Postby lindquist » Wed Apr 25, 2007 10:56

You're a coding machine Rackle :P

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Wed Apr 25, 2007 11:32

Sometimes I get lucky and quickly figure out something :wink:

It's been bugging me for a long time that WidgetGalore was "incomplete". I keep telling peeps to go there to learn the basics of every widget, but do not show menu, neither menu bar nor popup menu. This is a small step toward completeness.

Manually subscribing to every menuitem would quickly get tiresome, not to mention error-prone (what if the .layout is changed and new menuitems are added, but not added to the code). A better approach would be to iterate through the menu's children and subscribe each. Something like:

Code: Select all

void monitorMenuitems(CEGUI::Window* pParent)
{
  size_t childCount = pParent->getChildCount();
  for(size_t childIdx = 0; childIdx < childCount; childIdx++)
  {
    if(pParent->getChildAtIdx(childIdx)->testClassName("MenuItem")
    {
      pParent->getChildAtIdx(childIdx)->subscribeEvent(CEGUI::MenuItem::EventMouseEnters,   CEGUI::Event::Subscriber(&DemoSample::onMouseEnters,   this));
    }
    monitorMenuitems(pParent->getChildAtIdx(childIdx));
  }
}


There are a few other tidbits that I'd need (for my own projects), such as enabling/disabling menuitems with a callback to the application to query the state of the menuitems. Then there would need to be support for accelerator keys.

And by the way, I put some text within the toolip field of the .layout. I meant to query that text and display it within a "status bar" of the FrameWindow within onMouseEnters() and clear/empty/erase that text within onMouseLeaves().

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Thu Apr 26, 2007 16:57

Updated my post above. New bits are to automatically open and close a menu or sub-menu when the mouse enters/leaves.

A tricky part was with the "MyMenuItem/AutoPopup" auto-created item, by the layout editor. My feeling is that these are missing an auto-created flag.

There are a few iffy bits with the menu system. Some of those are due to my inexperience with this system, but some are due to the menu system itself. I'll probably submit a patch one of these days, after I'm done with my vacation (this menu stuff), and after my main "job" (the drag and drop stuff, which is quite difficult while trying to keep it as flexible as possible).

some_name
Just popping in
Just popping in
Posts: 15
Joined: Sat Mar 10, 2007 00:12

Postby some_name » Sun Apr 29, 2007 00:18

Thanks for the help!

Regarding 2): "You don't" isn't a good answer. Nobody can write a reasonable editor, for example, without being able to extract all the events of a given widget at runtime. Trying to keep a hard-coded list, per widget kind, would very quickly get tiresome and fall out of sync.

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Mon Apr 30, 2007 13:51

Maybe Rackle's Property Finder is what you want ?

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Mon Apr 30, 2007 13:59

I'll work on this soon (obtaining a list of possible events). Ideally I could integrate this in the Property Finder program, to list either the properties or the events supported by widgets.

Pompei2
Home away from home
Home away from home
Posts: 489
Joined: Tue May 23, 2006 16:31

Postby Pompei2 » Mon Apr 30, 2007 14:50

Aaaaah dumb me ! I mixed the properties and the events :)

sorry :oops:

bt good idea to integrate the events to your tool

Rackle
CEGUI Team (Retired)
Posts: 534
Joined: Mon Jan 16, 2006 11:59
Location: Montréal

Postby Rackle » Mon Apr 30, 2007 15:17

The event system seems underdevelopped.

Each widget defines a few string constants, which are then passed to the subscribeEvent() function. This function only puts the event string into an std::map, without ensuring that the event string is a valid event; it should be possible to subscribe to non-existant events, such as "Bleh" or "Blah" or "This is an invalid event" without the system returning an error.

It is possible to iterate through each subscribed events of a widget but it's not possible to iterate through each supported event by that widget.

I remember reading a post from a Cegui dev about restructuring the event system. That feature may be coming soon.


Return to “Help”

Who is online

Users browsing this forum: No registered users and 6 guests