diff -r 0e4f009eab8b -r 67188bd752db graph_displayer_canvas.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graph_displayer_canvas.h Mon Jul 07 08:10:39 2008 -0500 @@ -0,0 +1,452 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef GRAPH_DISPLAYER_CANVAS_H +#define GRAPH_DISPLAYER_CANVAS_H + +class NoteBookTab; + +#include "all_include.h" +#include +#include + +///This class is the canvas, on which the digraph can be drawn. +class DigraphDisplayerCanvas : public Gnome::Canvas::CanvasAA +{ + friend class BrokenArc; + friend class LoopArc; + + class ArcBase : public Gnome::Canvas::Group + { + protected: + ///Reference to the canvas, on which the digraph is drawn. + + ///It is needed, because some datas needed from + ///digraph can be accessed by this or should be sent + ///as parameter, but it would be complicated + DigraphDisplayerCanvas& canvas; + + ///The arc that the class displays. + + ///It is needed, because some datas needed from + ///digraph can be accessed by this or should be sent + ///as parameter, but it would be complicated + Arc arc; + + Gnome::Canvas::Polygon arrow; + + void drawArrow(XY); + public: + ArcBase(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + virtual ~ArcBase(); + virtual void draw() = 0; + virtual void setLineWidth(int) = 0; + virtual void setFillColor(Gdk::Color) = 0; + virtual Gnome::Canvas::Item * getLine() = 0; + }; + + ///Arc displayer class + + ///This class is responsible for displaying arcs in digraph. + ///The displayed arc is broken in the middle. The + ///aim of this is to be able to indicate direction of arcs + ///and to be able to display more then one arcs between the + ///same source and target + class BrokenArc : public ArcBase + { + private: + Gnome::Canvas::Line line; + + ///Indicates whether the button of mouse is pressed or not at the moment. + bool isbutton; + + ///At this location was the mousebutton pressed. Horizontal component. + + ///It helps to calculate the + ///distance of dragging. + double clicked_x; + + ///At this location was the mousebutton pressed. Vertical component. + + ///It helps to calculate the + ///distance of dragging. + double clicked_y; + + ///event handler for forming broken arcs + + ///\param event the + ///event to handle + bool arcFormerEventHandler(GdkEvent* event); + + public: + ///Constructor of broken arc class. + + ///\param g the group to which the arc belongs + ///\param _arc the represented arc + ///\param gc the canvas + BrokenArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + + ///Destructor of broken arc class + + ///Frees up + ///reserved memory + ~BrokenArc(); + + ///The function that draws the arc based on collected data + void draw(); + + void setLineWidth(int); + void setFillColor(Gdk::Color); + + Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); }; + }; + + class LoopArc : public ArcBase + { + private: + Gnome::Canvas::Ellipse line; + bool arcFormerEventHandler(GdkEvent* e); + bool isbutton; + public: + LoopArc(Gnome::Canvas::Group&, Arc, DigraphDisplayerCanvas&); + ~LoopArc(); + void draw(); + void setLineWidth(int); + void setFillColor(Gdk::Color); + Gnome::Canvas::Item * getLine() { return (Gnome::Canvas::Item *)(&line); }; + }; + + ///Type of canvas, on which the digraph is drawn + typedef Gnome::Canvas::CanvasAA Parent; + +public: + ///Constructor + + ///\param nbt the tab of the window, in which the digraph is displayed + DigraphDisplayerCanvas(NoteBookTab & nbt); + + ///destructor of the class + virtual ~DigraphDisplayerCanvas(); + + ///Returns a color of the rainbow based on a map value and the min and max value of the given map + + ///min and max is purple, between them there is a linear assign + Gdk::Color rainbowColorCounter(double, double, double); + + ///Changes the width of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the values to be set + ///\param arc if it is given, only the width of the given arc will be set, instead of all of them. + int changeArcWidth (std::string mapname, Arc arc=INVALID); + + ///Resets width of arc(s) to the default value + + ///\param arc if it is given, only the width of the + ///given arc will be reset, instead of all of them. + int resetArcWidth (Arc arc=INVALID); + + ///Changes the color of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param arc if it is given, only the color of the given arc will be set, instead of all of them. + int changeArcColor (std::string mapname, Arc arc=INVALID); + + ///Resets color of arc(s) to the default value + + ///\param arc if it is given, only the color of the + ///given arc will be reset, instead of all of them. + int resetArcColor (Arc arc=INVALID); + + ///Changes the label of arc(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param arc if it is given, only the label of the given arc will be set, instead of all of them. + int changeArcText (std::string mapname, Arc arc=INVALID); + + ///Resets label of arc(s) to the default value + + ///\param arc if it is given, only the color of the + ///given arc will be reset, instead of all of them. + int resetArcText (Arc arc=INVALID); + + ///Changes the radius of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the radius of the given node will be set, instead of all of them. + int changeNodeRadius (std::string mapname, Node node=INVALID); + + ///Resets radius of node(s) to the default value + + ///\param node if it is given, only the radius of the + ///given node will be reset, instead of all of them. + int resetNodeRadius (Node node=INVALID); + + ///Changes the color of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the color of the given node will be set, instead of all of them. + int changeNodeColor (std::string mapname, Node node=INVALID); + + ///Resets color of node(s) to the default value + + ///\param node if it is given, only the color of the + ///given node will be reset, instead of all of them. + int resetNodeColor (Node node=INVALID); + + ///Changes the label of node(s) according to the given map. + + ///\param mapname is the name of the map which contains the new values + ///\param node if it is given, only the label of the given node will be set, instead of all of them. + int changeNodeText (std::string mapname, Node node=INVALID); + + ///Resets label of node(s) to the default value + + ///\param node if it is given, only the label of the + ///given node will be reset, instead of all of them. + int resetNodeText (Node node=INVALID); + + ///This function is called, when any of the displayed attributes have to be updated, or changed + + ///\param itisarc if true, arc property has to be changed, else node property + ///\param prop the id of property that has to changed or updated + void propertyChange(bool itisarc, int prop); + + ///updates the given property + + ///\param arc if it is not INVALID, only the property of the given arc will be updated, instead of all of them + ///\param prop the property to update + void propertyUpdate(Arc arc, int prop); + + ///updates the given property + + ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them + ///\param prop the property to update + void propertyUpdate(Node node, int prop); + + ///updates all the property for the given arc + void propertyUpdate(Arc); + + ///updates all the property for the given node + void propertyUpdate(Node); + + ///Callback for 'ViewZoomIn' action. + virtual void zoomIn(); + ///Callback for 'ViewZoomOut' action. + virtual void zoomOut(); + ///Callback for 'ViewZoomFit' action. + virtual void zoomFit(); + ///Callback for 'ViewZoom100' action. + virtual void zoom100(); + ///Sets the scroll region of the convas to the bounding box of the digraph. + void updateScrollRegion(); + + ///This function changes the tool in the digraph-editor's hand + void changeEditorialTool(int); + +protected: + + //maximizing, minimizing, restoring window, etc. + virtual bool on_expose_event(GdkEventExpose *); + +private: + + ///This function is responsible for the correct + ///reaction of any action happened in the territory + ///of the canvas + ///DEPRECATED!!!! + bool eventHandler(GdkEvent* e, Node n); + + ///actual event handler + /// + ///Actual event handler should be stored, to be able to disconnect it and later reconnect it. + sigc::connection actual_handler; + + ///event handler for the case when move-tool is active + bool moveEventHandler(GdkEvent*); + ///event handler for the case when create_node-tool is active + bool createNodeEventHandler(GdkEvent*); + ///event handler for the case when create_arc-tool is active + bool createArcEventHandler(GdkEvent*); + ///event handler for the case when eraser-tool is active + bool eraserEventHandler(GdkEvent*); + ///event handler for the case when map editor tool is active + bool mapEditEventHandler(GdkEvent*); + ///event handler for the case when user scrolls the mouse + bool scrollEventHandler(GdkEvent*); + +private: + ///moves node according to the given parameters + void moveNode(double, double, Gnome::Canvas::Item * item=NULL, Node node=INVALID); + +public: + ///Moves the text to new place + void textReposition(XY); + + ///Activates an arc belonging to an ArcBase + + ///After we have activated an arc this way, + ///the GDC object will know, which arc is under forming + ///therefore it can redraw the necessary elements on the canvas, + ///for example the text belonging to the \ref ArcBase can be + ///redrawn (\ref textReposition). + void toggleArcActivity(ArcBase*, bool); + +public: + + ///Returns the actual tool in hand + int getActualTool(); + + ///Sets node representation settings + void setView(bool, bool, double, double); + + ///Gets node representation settings + void getView(bool &, bool &, double&, double&); + + ///draws the digraph + + ///Called when opening a file. + void drawDigraph(); + + ///Clears the canvas + + ///It achieves this by deleting all data + ///structure used to help handle the displayed digraph. + void clear(); + + ///creates a new Nodemap + + ///\param init initial value of the map + ///\param mapname name of new map + int addNewNodeMap(double init,std::string mapname); + ///creates a new Arcmap + + ///\param init initial value of the map + ///\param mapname name of new map + int addNewArcMap(double init,std::string mapname); + + void reDesignDigraph(); + + ///Show whether the digraph is already drawn. + bool is_drawn; + +private: + ///Deletes the given element. + void deleteItem(Node); + ///Deletes the given element. + void deleteItem(Arc); + +private: + + ///Map of nodes of digraph + Digraph::NodeMap nodesmap; + + ///Map of arcs of digraph + Digraph::ArcMap arcsmap; + + ///Map of texts to write on arcs + Digraph::ArcMap arctextmap; + + ///Map of texts to write on nodes + Digraph::NodeMap nodetextmap; + + ///Group of digraphical elements of displayed_graph + Gnome::Canvas::Group displayed_graph; + +private: + ///Indicates whether the button of mouse is pressed or not + int isbutton; + + ///Stores the actual tool in hand + int actual_tool; + + ///At this location was the mousebutton pressed. + ///It helps to calculate the distance of dragging. + double clicked_x, clicked_y; + + ///Remembers which Gnome::Canvas::Item was pressed. + + ///this variable is needed, to work on it after selection + Gnome::Canvas::Item * active_item; + + ///Remembers which Gnome::Canvas::Item was pressed. + + ///this variable is used at arc creation, it will + ///be the secondly selected node. No local variable + ///can be used for this purpose inside the function, + ///because the node selected by button press, and + ///the arc is created by button release. Both of + ///them is different function call. + Gnome::Canvas::Item * target_item; + + ///selected node (for any editing) + Node active_node; + + ///selected arc (for any editing) + Arc active_arc; + + ///the arc that is selected by clicking on the red arrow in the middle of it + + ///This arc is stored only for the purpose of reshape it. + ///That is why it is selected in a different manner. + Arc forming_arc; + + ///Map displayed by label can be edited. + std::string nodemap_to_edit; + + ///Map displayed by label can be edited. + std::string arcmap_to_edit; + + static const int zoom_step = 5; + + ///Is node radius autoscaled + bool autoscale; + + ///Should we track zoomfactor changes + bool zoomtrack; + + ///to store the zoom factor when it was "fixed" + double fixed_zoom_factor; + + ///Node radius size + double radius_size; + + ///Arc width + double arc_width; + + ///Was redesign run on this digraph already? + /// + ///If not, the layout will be modified randomly + ///to avoid frozen layout because of wrong + ///initial state + bool was_redesigned; + +private: + + ///reference to the container, in which the canvas is + NoteBookTab & mytab; + + XY calcArrowPos(XY, XY, XY, XY, int); + + bool background_set; + Glib::RefPtr refBackground; + Gnome::Canvas::Pixbuf *background; +public: + void setBackground(); +}; + +#endif //GRAPH_DISPLAYER_CANVAS_H