src/work/peter/canvas-test.cc
author hegyi
Thu, 17 Mar 2005 11:45:05 +0000
changeset 1224 7f4f2855fa11
parent 1221 6706c788ebb5
child 1225 4401e1aeafcf
permissions -rw-r--r--
Magic triangle is a bit more DONE, and is already not only a triangle.
     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, bool b);
    22 
    23 	///Event handler function that handles dragging triangle
    24 	bool tri_mover(GdkEvent* e, bool b);
    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 	///At this location was the mousebutton pressed.
    42 	///It helps to calculate the distance of dragging.
    43 	double clicked_x, clicked_y;
    44 
    45 	///Remembers which Gnome::Canvas::Item was pressed.
    46 	///this variable is needed, because
    47 	///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
    48 	///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
    49 	Gnome::Canvas::Item * active_item;
    50 
    51 
    52 };
    53 
    54 ///When we click on the weight point we can drag the whole triangle. This function resolves it.
    55 bool CanvasExample::tri_mover(GdkEvent* e, bool b)
    56 {
    57 	b=b;
    58 	switch(e->type)
    59 	{
    60 		case GDK_BUTTON_PRESS:
    61 			clicked_x=e->button.x;
    62 			clicked_y=e->button.y;
    63 			isbutton=true;
    64 			break;
    65 		case GDK_BUTTON_RELEASE:
    66 			isbutton=false;
    67 			active_item=NULL;
    68 			break;
    69 		case GDK_MOTION_NOTIFY:
    70 			if(isbutton)
    71 			{
    72 				double dx=e->motion.x-clicked_x;
    73 				double dy=e->motion.y-clicked_y;
    74 				for(int i=0;i<=noe;i++)
    75 				{
    76 					nodes[i]->move(dx,dy);
    77 				}
    78 				clicked_x=e->motion.x;
    79 				clicked_y=e->motion.y;
    80 
    81 				Gnome::Canvas::Points coos;
    82 				for(int i=0;i<noe;i++)
    83 				{
    84 					double x1,y1,x2,y2;
    85 					nodes[i]->get_bounds(x1,y1,x2,y2);
    86 					double x=(x1+x2)/2;
    87 					double y=(y1+y2)/2;
    88 					coos.push_back(Gnome::Art::Point(x, y));
    89 				}
    90 				sides->property_points().set_value(coos);
    91 
    92 			}
    93 		default: break;
    94 	}
    95 	return true;
    96 }
    97 
    98 ///This function moves only one node of triangle,
    99 ///but recalculate the location of wight point,
   100 ///and also redraw the sides of the planefigure.
   101 bool CanvasExample::event_handler(GdkEvent* e, bool b)
   102 {
   103 	b=b;
   104 	switch(e->type)
   105 	{
   106 		case GDK_BUTTON_PRESS:
   107 			clicked_x=e->button.x;
   108 			clicked_y=e->button.y;
   109 			active_item=(get_item_at(e->button.x, e->button.y));
   110 			isbutton=true;
   111 			break;
   112 		case GDK_BUTTON_RELEASE:
   113 			isbutton=false;
   114 			active_item=NULL;
   115 			break;
   116 		case GDK_MOTION_NOTIFY:
   117 			if(isbutton)
   118 			{
   119 				//double x1, y1, x2, y2;
   120 				//(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
   121 				//printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
   122 				//printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
   123 				double dx=e->motion.x-clicked_x;
   124 				double dy=e->motion.y-clicked_y;
   125 				active_item->move(dx, dy);
   126 
   127 				Gnome::Canvas::Points coos;
   128 
   129 				double x_wp=0;
   130 				double y_wp=0;
   131 
   132 				for(int i=0;i<noe;i++)
   133 				{
   134 					double x1,y1,x2,y2;
   135 					nodes[i]->get_bounds(x1,y1,x2,y2);
   136 					double x=(x1+x2)/2;
   137 					double y=(y1+y2)/2;
   138 					coos.push_back(Gnome::Art::Point(x, y));
   139 
   140 					x_wp+=x;
   141 					y_wp+=y;
   142 				}
   143 
   144 				sides->property_points().set_value(coos);
   145 
   146 				x_wp/=noe;
   147 				y_wp/=noe;
   148 
   149 				double x1,y1,x2,y2;
   150 				nodes[noe]->get_bounds(x1,y1,x2,y2);
   151 				double x=(x1+x2)/2;
   152 				double y=(y1+y2)/2;
   153 
   154 				dx=x_wp-x;
   155 				dy=y_wp-y;
   156 				nodes[noe]->move(dx, dy);
   157 
   158 				clicked_x=e->motion.x;
   159 				clicked_y=e->motion.y;
   160 			}
   161 		default: break;
   162 	}
   163 	return true;
   164 }
   165 
   166 CanvasExample::CanvasExample(double * coosarray, int numofcoos):triangle(*(root()), 0, 0),isbutton(false),active_item(NULL)
   167 {
   168 	noe=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++)
   175 	{
   176 		double x=coosarray[i++];
   177 		double y=coosarray[i];
   178 		coos.push_back(Gnome::Art::Point(x, y));
   179 
   180 		x_wp+=x;
   181 		y_wp+=y;
   182 
   183 	}
   184 
   185 	sides=new Gnome::Canvas::Polygon(triangle, coos);
   186 	*sides << Gnome::Canvas::Properties::outline_color("green");
   187 	sides->property_width_pixels().set_value(10);
   188 
   189 	nodes=new Gnome::Canvas::Ellipse* [noe+1];
   190 
   191 	for(int i=0; i<noe;i++)
   192 	{
   193 		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);
   194 		*(nodes[i]) << Gnome::Canvas::Properties::fill_color("blue");
   195 		*(nodes[i]) << Gnome::Canvas::Properties::outline_color("black");
   196 		(nodes[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::event_handler),true));
   197 	}
   198 
   199 	wp=new Gnome::Art::Point(x_wp/noe,y_wp/noe);
   200 
   201 	nodes[noe]= new Gnome::Canvas::Ellipse(triangle, wp->get_x()-20, wp->get_y()-20, wp->get_x()+20, wp->get_y()+20);
   202 	*(nodes[noe]) << Gnome::Canvas::Properties::fill_color("blue");
   203 	*(nodes[noe]) << Gnome::Canvas::Properties::outline_color("black");
   204 	(nodes[noe])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::tri_mover),true));
   205 
   206 
   207 }
   208 
   209 CanvasExample::~CanvasExample()
   210 {
   211 }
   212 
   213 //MainWin:
   214 
   215 class MainWin : public Gtk::Window
   216 {
   217 public:
   218 	MainWin(const std::string& title, double *, int);
   219 
   220 protected:
   221 	//Member widgets:
   222 	CanvasExample m_canvas;
   223 };
   224 
   225 MainWin::MainWin(const std::string& title, double * coosarray, int noc):m_canvas(coosarray, noc)
   226 {
   227 	set_title (title);
   228 	add(m_canvas);
   229 	set_default_size(900,600);
   230 
   231 	show_all();
   232 }
   233 
   234 //main():
   235 
   236 int main(int argc, char *argv[])
   237 {
   238 	if((argc>=7)&&( (argc/2)!=( (argc+1)/2 ) ) )
   239 	{
   240 		double * coosarray=new double[argc];
   241 
   242 		for(int i=1;i<argc;i++)
   243 		{
   244 			coosarray[i-1]=atof(argv[i]);
   245 		}
   246 
   247 		Gnome::Canvas::init();
   248 		Gtk::Main app(argc, argv);
   249 
   250 		MainWin mainwin("Magic Triangle",coosarray,argc-1);
   251 		app.run(mainwin);
   252 	}
   253 
   254 	return 0;
   255 }