graph_displayer_canvas.h
author hegyi
Thu, 28 Sep 2006 14:32:40 +0000
changeset 156 c5cdf6690cdf
parent 154 65c1b103443d
child 157 7e6ad28aeb9e
permissions -rw-r--r--
Zoom tracking of nodes is implemented and is switchable.
     1 // -*- C++ -*- //
     2 
     3 #ifndef GRAPH_DISPLAYER_CANVAS_H
     4 #define GRAPH_DISPLAYER_CANVAS_H
     5 
     6 class GraphDisplayerCanvas;
     7 
     8 #include "all_include.h"
     9 #include "nbtab.h"
    10 #include <libgnomecanvasmm.h>
    11 #include <libgnomecanvasmm/polygon.h>
    12 #include <lemon/dim2.h>
    13 
    14 ///This class is the canvas, on which the graph can be drawn.
    15 class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
    16 {
    17   friend class BrokenEdge;
    18   friend class LoopEdge;
    19 
    20   class EdgeBase : public Gnome::Canvas::Group
    21   {
    22     protected:
    23       ///Reference to the canvas, on which the graph is drawn.
    24 
    25       ///It is needed, because some datas needed from
    26       ///graph can be accessed by this or should be sent
    27       ///as parameter, but it would be complicated
    28       GraphDisplayerCanvas& canvas;
    29 
    30       ///The edge that the class displays.
    31 
    32       ///It is needed, because some datas needed from
    33       ///graph can be accessed by this or should be sent
    34       ///as parameter, but it would be complicated
    35       Edge edge;
    36 
    37       Gnome::Canvas::Polygon arrow;
    38 
    39       void drawArrow(XY);
    40     public:
    41       EdgeBase(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
    42       virtual ~EdgeBase();
    43       virtual void draw() = 0;
    44       virtual void setLineWidth(int) = 0;
    45       virtual void setFillColor(Gdk::Color) = 0;
    46       virtual Gnome::Canvas::Item * getLine() = 0;
    47   };
    48 
    49   ///Edge displayer class
    50 
    51   ///This class is responsible for displaying edges in graph.
    52   ///The displayed edge is broken in the middle. The
    53   ///aim of this is to be able to indicate direction of edges
    54   ///and to be able to display more then one edges between the
    55   ///same source and target
    56   class BrokenEdge : public EdgeBase
    57   {
    58     private:
    59       Gnome::Canvas::Line line;
    60 
    61       ///Indicates whether the button of mouse is pressed or not at the moment.
    62       bool isbutton;
    63 
    64       ///At this location was the mousebutton pressed. Horizontal component.
    65 
    66       ///It helps to calculate the
    67       ///distance of dragging.
    68       double clicked_x;
    69 
    70       ///At this location was the mousebutton pressed. Vertical component.
    71 
    72       ///It helps to calculate the
    73       ///distance of dragging.
    74       double clicked_y;
    75 
    76       ///event handler for forming broken edges
    77 
    78       ///\param event the
    79       ///event to handle
    80       bool edgeFormerEventHandler(GdkEvent* event);
    81 
    82     public:
    83       ///Constructor of broken edge class.
    84 
    85       ///\param g the group to which the edge belongs
    86       ///\param _edge the represented edge
    87       ///\param gc the canvas
    88       BrokenEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
    89 
    90       ///Destructor of broken edge class
    91 
    92       ///Frees up
    93       ///reserved memory
    94       ~BrokenEdge();
    95 
    96       ///The function that draws the edge based on collected data
    97       void draw();
    98 
    99       void setLineWidth(int);
   100       void setFillColor(Gdk::Color);
   101 
   102       Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
   103   };
   104 
   105   class LoopEdge : public EdgeBase
   106   {
   107     private:
   108       Gnome::Canvas::Ellipse line;
   109       bool edgeFormerEventHandler(GdkEvent* e);
   110       bool isbutton;
   111     public:
   112       LoopEdge(Gnome::Canvas::Group&, Edge, GraphDisplayerCanvas&);
   113       ~LoopEdge();
   114       void draw();
   115       void setLineWidth(int);
   116       void setFillColor(Gdk::Color);
   117       Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
   118   };
   119 
   120   ///Type of canvas, on which the graph is drawn
   121   typedef Gnome::Canvas::CanvasAA Parent;
   122 
   123 public:
   124   ///Constructor
   125 
   126   ///\param nbt the tab of the window, in which the graph is displayed
   127   GraphDisplayerCanvas(NoteBookTab & nbt);
   128 
   129   ///destructor of the class
   130   virtual ~GraphDisplayerCanvas();
   131 
   132   ///Changes the width of edge(s) according to the given map.
   133 
   134   ///\param mapname is the name of the map which contains the values to be set
   135   ///\param edge if it is given, only the width of the given edge will be set, instead of all of them.
   136   int changeEdgeWidth (std::string mapname, Edge edge=INVALID);
   137 
   138   ///Resets width of edge(s) to the default value
   139 
   140   ///\param edge if it is given, only the width of the
   141   ///given edge will be reset, instead of all of them.
   142   int resetEdgeWidth (Edge edge=INVALID);
   143 
   144   ///Changes the color of edge(s) according to the given map.
   145 
   146   ///\param mapname is the name of the map which contains the new values
   147   ///\param edge if it is given, only the color of the given edge will be set, instead of all of them.
   148   int changeEdgeColor (std::string mapname, Edge edge=INVALID);
   149 
   150   ///Resets color of edge(s) to the default value
   151 
   152   ///\param edge if it is given, only the color of the
   153   ///given edge will be reset, instead of all of them.
   154   int resetEdgeColor (Edge edge=INVALID);
   155 
   156   ///Changes the label of edge(s) according to the given map.
   157 
   158   ///\param mapname is the name of the map which contains the new values
   159   ///\param edge if it is given, only the label of the given edge will be set, instead of all of them.
   160   int changeEdgeText (std::string mapname, Edge edge=INVALID);
   161 
   162   ///Resets label of edge(s) to the default value
   163 
   164   ///\param edge if it is given, only the color of the
   165   ///given edge will be reset, instead of all of them.
   166   int resetEdgeText (Edge edge=INVALID);
   167 
   168   ///Changes the radius of node(s) according to the given map.
   169 
   170   ///\param mapname is the name of the map which contains the new values
   171   ///\param node if it is given, only the radius of the given node will be set, instead of all of them.
   172   int changeNodeRadius (std::string mapname, Node node=INVALID);
   173 
   174   ///Resets radius of node(s) to the default value
   175 
   176   ///\param node if it is given, only the radius of the
   177   ///given node will be reset, instead of all of them.
   178   int resetNodeRadius (Node node=INVALID);
   179 
   180   ///Changes the color of node(s) according to the given map.
   181 
   182   ///\param mapname is the name of the map which contains the new values
   183   ///\param node if it is given, only the color of the given node will be set, instead of all of them.
   184   int changeNodeColor (std::string mapname, Node node=INVALID);
   185 
   186   ///Resets color of node(s) to the default value
   187 
   188   ///\param node if it is given, only the color of the
   189   ///given node will be reset, instead of all of them.
   190   int resetNodeColor (Node node=INVALID);
   191 
   192   ///Changes the label of node(s) according to the given map.
   193 
   194   ///\param mapname is the name of the map which contains the new values
   195   ///\param node if it is given, only the label of the given node will be set, instead of all of them.
   196   int changeNodeText (std::string mapname, Node node=INVALID);
   197 
   198   ///Resets label of node(s) to the default value
   199 
   200   ///\param node if it is given, only the label of the
   201   ///given node will be reset, instead of all of them.
   202   int resetNodeText (Node node=INVALID);
   203 
   204   ///This function is called, when any of the displayed attributes have to be updated, or changed
   205 
   206   ///\param itisedge if true, edge property has to be changed, else node property
   207   ///\param prop the id of property that has to changed or updated
   208   void propertyChange(bool itisedge, int prop);
   209 
   210   ///updates the given property
   211 
   212   ///\param edge if it is not INVALID, only the property of the given edge will be updated, instead of all of them
   213   ///\param prop the property to update
   214   void propertyUpdate(Edge edge, int prop);
   215 
   216   ///updates the given property
   217 
   218   ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them
   219   ///\param prop the property to update
   220   void propertyUpdate(Node node, int prop);
   221 
   222   ///updates all the property for the given edge
   223   void propertyUpdate(Edge);
   224 
   225   ///updates all the property for the given node
   226   void propertyUpdate(Node);
   227 
   228   ///Callback for 'ViewZoomIn' action.
   229   virtual void zoomIn();
   230   ///Callback for 'ViewZoomOut' action.
   231   virtual void zoomOut();
   232   ///Callback for 'ViewZoomFit' action.
   233   virtual void zoomFit();
   234   ///Callback for 'ViewZoom100' action.
   235   virtual void zoom100();
   236   ///Sets the scroll region of the convas to the bounding box of the graph.
   237   void updateScrollRegion();
   238 
   239   ///This function changes the tool in the graph-editor's hand
   240   void changeEditorialTool(int);
   241 
   242 protected:
   243 
   244   //maximizing, minimizing, restoring window, etc.
   245   virtual bool on_expose_event(GdkEventExpose *);
   246 
   247 private:
   248 
   249   ///This function is responsible for the correct
   250   ///reaction of any action happened in the territory
   251   ///of the canvas
   252   ///DEPRECATED!!!!
   253   bool eventHandler(GdkEvent* e, Node n);
   254 
   255   ///actual event handler
   256   ///
   257   ///Actual event handler should be stored, to be able to disconnect it and later reconnect it.
   258   sigc::connection actual_handler;
   259 
   260   ///event handler for the case when move-tool is active
   261   bool moveEventHandler(GdkEvent*);
   262   ///event handler for the case when create_node-tool is active
   263   bool createNodeEventHandler(GdkEvent*);
   264   ///event handler for the case when create_edge-tool is active
   265   bool createEdgeEventHandler(GdkEvent*);
   266   ///event handler for the case when eraser-tool is active
   267   bool eraserEventHandler(GdkEvent*);
   268   ///event handler for the case when map editor tool is active
   269   bool mapEditEventHandler(GdkEvent*);
   270 
   271 public:
   272   ///Moves the text to new place
   273   void textReposition(XY);
   274 
   275   ///Activates an edge belonging to an EdgeBase
   276 
   277   ///After we have activated an edge this way,
   278   ///the GDC object will know, which edge is under forming
   279   ///therefore it can redraw the necessary elements on the canvas,
   280   ///for example the text belonging to the \ref EdgeBase can be
   281   ///redrawn (\ref textReposition).
   282   void toggleEdgeActivity(EdgeBase*, bool);
   283 
   284 public:
   285 
   286   ///Returns the actual tool in hand
   287   int getActualTool();
   288 
   289   ///Sets node representation settings
   290   void setNodeView(bool, bool, double, double, double);
   291 
   292   ///Gets node representation settings
   293   void getNodeView(bool &, bool &, double&, double&, double&);
   294 
   295   ///draws the graph
   296 
   297   ///Called when opening a file.
   298   void drawGraph();
   299 
   300   ///Clears the canvas
   301 
   302   ///It achieves this by deleting all data
   303   ///structure used to help handle the displayed graph.
   304   void clear();
   305 
   306   ///creates a new Nodemap
   307 
   308   ///\param init initial value of the map
   309   ///\param mapname name of new map
   310   int addNewNodeMap(double init,std::string mapname);
   311   ///creates a new Edgemap
   312 
   313   ///\param init initial value of the map
   314   ///\param mapname name of new map
   315   int addNewEdgeMap(double init,std::string mapname);
   316 
   317 private:
   318   ///Deletes the given element.
   319   void deleteItem(Node);
   320   ///Deletes the given element.
   321   void deleteItem(Edge);
   322 
   323 private:
   324 
   325   ///Map of nodes of graph
   326   Graph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
   327 
   328   ///Map of edges of graph
   329   Graph::EdgeMap<EdgeBase*> edgesmap;
   330 
   331   ///Map of texts to write on edges
   332   Graph::EdgeMap<Gnome::Canvas::Text *> edgetextmap;
   333 
   334   ///Map of texts to write on nodes
   335   Graph::NodeMap<Gnome::Canvas::Text *> nodetextmap;
   336 
   337   ///Group of graphical elements of displayed_graph
   338   Gnome::Canvas::Group displayed_graph;
   339 
   340 private:
   341   ///Indicates whether the button of mouse is pressed or not
   342   int isbutton;
   343 
   344   ///Stores the actual tool in hand
   345   int actual_tool;
   346 
   347   ///At this location was the mousebutton pressed.
   348   ///It helps to calculate the distance of dragging.
   349   double clicked_x, clicked_y;
   350 
   351   ///Remembers which Gnome::Canvas::Item was pressed.
   352 
   353   ///this variable is needed, to work on it after selection
   354   Gnome::Canvas::Item * active_item;
   355 
   356   ///Remembers which Gnome::Canvas::Item was pressed.
   357 
   358   ///this variable is used at edge creation, it will
   359   ///be the secondly selected node. No local variable
   360   ///can be used for this purpose inside the function,
   361   ///because the node selected by button press, and
   362   ///the edge is created by button release. Both of
   363   ///them is different function call.
   364   Gnome::Canvas::Item * target_item;
   365 
   366   ///selected node (for any editing)
   367   Node active_node;
   368 
   369   ///selected edge (for any editing)
   370   Edge active_edge;
   371 
   372   ///the edge that is selected by clicking on the red arrow in the middle of it
   373 
   374   ///This edge is stored only for the purpose of reshape it.
   375   ///That is why it is selected in a different manner.
   376   Edge forming_edge;
   377 
   378   ///Map displayed by label can be edited.
   379   std::string nodemap_to_edit;
   380 
   381   ///Map displayed by label can be edited.
   382   std::string edgemap_to_edit;
   383 
   384   static const int zoom_step = 5;
   385 
   386   ///Is node radius autoscaled
   387   bool autoscale;
   388   
   389   ///Should we track zoomfactor changes
   390   bool zoomtrack;
   391 
   392   ///to store the zoom factor when it was "fixed"
   393   double fixed_zoom_factor;
   394   
   395   ///Minimum node radius
   396   double radius_min;
   397 
   398   ///Maximum node radius
   399   double radius_max;
   400 
   401   ///Node radius unit
   402   double radius_unit;
   403 
   404 private:
   405 
   406   ///reference to the container, in which the canvas is
   407   NoteBookTab & mytab;
   408 
   409   XY calcArrowPos(XY, XY, XY, XY, int);
   410 };
   411 
   412 #endif //GRAPH_DISPLAYER_CANVAS_H