Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:17:41

0001 // $Id$
0002 //
0003 //    File: jv_mainframe.cc
0004 // Created: Fri Oct  3 08:12:01 EDT 2014
0005 // Creator: davidl (on Darwin harriet.jlab.org 13.4.0 i386)
0006 //
0007 
0008 
0009 #include "jv_mainframe.h"
0010 #include "JEventProcessor_janaview.h"
0011 #include <JANA/JEventSource.h>
0012 
0013 //---------------------------------
0014 // jv_mainframe    (Constructor)
0015 //---------------------------------
0016 jv_mainframe::jv_mainframe(const TGWindow *p, UInt_t w, UInt_t h,  bool /*build_gui*/):TGMainFrame(p,w,h, kMainFrame | kVerticalFrame)
0017 {
0018     CreateGUI();
0019     
0020     SetWindowName("JANA Viewer");
0021     SetIconName("JANA Viewer");
0022     MapSubwindows();
0023     MapWindow();
0024     this->SetWidth(1000);
0025     Redraw(this);
0026     
0027     timer = new TTimer();
0028     timer->Connect("Timeout()", "jv_mainframe", this, "DoTimer()");
0029     sleep_time = 250;
0030     timer->Start(sleep_time, kFALSE);
0031 
0032 }
0033 
0034 //---------------------------------
0035 // ~jv_mainframe    (Destructor)
0036 //---------------------------------
0037 jv_mainframe::~jv_mainframe()
0038 {
0039 
0040 }
0041 
0042 //-------------------
0043 // CloseWindow
0044 //-------------------
0045 void jv_mainframe::CloseWindow(void)
0046 {
0047     DeleteWindow();
0048     gApplication->Terminate(0);
0049 }
0050 
0051 //-------------------
0052 // HandleMenu
0053 //-------------------
0054 void jv_mainframe::HandleMenu(Int_t id)
0055 {
0056    // Handle menu items.
0057 
0058   //cout << "in HandleMenu(" << id << ")" << endl;
0059 
0060    switch (id) {
0061 
0062    case M_FILE_OPEN:
0063      break;
0064 
0065    case M_FILE_SAVE:
0066      break;
0067     
0068    case M_FILE_NEW_CONFIG:
0069      break;
0070 
0071    case M_FILE_OPEN_CONFIG:
0072      break;
0073 
0074    case M_FILE_SAVE_CONFIG:
0075      break;
0076 
0077    case M_FILE_SAVE_AS_CONFIG:
0078      break;
0079 
0080    case M_FILE_EXIT: 
0081      DoQuit();       
0082      break;
0083 
0084    case M_TOOLS_MACROS:
0085      break;
0086 
0087    case M_TOOLS_TBROWSER:
0088      break;
0089 
0090    case M_VIEW_NEW_TAB:
0091        break;
0092 
0093    case M_VIEW_REMOVE_TAB:
0094        break;
0095 
0096    }
0097 }
0098 
0099 //-------------------
0100 // DoTimer
0101 //-------------------
0102 void jv_mainframe::DoTimer(void)
0103 {
0104     /// This method gets called every 250ms. It doesn't do anything
0105     /// itself, but it does cause the screen to get updated. Without
0106     /// this, the screen does not seem to update on it's own. It needs
0107     /// at least a mouse movement over the screen to cause an update.
0108     /// (This was observed on both Linux and Mac OS X).
0109 }
0110 
0111 //-------------------
0112 // DoQuit
0113 //-------------------
0114 void jv_mainframe::DoQuit(void)
0115 {
0116     cout<<"quitting ..."<<endl;
0117     gApplication->Terminate(0); 
0118 }
0119 
0120 //-------------------
0121 // DoNext
0122 //-------------------
0123 void jv_mainframe::DoNext(void)
0124 {
0125     JEP->NextEvent();
0126 }
0127 
0128 //-------------------
0129 // DoDelayedSelectObjectType
0130 //-------------------
0131 void jv_mainframe::DoDelayedSelectObjectType(void)
0132 {
0133     /// This is here to allow us to defer selection of the object
0134     /// type box after UpdateObjectTypeList is called. This happens
0135     /// when a new event has been read in. For some reason, calling
0136     /// DoSelectObjectType directly from UpdateObjectTypeList causes
0137     /// bad behavior in the GUI. Hence, calling this routine a few
0138     /// milliseconds after UpdateObjectTypeList has returned.
0139     DoSelectObjectType(delayed_object_type_id);
0140     lbObjectTypes->Select(delayed_object_type_id);
0141     lbObjectTypes->SetTopEntry(delayed_object_type_id);
0142     
0143     Redraw(lbObjectTypes);
0144 }
0145 
0146 //-------------------
0147 // DoSelectObjectType
0148 //-------------------
0149 void jv_mainframe::DoSelectObjectType(Int_t id)
0150 {
0151     // Clear listboxs of associated objects
0152     lbObjects->RemoveAll();
0153     lbAssociatedObjects->RemoveAll();
0154     lbAssociatedToObjects->RemoveAll();
0155     Redraw(lbObjects);
0156     Redraw(lbAssociatedObjects);
0157     Redraw(lbAssociatedToObjects);
0158 
0159     TGLBEntry *e = lbObjectTypes->GetEntry(id);
0160     if(!e){
0161         _DBG_<<"Unable to find factory for id:"<<id<< endl;
0162         return;
0163     }
0164 
0165     // Update label
0166     string nametag = e->GetTitle();
0167     lObjectType->SetTitle(strdup(nametag.c_str()));
0168     lObjectType->Resize();
0169     last_selected_nametag = nametag;
0170     
0171     // Get factory name and tag
0172     string name = nametag;
0173     string tag = "";
0174     size_t pos=name.find(":");
0175     if(pos != name.npos){
0176         tag = name.substr(pos+1);
0177         name = name.substr(0, pos);
0178     }
0179 
0180     // Get factory and list of objects
0181     JEP->Lock();
0182     JFactory *fac = JEP->loop->GetFactory(name, tag.c_str());
0183     if(!fac){
0184         JEP->Unlock();
0185         _DBG_<<"Unable to find factory for name=\""<<name<<"\"  tag=\"" << tag << "\"" << endl;
0186         return;
0187     }
0188 
0189     // Here we have to go to some trouble to make sure the event source's GetObjects
0190     // method is called. The JFactory::Get method called below will only try to 
0191     // generate the objects using the factory algorithm so objects coming from the
0192     // source will not be necessarily be there unless we force the call here.   
0193     auto jevent = JEP->loop;
0194     JEventSource *source = jevent->GetJEventSource();
0195     source->GetObjects(jevent, fac);
0196 
0197     auto cgr = JEP->loop->GetJCallGraphRecorder();
0198     cgr->StartFactoryCall(name, tag);
0199 
0200     // Get pointers from factory
0201     auto objs = fac->GetAs<JObject>();
0202     for (auto obj : objs) {
0203         vobjs.push_back(obj);
0204     }
0205 
0206     cgr->FinishFactoryCall();
0207 
0208     // Copy list of objects into listbox
0209     lbObjects->RemoveAll();
0210     for(uint32_t i=0; i<vobjs.size(); i++){
0211         char str[256];
0212         snprintf(str, 256, "0x%016lx %s", (unsigned long)vobjs[i], ((JObject*)vobjs[i])->className().c_str());
0213         lbObjects->AddEntry(str, i+1);
0214     }
0215     
0216     JEP->MakeCallGraph();
0217     
0218     JEP->Unlock();
0219     Redraw(lbObjects);
0220 }
0221 
0222 //-------------------
0223 // DoSelectObject
0224 //-------------------
0225 void jv_mainframe::DoSelectObject(Int_t id)
0226 {
0227     // Clear listboxs of associated objects
0228     lbAssociatedObjects->RemoveAll();
0229     lbAssociatedToObjects->RemoveAll();
0230     Redraw(lbAssociatedObjects);
0231     Redraw(lbAssociatedToObjects);
0232 
0233     // Get pointer to selected object as a JObject
0234     Int_t idx = id-1;
0235     if(idx<0 || idx>=(Int_t)vobjs.size()) return;   
0236     JObject *obj = (JObject*)vobjs[idx];
0237     
0238     UpdateObjectValues(obj);
0239 
0240     // Get associated objects
0241     aobjs.clear();
0242     obj->GetT(aobjs);
0243     for(uint32_t i=0; i<aobjs.size(); i++){
0244         char str[256];
0245         snprintf(str, 256, "0x%016lx %s", (unsigned long)aobjs[i], aobjs[i]->className().c_str());
0246         lbAssociatedObjects->AddEntry(str, i+1);
0247     }
0248     Redraw(lbAssociatedObjects);
0249     
0250     // Get associated to objects
0251     a2objs.clear();
0252     JEP->GetAssociatedTo(obj, a2objs);
0253     for(uint32_t i=0; i<a2objs.size(); i++){
0254         char str[256];
0255         snprintf(str, 256, "0x%016lx %s", (unsigned long)a2objs[i], a2objs[i]->className().c_str());
0256         lbAssociatedToObjects->AddEntry(str, i+1);
0257     }
0258     Redraw(lbAssociatedToObjects);
0259 }
0260 
0261 //-------------------
0262 // DoSelectAssociatedObject
0263 //-------------------
0264 void jv_mainframe::DoSelectAssociatedObject(Int_t id)
0265 {
0266     // Get pointer to selected object as a JObject
0267     Int_t idx = id-1;
0268     if(idx<0 || idx>=(Int_t)aobjs.size()) return;   
0269     JObject *obj = (JObject*)aobjs[idx];
0270     
0271     UpdateObjectValues(obj);
0272 }
0273 
0274 //-------------------
0275 // DoSelectAssociatedToObject
0276 //-------------------
0277 void jv_mainframe::DoSelectAssociatedToObject(Int_t id)
0278 {
0279     // Get pointer to selected object as a JObject
0280     Int_t idx = id-1;
0281     if(idx<0 || idx>=(Int_t)a2objs.size()) return;  
0282     JObject *obj = (JObject*)a2objs[idx];
0283     
0284     UpdateObjectValues(obj);
0285 }
0286 
0287 //-------------------
0288 // DoDoubleClickAssociatedObject
0289 //-------------------
0290 void jv_mainframe::DoDoubleClickAssociatedObject(Int_t id)
0291 {
0292     // Get pointer to selected object as a JObject
0293     Int_t idx = id-1;
0294     if(idx<0 || idx>=(Int_t)aobjs.size()) return;   
0295     JObject *obj = (JObject*)aobjs[idx];
0296     
0297     SelectNewObject(obj);
0298 }
0299 
0300 //-------------------
0301 // DoDoubleClickAssociatedToObject
0302 //-------------------
0303 void jv_mainframe::DoDoubleClickAssociatedToObject(Int_t id)
0304 {
0305     // Get pointer to selected object as a JObject
0306     Int_t idx = id-1;
0307     if(idx<0 || idx>=(Int_t)a2objs.size()) return;  
0308     JObject *obj = (JObject*)a2objs[idx];
0309     
0310     SelectNewObject(obj);
0311 }
0312 
0313 //-------------------
0314 // DoCallGraphClicked
0315 //-------------------
0316 void jv_mainframe::DoCallGraphClicked(Int_t event, Int_t x, Int_t y, TObject */*selected*/)
0317 {
0318     if( event != kButton1Up ) return;
0319     
0320     // y is reported in pixels from bottom so reverse it
0321     y = canvas->GetCanvas()->GetWh() - y;
0322     
0323     for(auto it : JEP->cgobjs){
0324         auto cgobj = it.second;
0325         if(!cgobj) continue;
0326         if( x<cgobj->x1 || x>cgobj->x2) continue;
0327         if( y<cgobj->y1 || y>cgobj->y2) continue;
0328         
0329         // Search for entry in object type listbox with this nametag
0330         for(Int_t id=0; id<lbObjectTypes->GetNumberOfEntries(); id++){
0331             TGLBEntry *e = lbObjectTypes->GetEntry(id);
0332             if(!e) continue;
0333             string nametag = e->GetTitle();
0334             if(nametag != cgobj->nametag) continue;
0335             
0336             // Another oddity of the ROOT GUI system. We need to
0337             // set the object type twice, but do it on a timer
0338             // so the sequencing all works out. The screen flashes
0339             // a couple of times, but seems to settle quickly on
0340             // the right thing.
0341             delayed_object_type_id = id;
0342             TTimer::SingleShot(1, "jv_mainframe", this, "DoDelayedSelectObjectType()");
0343             TTimer::SingleShot(10, "jv_mainframe", this, "DoDelayedSelectObjectType()");
0344             _DBG_ << "selecting " << nametag << endl; 
0345             break;
0346         }
0347         break;
0348     }
0349 }
0350 
0351 //-------------------
0352 // HandleConfigureNotify
0353 //-------------------
0354 Bool_t jv_mainframe::HandleConfigureNotify(Event_t *event)
0355 {
0356     /// This gets called when the window is resized (but also for other things)
0357     /// It is here so we can update the CallGraph tab when the window is resized.
0358 
0359     if(JEP) JEP->MakeCallGraph();
0360     return this->TGMainFrame::HandleConfigureNotify(event);
0361 }
0362 
0363 
0364 //==============================================================================
0365 
0366 //-------------------
0367 // GetSelectedObjectType
0368 //-------------------
0369 string jv_mainframe::GetSelectedObjectType(void)
0370 {
0371     string selected_nametag = "";
0372     Int_t id = lbObjectTypes->GetSelected();
0373     if(id>0 && id<=lbObjectTypes->GetNumberOfEntries()){
0374         TGLBEntry *e = lbObjectTypes->GetEntry(id);
0375         if(e) selected_nametag = e->GetTitle();
0376     }
0377     if(selected_nametag=="") selected_nametag = last_selected_nametag;
0378     
0379     return selected_nametag;
0380 }
0381 
0382 //-------------------
0383 // UpdateInfo
0384 //-------------------
0385 void jv_mainframe::UpdateInfo(string source, int run, int event)
0386 {
0387     lSource->SetText(source.c_str());
0388 
0389     char str[256];
0390     snprintf(str, 256, "%d     ", run);
0391     lRun->SetText(str);
0392     snprintf(str, 256, "%d            ", event);
0393     lEvent->SetText(str);
0394     
0395     Redraw(lSource);
0396 }
0397 
0398 //-------------------
0399 // UpdateObjectTypeList
0400 //-------------------
0401 void jv_mainframe::UpdateObjectTypeList(vector<JVFactoryInfo> &facinfo)
0402 {
0403     // Check if an entry is already selected and remember it so we can re-select it
0404     string selected_nametag = GetSelectedObjectType();
0405 
0406     // Clean out old list and create new one of nametags
0407     lbObjectTypes->RemoveAll();
0408     objtypes.clear();
0409 
0410     // First, copy all nametags into a set so they will be ordered alphabetically
0411     set<string> nametags;
0412     for(uint32_t i=0; i<facinfo.size(); i++){
0413         JVFactoryInfo &finfo = facinfo[i];
0414         nametags.insert(finfo.nametag);
0415     }
0416 
0417     // Fill in listbox and keep corresponding vector of objects
0418     set<string>::iterator iter = nametags.begin();
0419     Int_t id=1;
0420     uint32_t selected_id = 0;
0421     for(; iter!=nametags.end(); iter++, id++){
0422         string nametag = *iter;
0423         lbObjectTypes->AddEntry(nametag.c_str(), id);
0424         objtypes.push_back(nametag);
0425         if(nametag == selected_nametag) selected_id = id;
0426     }
0427     
0428     Redraw(lbObjectTypes);
0429 
0430     if(selected_id>0){
0431         delayed_object_type_id = selected_id;
0432         TTimer::SingleShot(1000, "jv_mainframe", this, "DoDelayedSelectObjectType()");
0433     }   
0434 }
0435 
0436 //-------------------
0437 // UpdateObjectValues
0438 //-------------------
0439 void jv_mainframe::UpdateObjectValues(JObject *obj)
0440 {
0441     char title[256];
0442     snprintf(title, 256, "0x%016lx : %s", (unsigned long)obj, obj->className().c_str());
0443     lObjectValue->SetTitle(title);
0444     lObjectValue->Resize();
0445 
0446     vector<pair<string,string> > items;
0447     JObjectSummary summary;
0448     obj->Summarize(summary);
0449     for (const auto& field : summary.get_fields()) {
0450         items.push_back({field.name, field.value});
0451     }
0452 
0453     // Find maximum label width
0454     uint32_t max_width = 0;
0455     for(uint32_t i=0; i<items.size(); i++){
0456         uint32_t width = items[i].first.length();
0457         if(width>max_width) max_width = width;
0458     }
0459 
0460     // We must go to some trouble to use a fixed-width font in the
0461     // listbox, but this is needed to get things to line up. This
0462     // was copied from an example here:
0463     // http://root.cern.ch/phpBB3/viewtopic.php?p=9281
0464     const TGFont *ufont;         // will reflect user font changes
0465     ufont = gClient->GetFont("-adobe-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1");
0466     if (!ufont) ufont = fClient->GetResourcePool()->GetDefaultFont();
0467 
0468     // graphics context changes
0469     GCValues_t val;
0470     val.fMask = kGCFont;
0471     val.fFont = ufont->GetFontHandle();
0472     TGGC *uGC = gClient->GetGC(&val, kTRUE);
0473 
0474     // Replace contents of listbox
0475     lbObjectValues->RemoveAll();
0476     for(uint32_t i=0; i<items.size(); i++){
0477         string &lab = items[i].first;
0478         string &val = items[i].second;
0479         string line = lab + string(max_width+1 - lab.length(), ' ') + " : " + val;
0480         
0481         TGTextLBEntry *entry = new TGTextLBEntry(lbObjectValues->GetContainer(), new TGString(line.c_str()), i+1, uGC->GetGC(), ufont->GetFontStruct());
0482         lbObjectValues->AddEntry((TGLBEntry *)entry, new TGLayoutHints(kLHintsTop | kLHintsLeft));
0483     }
0484     Redraw(lbObjectValues);
0485 }
0486 
0487 //-------------------
0488 // SelectNewObject
0489 //-------------------
0490 void jv_mainframe::SelectNewObject(void *vobj)
0491 {
0492     JObject *obj = (JObject*)vobj;
0493     string nametag = obj->className(); // TODO: Should be name:tag except we aren't storing a factory ptr anymore
0494     for(uint32_t i=0; i<objtypes.size(); i++){
0495         if(objtypes[i] != nametag) continue;
0496         
0497         DoSelectObjectType(i+1);
0498         lbObjectTypes->Select(i+1);
0499         lbObjectTypes->SetTopEntry(i+1);
0500         
0501         break;
0502     }
0503     
0504     for(uint32_t i=0; i<objtypes.size(); i++){
0505         if(vobjs[i] != vobj) continue;
0506         
0507         DoSelectObject(i+1);
0508         lbObjects->Select(i+1);
0509         lbObjects->SetTopEntry(i+1);
0510         
0511         break;
0512     }
0513 }
0514 
0515 //-------------------
0516 // Redraw
0517 //-------------------
0518 void jv_mainframe::Redraw(TGFrame *f)
0519 {
0520     // This unfortunate business seems to be needed to get the listbox to redraw itself
0521     TGDimension dim = f->GetSize();
0522     dim.fWidth+=1;
0523     f->Resize(dim);
0524     dim.fWidth-=1;
0525     f->Resize(dim);
0526 }
0527 
0528 //==============================================================================
0529 
0530 //-------------------
0531 // AddLabel
0532 //-------------------
0533 TGLabel* jv_mainframe::AddLabel(TGCompositeFrame* frame, string text, Int_t mode, ULong_t hints)
0534 {
0535     TGLabel *lab = new TGLabel(frame, text.c_str());
0536     lab->SetTextJustify(mode);
0537     lab->SetMargins(0,0,0,0);
0538     lab->SetWrapLength(-1);
0539     frame->AddFrame(lab, new TGLayoutHints(hints,2,2,2,2));
0540 
0541     return lab;
0542 }
0543 
0544 //-------------------
0545 // AddNamedLabel
0546 //-------------------
0547 TGLabel* jv_mainframe::AddNamedLabel(TGCompositeFrame* frame, string title, Int_t mode, ULong_t /*hints*/)
0548 {
0549     TGHorizontalFrame *f = new TGHorizontalFrame(frame);
0550     AddLabel(f, title, kTextRight);
0551     TGLabel *lab = AddLabel(f, "------------------------", mode);
0552     frame->AddFrame(f, new TGLayoutHints(kLHintsExpandX,2,2,2,2));
0553 
0554     return lab;
0555 }
0556 
0557 //-------------------
0558 // AddButton
0559 //-------------------
0560 TGTextButton* jv_mainframe::AddButton(TGCompositeFrame* frame, string text, ULong_t hints)
0561 {
0562     TGTextButton *b = new TGTextButton(frame, text.c_str());
0563     b->SetTextJustify(36);
0564     b->SetMargins(0,0,0,0);
0565     b->SetWrapLength(-1);
0566     b->Resize(100,22);
0567     frame->AddFrame(b, new TGLayoutHints(hints,2,2,2,2));
0568 
0569     return b;
0570 }
0571 
0572 //-------------------
0573 // AddCheckButton
0574 //-------------------
0575 TGCheckButton* jv_mainframe::AddCheckButton(TGCompositeFrame* frame, string text, ULong_t hints)
0576 {
0577     TGCheckButton *b = new TGCheckButton(frame, text.c_str());
0578     b->SetTextJustify(36);
0579     b->SetMargins(0,0,0,0);
0580     b->SetWrapLength(-1);
0581     frame->AddFrame(b, new TGLayoutHints(hints,2,2,2,2));
0582 
0583     return b;
0584 }
0585 
0586 //-------------------
0587 // AddPictureButton
0588 //-------------------
0589 TGPictureButton* jv_mainframe::AddPictureButton(TGCompositeFrame* frame, string picture, string tooltip, ULong_t hints)
0590 {
0591     TGPictureButton *b = new TGPictureButton(frame, gClient->GetPicture(picture.c_str()));
0592     if(tooltip.length()>0) b->SetToolTipText(tooltip.c_str());
0593     frame->AddFrame(b, new TGLayoutHints(hints,2,2,2,2));
0594 
0595     return b;
0596 }
0597 
0598 //-------------------
0599 // AddSpacer
0600 //-------------------
0601 TGFrame* jv_mainframe::AddSpacer(TGCompositeFrame* frame, UInt_t w, UInt_t h, ULong_t hints)
0602 {
0603     /// Add some empty space. Usually, you'll only want to set w or h to
0604     /// reserve width or height pixels and set the other to "1".
0605 
0606     TGFrame *f =  new TGFrame(frame, w, h);
0607     frame->AddFrame(f, new TGLayoutHints(hints ,2,2,2,2));
0608     
0609     return f;
0610 }
0611 
0612 //-------------------
0613 // AddListBox
0614 //-------------------
0615 TGListBox* jv_mainframe::AddListBox(TGCompositeFrame* frame, string lab, UInt_t w, ULong_t hints)
0616 {
0617     if(lab != "") AddLabel(frame, lab);
0618     TGListBox *lb = new TGListBox(frame);
0619     frame->AddFrame(lb, new TGLayoutHints(hints ,2,2,2,2));
0620     lb->SetWidth(w);
0621     
0622     return lb;
0623 }
0624 
0625 
0626 //-------------------
0627 // CreateGUI
0628 //-------------------
0629 void jv_mainframe::CreateGUI(void)
0630 {
0631     // Use the "color wheel" rather than the classic palette.
0632     TColor::CreateColorWheel();
0633     
0634 
0635    //==============================================================================================
0636    // make a menubar
0637    // Create menubar and popup menus. The hint objects are used to place
0638    // and group the different menu widgets with respect to eachother.
0639 
0640 //  TGDockableFrame    *fMenuDock;
0641     TGMenuBar  *fMenuBar;
0642     TGPopupMenu  *fMenuFile, *fMenuTools, *fMenuView;
0643     TGLayoutHints      *fMenuBarLayout, *fMenuBarItemLayout;
0644 
0645     fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX);
0646     fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
0647 
0648     fMenuFile = new TGPopupMenu(gClient->GetRoot());
0649     fMenuFile->AddEntry("&Open List...", M_FILE_OPEN);
0650     fMenuFile->AddEntry("&Save List...", M_FILE_SAVE);
0651     fMenuFile->AddSeparator();
0652     fMenuFile->AddEntry("New Configuration...", M_FILE_NEW_CONFIG);
0653     fMenuFile->AddEntry("Open Configuration...", M_FILE_OPEN_CONFIG);
0654     fMenuFile->AddEntry("Save Configuration", M_FILE_SAVE_CONFIG);
0655     fMenuFile->AddEntry("Save Configuration As ...", M_FILE_SAVE_AS_CONFIG);
0656     fMenuFile->AddEntry("E&xit", M_FILE_EXIT);
0657 
0658     fMenuTools = new TGPopupMenu(gClient->GetRoot());
0659     fMenuTools->AddEntry("Config Macros...", M_TOOLS_MACROS);
0660     fMenuTools->AddEntry("Start TBrowser", M_TOOLS_TBROWSER);
0661     fMenuTools->AddEntry("View Tree Info", M_TOOLS_TREEINFO);
0662     fMenuTools->AddEntry("Save Hists...",  M_TOOLS_SAVEHISTS);
0663     fMenuTools->AddSeparator();
0664     fMenuTools->AddEntry("Reset Histograms/Macros...",  M_TOOLS_RESET);
0665 
0666     fMenuView = new TGPopupMenu(gClient->GetRoot());
0667     fMenuView->AddEntry("New Tab...", M_VIEW_NEW_TAB);
0668     fMenuView->AddEntry("Remove Tab...", M_VIEW_REMOVE_TAB);
0669     fMenuView->AddSeparator();
0670     fMenuView->AddEntry("Log X axis", M_VIEW_LOGX);
0671     fMenuView->AddEntry("Log Y axis", M_VIEW_LOGY);
0672     fMenuView->AddEntry("Scale Options...", M_VIEW_SCALE_OPTS);
0673 
0674     fMenuBar = new TGMenuBar(this, 1, 1, kHorizontalFrame | kRaisedFrame );
0675     this->AddFrame(fMenuBar, fMenuBarLayout);
0676     fMenuBar->AddPopup("&File",  fMenuFile, fMenuBarItemLayout);
0677     fMenuBar->AddPopup("&Tools", fMenuTools, fMenuBarItemLayout);
0678     fMenuBar->AddPopup("&View",  fMenuView, fMenuBarItemLayout);
0679 
0680     // connect the menus to methods
0681     // Menu button messages are handled by the main frame (i.e. "this")
0682     // HandleMenu() method.
0683     fMenuFile->Connect("Activated(Int_t)", "jv_mainframe", this, "HandleMenu(Int_t)");
0684     fMenuTools->Connect("Activated(Int_t)", "jv_mainframe", this, "HandleMenu(Int_t)");
0685     fMenuView->Connect("Activated(Int_t)", "jv_mainframe", this, "HandleMenu(Int_t)");
0686    
0687    
0688     //==============================================================================================
0689     // Fill in main content of window. Note that most of the area is taken up by the
0690     // contents of the TGTab object which is filled in by the RSTab class constructor.
0691 
0692     // Main vertical frame
0693     TGVerticalFrame *fMain = new TGVerticalFrame(this);
0694     this->AddFrame(fMain, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2));
0695 
0696     // Top, middle(tabs), and bottom frames
0697     TGHorizontalFrame *fMainTop = new TGHorizontalFrame(fMain);
0698     TGHorizontalFrame *fMainMid = new TGHorizontalFrame(fMain);
0699     TGHorizontalFrame *fMainBot = new TGHorizontalFrame(fMain);
0700 
0701     fMain->AddFrame(fMainTop, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
0702     fMain->AddFrame(fMainMid, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
0703     fMain->AddFrame(fMainBot, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX,2,2,2,2));
0704 
0705     //....... Top Frame .......
0706     
0707     TGGroupFrame *fInfo = new TGGroupFrame(fMainTop, "Current Event Info   ", kVerticalFrame);
0708     fMainTop->AddFrame(fInfo, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY,2,2,2,2));
0709 
0710     lSource = AddNamedLabel(fInfo, "Source:   ");
0711     lRun    = AddNamedLabel(fInfo, "   Run:  ");
0712     lEvent  = AddNamedLabel(fInfo, " Event:  ");
0713 
0714     TGButton *bNext = AddButton(fInfo, "Next ");
0715 
0716     //....... Middle Frame .......
0717     
0718     TGVerticalFrame *fObjectTypes = new TGVerticalFrame(fMainMid);
0719     fMainMid->AddFrame(fObjectTypes, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandY ,2,2,2,2));
0720     lbObjectTypes = AddListBox(fObjectTypes, "Object Types   ", 300, kLHintsExpandY);
0721 
0722     fTab = new TGTab(fMainMid);
0723     fMainMid->AddFrame(fTab, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2));
0724     fTab->SetWidth(600);
0725 
0726     // ---- Object Details Tab ----
0727     TGCompositeFrame *tObjectDetails = fTab->AddTab("Object Details      ");
0728     TGHorizontalFrame *fObjectDetails = new TGHorizontalFrame(tObjectDetails);
0729     tObjectDetails->AddFrame(fObjectDetails, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY ,2,2,2,2));
0730 
0731     TGVerticalFrame *fObjects = new TGVerticalFrame(fObjectDetails);
0732     TGVerticalFrame *fAssociated = new TGVerticalFrame(fObjectDetails);
0733     TGVerticalFrame *fObjectValues = new TGVerticalFrame(fObjectDetails);
0734     fObjectDetails->AddFrame(fObjects, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY ,2,2,2,2));
0735     fObjectDetails->AddFrame(fAssociated, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY ,2,2,2,2));
0736     fObjectDetails->AddFrame(fObjectValues, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX | kLHintsExpandY ,2,2,2,2));
0737 
0738     lObjectType = AddLabel(fObjects, "--------------------------");
0739     lbObjects = AddListBox(fObjects, "Objects this event:        ");
0740 
0741     lbAssociatedObjects = AddListBox(fAssociated, "Associated Objects:         ");
0742     lbAssociatedToObjects = AddListBox(fAssociated, "Objects to which this is associated:             \n(may be incomplete)");
0743 
0744     lObjectValue = AddLabel(fObjectValues, "---------------");
0745     lbObjectValues = AddListBox(fObjectValues, "", 250, kLHintsExpandX | kLHintsExpandY);
0746 
0747     // ---- Call Graph Tab ----
0748     TGCompositeFrame *tCallGraph = fTab->AddTab("Call Graph   ");
0749     
0750     // Use TGCanvas to get scrollbars for the canvas
0751     gcanvas = new TGCanvas(tCallGraph, 100, 100, kFixedSize);
0752     tCallGraph->AddFrame(gcanvas, new TGLayoutHints(kLHintsExpandY | kLHintsExpandX));
0753     fCanvas = new TGVerticalFrame(gcanvas->GetViewPort(), 10, 10);
0754     gcanvas->SetContainer(fCanvas);
0755 
0756     canvas = new TRootEmbeddedCanvas("rec1", fCanvas, 400, 400);
0757     canvas->GetCanvas()->SetFillColor(TColor::GetColor( (Float_t)0.96, 0.96, 0.99));
0758     fCanvas->AddFrame(canvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,2,2,2,2));
0759     
0760     //....... Bottom Frame .......
0761     //AddSpacer(fMainBot, 50, 1, kLHintsRight);
0762     TGTextButton *bQuit = AddButton(fMainBot, "Quit  ", kLHintsRight | kLHintsBottom);
0763 
0764 
0765     //==================== Connect GUI elements to methods ====================
0766     bQuit->Connect("Clicked()","jv_mainframe", this, "DoQuit()");
0767     bNext->Connect("Clicked()","jv_mainframe", this, "DoNext()");
0768     lbObjectTypes->Connect("Selected(Int_t)","jv_mainframe", this, "DoSelectObjectType(Int_t)");
0769     lbObjects->Connect("Selected(Int_t)","jv_mainframe", this, "DoSelectObject(Int_t)");
0770     lbAssociatedObjects->Connect("Selected(Int_t)","jv_mainframe", this, "DoSelectAssociatedObject(Int_t)");
0771     lbAssociatedObjects->Connect("DoubleClicked(Int_t)","jv_mainframe", this, "DoDoubleClickAssociatedObject(Int_t)");
0772     lbAssociatedToObjects->Connect("Selected(Int_t)","jv_mainframe", this, "DoSelectAssociatedToObject(Int_t)");
0773     lbAssociatedToObjects->Connect("DoubleClicked(Int_t)","jv_mainframe", this, "DoDoubleClickAssociatedToObject(Int_t)");
0774     canvas->GetCanvas()->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "jv_mainframe", this,"DoCallGraphClicked(Int_t,Int_t,Int_t,TObject*)");
0775 }
0776