## interactive

interactive — Gives tools to interact with the rendered area.

## Synopsis

                        VisuInteractive;
    enum                SpecialKeyStroke;
    gboolean            (*callBackOnEventFunc)              (SimplifiedEvents *event,
                                                             VisuInteractive *inter);
    void                (*callBackOnNodeSelectedFunc)       (PickMesure *mesureData,
                                                             gpointer data);
    #define             OPENGL_OBSERVE_CONSTRAINED
    #define             OPENGL_OBSERVE_WALKER
    VisuInteractive*    openGLInteractiveInit_session       (GenericRenderingWindow window,
                                                             callBackOnNodeSelectedFunc handler,
                                                             gpointer data,
                                                             GDestroyNotify stopPickObserve);
    void                openGLInteractiveEnd_session        (VisuInteractive *inter);
    void                openGLInteractiveBegin_mark         (VisuInteractive *inter);
    void                openGLInteractiveBegin_move         (VisuInteractive *inter);
    void                openGLInteractiveBegin_observe      (VisuInteractive *inter);
    void                openGLInteractiveBegin_pick         (VisuInteractive *inter);
    void                openGLInteractiveBegin_pickAndObserve
                                                            (VisuInteractive *inter);
    void                openGLInteractiveSet_visuData       (VisuInteractive *inter,
                                                             VisuData *data);
    void                openGLInteractiveSet_preferedObserveMethod
                                                            (int method);
    int                 openGLInteractiveGet_preferedObserveMethod
                                                            ();
    PickMesure*         openGLInteractiveGet_pickMesure     (VisuInteractive *inter);
    void                openGLInteractiveHandle_event       (SimplifiedEvents *ev,
                                                             VisuInteractive *inter);
    void                openGLInteractiveMove               (VisuInteractive *inter,
                                                             GList *nodes,
                                                             float drag[3]);
    void                openGLInteractiveStart_move         (VisuInteractive *inter,
                                                             GList *nodes);
    void                openGLInteractiveStop_move          (VisuInteractive *inter,
                                                             GList *nodes);

    void                openGLInteractive_init              ();

## Description

When one wants some interactions on the rendering area (either from the mouse or from the keyboard), one should initialise it using `openGLInteractiveInit_session()`. Then, during the interactive session, several modes have been implemented:

- `openGLInteractiveBegin_mark()`, is a mode where the mouse can select a node and this nodes become highlighted.

- `openGLInteractiveBegin_move()`, the mouse is then used to move picked nodes. Moves are possible in the plane of the screen or constrained along axis of the bounding box.

- `openGLInteractiveBegin_observe()`, in this mode, the mouse is used to change the position of camera, its orientation and its zoom characteristics.

- `openGLInteractiveBegin_pick()`, this mode is the most complex picking mode. It can select atoms up to two references and measure distances and angles.

- `openGLInteractiveBegin_pickAndObserve()`, this mode is a simplified mix of obervation and picking.

The observe mode has two different moving algorithms that can be changed using `openGLInteractiveSet_preferedObserveMethod()`. The first, called 'constrained' (cf. OPENGL_OBSERVE_CONSTRAINED) corresponds to movements along parallels and meridians. When the mouse is moved along x axis, the camera raotates along a parallel. When the camera is moved along y axis, the camera rotate along a meridian. The top is always pointing to the north pole (in fact, omega is always forced to 0 in this mode). This mode has a 'strange' behavior when the observer is near a pole: moving mouse along x axis make the box rotates on itself. It is normal, because movements on x axis is equivalent to movements on parallel and near the poles, parallel are small circle around the z axis. This can be unnatural in some occasion and the other mode, called 'walker' (see OPENGL_OBSERVE_WALKER) can be used instead of the 'constrained' mode. In the former, the moving is done has if the observer was a walking ant on a sphere : moving the mouse along y axis makes the ant go on or forward ; and x axis movements makes the ant goes on its left or on it right. This is a more natural way to move the box but it has the inconvient that it is hard to return in a given position (omega has never the right value).

