Graph displayer is now displaying nodes. Edges remain still undisplayed yet.
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/work/peter/graph-displayer.cc Fri Apr 01 09:44:29 2005 +0000
1.3 @@ -0,0 +1,312 @@
1.4 +// This example was started by Guillaume Laurent.
1.5 +// It has become a place to dump code that tests parts of the
1.6 +// gnomemm canvas code. Little thought has been given to the
1.7 +// actual on-screen output.
1.8 +
1.9 +#include <libgnomecanvasmm.h>
1.10 +#include <libgnomecanvasmm/polygon.h>
1.11 +
1.12 +#include <fstream>
1.13 +#include <iostream>
1.14 +
1.15 +#include <lemon/list_graph.h>
1.16 +#include <lemon/graph_reader.h>
1.17 +#include <lemon/graph_utils.h>
1.18 +#include <lemon/maps.h>
1.19 +#include <lemon/error.h>
1.20 +#include <lemon/xy.h>
1.21 +
1.22 +using namespace lemon;
1.23 +
1.24 +typedef xy<double> Coordinates;
1.25 +typedef ListGraph Graph;
1.26 +typedef Graph::NodeMap<Coordinates> CoordinatesMap;
1.27 +typedef Graph::Node Node;
1.28 +typedef Graph::EdgeIt EdgeIt;
1.29 +typedef Graph::NodeIt NodeIt;
1.30 +
1.31 +class GraphDisplayerCanvas : public Gnome::Canvas::CanvasAA
1.32 +{
1.33 + typedef Gnome::Canvas::CanvasAA Parent;
1.34 +
1.35 +public:
1.36 + GraphDisplayerCanvas(Graph &, CoordinatesMap &);
1.37 + virtual ~GraphDisplayerCanvas();
1.38 +
1.39 +private:
1.40 +
1.41 + ///Event handler function that handles dragging nodes of displayed_graph
1.42 + bool event_handler(GdkEvent* e, int b);
1.43 +
1.44 + ///Event handler function that handles dragging displayed_graph
1.45 + bool tri_mover(GdkEvent* e);
1.46 +
1.47 + ///Coordinates of Weight Point of tirangle
1.48 + Gnome::Art::Point * wp;
1.49 + ///Array of nodes of planefigure
1.50 + Gnome::Canvas::Ellipse ** nodes;
1.51 + ///Sides of planefigure
1.52 + Gnome::Canvas::Polygon * sides;
1.53 + ///Group of graphical elements of displayed_graph
1.54 + Gnome::Canvas::Group displayed_graph;
1.55 +
1.56 + ///Indicates whether the button of mouse is pressed or not
1.57 + bool isbutton;
1.58 +
1.59 + ///Number Of Elements - the number of nodes
1.60 + int noe;
1.61 +
1.62 + ///Array of coordinates
1.63 + double * coordinates;
1.64 +
1.65 + ///At this location was the mousebutton pressed.
1.66 + ///It helps to calculate the distance of dragging.
1.67 + double clicked_x, clicked_y;
1.68 +
1.69 + ///Remembers which Gnome::Canvas::Item was pressed.
1.70 + ///this variable is needed, because
1.71 + ///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
1.72 + ///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
1.73 + Gnome::Canvas::Item * active_item;
1.74 +
1.75 +
1.76 +};
1.77 +
1.78 +///When we click on the weight point we can drag the whole planefigure. This function resolves it.
1.79 +bool GraphDisplayerCanvas::tri_mover(GdkEvent* e)
1.80 +{
1.81 + switch(e->type)
1.82 + {
1.83 + case GDK_BUTTON_PRESS:
1.84 + clicked_x=e->button.x;
1.85 + clicked_y=e->button.y;
1.86 + isbutton=true;
1.87 + break;
1.88 + case GDK_BUTTON_RELEASE:
1.89 + isbutton=false;
1.90 + active_item=NULL;
1.91 + break;
1.92 + case GDK_MOTION_NOTIFY:
1.93 + if(isbutton)
1.94 + {
1.95 + double dx=e->motion.x-clicked_x;
1.96 + double dy=e->motion.y-clicked_y;
1.97 +
1.98 + Gnome::Canvas::Points coos;
1.99 +
1.100 + for(int i=0;i<=noe;i++)
1.101 + {
1.102 + nodes[i]->move(dx,dy);
1.103 +
1.104 + double x=(coordinates[2*i]+=dx);
1.105 + double y=(coordinates[2*i+1]+=dy);
1.106 +
1.107 + if(i!=noe)coos.push_back(Gnome::Art::Point(x,y));
1.108 +
1.109 + }
1.110 +
1.111 + clicked_x=e->motion.x;
1.112 + clicked_y=e->motion.y;
1.113 +
1.114 + sides->property_points().set_value(coos);
1.115 + }
1.116 + default: break;
1.117 + }
1.118 + return true;
1.119 +}
1.120 +
1.121 +///This function moves only one node of displayed_graph,
1.122 +///but recalculate the location of weight point,
1.123 +///and also redraw the sides of the planefigure.
1.124 +bool GraphDisplayerCanvas::event_handler(GdkEvent* e, int b)
1.125 +{
1.126 + switch(e->type)
1.127 + {
1.128 + case GDK_BUTTON_PRESS:
1.129 + clicked_x=e->button.x;
1.130 + clicked_y=e->button.y;
1.131 + active_item=(get_item_at(e->button.x, e->button.y));
1.132 + isbutton=true;
1.133 + break;
1.134 + case GDK_BUTTON_RELEASE:
1.135 + isbutton=false;
1.136 + active_item=NULL;
1.137 + break;
1.138 + case GDK_MOTION_NOTIFY:
1.139 + if(isbutton)
1.140 + {
1.141 + //double x1, y1, x2, y2;
1.142 + //(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
1.143 + //printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
1.144 + //printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
1.145 + double dx=e->motion.x-clicked_x;
1.146 + double dy=e->motion.y-clicked_y;
1.147 + active_item->move(dx, dy);
1.148 +
1.149 + coordinates[2*b]+=dx;
1.150 + coordinates[2*b+1]+=dy;
1.151 +
1.152 + Gnome::Canvas::Points coos;
1.153 +
1.154 + double x_wp=0;
1.155 + double y_wp=0;
1.156 +
1.157 + for(int i=0;i<noe;i++)
1.158 + {
1.159 + coos.push_back(Gnome::Art::Point(coordinates[2*i], coordinates[2*i+1]));
1.160 +
1.161 + x_wp+=coordinates[2*i];
1.162 + y_wp+=coordinates[2*i+1];
1.163 + }
1.164 +
1.165 + sides->property_points().set_value(coos);
1.166 +
1.167 + x_wp/=noe;
1.168 + y_wp/=noe;
1.169 +
1.170 + dx=x_wp-coordinates[noe*2];
1.171 + dy=y_wp-coordinates[noe*2+1];
1.172 + nodes[noe]->move(dx, dy);
1.173 +
1.174 + coordinates[noe*2]+=dx;
1.175 + coordinates[noe*2+1]+=dy;
1.176 +
1.177 + clicked_x=e->motion.x;
1.178 + clicked_y=e->motion.y;
1.179 + }
1.180 + default: break;
1.181 + }
1.182 + return true;
1.183 +}
1.184 +
1.185 +GraphDisplayerCanvas::GraphDisplayerCanvas(Graph & g, CoordinatesMap & cm):displayed_graph(*(root()), 0, 0),isbutton(false),active_item(NULL)
1.186 +{
1.187 + nodes=new Gnome::Canvas::Ellipse* [countNodes(g)];
1.188 + int sorszam=0;
1.189 +
1.190 + for (NodeIt i(g); i!=INVALID; ++i)
1.191 + {
1.192 + nodes[sorszam]= new Gnome::Canvas::Ellipse(displayed_graph, cm[i].x-20, cm[i].y-20, cm[i].x+20, cm[i].y+20);
1.193 + *(nodes[sorszam]) << Gnome::Canvas::Properties::fill_color("blue");
1.194 + *(nodes[sorszam]) << Gnome::Canvas::Properties::outline_color("black");
1.195 + (nodes[sorszam])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &GraphDisplayerCanvas::event_handler),sorszam));
1.196 + sorszam++;
1.197 + }
1.198 +
1.199 + for (EdgeIt i(g); i!=INVALID; ++i)
1.200 + {
1.201 + }
1.202 +
1.203 +
1.204 +}
1.205 +
1.206 +GraphDisplayerCanvas::~GraphDisplayerCanvas()
1.207 +{
1.208 +}
1.209 +
1.210 +//MainWin:
1.211 +
1.212 +class MainWin : public Gtk::Window
1.213 +{
1.214 +public:
1.215 + MainWin(const std::string& title, Graph &, CoordinatesMap &);
1.216 +
1.217 +protected:
1.218 + //Member widgets:
1.219 + GraphDisplayerCanvas gd_canvas;
1.220 +};
1.221 +
1.222 +MainWin::MainWin(const std::string& title, Graph & graph, CoordinatesMap & cm):gd_canvas(graph, cm)
1.223 +{
1.224 + set_title (title);
1.225 + add(gd_canvas);
1.226 + set_default_size(900,600);
1.227 +
1.228 + show_all();
1.229 +}
1.230 +
1.231 +
1.232 +///This class is responsible for being able
1.233 +///to read xy datastructure from file. It is
1.234 +///based on BaseMap. The set method sets the
1.235 +///appropriate value in the final xy NodeMap
1.236 +///that was given to the constructor.
1.237 +class CoordReaderMap: public MapBase <Node, double>
1.238 +{
1.239 + CoordinatesMap & cm;
1.240 + char xoy;
1.241 +
1.242 +public:
1.243 + CoordReaderMap(char xory, CoordinatesMap & coordmap);
1.244 + void set(Node node, double coord);
1.245 +};
1.246 +
1.247 +///The constructor expects for an xy NodeMap,
1.248 +///and we have to tell it, for which value
1.249 +///of the xy vector is responsible the actual
1.250 +///copy.
1.251 +CoordReaderMap::CoordReaderMap(char xory, CoordinatesMap & coordmap): cm(coordmap)
1.252 +{
1.253 + switch(xory)
1.254 + {
1.255 + case 'x':
1.256 + case 'y':
1.257 + xoy=xory;
1.258 + break;
1.259 + default:
1.260 + throw UninitializedParameter() ;
1.261 + }
1.262 +}
1.263 +
1.264 +///set method sets the appropriate value in the
1.265 +///xy type NodeMap that is under construction
1.266 +void CoordReaderMap::set(Node node, double coord)
1.267 +{
1.268 + switch(xoy)
1.269 + {
1.270 + case 'x':
1.271 + cm[node].x=coord;
1.272 + break;
1.273 + case 'y':
1.274 + cm[node].y=coord;
1.275 + break;
1.276 + default:
1.277 + throw UninitializedParameter() ;
1.278 + }
1.279 +}
1.280 +
1.281 +//main():
1.282 +
1.283 +int main(int argc, char *argv[])
1.284 +{
1.285 +
1.286 + Coordinates coosvector;
1.287 +
1.288 + Graph g;
1.289 +
1.290 + CoordinatesMap cm(g);
1.291 +
1.292 + //we create one object to read x coordinates
1.293 + //and one to read y coordinate of nodes and write them to cm NodeMap.
1.294 + CoordReaderMap xreader('x',cm);
1.295 + CoordReaderMap yreader('y',cm);
1.296 +
1.297 + std::ifstream is("graphocska.lemon");
1.298 +
1.299 + GraphReader<Graph> reader(is, g);
1.300 + reader.addNodeMap("coordinates_x", xreader);
1.301 + reader.addNodeMap("coordinates_y", yreader);
1.302 + reader.run();
1.303 +
1.304 + for (NodeIt i(g); i!=INVALID; ++i)
1.305 + std::cout << " " << g.id(i) << " " << cm[i];
1.306 + std::cout << std::endl;
1.307 +
1.308 + Gnome::Canvas::init();
1.309 + Gtk::Main app(argc, argv);
1.310 +
1.311 + MainWin mainwin("Displayed Graph", g, cm);
1.312 + app.run(mainwin);
1.313 +
1.314 + return 0;
1.315 +}