Adding to predefined context menu

Hi,

How do I add something to a pre-defined context menu? Specifically, I would like to add an entry to the context menu that appears when a right click is done on a TH1 drawn on a canvas. Just to be clear, this menu already has “Add”, “Divide”, “DrawPanel”, etc., and I would like to add an option to open a “FindPeaks” panel (homegrown code) just after the “FitPanel” option.

Thanks in advance for any suggestions,
Joe Chuma

Hello Joe,

you can simply add items to the context menu by the MENU comment. However, this works only for member functions.
So in your case the easiest way would be to create your own class inheriting from TH1 and add your function there.

class MyTH1F : public TH1F {

public:

void FindPeaks(); // MENU

};

Cheers,
Oliver

Thank you for the response. That is what I suspected, but I was just checking to see if there was some clever built-in method for extending the context menus.

Joe Chuma

Hi,
see also $ROOTSYS/tutorials/
customContextMenu.C
customTH1Fmenu.C

Regards. Valeriy

I have tried to implement Valeriy’s suggestion and looked at customContextMenu.C, but cannot get it to work completely.

We have a locally written gui which inputs root histograms, etc. from files and/or online via a socket. When a histogram is drawn, we would like to add to the right-click context menu and have a locally written peak finding panel as an option, along with the standard options such as fit panel. By following the example in customContextMenu, I was able to insert Peak Find as a new menu item, but when Peak Find is clicked, nothing happens. A popup window is supposed to appear when Peak Find is clicked, but nothing happens.

Can someone tell me what is missing?
Included are some code fragments:

void MyGui::DrawObject( TObject *obj )
{
if( obj->InheritsFrom(TH1::Class()) )
{
TH1 h = static_cast<TH1>(obj);
TClass *cl = h->IsA();
TList *menuList = cl->GetMenuList();
TClassMenuItem *menuItem = new TClassMenuItem(
TClassMenuItem::kPopupUserFunction, cl,
“PeakFind”, “PeakFind”, h, “” );
menuList->AddFirst( menuItem );
h->Draw();
}
gPad->Modified();
gPad->Update();
}

void MyGui::PeakFind()
{
new TPeakFindPanel( gClient->GetRoot(), 0, 250, 220 );
}

I tried having PeakFind() as a member function of MyGui and as a global function, but neither worked. Any help would be appreciated.

Thanks,
Joe Chuma

Hi,

You wrote:

TClassMenuItem *menuItem = new TClassMenuItem( TClassMenuItem::kPopupUserFunction, cl, "PeakFind", "PeakFind", h, "" );
However the string (“PeakFind”) will be interpreted with NO context what so ever. Hence it is looking for a global function known to CINT named ‘PeakFind’. This will not match your MyGui::PeakFind.
If you function is a static function, the following might work:

TClassMenuItem *menuItem = new TClassMenuItem( TClassMenuItem::kPopupUserFunction, cl, "PeakFind", "MyGui::PeakFind", h, "" );

Cheers,
Philippe.

Thanks Philippe, but I’ve tried making PeakFind() as a public member function, a static member function, and as a global function. Nothing seems to work. I also tried publicly deriving a new class, MyTH1, from TH1, but that led to page after page of multiply defined errors. As a last resort, I could modify the ROOT sources to include my context menu items, but that is a very unsatisfactory solution. I appreciate any insights or help with this.

Thanks,
Joe Chuma

Hi

How is that possible? This works in customContextMenu.C for poptest2!

Did you forget the ClassDef or to generate and link the dictionary?

I found that indeed this does not really work. You can make it work put you need to provide a (dummy) object and the class needs to inherit from TObject.

I attached a couple of files that demonstrated a custom context menu working for all 3 variation I think you tried (Peak Finder entries at the top of the context menu).

To test it just do

root customContextMenu.C

Cheers,
Philippe
custom.tar.gz (1.05 KB)

Thank you again Philippe, and I agree that the examples you provided do work in ROOT. However, I am writing a stand-alone program, and the context menu additions do not work there. I have cut my program down to the minimal size (about 80 total lines in 3 files + Makefile) needed to show that it doesn’t work and the gzip’ed tar file is attached. If anyone can see what I am doing wrong, please let me know.

Joe Chuma

By the way, I am using ROOT version 3.10.02 on RedHat 9.
MyGui.tar.gz (1.61 KB)

Hi,

You misunderstood the argument to the TClassMenuItem constructor.
To make your example work I used:

[quote] TClassMenuItem *menuItem = new TClassMenuItem( TClassMenuItem::kPopupUserFunction, MyGui::Class(),
“PeakFind”, this, “PeakFind”);[/quote]

See my example for the syntax on how to retrieve the selected object (by just adding a parameter to PeakFind which is a TObject* and adding more args to the menu item constructor).

Cheers,
Philippe.

Thank you once again Philippe. It now works. I appreciate the effort you put into helping me solve this problem.

Joe Chuma

Hello ROOTers,

I am solving the same problem as “chuma” with using TClassMenuItem to add additional menu items in compiled GUI application. I did succeed to implement exactly what I need under linux, but the same code under windows returns following message:
“Error in TCint::Execute: Wrong number of the parameters”
I did test it with ROOT 5.14 and 5.18.
Please, look at attached script. function GUIcl::pp should later do something with TObject c (in this case histogram).
Thank you for any help!

Cheers
OldA
cc.cxx (933 Bytes)