## Details

### VisuInteractive

    typedef struct _VisuInteractive VisuInteractive;

All fields are private.

### enum SpecialKeyStroke

    typedef enum
      {
        Key_None,
        Key_Page_Up,
        Key_Page_Down,
        Key_Arrow_Left,
        Key_Arrow_Right,
        Key_Arrow_Up,
        Key_Arrow_Down
      } SpecialKeyStroke;

Possible non ascii keys used in SimplifiedEvents.

`Key_None` | no key pressed ;
`Key_Page_Up` | key up ;
`Key_Page_Down` | key down ;
`Key_Arrow_Left` | key left ;
`Key_Arrow_Right` | key right ;
`Key_Arrow_Up` | key up ;
`Key_Arrow_Down` | key down.

### callBackOnEventFunc ()

    gboolean            (*callBackOnEventFunc)              (SimplifiedEvents *event,
                                                             VisuInteractive *inter);

An interface to methods that can be called whenever an action occurs.

`event` : | the event that triggered the action ;
`inter` : | the VisuInteractive object the callback deals with.
Returns : | TRUE if action should be stopped after this call.

### callBackOnNodeSelectedFunc ()

    void                (*callBackOnNodeSelectedFunc)       (PickMesure *mesureData,
                                                             gpointer data);

This interface defines functions that are called whenever a node is selected.

`mesureData` : | the object that stores the pick information ;
`data` : | a pointer to user define data.

### OPENGL_OBSERVE_CONSTRAINED

    #define OPENGL_OBSERVE_CONSTRAINED 0

This is a key for the constrained mode in the observe session. In this mode, the movements are along meridians when the mouse is dragged along y axis and along parallels when the movement is along x axis.

### OPENGL_OBSERVE_WALKER

    #define OPENGL_OBSERVE_WALKER 1

This is a key for the constrained mode in the observe session. In this mode, the movementsare those of a walking ant on a sphere, when mouse move along y axis, the ant goes strait on, when mouse is dragged along x axis, the ant translates on its right or on its left.

### openGLInteractiveInit_session ()

    VisuInteractive*    openGLInteractiveInit_session       (GenericRenderingWindow window,
                                                             callBackOnNodeSelectedFunc handler,
                                                             gpointer data,
                                                             GDestroyNotify stopPickObserve);

Initialises a period when the client can control an interactive session (observe, pick, move...). It changes cursors shapes and initialises different internal variables. It can be stop by a call to `openGLInteractiveEnd_session()`. The default first interactive session is an observe session.

`window` : | a pointer to the window that ask to initialize an interactive mode ;
`handler` : | a pointer to a method to be called whenever an element is selected (can be NULL) ;
`data` : | a location for user data that can be given to handler ;
`stopPickObserve` : | a pointer to a method that will be called every time a pick or an observe session are finish (can be NULL).
Returns : | a newly created object. This object is automatically associated to the VisuData handled by the `window` and will be destroyed with it.

### openGLInteractiveEnd_session ()

    void                openGLInteractiveEnd_session        (VisuInteractive *inter);

Stop the period when pick or observe sessions are allowed. Basically, for the user point of view it returns the cursor to its initial shape.

`inter` : | a VisuInteractive object.

### openGLInteractiveBegin_mark ()

    void                openGLInteractiveBegin_mark         (VisuInteractive *inter);

During an interactive session, the client can begin a mark session by a call to this method. It enables the press-button (and release), the motion-notify and the scroll event. A mark is drawn around the selected element (or removed) when clicked. To begin an interactive session, see `openGLInteractiveInit_session()`.

`inter` : | a VisuInteractive object.

### openGLInteractiveBegin_move ()

    void                openGLInteractiveBegin_move         (VisuInteractive *inter);

During an interactive session, the client can begin a move session by a call to this method. It enables the press-button (and release), the motion-notify and the scroll event. It returns the displacement and the node selected.

