How to Pick Objects?

When the mouse is moved or a button pressed/released, the TCanvas::HandleInput function scans the list of objects in all its pads and for each object invokes object->DistancetoPrimitive(px, py). This function computes a “distance” to an object from the moose position at the pixel position px,py and return this distance in pixel units. The selected object will be the one with the shortest computed distance. To see how this work, select the Event Status item in the canvas Options menu. ROOT will display one status line showing the picked object. If the picked object is, for example an histogram, the status line indicates the name of the histogram, the position x,y in histogram coordinates, the channel number and the channel content.

If you click on the left moose button, the object->ExecuteEvent(event, px, py) function is called.

If you click with the right moose button, a context menu (see TContextMenu) with the list of possible actions for this object is shown. This context menu is automatically built by ROOT from the class dictionary by selecting the member functions having the string MENU in the comment field. Remember that the class dictionary is built by parsing your class header files.

The middle button (or left+right on a 2-buttons moose) can be used to change the current pad to the pointed pad. The current pad is always highlighted. Its frame is drawn with a special color (see TCanvas:SetHighLightColor).

Various examples of DistancetoPrimitive or ExecuteEvent functions can be seen in the ROOT source code. To users who want to write such functions, we strongly recommend to look at existing implementations in the ROOT source code. In particular, have a look at TLine::ExecuteEvent and TBox::ExecuteEvent. Note that these functions may, in turn, invoke other objects such functions in case an object is drawn using other objects. You can also exploit at best the virtues of inheritance. See for example, how the class TArrow (derived from Tline) or TPaveText (derived from TPave, itself derived from TBox) use or redefine the picking functions in their base classes.

For example in the case of an event display program, the Event::DistancetoPrimitive may loop on the list of detectors and tracks and for each detector/track object invokes its DistancetoPrimitive. See, for example TGenerator::DistancetoPrimitive.

The moose position is always given in pixel units in these two functions. px=0 and py=0 correspond to the top-left corner of the canvas. Here we have followed the standard convention in windowing systems. Note that user coordinates in a pad have the origin at the bottom-left part of the pad. One can use transformation functions such as TPad::PixeltoX, TPad::XtoPixel,etc. to convert to/from pad coordinates.

If a named object of a class MyClass(derived from) is inserted in a pad, you can get a pointer to this object with:

auto obj = (Myclass*) pad->GetPrimitive(objectname);
1 Like