src/work/peter/canvas-test.cc
author alpar
Mon, 21 Mar 2005 07:47:00 +0000
changeset 1229 aa65e46aebc3
parent 1225 4401e1aeafcf
child 1277 e4cc8e996912
permissions -rw-r--r--
Bugfix, thanks to Janos.
     1 // This example was started by Guillaume Laurent.
     2 // It has become a place to dump code that tests parts of the
     3 // gnomemm canvas code. Little thought has been given to the
     4 // actual on-screen output.
     5 
     6 #include <libgnomecanvasmm.h>
     7 #include <libgnomecanvasmm/polygon.h>
     8 #include <iostream>
     9 
    10 class CanvasExample : public Gnome::Canvas::CanvasAA
    11 {
    12 	typedef Gnome::Canvas::CanvasAA Parent;
    13 
    14 public:
    15 	CanvasExample(double *, int);
    16 	virtual ~CanvasExample();
    17 
    18 private:
    19 
    20 	///Event handler function that handles dragging nodes of triangle
    21 	bool event_handler(GdkEvent* e, int b);
    22 
    23 	///Event handler function that handles dragging triangle
    24 	bool tri_mover(GdkEvent* e);
    25 
    26 	///Coordinates of Weight Point of tirangle
    27 	Gnome::Art::Point * wp;
    28 	///Array of nodes of planefigure
    29 	Gnome::Canvas::Ellipse ** nodes;
    30 	///Sides of planefigure
    31 	Gnome::Canvas::Polygon * sides;
    32 	///Group of graphical elements of triangle
    33 	Gnome::Canvas::Group triangle;
    34 
    35 	///Indicates whether the button of mouse is pressed or not
    36 	bool isbutton;
    37 
    38 	///Number Of Elements - the number of nodes
    39 	int noe;
    40 
    41 	///Array of coordinates
    42 	double * coordinates;
    43 
    44 	///At this location was the mousebutton pressed.
    45 	///It helps to calculate the distance of dragging.
    46 	double clicked_x, clicked_y;
    47 
    48 	///Remembers which Gnome::Canvas::Item was pressed.
    49 	///this variable is needed, because
    50 	///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
    51 	///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
    52 	Gnome::Canvas::Item * active_item;
    53 
    54 
    55 };
    56 
    57 ///When we click on the weight point we can drag the whole triangle. This function resolves it.
    58 bool CanvasExample::tri_mover(GdkEvent* e)
    59 {
    60 	switch(e->type)
    61 	{
    62 		case GDK_BUTTON_PRESS:
    63 			clicked_x=e->button.x;
    64 			clicked_y=e->button.y;
    65 			isbutton=true;
    66 			break;
    67 		case GDK_BUTTON_RELEASE:
    68 			isbutton=false;
    69 			active_item=NULL;
    70 			break;
    71 		case GDK_MOTION_NOTIFY:
    72 			if(isbutton)
    73 			{
    74 				double dx=e->motion.x-clicked_x;
    75 				double dy=e->motion.y-clicked_y;
    76 
    77 				Gnome::Canvas::Points coos;
    78 
    79 				for(int i=0;i<=noe;i++)
    80 				{
    81 					nodes[i]->move(dx,dy);
    82 
    83 					double x=(coordinates[2*i]+=dx);
    84 					double y=(coordinates[2*i+1]+=dy);
    85 
    86 					if(i!=noe)coos.push_back(Gnome::Art::Point(x,y));
    87 
    88 				}
    89 
    90 				clicked_x=e->motion.x;
    91 				clicked_y=e->motion.y;
    92 
    93 				sides->property_points().set_value(coos);
    94 			}
    95 		default: break;
    96 	}
    97 	return true;
    98 }
    99 
   100 ///This function moves only one node of triangle,
   101 ///but recalculate the location of wight point,
   102 ///and also redraw the sides of the planefigure.
   103 bool CanvasExample::event_handler(GdkEvent* e, int b)
   104 {
   105 	switch(e->type)
   106 	{
   107 		case GDK_BUTTON_PRESS:
   108 			clicked_x=e->button.x;
   109 			clicked_y=e->button.y;
   110 			active_item=(get_item_at(e->button.x, e->button.y));
   111 			isbutton=true;
   112 			break;
   113 		case GDK_BUTTON_RELEASE:
   114 			isbutton=false;
   115 			active_item=NULL;
   116 			break;
   117 		case GDK_MOTION_NOTIFY:
   118 			if(isbutton)
   119 			{
   120 				//double x1, y1, x2, y2;
   121 				//(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
   122 				//printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
   123 				//printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
   124 				double dx=e->motion.x-clicked_x;
   125 				double dy=e->motion.y-clicked_y;
   126 				active_item->move(dx, dy);
   127 
   128 				coordinates[2*b]+=dx;
   129 				coordinates[2*b+1]+=dy;
   130 
   131 				Gnome::Canvas::Points coos;
   132 
   133 				double x_wp=0;
   134 				double y_wp=0;
   135 
   136 				for(int i=0;i<noe;i++)
   137 				{
   138 					coos.push_back(Gnome::Art::Point(coordinates[2*i], coordinates[2*i+1]));
   139 
   140 					x_wp+=coordinates[2*i];
   141 					y_wp+=coordinates[2*i+1];
   142 				}
   143 
   144 				sides->property_points().set_value(coos);
   145 
   146 				x_wp/=noe;
   147 				y_wp/=noe;
   148 
   149 				dx=x_wp-coordinates[noe*2];
   150 				dy=y_wp-coordinates[noe*2+1];
   151 				nodes[noe]->move(dx, dy);
   152 
   153 				coordinates[noe*2]+=dx;
   154 				coordinates[noe*2+1]+=dy;
   155 
   156 				clicked_x=e->motion.x;
   157 				clicked_y=e->motion.y;
   158 			}
   159 		default: break;
   160 	}
   161 	return true;
   162 }
   163 
   164 CanvasExample::CanvasExample(double * coosarray, int numofcoos):triangle(*(root()), 0, 0),isbutton(false),active_item(NULL)
   165 {
   166 	noe=numofcoos/2;
   167 
   168 	coordinates=new double [numofcoos+2];
   169 
   170 	double x_wp=0;
   171 	double y_wp=0;
   172 
   173 	Gnome::Canvas::Points coos;
   174 	for(int i=0;i<numofcoos;i+=2)
   175 	{
   176 		coordinates[i]=coosarray[i];
   177 		coordinates[i+1]=coosarray[i+1];
   178 		coos.push_back(Gnome::Art::Point(coordinates[i],
   179 						 coordinates[i+1]));
   180 
   181 		x_wp+=coordinates[i];
   182 		y_wp+=coordinates[i+1];
   183 
   184 	}
   185 
   186 	sides=new Gnome::Canvas::Polygon(triangle, coos);
   187 	*sides << Gnome::Canvas::Properties::outline_color("green");
   188 	sides->property_width_pixels().set_value(10);
   189 
   190 	nodes=new Gnome::Canvas::Ellipse* [noe+1];
   191 
   192 	for(int i=0; i<noe;i++)
   193 	{
   194 		nodes[i]= new Gnome::Canvas::Ellipse(triangle, coos[i].get_x()-20, coos[i].get_y()-20, coos[i].get_x()+20, coos[i].get_y()+20);
   195 		*(nodes[i]) << Gnome::Canvas::Properties::fill_color("blue");
   196 		*(nodes[i]) << Gnome::Canvas::Properties::outline_color("black");
   197 		(nodes[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::event_handler),i));
   198 	}
   199 
   200 	coordinates[numofcoos]=x_wp/noe;
   201 	coordinates[numofcoos+1]=y_wp/noe;
   202 
   203 	wp=new Gnome::Art::Point(coordinates[numofcoos],coordinates[numofcoos+1]);
   204 
   205 	nodes[noe]= new Gnome::Canvas::Ellipse
   206 	(
   207 		triangle,
   208 		coordinates[numofcoos]-20,
   209 		coordinates[numofcoos+1]-20,
   210 		coordinates[numofcoos]+20,
   211 		coordinates[numofcoos+1]+20
   212 	);
   213 	*(nodes[noe]) << Gnome::Canvas::Properties::fill_color("blue");
   214 	*(nodes[noe]) << Gnome::Canvas::Properties::outline_color("black");
   215 	(nodes[noe])->signal_event().connect(sigc::mem_fun(*this, &CanvasExample::tri_mover));
   216 
   217 
   218 
   219 }
   220 
   221 CanvasExample::~CanvasExample()
   222 {
   223 }
   224 
   225 //MainWin:
   226 
   227 class MainWin : public Gtk::Window
   228 {
   229 public:
   230 	MainWin(const std::string& title, double *, int);
   231 
   232 protected:
   233 	//Member widgets:
   234 	CanvasExample m_canvas;
   235 };
   236 
   237 MainWin::MainWin(const std::string& title, double * coosarray, int noc):m_canvas(coosarray, noc)
   238 {
   239 	set_title (title);
   240 	add(m_canvas);
   241 	set_default_size(900,600);
   242 
   243 	show_all();
   244 }
   245 
   246 //main():
   247 
   248 int main(int argc, char *argv[])
   249 {
   250 	if((argc>=7)&& (argc%2) )
   251 	{
   252 		double * coosarray=new double[argc];
   253 
   254 		for(int i=1;i<argc;i++)
   255 		{
   256 			coosarray[i-1]=atof(argv[i]);
   257 			printf("%g%c",coosarray[i-1],i%2?' ':'\n');
   258 		}
   259 
   260 		Gnome::Canvas::init();
   261 		Gtk::Main app(argc, argv);
   262 
   263 		MainWin mainwin("Magic Triangle",coosarray,argc-1);
   264 		app.run(mainwin);
   265 	}
   266 
   267 	return 0;
   268 }