/// \file /// \ingroup tutorial_gui /// Test program for ROOT native GUI classes /// Exactly like $ROOTSYS/test/guitest.cxx but using the new signal and slots communication mechanism. /// It is now possible to run this entire test program in the interpreter. /// Do either: /// ~~~{.cpp} /// .x guitest.C /// .x guitest.C++ /// ~~~ /// /// \macro_code /// /// \authors Ilka Antcheva, Bertrand Bellenot, Fons Rademakers, Valeri Onuchin #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; enum ETestCommandIdentifiers { M_FILE_OPEN, M_FILE_SAVE, M_FILE_SAVEAS, M_FILE_PRINT, M_FILE_PRINTSETUP, M_FILE_EXIT, M_TEST_DLG, M_TEST_MSGBOX, M_TEST_SLIDER, M_TEST_SHUTTER, M_TEST_DIRLIST, M_TEST_FILELIST, M_TEST_PROGRESS, M_TEST_NUMBERENTRY, M_TEST_FONTDIALOG, M_TEST_NEWMENU, M_VIEW_ENBL_DOCK, M_VIEW_ENBL_HIDE, M_VIEW_DOCK, M_VIEW_UNDOCK, M_HELP_CONTENTS, M_HELP_SEARCH, M_HELP_ABOUT, M_CASCADE_1, M_CASCADE_2, M_CASCADE_3, M_NEW_REMOVEMENU, VId1, HId1, VId2, HId2, VSId1, HSId1, VSId2, HSId2 }; Int_t mb_button_id[13] = { kMBYes, kMBNo, kMBOk, kMBApply, kMBRetry, kMBIgnore, kMBCancel, kMBClose, kMBYesAll, kMBNoAll, kMBNewer, kMBAppend, kMBDismiss}; EMsgBoxIcon mb_icon[4] = { kMBIconStop, kMBIconQuestion, kMBIconExclamation, kMBIconAsterisk }; const char *filetypes[] = { "All files", "*", "ROOT files", "*.root", "ROOT macros", "*.C", "Text files", "*.[tT][xX][tT]", 0, 0 }; struct shutterData_t { const char *pixmap_name; const char *tip_text; Int_t id; TGButton *button; }; shutterData_t histo_data[] = { { "h1_s.xpm", "TH1", 1001, 0 }, { "h2_s.xpm", "TH2", 1002, 0 }, { "h3_s.xpm", "TH3", 1003, 0 }, { "profile_s.xpm", "TProfile", 1004, 0 }, { 0, 0, 0, 0 } }; shutterData_t function_data[] = { { "f1_s.xpm", "TF1", 2001, 0 }, { "f2_s.xpm", "TF2", 2002, 0 }, { 0, 0, 0, 0 } }; shutterData_t tree_data[] = { { "ntuple_s.xpm", "TNtuple", 3001, 0 }, { "tree_s.xpm", "TTree", 3002, 0 }, { "chain_s.xpm", "TChain", 3003, 0 }, { 0, 0, 0, 0 } }; const char *editortxt1 = "This is the ROOT text edit widget TGTextEdit. It is not intended as\n" "a full developers editor, but it is relatively complete and can ideally\n" "be used to edit scripts or to present users editable config files, etc.\n\n" "The text edit widget supports standard emacs style ctrl-key navigation\n" "in addition to the arrow keys. By default the widget has under the right\n" "mouse button a popup menu giving access to several built-in functions.\n\n" "Cut, copy and paste between different editor windows and any other\n" "standard text handling application is supported.\n\n" "Text can be selected with the mouse while holding the left button\n" "or with the arrow keys while holding the shift key pressed. Use the\n" "middle mouse button to paste text at the current mouse location." ; class TestFileList; class TestMainFrame { RQ_OBJECT("TestMainFrame") private: TGMainFrame *fMain; TGDockableFrame *fMenuDock; TGCompositeFrame *fStatusFrame,*fF2, *fF3, *fF5; TGCanvas *fCanvasWindow; TGTextEntry *fTestText; TGButton *fTestButton, *fStartB, *fStopB, *fFITB; TGColorSelect *fColorSel; TRootEmbeddedCanvas *fEc1, *fEc2; TGMenuBar *fMenuBar; TGPopupMenu *fMenuFile, *fMenuTest, *fMenuView, *fMenuHelp; TGPopupMenu *fCascadeMenu, *fCascade1Menu, *fCascade2Menu; TGPopupMenu *fMenuNew1, *fMenuNew2; TGLayoutHints *fMenuBarLayout, *fMenuBarItemLayout, *fMenuBarHelpLayout, *fL3, *fL4, *fL5; TGComboBox *fComboR; Bool_t fFillHistos; TH1F *fHpx; TH2F *fHpxpy; TFile *tfile; TCanvas *c1, *c2; void FillHistos(); void FitHisto(); vector peaks; int test; public: TestMainFrame(const TGWindow *p, UInt_t w, UInt_t h); virtual ~TestMainFrame(); friend class TestFileList; // slots void CloseWindow(); void DoButton(); void HandleMenu(Int_t id); void HandlePopup() { printf("menu popped up\n"); } void HandlePopdown() { printf("menu popped down\n"); } void HandleButtons(Int_t id = -1); void PlotHisto(Int_t id = -1); void ExecuteEvent(Int_t event, Int_t px, Int_t py, TObject *sel); void Created() { Emit("Created()"); } //*SIGNAL* void Welcome() { printf("TestMainFrame has been created. Welcome!\n"); } }; class TestFileList { RQ_OBJECT("TestFileList") private: TestMainFrame *TMF; protected: TGTransientFrame *fMain; TGFileContainer *fContents; TGPopupMenu *fMenu; void DisplayFile(const TString &fname); void DisplayDirectory(const TString &fname); void DisplayObject(const TString& fname,const TString& name); public: TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h); virtual ~TestFileList(); // slots void OnDoubleClick(TGLVEntry*,Int_t); void DoMenu(Int_t); void CloseWindow(); }; TestMainFrame::TestMainFrame(const TGWindow *p, UInt_t w, UInt_t h) { // Create test main frame. A TGMainFrame is a top level window. fMain = new TGMainFrame(p, w, h); // use hierarchical cleaning fMain->SetCleanup(kDeepCleanup); fMain->Connect("CloseWindow()", "TestMainFrame", this, "CloseWindow()"); // Create menubar and popup menus. The hint objects are used to place // and group the different menu widgets with respect to eachother. fMenuDock = new TGDockableFrame(fMain); //fMain->AddFrame(fMenuDock, new TGLayoutHints(kLHintsExpandX, 0, 0, 1, 0)); fMenuDock->SetWindowName("GuiTest Menu"); fMenuBarLayout = new TGLayoutHints(kLHintsTop | kLHintsExpandX); fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0); fMenuBarHelpLayout = new TGLayoutHints(kLHintsTop | kLHintsRight); fMenuFile = new TGPopupMenu(gClient->GetRoot()); fMenuFile->AddEntry("&Open...", M_FILE_OPEN); fMenuFile->AddEntry("&Save", M_FILE_SAVE); fMenuFile->AddEntry("S&ave as...", M_FILE_SAVEAS); fMenuFile->AddEntry("&Close", -1); fMenuFile->AddSeparator(); fMenuFile->AddEntry("&Print", M_FILE_PRINT); fMenuFile->AddEntry("P&rint setup...", M_FILE_PRINTSETUP); fMenuFile->AddSeparator(); fMenuFile->AddEntry("E&xit", M_FILE_EXIT); fMenuFile->DisableEntry(M_FILE_SAVEAS); fMenuFile->HideEntry(M_FILE_PRINT); fCascade2Menu = new TGPopupMenu(gClient->GetRoot()); fCascade2Menu->AddEntry("ID = 2&3", M_CASCADE_1); fCascade2Menu->AddEntry("ID = 2&4", M_CASCADE_2); fCascade2Menu->AddEntry("ID = 2&5", M_CASCADE_3); fCascade1Menu = new TGPopupMenu(gClient->GetRoot()); fCascade1Menu->AddEntry("ID = 4&1", 41); fCascade1Menu->AddEntry("ID = 4&2", 42); fCascade1Menu->AddEntry("ID = 4&3", 43); fCascade1Menu->AddSeparator(); fCascade1Menu->AddPopup("Cascade&d 2", fCascade2Menu); fCascadeMenu = new TGPopupMenu(gClient->GetRoot()); fCascadeMenu->AddEntry("ID = 5&1", 51); fCascadeMenu->AddEntry("ID = 5&2", 52); fCascadeMenu->AddEntry("ID = 5&3", 53); fCascadeMenu->AddSeparator(); fCascadeMenu->AddPopup("&Cascaded 1", fCascade1Menu); fMenuTest = new TGPopupMenu(gClient->GetRoot()); fMenuTest->AddLabel("Test different features..."); fMenuTest->AddSeparator(); fMenuTest->AddEntry("&Dialog...", M_TEST_DLG); fMenuTest->AddEntry("&Message Box...", M_TEST_MSGBOX); fMenuTest->AddEntry("&Sliders...", M_TEST_SLIDER); fMenuTest->AddEntry("Sh&utter...", M_TEST_SHUTTER); fMenuTest->AddEntry("&List Directory...", M_TEST_DIRLIST); fMenuTest->AddEntry("&File List...", M_TEST_FILELIST); fMenuTest->AddEntry("&Progress...", M_TEST_PROGRESS); fMenuTest->AddEntry("&Number Entry...", M_TEST_NUMBERENTRY); fMenuTest->AddEntry("F&ont Dialog...", M_TEST_FONTDIALOG); fMenuTest->AddSeparator(); fMenuTest->AddEntry("Add New Menus", M_TEST_NEWMENU); fMenuTest->AddSeparator(); fMenuTest->AddPopup("&Cascaded menus", fCascadeMenu); fMenuView = new TGPopupMenu(gClient->GetRoot()); fMenuView->AddEntry("&Dock", M_VIEW_DOCK); fMenuView->AddEntry("&Undock", M_VIEW_UNDOCK); fMenuView->AddSeparator(); fMenuView->AddEntry("Enable U&ndock", M_VIEW_ENBL_DOCK); fMenuView->AddEntry("Enable &Hide", M_VIEW_ENBL_HIDE); fMenuView->DisableEntry(M_VIEW_DOCK); fMenuDock->EnableUndock(kTRUE); fMenuDock->EnableHide(kTRUE); fMenuView->CheckEntry(M_VIEW_ENBL_DOCK); fMenuView->CheckEntry(M_VIEW_ENBL_HIDE); // When using the DockButton of the MenuDock, // the states 'enable' and 'disable' of menus have to be updated. fMenuDock->Connect("Undocked()", "TestMainFrame", this, "HandleMenu(=M_VIEW_UNDOCK)"); fMenuHelp = new TGPopupMenu(gClient->GetRoot()); fMenuHelp->AddEntry("&Contents", M_HELP_CONTENTS); fMenuHelp->AddEntry("&Search...", M_HELP_SEARCH); fMenuHelp->AddSeparator(); fMenuHelp->AddEntry("&About", M_HELP_ABOUT); fMenuNew1 = new TGPopupMenu(); fMenuNew1->AddEntry("Remove New Menus", M_NEW_REMOVEMENU); fMenuNew2 = new TGPopupMenu(); fMenuNew2->AddEntry("Remove New Menus", M_NEW_REMOVEMENU); // Menu button messages are handled by the main frame (i.e. "this") // HandleMenu() method. fMenuFile->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuFile->Connect("PoppedUp()", "TestMainFrame", this, "HandlePopup()"); fMenuFile->Connect("PoppedDown()", "TestMainFrame", this, "HandlePopdown()"); fMenuTest->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuView->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuHelp->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fCascadeMenu->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fCascade1Menu->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fCascade2Menu->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuNew1->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuNew2->Connect("Activated(Int_t)", "TestMainFrame", this, "HandleMenu(Int_t)"); fMenuBar = new TGMenuBar(fMain, 1, 1, kHorizontalFrame); fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout); fMenuBar->AddPopup("&Test", fMenuTest, fMenuBarItemLayout); fMenuBar->AddPopup("&View", fMenuView, fMenuBarItemLayout); fMenuBar->AddPopup("&Help", fMenuHelp, fMenuBarHelpLayout); fMain->AddFrame(fMenuBar, fMenuBarLayout); //-------------- embedded canvas demo fF2 = new TGCompositeFrame(fMain,400,220,kVerticalFrame); fFillHistos = kFALSE; fHpx = 0; fHpxpy = 0; fL3 = new TGLayoutHints(kLHintsTop | kLHintsLeft, 5, 5, 5, 5); fL4 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5); fF3 = new TGCompositeFrame(fF2, 400, 220, kHorizontalFrame); fStartB = new TGTextButton(fF3, "Start &Filling Hists", 40); fStopB = new TGTextButton(fF3, "&Stop Filling Hists", 41); fFITB = new TGTextButton(fF3, "&FIT Hists", 42); fStartB->Connect("Clicked()", "TestMainFrame", this, "HandleButtons()"); fStopB->Connect("Clicked()", "TestMainFrame", this, "HandleButtons()"); fFITB->Connect("Clicked()", "TestMainFrame", this, "HandleButtons()"); fComboR = new TGComboBox(fF2, 200); fF3->AddFrame(fComboR, fL3); fF3->AddFrame(fStartB, fL3); fF3->AddFrame(fStopB, fL3); fF3->AddFrame(fFITB, fL3); fComboR->Resize(300,22); fComboR->Connect("Selected(Int_t)","TestMainFrame",this,"PlotHisto(Int_t)"); fF5 = new TGCompositeFrame(fF2, 60, 60, kVerticalFrame); fL4 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 0); fL5 = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 5, 5, 10, 5); fEc1 = new TRootEmbeddedCanvas("ec1", fF5, 100, 400); fEc2 = new TRootEmbeddedCanvas("ec2", fF5, 100, 250); gVirtualX->SetInputFocus(fEc1->GetContainer()->GetId()); c1 = fEc1->GetCanvas(); fF5->AddFrame(fEc1, fL4); fF5->AddFrame(fEc2, fL5); fF2->AddFrame(fF3, fL3); fF2->AddFrame(fF5, fL4); fEc1->GetCanvas()->SetBorderMode(0); fEc2->GetCanvas()->SetBorderMode(0); fMain->AddFrame(fF2,new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 2, 2)); // Create status frame containing a button and a text entry widget fStatusFrame = new TGCompositeFrame(fMain, 400, 20, kHorizontalFrame | kSunkenFrame); fTestButton = new TGTextButton(fStatusFrame, "&Open editor...", 150); fTestButton->Connect("Clicked()", "TestMainFrame", this, "DoButton()"); fTestButton->SetToolTipText("Pops up\ntext editor"); fStatusFrame->AddFrame(fTestButton, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 2, 2)); Pixel_t yellow; gClient->GetColorByName("yellow", yellow); fColorSel = new TGColorSelect(fStatusFrame, yellow, 0); fStatusFrame->AddFrame(fColorSel, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 0, 2, 2)); fMain->AddFrame(fStatusFrame, new TGLayoutHints(kLHintsBottom | kLHintsExpandX, 0, 0, 1, 0)); fMain->SetWindowName("GuiTest Signal/Slots"); fMain->MapSubwindows(); fMain->Layout(); // we need to use GetDefault...() to initialize the layout algorithm... fMain->MapWindow(); fMain->Resize(w,h); fMain->Print(); Connect("Created()", "TestMainFrame", this, "Welcome()"); Created(); } void TestMainFrame::ExecuteEvent(Int_t event, Int_t px, Int_t py, TObject *sel){ // some magic to get the coordinates... float x = gPad->AbsPixeltoX(px); float y = gPad->AbsPixeltoY(py); x = gPad->PadtoX(x); y = gPad->PadtoY(y); static float last_x; static float last_y; if(event!=kKeyPress) { last_x=x; last_y=y; //return; } if(event == kKeyPress){ switch(px){ case 'b': cout << "background" << endl; break; case 'p':{ cout << "Peak Select" << endl; peaks.push_back(1); cout << last_x << " " << last_y << " " << peaks.size() << endl; break; } }; } } void TestMainFrame::PlotHisto(Int_t id){ TGTextLBEntry *fp = (TGTextLBEntry *)fComboR->GetSelectedEntry(); const char *T = fp->GetTitle(); //c1 = fEc1->GetCanvas(); c1->cd(); fHpx=(TH1F *)tfile->Get(T); fHpx->Draw(); gStyle->SetOptStat(0); gVirtualX->SetInputFocus(fEc1->GetContainer()->GetId()); c1->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "TestMainFrame", fHpx, "ExecuteEvent(Int_t,Int_t,Int_t,TObject*)"); c1->Modified(); c1->Update(); } void TestMainFrame::FillHistos() { // Fill histograms till user clicks "Stop Filling" button. static int cnt; if (fHpx ==0) { fHpx = new TH1F("hpx","This is the px distribution",100,-4,4); fHpxpy = new TH2F("hpxpy","py vs px",40,-4,4,40,-4,4); fHpx->SetFillColor(kRed); cnt = 0; } const int kUPDATE = 1000; float px, py; c1 = fEc1->GetCanvas(); c2 = fEc2->GetCanvas(); while (fFillHistos) { gRandom->Rannor(px,py); //px and py will be two gaussian random numbers fHpx->Fill(px); fHpxpy->Fill(px,py); cnt++; if (!(cnt % kUPDATE)) { if (cnt == kUPDATE) { c1->cd(); fHpx->Draw(); c2->cd(); fHpxpy->Draw("cont"); } c1->Modified(); c1->Update(); c2->Modified(); c2->Update(); gSystem->ProcessEvents(); // handle GUI events } } } TestMainFrame::~TestMainFrame() { // Delete all created widgets. delete fMenuFile; delete fMenuTest; delete fMenuView; delete fMenuHelp; delete fCascadeMenu; delete fCascade1Menu; delete fCascade2Menu; delete fMenuNew1; delete fMenuNew2; delete fMain; } void TestMainFrame::HandleButtons(Int_t id) { // Handle different buttons. if (id == -1) { TGButton *btn = (TGButton *) gTQSender; id = btn->WidgetId(); } printf("DoButton: id = %d\n", id); char tmp[20]; switch (id) { case 40: // start histogram filling fFillHistos = kTRUE; FillHistos(); break; case 41: // stop histogram filling fFillHistos = kFALSE; break; case 42: // stop histogram filling fFillHistos = kFALSE; FitHisto(); break; } } void TestMainFrame::FitHisto(){ cout << peaks.size() << endl; c1->cd(); TF1 *fF1 = new TF1("fF1","gaus(0) + pol1(3)",0,3000); fF1->SetParameters(1000,4097,2,1,1); fF1->SetParLimits(0,0,1e6); fHpx->Fit(fF1); c1->Modified(); c1->Update(); } void TestMainFrame::CloseWindow() { // Got close message for this MainFrame. Terminates the application. gApplication->Terminate(); } void TestMainFrame::DoButton() { // Handle button click. // Editor *ed = new Editor(fMain, 600, 400); // ed->LoadBuffer(editortxt1); // ed->Popup(); } void TestMainFrame::HandleMenu(Int_t id) { // Handle menu items. switch (id) { case M_FILE_OPEN: { int i =0; static TString dir("."); TGFileInfo fi; fi.fFileTypes = filetypes; fi.fIniDir = StrDup(dir); printf("fIniDir = %s\n", fi.fIniDir); new TGFileDialog(gClient->GetRoot(), fMain, kFDOpen, &fi); printf("Open file: %s (dir: %s)\n", fi.fFilename, fi.fIniDir); tfile = new TFile(fi.fFilename); dir = fi.fIniDir; TIter next(tfile->GetListOfKeys()); TKey *key; while ((key=(TKey*)next())) { TString cname = key->GetClassName(); TString name = key->GetName(); fComboR->AddEntry(name, i++); } } break; case M_FILE_SAVE: printf("M_FILE_SAVE\n"); break; case M_FILE_PRINT: printf("M_FILE_PRINT\n"); printf("Hiding itself, select \"Print Setup...\" to enable again\n"); fMenuFile->HideEntry(M_FILE_PRINT); break; case M_FILE_PRINTSETUP: printf("M_FILE_PRINTSETUP\n"); printf("Enabling \"Print\"\n"); fMenuFile->EnableEntry(M_FILE_PRINT); break; case M_FILE_EXIT: CloseWindow(); // terminate theApp no need to use SendCloseMessage() break; case M_TEST_DLG: //new TestDialog(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_MSGBOX: //new TestMsgBox(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_SLIDER: //new TestSliders(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_SHUTTER: //new TestShutter(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_DIRLIST: //new TestDirList(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_FILELIST: new TestFileList(gClient->GetRoot(), fMain, 400, 200); break; case M_TEST_PROGRESS: //new TestProgress(gClient->GetRoot(), fMain, 600, 300); break; case M_TEST_NUMBERENTRY: //new EntryTestDlg(gClient->GetRoot(), fMain); break; case M_TEST_FONTDIALOG: { TGFontDialog::FontProp_t prop; new TGFontDialog(gClient->GetRoot(), fMain, &prop); if (prop.fName != "") printf("Selected font: %s, size %d, italic %s, bold %s, color 0x%lx, align %u\n", prop.fName.Data(), prop.fSize, prop.fItalic ? "yes" : "no", prop.fBold ? "yes" : "no", prop.fColor, prop.fAlign); } break; case M_TEST_NEWMENU: { if (fMenuTest->IsEntryChecked(M_TEST_NEWMENU)) { HandleMenu(M_NEW_REMOVEMENU); return; } fMenuTest->CheckEntry(M_TEST_NEWMENU); TGPopupMenu *p = fMenuBar->GetPopup("Test"); fMenuBar->AddPopup("New 1", fMenuNew1, fMenuBarItemLayout, p); p = fMenuBar->GetPopup("Help"); fMenuBar->AddPopup("New 2", fMenuNew2, fMenuBarItemLayout, p); fMenuBar->MapSubwindows(); fMenuBar->Layout(); TGMenuEntry *e = fMenuTest->GetEntry("Add New Menus"); fMenuTest->AddEntry("Remove New Menus", M_NEW_REMOVEMENU, 0, 0, e); } break; case M_NEW_REMOVEMENU: { fMenuBar->RemovePopup("New 1"); fMenuBar->RemovePopup("New 2"); fMenuBar->Layout(); fMenuTest->DeleteEntry(M_NEW_REMOVEMENU); fMenuTest->UnCheckEntry(M_TEST_NEWMENU); } break; case M_VIEW_ENBL_DOCK: fMenuDock->EnableUndock(!fMenuDock->EnableUndock()); if (fMenuDock->EnableUndock()) { fMenuView->CheckEntry(M_VIEW_ENBL_DOCK); fMenuView->EnableEntry(M_VIEW_UNDOCK); } else { fMenuView->UnCheckEntry(M_VIEW_ENBL_DOCK); fMenuView->DisableEntry(M_VIEW_UNDOCK); } break; case M_VIEW_ENBL_HIDE: fMenuDock->EnableHide(!fMenuDock->EnableHide()); if (fMenuDock->EnableHide()) { fMenuView->CheckEntry(M_VIEW_ENBL_HIDE); } else { fMenuView->UnCheckEntry(M_VIEW_ENBL_HIDE); } break; case M_VIEW_DOCK: fMenuDock->DockContainer(); fMenuView->EnableEntry(M_VIEW_UNDOCK); fMenuView->DisableEntry(M_VIEW_DOCK); break; case M_VIEW_UNDOCK: fMenuDock->UndockContainer(); fMenuView->EnableEntry(M_VIEW_DOCK); fMenuView->DisableEntry(M_VIEW_UNDOCK); break; default: printf("Menu item %d selected\n", id); break; } } TestFileList::TestFileList(const TGWindow *p, const TGWindow *main, UInt_t w, UInt_t h) { // Create transient frame containing a filelist widget. TGLayoutHints *lo; fMain = new TGTransientFrame(p, main, w, h); fMain->Connect("CloseWindow()", "TestDirList", this, "CloseWindow()"); fMain->DontCallClose(); // to avoid double deletions. // use hierarchical cleaning fMain->SetCleanup(kDeepCleanup); TGMenuBar* mb = new TGMenuBar(fMain); lo = new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1); fMain->AddFrame(mb, lo); fMenu = mb->AddPopup("&View"); fMenu->AddEntry("Lar&ge Icons",kLVLargeIcons); fMenu->AddEntry("S&mall Icons",kLVSmallIcons); fMenu->AddEntry("&List", kLVList); fMenu->AddEntry("&Details", kLVDetails); fMenu->AddSeparator(); fMenu->AddEntry("&Close", 10); fMenu->Connect("Activated(Int_t)","TestFileList",this,"DoMenu(Int_t)"); TGListView* lv = new TGListView(fMain, w, h); lo = new TGLayoutHints(kLHintsExpandX | kLHintsExpandY); fMain->AddFrame(lv,lo); Pixel_t white; gClient->GetColorByName("white", white); fContents = new TGFileContainer(lv, kSunkenFrame,white); fContents->Connect("DoubleClicked(TGFrame*,Int_t)", "TestFileList", this, "OnDoubleClick(TGLVEntry*,Int_t)"); // position relative to the parent's window fMain->CenterOnParent(); fMain->SetWindowName("File List Test"); fMain->MapSubwindows(); fMain->MapWindow(); fContents->SetDefaultHeaders(); fContents->DisplayDirectory(); fContents->AddFile(".."); // up level directory fContents->Resize(); fContents->StopRefreshTimer(); // stop refreshing fMain->Resize(); } TestFileList::~TestFileList() { // Cleanup. delete fContents; fMain->DeleteWindow(); // deletes fMain } void TestFileList::DoMenu(Int_t mode) { // Switch view mode. if (mode<10) { fContents->SetViewMode((EListViewMode)mode); } else { delete this; } } void TestFileList::DisplayFile(const TString &fname) { // Display content of ROOT file. TFile file(fname); fContents->RemoveAll(); fContents->AddFile(gSystem->WorkingDirectory()); fContents->SetPagePosition(0,0); fContents->SetColHeaders("Name","Title"); TIter next(file.GetListOfKeys()); TKey *key; while ((key=(TKey*)next())) { TString cname = key->GetClassName(); TString name = key->GetName(); TGLVEntry *entry = new TGLVEntry(fContents,name,cname); entry->SetSubnames(key->GetTitle()); fContents->AddItem(entry); // user data is a filename entry->SetUserData((void*)StrDup(fname)); } fMain->Resize(); } void TestFileList::DisplayDirectory(const TString &fname) { // Display content of directory. fContents->SetDefaultHeaders(); gSystem->ChangeDirectory(fname); fContents->ChangeDirectory(fname); fContents->DisplayDirectory(); fContents->AddFile(".."); // up level directory fMain->Resize(); } void TestFileList::DisplayObject(const TString& fname,const TString& name) { // Browse object located in file. TDirectory *sav = gDirectory; static TFile *file = 0; if (file) delete file; // close file = new TFile(fname); // reopen TObject* obj = file->Get(name); if (obj) { if (!obj->IsFolder()) { obj->Browse(0); } else obj->Print(); } gDirectory = sav; } void TestFileList::OnDoubleClick(TGLVEntry *f, Int_t btn) { // Handle double click. if (btn != kButton1) return; // set kWatch cursor ULong_t cur = gVirtualX->CreateCursor(kWatch); gVirtualX->SetCursor(fContents->GetId(), cur); TString name(f->GetTitle()); const char* fname = (const char*)f->GetUserData(); if (fname) { DisplayObject(fname, name); } else if (name.EndsWith(".root")) { DisplayFile(name); } else { DisplayDirectory(name); } // set kPointer cursor cur = gVirtualX->CreateCursor(kPointer); gVirtualX->SetCursor(fContents->GetId(), cur); } void TestFileList::CloseWindow() { delete this; } void guitest() { new TestMainFrame(gClient->GetRoot(), 600, 420); } //---- Main program ------------------------------------------------------------ #ifdef STANDALONE int main(int argc, char **argv) { TApplication theApp("App", &argc, argv); if (gROOT->IsBatch()) { fprintf(stderr, "%s: cannot run in batch mode\n", argv[0]); return 1; } guitest(); theApp.Run(); return 0; } #endif