ladanyi@6: // -*- C++ -*- // ladanyi@6: ladanyi@6: #ifndef GRAPH_DISPLAYER_CANVAS_H ladanyi@6: #define GRAPH_DISPLAYER_CANVAS_H ladanyi@6: hegyi@21: class GraphDisplayerCanvas; hegyi@21: ladanyi@53: #include "all_include.h" hegyi@96: #include "nbtab.h" ladanyi@6: #include ladanyi@6: #include hegyi@89: #include ladanyi@6: ladanyi@6: ///This class is the canvas, on which the graph can be drawn. ladanyi@6: class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA ladanyi@6: { ladanyi@98: friend class BrokenEdge; ladanyi@98: hegyi@118: ///Edge displayer class hegyi@118: hegyi@118: ///This class is responsible for displaying edges in graph. hegyi@118: ///The displayed edge is broken in the middle. The hegyi@118: ///aim of this is to be able to indicate direction of edges hegyi@118: ///and to be able to display more then one edges between the hegyi@118: ///same source and target hegyi@89: class BrokenEdge : public Gnome::Canvas::Line hegyi@89: { hegyi@118: ///The edge that the class displays. hegyi@118: hegyi@118: ///It is needed, because some datas needed from hegyi@118: ///graph can be accessed by this or should be sent hegyi@118: ///as parameter, but it would be complicated ladanyi@98: Edge edge; hegyi@118: hegyi@118: ///Reference to the canvas, on which the graph is drawn. hegyi@118: hegyi@118: ///It is needed, because some datas needed from hegyi@118: ///graph can be accessed by this or should be sent hegyi@118: ///as parameter, but it would be complicated hegyi@89: GraphDisplayerCanvas & gdc; hegyi@118: hegyi@118: ///An arrow that indicates the direction of the edges hegyi@118: hegyi@118: ///in case of directional graph direction can be indicated hegyi@118: ///by this polygon. The polygon formulates a red arrow. hegyi@89: Gnome::Canvas::Polygon * arrow; hegyi@89: hegyi@118: ///Indicates whether the button of mouse is pressed or not at the moment. hegyi@89: bool isbutton; hegyi@89: hegyi@118: ///At this location was the mousebutton pressed. Horizontal component. hegyi@89: hegyi@118: ///It helps to calculate the hegyi@118: ///distance of dragging. hegyi@118: double clicked_x; hegyi@118: hegyi@118: ///At this location was the mousebutton pressed. Vertical component. hegyi@118: hegyi@118: ///It helps to calculate the hegyi@118: ///distance of dragging. hegyi@118: double clicked_y; hegyi@118: hegyi@118: ///event handler for forming broken edges hegyi@118: hegyi@118: ///\param event the hegyi@118: ///event to handle hegyi@118: bool edgeFormerEventHandler(GdkEvent* event); hegyi@89: public: hegyi@118: hegyi@118: ///Constructor of broken edge class. hegyi@118: hegyi@118: ///\param g the group to which the edge belongs hegyi@118: ///\param _edge the represented edge hegyi@118: ///\param gc the canvas hegyi@118: BrokenEdge(Gnome::Canvas::Group & g, Edge _edge, GraphDisplayerCanvas & gc); hegyi@118: hegyi@118: ///Destructor of broken edge class hegyi@118: hegyi@118: ///Frees up hegyi@118: ///reserved memory hegyi@89: ~BrokenEdge(); hegyi@118: hegyi@118: ///The function that draws the edge based on collected data ladanyi@98: void draw(); hegyi@89: }; hegyi@118: hegyi@118: ///Type of canvas, on which the graph is drawn ladanyi@6: typedef Gnome::Canvas::CanvasAA Parent; ladanyi@6: ladanyi@6: public: hegyi@118: ///Constructor hegyi@118: hegyi@118: ///\param nbt the tab of the window, in which the graph is displayed hegyi@118: GraphDisplayerCanvas(NoteBookTab & nbt); hegyi@118: hegyi@118: ///destructor of the class ladanyi@6: virtual ~GraphDisplayerCanvas(); ladanyi@6: hegyi@118: ///Changes the width of edge(s) according to the given map. hegyi@118: hegyi@118: ///\param mapname is the name of the map which contains the values to be set hegyi@118: ///\param edge if it is given, only the width of the given edge will be set, instead of all of them. hegyi@118: int changeEdgeWidth (std::string mapname, Edge edge=INVALID); hegyi@118: hegyi@118: ///Resets width of edge(s) to the default value hegyi@118: hegyi@118: ///\param edge if it is given, only the width of the hegyi@118: ///given edge will be reset, instead of all of them. hegyi@118: int resetEdgeWidth (Edge edge=INVALID); hegyi@118: hegyi@118: ///Changes the color of edge(s) according to the given map. hegyi@118: ladanyi@6: ///\param mapname is the name of the map which contains the new values hegyi@118: ///\param edge if it is given, only the color of the given edge will be set, instead of all of them. hegyi@118: int changeEdgeColor (std::string mapname, Edge edge=INVALID); ladanyi@6: hegyi@118: ///Resets color of edge(s) to the default value hegyi@118: hegyi@118: ///\param edge if it is given, only the color of the hegyi@118: ///given edge will be reset, instead of all of them. hegyi@118: int resetEdgeColor (Edge edge=INVALID); hegyi@118: hegyi@118: ///Changes the label of edge(s) according to the given map. hegyi@118: ladanyi@6: ///\param mapname is the name of the map which contains the new values hegyi@118: ///\param edge if it is given, only the label of the given edge will be set, instead of all of them. hegyi@118: int changeEdgeText (std::string mapname, Edge edge=INVALID); ladanyi@6: hegyi@118: ///Resets label of edge(s) to the default value hegyi@118: hegyi@118: ///\param edge if it is given, only the color of the hegyi@118: ///given edge will be reset, instead of all of them. hegyi@118: int resetEdgeText (Edge edge=INVALID); hegyi@118: hegyi@118: ///Changes the radius of node(s) according to the given map. hegyi@118: ladanyi@6: ///\param mapname is the name of the map which contains the new values hegyi@118: ///\param node if it is given, only the radius of the given node will be set, instead of all of them. hegyi@118: int changeNodeRadius (std::string mapname, Node node=INVALID); hegyi@28: hegyi@118: ///Resets radius of node(s) to the default value hegyi@118: hegyi@118: ///\param node if it is given, only the radius of the hegyi@118: ///given node will be reset, instead of all of them. hegyi@118: int resetNodeRadius (Node node=INVALID); hegyi@118: hegyi@118: ///Changes the color of node(s) according to the given map. hegyi@118: hegyi@28: ///\param mapname is the name of the map which contains the new values hegyi@118: ///\param node if it is given, only the color of the given node will be set, instead of all of them. hegyi@118: int changeNodeColor (std::string mapname, Node node=INVALID); hegyi@28: hegyi@118: ///Resets color of node(s) to the default value hegyi@118: hegyi@118: ///\param node if it is given, only the color of the hegyi@118: ///given node will be reset, instead of all of them. hegyi@118: int resetNodeColor (Node node=INVALID); hegyi@118: hegyi@118: ///Changes the label of node(s) according to the given map. hegyi@118: hegyi@28: ///\param mapname is the name of the map which contains the new values hegyi@118: ///\param node if it is given, only the label of the given node will be set, instead of all of them. hegyi@118: int changeNodeText (std::string mapname, Node node=INVALID); hegyi@28: hegyi@118: ///Resets label of node(s) to the default value ladanyi@6: hegyi@118: ///\param node if it is given, only the label of the hegyi@118: ///given node will be reset, instead of all of them. hegyi@118: int resetNodeText (Node node=INVALID); hegyi@94: hegyi@118: ///This function is called, when any of the displayed attributes have to be updated, or changed hegyi@118: hegyi@118: ///\param itisedge if true, edge property has to be changed, else node property hegyi@118: ///\param prop the id of property that has to changed or updated hegyi@118: void propertyChange(bool itisedge, int prop); hegyi@118: hegyi@118: ///updates the given property hegyi@118: hegyi@118: ///\param edge if it is not INVALID, only the property of the given edge will be updated, instead of all of them hegyi@118: ///\param prop the property to update hegyi@118: void propertyUpdate(Edge edge, int prop); hegyi@118: hegyi@118: ///updates the given property hegyi@118: hegyi@118: ///\param node if it is not INVALID, only the property of the given node will be updated, instead of all of them hegyi@118: ///\param prop the property to update hegyi@118: void propertyUpdate(Node node, int prop); hegyi@118: hegyi@118: ///updates all the property for the given edge hegyi@94: void propertyUpdate(Edge); hegyi@118: hegyi@118: ///updates all the property for the given node hegyi@94: void propertyUpdate(Node); hegyi@94: ladanyi@6: ///Callback for 'ViewZoomIn' action. ladanyi@6: virtual void zoomIn(); ladanyi@6: ///Callback for 'ViewZoomOut' action. ladanyi@6: virtual void zoomOut(); ladanyi@6: ///Callback for 'ViewZoomFit' action. ladanyi@6: virtual void zoomFit(); ladanyi@6: ///Callback for 'ViewZoom100' action. ladanyi@6: virtual void zoom100(); ladanyi@6: ///Sets the scroll region of the convas to the bounding box of the graph. ladanyi@6: void updateScrollRegion(); ladanyi@6: hegyi@9: ///This function changes the tool in the graph-editor's hand hegyi@9: void changeEditorialTool(int); hegyi@9: ladanyi@6: protected: ladanyi@6: hegyi@118: //maximizing, minimizing, restoring window, etc. ladanyi@6: virtual bool on_expose_event(GdkEventExpose *); ladanyi@6: ladanyi@6: private: ladanyi@6: ladanyi@6: ///This function is responsible for the correct ladanyi@6: ///reaction of any action happened in the territory ladanyi@6: ///of the canvas hegyi@25: ///DEPRECATED!!!! hegyi@30: bool eventHandler(GdkEvent* e, Node n); ladanyi@6: hegyi@9: ///actual event handler hegyi@9: /// hegyi@9: ///Actual event handler should be stored, to be able to disconnect it and later reconnect it. hegyi@9: sigc::connection actual_handler; hegyi@9: hegyi@9: ///event handler for the case when move-tool is active hegyi@30: bool moveEventHandler(GdkEvent*); hegyi@9: ///event handler for the case when create_node-tool is active hegyi@30: bool createNodeEventHandler(GdkEvent*); hegyi@9: ///event handler for the case when create_edge-tool is active hegyi@30: bool createEdgeEventHandler(GdkEvent*); hegyi@13: ///event handler for the case when eraser-tool is active hegyi@30: bool eraserEventHandler(GdkEvent*); hegyi@32: ///event handler for the case when edge map editor tool is active hegyi@30: bool edgeMapEditEventHandler(GdkEvent*); hegyi@32: ///event handler for the case when node map editor tool is active hegyi@32: bool nodeMapEditEventHandler(GdkEvent*); hegyi@13: hegyi@21: public: hegyi@25: ///Moves the text to new place hegyi@30: void textReposition(xy); hegyi@118: hegyi@25: ///Activates an edge belonging to a BrokenEdge hegyi@118: hegyi@35: ///After we have activated an edge this way, hegyi@35: ///the GDC object will know, which edge is under forming hegyi@118: ///therefore it can redraw the necessary elements on the canvas, hegyi@35: ///for example the text belonging to the \ref BrokenEdge can be hegyi@35: ///redrawn (\ref textReposition). hegyi@30: void toggleEdgeActivity(BrokenEdge*, bool); hegyi@25: hegyi@25: public: hegyi@118: hegyi@118: ///Returns the actual tool in hand hegyi@30: int getActualTool(); hegyi@21: hegyi@118: ///draws the graph hegyi@118: hegyi@118: ///Called when opening a file. ladanyi@53: void drawGraph(); hegyi@118: hegyi@118: ///Clears the canvas hegyi@118: hegyi@118: ///It achieves this by deleting all data hegyi@118: ///structure used to help handle the displayed graph. ladanyi@53: void clear(); ladanyi@53: hegyi@37: ///creates a new Nodemap hegyi@118: hegyi@118: ///\param init initial value of the map hegyi@118: ///\param mapname name of new map hegyi@118: int addNewNodeMap(double init,std::string mapname); hegyi@37: ///creates a new Edgemap hegyi@118: hegyi@118: ///\param init initial value of the map hegyi@118: ///\param mapname name of new map hegyi@118: int addNewEdgeMap(double init,std::string mapname); hegyi@37: hegyi@21: private: hegyi@14: ///Deletes the given element. alpar@62: void deleteItem(Node); hegyi@14: ///Deletes the given element. alpar@62: void deleteItem(Edge); hegyi@9: hegyi@21: private: hegyi@21: ladanyi@6: ///Map of nodes of graph ladanyi@6: Graph::NodeMap nodesmap; ladanyi@6: ladanyi@6: ///Map of edges of graph hegyi@19: Graph::EdgeMap edgesmap; ladanyi@6: ladanyi@6: ///Map of texts to write on edges ladanyi@6: Graph::EdgeMap edgetextmap; ladanyi@6: hegyi@28: ///Map of texts to write on nodes hegyi@28: Graph::NodeMap nodetextmap; hegyi@28: ladanyi@6: ///Group of graphical elements of displayed_graph ladanyi@6: Gnome::Canvas::Group displayed_graph; ladanyi@6: hegyi@88: private: ladanyi@6: ///Indicates whether the button of mouse is pressed or not hegyi@20: int isbutton; ladanyi@6: hegyi@21: ///Stores the actual tool in hand hegyi@21: int actual_tool; hegyi@21: ladanyi@6: ///At this location was the mousebutton pressed. ladanyi@6: ///It helps to calculate the distance of dragging. ladanyi@6: double clicked_x, clicked_y; ladanyi@6: ladanyi@6: ///Remembers which Gnome::Canvas::Item was pressed. hegyi@118: hegyi@118: ///this variable is needed, to work on it after selection hegyi@118: Gnome::Canvas::Item * active_item; hegyi@118: hegyi@118: ///Remembers which Gnome::Canvas::Item was pressed. hegyi@118: hegyi@118: ///this variable is used at edge creation, it will hegyi@118: ///be the secondly selected node. No local variable hegyi@118: ///can be used for this purpose inside the function, hegyi@118: ///because the node selected by button press, and hegyi@118: ///the edge is created by button release. Both of hegyi@118: ///them is different function call. hegyi@118: Gnome::Canvas::Item * target_item; hegyi@118: hegyi@118: ///selected node (for any editing) alpar@62: Node active_node; hegyi@118: hegyi@118: ///selected edge (for any editing) alpar@62: Edge active_edge; hegyi@118: hegyi@118: ///the edge that is selected by clicking on the red arrow in the middle of it hegyi@118: hegyi@118: ///This edge is stored only for the purpose of reshape it. hegyi@118: ///That is why it is selected in a different manner. alpar@62: Edge forming_edge; hegyi@35: hegyi@118: ///Map displayed by label can be edited. hegyi@118: std::string nodemap_to_edit; hegyi@118: hegyi@118: ///Map displayed by label can be edited. hegyi@118: std::string edgemap_to_edit; ladanyi@6: ladanyi@6: static const int zoom_step = 5; hegyi@19: hegyi@88: private: hegyi@88: hegyi@118: ///reference to the container, in which the canvas is hegyi@96: NoteBookTab & mytab; hegyi@55: alpar@127: XY calcArrowPos(XY, XY, XY, XY, bool); ladanyi@6: }; ladanyi@6: ladanyi@6: #endif //GRAPH_DISPLAYER_CANVAS_H