Hi All, I need to get an indication of a mouse button event on a graph and find the graph point clicked. To this end I've overridden the TGraph::ExecuteEvent function and added my own code at the bottom: void TGraph::ExecuteEvent(Int_t event, Int_t px, Int_t py) { //*-*-*-*-*-*-*-*-*-*-*Execute action corresponding to one event*-*-*-* //*-* ========================================= // This member function is called when a graph is clicked with the locator // // If Left button clicked on one of the line end points, this point // follows the cursor until button is released. // // if Middle button clicked, the line is moved parallel to itself // until the button is released. // Int_t i, d; Double_t xmin, xmax, ymin, ymax, dx, dy, dxr, dyr; const Int_t kMaxDiff = 10; static Bool_t MIDDLE, BADCASE; static Int_t ipoint, pxp, pyp; static Int_t px1,px2,py1,py2; static Int_t pxold, pyold, px1old, py1old, px2old, py2old; static Int_t dpx, dpy; static Int_t *x=0, *y=0; if (!IsEditable()) {gPad->SetCursor(kHand); return;} if (!gPad->IsEditable()) return; // printf("%i\n",event); switch (event) { case kButton1Down: printf("Button 1 Down\n"); BADCASE = kFALSE; gVirtualX->SetLineColor(-1); TAttLine::Modify(); //Change line attributes only if necessary px1 = gPad->XtoAbsPixel(gPad->GetX1()); py1 = gPad->YtoAbsPixel(gPad->GetY1()); px2 = gPad->XtoAbsPixel(gPad->GetX2()); py2 = gPad->YtoAbsPixel(gPad->GetY2()); ipoint = -1; if (x || y) break; x = new Int_t[fNpoints+1]; y = new Int_t[fNpoints+1]; for (i=0;i<fNpoints;i++) { pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i])); pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i])); if (pxp < -kMaxPixel || pxp >= kMaxPixel || pyp < -kMaxPixel || pyp >= kMaxPixel) { BADCASE = kTRUE; continue; } gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4); gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4); gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4); gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4); x[i] = pxp; y[i] = pyp; d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py); if (d < kMaxDiff) ipoint =i; } dpx = 0; dpy = 0; pxold = px; pyold = py; if (ipoint < 0) return; if (ipoint == 0) { px1old = 0; py1old = 0; px2old = gPad->XtoAbsPixel(fX[1]); py2old = gPad->YtoAbsPixel(fY[1]); } else if (ipoint == fNpoints-1) { px1old = gPad->XtoAbsPixel(gPad->XtoPad(fX[fNpoints-2])); py1old = gPad->YtoAbsPixel(gPad->YtoPad(fY[fNpoints-2])); px2old = 0; py2old = 0; } else { px1old = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint-1])); py1old = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint-1])); px2old = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint+1])); py2old = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint+1])); } pxold = gPad->XtoAbsPixel(gPad->XtoPad(fX[ipoint])); pyold = gPad->YtoAbsPixel(gPad->YtoPad(fY[ipoint])); /* if (this==BBF->EGraph) { //printf("E Plane Point Number: %i\n",ipoint+1); TCanvas *c1=new TCanvas(); sprintf(dummy,"E Plane Channel %i TDC Left",ipoint+1); TH1F tdcl("tdcl",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i TDC Right",ipoint+1); TH1F tdcr("tdcr",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i ADC Left",ipoint+1); TH1F adcl("adcl",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i ADC Right",ipoint+1); TH1F adcr("adcr",dummy,100,0,2000); //c1->Divide(2,2); sprintf(dummy,"BB.tp.e.lt.data[%i]",ipoint); sprintf(dummy1,"BB.tp.e.lt.data[%i]>0",ipoint); BBTree->Draw(dummy,dummy1); c1->cd(2); sprintf(dummy,"BB.tp.e.rt.data[%i]",ipoint); BBTree->Draw(dummy); c1->cd(3); sprintf(dummy,"BB.tp.e.la.data[%i]",ipoint); BBTree->Draw(dummy); c1->cd(4); sprintf(dummy,"BB.tp.e.ra.data[%i]",ipoint); BBTree->Draw(dummy); // BBTree->Draw("BB.tp.e.nlthit"); } else if (this==BBF->DEGraph) { } */ break; case kMouseMotion: MIDDLE = kTRUE; for (i=0;i<fNpoints;i++) { pxp = gPad->XtoAbsPixel(gPad->XtoPad(fX[i])); pyp = gPad->YtoAbsPixel(gPad->YtoPad(fY[i])); d = TMath::Abs(pxp-px) + TMath::Abs(pyp-py); if (d < kMaxDiff) MIDDLE = kFALSE; } //*-*- check if point is close to an axis if (MIDDLE) gPad->SetCursor(kMove); else gPad->SetCursor(kHand); break; case kButton1Motion: if (MIDDLE) { for(i=0;i<fNpoints-1;i++) { gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy); pxp = x[i]+dpx; pyp = y[i]+dpy; if (pxp < -kMaxPixel || pxp >= kMaxPixel || pyp < -kMaxPixel || pyp >= kMaxPixel) continue; gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4); gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4); gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4); gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4); } pxp = x[fNpoints-1]+dpx; pyp = y[fNpoints-1]+dpy; gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4); gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4); gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4); gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4); dpx += px - pxold; dpy += py - pyold; pxold = px; pyold = py; for(i=0;i<fNpoints-1;i++) { gVirtualX->DrawLine(x[i]+dpx, y[i]+dpy, x[i+1]+dpx, y[i+1]+dpy); pxp = x[i]+dpx; pyp = y[i]+dpy; if (pxp < -kMaxPixel || pxp >= kMaxPixel || pyp < -kMaxPixel || pyp >= kMaxPixel) continue; gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4); gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4); gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4); gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4); } pxp = x[fNpoints-1]+dpx; pyp = y[fNpoints-1]+dpy; gVirtualX->DrawLine(pxp-4, pyp-4, pxp+4, pyp-4); gVirtualX->DrawLine(pxp+4, pyp-4, pxp+4, pyp+4); gVirtualX->DrawLine(pxp+4, pyp+4, pxp-4, pyp+4); gVirtualX->DrawLine(pxp-4, pyp+4, pxp-4, pyp-4); } else { if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold); if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old); gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4); gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4); gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4); gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4); pxold = px; pxold = TMath::Max(pxold, px1); pxold = TMath::Min(pxold, px2); pyold = py; pyold = TMath::Max(pyold, py2); pyold = TMath::Min(pyold, py1); if (px1old) gVirtualX->DrawLine(px1old, py1old, pxold, pyold); if (px2old) gVirtualX->DrawLine(pxold, pyold, px2old, py2old); gVirtualX->DrawLine(pxold-4, pyold-4, pxold+4, pyold-4); gVirtualX->DrawLine(pxold+4, pyold-4, pxold+4, pyold+4); gVirtualX->DrawLine(pxold+4, pyold+4, pxold-4, pyold+4); gVirtualX->DrawLine(pxold-4, pyold+4, pxold-4, pyold-4); } break; case kButton1Up: xmin = gPad->GetUxmin(); xmax = gPad->GetUxmax(); ymin = gPad->GetUymin(); ymax = gPad->GetUymax(); dx = xmax-xmin; dy = ymax-ymin; dxr = dx/(1 - gPad->GetLeftMargin() - gPad->GetRightMargin()); dyr = dy/(1 - gPad->GetBottomMargin() - gPad->GetTopMargin()); gPad->Range(xmin - dxr*gPad->GetLeftMargin(), ymin - dyr*gPad->GetBottomMargin(), xmax + dxr*gPad->GetRightMargin(), ymax + dyr*gPad->GetTopMargin()); gPad->RangeAxis(xmin, ymin, xmax, ymax); if (MIDDLE) { for(i=0;i<fNpoints;i++) { if (BADCASE) continue; //do not update if big zoom and points moved fX[i] = gPad->PadtoX(gPad->AbsPixeltoX(x[i]+dpx)); fY[i] = gPad->PadtoY(gPad->AbsPixeltoY(y[i]+dpy)); } } else { fX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(pxold)); fY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(pyold)); if (InheritsFrom("TCutG")) { //make sure first and last point are the same if (ipoint == 0) { fX[fNpoints-1] = fX[0]; fY[fNpoints-1] = fY[0]; } if (ipoint == fNpoints-1) { fX[0] = fX[fNpoints-1]; fY[0] = fY[fNpoints-1]; } } } BADCASE = kFALSE; delete [] x; x = 0; delete [] y; y = 0; gPad->Modified(kTRUE); gVirtualX->SetLineColor(-1); if (this==BBF->EGraph) { //printf("E Plane Point Number: %i\n",ipoint+1); TCanvas *c1=new TCanvas(); sprintf(dummy,"E Plane Channel %i TDC Left",ipoint+1); TH1F tdcl("tdcl",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i TDC Right",ipoint+1); TH1F tdcr("tdcr",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i ADC Left",ipoint+1); TH1F adcl("adcl",dummy,100,0,2000); sprintf(dummy,"E Plane Channel %i ADC Right",ipoint+1); TH1F adcr("adcr",dummy,100,0,2000); //c1->Divide(2,2); sprintf(dummy,"BB.tp.e.lt.data[%i]",ipoint); sprintf(dummy1,"BB.tp.e.lt.data[%i]>0",ipoint); BBTree->Draw(dummy,dummy1); // BBTree->Draw("BB.tp.e.nlthit"); } else if (this==BBF->DEGraph) { } } } The problem is that when I do this I get the following error message when clicking on the graph: *** Break *** segmentation violation Generating stack trace... 0x401aa93b in TUnixSystem::StackTrace(void) + 0x25b from /home/rshneor/root/lib/libCore.so 0x401a95ba in TUnixSystem::DispatchSignals(ESignals) + 0xb2 from /home/rshneor/root/lib/libCore.so 0x401a8763 in <unknown> from /home/rshneor/root/lib/libCore.so 0x401ac1fd in <unknown> from /home/rshneor/root/lib/libCore.so 0x41036f05 in <unknown> from /lib/i686/libpthread.so.0 0x42029188 in <unknown> from ./BBgui 0x00000000 in <unknown function> and the program still runs, when I try to divide the new canvas, though, and try to plot several histograms it crashes completely. My questions are: 1. What's happening and is there any way to avoid it? 2. I may be able to work around this by storing the number of the clicked opint somewhere and using a timer to plot the histograms, so how do I set up such a timer? Thanks, Guy Ron Tel Aviv University
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:12 MET