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