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