.. _input-handler-page:

#############################
Navigation and Input Handlers
#############################


|ProductName| has built in support for manipulating the camera from input events (typically mouse interaction).

The :class:`Camera <cee::vis::Camera>` has an input handler, :class:`CameraInputHandler <cee::vis::CameraInputHandler>`, 
that handles user input (mouse and keyboard events) and manipulates 
the camera based on these events. This is used to move the camera around the scene to inspect the model.

|ProductName| provides two default Input Handlers:

-   :class:`CameraInputHandlerZoom <cee::vis::CameraInputHandlerZoom>`: Envision style zoom navigation. This is the 
    default navigation handler.
-   :class:`CameraInputHandlerWalk <cee::vis::CameraInputHandlerWalk>`: Envision style walk navigation.  

The built-in navigation schemes are using Pan on left mouse button, Rotate on right 
mouse button and Zoom/Walk on mouse wheel (or both left and right mouse buttons).

The easiest way to add a custom navigation scheme is to derive from the 
:class:`CameraInputHandler <cee::vis::CameraInputHandler>` class and override the
:func:`navigationTypeFromInputState() <cee::vis::CameraInputHandler::navigationTypeFromInputState>` method. 
The :func:`navigationTypeFromInputState() <cee::vis::CameraInputHandler::navigationTypeFromInputState>` 
method should return the wanted navigation type (PAN, ROTATE, WALK, ZOOM) based on 
the mouse and keyboard input state.

The :func:`wheelNavigationType() <cee::vis::CameraInputHandler::wheelNavigationType>` determines the use of the mouse 
wheel. Usually WALK or ZOOM.

In more advanced cases the user can also override the 
:func:`mousePressEvent() <cee::vis::CameraInputHandler::mousePressEvent>`, 
:func:`mouseMoveEvent() <cee::vis::CameraInputHandler::mouseMoveEvent>`, 
:func:`mouseReleaseEvent() <cee::vis::CameraInputHandler::mouseReleaseEvent>` and
:func:`wheelEvent() <cee::vis::CameraInputHandler::wheelEvent>` methods and create a fully custom user experience.


**Example Custom Input Handler**

.. code-block:: cpp

    //--------------------------------------------------------------------------------------------------
    // A custom input handler implementing our navigation scheme
    //--------------------------------------------------------------------------------------------------
    class MyInputHandler : public cee::vis::CameraInputHandler
    {
    protected:

        // Determine the navigation type from the given input state
        // Out custom scheme uses the left mouse button for navigation (reserving the right for e.g. context menu).
        // - Left button + CTRL = PAN
        // - Left button + Shift = Rotate
        // - Left button + CTRL and Shift = Zoom
        // - Mouse wheel = zoom
        virtual NavigationType  navigationTypeFromInputState(cee::vis::MouseButtons mouseButtons, cee::vis::KeyboardModifiers keyboardModifiers) const
        {
            if (mouseButtons == cee::vis::LeftButton && keyboardModifiers == cee::vis::ControlModifier)
            {
                return PAN;
            }
            else if (mouseButtons == cee::vis::LeftButton && keyboardModifiers == cee::vis::ShiftModifier)
            {
                return ROTATE;
            }
            else if ((mouseButtons == cee::vis::LeftButton) && (keyboardModifiers == (cee::vis::ControlModifier | cee::vis::ShiftModifier)))
            {
                return ZOOM;
            }

            return NONE;
        }

        // Zoom for the mouse wheel
        virtual NavigationType wheelNavigationType() const
        {
            return CameraInputHandler::ZOOM;
        }
    };

**Connecting Your Own Custom Input Handler**

.. code-block:: cpp

    // Setup the camera to use our own custom navigation input handler
    m_view->camera().setInputHandler(new MyInputHandler);

**Tutorial**

.. |img| image:: ../../images/tut_customnavigation.png
   :width: 150
   :target: ../../tutorials/custom-navigation.html

+-----------------------+------------------------------------------------------------------------------------+
| |img|                 | :ref:`custom-navigation-tutorial`                                                  |
+-----------------------+------------------------------------------------------------------------------------+

