/* -*- 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