graph_displayer_canvas.h
author Akos Ladanyi <ladanyi@tmit.bme.hu>
Mon, 07 Jul 2008 15:20:43 +0100
changeset 3 2cc5ed6e6255
permissions -rw-r--r--
Use hg changeset hash instead of svn revision.
hegyi@1
     1
/* -*- C++ -*-
hegyi@1
     2
 *
hegyi@1
     3
 * This file is a part of LEMON, a generic C++ optimization library
hegyi@1
     4
 *
hegyi@1
     5
 * Copyright (C) 2003-2006
hegyi@1
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
hegyi@1
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
hegyi@1
     8
 *
hegyi@1
     9
 * Permission to use, modify and distribute this software is granted
hegyi@1
    10
 * provided that this copyright notice appears in all copies. For
hegyi@1
    11
 * precise terms see the accompanying LICENSE file.
hegyi@1
    12
 *
hegyi@1
    13
 * This software is provided "AS IS" with no warranty of any kind,
hegyi@1
    14
 * express or implied, and with no claim as to its suitability for any
hegyi@1
    15
 * purpose.
hegyi@1
    16
 *
hegyi@1
    17
 */
hegyi@1
    18
hegyi@1
    19
#ifndef GRAPH_DISPLAYER_CANVAS_H
hegyi@1
    20
#define GRAPH_DISPLAYER_CANVAS_H
hegyi@1
    21
hegyi@1
    22
class NoteBookTab;
hegyi@1
    23
hegyi@1
    24
#include "all_include.h"
hegyi@1
    25
#include <libgnomecanvasmm.h>
hegyi@1
    26
#include <libgnomecanvasmm/polygon.h>
hegyi@1
    27
hegyi@1
    28
///This class is the canvas, on which the digraph can be drawn.
hegyi@1
    29
class DigraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
hegyi@1
    30
{
hegyi@1
    31
  friend class BrokenArc;
hegyi@1
    32
  friend class LoopArc;
hegyi@1
    33
hegyi@1
    34
  class ArcBase : public Gnome::Canvas::Group
hegyi@1
    35
  {
hegyi@1
    36
    protected:
hegyi@1
    37
      ///Reference to the canvas, on which the digraph is drawn.
hegyi@1
    38
hegyi@1
    39
      ///It is needed, because some datas needed from
hegyi@1
    40
      ///digraph can be accessed by this or should be sent
hegyi@1
    41
      ///as parameter, but it would be complicated
hegyi@1
    42
      DigraphDisplayerCanvas& canvas;
hegyi@1
    43
hegyi@1
    44
      ///The arc that the class displays.
hegyi@1
    45
hegyi@1
    46
      ///It is needed, because some datas needed from
hegyi@1
    47
      ///digraph can be accessed by this or should be sent
hegyi@1
    48
      ///as parameter, but it would be complicated
hegyi@1
    49
      Arc arc;
hegyi@1
    50
hegyi@1
    51
      Gnome::Canvas::Polygon arrow;
hegyi@1
    52
hegyi@1
    53
      void drawArrow(XY);
hegyi@1
    54
    public:
hegyi@1
    55
      ArcBase(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
hegyi@1
    56
      virtual ~ArcBase();
hegyi@1
    57
      virtual void draw() = 0;
hegyi@1
    58
      virtual void setLineWidth(int) = 0;
hegyi@1
    59
      virtual void setFillColor(Gdk::Color) = 0;
hegyi@1
    60
      virtual Gnome::Canvas::Item * getLine() = 0;
hegyi@1
    61
  };
hegyi@1
    62
hegyi@1
    63
  ///Arc displayer class
hegyi@1
    64
hegyi@1
    65
  ///This class is responsible for displaying arcs in digraph.
hegyi@1
    66
  ///The displayed arc is broken in the middle. The
hegyi@1
    67
  ///aim of this is to be able to indicate direction of arcs
hegyi@1
    68
  ///and to be able to display more then one arcs between the
hegyi@1
    69
  ///same source and target
hegyi@1
    70
  class BrokenArc : public ArcBase
hegyi@1
    71
  {
hegyi@1
    72
    private:
hegyi@1
    73
      Gnome::Canvas::Line line;
hegyi@1
    74
hegyi@1
    75
      ///Indicates whether the button of mouse is pressed or not at the moment.
hegyi@1
    76
      bool isbutton;
hegyi@1
    77
hegyi@1
    78
      ///At this location was the mousebutton pressed. Horizontal component.
hegyi@1
    79
hegyi@1
    80
      ///It helps to calculate the
hegyi@1
    81
      ///distance of dragging.
hegyi@1
    82
      double clicked_x;
hegyi@1
    83
hegyi@1
    84
      ///At this location was the mousebutton pressed. Vertical component.
hegyi@1
    85
hegyi@1
    86
      ///It helps to calculate the
hegyi@1
    87
      ///distance of dragging.
hegyi@1
    88
      double clicked_y;
hegyi@1
    89
hegyi@1
    90
      ///event handler for forming broken arcs
hegyi@1
    91
hegyi@1
    92
      ///\param event the
hegyi@1
    93
      ///event to handle
hegyi@1
    94
      bool arcFormerEventHandler(GdkEvent* event);
hegyi@1
    95
hegyi@1
    96
    public:
hegyi@1
    97
      ///Constructor of broken arc class.
hegyi@1
    98
hegyi@1
    99
      ///\param g the group to which the arc belongs
hegyi@1
   100
      ///\param _arc the represented arc
hegyi@1
   101
      ///\param gc the canvas
hegyi@1
   102
      BrokenArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
hegyi@1
   103
hegyi@1
   104
      ///Destructor of broken arc class
hegyi@1
   105
hegyi@1
   106
      ///Frees up
hegyi@1
   107
      ///reserved memory
hegyi@1
   108
      ~BrokenArc();
hegyi@1
   109
hegyi@1
   110
      ///The function that draws the arc based on collected data
hegyi@1
   111
      void draw();
hegyi@1
   112
hegyi@1
   113
      void setLineWidth(int);
hegyi@1
   114
      void setFillColor(Gdk::Color);
hegyi@1
   115
hegyi@1
   116
      Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
hegyi@1
   117
  };
hegyi@1
   118
hegyi@1
   119
  class LoopArc : public ArcBase
hegyi@1
   120
  {
hegyi@1
   121
    private:
hegyi@1
   122
      Gnome::Canvas::Ellipse line;
hegyi@1
   123
      bool arcFormerEventHandler(GdkEvent* e);
hegyi@1
   124
      bool isbutton;
hegyi@1
   125
    public:
hegyi@1
   126
      LoopArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
hegyi@1
   127
      ~LoopArc();
hegyi@1
   128
      void draw();
hegyi@1
   129
      void setLineWidth(int);
hegyi@1
   130
      void setFillColor(Gdk::Color);
hegyi@1
   131
      Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
hegyi@1
   132
  };
hegyi@1
   133
hegyi@1
   134
  ///Type of canvas, on which the digraph is drawn
hegyi@1
   135
  typedef Gnome::Canvas::CanvasAA Parent;
hegyi@1
   136
hegyi@1
   137
public:
hegyi@1
   138
  ///Constructor
hegyi@1
   139
hegyi@1
   140
  ///\param nbt the tab of the window, in which the digraph is displayed
hegyi@1
   141
  DigraphDisplayerCanvas(NoteBookTab & nbt);
hegyi@1
   142
hegyi@1
   143
  ///destructor of the class
hegyi@1
   144
  virtual ~DigraphDisplayerCanvas();
hegyi@1
   145
hegyi@1
   146
  ///Returns a color of the rainbow based on a map value and the min and max value of the given map
hegyi@1
   147
hegyi@1
   148
  ///min and max is purple, between them there is a linear assign
hegyi@1
   149
  Gdk::Color rainbowColorCounter(double, double, double);
hegyi@1
   150
hegyi@1
   151
  ///Changes the width of arc(s) according to the given map.
hegyi@1
   152
hegyi@1
   153
  ///\param mapname is the name of the map which contains the values to be set
hegyi@1
   154
  ///\param arc if it is given, only the width of the given arc will be set, instead of all of them.
hegyi@1
   155
  int changeArcWidth (std::string mapname, Arc arc=INVALID);
hegyi@1
   156
hegyi@1
   157
  ///Resets width of arc(s) to the default value
hegyi@1
   158
hegyi@1
   159
  ///\param arc if it is given, only the width of the
hegyi@1
   160
  ///given arc will be reset, instead of all of them.
hegyi@1
   161
  int resetArcWidth (Arc arc=INVALID);
hegyi@1
   162
hegyi@1
   163
  ///Changes the color of arc(s) according to the given map.
hegyi@1
   164
hegyi@1
   165
  ///\param mapname is the name of the map which contains the new values
hegyi@1
   166
  ///\param arc if it is given, only the color of the given arc will be set, instead of all of them.
hegyi@1
   167
  int changeArcColor (std::string mapname, Arc arc=INVALID);
hegyi@1
   168
hegyi@1
   169
  ///Resets color of arc(s) to the default value
hegyi@1
   170
hegyi@1
   171
  ///\param arc if it is given, only the color of the
hegyi@1
   172
  ///given arc will be reset, instead of all of them.
hegyi@1
   173
  int resetArcColor (Arc arc=INVALID);
hegyi@1
   174
hegyi@1
   175
  ///Changes the label of arc(s) according to the given map.
hegyi@1
   176
hegyi@1
   177
  ///\param mapname is the name of the map which contains the new values
hegyi@1
   178
  ///\param arc if it is given, only the label of the given arc will be set, instead of all of them.
hegyi@1
   179
  int changeArcText (std::string mapname, Arc arc=INVALID);
hegyi@1
   180
hegyi@1
   181
  ///Resets label of arc(s) to the default value
hegyi@1
   182
hegyi@1
   183
  ///\param arc if it is given, only the color of the
hegyi@1
   184
  ///given arc will be reset, instead of all of them.
hegyi@1
   185
  int resetArcText (Arc arc=INVALID);
hegyi@1
   186
hegyi@1
   187
  ///Changes the radius of node(s) according to the given map.
hegyi@1
   188
hegyi@1
   189
  ///\param mapname is the name of the map which contains the new values
hegyi@1
   190
  ///\param node if it is given, only the radius of the given node will be set, instead of all of them.
hegyi@1
   191
  int changeNodeRadius (std::string mapname, Node node=INVALID);
hegyi@1
   192
hegyi@1
   193
  ///Resets radius of node(s) to the default value
hegyi@1
   194
hegyi@1
   195
  ///\param node if it is given, only the radius of the
hegyi@1
   196
  ///given node will be reset, instead of all of them.
hegyi@1
   197
  int resetNodeRadius (Node node=INVALID);
hegyi@1
   198
hegyi@1
   199
  ///Changes the color of node(s) according to the given map.
hegyi@1
   200
hegyi@1
   201
  ///\param mapname is the name of the map which contains the new values
hegyi@1
   202
  ///\param node if it is given, only the color of the given node will be set, instead of all of them.
hegyi@1
   203
  int changeNodeColor (std::string mapname, Node node=INVALID);
hegyi@1
   204
hegyi@1
   205
  ///Resets color of node(s) to the default value
hegyi@1
   206
hegyi@1
   207
  ///\param node if it is given, only the color of the
hegyi@1
   208
  ///given node will be reset, instead of all of them.
hegyi@1
   209
  int resetNodeColor (Node node=INVALID);
hegyi@1
   210
hegyi@1
   211
  ///Changes the label of node(s) according to the given map.
hegyi@1
   212
hegyi@1
   213
  ///\param mapname is the name of the map which contains the new values
hegyi@1
   214
  ///\param node if it is given, only the label of the given node will be set, instead of all of them.
hegyi@1
   215
  int changeNodeText (std::string mapname, Node node=INVALID);
hegyi@1
   216
hegyi@1
   217
  ///Resets label of node(s) to the default value
hegyi@1
   218
hegyi@1
   219
  ///\param node if it is given, only the label of the
hegyi@1
   220
  ///given node will be reset, instead of all of them.
hegyi@1
   221
  int resetNodeText (Node node=INVALID);
hegyi@1
   222
hegyi@1
   223
  ///This function is called, when any of the displayed attributes have to be updated, or changed
hegyi@1
   224
hegyi@1
   225
  ///\param itisarc if true, arc property has to be changed, else node property
hegyi@1
   226
  ///\param prop the id of property that has to changed or updated
hegyi@1
   227
  void propertyChange(bool itisarc, int prop);
hegyi@1
   228
hegyi@1
   229
  ///updates the given property
hegyi@1
   230
hegyi@1
   231
  ///\param arc if it is not INVALID, only the property of the given arc will be updated, instead of all of them
hegyi@1
   232
  ///\param prop the property to update
hegyi@1
   233
  void propertyUpdate(Arc arc, int prop);
hegyi@1
   234
hegyi@1
   235
  ///updates the given property
hegyi@1
   236
hegyi@1
   237
  ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them
hegyi@1
   238
  ///\param prop the property to update
hegyi@1
   239
  void propertyUpdate(Node node, int prop);
hegyi@1
   240
hegyi@1
   241
  ///updates all the property for the given arc
hegyi@1
   242
  void propertyUpdate(Arc);
hegyi@1
   243
hegyi@1
   244
  ///updates all the property for the given node
hegyi@1
   245
  void propertyUpdate(Node);
hegyi@1
   246
hegyi@1
   247
  ///Callback for 'ViewZoomIn' action.
hegyi@1
   248
  virtual void zoomIn();
hegyi@1
   249
  ///Callback for 'ViewZoomOut' action.
hegyi@1
   250
  virtual void zoomOut();
hegyi@1
   251
  ///Callback for 'ViewZoomFit' action.
hegyi@1
   252
  virtual void zoomFit();
hegyi@1
   253
  ///Callback for 'ViewZoom100' action.
hegyi@1
   254
  virtual void zoom100();
hegyi@1
   255
  ///Sets the scroll region of the convas to the bounding box of the digraph.
hegyi@1
   256
  void updateScrollRegion();
hegyi@1
   257
hegyi@1
   258
  ///This function changes the tool in the digraph-editor's hand
hegyi@1
   259
  void changeEditorialTool(int);
hegyi@1
   260
hegyi@1
   261
protected:
hegyi@1
   262
hegyi@1
   263
  //maximizing, minimizing, restoring window, etc.
hegyi@1
   264
  virtual bool on_expose_event(GdkEventExpose *);
hegyi@1
   265
hegyi@1
   266
private:
hegyi@1
   267
hegyi@1
   268
  ///This function is responsible for the correct
hegyi@1
   269
  ///reaction of any action happened in the territory
hegyi@1
   270
  ///of the canvas
hegyi@1
   271
  ///DEPRECATED!!!!
hegyi@1
   272
  bool eventHandler(GdkEvent* e, Node n);
hegyi@1
   273
hegyi@1
   274
  ///actual event handler
hegyi@1
   275
  ///
hegyi@1
   276
  ///Actual event handler should be stored, to be able to disconnect it and later reconnect it.
hegyi@1
   277
  sigc::connection actual_handler;
hegyi@1
   278
hegyi@1
   279
  ///event handler for the case when move-tool is active
hegyi@1
   280
  bool moveEventHandler(GdkEvent*);
hegyi@1
   281
  ///event handler for the case when create_node-tool is active
hegyi@1
   282
  bool createNodeEventHandler(GdkEvent*);
hegyi@1
   283
  ///event handler for the case when create_arc-tool is active
hegyi@1
   284
  bool createArcEventHandler(GdkEvent*);
hegyi@1
   285
  ///event handler for the case when eraser-tool is active
hegyi@1
   286
  bool eraserEventHandler(GdkEvent*);
hegyi@1
   287
  ///event handler for the case when map editor tool is active
hegyi@1
   288
  bool mapEditEventHandler(GdkEvent*);
hegyi@1
   289
  ///event handler for the case when user scrolls the mouse
hegyi@1
   290
  bool scrollEventHandler(GdkEvent*);
hegyi@1
   291
hegyi@1
   292
private:
hegyi@1
   293
  ///moves node according to the given parameters
hegyi@1
   294
  void moveNode(double, double,  Gnome::Canvas::Item * item=NULL, Node node=INVALID);
hegyi@1
   295
hegyi@1
   296
public:
hegyi@1
   297
  ///Moves the text to new place
hegyi@1
   298
  void textReposition(XY);
hegyi@1
   299
hegyi@1
   300
  ///Activates an arc belonging to an ArcBase
hegyi@1
   301
hegyi@1
   302
  ///After we have activated an arc this way,
hegyi@1
   303
  ///the GDC object will know, which arc is under forming
hegyi@1
   304
  ///therefore it can redraw the necessary elements on the canvas,
hegyi@1
   305
  ///for example the text belonging to the \ref ArcBase can be
hegyi@1
   306
  ///redrawn (\ref textReposition).
hegyi@1
   307
  void toggleArcActivity(ArcBase*, bool);
hegyi@1
   308
hegyi@1
   309
public:
hegyi@1
   310
hegyi@1
   311
  ///Returns the actual tool in hand
hegyi@1
   312
  int getActualTool();
hegyi@1
   313
hegyi@1
   314
  ///Sets node representation settings
hegyi@1
   315
  void setView(bool, bool, double, double);
hegyi@1
   316
hegyi@1
   317
  ///Gets node representation settings
hegyi@1
   318
  void getView(bool &, bool &, double&, double&);
hegyi@1
   319
hegyi@1
   320
  ///draws the digraph
hegyi@1
   321
hegyi@1
   322
  ///Called when opening a file.
hegyi@1
   323
  void drawDigraph();
hegyi@1
   324
hegyi@1
   325
  ///Clears the canvas
hegyi@1
   326
hegyi@1
   327
  ///It achieves this by deleting all data
hegyi@1
   328
  ///structure used to help handle the displayed digraph.
hegyi@1
   329
  void clear();
hegyi@1
   330
hegyi@1
   331
  ///creates a new Nodemap
hegyi@1
   332
hegyi@1
   333
  ///\param init initial value of the map
hegyi@1
   334
  ///\param mapname name of new map
hegyi@1
   335
  int addNewNodeMap(double init,std::string mapname);
hegyi@1
   336
  ///creates a new Arcmap
hegyi@1
   337
hegyi@1
   338
  ///\param init initial value of the map
hegyi@1
   339
  ///\param mapname name of new map
hegyi@1
   340
  int addNewArcMap(double init,std::string mapname);
hegyi@1
   341
hegyi@1
   342
  void reDesignDigraph();
hegyi@1
   343
hegyi@1
   344
  ///Show whether the digraph is already drawn.
hegyi@1
   345
  bool is_drawn;
hegyi@1
   346
hegyi@1
   347
private:
hegyi@1
   348
  ///Deletes the given element.
hegyi@1
   349
  void deleteItem(Node);
hegyi@1
   350
  ///Deletes the given element.
hegyi@1
   351
  void deleteItem(Arc);
hegyi@1
   352
hegyi@1
   353
private:
hegyi@1
   354
hegyi@1
   355
  ///Map of nodes of digraph
hegyi@1
   356
  Digraph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
hegyi@1
   357
hegyi@1
   358
  ///Map of arcs of digraph
hegyi@1
   359
  Digraph::ArcMap<ArcBase*> arcsmap;
hegyi@1
   360
hegyi@1
   361
  ///Map of texts to write on arcs
hegyi@1
   362
  Digraph::ArcMap<Gnome::Canvas::Text *> arctextmap;
hegyi@1
   363
hegyi@1
   364
  ///Map of texts to write on nodes
hegyi@1
   365
  Digraph::NodeMap<Gnome::Canvas::Text *> nodetextmap;
hegyi@1
   366
hegyi@1
   367
  ///Group of digraphical elements of displayed_graph
hegyi@1
   368
  Gnome::Canvas::Group displayed_graph;
hegyi@1
   369
hegyi@1
   370
private:
hegyi@1
   371
  ///Indicates whether the button of mouse is pressed or not
hegyi@1
   372
  int isbutton;
hegyi@1
   373
hegyi@1
   374
  ///Stores the actual tool in hand
hegyi@1
   375
  int actual_tool;
hegyi@1
   376
hegyi@1
   377
  ///At this location was the mousebutton pressed.
hegyi@1
   378
  ///It helps to calculate the distance of dragging.
hegyi@1
   379
  double clicked_x, clicked_y;
hegyi@1
   380
hegyi@1
   381
  ///Remembers which Gnome::Canvas::Item was pressed.
hegyi@1
   382
hegyi@1
   383
  ///this variable is needed, to work on it after selection
hegyi@1
   384
  Gnome::Canvas::Item * active_item;
hegyi@1
   385
hegyi@1
   386
  ///Remembers which Gnome::Canvas::Item was pressed.
hegyi@1
   387
hegyi@1
   388
  ///this variable is used at arc creation, it will
hegyi@1
   389
  ///be the secondly selected node. No local variable
hegyi@1
   390
  ///can be used for this purpose inside the function,
hegyi@1
   391
  ///because the node selected by button press, and
hegyi@1
   392
  ///the arc is created by button release. Both of
hegyi@1
   393
  ///them is different function call.
hegyi@1
   394
  Gnome::Canvas::Item * target_item;
hegyi@1
   395
hegyi@1
   396
  ///selected node (for any editing)
hegyi@1
   397
  Node active_node;
hegyi@1
   398
hegyi@1
   399
  ///selected arc (for any editing)
hegyi@1
   400
  Arc active_arc;
hegyi@1
   401
hegyi@1
   402
  ///the arc that is selected by clicking on the red arrow in the middle of it
hegyi@1
   403
hegyi@1
   404
  ///This arc is stored only for the purpose of reshape it.
hegyi@1
   405
  ///That is why it is selected in a different manner.
hegyi@1
   406
  Arc forming_arc;
hegyi@1
   407
hegyi@1
   408
  ///Map displayed by label can be edited.
hegyi@1
   409
  std::string nodemap_to_edit;
hegyi@1
   410
hegyi@1
   411
  ///Map displayed by label can be edited.
hegyi@1
   412
  std::string arcmap_to_edit;
hegyi@1
   413
hegyi@1
   414
  static const int zoom_step = 5;
hegyi@1
   415
hegyi@1
   416
  ///Is node radius autoscaled
hegyi@1
   417
  bool autoscale;
hegyi@1
   418
  
hegyi@1
   419
  ///Should we track zoomfactor changes
hegyi@1
   420
  bool zoomtrack;
hegyi@1
   421
hegyi@1
   422
  ///to store the zoom factor when it was "fixed"
hegyi@1
   423
  double fixed_zoom_factor;
hegyi@1
   424
  
hegyi@1
   425
  ///Node radius size
hegyi@1
   426
  double radius_size;
hegyi@1
   427
hegyi@1
   428
  ///Arc width
hegyi@1
   429
  double arc_width;
hegyi@1
   430
hegyi@1
   431
  ///Was redesign run on this digraph already?
hegyi@1
   432
  ///
hegyi@1
   433
  ///If not, the layout will be modified randomly
hegyi@1
   434
  ///to avoid frozen layout because of wrong
hegyi@1
   435
  ///initial state
hegyi@1
   436
  bool was_redesigned;
hegyi@1
   437
  
hegyi@1
   438
private:
hegyi@1
   439
hegyi@1
   440
  ///reference to the container, in which the canvas is
hegyi@1
   441
  NoteBookTab & mytab;
hegyi@1
   442
hegyi@1
   443
  XY calcArrowPos(XY, XY, XY, XY, int);
hegyi@1
   444
hegyi@1
   445
  bool background_set;
hegyi@1
   446
  Glib::RefPtr<Gdk::Pixbuf> refBackground;
hegyi@1
   447
  Gnome::Canvas::Pixbuf *background;
hegyi@1
   448
public:
hegyi@1
   449
  void setBackground();
hegyi@1
   450
};
hegyi@1
   451
hegyi@1
   452
#endif //GRAPH_DISPLAYER_CANVAS_H