/*! \page ex3 Implementing mouse and keyboard interaction
 *
 * \section overview_ex3 Overview
 *
 * Mouse interaction (especially object picking) and keyboard shortcuts
 * form essential and often used functionality in OpenFlipper. In this
 * tutorial we will learn how to use picking modes, context menus and
 * simple keyboard shortcuts. The plugin will provide the following functions:
 *
 * - Hide object by right-clicking at it and selecting our defined action
 * - Select an object by entering user defined pick mode and double-clicking
 * 	 at object in the scene
 * - Rotate selected object by hitting the j,k,h,l keys on the keyboard
 *
 * For this purpose we will make use of the following \ref interfaces
 *
 * - \ref baseInterfacePage
 * - \ref mouseInterfacePage
 * - \ref pickingInterfacePage
 * - \ref keyInterfacePage
 * - \ref contextMenuInterfacePage
 * - \ref toolboxInterfacePage
 * - \ref loggingInterfacePage
 *
 * Since we outlined the details of overriding the BaseInterface methods
 * in the previous tutorials (\ref ex1 and \ref ex2) we can directly switch
 * over to what happens within these methods. When initializing our plugin
 * we set the active object identifier to -1 since no object has been selected yet.
 * We initialize the axis vectors that we'll need for the rotation later on.
 * Then we tell OpenFlipper that we will use the j, k, h and l key on the
 * keyboard (so it'll call slotKeyEvent() each time one of
 * the keys has been pressed). Note: OpenFlipper will show up a warning message in the log
 * widget if the desired keys are already assigned to another plugin or core function.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::initializePlugin() {
 * \until } // End initializePlugin
 *
 * If all plugins have been initialized, we add our own pick mode named "MouseAndKeyPlugin"
 * to OpenFlipper and create the context menu entry (which is actually a QMenu object containing
 * one (or generally multiple) object(s) of type QAction) which we connect to contextMenuItemSelected().
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::pluginsInitialized() {
 * \until } // End pluginsInitialized
 *
 * In intializeToolbox() we create a simple toolbox containing a label and a push-button.
 * We connect the button to our method slotButtonClicked() which will then be called
 * each time the button is clicked.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip bool MouseAndKeyPlugin::initializeToolbox(QWidget*& _widget)
 * \until } // End initializeToolbox
 *
 * Now each time the button in our toolbox is clicked we want to activate
 * the picking mode, such that if the button is checked pick mode "MouseAndKeyPlugin"
 * that we defined at the beginning will be active and OpenFlipper switches over from
 * ExamineMode to PickingMode (see \ref PluginFunctions for details). Clicking once more
 * at the button will return to ExamineMode (in which the user can navigate through the scene).
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::slotButtonClicked() {
 * \until } // End slotButtonClicked
 *
 * If the pick mode has been changed externally, we want our button in the toolbox
 * to appear pressed (or unpressed respectively). _mode holds the name of the
 * currently selected pick mode.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::slotPickModeChanged(const std::string& _mode) {
 * \until } // End slotPickModeChanged
 *
 * In the next method we describe how mouse actions are to be handled by the plugin.
 * We want our plugin only to react to mouse events if our pick mode is active otherwise
 * don't do anything. If OpenFlipper is in PickingMode and the currently active pick mode
 * is "MouseAndKeyPlugin" we try to get the object on that the user has double clicked.
 * If the object can be found, we'll show up a dialog window displaying the picked object's
 * identifier and assign it to the member variable that holds the active object.
 * Otherwise we display "Picking failed" in the log widget. Note that
 * the mouse event has to be traversed through the rest of the scene graph after
 * intercepting and treating the desired mouse action.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::slotMouseEvent(QMouseEvent* _event) {
 * \until } // End slotMouseEvent
 *
 * Next method is called whenever any of the keys j, k, h or l is pressed. If an object has
 * been selected (accordingly the member variable activeObject_ holds a valid objects
 * identifier -as described before-) we try to get its handle by calling
 * PluginFunctions::getPickedObject(). We then set the rotation matrix of the selected
 * object's transform node (manipulatorNode) to hold a matrix that describes
 * a rotation around the x (if j or k is pressed) or y axis (if h or l is pressed) by +/- 10 degrees.
 * We then call the method transformMesh and pass the recently calculated matrix and
 * a handle to the mesh (triangle or polygon). We have to
 * inform OpenFlipper's core about the changes by emitting the updatedObject signal and specifying
 * that the geometry has changed.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::slotKeyEvent( QKeyEvent* _event ) {
 * \until } // End slotKeyEvent
 *
 * This template method transforms the given mesh:
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip template< typename MeshT >
 * \until } // End transformMesh
 *
 * Last but not least, the method that is called each time our context menu has been clicked.
 * We get the object's id on which the user has performed a right click from the action data.
 * Then we try to get the node and its BaseObjectData handle. If successfully passed to this
 * point we hide the object by calling its hide() method.
 *
 * \dontinclude MouseAndKeyPlugin.cc
 * \skip void MouseAndKeyPlugin::contextMenuItemSelected(QAction* _action) {
 * \until } // End contextMenuItemSelected
 *
 * \section ex3_source The complete source code of this example
 *
 * We use the same project file as before.
 *
 * MouseAndKeyPlugin.hh
 * \include MouseAndKeyPlugin.hh
 *
 * MouseAndKeyPlugin.cc
 * \include MouseAndKeyPlugin.cc
 */
