Re: Dynamic Menus


Subject: Re: Dynamic Menus
From: Joaquín Cuenca Abela (cuenca@pacaterie.u-psud.fr)
Date: Wed Sep 12 2001 - 16:48:44 CDT


On 12 Sep 2001 11:03:07 -0500, Jared Davis wrote:
> Joaquin--
>
> Thanks a lot for the dynamic menu stuff. I'm still a little hazy on some
> of the implementation details...
>
> First off, the XAP_Menu_Id that is needed to tie all the menus
> together... how do I get one of these? Someone suggested using
> AP_MENU_ID__BOGUS2__ + N (where N > 1) but I see that this is
> probably not a good long term solution.

No, you're absolutely right. The way to get a unused XAP_Menu_Id is to
ask EV_Menu_LayoutSet for a new one.

Let's assume that you know:

* The label that this item will carry (for instance: "Thesaurus") <- I
will call it "stLabel"
* A position to put your item <- I will call it "nPos"
* A function to callback (to simplify, let's assume that we only need a
string with the name of the method to call back). <- I will call it
"stCallback"

You start creating a new menu item doing:

XAP_Menu_Id id = m_pLayout->addLayoutItem(nPos, EV_MLF_Normal);

m_pLayout (a EV_Menu_LayoutSet object) will create for you a new
EV_Menu_LayoutItem, using a unique XAP_Menu_Id, which will be returned
by addLayoutItem.

Now, you can create a EV_Menu_Label and a EV_Menu_Action, and put them
in their respective containers, for example:

m_pLabelSet->addLabel(new EV_Menu_Label(id, stLabel, "Open the [snip]
synonyms"));
m_pActionSet->addAction(new EV_Menu_Action(
        id,
        0, // no, it doesn't have a sub menu
        1, // yes, it raises a dialog
        0, // no, it's not a checkbox item
        stCallback,
        NULL,
        NULL
);

That will add a new menu item named Thesaurus, at the position nPos, and
it will call the EV_EditMethod named stCallback when clicked.

So this way you can call whatever EV_EditMethod. The list of
EV_EditMethod is a "static" one, only know at compilation time, so if
you want to add a new method to the list, you should call the method:

EV_EditMethodContainer::addEditMethod(EV_EditMethod * pem)

(note that I've not done this method, it was already there from "the
beginning", it seems that it was there to provide support for javascript
callback methods. So in short, I know less these parts of the code, but
anyway I studied them when I was doing the dynamic menus stuff)

In order to make a new EV_EditMethod, you will need a pointer to your
callback method, and it should have the signature:

bool (callback_name)(AV_View*, EV_EditMethodCallData*);

Then you can just do:

m_pEMC->addEditMethod(new EV_EditMethod("callback_name",
                      callback_name,
                      0, // if it does not require the additional data
                      "" // description. I think that it's not used
anywhere
));

>
> I have gone ahead and created new objects for the label, layout
> item, and action classes. I'm not sure if what I've done is right, and
> still have a few questions:
>
> EV_Menu_Label* ThesaurusLabel = new EV_Menu_Label(
> ThesaurusID,
> "/&Tools/Thesaurus",
> "Open the thesaurus and search for synonyms"
> );
>
> EV_Menu_LayoutItem* ThesaurusLayoutItem = new EV_Menu_LayoutItem(
> ThesaurusID,
> EV_MLF_Normal
> );
>
> EV_Menu_Action* ThesaurusAction = new EV_Menu_Action(
> ThesaurusID,
> 0, // no, it doesn't have a sub menu
> 1, // yes, it raises a dialog
> 0, // no, it's not a checkbox item
> "???", // what goes here?
> NULL,
> NULL
> );
>
> But once I create these objects, I'm not quite sure how to add them
> to the menu. In other words, how do I get a pointer to the
> EV_Menu_Layout*, EV_Menu_ActionSet*, and EV_Menu_LabelSet*
> that I need in order to call the addLayout(), adAction(), and addLabel()
> functions, respectively?

if the code that should add the new menu item belongs to
[x]ap_{Unix,Win,...}Frame, then you have a pointer to the menu bar
(m_pUnixMenu, for instance), and from there, you may reach
EV_Menu_LabelSet & EV_Menu_Layout.

You also have a pointer to the app, that gives you acces to
EV_Menu_ActionSet.

If the code that should add the new menu item doesn't belong to
xap_UnixFrame, then currently you can not reach these objects. IMO
accessors should be written in XAP_Frame to these objects.

Also note that the front-end specific code to show the menu items have
been only very barely tested. For instance, I've got some crashes here
that I think are related to a dynamic menu item that I've build just to
test things out.

Hope that it will helps.

If you have some other question, don't hesitate.

P.S.: An easy alternative to the former
EV_Menu_{LabelSet,ActionSet,Layout} ::addStuff methods is
EV_Menu::addPath("/&Edit/blah");

it will find automagically the right layout position, and create any
submenu needed (addPath("/&Edit/blah/foo/bar") will create the submenus
"blah" & "foo" in the menu Edit, and it will add a menu entry named
"bar" in the submenu "foo".

Unfortunately this method should be expanded a bit to get a callback
method name (right now the new menu item will call "scriptPlay" each
time that it's clicked).

Cheers,

-- 
Joaquín Cuenca Abela
cuenca@celium.net



This archive was generated by hypermail 2b25 : Wed Sep 12 2001 - 16:57:41 CDT