Tulip  4.6.0
Better Visualization Through Research
library/tulip-gui/include/tulip/Interactor.h
00001 /*
00002  *
00003  * This file is part of Tulip (www.tulip-software.org)
00004  *
00005  * Authors: David Auber and the Tulip development Team
00006  * from LaBRI, University of Bordeaux
00007  *
00008  * Tulip is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation, either version 3
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Tulip is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  *
00018  */
00019 
00020 #ifndef _INTERACTOR_H
00021 #define _INTERACTOR_H
00022 
00023 #include <tulip/Plugin.h>
00024 
00025 #include <QObject>
00026 #include <QCursor>
00027 #include <QMap>
00028 
00029 #include <string>
00030 
00031 class QAction;
00032 
00033 namespace tlp {
00034 
00035 static const std::string INTERACTOR_CATEGORY = "Interactor";
00036 
00037 class View;
00038 
00039 /**
00040   @ingroup Plugins
00041   @brief Interactor provides a way to handle user inputs over a view.
00042   Basically, The interactor class is an overlay to the Qt's event filtering mechanism. It adds several features like the ability to define priorities, custom cursors, etc
00043 
00044   When an interactor is constructed, the following methods are called in this order:
00045   @li The constructor. This method should almost be a no-op. Interactors may be instantiated by the plugin manager system and doing unneeded operations in the constructor may lead to poor performances when the application loads up.
00046   @li isCompatible. When creating a View, the application will check for all interactors to see if they could be installed on it. This is done using the isCompatible method.
00047   @li construct. Initialize the interactor. Since the constructor should be a no-op, initialization code should be put here.
00048   @li setView. Defines the view this interactor is bound to. The Interactor may keep a reference to the view object to perform specific operations on user inputs.
00049 
00050   Methods listed above are only called once. Once the interactor is initialized, it may be installed/removed several times on different QObjects. It will then repond to user inputs via the eventFilter method
00051   @see QObject::eventFilter()
00052   */
00053 class TLP_QT_SCOPE Interactor: public QObject, public Plugin {
00054   Q_OBJECT
00055   Q_PROPERTY(unsigned int priority READ priority)
00056   Q_PROPERTY(QAction* action READ action)
00057   Q_PROPERTY(tlp::View* view READ view WRITE setView)
00058   Q_PROPERTY(QCursor cursor READ cursor)
00059 
00060 public:
00061   virtual std::string category() const {
00062     return INTERACTOR_CATEGORY;
00063   }
00064   std::string icon() const {
00065     return ":/tulip/gui/icons/32/plugin_interactor.png";
00066   }
00067   /**
00068     @brief Checks the compatibility between the interactor and the given view (identified by its name).
00069     If this method returns true, it's very likely that the interactor will be installed on the associated view.
00070     */
00071   virtual bool isCompatible(const std::string& viewName) const=0;
00072 
00073   /**
00074     @return the configuration widget used to set up the interactor.
00075     @warning This method MUST ALWAYS return the same pointer. Doing otherwise may lead to memory leaks.
00076     @note The configuration widget has to be instantiated from the construct method.
00077     @note It is up to the interactor developper to delete the configuration widget
00078     */
00079   virtual QWidget* configurationWidget() const=0;
00080 
00081   /**
00082     @return the interactor's priority.
00083     Priority defines how interactors gets ordered when displayed in the View's toolbar.
00084     Interactors with the top-most priority value will be displayed at the beginning of the list while lowest priority will be position at the end.
00085     */
00086   virtual unsigned int priority() const=0;
00087 
00088   /**
00089     @return a QAction associated to this interactor.
00090     This is used by the overleying system to associate an icon/text to the interactor.
00091     @warning The parent (QObject::parent()) object of this QAction MUST BE the Interactor.
00092     */
00093   virtual QAction* action() const=0;
00094 
00095   /**
00096     @return the View object associated to this Interactor.
00097     @warning The returned object MUST be the same as the one passed down to the setView method.
00098     */
00099   virtual tlp::View* view() const=0;
00100 
00101   /**
00102     @return The cursor associated to this interactor.
00103     When the interactor gets active on a view, the View's cursor is changed to what this method returns.
00104     */
00105   virtual QCursor cursor() const=0;
00106 
00107   /**
00108     @brief Builds up the interactor's internal state.
00109     This method should be used instead of the constructor to initialize the interactor.
00110     */
00111   virtual void construct()=0;
00112 
00113 public slots:
00114   /**
00115     @brief Defines the view object associated to this interactor.
00116     @warning The view() method MUST ALWAYS return the same pointer as the one passed down to this method.
00117     */
00118   virtual void setView(tlp::View*)=0;
00119 
00120   /**
00121     @brief Install the interactor on the given target
00122     A call to this method means thatr the interactor should start listening to the target's events and handle them.
00123     Returning true prevents further handling of the event. Doing otherwise means that the interactor will let following filters to hand over this kind of event.
00124     */
00125   virtual void install(QObject* target)=0;
00126 
00127   /**
00128     @brief Removes the interactor from the previously set target.
00129     Interactors can be installed on only one target at once.
00130     */
00131   virtual void uninstall()=0;
00132 
00133   /**
00134     @brief Informs the interactor when the undo command (Ctrl+Z) has been triggered
00135     */
00136   virtual void undoIsDone()=0;
00137 
00138 protected:
00139   /**
00140     @brief Provides input filtering for the interactor
00141     @see QObject::eventFilter()
00142     */
00143   inline virtual bool eventFilter(QObject* obj, QEvent* ev) {
00144     return QObject::eventFilter(obj,ev);
00145   }
00146 };
00147 
00148 /**
00149  * @ingroup Plugins
00150  * @brief The InteractorLister class lists compatible interactors for a given tlp::View
00151  */
00152 class TLP_QT_SCOPE InteractorLister {
00153   static QMap<std::string,QList<std::string> > _compatibilityMap;
00154 public:
00155   static void initInteractorsDependencies();
00156   static QList<std::string> compatibleInteractors(const std::string& viewName);
00157 };
00158 
00159 /**
00160  * @ingroup Plugins
00161  * @def INTERACTORPLUGINVIEWEXTENSION(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION)
00162  *
00163  * @brief Copy an existing Tulip interactor and sets it compatible with a given View.
00164  *
00165  * This macro is used when you're making your own View and want to use an existing interactor with it. Interactors are declared to be compatible with a list of View. This macro extends the compatibility of an existing interactor by subclassing it.
00166  *
00167  * @note: This macro used the same interactor priority as the base interactor. To define your own priority, see INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY
00168  *
00169  * @param CLASS_NAME The name of the interactor class to generate.
00170  * @param STRING_CLASS_NAME The name of the interactor plugin to generate (see tlp::Plugin::name())
00171  * @param BASE_INTERACTOR_STRING_NAME The name of the interactor to extend
00172  * @param VIEW_STRING_NAME The name of the View to set the interactor compatible with
00173  * @param AUTHOR see tlp::Plugin::author()
00174  * @param DATE see tlp::Plugin::date()
00175  * @param DESCRIPTION see tlp::Plugin::info()
00176  * @param VERSION see tlp::Plugin::version()
00177  */
00178 #define INTERACTORPLUGINVIEWEXTENSION(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION)\
00179 class CLASS_NAME : public tlp::Interactor {\
00180   mutable tlp::Interactor* _component;\
00181 public:\
00182   std::string name() const { return std::string(STRING_CLASS_NAME); } \
00183   std::string author() const { return std::string(AUTHOR); }\
00184   std::string date() const { return std::string(DATE); }  \
00185   std::string info() const { return std::string(DESCRIPTION); }  \
00186   std::string release() const { return std::string(VERSION); }\
00187   std::string tulipRelease() const { return std::string(TULIP_VERSION); }\
00188   std::string group() const { return getComponent()->group(); }\
00189   CLASS_NAME(const PluginContext *):_component(NULL) {}\
00190   bool isCompatible(const std::string& viewName) const { return viewName == VIEW_STRING_NAME; }\
00191   QWidget* configurationWidget() const { return getComponent()->configurationWidget(); }\
00192   unsigned int priority() const { return getComponent()->priority(); }\
00193   QAction* action() const { return getComponent()->action(); }\
00194   tlp::View* view() const { return getComponent()->view(); }\
00195   QCursor cursor() const { return getComponent()->cursor(); }\
00196   void construct() { getComponent()->construct(); }\
00197   void setView(tlp::View* v) { getComponent()->setView(v); }\
00198   void install(QObject* target) { getComponent()->install(target); }\
00199   void uninstall() { getComponent()->uninstall(); }\
00200   void undoIsDone() { getComponent()->undoIsDone(); }\
00201   tlp::Interactor* getComponent() const {\
00202     if(!_component) {\
00203       _component = tlp::PluginLister::instance()->getPluginObject<Interactor>(BASE_INTERACTOR_STRING_NAME,NULL); assert(_component != NULL);\
00204     }\
00205     return _component;\
00206   }\
00207 };\
00208 PLUGIN(CLASS_NAME)
00209 
00210 /**
00211  * @ingroup Plugins
00212  * @def INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION,PRIORITY)
00213  * @brief Similar to INTERACTORPLUGINVIEWEXTENSION but allows to define the generated interactor's priority.
00214  * @see tlp::Interactor::priority()
00215  * @see INTERACTORPLUGINVIEWEXTENSION
00216  */
00217 #define INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION,PRIORITY)     \
00218 class CLASS_NAME : public tlp::Interactor {\
00219   mutable tlp::Interactor* _component;\
00220 public:\
00221   std::string name() const { return std::string(STRING_CLASS_NAME); } \
00222   std::string author() const { return std::string(AUTHOR); }\
00223   std::string date() const { return std::string(DATE); }  \
00224   std::string info() const { return std::string(DESCRIPTION); }  \
00225   std::string release() const { return std::string(VERSION); }\
00226   std::string tulipRelease() const { return std::string(TULIP_VERSION); }\
00227   std::string group() const { return getComponent()->group(); }\
00228   CLASS_NAME(const PluginContext *):_component(NULL) {}\
00229   bool isCompatible(const std::string& viewName) const { return viewName == VIEW_STRING_NAME; }\
00230   QWidget* configurationWidget() const { return getComponent()->configurationWidget(); }\
00231   unsigned int priority() const { return PRIORITY; }\
00232   QAction* action() const { return getComponent()->action(); }\
00233   tlp::View* view() const { return getComponent()->view(); }\
00234   QCursor cursor() const { return getComponent()->cursor(); }\
00235   void construct() { getComponent()->construct(); }\
00236   void setView(tlp::View* v) { getComponent()->setView(v); }\
00237   void install(QObject* target) { getComponent()->install(target); }\
00238   void uninstall() { getComponent()->uninstall(); }\
00239   void undoIsDone() { getComponent()->undoIsDone(); }\
00240   tlp::Interactor* getComponent() const {\
00241     if(!_component) {\
00242       _component = tlp::PluginLister::instance()->getPluginObject<Interactor>(BASE_INTERACTOR_STRING_NAME,NULL); assert(_component != NULL);\
00243     }\
00244     return _component;\
00245   }\
00246 };\
00247 PLUGIN(CLASS_NAME)
00248 
00249 }
00250 
00251 #endif
 All Classes Files Functions Variables Enumerations Enumerator Properties