graph_displayer_canvas.h
changeset 1 67188bd752db
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/graph_displayer_canvas.h	Mon Jul 07 08:10:39 2008 -0500
     1.3 @@ -0,0 +1,452 @@
     1.4 +/* -*- C++ -*-
     1.5 + *
     1.6 + * This file is a part of LEMON, a generic C++ optimization library
     1.7 + *
     1.8 + * Copyright (C) 2003-2006
     1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11 + *
    1.12 + * Permission to use, modify and distribute this software is granted
    1.13 + * provided that this copyright notice appears in all copies. For
    1.14 + * precise terms see the accompanying LICENSE file.
    1.15 + *
    1.16 + * This software is provided "AS IS" with no warranty of any kind,
    1.17 + * express or implied, and with no claim as to its suitability for any
    1.18 + * purpose.
    1.19 + *
    1.20 + */
    1.21 +
    1.22 +#ifndef GRAPH_DISPLAYER_CANVAS_H
    1.23 +#define GRAPH_DISPLAYER_CANVAS_H
    1.24 +
    1.25 +class NoteBookTab;
    1.26 +
    1.27 +#include "all_include.h"
    1.28 +#include <libgnomecanvasmm.h>
    1.29 +#include <libgnomecanvasmm/polygon.h>
    1.30 +
    1.31 +///This class is the canvas, on which the digraph can be drawn.
    1.32 +class DigraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
    1.33 +{
    1.34 +  friend class BrokenArc;
    1.35 +  friend class LoopArc;
    1.36 +
    1.37 +  class ArcBase : public Gnome::Canvas::Group
    1.38 +  {
    1.39 +    protected:
    1.40 +      ///Reference to the canvas, on which the digraph is drawn.
    1.41 +
    1.42 +      ///It is needed, because some datas needed from
    1.43 +      ///digraph can be accessed by this or should be sent
    1.44 +      ///as parameter, but it would be complicated
    1.45 +      DigraphDisplayerCanvas& canvas;
    1.46 +
    1.47 +      ///The arc that the class displays.
    1.48 +
    1.49 +      ///It is needed, because some datas needed from
    1.50 +      ///digraph can be accessed by this or should be sent
    1.51 +      ///as parameter, but it would be complicated
    1.52 +      Arc arc;
    1.53 +
    1.54 +      Gnome::Canvas::Polygon arrow;
    1.55 +
    1.56 +      void drawArrow(XY);
    1.57 +    public:
    1.58 +      ArcBase(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
    1.59 +      virtual ~ArcBase();
    1.60 +      virtual void draw() = 0;
    1.61 +      virtual void setLineWidth(int) = 0;
    1.62 +      virtual void setFillColor(Gdk::Color) = 0;
    1.63 +      virtual Gnome::Canvas::Item * getLine() = 0;
    1.64 +  };
    1.65 +
    1.66 +  ///Arc displayer class
    1.67 +
    1.68 +  ///This class is responsible for displaying arcs in digraph.
    1.69 +  ///The displayed arc is broken in the middle. The
    1.70 +  ///aim of this is to be able to indicate direction of arcs
    1.71 +  ///and to be able to display more then one arcs between the
    1.72 +  ///same source and target
    1.73 +  class BrokenArc : public ArcBase
    1.74 +  {
    1.75 +    private:
    1.76 +      Gnome::Canvas::Line line;
    1.77 +
    1.78 +      ///Indicates whether the button of mouse is pressed or not at the moment.
    1.79 +      bool isbutton;
    1.80 +
    1.81 +      ///At this location was the mousebutton pressed. Horizontal component.
    1.82 +
    1.83 +      ///It helps to calculate the
    1.84 +      ///distance of dragging.
    1.85 +      double clicked_x;
    1.86 +
    1.87 +      ///At this location was the mousebutton pressed. Vertical component.
    1.88 +
    1.89 +      ///It helps to calculate the
    1.90 +      ///distance of dragging.
    1.91 +      double clicked_y;
    1.92 +
    1.93 +      ///event handler for forming broken arcs
    1.94 +
    1.95 +      ///\param event the
    1.96 +      ///event to handle
    1.97 +      bool arcFormerEventHandler(GdkEvent* event);
    1.98 +
    1.99 +    public:
   1.100 +      ///Constructor of broken arc class.
   1.101 +
   1.102 +      ///\param g the group to which the arc belongs
   1.103 +      ///\param _arc the represented arc
   1.104 +      ///\param gc the canvas
   1.105 +      BrokenArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
   1.106 +
   1.107 +      ///Destructor of broken arc class
   1.108 +
   1.109 +      ///Frees up
   1.110 +      ///reserved memory
   1.111 +      ~BrokenArc();
   1.112 +
   1.113 +      ///The function that draws the arc based on collected data
   1.114 +      void draw();
   1.115 +
   1.116 +      void setLineWidth(int);
   1.117 +      void setFillColor(Gdk::Color);
   1.118 +
   1.119 +      Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
   1.120 +  };
   1.121 +
   1.122 +  class LoopArc : public ArcBase
   1.123 +  {
   1.124 +    private:
   1.125 +      Gnome::Canvas::Ellipse line;
   1.126 +      bool arcFormerEventHandler(GdkEvent* e);
   1.127 +      bool isbutton;
   1.128 +    public:
   1.129 +      LoopArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&);
   1.130 +      ~LoopArc();
   1.131 +      void draw();
   1.132 +      void setLineWidth(int);
   1.133 +      void setFillColor(Gdk::Color);
   1.134 +      Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); };
   1.135 +  };
   1.136 +
   1.137 +  ///Type of canvas, on which the digraph is drawn
   1.138 +  typedef Gnome::Canvas::CanvasAA Parent;
   1.139 +
   1.140 +public:
   1.141 +  ///Constructor
   1.142 +
   1.143 +  ///\param nbt the tab of the window, in which the digraph is displayed
   1.144 +  DigraphDisplayerCanvas(NoteBookTab & nbt);
   1.145 +
   1.146 +  ///destructor of the class
   1.147 +  virtual ~DigraphDisplayerCanvas();
   1.148 +
   1.149 +  ///Returns a color of the rainbow based on a map value and the min and max value of the given map
   1.150 +
   1.151 +  ///min and max is purple, between them there is a linear assign
   1.152 +  Gdk::Color rainbowColorCounter(double, double, double);
   1.153 +
   1.154 +  ///Changes the width of arc(s) according to the given map.
   1.155 +
   1.156 +  ///\param mapname is the name of the map which contains the values to be set
   1.157 +  ///\param arc if it is given, only the width of the given arc will be set, instead of all of them.
   1.158 +  int changeArcWidth (std::string mapname, Arc arc=INVALID);
   1.159 +
   1.160 +  ///Resets width of arc(s) to the default value
   1.161 +
   1.162 +  ///\param arc if it is given, only the width of the
   1.163 +  ///given arc will be reset, instead of all of them.
   1.164 +  int resetArcWidth (Arc arc=INVALID);
   1.165 +
   1.166 +  ///Changes the color of arc(s) according to the given map.
   1.167 +
   1.168 +  ///\param mapname is the name of the map which contains the new values
   1.169 +  ///\param arc if it is given, only the color of the given arc will be set, instead of all of them.
   1.170 +  int changeArcColor (std::string mapname, Arc arc=INVALID);
   1.171 +
   1.172 +  ///Resets color of arc(s) to the default value
   1.173 +
   1.174 +  ///\param arc if it is given, only the color of the
   1.175 +  ///given arc will be reset, instead of all of them.
   1.176 +  int resetArcColor (Arc arc=INVALID);
   1.177 +
   1.178 +  ///Changes the label of arc(s) according to the given map.
   1.179 +
   1.180 +  ///\param mapname is the name of the map which contains the new values
   1.181 +  ///\param arc if it is given, only the label of the given arc will be set, instead of all of them.
   1.182 +  int changeArcText (std::string mapname, Arc arc=INVALID);
   1.183 +
   1.184 +  ///Resets label of arc(s) to the default value
   1.185 +
   1.186 +  ///\param arc if it is given, only the color of the
   1.187 +  ///given arc will be reset, instead of all of them.
   1.188 +  int resetArcText (Arc arc=INVALID);
   1.189 +
   1.190 +  ///Changes the radius of node(s) according to the given map.
   1.191 +
   1.192 +  ///\param mapname is the name of the map which contains the new values
   1.193 +  ///\param node if it is given, only the radius of the given node will be set, instead of all of them.
   1.194 +  int changeNodeRadius (std::string mapname, Node node=INVALID);
   1.195 +
   1.196 +  ///Resets radius of node(s) to the default value
   1.197 +
   1.198 +  ///\param node if it is given, only the radius of the
   1.199 +  ///given node will be reset, instead of all of them.
   1.200 +  int resetNodeRadius (Node node=INVALID);
   1.201 +
   1.202 +  ///Changes the color of node(s) according to the given map.
   1.203 +
   1.204 +  ///\param mapname is the name of the map which contains the new values
   1.205 +  ///\param node if it is given, only the color of the given node will be set, instead of all of them.
   1.206 +  int changeNodeColor (std::string mapname, Node node=INVALID);
   1.207 +
   1.208 +  ///Resets color of node(s) to the default value
   1.209 +
   1.210 +  ///\param node if it is given, only the color of the
   1.211 +  ///given node will be reset, instead of all of them.
   1.212 +  int resetNodeColor (Node node=INVALID);
   1.213 +
   1.214 +  ///Changes the label of node(s) according to the given map.
   1.215 +
   1.216 +  ///\param mapname is the name of the map which contains the new values
   1.217 +  ///\param node if it is given, only the label of the given node will be set, instead of all of them.
   1.218 +  int changeNodeText (std::string mapname, Node node=INVALID);
   1.219 +
   1.220 +  ///Resets label of node(s) to the default value
   1.221 +
   1.222 +  ///\param node if it is given, only the label of the
   1.223 +  ///given node will be reset, instead of all of them.
   1.224 +  int resetNodeText (Node node=INVALID);
   1.225 +
   1.226 +  ///This function is called, when any of the displayed attributes have to be updated, or changed
   1.227 +
   1.228 +  ///\param itisarc if true, arc property has to be changed, else node property
   1.229 +  ///\param prop the id of property that has to changed or updated
   1.230 +  void propertyChange(bool itisarc, int prop);
   1.231 +
   1.232 +  ///updates the given property
   1.233 +
   1.234 +  ///\param arc if it is not INVALID, only the property of the given arc will be updated, instead of all of them
   1.235 +  ///\param prop the property to update
   1.236 +  void propertyUpdate(Arc arc, int prop);
   1.237 +
   1.238 +  ///updates the given property
   1.239 +
   1.240 +  ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them
   1.241 +  ///\param prop the property to update
   1.242 +  void propertyUpdate(Node node, int prop);
   1.243 +
   1.244 +  ///updates all the property for the given arc
   1.245 +  void propertyUpdate(Arc);
   1.246 +
   1.247 +  ///updates all the property for the given node
   1.248 +  void propertyUpdate(Node);
   1.249 +
   1.250 +  ///Callback for 'ViewZoomIn' action.
   1.251 +  virtual void zoomIn();
   1.252 +  ///Callback for 'ViewZoomOut' action.
   1.253 +  virtual void zoomOut();
   1.254 +  ///Callback for 'ViewZoomFit' action.
   1.255 +  virtual void zoomFit();
   1.256 +  ///Callback for 'ViewZoom100' action.
   1.257 +  virtual void zoom100();
   1.258 +  ///Sets the scroll region of the convas to the bounding box of the digraph.
   1.259 +  void updateScrollRegion();
   1.260 +
   1.261 +  ///This function changes the tool in the digraph-editor's hand
   1.262 +  void changeEditorialTool(int);
   1.263 +
   1.264 +protected:
   1.265 +
   1.266 +  //maximizing, minimizing, restoring window, etc.
   1.267 +  virtual bool on_expose_event(GdkEventExpose *);
   1.268 +
   1.269 +private:
   1.270 +
   1.271 +  ///This function is responsible for the correct
   1.272 +  ///reaction of any action happened in the territory
   1.273 +  ///of the canvas
   1.274 +  ///DEPRECATED!!!!
   1.275 +  bool eventHandler(GdkEvent* e, Node n);
   1.276 +
   1.277 +  ///actual event handler
   1.278 +  ///
   1.279 +  ///Actual event handler should be stored, to be able to disconnect it and later reconnect it.
   1.280 +  sigc::connection actual_handler;
   1.281 +
   1.282 +  ///event handler for the case when move-tool is active
   1.283 +  bool moveEventHandler(GdkEvent*);
   1.284 +  ///event handler for the case when create_node-tool is active
   1.285 +  bool createNodeEventHandler(GdkEvent*);
   1.286 +  ///event handler for the case when create_arc-tool is active
   1.287 +  bool createArcEventHandler(GdkEvent*);
   1.288 +  ///event handler for the case when eraser-tool is active
   1.289 +  bool eraserEventHandler(GdkEvent*);
   1.290 +  ///event handler for the case when map editor tool is active
   1.291 +  bool mapEditEventHandler(GdkEvent*);
   1.292 +  ///event handler for the case when user scrolls the mouse
   1.293 +  bool scrollEventHandler(GdkEvent*);
   1.294 +
   1.295 +private:
   1.296 +  ///moves node according to the given parameters
   1.297 +  void moveNode(double, double,  Gnome::Canvas::Item * item=NULL, Node node=INVALID);
   1.298 +
   1.299 +public:
   1.300 +  ///Moves the text to new place
   1.301 +  void textReposition(XY);
   1.302 +
   1.303 +  ///Activates an arc belonging to an ArcBase
   1.304 +
   1.305 +  ///After we have activated an arc this way,
   1.306 +  ///the GDC object will know, which arc is under forming
   1.307 +  ///therefore it can redraw the necessary elements on the canvas,
   1.308 +  ///for example the text belonging to the \ref ArcBase can be
   1.309 +  ///redrawn (\ref textReposition).
   1.310 +  void toggleArcActivity(ArcBase*, bool);
   1.311 +
   1.312 +public:
   1.313 +
   1.314 +  ///Returns the actual tool in hand
   1.315 +  int getActualTool();
   1.316 +
   1.317 +  ///Sets node representation settings
   1.318 +  void setView(bool, bool, double, double);
   1.319 +
   1.320 +  ///Gets node representation settings
   1.321 +  void getView(bool &, bool &, double&, double&);
   1.322 +
   1.323 +  ///draws the digraph
   1.324 +
   1.325 +  ///Called when opening a file.
   1.326 +  void drawDigraph();
   1.327 +
   1.328 +  ///Clears the canvas
   1.329 +
   1.330 +  ///It achieves this by deleting all data
   1.331 +  ///structure used to help handle the displayed digraph.
   1.332 +  void clear();
   1.333 +
   1.334 +  ///creates a new Nodemap
   1.335 +
   1.336 +  ///\param init initial value of the map
   1.337 +  ///\param mapname name of new map
   1.338 +  int addNewNodeMap(double init,std::string mapname);
   1.339 +  ///creates a new Arcmap
   1.340 +
   1.341 +  ///\param init initial value of the map
   1.342 +  ///\param mapname name of new map
   1.343 +  int addNewArcMap(double init,std::string mapname);
   1.344 +
   1.345 +  void reDesignDigraph();
   1.346 +
   1.347 +  ///Show whether the digraph is already drawn.
   1.348 +  bool is_drawn;
   1.349 +
   1.350 +private:
   1.351 +  ///Deletes the given element.
   1.352 +  void deleteItem(Node);
   1.353 +  ///Deletes the given element.
   1.354 +  void deleteItem(Arc);
   1.355 +
   1.356 +private:
   1.357 +
   1.358 +  ///Map of nodes of digraph
   1.359 +  Digraph::NodeMap<Gnome::Canvas::Ellipse *> nodesmap;
   1.360 +
   1.361 +  ///Map of arcs of digraph
   1.362 +  Digraph::ArcMap<ArcBase*> arcsmap;
   1.363 +
   1.364 +  ///Map of texts to write on arcs
   1.365 +  Digraph::ArcMap<Gnome::Canvas::Text *> arctextmap;
   1.366 +
   1.367 +  ///Map of texts to write on nodes
   1.368 +  Digraph::NodeMap<Gnome::Canvas::Text *> nodetextmap;
   1.369 +
   1.370 +  ///Group of digraphical elements of displayed_graph
   1.371 +  Gnome::Canvas::Group displayed_graph;
   1.372 +
   1.373 +private:
   1.374 +  ///Indicates whether the button of mouse is pressed or not
   1.375 +  int isbutton;
   1.376 +
   1.377 +  ///Stores the actual tool in hand
   1.378 +  int actual_tool;
   1.379 +
   1.380 +  ///At this location was the mousebutton pressed.
   1.381 +  ///It helps to calculate the distance of dragging.
   1.382 +  double clicked_x, clicked_y;
   1.383 +
   1.384 +  ///Remembers which Gnome::Canvas::Item was pressed.
   1.385 +
   1.386 +  ///this variable is needed, to work on it after selection
   1.387 +  Gnome::Canvas::Item * active_item;
   1.388 +
   1.389 +  ///Remembers which Gnome::Canvas::Item was pressed.
   1.390 +
   1.391 +  ///this variable is used at arc creation, it will
   1.392 +  ///be the secondly selected node. No local variable
   1.393 +  ///can be used for this purpose inside the function,
   1.394 +  ///because the node selected by button press, and
   1.395 +  ///the arc is created by button release. Both of
   1.396 +  ///them is different function call.
   1.397 +  Gnome::Canvas::Item * target_item;
   1.398 +
   1.399 +  ///selected node (for any editing)
   1.400 +  Node active_node;
   1.401 +
   1.402 +  ///selected arc (for any editing)
   1.403 +  Arc active_arc;
   1.404 +
   1.405 +  ///the arc that is selected by clicking on the red arrow in the middle of it
   1.406 +
   1.407 +  ///This arc is stored only for the purpose of reshape it.
   1.408 +  ///That is why it is selected in a different manner.
   1.409 +  Arc forming_arc;
   1.410 +
   1.411 +  ///Map displayed by label can be edited.
   1.412 +  std::string nodemap_to_edit;
   1.413 +
   1.414 +  ///Map displayed by label can be edited.
   1.415 +  std::string arcmap_to_edit;
   1.416 +
   1.417 +  static const int zoom_step = 5;
   1.418 +
   1.419 +  ///Is node radius autoscaled
   1.420 +  bool autoscale;
   1.421 +  
   1.422 +  ///Should we track zoomfactor changes
   1.423 +  bool zoomtrack;
   1.424 +
   1.425 +  ///to store the zoom factor when it was "fixed"
   1.426 +  double fixed_zoom_factor;
   1.427 +  
   1.428 +  ///Node radius size
   1.429 +  double radius_size;
   1.430 +
   1.431 +  ///Arc width
   1.432 +  double arc_width;
   1.433 +
   1.434 +  ///Was redesign run on this digraph already?
   1.435 +  ///
   1.436 +  ///If not, the layout will be modified randomly
   1.437 +  ///to avoid frozen layout because of wrong
   1.438 +  ///initial state
   1.439 +  bool was_redesigned;
   1.440 +  
   1.441 +private:
   1.442 +
   1.443 +  ///reference to the container, in which the canvas is
   1.444 +  NoteBookTab & mytab;
   1.445 +
   1.446 +  XY calcArrowPos(XY, XY, XY, XY, int);
   1.447 +
   1.448 +  bool background_set;
   1.449 +  Glib::RefPtr<Gdk::Pixbuf> refBackground;
   1.450 +  Gnome::Canvas::Pixbuf *background;
   1.451 +public:
   1.452 +  void setBackground();
   1.453 +};
   1.454 +
   1.455 +#endif //GRAPH_DISPLAYER_CANVAS_H