MouseGrabber Class Reference

Abstract class for mouse interactive objects. More...

#include <mouseGrabber.h>

Inherited by ManipulatedFrame.

List of all members.

Mouse detection

virtual void checkIfGrabsMouse (int x, int y, const Camera *const camera)=0
bool grabsMouse () const
void setGrabsMouse (const bool flag)

MouseGrabber pool

bool isInMouseGrabberPool () const
void addInMouseGrabberPool ()
void removeFromMouseGrabberPool ()
void clearMouseGrabberPool (bool autoDelete=false)
const QPtrList< MouseGrabber > & MouseGrabberPool ()

Mouse event handlers

virtual void mousePressEvent (QMouseEvent *const , Camera *const )
virtual void mouseDoubleClickEvent (QMouseEvent *const , Camera *const )
virtual void mouseReleaseEvent (QMouseEvent *const , Camera *const )
virtual void mouseMoveEvent (QMouseEvent *const , const Camera *const )
virtual void wheelEvent (QWheelEvent *const , const Camera *const )

Public Member Functions

 MouseGrabber ()
virtual ~MouseGrabber ()


Detailed Description

Abstract class for mouse interactive objects.

MouseGrabber are object which react to the mouse cursor, usually when it get close to them. Their actual behavior is arbitrary and has to be defined in a derived class : this class only provides a common interface for all these objects.

All the created MouseGrabber objects are grouped in a MouseGrabberPool(). All the QGLViewers parse this pool, calling all the MouseGrabbers' checkIfGrabsMouse() functions to determine if one of the MouseGrabber grabsMouse(). Individual MouseGrabbers can be removed from this pool using removeFromMouseGrabberPool() if you want to (temporarily) disable them.

When a MouseGrabber grabsMouse(), it becomes the QGLViewer::mouseGrabber(). All the mouse events (mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent(), mouseDoubleClickEvent() and wheelEvent()) are then transmitted to the QGLViewer::mouseGrabber() instead of being normally processed.

checkIfGrabsMouse() is still called after each mouse motion to check if the QGLViewer::mouseGrabber() still grabs the mouse.

In order to make MouseGrabber react to mouse events, the mouse tracking option has to be activated in the QGLViewer which wants to use MouseGrabbers:

  init() { setMouseTracking(true); }
Call QGLWidget::hasMouseTracking() to get the current state of this flag.

The camera parameter of the different functions is a pointer to the Camera used by the QGLViewer which calls the MouseGrabber. It can be used to compute 2D to 3D coordinates conversion using Camera::projectedCoordinatesOf() and Camera::unprojectedCoordinatesOf().

Very complex behaviors can be implemented using this framework: auto-selected objects (no need to press a key to use them), automatic drop-down menus, 3D GUI, spinners using the wheelEvent(), and whatever your imagination creates.

See the mouseGrabber example for an illustration. Note that ManipulatedFrame are MouseGrabber : see the keyFrame example for an illustration. Every created ManipulatedFrame is hence inserted in the MouseGrabberPool() (note however that ManipulatedCameraFrame are not inserted).

Here is for instance a draft version of a movableObject class. Instances of these class can freely be moved on screen using the mouse. A possible application would be movable post-it-like notes.

  class MovableObject : public MouseGrabber
  {
  public:
    MovableObject() : posX(0), posY(0), moved(false) {};

    void checkIfGrabsMouse(int x, int y, const qglviewer::Camera* const)
    {
      // Active in a region of 5 pixels. Should depend on the actual shape of the object.
      setGrabsMouse( sqrt((x-posX)*(x-posX) + (y-posY)*(y-posY)) < 5 );
    }

    void mousePressEvent(QMouseEvent *e, Camera* const) { lastPos = e->pos(); moved = true; }
    void mouseReleaseEvent(QMouseEvent *, Camera* const) { moved = false; }
    
    void mouseMoveEvent(QMouseEvent *e, Camera* const)
    {
      if (moved)
      {
        // Add position delta to current pos
        pos += e->pos() - lastPos;
        lastPos() = e->pos();
      }
    }

    void draw()
    {
      // The object is drawned centered on its pos, with different possible aspects:
      if (grabsMouse())
        if (moved)
          // Object being moved, maybe a transparent display
        else
          // Visual feedback (highlight) : object ready to be grabbed 
      else
        // Normal display
    }
  private:
    QPoint pos, lastPos;
    bool moved;
  };


Constructor & Destructor Documentation

MouseGrabber  ) 
 

Adds the created MouseGrabber in the MouseGrabberPool(). grabsMouse() set to false.

virtual ~MouseGrabber  )  [inline, virtual]
 

Virtual destructor. Removes object from the MouseGrabberPool().


Member Function Documentation

void addInMouseGrabberPool  ) 
 

Adds the MouseGrabber in the MouseGrabberPool(). Note that all MouseGrabber are automatically added in the MouseGrabberPool() by the constructor. Trying to add a MouseGrabber that already isInMouseGrabberPool() has no effect.

