Tulip  5.3.0
Large graphs analysis and drawing
Interactor.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 
20 #ifndef _INTERACTOR_H
21 #define _INTERACTOR_H
22 
23 #include <tulip/Plugin.h>
24 
25 #include <QObject>
26 #include <QCursor>
27 #include <QMap>
28 
29 #include <string>
30 
31 class QAction;
32 class QLabel;
33 
34 namespace tlp {
35 
36 static const std::string INTERACTOR_CATEGORY = "Interactor";
37 
38 class View;
39 
40 /**
41  @ingroup Plugins
42  @brief Interactor provides a way to handle user inputs over a view.
43  Basically, The interactor class is an overlay to the Qt's event filtering mechanism. It adds
44  several features like the ability to define priorities, custom cursors, etc
45 
46  When an interactor is constructed, the following methods are called in this order:
47  @li The constructor. This method should almost be a no-op. Interactors may be instantiated by the
48  plugin manager system and doing unneeded operations in the constructor may lead to poor
49  performances when the application loads up.
50  @li isCompatible. When creating a View, the application will check for all interactors to see if
51  they could be installed on it. This is done using the isCompatible method.
52  @li construct. Initialize the interactor. Since the constructor should be a no-op, initialization
53  code should be put here.
54  @li setView. Defines the view this interactor is bound to. The Interactor may keep a reference to
55  the view object to perform specific operations on user inputs.
56 
57  Methods listed above are only called once. Once the interactor is initialized, it may be
58  installed/removed several times on different QObjects. It will then repond to user inputs via the
59  eventFilter method
60  @see QObject::eventFilter()
61  */
62 class TLP_QT_SCOPE Interactor : public QObject, public Plugin {
63  Q_OBJECT
64  Q_PROPERTY(unsigned int priority READ priority)
65  Q_PROPERTY(QAction *action READ action)
66  Q_PROPERTY(tlp::View *view READ view WRITE setView)
67  Q_PROPERTY(QCursor cursor READ cursor)
68 
69 public:
70  std::string category() const override {
71  return INTERACTOR_CATEGORY;
72  }
73  std::string icon() const override {
74  return ":/tulip/gui/icons/32/plugin_interactor.png";
75  }
76  /**
77  @brief Checks the compatibility between the interactor and the given view (identified by its
78  name).
79  If this method returns true, it's very likely that the interactor will be installed on the
80  associated view.
81  */
82  virtual bool isCompatible(const std::string &viewName) const = 0;
83 
84  /**
85  @deprecated Use QWidget *configurationDocWidget() and/or QWidget *configurationOptionsWidget()
86  instead
87  @return the configuration widget used to set up the interactor.
88  @warning This method MUST ALWAYS return the same pointer. Doing otherwise may lead to memory
89  leaks.
90  @note The configuration widget has to be instantiated from the construct method.
91  @note It is up to the interactor developper to delete the configuration widget
92  */
93  virtual QWidget *configurationWidget() const {
94  return nullptr;
95  }
96  virtual QLabel *configurationDocWidget() const {
97  return nullptr;
98  }
99  virtual QWidget *configurationOptionsWidget() const {
100  return nullptr;
101  }
102 
103  /**
104  @return the interactor's priority.
105  Priority defines how interactors gets ordered when displayed in the View's toolbar.
106  Interactors with the top-most priority value will be displayed at the beginning of the list
107  while lowest priority will be position at the end.
108  */
109  virtual unsigned int priority() const = 0;
110 
111  /**
112  @return a QAction associated to this interactor.
113  This is used by the overleying system to associate an icon/text to the interactor.
114  @warning The parent (QObject::parent()) object of this QAction MUST BE the Interactor.
115  */
116  virtual QAction *action() const = 0;
117 
118  /**
119  @return the View object associated to this Interactor.
120  @warning The returned object MUST be the same as the one passed down to the setView method.
121  */
122  virtual tlp::View *view() const = 0;
123 
124  /**
125  @return The cursor associated to this interactor.
126  When the interactor gets active on a view, the View's cursor is changed to what this method
127  returns.
128  */
129  virtual QCursor cursor() const = 0;
130 
131  /**
132  @brief Builds up the interactor's internal state.
133  This method should be used instead of the constructor to initialize the interactor.
134  */
135  virtual void construct() = 0;
136 
137 public slots:
138  /**
139  @brief Defines the view object associated to this interactor.
140  @warning The view() method MUST ALWAYS return the same pointer as the one passed down to this
141  method.
142  */
143  virtual void setView(tlp::View *) = 0;
144 
145  /**
146  @brief Install the interactor on the given target
147  A call to this method means that the interactor should start listening to the target's events
148  and handle them.
149  Returning true prevents further handling of the event. Doing otherwise means that the interactor
150  will let following filters to hand over this kind of event.
151  */
152  virtual void install(QObject *target) = 0;
153 
154  /**
155  @brief Removes the interactor from the previously set target.
156  Interactors can be installed on only one target at once.
157  */
158  virtual void uninstall() = 0;
159 
160  /**
161  @brief Informs the interactor when the undo command (Ctrl+Z) has been triggered
162  */
163  virtual void undoIsDone() = 0;
164 
165 protected:
166  /**
167  @brief Provides input filtering for the interactor
168  @see QObject::eventFilter()
169  */
170  inline bool eventFilter(QObject *obj, QEvent *ev) override {
171  return QObject::eventFilter(obj, ev);
172  }
173 };
174 
175 /**
176  * @ingroup Plugins
177  * @brief The InteractorLister class lists compatible interactors for a given tlp::View
178  */
179 class TLP_QT_SCOPE InteractorLister {
180  static QMap<std::string, QList<std::string>> _compatibilityMap;
181 
182 public:
183  static void initInteractorsDependencies();
184  static QList<std::string> compatibleInteractors(const std::string &viewName);
185 };
186 
187 /**
188  * @ingroup Plugins
189  * @def
190  * INTERACTORPLUGINVIEWEXTENSION(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION)
191  *
192  * @brief Copy an existing Tulip interactor and sets it compatible with a given View.
193  *
194  * This macro is used when you're making your own View and want to use an existing interactor with
195  * it. Interactors are declared to be compatible with a list of View. This macro extends the
196  * compatibility of an existing interactor by subclassing it.
197  *
198  * @note: This macro used the same interactor priority as the base interactor. To define your own
199  * priority, see INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY
200  *
201  * @param CLASS_NAME The name of the interactor class to generate.
202  * @param STRING_CLASS_NAME The name of the interactor plugin to generate (see tlp::Plugin::name())
203  * @param BASE_INTERACTOR_STRING_NAME The name of the interactor to extend
204  * @param VIEW_STRING_NAME The name of the View to set the interactor compatible with
205  * @param AUTHOR see tlp::Plugin::author()
206  * @param DATE see tlp::Plugin::date()
207  * @param DESCRIPTION see tlp::Plugin::info()
208  * @param VERSION see tlp::Plugin::version()
209  */
210 #define INTERACTORPLUGINVIEWEXTENSION(CLASS_NAME, STRING_CLASS_NAME, BASE_INTERACTOR_STRING_NAME, \
211  VIEW_STRING_NAME, AUTHOR, DATE, DESCRIPTION, VERSION) \
212  class CLASS_NAME : public tlp::Interactor { \
213  mutable tlp::Interactor *_component; \
214  \
215  public: \
216  std::string name() const { \
217  return std::string(STRING_CLASS_NAME); \
218  } \
219  std::string author() const { \
220  return std::string(AUTHOR); \
221  } \
222  std::string date() const { \
223  return std::string(DATE); \
224  } \
225  std::string info() const { \
226  return std::string(DESCRIPTION); \
227  } \
228  std::string release() const { \
229  return std::string(VERSION); \
230  } \
231  std::string tulipRelease() const { \
232  return std::string(TULIP_VERSION); \
233  } \
234  std::string group() const { \
235  return getComponent()->group(); \
236  } \
237  CLASS_NAME(const PluginContext *) : _component(nullptr) {} \
238  bool isCompatible(const std::string &viewName) const { \
239  return viewName == VIEW_STRING_NAME; \
240  } \
241  QWidget *configurationWidget() const { \
242  return getComponent()->configurationWidget(); \
243  } \
244  QLabel *configurationDocWidget() const { \
245  return getComponent()->configurationDocWidget(); \
246  } \
247  QWidget *configurationActionsWidget() const { \
248  return getComponent()->configurationOptionsWidget(); \
249  } \
250  unsigned int priority() const { \
251  return getComponent()->priority(); \
252  } \
253  QAction *action() const { \
254  return getComponent()->action(); \
255  } \
256  tlp::View *view() const { \
257  return getComponent()->view(); \
258  } \
259  QCursor cursor() const { \
260  return getComponent()->cursor(); \
261  } \
262  void construct() { \
263  getComponent()->construct(); \
264  } \
265  void setView(tlp::View *v) { \
266  getComponent()->setView(v); \
267  } \
268  void install(QObject *target) { \
269  getComponent()->install(target); \
270  } \
271  void uninstall() { \
272  getComponent()->uninstall(); \
273  } \
274  void undoIsDone() { \
275  getComponent()->undoIsDone(); \
276  } \
277  tlp::Interactor *getComponent() const { \
278  if (!_component) { \
279  _component = tlp::PluginLister::instance()->getPluginObject<Interactor>( \
280  BASE_INTERACTOR_STRING_NAME, nullptr); \
281  assert(_component != nullptr); \
282  } \
283  return _component; \
284  } \
285  }; \
286  PLUGIN(CLASS_NAME)
287 
288 /**
289  * @ingroup Plugins
290  * @def
291  * INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY(CLASS_NAME,STRING_CLASS_NAME,BASE_INTERACTOR_STRING_NAME,VIEW_STRING_NAME,AUTHOR,DATE,DESCRIPTION,VERSION,PRIORITY)
292  * @brief Similar to INTERACTORPLUGINVIEWEXTENSION but allows to define the generated interactor's
293  * priority.
294  * @see tlp::Interactor::priority()
295  * @see INTERACTORPLUGINVIEWEXTENSION
296  */
297 #define INTERACTORPLUGINVIEWEXTENSIONWITHPRIORITY(CLASS_NAME, STRING_CLASS_NAME, \
298  BASE_INTERACTOR_STRING_NAME, VIEW_STRING_NAME, \
299  AUTHOR, DATE, DESCRIPTION, VERSION, PRIORITY) \
300  class CLASS_NAME : public tlp::Interactor { \
301  mutable tlp::Interactor *_component; \
302  \
303  public: \
304  std::string name() const { \
305  return std::string(STRING_CLASS_NAME); \
306  } \
307  std::string author() const { \
308  return std::string(AUTHOR); \
309  } \
310  std::string date() const { \
311  return std::string(DATE); \
312  } \
313  std::string info() const { \
314  return std::string(DESCRIPTION); \
315  } \
316  std::string release() const { \
317  return std::string(VERSION); \
318  } \
319  std::string tulipRelease() const { \
320  return std::string(TULIP_VERSION); \
321  } \
322  std::string group() const { \
323  return getComponent()->group(); \
324  } \
325  CLASS_NAME(const PluginContext *) : _component(nullptr) {} \
326  bool isCompatible(const std::string &viewName) const { \
327  return viewName == VIEW_STRING_NAME; \
328  } \
329  QWidget *configurationWidget() const { \
330  return getComponent()->configurationWidget(); \
331  } \
332  QLabel *configurationDocWidget() const { \
333  return getComponent()->configurationDocWidget(); \
334  } \
335  QWidget *configurationActionsWidget() const { \
336  return getComponent()->configurationOptionsWidget(); \
337  } \
338  unsigned int priority() const { \
339  return PRIORITY; \
340  } \
341  QAction *action() const { \
342  return getComponent()->action(); \
343  } \
344  tlp::View *view() const { \
345  return getComponent()->view(); \
346  } \
347  QCursor cursor() const { \
348  return getComponent()->cursor(); \
349  } \
350  void construct() { \
351  getComponent()->construct(); \
352  } \
353  void setView(tlp::View *v) { \
354  getComponent()->setView(v); \
355  } \
356  void install(QObject *target) { \
357  getComponent()->install(target); \
358  } \
359  void uninstall() { \
360  getComponent()->uninstall(); \
361  } \
362  void undoIsDone() { \
363  getComponent()->undoIsDone(); \
364  } \
365  tlp::Interactor *getComponent() const { \
366  if (!_component) { \
367  _component = tlp::PluginLister::instance()->getPluginObject<Interactor>( \
368  BASE_INTERACTOR_STRING_NAME, nullptr); \
369  assert(_component != nullptr); \
370  } \
371  return _component; \
372  } \
373  }; \
374  PLUGIN(CLASS_NAME)
375 } // namespace tlp
376 
377 #endif
virtual QWidget * configurationWidget() const
Definition: Interactor.h:93
bool eventFilter(QObject *obj, QEvent *ev) override
Provides input filtering for the interactor.
Definition: Interactor.h:170
Interactor provides a way to handle user inputs over a view. Basically, The interactor class is an ov...
Definition: Interactor.h:62
Top-level interface for plug-ins.
Definition: Plugin.h:85
std::string category() const override
A string identifier for a plugin used for categorization purposes.
Definition: Interactor.h:70
View plugins provide a way to dynamically add to a Tulip plateform various ways to visualize a graph...
Definition: View.h:92
The InteractorLister class lists compatible interactors for a given tlp::View.
Definition: Interactor.h:179
std::string icon() const override
The icon (preferably a thumbnail) of the plugin.
Definition: Interactor.h:73