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