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