//Begin_Html <img src="gif/hsumMenu.gif"> End_Html //
//Begin_Html <img src="gif/hsumDialog.gif"> End_Html //
#include "TRootContextMenu.h"
#include "TROOT.h"
#include "TGClient.h"
#include "TList.h"
#include "TContextMenu.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TClass.h"
#include "TVirtualX.h"
#include "TCanvas.h"
#include "TDataMember.h"
#include "TToggle.h"
#include "TRootDialog.h"
#include "TDataType.h"
#include "TCanvas.h"
#include "TBrowser.h"
#include "TRootCanvas.h"
#include "TRootBrowser.h"
#include "TClassMenuItem.h"
#include "TObjectSpy.h"
enum EContextMenu {
kToggleStart = 1000,
kToggleListStart = 2000,
kUserFunctionStart = 3000
};
ClassImp(TRootContextMenu)
TRootContextMenu::TRootContextMenu(TContextMenu *c, const char *)
: TGPopupMenu(gClient->GetDefaultRoot()), TContextMenuImp(c)
{
fDialog = 0;
fTrash = new TList;
Associate(this);
}
TRootContextMenu::~TRootContextMenu()
{
delete fDialog;
if (fTrash) fTrash->Delete();
delete fTrash;
}
void TRootContextMenu::DisplayPopup(Int_t x, Int_t y)
{
if (fClient->IsEditable()) return;
if (fEntryList) fEntryList->Delete();
if (fTrash) fTrash->Delete();
fMenuHeight = 6;
fMenuWidth = 8;
if (fDialog) {
delete fDialog;
fDialog = 0;
}
CreateMenu(fContextMenu->GetSelectedObject());
int xx, yy, topx = 0, topy = 0;
UInt_t w, h;
if (fContextMenu->GetSelectedCanvas())
gVirtualX->GetGeometry(fContextMenu->GetSelectedCanvas()->GetCanvasID(),
topx, topy, w, h);
xx = topx + x + 1;
yy = topy + y + 1;
PlaceMenu(xx, yy, kFALSE, kTRUE);
}
void TRootContextMenu::CreateMenu(TObject *object)
{
if (fClient->IsEditable()) return;
int entry = 0, toggle = kToggleStart, togglelist = kToggleListStart;
int userfunction = kUserFunctionStart;
AddLabel(fContextMenu->CreatePopupTitle(object));
AddSeparator();
TList *menuItemList = object->IsA()->GetMenuList();
TClassMenuItem *menuItem;
TIter nextItem(menuItemList);
while ((menuItem = (TClassMenuItem*) nextItem())) {
switch (menuItem->GetType()) {
case TClassMenuItem::kPopupSeparator:
AddSeparator();
break;
case TClassMenuItem::kPopupStandardList:
{
TList *methodList = new TList;
object->IsA()->GetMenuItems(methodList);
TMethod *method;
TClass *classPtr = 0;
TIter next(methodList);
while ((method = (TMethod*) next())) {
if (classPtr != method->GetClass()) {
AddSeparator();
classPtr = method->GetClass();
}
TDataMember *m;
EMenuItemKind menuKind = method->IsMenuItem();
switch (menuKind) {
case kMenuDialog:
AddEntry(method->GetName(), entry++, method);
break;
case kMenuSubMenu:
if ((m = method->FindDataMember())) {
if (m->GetterMethod()) {
TGPopupMenu *r = new TGPopupMenu(gClient->GetDefaultRoot());
AddPopup(method->GetName(), r);
fTrash->Add(r);
TIter nxt(m->GetOptions());
TOptionListItem *it;
while ((it = (TOptionListItem*) nxt())) {
char *name = it->fOptName;
Long_t val = it->fValue;
TToggle *t = new TToggle;
t->SetToggledObject(object, method);
t->SetOnValue(val);
fTrash->Add(t);
r->AddSeparator();
r->AddEntry(name, togglelist++, t);
if (t->GetState()) r->CheckEntry(togglelist-1);
}
} else {
AddEntry(method->GetName(), entry++, method);
}
}
break;
case kMenuToggle:
{
TToggle *t = new TToggle;
t->SetToggledObject(object, method);
t->SetOnValue(1);
fTrash->Add(t);
AddEntry(method->GetName(), toggle++, t);
if (t->GetState()) CheckEntry(toggle-1);
}
break;
default:
break;
}
}
delete methodList;
}
break;
case TClassMenuItem::kPopupUserFunction:
{
if (menuItem->IsToggle()) {
if (object) {
TMethod* method =
object->IsA()->GetMethodWithPrototype(menuItem->GetFunctionName(),menuItem->GetArgs());
TToggle *t = new TToggle;
t->SetToggledObject(object, method);
t->SetOnValue(1);
fTrash->Add(t);
AddEntry(method->GetName(), toggle++, t);
if (t->GetState()) CheckEntry(toggle-1);
} else {
Warning("Dialog","Cannot use toggle for a global function");
}
} else {
const char* menuItemTitle = menuItem->GetTitle();
if (strlen(menuItemTitle)==0) menuItemTitle = menuItem->GetFunctionName();
AddEntry(menuItemTitle,userfunction++,menuItem);
}
}
break;
default:
break;
}
}
}
void TRootContextMenu::Dialog(TObject *object, TMethod *method)
{
Dialog(object,(TFunction*)method);
}
void TRootContextMenu::Dialog(TObject *object, TFunction *function)
{
Int_t selfobjpos;
if (!function) return;
if (fContextMenu->GetSelectedMenuItem())
selfobjpos = fContextMenu->GetSelectedMenuItem()->GetSelfObjectPos();
else selfobjpos = -1;
const TGWindow *w;
if (fContextMenu->GetSelectedCanvas()) {
TCanvas *c = (TCanvas *) fContextMenu->GetSelectedCanvas();
if (c->GetCanvasImp()->IsA()->InheritsFrom(TGFrame::Class())) {
w = fClient->GetWindowById(gVirtualX->GetWindowID(c->GetCanvasID()));
if (!w) w = (TRootCanvas *) c->GetCanvasImp();
} else {
w = gClient->GetDefaultRoot();
}
} else if (fContextMenu->GetBrowser()) {
TBrowser *b = (TBrowser *) fContextMenu->GetBrowser();
w = (TRootBrowser *) b->GetBrowserImp();
} else {
w = gClient->GetDefaultRoot();
}
fDialog = new TRootDialog(this, w, fContextMenu->CreateDialogTitle(object, function));
TMethodArg *argument = 0;
TIter next(function->GetListOfMethodArgs());
Int_t argpos = 0;
while ((argument = (TMethodArg *) next())) {
if (selfobjpos != argpos) {
Text_t *argname = fContextMenu->CreateArgumentTitle(argument);
const Text_t *type = argument->GetTypeName();
TDataType *datatype = gROOT->GetType(type);
const Text_t *charstar = "char*";
Text_t basictype[32];
if (datatype) {
strcpy(basictype, datatype->GetTypeName());
} else {
TClass *cl = gROOT->GetClass(type);
if (strncmp(type, "enum", 4) && (cl && !(cl->Property() & kIsEnum)))
Warning("Dialog", "data type is not basic type, assuming (int)");
strcpy(basictype, "int");
}
if (strchr(argname, '*')) {
strcat(basictype, "*");
type = charstar;
}
TDataMember *m = argument->GetDataMember();
if (m && m->GetterMethod(object->IsA())) {
Text_t val[256];
if (!strncmp(basictype, "char*", 5)) {
Text_t *tdefval;
m->GetterMethod()->Execute(object, "", &tdefval);
strncpy(val, tdefval, 255);
} else if (!strncmp(basictype, "float", 5) ||
!strncmp(basictype, "double", 6)) {
Double_t ddefval;
m->GetterMethod()->Execute(object, "", ddefval);
sprintf(val, "%g", ddefval);
} else if (!strncmp(basictype, "char", 4) ||
!strncmp(basictype, "bool", 4) ||
!strncmp(basictype, "int", 3) ||
!strncmp(basictype, "long", 4) ||
!strncmp(basictype, "short", 5)) {
Long_t ldefval;
m->GetterMethod()->Execute(object, "", ldefval);
sprintf(val, "%li", ldefval);
}
TList *opt;
if ((opt = m->GetOptions())) {
Warning("Dialog", "option menu not yet implemented", opt);
#if 0
TMotifOptionMenu *o= new TMotifOptionMenu(argname);
TIter nextopt(opt);
TOptionListItem *it = 0;
while ((it = (TOptionListItem*) nextopt())) {
Text_t *name = it->fOptName;
Text_t *label = it->fOptLabel;
Long_t value = it->fValue;
if (value != -9999) {
Text_t val[256];
sprintf(val, "%li", value);
o->AddItem(name, val);
}else
o->AddItem(name, label);
}
o->SetData(val);
fDialog->Add(o);
#endif
} else {
fDialog->Add(argname, val, type);
}
} else {
char val[256] = "";
const char *tval = argument->GetDefault();
if (tval) strncpy(val, tval, 255);
fDialog->Add(argname, val, type);
}
}
argpos++;
}
fDialog->Popup();
}
Bool_t TRootContextMenu::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
{
TObjectSpy savedPad;
if (GetContextMenu()->GetSelectedPad()) {
savedPad.SetObject(gPad);
gPad = GetContextMenu()->GetSelectedPad();
}
switch (GET_MSG(msg)) {
case kC_COMMAND:
switch (GET_SUBMSG(msg)) {
case kCM_MENU:
if (parm1 < kToggleStart) {
TMethod *m = (TMethod *) parm2;
GetContextMenu()->Action(m);
} else if (parm1 >= kToggleStart && parm1 < kToggleListStart) {
TToggle *t = (TToggle *) parm2;
GetContextMenu()->Action(t);
} else if (parm1 >= kToggleListStart && parm1<kUserFunctionStart) {
TToggle *t = (TToggle *) parm2;
if (t->GetState() == 0)
t->SetState(1);
} else {
TClassMenuItem *mi = (TClassMenuItem*)parm2;
GetContextMenu()->Action(mi);
}
break;
case kCM_BUTTON:
if (parm1 == 1) {
const char *args = fDialog->GetParameters();
GetContextMenu()->Execute((char *)args);
delete fDialog;
fDialog = 0;
}
if (parm1 == 2) {
const char *args = fDialog->GetParameters();
GetContextMenu()->Execute((char *)args);
}
if (parm1 == 3) {
delete fDialog;
fDialog = 0;
}
break;
default:
break;
}
break;
case kC_TEXTENTRY:
switch (GET_SUBMSG(msg)) {
case kTE_ENTER:
{
const char *args = fDialog->GetParameters();
GetContextMenu()->Execute((char *)args);
delete fDialog;
fDialog = 0;
}
break;
default:
break;
}
break;
default:
break;
}
if (savedPad.GetObject()) gPad = (TVirtualPad*) savedPad.GetObject();
return kTRUE;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.