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