Use removeFromMouseGrabberPool() to remove the MouseGrabber from the list, so that it is no longer tested with checkIfGrabsMouse() by the QGLViewer. Use isInMouseGrabberPool() to know the current state of the MouseGrabber.

virtual void checkIfGrabsMouse int  x,
int  y,
const Camera *const   camera
[pure virtual]
 

This is the core function of the MouseGrabber. It has to be overloaded and defined in your derived classes. Its goal is to update the grabsMouse() flag according to the mouse current positon, using setGrabsMouse().

grabsMouse() should be set to true when the mouse cursor is close enough to the MouseGrabber position (or whatever is appropriate). It also must be set to false as soon as the mouse cursor leaves this region in order to release the mouse focus for the other parts of the application.

A typical implementation will look like:

    // (posX,posY) is the position of the MouseGrabber on screen.
    // (0,0) corresponds to the upper left corner (Qt coordinate system).
    // Here, distance to mouse must be less than 10 pixels to activate the MouseGrabber.
    setGrabsMouse( sqrt((x-posX)*(x-posX) + (y-posY)*(y-posY)) < 10);

If the MouseGrabber position is defined in 3D. Project it on screen and then compare the projected coordinates:

    Vec proj = camera->projectedCoordinatesOf(myObject->frame()->position());
    setGrabsMouse((fabs(x-proj.x) < 5) && (fabs(y-proj.y) < 2));

More complex behavior can be obtained using extra flags, for instance related to mousePressEvent() and mouseReleaseEvent(). See the detailed description section and the mouseGrabber example.

Implemented in ManipulatedFrame.

void clearMouseGrabberPool bool  autoDelete = false  ) 
 

Clears the mouseGrabberPool(). Consider using QGLViewer::setMouseTracking(false) to disable all mouse grabbers.

When autoDelete is set to true, all the MouseGrabbers themselves are actually deleted (use this only if you're sure of what you do).

bool grabsMouse  )  const [inline]
 

Returns true when the MouseGrabber grabs the mouse and hence receives all the QGLViewer's mouse events. This flag is set with setGrabsMouse() by the checkIfGrabsMouse() function.

bool isInMouseGrabberPool  )  const [inline]
 

Returns true if the MouseGrabber is currently in the MouseGrabberPool(). Default value is true. When set to false using removeFromMouseGrabberPool(), the MouseGrabber is no longer checkIfGrabsMouse() by QGLViewers. See also addInMouseGrabberPool().

virtual void mouseDoubleClickEvent QMouseEvent *  const ,
Camera const
[inline, protected, virtual]
 

See the associated QGLWidget documentation. See also mousePressEvent().

const QPtrList<MouseGrabber>& MouseGrabberPool  )  [inline, static]
 

This list contains all the created MouseGrabber. Used by the QGLViewer to check if any of them grabsMouse() using checkIfGrabsMouse().

You should not have to directly use this list. In case you want to, use code like:

    QPtrListIterator<MouseGrabber> it(MouseGrabber::MouseGrabberPool());
    for (MouseGrabber* mg; (mg = it.current()) != NULL; ++it)
      mg->anyAction(); // possible dynamic_cast here.

virtual void mouseMoveEvent QMouseEvent *  const ,
const Camera const
[inline, protected, virtual]
 

See the associated QGLWidget documentation. Probably useful to update the state of the MouseGrabber between a mousePressEvent() and a mouseReleaseEvent(). See the detailed description section for an example.

Reimplemented in ManipulatedCameraFrame, and ManipulatedFrame.

virtual void mousePressEvent QMouseEvent *  const ,
Camera const
[inline, protected, virtual]
 

See the associated QGLWidget documentation. The MouseGrabber will probably start an action or change its state when a mouse button is pressed. See the detailed description section for an example.

Reimplemented in ManipulatedFrame.

virtual void mouseReleaseEvent QMouseEvent *  const ,
Camera const
[inline, protected, virtual]
 

See the associated QGLWidget documentation. A probable use of this function will be to desactivate the MouseGrabber. See the detailed description section for an example.

Reimplemented in ManipulatedCameraFrame, and ManipulatedFrame.

void removeFromMouseGrabberPool  ) 
 

Removes the MouseGrabber from the MouseGrabberPool(). See addInMouseGrabberPool() for details. Removing a MouseGrabber that is not in MouseGrabberPool() has no effect.

void setGrabsMouse const bool  flag  )  [inline, protected]
 

The protected method is used to define the grabsMouse() flag. See the grabsMouse() and the checkIfGrabsMouse() documentations.

virtual void wheelEvent QWheelEvent *  const ,
const Camera const
[inline, protected, virtual]
 

See the associated QGLWidget documentation. Can be useful to implement spinners.

Reimplemented in ManipulatedCameraFrame, and ManipulatedFrame.


Generated on Wed Jul 7 12:17:47 2004 for libQGLViewer by doxygen 1.3.4