`inter` : | a VisuInteractive object.

### openGLInteractiveBegin_observe ()

    void                openGLInteractiveBegin_observe      (VisuInteractive *inter);

During a pick or observe session, the client can begin an observe session by a call to this method. It actually stops also a possibly running pick session.

`inter` : | a VisuInteractive object.

### openGLInteractiveBegin_pick ()

    void                openGLInteractiveBegin_pick         (VisuInteractive *inter);

During a pick or observe session, the client can begin a pick session by a call to this method. It actually stops also a possibly running observe session.

`inter` : | a VisuInteractive object.

### openGLInteractiveBegin_pickAndObserve ()

    void                openGLInteractiveBegin_pickAndObserve
                                                            (VisuInteractive *inter);

During a pick or observe session, the client can both observe (normal way) and do minimal pick with the right button.

`inter` : | a VisuInteractive object.

### openGLInteractiveSet_visuData ()

    void                openGLInteractiveSet_visuData       (VisuInteractive *inter,
                                                             VisuData *data);

Change the VisuData the interactive session is dealing with.

`inter` : | a VisuInteractive object ;
`data` : | a VisuData object.

### openGLInteractiveSet_preferedObserveMethod ()

    void                openGLInteractiveSet_preferedObserveMethod
                                                            (int method);

There are two methods to move the camera in a pick and observe sesion. These two methods are described in the commentary of the keys OPENGL_OBSERVE_CONSTRAINED an dOPENGL_OBSERVE_WALKER.

`method` : | an integer that identify the method, see OPENGL_OBSERVE_CONSTRAINED, and OPENGL_OBSERVE_WALKER flags.

### openGLInteractiveGet_preferedObserveMethod ()

    int                 openGLInteractiveGet_preferedObserveMethod
                                                            ();

There are two methods to move the camera in a pick and observe sesion. These two methods are described in the commentary of the keys OPENGL_OBSERVE_CONSTRAINED an dOPENGL_OBSERVE_WALKER.

Returns : | an integer that identify the method, see OPENGL_OBSERVE_CONSTRAINED, and OPENGL_OBSERVE_WALKER flags.

### openGLInteractiveGet_pickMesure ()

    PickMesure*         openGLInteractiveGet_pickMesure     (VisuInteractive *inter);

Get the PickMesure object associated to an interactive session.

`inter` : | a VisuInteractive object.
Returns : | a PickMesure object, private.

### openGLInteractiveHandle_event ()

    void                openGLInteractiveHandle_event       (SimplifiedEvents *ev,
                                                             VisuInteractive *inter);

This routine should be called by the rendering window when some event is raised on the rendering surface.

`ev` : | an event ;
`inter` : | a VisuInteractive object.

### openGLInteractiveMove ()

    void                openGLInteractiveMove               (VisuInteractive *inter,
                                                             GList *nodes,
                                                             float drag[3]);

Update the internal of `inter` when the given list is dragged.

`inter` : | a VisuInteractive object ;
`nodes` : | a list of VisuNode ids ;
`drag` : | a translation (in cartesian coordinates).

### openGLInteractiveStart_move ()

    void                openGLInteractiveStart_move         (VisuInteractive *inter,
                                                             GList *nodes);

Update the internal of `inter` when the given list is dragged. This means to create a new list with the given nodes and remove them from the classical VisuData OpenGL lists. A redraw is automatically asked.

`inter` : | a VisuInteractive object ;
`nodes` : | a list of VisuNode (not ids).

### openGLInteractiveStop_move ()

    void                openGLInteractiveStop_move          (VisuInteractive *inter,
                                                             GList *nodes);

Update the internal of `inter` when the drag stops. The `nodes` are recreated in the OpenGL lists of VisuData. A redraw is automatically asked.

`inter` : | a VisuInteractive object ;
`nodes` : | a list of VisuNode (not ids).

### openGLInteractive_init ()

    void                openGLInteractive_init              ();

Used to initialise this part of code, don't use it.