# HG changeset patch # User hegyi # Date 1112348669 0 # Node ID 142633fc5014b3e0f84e223a7387fc1e7ab8a8a2 # Parent 6cc7b573b7b569c0bffc437327539882344474ed Graph displayer is now displaying nodes. Edges remain still undisplayed yet. diff -r 6cc7b573b7b5 -r 142633fc5014 src/work/peter/graph-displayer.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/peter/graph-displayer.cc Fri Apr 01 09:44:29 2005 +0000 @@ -0,0 +1,312 @@ +// This example was started by Guillaume Laurent. +// It has become a place to dump code that tests parts of the +// gnomemm canvas code. Little thought has been given to the +// actual on-screen output. + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace lemon; + +typedef xy Coordinates; +typedef ListGraph Graph; +typedef Graph::NodeMap CoordinatesMap; +typedef Graph::Node Node; +typedef Graph::EdgeIt EdgeIt; +typedef Graph::NodeIt NodeIt; + +class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA +{ + typedef Gnome::Canvas::CanvasAA Parent; + +public: + GraphDisplayerCanvas(Graph &, CoordinatesMap &); + virtual ~GraphDisplayerCanvas(); + +private: + + ///Event handler function that handles dragging nodes of displayed_graph + bool event_handler(GdkEvent* e, int b); + + ///Event handler function that handles dragging displayed_graph + bool tri_mover(GdkEvent* e); + + ///Coordinates of Weight Point of tirangle + Gnome::Art::Point * wp; + ///Array of nodes of planefigure + Gnome::Canvas::Ellipse ** nodes; + ///Sides of planefigure + Gnome::Canvas::Polygon * sides; + ///Group of graphical elements of displayed_graph + Gnome::Canvas::Group displayed_graph; + + ///Indicates whether the button of mouse is pressed or not + bool isbutton; + + ///Number Of Elements - the number of nodes + int noe; + + ///Array of coordinates + double * coordinates; + + ///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, because + ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault + ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution + Gnome::Canvas::Item * active_item; + + +}; + +///When we click on the weight point we can drag the whole planefigure. This function resolves it. +bool GraphDisplayerCanvas::tri_mover(GdkEvent* e) +{ + switch(e->type) + { + case GDK_BUTTON_PRESS: + clicked_x=e->button.x; + clicked_y=e->button.y; + isbutton=true; + break; + case GDK_BUTTON_RELEASE: + isbutton=false; + active_item=NULL; + break; + case GDK_MOTION_NOTIFY: + if(isbutton) + { + double dx=e->motion.x-clicked_x; + double dy=e->motion.y-clicked_y; + + Gnome::Canvas::Points coos; + + for(int i=0;i<=noe;i++) + { + nodes[i]->move(dx,dy); + + double x=(coordinates[2*i]+=dx); + double y=(coordinates[2*i+1]+=dy); + + if(i!=noe)coos.push_back(Gnome::Art::Point(x,y)); + + } + + clicked_x=e->motion.x; + clicked_y=e->motion.y; + + sides->property_points().set_value(coos); + } + default: break; + } + return true; +} + +///This function moves only one node of displayed_graph, +///but recalculate the location of weight point, +///and also redraw the sides of the planefigure. +bool GraphDisplayerCanvas::event_handler(GdkEvent* e, int b) +{ + switch(e->type) + { + case GDK_BUTTON_PRESS: + clicked_x=e->button.x; + clicked_y=e->button.y; + active_item=(get_item_at(e->button.x, e->button.y)); + isbutton=true; + break; + case GDK_BUTTON_RELEASE: + isbutton=false; + active_item=NULL; + break; + case GDK_MOTION_NOTIFY: + if(isbutton) + { + //double x1, y1, x2, y2; + //(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2); + //printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2); + //printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y); + double dx=e->motion.x-clicked_x; + double dy=e->motion.y-clicked_y; + active_item->move(dx, dy); + + coordinates[2*b]+=dx; + coordinates[2*b+1]+=dy; + + Gnome::Canvas::Points coos; + + double x_wp=0; + double y_wp=0; + + for(int i=0;iproperty_points().set_value(coos); + + x_wp/=noe; + y_wp/=noe; + + dx=x_wp-coordinates[noe*2]; + dy=y_wp-coordinates[noe*2+1]; + nodes[noe]->move(dx, dy); + + coordinates[noe*2]+=dx; + coordinates[noe*2+1]+=dy; + + clicked_x=e->motion.x; + clicked_y=e->motion.y; + } + default: break; + } + return true; +} + +GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & g, CoordinatesMap & cm):displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL) +{ + nodes=new Gnome::Canvas::Ellipse* [countNodes(g)]; + int sorszam=0; + + for (NodeIt i(g); i!=INVALID; ++i) + { + nodes[sorszam]= new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20); + *(nodes[sorszam]) << Gnome::Canvas::Properties::fill_color("blue"); + *(nodes[sorszam]) << Gnome::Canvas::Properties::outline_color("black"); + (nodes[sorszam])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),sorszam)); + sorszam++; + } + + for (EdgeIt i(g); i!=INVALID; ++i) + { + } + + +} + +GraphDisplayerCanvas::~GraphDisplayerCanvas() +{ +} + +//MainWin: + +class MainWin : public Gtk::Window +{ +public: + MainWin(const std::string& title, Graph &, CoordinatesMap &); + +protected: + //Member widgets: + GraphDisplayerCanvas gd_canvas; +}; + +MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm):gd_canvas(graph, cm) +{ + set_title (title); + add(gd_canvas); + set_default_size(900,600); + + show_all(); +} + + +///This class is responsible for being able +///to read xy datastructure from file. It is +///based on BaseMap. The set method sets the +///appropriate value in the final xy NodeMap +///that was given to the constructor. +class CoordReaderMap: public MapBase +{ + CoordinatesMap & cm; + char xoy; + +public: + CoordReaderMap(char xory, CoordinatesMap & coordmap); + void set(Node node, double coord); +}; + +///The constructor expects for an xy NodeMap, +///and we have to tell it, for which value +///of the xy vector is responsible the actual +///copy. +CoordReaderMap::CoordReaderMap(char xory, CoordinatesMap & coordmap): cm(coordmap) +{ + switch(xory) + { + case 'x': + case 'y': + xoy=xory; + break; + default: + throw UninitializedParameter() ; + } +} + +///set method sets the appropriate value in the +///xy type NodeMap that is under construction +void CoordReaderMap::set(Node node, double coord) +{ + switch(xoy) + { + case 'x': + cm[node].x=coord; + break; + case 'y': + cm[node].y=coord; + break; + default: + throw UninitializedParameter() ; + } +} + +//main(): + +int main(int argc, char *argv[]) +{ + + Coordinates coosvector; + + Graph g; + + CoordinatesMap cm(g); + + //we create one object to read x coordinates + //and one to read y coordinate of nodes and write them to cm NodeMap. + CoordReaderMap xreader('x',cm); + CoordReaderMap yreader('y',cm); + + std::ifstream is("graphocska.lemon"); + + GraphReader reader(is, g); + reader.addNodeMap("coordinates_x", xreader); + reader.addNodeMap("coordinates_y", yreader); + reader.run(); + + for (NodeIt i(g); i!=INVALID; ++i) + std::cout << " " << g.id(i) << " " << cm[i]; + std::cout << std::endl; + + Gnome::Canvas::init(); + Gtk::Main app(argc, argv); + + MainWin mainwin("Displayed Graph", g, cm); + app.run(mainwin); + + return 0; +}