Tulip  4.6.0
Better Visualization Through Research
library/tulip-gui/include/tulip/View.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 #ifndef VIEW_H
00020 #define VIEW_H
00021 
00022 #include <QObject>
00023 #include <QSet>
00024 #include <QList>
00025 #include <QSize>
00026 
00027 #include <tulip/tulipconf.h>
00028 #include <tulip/Observable.h>
00029 #include <tulip/Plugin.h>
00030 
00031 class QGraphicsView;
00032 class QGraphicsItem;
00033 class QWidget;
00034 class QPixmap;
00035 class QMenu;
00036 class QPointF;
00037 class QPoint;
00038 
00039 namespace tlp {
00040 static const std::string VIEW_CATEGORY = "Panel";
00041 
00042 class Interactor;
00043 
00044 /**
00045   @ingroup Plugins
00046 
00047   @brief View plugins provide a way to dynamically add to a Tulip plateform various ways to visualize a graph.
00048 
00049   A view takes the following elements as inputs:
00050   @li A graph which contains the data to be displayed.
00051   @li A state (@c tlp::DataSet) which contains initialization parameters.
00052 
00053   As an output, a View must provide a @c QGraphicsView instance where all drawing is done.
00054   User interaction on a View is handled by the tlp::Interactor class. Several interactors can be installed on the same view but there can be only one active interactor at the same time.
00055   In the end, the view can provide several configuration widgets used to set up additional parameters.
00056 
00057   When a View gets created, the following methods will always be called in the following order:
00058   @li The constructor. Basically, you don't want to do anything in this method as View instance may be created at Tulip startup when the plugin system gets initialized. Subsequent methods will be called in order for the view to build UI elements
00059   @li View::setupUi(). Notifies the view it can now build GUI components since every part of its initial state should be valid by now. Once this method is called, any call to View::graphicsView() is expected to return a valid pointer object.
00060   @li View::setGraph. Sets the graph that is meant to be visualized in the View's panel.
00061   @li View::setState(). Sets initial data. This method may be used to restore a previously backed-up state retrieved from the View::state() method.
00062   @li View::interactorsInstalled(). Notifies the view of the available interactors. Interactors objects taken from the list have already been initialized.
00063 
00064   Once the View is initialized, none of the previously mentioned methods, except View::setGraph(), can be called again.
00065   View::setGraph method may be called again to notify the view that another graph should be displayed (this may be a sub/parent graph of the previously displayed graph or a graph coming from a totally different hierarchy)
00066 
00067   Views are meant to be managed by an overleying system. As a consequence, a view may not decide directly when to redraw.
00068   Thus, you should never call the View::draw() method. To notify the overleying system that your view needs to be redrawn, emit the View::drawNeeded() signal instead.
00069 
00070   A tlp::View subclass automatically inherits from the tlp::Observable interface. The tlp::View interface also automatically listn to its active graph to trigger handling trigger when this graph gets deleted.
00071   When the graph associated to a View gets deleted, the View::graphDeleted() callback is triggered. @see graphDeleted() for more information.
00072   */
00073 class TLP_QT_SCOPE View: public QObject, public tlp::Plugin, public tlp::Observable {
00074   Q_OBJECT
00075 
00076   QList<tlp::Interactor*> _interactors;
00077   tlp::Interactor* _currentInteractor;
00078   tlp::Graph* _graph;
00079 
00080   QSet<tlp::Observable*> _triggers;
00081 
00082 public:
00083   /**
00084     @brief Default constructor
00085     @warning Code of this method should almost be a no-op. Subsequent calls on other methods should allow you to setup your view.
00086     */
00087   View();
00088 
00089   /**
00090     @brief Destructor
00091     View's GUI components (graphics view, configuration widgets) responisbility belongs to the overleying system. Thus, the View is not in charge of deleting its graphcis view.
00092     View's interactors are already deleted in the top class.
00093     */
00094   virtual ~View();
00095 
00096   virtual std::string category() const {
00097     return VIEW_CATEGORY;
00098   }
00099   std::string icon() const {
00100     return ":/tulip/gui/icons/32/plugin_view.png";
00101   }
00102 
00103   /**
00104     @return the View's panel as a @c QGraphicsView instance.
00105     @note This method MUST ALWAYS return the same instance of a QGraphicsView.
00106     */
00107   virtual QGraphicsView* graphicsView() const=0;
00108 
00109   /**
00110     @return The list of interactors installed on this view.
00111     The list is always the same as the one given when View::setInteractors() was called.
00112     @see setInteractors();
00113     */
00114   QList<tlp::Interactor*> interactors() const;
00115 
00116   /**
00117     @return The currently active interactor.
00118     The active interactor is the one that currently recieve user inputs.
00119     @see setCurrentInteractor();
00120     @warning This method may return a NULL pointer if no interactor is currently active.
00121     */
00122   tlp::Interactor* currentInteractor() const;
00123 
00124   /**
00125     @return a list of widgets that can be used to set up the view.
00126     Since several widgets can be retrived, user will be able to select them from a combo box where each widget will be identified by its windowsTitle.
00127     @see View::applySettings()
00128     @warning This method must not instantiate configuration widgets on the fly.
00129     */
00130   virtual QList<QWidget*> configurationWidgets() const;
00131 
00132   /**
00133    * @brief This method can be used to change the configuration widgets' style
00134    * sheet. From Qt documentation: The style sheet contains a textual description of customizations to the
00135    *  widget's style, as described in the Qt Style Sheets document. see http://qt-project.org/doc/qt-4.7/stylesheet.html.
00136    * @return The stylesheet to use
00137    */
00138   virtual QString configurationWidgetsStyleSheet() const;
00139 
00140   /**
00141     @brief Backup the state of the view.
00142     This method is used to restore the View's parameters when it's re-opened.
00143     */
00144   virtual tlp::DataSet state() const=0;
00145 
00146   /**
00147     @return the graph displayed by the view.
00148     @note This method MUST return the same graph pointer that was previously passed down to setGraph.
00149     */
00150   tlp::Graph* graph() const;
00151 
00152   /**
00153     @return The list of currently registered triggers.
00154     @see View::addRedrawTrigger()
00155     */
00156   QSet<tlp::Observable*> triggers() const;
00157 
00158   /**
00159     @brief reimplemented from tlp::Observable to provide the triggers mechanism.
00160     @see View::addRedrawTrigger()
00161     */
00162   void treatEvents(const std::vector<Event> &events);
00163 
00164   /**
00165     @brief defines which item is considered as the central item in the view.
00166     The central item is considered to be a background item that will be set as parent of every graphics item added by the workspace into the view.
00167     By default, this method returns NULL, which means that no central item is defined.
00168     */
00169   virtual QGraphicsItem* centralItem() const;
00170 
00171   /**
00172     @brief Takes a snapshot of the view's screen and saves it into the given pixmap.
00173     The snapshot is scaled to outputSize. If a null size is given, the snapshot is to be on a 1:1 ratio
00174     @return A non-null pixmap of the snapshot was correctly taken.
00175     */
00176   virtual QPixmap snapshot(const QSize& outputSize=QSize()) const=0;
00177 
00178 public slots:
00179   /**
00180   * @brief This method is called whenever the context menu is required on the view.
00181   * @param point The screen coordinates where the context menu should be displayed.
00182   */
00183   void showContextMenu(const QPoint& point, const QPointF &scenePoint);
00184 
00185   /**
00186    * @brief This method is a callback to notify the panel that the pop() method (undo) has just been called on the graph.
00187    * By default, this method will make a call to centerView()
00188    **/
00189   virtual void undoCallback();
00190 
00191   /**
00192     @brief This method applies settings changed in the configuration widgets
00193     This method may be called from the overleying system in various situations. The View is expected to apply settings in an optimized way to prevent extra redraws.
00194     By default, this method does nothing.
00195     */
00196   virtual void applySettings();
00197 
00198   /**
00199     @brief Reset the visualization to the center.
00200     This method is called after major changes into the data structure. At this point, the user point of view should be reset and brought back to a point where all the data can be seen.
00201     @note It is expected for the view to be redrawn when calling centerView
00202     For a 3D visualization, this method could be implemented by centering the camera. For a table, this could be done by setting the scroll bar to the top position etc...
00203     By default, this method calls draw().
00204     */
00205   virtual void centerView(bool graphChanged = false);
00206 
00207 
00208   /**
00209     @brief defines the list of interactors available on this View
00210     @note Calling this will trigger the View::interactorsInstalled() callback for custom handling.
00211   */
00212   virtual void setInteractors(const QList<tlp::Interactor*>&);
00213 
00214   /**
00215     @brief defines the active interactor that will receive user inputs.
00216     @note This method will first remove the previously active interactor (if any) using Interactor::uninstall()
00217     @note Calling this will trigger the View::currentInteractorChanged() callback for custom handling.
00218     @note Calling View::setCurrentInteractor(NULL) will only remove the previous current interactor.
00219   */
00220   void setCurrentInteractor(tlp::Interactor* currentInteractor);
00221 
00222   /**
00223     @brief Restores the state of the view.
00224     DataSet passed down to this method can come from a previous backup or be generated by the overleying system. It's up to the view to use this data or not.
00225     */
00226   virtual void setState(const tlp::DataSet&)=0;
00227 
00228   /**
00229     @brief Defines the graph that should be displayed by the View
00230     @note Calling setGraph triggers the View::graphChanged() callback for custom handling.
00231     @warning This method and its subsequent callback might be called several times.
00232     */
00233   void setGraph(tlp::Graph* graph);
00234 
00235   /**
00236     @brief Asks the view to draw.
00237     A call to draw() means that internal data has most probably been modified and that the View should take that into account when drawing.
00238     */
00239   virtual void draw()=0;
00240 
00241   /**
00242     @brief Refresh the View's panel.
00243     Calling refresh() means that no internal data has been modified. This can happen when the view's panel gets resized, restored etc
00244     */
00245   inline virtual void refresh() {
00246     draw();
00247   }
00248 
00249   /**
00250     @brief Sets up GUI elements belonging to the View.
00251     This method is called once the initial state as been set (using setGraph and setState) and is called only once.
00252     */
00253   virtual void setupUi()=0;
00254 
00255   /**
00256     @brief This method is inherited from tlp::Observable and allows the view to trigger custom callback when its associated graph gets deleted.
00257     @warning When overriding this method. You MUST always make a call to View::treatEvent before doing anything in order to keep this callback working.
00258     */
00259   virtual void treatEvent(const Event&);
00260 
00261   /**
00262     @brief Registers a new trigger for automatic view drawing.
00263     Triggers are tlp::Observable subclasses. Once registered, the view will listen to the trigger's events and emit the drawNeeded signal each time the Observable::treatEvents() callback is run.
00264     For more information about the Observable system, @see tlp::Observable
00265 
00266     @note This is a convenience function. However, using triggers prevent from performign extra checks on the data structure to know if a redraw must me made or not. For more control over event handling, you will have to implement your own treatEvent/treatEvents callback.
00267     @warning If your tlp::View subclass overloads the treatEvents method. You must make sure to call the View::treatEvents method in order to keep the triggers system working.
00268     */
00269   void addRedrawTrigger(tlp::Observable*);
00270 
00271   /**
00272     @brief Removes a trigger from the list of registered triggers. Event coming from this trigger will no longer trigger the drawNeeded signal.
00273     @see View::addRedrawTrigger()
00274     */
00275   void removeRedrawTrigger(tlp::Observable*);
00276 
00277   /**
00278     @brief Clears the list of attached triggers
00279     This method removes all triggers associated to the View.
00280     @note From the moment this method is called, no update on previous triggers will be considered. Even if this is called during an Observable::holdObservers()
00281     */
00282   void clearRedrawTriggers();
00283 
00284   /**
00285     @brief This function emit the signal drawNeeded
00286     */
00287   void emitDrawNeededSignal();
00288 
00289 signals:
00290   /**
00291     @brief Inform the overlying subsystem that this view needs to be drawn.
00292     @note Depending on the overlying implementation, a subsequent call to draw might not be immediate.
00293     */
00294   void drawNeeded();
00295 
00296   /**
00297     @brief Emitted after the setGraph method has been called.
00298     @note This signal is emitted from the non-virtual View::setGraph() method thus cannot be prevented.
00299     */
00300   void graphSet(tlp::Graph*);
00301 
00302   void interactorsChanged();
00303 
00304 protected slots:
00305   /**
00306     @brief Callback method after setInteractors() was called.
00307     At this point, a call to View::interactors() is considered valid.
00308     */
00309   virtual void interactorsInstalled(const QList<tlp::Interactor*>& interactors);
00310 
00311   /**
00312     @brief Callback method after setCurrentInteractor() was called.
00313     At this point, a call to View::currentInteractor() is considered valid and return the newly active interactor.
00314     @warning The interactor passed down to this method MAY BE a NULL pointer ! This means that no current interactor should be set.
00315     */
00316   virtual void currentInteractorChanged(tlp::Interactor*);
00317 
00318   /**
00319     @brief Callback method after setGraph() was called.
00320     At this point, a call to View::graph() is considered valid and return the lastly set graph.
00321     */
00322   virtual void graphChanged(tlp::Graph*)=0;
00323 
00324   /**
00325     @brief Called when the graph associated to the view gets deleted.
00326     This method should call setGraph to input a new graph pointer (NULL or valid)
00327     @param parentGraph The parent of the graph that was just deleted. If there is no parent available (eg. the graph was root), parentGraph is NULL
00328     */
00329   virtual void graphDeleted(tlp::Graph* parentGraph)=0;
00330 
00331   /**
00332    * @brief fills the context menu with entries related to the view.
00333    * This method is called whenever the context menu is displayed on the panel.
00334    * @param QMenu The popup menu that will be displayed. This menu should be populated with context action related to the panel.
00335    */
00336   virtual void fillContextMenu(QMenu*,const QPointF &) {}
00337 };
00338 
00339 }
00340 
00341 #endif /* VIEW_H_ */
 All Classes Files Functions Variables Enumerations Enumerator Properties