#include "xcddraw.h" extern "C" double sin(double); extern "C" double cos(double); extern "C" double sqrt(double); void ObjectStore::draw_last_seg() { if (objects) objects->draw_last_seg(); } void ObjectStore::draw_first_seg() { if (objects) objects->draw_first_seg(); } void GraphicsObjectList::draw_last_seg() { elm->draw_last_seg(); if (next) next->draw_last_seg(); } void GraphicsObjectList::draw_first_seg() { elm->draw_first_seg(); if (next) next->draw_first_seg(); } void GraphicsObject::draw_last_seg() { } void GraphicsObject::draw_first_seg() { } void EdgeObject::draw_last_seg() { this->get_points()->draw_last_seg(this->get_kind()); } void EdgeObject::draw_first_seg() { if (this->get_points()->length() == 2) this->draw_last_seg(); else { this->get_points()->draw_first_seg(this->get_kind()); } } void PointObjectList::draw_first_seg(draw_kind kind) { XPoint pts[2]; int l = 2; pts[0].x = elm->get_x() - pix_hoffset; pts[0].y = elm->get_y() - pix_voffset; pts[1].x = next->get_elm()->get_x() - pix_hoffset; pts[1].y = next->get_elm()->get_y() - pix_voffset; switch(kind) { case ALT_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case REQ_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case REQ_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case INH_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case PAR_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pe_gc,pts,l,CoordModeOrigin); break; case PAR_INST_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pie_gc,pts,l,CoordModeOrigin); break; default: fprintf(stderr,"Unknown edge kind: %d\n",kind); exit(1); } } void PointObjectList::draw_inner(draw_kind kind,int cur_p, int exp_p) { if (cur_p < exp_p) { next->draw_inner(kind,cur_p+1,exp_p); return; } XPoint pts[2]; int l = 2; pts[0].x = elm->get_x() - pix_hoffset; pts[0].y = elm->get_y() - pix_voffset; pts[1].x = next->get_elm()->get_x() - pix_hoffset; pts[1].y = next->get_elm()->get_y() - pix_voffset; switch(kind) { case ALT_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case REQ_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case REQ_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case INH_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case PAR_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pe_gc,pts,l,CoordModeOrigin); break; case PAR_INST_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pie_gc,pts,l,CoordModeOrigin); break; default: fprintf(stderr,"Unknown edge kind: %d\n",kind); exit(1); } } void PointObjectList::draw_last_seg(draw_kind kind) { if (next) { next->draw_last_seg(kind); return; } XPoint pts[2]; int l = 2; pts[0].x = elm->get_x() - pix_hoffset; pts[0].y = elm->get_y() - pix_voffset; pts[1].x = prev->get_elm()->get_x() - pix_hoffset; pts[1].y = prev->get_elm()->get_y() - pix_voffset; switch(kind) { case ALT_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case REQ_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_C_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case REQ_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case OPT_R_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_re_gc,pts,l,CoordModeOrigin); break; case INH_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_bgc,pts,l,CoordModeOrigin); XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_ae_fgc,pts,l,CoordModeOrigin); break; case PAR_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pe_gc,pts,l,CoordModeOrigin); break; case PAR_INST_EDGE: XDrawLines(XtDisplay(draw_area),XtWindow(draw_area),xor_pie_gc,pts,l,CoordModeOrigin); break; default: fprintf(stderr,"Unknown edge kind: %d\n",kind); exit(1); } int x1 = this->get_prev()->get_elm()->get_x() - pix_hoffset; int y1 = this->get_prev()->get_elm()->get_y() - pix_voffset; int x2 = this->get_elm()->get_x() - pix_hoffset; int y2 = this->get_elm()->get_y() - pix_voffset; static double theta = 3.14159265358979323846/7; static double sin_theta = sin(theta); static double cos_theta = cos(theta); /* draw arrow */ double arrow_slope_length; if (kind == INH_EDGE || kind == ALT_EDGE || kind == PAR_INST_EDGE) arrow_slope_length = 20; else if (kind == PAR_EDGE) arrow_slope_length = 10; else arrow_slope_length = 15; if (y1 == y2) { int xd1,yd1,xd2,yd2,xd3,yd3,xd4,yd4; XPoint points[4]; xd1 = x2; yd1 = y2; yd2 = yd1 + (int) (arrow_slope_length * sin_theta); yd3 = yd1; yd4 = yd1 - (int) (arrow_slope_length * sin_theta); if (x1 > x2) { xd2 = xd4 = x2 + (int) (arrow_slope_length * cos_theta); xd3 = x2 + (int)(arrow_slope_length/2); } else { xd2 = xd4 = x2 - (int) (arrow_slope_length * cos_theta); xd3 = x2 - (int)(arrow_slope_length/2); } points[0].x = xd1; points[0].y = yd1; points[1].x = xd2; points[1].y = yd2; points[2].x = xd3; points[2].y = yd3; points[3].x = xd4; points[3].y = yd4; XFillPolygon(XtDisplay(draw_area),XtWindow(draw_area),xor_p_v_gc, points,4,Nonconvex, CoordModeOrigin); return; } else if (x1 == x2) { int xd1,yd1,xd2,yd2,xd3,yd3,xd4,yd4; XPoint points[4]; xd1 = x2; yd1 = y2; xd2 = xd1 + (int) (arrow_slope_length * sin_theta); xd3 = xd1; xd4 = xd1 - (int) (arrow_slope_length * sin_theta); if (y1 > y2) { yd2 = yd4 = y2 + (int) (arrow_slope_length * cos_theta); yd3 = y2 + (int)(arrow_slope_length/2); } else { yd2 = yd4 = y2 - (int) (arrow_slope_length * cos_theta); yd3 = y2 - (int)(arrow_slope_length/2); } points[0].x = xd1; points[0].y = yd1; points[1].x = xd2; points[1].y = yd2; points[2].x = xd3; points[2].y = yd3; points[3].x = xd4; points[3].y = yd4; XFillPolygon(XtDisplay(draw_area),XtWindow(draw_area),xor_p_v_gc, points,4,Nonconvex, CoordModeOrigin); return; } else { double xd1,yd1; XPoint points[4]; xd1 = x2; yd1 = y2; double d = sqrt(((double)x1-(double)x2) * ((double)x1-(double)x2) + ((double)y1-(double)y2) * ((double)y1-(double)y2)); double xd2 = cos_theta; double yd2 = sin_theta; double xd3 = 0.6; double yd3 = 0; double xd4 = xd2; double yd4 = -yd2; /* rotate */ double sin_gamma = ((double)y1-(double)y2)/d; double cos_gamma = ((double)x1-(double)x2)/d; double tx = xd2*cos_gamma - yd2*sin_gamma; double ty = xd2*sin_gamma + yd2*cos_gamma; xd2 = tx; yd2 = ty; tx = xd3*cos_gamma - yd3*sin_gamma; ty = xd3*sin_gamma + yd3*cos_gamma; xd3 = tx; yd3 = ty; tx = xd4*cos_gamma - yd4*sin_gamma; ty = xd4*sin_gamma + yd4*cos_gamma; xd4 = tx; yd4 = ty; d = sqrt(tx*tx + ty*ty); xd2 = xd2/d*arrow_slope_length + x2; xd3 = xd3/d*arrow_slope_length + x2; xd4 = xd4/d*arrow_slope_length + x2; yd2 = yd2/d*arrow_slope_length + y2; yd3 = yd3/d*arrow_slope_length + y2; yd4 = yd4/d*arrow_slope_length + y2; points[0].x = (int)xd1; points[0].y = (int)yd1; points[1].x = (int)xd2; points[1].y = (int)yd2; points[2].x = (int)xd3; points[2].y = (int)yd3; points[3].x = (int)xd4; points[3].y = (int)yd4; XFillPolygon(XtDisplay(draw_area),XtWindow(draw_area),xor_p_v_gc, points,4,Nonconvex, CoordModeOrigin); return; } } void ConstructionEdge::draw_last_seg() { if (this->get_points()->length() == 2) this->get_edge_label()->draw(xor_label_gc); this->EdgeObject::draw_last_seg(); } void ConstructionEdge::draw_first_seg() { if (this->get_points()->length() == 2) this->draw_last_seg(); else { this->get_edge_label()->draw(xor_label_gc); this->EdgeObject::draw_first_seg(); } } int PointObjectList::selected_points_position(int b) { assert(next); if (this->get_elm()->get_selected_flag() == SELECT_EDGE_INNER_POINT) return b; else return next->selected_points_position(b+1); } void EdgeObject::draw_inner_segs() { int p = this->get_points()->selected_points_position(1); int l = this->get_points()->length(); if (p == l - 1) { this->EdgeObject::draw_last_seg(); this->get_points()->draw_inner(this->get_kind(),1,p-1); } else { this->get_points()->draw_inner(this->get_kind(),1,p); this->get_points()->draw_inner(this->get_kind(),1,p-1); } } void ConstructionEdge::draw_inner_segs() { int p = this->get_points()->selected_points_position(1); int l = this->get_points()->length(); if (p == 2) this->get_edge_label()->draw(xor_label_gc); if (p == l - 1) { this->EdgeObject::draw_last_seg(); this->get_points()->draw_inner(this->get_kind(),1,p-1); } else { this->get_points()->draw_inner(this->get_kind(),1,p); this->get_points()->draw_inner(this->get_kind(),1,p-1); } } void VertexObject::move_vertex(int dx, int dy) { box->set_x1(dx + box->get_x1()); box->set_y1(dy + box->get_y1()); box->set_x2(dx + box->get_x2()); box->set_y2(dy + box->get_y2()); name_x += dx; name_y += dy; this->get_incoming_consedge_store()->moveEndPoint(dx,dy); this->get_incoming_repedge_store()->moveEndPoint(dx,dy); this->get_incoming_altedge_store()->moveEndPoint(dx,dy); this->get_incoming_inhedge_store()->moveEndPoint(dx,dy); this->get_incoming_paredge_store()->moveEndPoint(dx,dy); this->get_incoming_parinstedge_store()->moveEndPoint(dx,dy); this->get_outgoing_consedge_store()->moveStartPoint(dx,dy); this->get_outgoing_repedge_store()->moveStartPoint(dx,dy); this->get_outgoing_altedge_store()->moveStartPoint(dx,dy); this->get_outgoing_inhedge_store()->moveStartPoint(dx,dy); this->get_outgoing_paredge_store()->moveStartPoint(dx,dy); this->get_outgoing_parinstedge_store()->moveStartPoint(dx,dy); } void ObjectStore::moveStartPoint(int dx,int dy) { if (objects) objects->moveStartPoint(dx,dy); } void ObjectStore::moveEndPoint(int dx,int dy) { if (objects) objects->moveEndPoint(dx,dy); } void GraphicsObjectList::moveStartPoint(int dx,int dy) { elm->moveStartPoint(dx,dy); if (next) next->moveStartPoint(dx,dy); } void GraphicsObjectList::moveEndPoint(int dx,int dy) { elm->moveEndPoint(dx,dy); if (next) next->moveEndPoint(dx,dy); } void GraphicsObject::moveStartPoint(int dx,int dy) { } void GraphicsObject::moveEndPoint(int dx,int dy) { } void ConstructionEdge::moveStartPoint(int dx,int dy) { this->get_points()->moveConsStartPoint(dx,dy,this->get_edge_label()); } void ConstructionEdge::moveEndPoint(int dx,int dy) { this->get_points()->moveConsEndPoint(dx,dy,this->get_edge_label()); } void EdgeObject::moveStartPoint(int dx,int dy) { this->get_points()->moveStartPoint(dx,dy); } void EdgeObject::moveEndPoint(int dx,int dy) { this->get_points()->moveEndPoint(dx,dy); } void PointObjectList::moveStartPoint(int dx,int dy) { int x1 = elm->get_x(); int y1 = elm->get_y(); elm->set_x(x1 + dx); elm->set_y(y1 + dy); } void PointObjectList::moveEndPoint(int dx,int dy) { if (next->get_next() == NULL) { int x2 = next->get_elm()->get_x(); int y2 = next->get_elm()->get_y(); next->get_elm()->set_x(x2 + dx); next->get_elm()->set_y(y2 + dy); } else next->moveEndPoint(dx,dy); } void PointObjectList::moveConsStartPoint(int dx,int dy,EdgeLabelObject *el) { int x1 = elm->get_x(); int y1 = elm->get_y(); int x2 = next->get_elm()->get_x(); int y2 = next->get_elm()->get_y(); elm->set_x(x1 + dx); elm->set_y(y1 + dy); dx = (elm->get_x() + x2)/2 - (x1 + x2)/2; dy = (elm->get_y() + y2)/2 - (y1 + y2)/2; el->set_x(el->get_x() + dx); el->set_y(el->get_y() + dy); } void PointObjectList::moveConsEndPoint(int dx,int dy,EdgeLabelObject *el) { if (next->get_next() == NULL) { int x1 = elm->get_x(); int y1 = elm->get_y(); int x2 = next->get_elm()->get_x(); int y2 = next->get_elm()->get_y(); next->get_elm()->set_x(x2 + dx); next->get_elm()->set_y(y2 + dy); if (prev == NULL) { dx = (next->get_elm()->get_x() + x1)/2 - (x1 + x2)/2; dy = (next->get_elm()->get_y() + y1)/2 - (y1 + y2)/2; el->set_x(el->get_x() + dx); el->set_y(el->get_y() + dy); } } else next->moveConsEndPoint(dx,dy,el); } void GraphicsObject::drawRelated() { } void EdgeObject::drawRelated() { if (this->get_selected_flag() == SELECT_EDGE_START_POINT) this->draw_first_seg(); else if (this->get_selected_flag() == SELECT_EDGE_END_POINT) this->draw_last_seg(); else if (this->get_selected_flag() == SELECT_EDGE_INNER_POINT) this->draw_inner_segs(); } void VertexObject::drawRelated() { this->draw(); this->get_incoming_consedge_store()->draw_last_seg(); this->get_incoming_repedge_store()->draw_last_seg(); this->get_incoming_altedge_store()->draw_last_seg(); this->get_incoming_inhedge_store()->draw_last_seg(); this->get_incoming_paredge_store()->draw_last_seg(); this->get_incoming_parinstedge_store()->draw_last_seg(); this->get_outgoing_consedge_store()->draw_first_seg(); this->get_outgoing_repedge_store()->draw_first_seg(); this->get_outgoing_altedge_store()->draw_first_seg(); this->get_outgoing_inhedge_store()->draw_first_seg(); this->get_outgoing_paredge_store()->draw_first_seg(); this->get_outgoing_parinstedge_store()->draw_first_seg(); } void GraphicsObject::move_start_point(int x,int y) { } void GraphicsObject::move_end_point(int x,int y) { } void GraphicsObject::move_inner_point(int x,int y) { } void EdgeObject::move_start_point(int mx,int my) { int rx,ry; VertexObject* end_v = NULL; this->get_from_vertex()->select_box(rx,ry,mx,my,end_v); if (end_v) { this->get_points()->get_elm()->set_x(rx); this->get_points()->get_elm()->set_y(ry); } } void EdgeObject::move_end_point(int mx,int my) { int rx,ry; VertexObject* end_v = NULL; this->get_to_vertex()->select_box(rx,ry,mx,my,end_v); if (end_v) { this->get_points()->move_end_point(rx,ry); } } void PointObjectList::move_end_point(int rx,int ry) { if (next == NULL) { elm->set_x(rx); elm->set_y(ry); } else next->move_end_point(rx,ry); } void EdgeObject::move_inner_point(int dx,int dy) { this->get_points()->move_inner_point(dx,dy); } void PointObjectList::move_inner_point(int dx,int dy) { if (elm->get_selected_flag() == SELECT_EDGE_INNER_POINT) { int x1 = elm->get_x(); int y1 = elm->get_y(); elm->set_x(x1 + dx); elm->set_y(y1 + dy); } else if (next) next->move_inner_point(dx,dy); } void ConstructionEdge::move_start_point(int mx,int my) { int rx,ry; VertexObject* end_v = NULL; this->get_from_vertex()->select_box(rx,ry,mx,my,end_v); if (end_v) { int x = this->get_points()->get_elm()->get_x(); int y = this->get_points()->get_elm()->get_y(); this->get_points()->moveConsStartPoint(rx - x,ry - y,this->get_edge_label()); } } void ConstructionEdge::move_end_point(int mx,int my) { int rx,ry; VertexObject* end_v = NULL; this->get_to_vertex()->select_box(rx,ry,mx,my,end_v); if (end_v) { int lx = 0; int ly = 0; this->get_points()->get_lastxy(lx,ly); this->get_points()->moveConsEndPoint(rx - lx,ry - ly,this->get_edge_label()); } } void PointObjectList::get_lastxy(int &lx,int &ly) { if (next == NULL) { lx = elm->get_x(); ly = elm->get_y(); } else next->get_lastxy(lx,ly); } void ConstructionEdge::move_inner_point(int dx,int dy) { this->get_points()->move_inner_point(dx,dy,this->get_edge_label()); } void PointObjectList::move_inner_point(int dx,int dy, EdgeLabelObject *el) { if (elm->get_selected_flag() == SELECT_EDGE_INNER_POINT) { int x1 = elm->get_x(); int y1 = elm->get_y(); elm->set_x(x1 + dx); elm->set_y(y1 + dy); if (prev->get_prev() == NULL) { int x2 = prev->get_elm()->get_x(); int y2 = prev->get_elm()->get_y(); dx = (elm->get_x() + x2)/2 - (x1 + x2)/2; dy = (elm->get_y() + y2)/2 - (y1 + y2)/2; el->set_x(el->get_x() + dx); el->set_y(el->get_y() + dy); } } else if (next) next->move_inner_point(dx,dy,el); }