BaseInterface.hh 19.2 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
   
Jan Möbius committed
42

43
44
#ifndef BASEINTERFACE_HH
#define BASEINTERFACE_HH
Jan Möbius's avatar
   
Jan Möbius committed
45

46
47
48
#include <QtGui>
#include <QMenuBar>
#include <OpenFlipper/common/Types.hh>
49

50

51
52
53
54
/** \file BaseInterface.hh
*
* OpenFlippers main plugin Interface \ref baseInterfacePage.
*/
Jan Möbius's avatar
Jan Möbius committed
55

56
57

/** \brief Interface class from which all plugins have to be created.
58
  *
Jan Möbius's avatar
   
Jan Möbius committed
59
  * You have to implement at least name and description for your plugin.
60
  * All other functions and signals are optional. If you want to implement or use
61
62
  * them just add them to your plugin header. A detailed description of this interface
  * can be found in the \ref baseInterfacePage .
63
  *
64
65
66
67
  * See \ref pluginProgramming for a tutorial on plugin programming.
  *
  * Also see \ref dataFlow diagrams for a detailed overview of
  * OpenFlipper's data flow and interface function calls.
Jan Möbius's avatar
   
Jan Möbius committed
68
69
 */
class BaseInterface {
70

71
72
73
74
   //===========================================================================
    /** @name Initialization
    * @{ */
   //===========================================================================
75

76
77
  private slots:
      /**  \brief Initialize Plugin
78
       *
Jan Möbius's avatar
   
Jan Möbius committed
79
       *   This slot is called if the plugin is loaded and has to be initialized. All initialization stuff
Jan Möbius's avatar
Jan Möbius committed
80
       *   in this slot has to stay inside the plugin, no external signals are allowed here (and will be ignored).
Jan Möbius's avatar
Jan Möbius committed
81
       *   Don't create any objects via PluginFunctions here. Use the pluginsInitialized() slot for external
Jan Möbius's avatar
Jan Möbius committed
82
       *   initialization. After execution of this slot your plugin should be fully functional.
83
       *   Only gui elements may be uninitialized and should be created in pluginsInitialized().
Jan Möbius's avatar
   
Jan Möbius committed
84
85
      */
      virtual void initializePlugin() {};
86

Jan Möbius's avatar
   
Jan Möbius committed
87
      /**  \brief Initialize Plugin step 2
88
       *
Jan Möbius's avatar
   
Jan Möbius committed
89
90
91
92
       *   This slot is called if all plugins are loaded and the core is ready. Here you can create objects,
       *   set Textures and everything which will involve signals to the core.
      */
      virtual void pluginsInitialized() {};
93
94


95
96
97
98
  /** @} */

  //===========================================================================
  /** @name Object/View updates
Jan Möbius's avatar
Jan Möbius committed
99
100
101
102
  * @{
  * \anchor BaseInterfaceUpdateSlots
  * */

103
104
105
106
107
  //===========================================================================

