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