3d1e80366fba6c8959fa3305e1413b957d88f13b
[occt.git] / samples / qt / Graphic3dDemo / inc / Graph.h
1 // The following ifdef block is the standard way of creating macros which make exporting 
2 // from a DLL simpler. All files within this DLL are compiled with the TEST_EXPORTS
3 // symbol defined on the command line. this symbol should not be defined on any project
4 // that uses this DLL. This way any other project whose source files include this file see 
5 // TEST_API functions as being imported from a DLL, wheras this DLL sees symbols
6 // defined with this macro as being exported.
7
8 #ifdef GRAPH_EXPORTS
9 #define GRAPH_API __declspec(dllexport)
10 #else
11 #define GRAPH_API __declspec(dllimport)
12 #endif
13
14 //////////////////////////////////////////////////////////////////////
15 // File     : Graph.h
16 // Created  : 26.03.02
17 // Author   : Vadim SANDLER
18 //////////////////////////////////////////////////////////////////////
19
20 #if !defined(_Graph_h)
21 #define _Graph_h
22
23 #include <qwidget.h>
24 #include <qpixmap.h>
25 #include <qcursor.h>
26 #include <qlist.h>
27 #include <qsplitter.h>
28 #include <qlayout.h>
29 #include <qcolor.h>
30 #include <qrubberband.h>
31
32 //================================================================
33 // Class        : GraphNode
34 // Description  : graph node
35 //================================================================
36 class GRAPH_API GraphNode {
37 public:
38 // default constructor
39   GraphNode();
40 // constructor
41   GraphNode(const double x, const double y);
42 // copy constructor
43   GraphNode(const GraphNode& node);
44
45 // x coordinate
46   inline double x() const { return myX; }
47 // y coordinate
48   inline double y() const { return myY; }
49 // operator ==
50   bool          operator== (const GraphNode& node);
51 // operator <
52   bool          operator<  (const GraphNode& node);
53 // operator >
54   bool          operator>  (const GraphNode& node);
55 // operator =
56   GraphNode&    operator=  (const GraphNode& node);
57
58 private:
59 // node coordinates
60   double        myX;
61   double        myY;
62 };
63
64 typedef QList<GraphNode*> NodeList;
65 class   GraphView;
66
67 //================================================================
68 // Class        : GraphItem
69 // Description  : graph data set
70 //================================================================
71 class GRAPH_API GraphItem {
72 public:
73 // constructor
74   GraphItem(GraphView* parent, QString name = QString::null);
75 // destructor
76   virtual ~GraphItem();
77
78 // adds node
79   void          addNode (GraphNode* node);
80 // adds node
81   void          addNode (const double x, const double y);
82 // adds nodes
83   void          addNodes(NodeList& nodes);
84 // removes node (and deletes it)
85   void          removeNode(GraphNode* node);
86 // removes node by index (and deletes it)
87   void          removeNode(int index);
88 // clears nodes
89   void          clear ();
90 // gets number of nodes
91   int           count ()   { return myNodes.count(); }
92 // returns true if list of nodes is empty
93   bool          isEmpty () { return myNodes.isEmpty(); }
94 // returns true if item is valid, i.e. has valid attributes and not empty
95   bool          isValid ();
96 // returns <Sorted> flag, true by default
97   bool          isSorted() { return mySorted; }
98 // sets/clears <Sorted> flag (and reorders nodes)
99   void          setSorted (bool sorted);
100 // gets node by index or NULL if index is out of range
101   GraphNode*    getNode (const int index);
102 // gets node by index or NULL if index is out of range
103   GraphNode*    operator[] (const int index);
104 // sets dynamic marker for item
105   void          setMarker (const int marker, 
106                            const int color, 
107                            const int line);
108 // sets static marker for item 
109 // (with own (NOT CHANGEABLE) marker, color and type line)
110   void          setMarker (const int      marker, 
111                            const QColor&  color, 
112                            const Qt::PenStyle line);
113 // gets item name
114   QString       getName() const { return myName; }
115 // sets item name
116   void          setName(const QString& name) { myName = name; }
117 // returns true if item has own color
118   bool          hasOwnColor() const  { return myHasOwnColor; }
119 // returns true if item has own line type
120   bool          hasOwnLine() const   { return myHasOwnLine; }
121 // returns true if item has own marker
122   bool          hasOwnMarker() const { return myHasOwnMarker; }
123 // sets own color
124   void          setColor(const QColor& color);
125 // returns item's color
126   QColor        getColor();
127 // sets own line
128   void          setLine(const Qt::PenStyle line);
129 // returns item's line type
130   Qt::PenStyle  getLine();
131 // sets own marker 
132   void          setMarker(const int marker);
133 // return item's marker type
134   int           getMarker();
135 // gets marker attributes
136   void          getMarker (int& marker, int& color, int& line);
137
138 protected:
139 // performs initialization
140   void          init();
141
142 private:
143 // parent graph viewer
144   GraphView*    myParent;
145 // node list  
146   NodeList      myNodes;
147 // name of item
148   QString       myName;
149 // attributes type of line, color and marker
150   int           myMarker;
151   int           myColor;
152   int           myLine;
153 // own marker
154   bool          myHasOwnMarker;
155 // own color
156   bool          myHasOwnColor;
157   QColor        myOwnColor;
158 // own line type
159   bool          myHasOwnLine;
160   Qt::PenStyle  myOwnLine;
161 // <Sort coordinates> flag
162   bool          mySorted;
163 };
164
165 typedef QList<GraphItem*>   ItemList;
166 typedef QList<QColor>       ColorList;
167 typedef QList<Qt::PenStyle> LineList;
168 typedef QList<int>          IntList;
169
170 class GraphLegend;
171
172 //================================================================
173 // Class        : GraphView
174 // Description  : simple graph displayer
175 //================================================================
176 class GRAPH_API GraphView : public QWidget {
177   struct OperationButton {
178     Qt::MouseButtons      button;
179     Qt::KeyboardModifiers modifier;
180     OperationButton(const Qt::MouseButtons      btn = Qt::NoButton,
181                     const Qt::KeyboardModifiers m   = Qt::NoModifier)
182       : button(btn), modifier(m) {}
183   };
184
185 public:
186   enum ViewOperation { voNone, voZoom, voZoomX, voZoomY, 
187                        voPan,  voPanX, voPanY,  voRect };
188   enum GridMode      { gmFixed, gmIntervals, gmFloating };
189
190 #ifdef DEB
191   void          drawItem(QPainter* painter, 
192                          int       pxMin,
193                          int       pxMax, 
194                          int       pyMin, 
195                          int       pyMax,
196                          double    xMin, 
197                          double    xMax, 
198                          double    yMin, 
199                          double    yMax, 
200                          GraphItem* item);
201 #endif
202
203 /* ================== CONSTRUCTION/DESTRUCTION ================ */
204 // Constructor
205   GraphView(QWidget* parent = 0);
206 // Destructor
207   ~GraphView();
208
209 /* ======================= OVERRIDED ========================== */
210 // event filter 
211   bool            eventFilter(QObject* object, QEvent* event);
212
213 /* ================== CURSORS HANDLING ======================== */
214 // sets cursor for certain view operation
215   void            setOperationCursor (const ViewOperation operation, 
216                                       const QCursor&      newCursor);
217 // gets cursor for certain view operation
218   QCursor         getOperationCursor (const ViewOperation operation) const;
219
220 /* =================== VIEW OPERATIONS ======================== */
221 // returns global <Enable operations> flag state
222   bool            isOperationsEnabled() const { return myEnableGlobal; }
223 // globally enables/disables operations
224   void            setOperationsEnabled(bool on);
225 // returns 'true' if view operation is enabled 
226   bool            isOperationEnabled (const ViewOperation operation) const;
227 // enables/disables view operation 
228   void            setOperationEnabled(const ViewOperation operation, 
229                                       bool                enable);
230 // sets operation key-mousebutton combination
231   void            setOperationButton (const ViewOperation         operation, 
232                                       const Qt::MouseButtons      button,
233                                       const Qt::KeyboardModifiers modifier);
234 // gets operation key-mousebutton combination
235   void            getOperationButton (const ViewOperation    operation,
236                                       Qt::MouseButtons&      button,
237                                       Qt::KeyboardModifiers& modifier) const;
238 // tests for operation key-mousebutton combination
239   bool            testOperation      (const ViewOperation theOp, 
240                                       const Qt::MouseButtons      button,
241                                       const Qt::KeyboardModifiers modifier) const;
242 // tests key-mousebutton combination and returns view operation if any matches
243   ViewOperation   testOperation      (const Qt::MouseButtons      button,
244                                       const Qt::KeyboardModifiers modifier) const;
245
246   // resets view : sets origin to 0.0 and scales to 1.0
247   void            reset();
248 // fits viewer so display all data  
249   void            fitAll();
250 // fits viewer to display certain data
251   void            fitData(const double xMin, const double xMax,
252                           const double yMin, const double yMax);
253 // fits viewer to display certain data along horizontal axis
254   void            fitDataX(const double xMin, const double xMax);
255 // fits viewer to display certain data along vertical axis
256   void            fitDataY(const double yMin, const double yMax);
257 // performs pan operation by dx, dy pixels
258   void            pan(const int dx, const int dy);
259 // performs zoom operation by dx, dy pixels
260   void            zoom(const int dx, const int dy);
261 // starts view operation if it is enabled
262   void            startViewOperation(const ViewOperation operation);
263
264 /* ================== ATRIBUTES HANDLING ====================== */
265 // enables/disables internal markers drawing
266   void            showMarkers     (bool show);
267 // enables/disables tooltips
268   void            showTooltips    (bool show);
269 // returns true is axes are shown
270   bool            isAxesShown     () const { return myShowAxes; }
271 // shows/hides axes
272   void            showAxes        (bool show);
273 // returns true is tick-marks are shown
274   bool            isTickMarkShown () const { return myShowTickMarks; }
275 // shows/hides tick-marks
276   void            showTickMark     (bool show);
277 // returns true is title is shown
278   bool            isTitleShown    () const { return myShowTitle; }
279 // shows/hides title
280   void            showTitle       (bool show);
281 // gets graph title
282   const QString&  getTitle        () const { return myTitle; }
283 // sets graph title
284   void            setTitle        (const QString& title);
285 // returns true is axes titles are shown
286   bool            isAxesTitleShown() const { return myShowAxesTitle; }
287 // shows/hides axis titles
288   void            showAxesTitle   (bool show);
289 // gets graph X axis title
290   const QString&  getXTitle       () const { return myXTitle; }
291 // sets graph X axis title
292   void            setXTitle       (const QString& title);
293 // gets graph Y axis title
294   const QString&  getYTitle       () const { return myYTitle; }
295 // sets graph Y axis title
296   void            setYTitle       (const QString& title);
297 // returns true is grid is shown
298   bool            isGridShown     () const { return myShowGrid; }
299 // shows/hides grid
300   void            showGrid        (bool show);
301 // sets grid step (FLOATING mode) for x, y axes, 
302 // doesn't change step if it is <= 0
303   void            setGridStep (const double x, const double y, bool turn = true);
304 // gets grid step (FLOATING mode) for x, y axes 
305 // and returns true if grid mode is FLOATING
306   bool            getGridStep (double& x, double& y) const;
307 // sets grid step (FIXED mode) for x, y axes in pixels, 
308 // doesn't change step if it is less <= 0
309   void            setFixedGridStep (const int x, const int y, bool turn = true);
310 // gets grid step (FIXED mode) for x, y axes in pixels 
311 // and returns true if grid mode is FIXED
312   bool            getFixedGridStep (int& x, int& y) const;
313 // sets number of grid intervals (INTERVALS mode) for x, y axes, 
314 // doesn't change if <= 0
315   void            setGridIntervals (const int xInt, 
316                                     const int yInt, 
317                                     bool      turn = true);
318 // gets number of grid intervals (INTERVALS mode) for x, y axes, 
319 // and returns true if grid mode is INTERVALS
320   bool            getGridIntervals (int &xInt, int &yInt) const;
321 // returns grid mode [FIXED, INTERVALS, FLOATING]
322   GridMode        getGridMode() const { return myGridMode; }
323 // switches grid mode [FIXED, INTERVALS, FLOATING]
324   void            setGridMode(const GridMode mode);
325 // sets X axis scale 
326   void            setXScale(const double scale);
327 // gets X axis scale (data per pixel along X axis)
328   double          getXScale() const { return myXScale; }
329 // sets Y axis scale
330   void            setYScale(const double scale);
331 // gets Y axis scale (data per pixel along Y axis)
332   double          getYScale() const { return myYScale; }
333 // sets X,Y axis scale
334   void            setScale(const double scale);
335 // moves axes origin to point [x, y]
336   void            setOrigin(const double x, const double y);
337 // gets axes origin
338   void            getOrigin(double& x, double& y) const;
339 // changes backgroundColor, use it instead setBackgroundColor
340   void            changeBackgroundColor(const int index = -1);
341 // gets main title font
342   QFont           getTitleFont() { return myTitleFont; }
343 // sets main title font
344   void            setTitleFont(QFont& font);
345 // gets axes title font
346   QFont           getAxesTitleFont() { return myAxesTitleFont; }
347 // sets axes title font
348   void            setAxesTitleFont(QFont& font);
349 // gets tick marks font
350   QFont           getTickMarksFont() { return myTickMarksFont; }
351 // sets tick marks font
352   void            setTickMarksFont(QFont& font);
353 // sets legend widget
354   void            setLegend(GraphLegend* legend);
355 // gets legend widget
356   GraphLegend*    getLegend() { return myLegend; }
357 // gets margins size
358   void            getMargins(int& leftMargin, 
359                              int& rightMargin, 
360                              int& topMargin, 
361                              int& bottomMargin);
362
363 /* ================== DATA HANDLING =========================== */
364 // inserts item into list
365   void            insertItem(GraphItem* item);
366 // removes item from list
367   void            removeItem(const int index);
368 // clears data list
369   void            clear();
370 // gets number of items
371   int             getNbItems() { return myItems.count(); }
372 // gets item by index, returns NULL if index is out of range
373   GraphItem*      getItem(const int index);
374 // returns index of item in data list 
375   int             findItem(GraphItem* item);
376 // sets/unsets items to be sorted by horizontal coordinate
377   void            setSorted(bool sorted);
378 // gets full data range
379   void            getRange(double& minX, double& minY, 
380                            double& maxX, double& maxY);
381 // gets current data range
382   void            getCurrentRange(double& minX, double& minY, 
383                                   double& maxX, double& maxY);
384 // returns number of colors provided
385   virtual int     getNbColors();
386 // returns number of markers provided
387   virtual int     getNbMarkers();
388 // returns number of type lines provided
389   virtual int     getNbTypeLines();
390 // gets marker size (default is 9 pixels)
391   int             getMarkerSize() { return myMarkerSize; } 
392 // sets marker size (for good look it should be odd)
393   void            setMarkerSize(const int size); 
394 // gets color by index
395   virtual QColor  getColor(const int color);
396 // gets line
397   virtual Qt::PenStyle getLine(const int line);
398 // returns true if colors seem to be the same (difference is less than gap)
399   static bool     isSameColors(const QColor color1, 
400                                const QColor color2, 
401                                const int    gap = 10);
402
403 protected:
404 /* ================== VIEW OPERATIONS HANDLING ================ */
405 // starts/finishes view operation
406   void            startOperation (ViewOperation theOp);
407 // called on view operation starting
408   virtual void    onStartOperation  ();
409 // called on view operation finishing
410   virtual void    onFinishOperation ();
411 // called on view operation running
412   virtual void    onOperation (QPoint mousePos);
413 // called on mouse moving action (e.g. for highlighting item)
414   virtual void    onMouseMove (QPoint mousePos);
415 // gets sensibility area size
416   int             getSensibilitySize() const { return mySensibilitySize; }
417 // sets sensibility area size
418   void            setSensibilitySize(const int size);
419 // handles tooltips for the view
420   QRect           tip(const QPoint& point, QString& tipText);
421
422 /* ================== EVENTS HANDLING ========================= */
423 // MousePress event handler
424   void            mousePressEvent (QMouseEvent* e);
425 // MouseMove event handler
426   void            mouseMoveEvent (QMouseEvent* e);
427 // MouseRelease event handler
428   void            mouseReleaseEvent (QMouseEvent* e);
429 // MouseDoubleClick event handler
430   void            mouseDoubleClickEvent (QMouseEvent *e);
431 // KeyPress event handler
432   void            keyPressEvent (QKeyEvent *e);
433 // KeyRelease event handler
434   void            keyReleaseEvent (QKeyEvent *e);
435 // Resize event handler
436   void            resizeEvent (QResizeEvent* e);
437 // Paint event handler
438   void            paintEvent (QPaintEvent* e);
439 // global event handler
440   bool            event (QEvent* e);
441
442 /* ================== DRAWING FUNCTIONS ======================= */
443 // gets graph painting area
444   virtual QRect   getGraphRect ();
445 // draws grid
446   virtual void    drawGrid (QPainter* painter);
447 // draws border (it is drawn when grid is not)
448   virtual void    drawBorder (QPainter* painter);
449 // draws axes
450   virtual void    drawAxes (QPainter* painter);
451 // draws tick marks
452   virtual void    drawTickMarks(QPainter* painter);
453 // draws axes titles
454   virtual void    drawAxesTitle(QPainter* painter);
455 // draws graph title
456   virtual void    drawTitle(QPainter* painter);
457 // draws item
458   virtual void    drawItem (QPainter* painter, GraphItem* item);
459 // draws marker at position
460   virtual void    drawMarker(QPainter*     painter, 
461                              const QPoint  point, 
462                              const int     marker, 
463                              const QColor& color);
464 // gets new unique marker for item if possible
465   virtual void    getNextMarker(int& typeMarker, int& color, int& typeLine);
466 // checks if marker belongs to some entity
467   bool            existMarker(const int typeMarker, 
468                               const int color, 
469                               const int typeLine);
470
471 private:
472 // returns true if line [x1,y1] - [x2,y2] intersect rectangle
473   static bool     intersects(QRect rect, long x1, long y1, long x2, long y2);
474 // calculates points for grid and/or tick marks
475   void            getTickPoints(IntList& xList, IntList& yList);
476
477 private:
478 // enable view operations flags
479   bool            myEnableGlobal;
480   bool            myEnableRect;
481   bool            myEnablePan;
482   bool            myEnablePanX;
483   bool            myEnablePanY;
484   bool            myEnableZoom;
485   bool            myEnableZoomX;
486   bool            myEnableZoomY;
487 // current view operation
488   ViewOperation   myOperation;
489 // current view operation
490   ViewOperation   myForcedOp;
491 // sensibility size for rect selection operation
492   int             mySensibilitySize;
493 // view operation points (second is used for rubber rectangle)
494   QPoint          myPoint;
495   QPoint          myOtherPoint;
496 // view operations key-mouse combinations
497   OperationButton myRectKey;
498   OperationButton myPanKey;
499   OperationButton myPanXKey;
500   OperationButton myPanYKey;
501   OperationButton myZoomKey;
502   OperationButton myZoomXKey;
503   OperationButton myZoomYKey;
504 // state cursors
505   QCursor         myDefCursor;
506   QCursor         myRectCursor;
507   QCursor         myPanCursor;
508   QCursor         myPanXCursor;
509   QCursor         myPanYCursor;
510   QCursor         myZoomCursor;
511   QCursor         myZoomXCursor;
512   QCursor         myZoomYCursor;
513 // axes origin (left-bottom point)
514   GraphNode       myOrigin;
515 // X axis scale
516   double          myXScale;
517   double          myYScale;
518 // draw flags
519   bool            myShowAxes;
520   bool            myShowTitle;
521   bool            myShowAxesTitle;
522   bool            myShowTickMarks;
523   bool            myShowGrid;
524   bool            myShowTooltips;
525   bool            myShowMarkers;
526 // grid mode
527   GridMode        myGridMode;
528 // fixed grid size
529   int             myGridPStepX;
530   int             myGridPStepY;
531 // floating grid size
532   double          myGridStepX;
533   double          myGridStepY;
534 // number of grid intervals
535   int             myGridIntX;
536   int             myGridIntY;
537 // marker size
538   int             myMarkerSize;
539 // titles
540   QString         myTitle;
541   QString         myXTitle;
542   QString         myYTitle;
543 // colors
544   ColorList       myColors;
545 // line types
546   LineList        myLines;
547 // data
548   ItemList        myItems;
549   GraphLegend*    myLegend;
550 // fonts
551   QFont           myTitleFont;
552   QFont           myAxesTitleFont;
553   QFont           myTickMarksFont;
554 // rubber band
555   QRubberBand*    myRubberBand;
556   
557   friend class GraphLegend;
558 };
559
560 //================================================================
561 // Class        : GraphLegend
562 // Description  : Legend widget
563 //================================================================
564 class GRAPH_API GraphLegend : public QWidget {
565 public:
566 // constructor
567   GraphLegend(QWidget* parent, GraphView* graph);
568
569 // updates legend contents
570   void            updateMe();
571 // shows/hides legend title
572   void            showTitle(bool show);
573 // sets legend title
574   void            setTitle(const QString& title);
575 // gets legend title
576   QString         getTitle() const { return myTitle; }
577 // returns graph item which is below the point or NULL
578   GraphItem*      itemAt(const QPoint& point);
579 // gets legend title font
580   QFont           getTitleFont() { return myTitleFont; }
581 // sets legend title font
582   void            setTitleFont(QFont& font);
583 // gets item font
584   QFont           getItemFont() { return font(); }
585 // sets item font
586   void            setItemFont(QFont& font);
587 // get minimum size
588   QSize           minimumSizeHint() const;
589   QSize           sizeHint() const;
590
591 protected:
592 // handles tooltips for the view
593   QRect           tip(const QPoint& point, QString& tipText);
594 // returns rect which contains item's name
595   QRect           textRect(GraphItem* item, QString& tipText);
596 // draws contents
597   void            paintEvent(QPaintEvent* e);
598 // global event handler
599   bool            event(QEvent* e);
600
601 private:
602 // parent graph
603   GraphView*      myGraph;
604   bool            myShowTitle;
605   QString         myTitle;
606   QFont           myTitleFont;
607 };
608
609 //================================================================
610 // Class        : GraphSplitView
611 // Description  : Graph view with a legend in splitted window
612 //================================================================
613 class GRAPH_API GraphSplitView : public QWidget {
614 public:
615 // constructor
616   GraphSplitView(QWidget* parent);
617
618 // returns graph view
619   GraphView*      getGraph()  { return myGraph; }
620 // returns legend view
621   GraphLegend*    getLegend();
622 // shows/hides legend view
623   void            showLegend(bool show);
624 // returns true if legend is being shown
625   bool            isLegendShown();
626
627 private:
628 // graph view
629   GraphView*      myGraph;
630 // splitter window
631   QSplitter*      mySplitter;
632 };
633
634 #endif // !defined(_Graph_h)