  signals :
    /** \brief Update current view in Main Application
      *
Jan Möbius's avatar
Jan Möbius committed
108
109
110
      *  Emit this Signal if the viewer widget in the main application should update the current view.
      *  If you do an updatedObject the core will trigger an update itself and you don't have to care
      *  about it.
111
112
113
    */
    virtual void updateView() {};

Jan Möbius's avatar
Jan Möbius committed
114
    /** \brief An object has been changed or added by this plugin
115
      *
116
      *  Emit this Signal, if you updated any part of an object.\n
Jan Möbius's avatar
Jan Möbius committed
117
      *  If you changed the element itself (geometry, topology,..) you also have to emit this signal.\n
118
      *  Don't emit this Signal in BaseInterface::slotObjectUpdated() as this causes an endless Loop!!
Jan Möbius's avatar
Jan Möbius committed
119
      *  Give the id of the new object as parameter or -1 if you updated all objects or deleted an object.
120
      *  For performance reasons try to always give the id and not -1!
121
      *
Jan Möbius's avatar
Jan Möbius committed
122
      *  @param _ objectId Id of the object or -1 if referring to all or deleted objects.
123
      */
124
    virtual void updatedObject(int _objectId) {};
125

Dirk Wilden's avatar
Dirk Wilden committed
126
127
128
129
    /** \brief An object has been changed or added by this plugin
      *
      *  Emit this Signal, if you updated any part of an object.\n
      *  If you changed the element itself (geometry, topology,..) you also have to emit this signal.\n
Jan Möbius's avatar
Jan Möbius committed
130
      *  Don't emit this Signal in BaseInterface::slotObjectUpdated() as this causes an endless Loop!!
Dirk Wilden's avatar
Dirk Wilden committed
131
      *  Give the id of the new object as parameter or -1 if you updated all objects or deleted an object.
132
      *  For performance reasons try to always give the id and not -1!
Dirk Wilden's avatar
Dirk Wilden committed
133
      *
Jan Möbius's avatar
Jan Möbius committed
134
      * @param _identifier id of the object or -1 if referring to all or deleted objects.
Dirk Wilden's avatar
Dirk Wilden committed
135
136
      * @param _type the type states which part of the object (topology, selection, ..) has to be updated
      */
137
    virtual void updatedObject(int _identifier, const UpdateType _type) {};
Dirk Wilden's avatar
Dirk Wilden committed
138
    
139
    /** \brief A scenegraph node has been shown or hidden
140
      *
141
      *  Emit this Signal, if you changed the visibility of a scenegraph node directly (not via object->show/hide).
142
      *  This is required to reset the near and far plane for the viewers to provide
143
      *  an optimal view. Use the id of the object the node is attached to or -1 if it is not connected to an object.
144
145
      *
      */
146
    virtual void nodeVisibilityChanged( int _identifier ) {};
147

148
149
  private slots:

Jan Möbius's avatar
Jan Möbius committed
150
    /**  \brief An object has been updated by another plugin
151
      *
Jan Möbius's avatar
Jan Möbius committed
152
      *   This slot is called by the main application if the number or status of existing objects changed or if
153
      *   an existing object has been changed. This could mean, that objects are added or deleted
Jan Möbius's avatar
Jan Möbius committed
154
      *   or that an existing object with the given id has been modified.
155
      *   If you store local information about one of these Objects, you should check if its still valid!\n
Jan Möbius's avatar
Jan Möbius committed
156
157
      *  Don't emit BaseInterface::updatedObject(int) in this slot as this causes an endless Loop!!
      *   You don't need to call updateView as the core triggers a redraw itself.
158
      *  @param _identifier Identifier of the updated/new object or -1 if one is deleted.
159
    */
160
    virtual void slotObjectUpdated( int _identifier ) {};
161

Dirk Wilden's avatar
Dirk Wilden committed
162
163
    /**  \brief An object has been updated by another plugin
      *
Jan Möbius's avatar
Jan Möbius committed
164
      *   This slot is called by the main application if the number or status of existing objects changed or if
Dirk Wilden's avatar
Dirk Wilden committed
165
166
167
      *   an existing object has been changed. This could mean, that objects are added or deleted
      *   or that an existing object with the given id has been modified.
      *   If you store local information about one of these Objects, you should check if its still valid!\n
Jan Möbius's avatar
Jan Möbius committed
168
169
      *  Don't emit BaseInterface::updatedObject(int) in this slot as this causes an endless Loop!!
      *   You don't need to call updateView as the core triggers a redraw itself.
Dirk Wilden's avatar
Dirk Wilden committed
170
171
172
      *  @param _identifier Identifier of the updated/new object or -1 if one is deleted.
      *  @param _type the type states which part of the object (topology, selection, ..) had been updated
    */
173
    virtual void slotObjectUpdated( int _identifier, const UpdateType _type ) {};
Dirk Wilden's avatar
Dirk Wilden committed
174

175
    /**  \brief Called if the whole scene is cleared
Jan Möbius's avatar
Jan Möbius committed
176
177
178
      *
      * This slot is called if the main application cleared the whole scene. No objects will remain in memory
      * and all destructors of the objects are called before this signal is emitted.
179
180
181
182
183
184
      *
      */
    virtual void slotAllCleared( ) {};

      /**  \brief The active object has changed
      *
Jan Möbius's avatar
Jan Möbius committed
185
      *   This slot is called by the main application if the current selection of an object has changed.\n
186
      *   This means that the selection of source / target objects has changed.
Jan Möbius's avatar
Jan Möbius committed
187
      *   Additionally you get the id of the object that has been changed or -1 if all objects
188
      *   have been modified.
189
    */
190
    virtual void slotObjectSelectionChanged( int _identifier ) {};
191
192
193

    /** \brief An object has been shown or hidden
      *
Jan Möbius's avatar
Jan Möbius committed
194
      *  This slot is called if an object is shown or hidden.
195
196
197
198
      *  The id of the object is given as a parameter.
      *  If multiple or all objects have changed, the id will be -1.
      *
      */
199
    virtual void slotVisibilityChanged( int _identifier ) {};
200

Jan Möbius's avatar
Jan Möbius committed
201
202
203
204
205
206
207
    /**  \brief Object properties have been changed
      *
      *  This slot is called if the object properties (e.g. name ) have changed
      *  The id of the object is given as a parameter.
      *  If multiple or all objects have changed, the id will be -1.
      *
    */
208
    virtual void slotObjectPropertiesChanged( int _identifier ) {};
209
210
211
212
213
    
