#include "xcddraw.h" extern "C" double sqrt(double ); void select_clicked_obj(int x,int y, long cur_time, GraphicsObject *&ret) /* drawing area coordinate, not an absolute coordinate */ { assert(selected_object == NULL); /* edge start point ? */ consedge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; repedge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; altedge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; inhedge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; paredge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; parinstedge_store->clicked_obj(ret,x,y,SELECT_EDGE_START_POINT); if (ret) return; /* edge end point ? */ consedge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; repedge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; altedge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; inhedge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; paredge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; parinstedge_store->clicked_obj(ret,x,y, SELECT_EDGE_END_POINT); if (ret) return; /* edge inner pointer ? */ consedge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; repedge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; altedge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; inhedge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; paredge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; parinstedge_store->clicked_obj(ret,x,y, SELECT_EDGE_INNER_POINT); if (ret) return; /* edge label */ consedge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; repedge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; altedge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; inhedge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; paredge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; parinstedge_store->clicked_obj(ret,x,y,SELECT_EDGE_LABEL); if (ret) return; /* vertex name */ vertex_store->clicked_obj(ret,x,y,SELECT_VERTEX_NAME); if (ret) return; /* edge */ consedge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; repedge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; altedge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; inhedge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; paredge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; parinstedge_store->clicked_obj(ret,x,y,SELECT_EDGE); if (ret) return; /* vertex ? */ vertex_store->clicked_obj(ret,x,y, SELECT_VERTEX); if (ret) return; } void VertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); consvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; altvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; repvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; termvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; paravstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; extvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; ubvstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void TemplateInstStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); instances->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void NameInsensitiveVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); vertices->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void NameSensitiveVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); if (vertices) vertices->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void NameSensitiveVertexList::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); elm->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; if (next) next->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void NameSensitiveVertex::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); vertices->clicked_obj(ret,clicked_x,clicked_y,selectflag); if (ret) return; tempinststore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void ConstructionVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); tempstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void AlternationVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); tempstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void RepetitionVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); tempstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void TerminalVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); vstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void UnboundVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); vstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void ParameterVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); vstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void ExternalVertexStore::clicked_obj( GraphicsObject *&ret, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); tempstore->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void ObjectStore::clicked_obj(GraphicsObject *&ret,int clicked_x,int clicked_y,selectflag_t selectflag) { if (objects) objects->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void GraphicsObjectList::clicked_obj(GraphicsObject *&ret,int clicked_x,int clicked_y,selectflag_t selectflag) { assert(this->get_elm()); this->get_elm()->clicked_obj(ret,this->get_elm(),clicked_x,clicked_y,selectflag); if (ret==NULL) if (this->get_next()) this->get_next()->clicked_obj(ret,clicked_x,clicked_y,selectflag); } void EdgeObject::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { assert(points); if ((selectflag == SELECT_EDGE_START_POINT) || (selectflag == SELECT_EDGE_END_POINT) || (selectflag == SELECT_EDGE_INNER_POINT) || (selectflag == SELECT_EDGE)) points->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); } void ConstructionEdge::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { assert(edge_label); if ((selectflag == SELECT_EDGE_START_POINT) || (selectflag == SELECT_EDGE_END_POINT) || (selectflag == SELECT_EDGE_INNER_POINT) || (selectflag == SELECT_EDGE)) this->EdgeObject::clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); else if (selectflag == SELECT_EDGE_LABEL) edge_label->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); } void VertexObject::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { assert( selectflag == SELECT_VERTEX_NAME || selectflag == SELECT_VERTEX); if (selectflag == SELECT_VERTEX_NAME) { static char pname[1024]; pname[0] = '\0'; if (this->no_parameters()) { assert(this->get_name()); this->get_name()-> get_parameterized_name(parassignstore,pname); pname[strlen(pname) - 2] = '\0'; } else { if (this->get_template_name()) /* template instance */ this->get_template_name()-> get_parameterized_name(parassignstore,pname); else /* template */ this->get_name()-> get_parameterized_name(parassignstore,pname); } int width = XTextWidth(class_font,pname,strlen(pname)); int height = class_font->ascent + class_font->descent; if ( (clicked_x >= name_x - pix_hoffset) && (clicked_x <= name_x - pix_hoffset + width) && (clicked_y <= name_y - pix_voffset) && (clicked_y >= name_y - pix_voffset - height) ) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } else { this->get_box()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); } } void EdgeLabelObject::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int width = XTextWidth(label_font,this->get_val(),strlen(this->get_val())); //this->get_text_width(); int height = label_font->ascent + label_font->descent; if ( (clicked_x >= this->get_x() - pix_hoffset) && (clicked_x <= this->get_x() - pix_hoffset + width) && (clicked_y <= this->get_y() - pix_voffset) && (clicked_y >= this->get_y() - pix_voffset - height) ) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void HexagonRect::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 34) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void Hexagon::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 34) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void ERectangle::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 34) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void TRectangle::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 34) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void Circle::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 24) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void Rectangle::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { int center_x = (this->get_x1() + this->get_x2())/2 - pix_hoffset; int center_y = (this->get_y1() + 20 + this->get_y2())/2 - pix_voffset; if ((abs(clicked_x - center_x) <= 34) && (abs(clicked_y - center_y) <= 24)) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } void PointObjectList::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { assert(selectflag == SELECT_EDGE_START_POINT || selectflag == SELECT_EDGE_END_POINT || selectflag == SELECT_EDGE_INNER_POINT || selectflag == SELECT_EDGE); if (selectflag == SELECT_EDGE_START_POINT) { if (this->get_prev() == NULL) /* select */ this->get_elm()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } if (selectflag == SELECT_EDGE_INNER_POINT) /* select inner points */ { if (this->get_prev() && this->get_next()) this->get_elm()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); if (ret) return; if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } if (selectflag == SELECT_EDGE_END_POINT) { if (this->get_next() == NULL) this->get_elm()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); else this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } if (selectflag == SELECT_EDGE) { /* select */ if (this->get_next()) { double x0 = this->get_elm()->get_x() - pix_hoffset; double y0 = this->get_elm()->get_y() - pix_voffset; double x1 = this->get_next()->get_elm()->get_x() - pix_hoffset; double y1 = this->get_next()->get_elm()->get_y() - pix_voffset; double x2 = clicked_x; double y2 = clicked_y; x1 = x1 - x0; y1 = y1 - y0; x2 = x2 - x0; y2 = y2 - y0; x0 = y0 = 0; double cos_alpha = x1*x2 + y1*y2; if (cos_alpha < 0) { if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } x0 = this->get_next()->get_elm()->get_x() - pix_hoffset; y0 = this->get_next()->get_elm()->get_y() - pix_voffset; x1 = this->get_elm()->get_x() - pix_hoffset; y1 = this->get_elm()->get_y() - pix_voffset; x2 = clicked_x; y2 = clicked_y; x1 = x1 - x0; y1 = y1 - y0; x2 = x2 - x0; y2 = y2 - y0; x0 = y0 = 0; cos_alpha = x1*x2 + y1*y2; if (cos_alpha < 0) { if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } if (y0 == y1) { if (abs(y2 - y0) < 4) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } else { if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } } if (x0 == x1) { if (abs(x2 - x0) < 4) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } else { if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); return; } } /* if ( ((abs(x2 - x1) < 4) || (abs(x2) < 4)) || ((abs(y2 - y1) < 4) || (abs(y2) < 4)) ) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } */ double sin_alpha = abs(x1*y2 - x2*y1)/ (sqrt(x1*x1 + y1*y1)*sqrt(x2*x2 + y2*y2)); x0 = this->get_elm()->get_x() - pix_hoffset; y0 = this->get_elm()->get_y() - pix_voffset; x2 = clicked_x; y2 = clicked_y; if ((sqrt((x2-x0)*(x2-x0) + (y2-y0)*(y2-y0)) * sin_alpha) < 4) { ret = cur_obj; ret->set_selected_flag(selectflag); return; } } if (ret == NULL) if (this->get_next()) this->get_next()->clicked_obj(ret,cur_obj,clicked_x,clicked_y,selectflag); } } void PointObject::clicked_obj(GraphicsObject *&ret, GraphicsObject *cur_obj, int clicked_x,int clicked_y, selectflag_t selectflag) { assert(selectflag == SELECT_EDGE_START_POINT || selectflag == SELECT_EDGE_END_POINT || selectflag == SELECT_EDGE_INNER_POINT); if ((abs((this->get_x() -pix_hoffset)- clicked_x) < 4) && (abs((this->get_y() -pix_voffset)- clicked_y) < 4)) { ret = cur_obj; ret->set_selected_flag(selectflag); this->set_selected_flag(selectflag); } }