graph_displayer_canvas.h
author hegyi
Thu, 12 Oct 2006 11:39:29 +0000
changeset 160 14a76109b561
parent 157 7e6ad28aeb9e
child 166 302d75b08b27
permissions -rw-r--r--
Node antigravity and edge elasticity based graph layout redesigner.
     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 private:
   272   ///moves node according to the given parameters
   273   void moveNode(double, double,  Gnome::Canvas::Item * item=NULL, Node node=INVALID);
   274 
   275 public:
   276   ///Moves the text to new place
   277   void textReposition(XY);
   278 
   279   ///Activates an edge belonging to an EdgeBase
   280 
   281   ///After we have activated an edge this way,
   282   ///the GDC object will know, which edge is under forming
   283   ///therefore it can redraw the necessary elements on the canvas,
   284   ///for example the text belonging to the \ref EdgeBase can be
   285   ///redrawn (\ref textReposition).
   286   void toggleEdgeActivity(EdgeBase*, bool);
   287 
   288 public:
   289 
   290   ///Returns the actual tool in hand
   291   int getActualTool();
   292 
   293   ///Sets node representation settings
   294   void setView(bool, bool, double, double);
   295 
   296   ///Gets node representation settings
   297   void getView(bool &, bool &, double&, double&);
   298 
   299   ///draws the graph
   300 
   301   ///Called when opening a file.
   302   void drawGraph();
   303 
   304   ///Clears the canvas
   305 
   306   ///It achieves this by deleting all data
   307   ///structure used to help handle the displayed graph.
   308   void clear();
   309 
   310   ///creates a new Nodemap
   311 
   312   ///\param init initial value of the map
   313   ///\param mapname name of new map
   314   int addNewNodeMap(double init,std::string mapname);
   315   ///creates a new Edgemap
   316 
   317   ///\param init initial value of the map
   318   ///\param mapname name of new map
   319   int addNewEdgeMap(double init,std::string mapname);
   320 
   321   void reDesignGraph();
   322 
   323   void get_design_data(double &, double &, int &);
   324   void set_attraction(double);
   325   void set_propulsation(double);
   326   void set_iteration(int);
   327 
   328 private:
   329   ///Deletes the given element.
   330   void deleteItem(Node);
   331   ///Deletes the given element.
   332   void deleteItem(Edge);
   333 
   334 private:
   335 
   336   ///Map of nodes of graph
   337   Graph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
   338 
   339   ///Map of edges of graph
   340   Graph::EdgeMap<EdgeBase*> edgesmap;
   341 
   342   ///Map of texts to write on edges
   343   Graph::EdgeMap<Gnome::Canvas::Text *> edgetextmap;
   344 
   345   ///Map of texts to write on nodes
   346   Graph::NodeMap<Gnome::Canvas::Text *> nodetextmap;
   347 
   348   ///Group of graphical elements of displayed_graph
   349   Gnome::Canvas::Group displayed_graph;
   350 
   351 private:
   352   ///Indicates whether the button of mouse is pressed or not
   353   int isbutton;
   354 
   355   ///Stores the actual tool in hand
   356   int actual_tool;
   357 
   358   ///At this location was the mousebutton pressed.
   359   ///It helps to calculate the distance of dragging.
   360   double clicked_x, clicked_y;
   361 
   362   ///Remembers which Gnome::Canvas::Item was pressed.
   363 
   364   ///this variable is needed, to work on it after selection
   365   Gnome::Canvas::Item * active_item;
   366 
   367   ///Remembers which Gnome::Canvas::Item was pressed.
   368 
   369   ///this variable is used at edge creation, it will
   370   ///be the secondly selected node. No local variable
   371   ///can be used for this purpose inside the function,
   372   ///because the node selected by button press, and
   373   ///the edge is created by button release. Both of
   374   ///them is different function call.
   375   Gnome::Canvas::Item * target_item;
   376 
   377   ///selected node (for any editing)
   378   Node active_node;
   379 
   380   ///selected edge (for any editing)
   381   Edge active_edge;
   382 
   383   ///the edge that is selected by clicking on the red arrow in the middle of it
   384 
   385   ///This edge is stored only for the purpose of reshape it.
   386   ///That is why it is selected in a different manner.
   387   Edge forming_edge;
   388 
   389   ///Map displayed by label can be edited.
   390   std::string nodemap_to_edit;
   391 
   392   ///Map displayed by label can be edited.
   393   std::string edgemap_to_edit;
   394 
   395   static const int zoom_step = 5;
   396 
   397   ///Is node radius autoscaled
   398   bool autoscale;
   399   
   400   ///Should we track zoomfactor changes
   401   bool zoomtrack;
   402 
   403   ///to store the zoom factor when it was "fixed"
   404   double fixed_zoom_factor;
   405   
   406   ///Node radius size
   407   double radius_size;
   408 
   409   ///Edge width
   410   double edge_width;
   411 
   412   ///Iteration number during graph design
   413   int iterations;
   414 
   415   ///Attraction factor during graph design
   416   double attraction;
   417 
   418   ///Propulsation factor during graph design
   419   double propulsation;
   420   
   421 private:
   422 
   423   ///reference to the container, in which the canvas is
   424   NoteBookTab & mytab;
   425 
   426   XY calcArrowPos(XY, XY, XY, XY, int);
   427 };
   428 
   429 #endif //GRAPH_DISPLAYER_CANVAS_H