    /** \brief View has changed
      *
      * This slot is called when the view in one of the viewers changed
      * ( Viewing direction/viewer position )
Jan Möbius's avatar
Jan Möbius committed
214
      * !! Be careful to not change the view in this slot !!
215
216
217
      * !! This will of course lead to an endless loop !!
    */
    virtual void slotViewChanged() {};
Jan Möbius's avatar
Jan Möbius committed
218

219
220
221
222
223
    /** \brief A viewer changed its draw mode
     *
     * @param _viewerId Id of the viewer that changed its draw mode
     */
    virtual void slotDrawModeChanged(int _viewerId) {};
224
225
226
227
228
229
230
231
  /** @} */

  //===========================================================================
  /** @name Plugin identification
  * @{ */
  //===========================================================================
  public :

Jan Möbius's avatar
Jan Möbius committed
232
    /** \brief Return a name for the plugin
233
234
235
236
237
238
239
240
241
242
      *
      * This Function has to return the name of the plugin.
    */
    virtual QString name() = 0;

    /** \brief Return a description of what the plugin is doing
      *
      * This function has to return a basic description of the plugin
      */
    virtual QString description() = 0;
243
244
245
246

  public slots:
      /** \brief Return a version string for your plugin
       *
Jan Möbius's avatar
Jan Möbius committed
247
       * This function will be used to determine the current version of your plugin.
248
249
250
251
       * Should have the form x.x.x ( you do not need to give that many subversions )
       */
      virtual QString version() { return QString("-1"); };

252
  signals:
253

254
      /**  \brief Set a description for a public slot
255
       *
Jan Möbius's avatar
Jan Möbius committed
256
       *   public slots of each plugin are automatically available for scripting. \n
257
258
259
260
261
262
       *   Use this Signal to add a description for your slot so that everyone knows what it is used for. \n
       *
       *   @param _slotName the name of the slot
       *   @param _slotDescription a description for the slot
       *   @param _parameters list of parameters
       *   @param _descriptions list of descriptions for the parameters (_descriptions[i] corresponds to _parameters[i])
Jan Möbius's avatar
   
Jan Möbius committed
263
      */
264
265
      virtual void setSlotDescription(QString     _slotName    ,   QString     _slotDescription,
                                      QStringList _parameters  , QStringList _descriptions) {};
266

267
268
269
270
271
272
273
274
275
276
  /** @} */

  private slots :

    /** This function is called when the application exits or when your plugin is about to be unloaded.
      * Here you can clean up your plugin, delete local variables...
      */
    virtual void exit(){};

    /** Using this function you can inform the core that your plugin can run without creating a widget.
Jan Möbius's avatar
Jan Möbius committed
277
      * If your plugin does not implement this function, it will not be loaded in scripting mode without gui.
Jan Möbius's avatar
Jan Möbius committed
278
      * You don't have to do anything in this function.
279
280
281
282
283
284
285
      */
    virtual void noguiSupported( ) {} ;

  public :

    /// Destructor
    virtual ~BaseInterface() {};
286

Jan Möbius's avatar
   
Jan Möbius committed
287
288
};

289
290
291
292
293

