Re: [ROOT] Drag and zoom?

From: Brett Viren (bv@bnl.gov)
Date: Thu Jun 07 2001 - 20:07:39 MEST


Hi David,

David Faden writes:
 >    I'd like to allow users to zoom in on a graph by clicking and dragging 
 > the mouse not on the axes but on the graph itself. Ideally, users 
 > would click at the point they want to be one corner of the zoomed view, 
 > then drag the mouse to select the area of the zoomed view. And I would 
 > like to draw a box around the area to be zoomed into. How hard is this to 
 > do with ROOT? Is there already a class included with ROOT 3.0 that 
 > provides the service I describe? If anyone has example code, I would love 
 > to see it. (Sorry if I have once again missed the obvious.)

As far as I have found you need to do some by-hand work to get this to
happen.  I do this by subclassing TPad (in a class called ``View''),
overriding ExecuteEvent and emitting a signal when a box is drawn
(click-hold-drag events).  This signal is then connected to a method
which calls View's TPad::Range() method.  I use a signal instead of
calling a function directly because other things may be interested in
this click-hold-drag gesture.

Having TPad or a TPad derived class in ROOT which emits signals in
response to various common gestures might be useful.

The overridden ExecuteEvent() is below.  If anything isn't clear, ask
away.

HTH,
-Brett.
----------------

void View::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   switch (event) {

   case kButton1Down:
       gPad->SetCursor(kHand);
       fInside = 1;
       fSelectedRange[0] = px;
       fSelectedRange[1] = py;
       break;

   case kButton1Motion:
       fInside=1;

       if (fDrawingSelection)
           gVirtualX->DrawBox(fSelectedRange[0], fSelectedRange[1],
                              fSelectedRange[2], fSelectedRange[3],
                              TVirtualX::kHollow);
       fSelectedRange[2] = px;
       fSelectedRange[3] = py;
       fDrawingSelection = true;
       gVirtualX->DrawBox(fSelectedRange[0], fSelectedRange[1],
                          fSelectedRange[2], fSelectedRange[3],
                          TVirtualX::kHollow);
       break;

   case kButton1Up: {
       gPad->SetCursor(kPointer);

       // Bail if outside pad - this check was found empirically,
       // there might be a better way???
       Int_t dtp = this->DistancetoPrimitive(fSelectedRange[2],
                                             fSelectedRange[3]);
       if (!fDrawingSelection || dtp || !fInside) {
           this->ClearSelection();
           break;
       }

       fHaveSelection = true;
       fDrawingSelection = false;

       Selected(); // emits "Selected()" signal

       break;
   }
   case kMouseLeave:
       fInside = false;
       break;
   case kMouseEnter:
       fInside = true;
       break;
   }
}

void View::Slected(void)
{
    Emit("Selected()");
}



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:49 MET