src/work/peter/canvas-test.cc
changeset 1224 7f4f2855fa11
parent 1221 6706c788ebb5
child 1225 4401e1aeafcf
equal deleted inserted replaced
1:338b56c3315d 2:20b268a45773
    14 public:
    14 public:
    15 	CanvasExample(double *, int);
    15 	CanvasExample(double *, int);
    16 	virtual ~CanvasExample();
    16 	virtual ~CanvasExample();
    17 
    17 
    18 private:
    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
    19 	int noe;
    39 	int noe;
    20 
    40 
    21 	bool isbutton;
    41 	///At this location was the mousebutton pressed.
       
    42 	///It helps to calculate the distance of dragging.
    22 	double clicked_x, clicked_y;
    43 	double clicked_x, clicked_y;
    23 
    44 
       
    45 	///Remembers which Gnome::Canvas::Item was pressed.
    24 	///this variable is needed, because
    46 	///this variable is needed, because
    25 	///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
    47 	///1. we cannot query the item at he cursor as fast as it could not cause a Segmentation Fault
    26 	///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
    48 	///2. we would like to handle only ony item per movement, therefore quering it is not a working solution
    27 	Gnome::Canvas::Item * active_item;
    49 	Gnome::Canvas::Item * active_item;
    28 
    50 
    29 	bool event_handler(GdkEvent* e, bool b);
    51 
    30 	bool tri_mover(GdkEvent* e, bool b);
       
    31 	Gnome::Art::Point * wp;
       
    32 	Gnome::Canvas::Ellipse ** nodes;
       
    33 	Gnome::Canvas::Polygon * sides;
       
    34 	Gnome::Canvas::Group triangle;
       
    35 };
    52 };
    36 
    53 
       
    54 ///When we click on the weight point we can drag the whole triangle. This function resolves it.
    37 bool CanvasExample::tri_mover(GdkEvent* e, bool b)
    55 bool CanvasExample::tri_mover(GdkEvent* e, bool b)
    38 {
    56 {
       
    57 	b=b;
    39 	switch(e->type)
    58 	switch(e->type)
    40 	{
    59 	{
    41 		case GDK_BUTTON_PRESS:
    60 		case GDK_BUTTON_PRESS:
    42 			clicked_x=e->button.x;
    61 			clicked_x=e->button.x;
    43 			clicked_y=e->button.y;
    62 			clicked_y=e->button.y;
    48 			active_item=NULL;
    67 			active_item=NULL;
    49 			break;
    68 			break;
    50 		case GDK_MOTION_NOTIFY:
    69 		case GDK_MOTION_NOTIFY:
    51 			if(isbutton)
    70 			if(isbutton)
    52 			{
    71 			{
    53 				//double x1, y1, x2, y2;
       
    54 				//(get_item_at(e->motion.x, e->motion.y))->get_bounds(x1, y1, x2, y2);
       
    55 				//printf("Item coos: %d %d %d %d\n", (int)x1, (int)y1, (int)x2, (int)y2);
       
    56 				//printf("Mouse is moved! %d %d\n",(int)e->motion.x,(int)e->motion.y);
       
    57 				double dx=e->motion.x-clicked_x;
    72 				double dx=e->motion.x-clicked_x;
    58 				double dy=e->motion.y-clicked_y;
    73 				double dy=e->motion.y-clicked_y;
    59 				for(int i=0;i<=noe/2;i++)
    74 				for(int i=0;i<=noe;i++)
    60 				{
    75 				{
    61 					nodes[i]->move(dx,dy);
    76 					nodes[i]->move(dx,dy);
    62 				}
    77 				}
    63 				clicked_x=e->motion.x;
    78 				clicked_x=e->motion.x;
    64 				clicked_y=e->motion.y;
    79 				clicked_y=e->motion.y;
    65 
    80 
    66 				Gnome::Canvas::Points coos;
    81 				Gnome::Canvas::Points coos;
    67 				for(int i=0;i<noe/2;i++)
    82 				for(int i=0;i<noe;i++)
    68 				{
    83 				{
    69 					double x1,y1,x2,y2;
    84 					double x1,y1,x2,y2;
    70 					nodes[i]->get_bounds(x1,y1,x2,y2);
    85 					nodes[i]->get_bounds(x1,y1,x2,y2);
    71 					double x=(x1+x2)/2;
    86 					double x=(x1+x2)/2;
    72 					double y=(y1+y2)/2;
    87 					double y=(y1+y2)/2;
    75 				sides->property_points().set_value(coos);
    90 				sides->property_points().set_value(coos);
    76 
    91 
    77 			}
    92 			}
    78 		default: break;
    93 		default: break;
    79 	}
    94 	}
    80 }
    95 	return true;
    81 
    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.
    82 bool CanvasExample::event_handler(GdkEvent* e, bool b)
   101 bool CanvasExample::event_handler(GdkEvent* e, bool b)
    83 {
   102 {
       
   103 	b=b;
    84 	switch(e->type)
   104 	switch(e->type)
    85 	{
   105 	{
    86 		case GDK_BUTTON_PRESS:
   106 		case GDK_BUTTON_PRESS:
    87 			clicked_x=e->button.x;
   107 			clicked_x=e->button.x;
    88 			clicked_y=e->button.y;
   108 			clicked_y=e->button.y;
   107 				Gnome::Canvas::Points coos;
   127 				Gnome::Canvas::Points coos;
   108 
   128 
   109 				double x_wp=0;
   129 				double x_wp=0;
   110 				double y_wp=0;
   130 				double y_wp=0;
   111 
   131 
   112 				for(int i=0;i<noe/2;i++)
   132 				for(int i=0;i<noe;i++)
   113 				{
   133 				{
   114 					double x1,y1,x2,y2;
   134 					double x1,y1,x2,y2;
   115 					nodes[i]->get_bounds(x1,y1,x2,y2);
   135 					nodes[i]->get_bounds(x1,y1,x2,y2);
   116 					double x=(x1+x2)/2;
   136 					double x=(x1+x2)/2;
   117 					double y=(y1+y2)/2;
   137 					double y=(y1+y2)/2;
   118 					coos.push_back(Gnome::Art::Point(x, y));
   138 					coos.push_back(Gnome::Art::Point(x, y));
   119 
   139 
   120 					if(i<3)
   140 					x_wp+=x;
   121 					{
   141 					y_wp+=y;
   122 						x_wp+=x;
       
   123 						y_wp+=y;
       
   124 					}
       
   125 				}
   142 				}
   126 
   143 
   127 				sides->property_points().set_value(coos);
   144 				sides->property_points().set_value(coos);
   128 
   145 
   129 				x_wp/=3;
   146 				x_wp/=noe;
   130 				y_wp/=3;
   147 				y_wp/=noe;
   131 
   148 
   132 				double x1,y1,x2,y2;
   149 				double x1,y1,x2,y2;
   133 				nodes[noe/2]->get_bounds(x1,y1,x2,y2);
   150 				nodes[noe]->get_bounds(x1,y1,x2,y2);
   134 				double x=(x1+x2)/2;
   151 				double x=(x1+x2)/2;
   135 				double y=(y1+y2)/2;
   152 				double y=(y1+y2)/2;
   136 
   153 
   137 				dx=x_wp-x;
   154 				dx=x_wp-x;
   138 				dy=y_wp-y;
   155 				dy=y_wp-y;
   139 				nodes[noe/2]->move(dx, dy);
   156 				nodes[noe]->move(dx, dy);
   140 
   157 
   141 				clicked_x=e->motion.x;
   158 				clicked_x=e->motion.x;
   142 				clicked_y=e->motion.y;
   159 				clicked_y=e->motion.y;
   143 			}
   160 			}
   144 		default: break;
   161 		default: break;
   145 	}
   162 	}
   146 }
   163 	return true;
   147 
   164 }
   148 CanvasExample::CanvasExample(double * coosarray, int numofels):triangle(*(root()), 0, 0),isbutton(false),active_item(NULL)
   165 
   149 {
   166 CanvasExample::CanvasExample(double * coosarray, int numofcoos):triangle(*(root()), 0, 0),isbutton(false),active_item(NULL)
   150 	noe=numofels;
   167 {
   151 
   168 	noe=numofcoos/2;
   152 	int j=0;
   169 
   153 	double ax=coosarray[j++];
   170 	double x_wp=0;
   154 	double ay=coosarray[j++];
   171 	double y_wp=0;
   155 	double bx=coosarray[j++];
       
   156 	double by=coosarray[j++];
       
   157 	double cx=coosarray[j++];
       
   158 	double cy=coosarray[j++];
       
   159 
   172 
   160 	Gnome::Canvas::Points coos;
   173 	Gnome::Canvas::Points coos;
   161 	for(int i=0;i<noe;i++)
   174 	for(int i=0;i<numofcoos;i++)
   162 	{
   175 	{
   163 		double x=coosarray[i++];
   176 		double x=coosarray[i++];
   164 		double y=coosarray[i];
   177 		double y=coosarray[i];
   165 		coos.push_back(Gnome::Art::Point(x, y));
   178 		coos.push_back(Gnome::Art::Point(x, y));
       
   179 
       
   180 		x_wp+=x;
       
   181 		y_wp+=y;
       
   182 
   166 	}
   183 	}
   167 
   184 
   168 	sides=new Gnome::Canvas::Polygon(triangle, coos);
   185 	sides=new Gnome::Canvas::Polygon(triangle, coos);
   169 	*sides << Gnome::Canvas::Properties::outline_color("green");
   186 	*sides << Gnome::Canvas::Properties::outline_color("green");
   170 	sides->property_width_pixels().set_value(10);
   187 	sides->property_width_pixels().set_value(10);
   171 
   188 
   172 	nodes=new ( Gnome::Canvas::Ellipse * ) [noe/2+1];
   189 	nodes=new Gnome::Canvas::Ellipse* [noe+1];
   173 
   190 
   174 	for(int i=0; i<noe/2;i++)
   191 	for(int i=0; i<noe;i++)
   175 	{
   192 	{
   176 		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);
   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);
   177 		*(nodes[i]) << Gnome::Canvas::Properties::fill_color("blue");
   194 		*(nodes[i]) << Gnome::Canvas::Properties::fill_color("blue");
   178 		*(nodes[i]) << Gnome::Canvas::Properties::outline_color("black");
   195 		*(nodes[i]) << Gnome::Canvas::Properties::outline_color("black");
   179 		(nodes[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::event_handler),true));
   196 		(nodes[i])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::event_handler),true));
   180 	}
   197 	}
   181 
   198 
   182 	wp=new Gnome::Art::Point((ax+bx+cx)/3,(ay+by+cy)/3);
   199 	wp=new Gnome::Art::Point(x_wp/noe,y_wp/noe);
   183 
   200 
   184 	nodes[noe/2]= new Gnome::Canvas::Ellipse(triangle, wp->get_x()-20, wp->get_y()-20, wp->get_x()+20, wp->get_y()+20);
   201 	nodes[noe]= new Gnome::Canvas::Ellipse(triangle, wp->get_x()-20, wp->get_y()-20, wp->get_x()+20, wp->get_y()+20);
   185 	*(nodes[noe/2]) << Gnome::Canvas::Properties::fill_color("blue");
   202 	*(nodes[noe]) << Gnome::Canvas::Properties::fill_color("blue");
   186 	*(nodes[noe/2]) << Gnome::Canvas::Properties::outline_color("black");
   203 	*(nodes[noe]) << Gnome::Canvas::Properties::outline_color("black");
   187 	(nodes[noe/2])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::tri_mover),true));
   204 	(nodes[noe])->signal_event().connect(sigc::bind(sigc::mem_fun(*this, &CanvasExample::tri_mover),true));
   188 
   205 
   189 
   206 
   190 }
   207 }
   191 
   208 
   192 CanvasExample::~CanvasExample()
   209 CanvasExample::~CanvasExample()
   203 protected:
   220 protected:
   204 	//Member widgets:
   221 	//Member widgets:
   205 	CanvasExample m_canvas;
   222 	CanvasExample m_canvas;
   206 };
   223 };
   207 
   224 
   208 MainWin::MainWin(const std::string& title, double * coosarray, int noe):m_canvas(coosarray, noe)
   225 MainWin::MainWin(const std::string& title, double * coosarray, int noc):m_canvas(coosarray, noc)
   209 {
   226 {
   210 	set_title (title);
   227 	set_title (title);
   211 	add(m_canvas);
   228 	add(m_canvas);
   212 	set_default_size(900,600);
   229 	set_default_size(900,600);
   213 
   230 
   232 
   249 
   233 		MainWin mainwin("Magic Triangle",coosarray,argc-1);
   250 		MainWin mainwin("Magic Triangle",coosarray,argc-1);
   234 		app.run(mainwin);
   251 		app.run(mainwin);
   235 	}
   252 	}
   236 
   253 
   237 	printf("Usage:\n./triangle x1 y1 x2 y2 x3 y3\nWhere xi and yi are the coordinates of the points of the triangle\n");
       
   238 
       
   239 	return 0;
   254 	return 0;
   240 }
   255 }