/** \page baseInterfacePage Base Interface
The BaseInterface has to be used by every plugin in OpenFlipper. As the minimum a plugin
has to implement the BaseInterface::name() and BaseInterface::description() functions from this interface.

Jan Möbius's avatar
Jan Möbius committed
294
295
296
297
298
299
300
301
To use the BaseInterface:
<ul>
<li> include BaseInterface.hh in your plugins header file
<li> derive your plugin from the class BaseInterface
<li> add Q_INTERFACES(BaseInterface) to your plugin class 
<li> And add the signals or slots you want to use to your plugin class (You don't need to implement all of them except BaseInterface::description() and BaseInterface::name() )
</ul>

Jan Möbius's avatar
Jan Möbius committed
302
\section baseInterfacePluginInitialization Plugin Initialization
Jan Möbius's avatar
Jan Möbius committed
303
BaseInterface provides two functions to initialize a plugin. The first function is BaseInterface::initializePlugin().
Jan Möbius's avatar
Jan Möbius committed
304
This function is called immediately after the plugin has been connected with OpenFlipper. When a plugin is
Jan Möbius's avatar
Jan Möbius committed
305
loaded, all signals and slots from the used interfaces are connected to the core. After this, the
306
307
308
BaseInterface::initializePlugin() slot is called. In this slot you can initialize your plugin.
The order how plugins are loaded is not fixed. So you should not rely or communicate with other plugins
in this slot. \n
Jan Möbius's avatar
Jan Möbius committed
309
After all plugins are loaded, the slot  BaseInterface::pluginsInitialized() is called for each plugin. All
Jan Möbius's avatar
Jan Möbius committed
310
other plugins are now available and you can setup your user interface components in this slot.
311
312
The following graphic shows the initialization of a plugin.
\image html startupProcess.jpg
313

314
\section baseInterfaceObjectUpdateNotification Object Update Notification
Jan Möbius's avatar
Jan Möbius committed
315
316
317
318
319
320
321
The objects in OpenFlippers scene are stored and managed in OpenFlippers core. If a plugin changes one of the
objects, it has to notify the core about that change. In turn OpenFlipper will then notify all other plugins about
this change. This functionality is provided by the signals and slots for \ref BaseInterfaceUpdateSlots "update handling" .

\image html updateObject.jpg

If you change data you have to emit one of BaseInterface::updatedObject(int) or BaseInterface::updatedObject(int,const UpdateType).
322
\n
Jan Möbius's avatar
Jan Möbius committed
323
324
BaseInterface::updatedObject(int) forces an update of the whole object while BaseInterface::updatedObject(int,const UpdateType)
can be restricted to a part of the object ( Geometry,Selection, ... ; see UpdateType ) and is therefore faster and should be preferred.
325
326

Both signals get the id of the object that has been updated or -1 if all should be updated( you should not use -1 if you know what object changed!).
Jan Möbius's avatar
Jan Möbius committed
327
328
329
330

If the signal is emitted, the core calls BaseInterface::slotObjectUpdated( int , const UpdateType ) of every plugin. You can
implement this slot if you need to react on object changes.

331
332
333
334
335
336
337
338
339
340
After all plugins have been informed, the scene will be redrawn.

For more details about the UpdateType read the documentation about UpdateType and \ref DefaultUpdateTypes "predefined update types".
A description for adding custom update types at runtime is available \ref UpdateTypeFunctions "here".

It is also possible to insert custom nodes into the scenegraph. If you changed these nodes, you also have to inform the core.
This is achieved by the BaseInterface::nodeVisibilityChanged() function. As nodes they are usually attached to objects in the scene,
you should pass the id of the object to the function or -1 if its a global node (which should not be used!).

If the complete scene gets cleared, the slot BaseInterface::slotAllCleared() will be executed after all objects have been removed from the scene.
341
A more fine grained information about objects added or removed from the scene is available via the \ref loadSaveInterfacePage .
342
343
344
345

There are three additional slots that are called by the core, if the object selection(source/target BaseInterface::slotObjectSelectionChanged() ),
the object visibility(Show/Hide BaseInterface::slotVisibilityChanged()) or other properties changed (e.g. name BaseInterface::slotObjectPropertiesChanged() )

Jan Möbius's avatar
Jan Möbius committed
346
347
348
349
350
351
Remarks:
<ul>
<li>If the object id passed to the functions is -1 all objects should be treated as updated.
<li>Never emit the signal BaseInterface::updatedObject() inside the updated object slots as this causes endless loops!
</ul>

352
\section baseInterfaceSceneUpdateNotification Scene Update Notifications
353
354
355
356

OpenFlipper manages the scene updates in its core. If objects get updated the scene will be automatically redrawn. Nevertheless,
you can force an update of the scene by emitting the signal BaseInterface::updateView().

357
358
\image html updateView.jpg

Jan Möbius's avatar
Jan Möbius committed
359
If the view (viewer position /viewing direction) has been changed, the slot BaseInterface::slotViewChanged() will be called. Be carefull, not to
360
361
change the view in this function or you get an endless loop!

362
\section baseInterfaceManagementFunctions Management Functions
363
There are some basic functions for managing plugins. The BaseInterface::description() function can be used
Jan Möbius's avatar
Jan Möbius committed
364
to provide a description for the plugin which will be printed along with the plugin name. The BaseInterface::name()
365
366
367
368
369
370
371
function has to return the name of the plugin. This name will also be used inside the scripting system.
Additionally it is possible to provide a plugin version number with BaseInterface::version().

OpenFlippers scripting system can use all public slots defined in your plugin. If it should also provide a
small text description for your functions, you could set them with BaseInterface::setSlotDescription(). Even if
you do not implement scripting functions in your plugin, the core will then be able to provide this information
to the user.
Jan Möbius's avatar
Jan Möbius committed
372

373
374
375
376
Along with the scripting, OpenFlipper provides a batch mode, running without any user interface. If your plugin
will work without an user interface (e.g. only scripting functions), you can define a slot BaseInterface::noguiSupported().
This empty slot is used to tell the core, that the plugin can work in batch mode. Otherwise it will not be loaded
when running a batch file.
Jan Möbius's avatar
Jan Möbius committed
377

378
379
*/

380
Q_DECLARE_INTERFACE(BaseInterface,"OpenFlipper.BaseInterface/1.0")
381

Jan Möbius's avatar
   
Jan Möbius committed
382
#endif // BASEINTERFACE_HH