static void branch_select(Branch *branch, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&branch->element); }
static void ellipse_select(Ellipse *ellipse, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&ellipse->element); }
static void ellipse_update_data(Ellipse *ellipse) { Element *elem = &ellipse->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center; real half_x, half_y; /* handle circle implies height=width */ if (ellipse->aspect == CIRCLE_ASPECT) { float size = elem->height < elem->width ? elem->height : elem->width; elem->height = elem->width = size; } center.x = elem->corner.x + elem->width / 2.0; center.y = elem->corner.y + elem->height / 2.0; half_x = elem->width * M_SQRT1_2 / 2.0; half_y = elem->height * M_SQRT1_2 / 2.0; /* Update connections: */ ellipse->connections[0].pos.x = center.x - half_x; ellipse->connections[0].pos.y = center.y - half_y; ellipse->connections[1].pos.x = center.x; ellipse->connections[1].pos.y = elem->corner.y; ellipse->connections[2].pos.x = center.x + half_x; ellipse->connections[2].pos.y = center.y - half_y; ellipse->connections[3].pos.x = elem->corner.x; ellipse->connections[3].pos.y = center.y; ellipse->connections[4].pos.x = elem->corner.x + elem->width; ellipse->connections[4].pos.y = elem->corner.y + elem->height / 2.0; ellipse->connections[5].pos.x = center.x - half_x; ellipse->connections[5].pos.y = center.y + half_y; ellipse->connections[6].pos.x = elem->corner.x + elem->width / 2.0; ellipse->connections[6].pos.y = elem->corner.y + elem->height; ellipse->connections[7].pos.x = center.x + half_x; ellipse->connections[7].pos.y = center.y + half_y; ellipse->connections[8].pos.x = center.x; ellipse->connections[8].pos.y = center.y; /* Update directions -- if the ellipse is very thin, these may not be good */ ellipse->connections[0].directions = DIR_NORTH|DIR_WEST; ellipse->connections[1].directions = DIR_NORTH; ellipse->connections[2].directions = DIR_NORTH|DIR_EAST; ellipse->connections[3].directions = DIR_WEST; ellipse->connections[4].directions = DIR_EAST; ellipse->connections[5].directions = DIR_SOUTH|DIR_WEST; ellipse->connections[6].directions = DIR_SOUTH; ellipse->connections[7].directions = DIR_SOUTH|DIR_EAST; ellipse->connections[8].directions = DIR_ALL; extra->border_trans = ellipse->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); obj->handles[8]->pos.x = center.x; obj->handles[8]->pos.y = center.y; }
static void attribute_select(Attribute *attribute, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&attribute->element); }
static void attribute_update_data(Attribute *attribute) { Element *elem = &attribute->element; DiaObject *obj = &elem->object; Point center; ElementBBExtras *extra = &elem->extra_spacing; real half_x, half_y; attribute->name_width = dia_font_string_width(attribute->name, attribute->font, attribute->font_height); elem->width = attribute->name_width + 2*TEXT_BORDER_WIDTH_X; elem->height = attribute->font_height + 2*TEXT_BORDER_WIDTH_Y; center.x = elem->corner.x + elem->width / 2.0; center.y = elem->corner.y + elem->height / 2.0; half_x = elem->width * M_SQRT1_2 / 2.0; half_y = elem->height * M_SQRT1_2 / 2.0; /* Update connections: */ connpoint_update(&attribute->connections[0], center.x - half_x, center.y - half_y, DIR_NORTHWEST); connpoint_update(&attribute->connections[1], center.x, elem->corner.y, DIR_NORTH); connpoint_update(&attribute->connections[2], center.x + half_x, center.y - half_y, DIR_NORTHEAST); connpoint_update(&attribute->connections[3], elem->corner.x, center.y, DIR_WEST); connpoint_update(&attribute->connections[4], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&attribute->connections[5], center.x - half_x, center.y + half_y, DIR_SOUTHWEST); connpoint_update(&attribute->connections[6], elem->corner.x + elem->width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&attribute->connections[7], center.x + half_x, center.y + half_y, DIR_SOUTHEAST); connpoint_update(&attribute->connections[8], center.x, center.y, DIR_ALL); extra->border_trans = attribute->border_width/2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void transition_update_data(Transition *transition) { Element *elem = &transition->element; DiaObject *obj = &elem->object; Point *p; transition->element.extra_spacing.border_trans = TRANSITION_LINE_WIDTH / 2.0; obj->position = elem->corner; elem->width = TRANSITION_DECLAREDWIDTH; elem->height = TRANSITION_DECLAREDWIDTH; /* compute the useful points' positions : */ transition->A.x = transition->B.x = (TRANSITION_DECLAREDWIDTH / 2.0); transition->A.y = (TRANSITION_DECLAREDHEIGHT / 2.0) - (TRANSITION_HEIGHT / 2.0); transition->B.y = transition->A.y + TRANSITION_HEIGHT; transition->C.y = transition->D.y = (TRANSITION_DECLAREDHEIGHT / 2.0); transition->C.x = (TRANSITION_DECLAREDWIDTH / 2.0) - (TRANSITION_WIDTH / 2.0); transition->D.x = transition->C.x + TRANSITION_WIDTH; transition->Z.y = (TRANSITION_DECLAREDHEIGHT / 2.0) + (.3 * transition->receptivity->fontheight); transition->Z.x = transition->D.x + dia_font_string_width("_",transition->receptivity->font, transition->receptivity->fontheight); for (p = &transition->A; p <= &transition->Z; p++) point_add(p,&elem->corner); transition->receptivity->pos = transition->Z; /* Update handles: */ if (transition->north.pos.x == -65536.0) { transition->north.pos = transition->A; transition->south.pos = transition->B; } transition->NU1.x = transition->north.pos.x; transition->NU2.x = transition->A.x; transition->NU1.y = transition->NU2.y = (transition->north.pos.y + transition->A.y) / 2.0; transition->SD1.x = transition->B.x; transition->SD2.x = transition->south.pos.x; transition->SD1.y = transition->SD2.y = (transition->south.pos.y + transition->B.y) / 2.0; obj->connections[0]->pos = transition->A; obj->connections[0]->directions = DIR_EAST|DIR_WEST; obj->connections[1]->pos = transition->B; obj->connections[1]->directions = DIR_EAST|DIR_WEST; element_update_boundingbox(elem); rectangle_add_point(&obj->bounding_box,&transition->north.pos); rectangle_add_point(&obj->bounding_box,&transition->south.pos); /* compute the rcept's width and bounding box, then merge. */ boolequation_calc_boundingbox(transition->receptivity,&transition->rceptbb); rectangle_union(&obj->bounding_box,&transition->rceptbb); element_update_handles(elem); }
static void usecase_update_data(Usecase *usecase) { real w, h, ratio; Point c, half, r,p; Element *elem = &usecase->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; text_calc_boundingbox(usecase->text, NULL); w = usecase->text->max_width; h = usecase->text->height*usecase->text->numlines; if (!usecase->text_outside) { ratio = w/h; if (ratio > USECASE_MAX_RATIO) ratio = USECASE_MAX_RATIO; if (ratio < USECASE_MIN_RATIO) { ratio = USECASE_MIN_RATIO; r.y = w / ratio + h; r.x = r.y * ratio; } else { r.x = ratio*h + w; r.y = r.x / ratio; } if (r.x < USECASE_WIDTH) r.x = USECASE_WIDTH; if (r.y < USECASE_HEIGHT) r.y = USECASE_HEIGHT; } else { r.x = USECASE_WIDTH; r.y = USECASE_HEIGHT; } elem->width = r.x; elem->height = r.y; extra->border_trans = usecase->line_width / 2.0; if (usecase->text_outside) { elem->width = MAX(elem->width, w); elem->height += h + USECASE_MARGIN_Y; } r.x /= 2.0; r.y /= 2.0; c.x = elem->corner.x + elem->width / 2.0; c.y = elem->corner.y + r.y; half.x = r.x * M_SQRT1_2; half.y = r.y * M_SQRT1_2; /* Update connections: */ usecase->connections[0].pos.x = c.x - half.x; usecase->connections[0].pos.y = c.y - half.y; usecase->connections[1].pos.x = c.x; usecase->connections[1].pos.y = elem->corner.y; usecase->connections[2].pos.x = c.x + half.x; usecase->connections[2].pos.y = c.y - half.y; usecase->connections[3].pos.x = c.x - r.x; usecase->connections[3].pos.y = c.y; usecase->connections[4].pos.x = c.x + r.x; usecase->connections[4].pos.y = c.y; if (usecase->text_outside) { usecase->connections[5].pos.x = elem->corner.x; usecase->connections[5].pos.y = elem->corner.y + elem->height; usecase->connections[6].pos.x = c.x; usecase->connections[6].pos.y = elem->corner.y + elem->height; usecase->connections[7].pos.x = elem->corner.x + elem->width; usecase->connections[7].pos.y = elem->corner.y + elem->height; } else { usecase->connections[5].pos.x = c.x - half.x; usecase->connections[5].pos.y = c.y + half.y; usecase->connections[6].pos.x = c.x; usecase->connections[6].pos.y = elem->corner.y + elem->height; usecase->connections[7].pos.x = c.x + half.x; usecase->connections[7].pos.y = c.y + half.y; } usecase->connections[8].pos.x = c.x; usecase->connections[8].pos.y = c.y; usecase->connections[0].directions = DIR_NORTH|DIR_WEST; usecase->connections[1].directions = DIR_NORTH; usecase->connections[2].directions = DIR_NORTH|DIR_EAST; usecase->connections[3].directions = DIR_WEST; usecase->connections[4].directions = DIR_EAST; usecase->connections[5].directions = DIR_SOUTH|DIR_WEST; usecase->connections[6].directions = DIR_SOUTH; usecase->connections[7].directions = DIR_SOUTH|DIR_EAST; usecase->connections[8].directions = DIR_ALL; h = usecase->text->height*usecase->text->numlines; p = usecase->element.corner; p.x += usecase->element.width/2.0; if (usecase->text_outside) { p.y += usecase->element.height - h + usecase->text->ascent; } else { p.y += (usecase->element.height - h)/2.0 + usecase->text->ascent; } text_set_position(usecase->text, &p); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert) { Element *elem = &ellipse->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p, c; real dw, dh; real width, height; real radius1, radius2; int i; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(ellipse->text, NULL); width = ellipse->text->max_width + 2 * ellipse->padding; height = ellipse->text->height * ellipse->text->numlines + 2 * ellipse->padding; /* stop ellipse from getting infinite width/height */ if (elem->width / elem->height > 4) elem->width = elem->height * 4; else if (elem->height / elem->width > 4) elem->height = elem->width * 4; c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; p.x = c.x - width / 2; p.y = c.y - height / 2; radius1 = ellipse_radius(ellipse, p.x, p.y) - ellipse->border_width/2; radius2 = distance_point_point(&c, &p); if ( (radius1 < radius2 && ellipse->text_fitting == TEXTFIT_WHEN_NEEDED) /* stop infinite resizing with 5% tolerance obsvered with _test_movement */ || (fabs(1.0 - radius2 / radius1) > 0.05 && ellipse->text_fitting == TEXTFIT_ALWAYS)) { /* increase size of the ellipse while keeping its aspect ratio */ elem->width *= radius2 / radius1; elem->height *= radius2 / radius1; } /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - ellipse->text->height*ellipse->text->numlines/2 + ellipse->text->ascent; switch (ellipse->text->alignment) { case ALIGN_LEFT: p.x -= (elem->width - 2*(ellipse->padding + ellipse->border_width))/2; break; case ALIGN_RIGHT: p.x += (elem->width - 2*(ellipse->padding + ellipse->border_width))/2; break; case ALIGN_CENTER: break; } text_set_position(ellipse->text, &p); /* Update connections: */ c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; dw = elem->width / 2.0; dh = elem->height / 2.0; for (i = 0; i < NUM_CONNECTIONS-1; i++) { real theta = M_PI / 8.0 * i; real costheta = cos(theta); real sintheta = sin(theta); connpoint_update(&ellipse->connections[i], c.x + dw * costheta, c.y - dh * sintheta, (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))| (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0))); } connpoint_update(&ellipse->connections[16], c.x, c.y, DIR_ALL); extra->border_trans = ellipse->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void analog_clock_select(Analog_Clock *analog_clock, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&analog_clock->element); }
static void function_update_data(Function *pkg) { Element *elem = &pkg->element; DiaObject *obj = &elem->object; DiaFont *font; Point p1; real h, w = 0, font_height; text_calc_boundingbox(pkg->text, NULL) ; font = pkg->text->font ; font_height = pkg->text->height ; h = elem->corner.y + font_height/FUNCTION_MARGIN_Y; if (pkg->is_user) { h += 2*font_height/FUNCTION_MARGIN_SCALE; } w = MAX(w, pkg->text->max_width); p1.y = h + pkg->text->ascent - ( pkg->is_user ? font_height/FUNCTION_MARGIN_SCALE : 0 ); /* position of text */ h += pkg->text->height*pkg->text->numlines; h += font_height/FUNCTION_MARGIN_Y; w += 2*font_height/FUNCTION_MARGIN_X; p1.x = elem->corner.x + w/2.0 + ( pkg->is_user ? font_height/FUNCTION_MARGIN_SCALE : 0 ); text_set_position(pkg->text, &p1); if (pkg->is_user) { w += 2*font_height/FUNCTION_MARGIN_SCALE; } elem->width = w; elem->height = h - elem->corner.y; /* Update connections: */ connpoint_update(&pkg->connections[0], elem->corner.x, elem->corner.y, DIR_NORTHWEST); connpoint_update(&pkg->connections[1], elem->corner.x + elem->width / 2.0, elem->corner.y, DIR_NORTH); connpoint_update(&pkg->connections[2], elem->corner.x + elem->width, elem->corner.y, DIR_NORTHEAST); connpoint_update(&pkg->connections[3], elem->corner.x, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&pkg->connections[4], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&pkg->connections[5], elem->corner.x, elem->corner.y + elem->height, DIR_SOUTHWEST); connpoint_update(&pkg->connections[6], elem->corner.x + elem->width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pkg->connections[7], elem->corner.x + elem->width, elem->corner.y + elem->height, DIR_SOUTHEAST); connpoint_update(&pkg->connections[8], elem->corner.x + elem->width / 2.0, elem->corner.y + elem->height / 2.0, DIR_SOUTHEAST); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void pgram_update_data(Pgram *pgram, AnchorShape horiz, AnchorShape vert) { Element *elem = &pgram->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real offs; real width, height; real avail_width; real top_left; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; /* this takes the shearing of the parallelogram into account, so the * text can be extend to the edges of the parallelogram */ text_calc_boundingbox(pgram->text, NULL); height = pgram->text->height * pgram->text->numlines + pgram->padding*2 + pgram->border_width; if ( pgram->text_fitting == TEXTFIT_ALWAYS || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED && height > elem->height)) elem->height = height; avail_width = elem->width - (pgram->padding*2 + pgram->border_width + fabs(pgram->shear_grad) * (elem->height + pgram->text->height * pgram->text->numlines)); if ( pgram->text_fitting == TEXTFIT_ALWAYS || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED && avail_width < pgram->text->max_width)) { elem->width = (elem->width-avail_width) + pgram->text->max_width; avail_width = pgram->text->max_width; } /* width = pgram->text->max_width + pgram->padding*2 + pgram->border_width + fabs(pgram->shear_grad) * (elem->height + pgram->text->height * pgram->text->numlines); if (width > elem->width) elem->width = width; */ /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - pgram->text->height * pgram->text->numlines / 2 + pgram->text->ascent; switch (pgram->text->alignment) { case ALIGN_LEFT: p.x -= avail_width/2; break; case ALIGN_RIGHT: p.x += avail_width/2; break; case ALIGN_CENTER: break; } text_set_position(pgram->text, &p); /* 1/4 of how much more to the left the bottom line is */ offs = -(elem->height / 4.0 * pgram->shear_grad); width = elem->width - 4.0*fabs(offs); top_left = elem->corner.x; if (offs < 0.0) { top_left -= 4*offs; } /* Update connections: */ connpoint_update(&pgram->connections[0], top_left, elem->corner.y, DIR_NORTHWEST); connpoint_update(&pgram->connections[1], top_left + width / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[2], top_left + width / 2.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[3], top_left + width * 3.0 / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[4], top_left + width, elem->corner.y, DIR_NORTHEAST); connpoint_update(&pgram->connections[5], top_left + offs, elem->corner.y + elem->height / 4.0, DIR_WEST); connpoint_update(&pgram->connections[6], top_left + width + offs, elem->corner.y + elem->height / 4.0, DIR_EAST); connpoint_update(&pgram->connections[7], top_left + 2.0 * offs, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&pgram->connections[8], top_left + width + 2.0 * offs, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&pgram->connections[9], top_left + 3.0 * offs, elem->corner.y + elem->height * 3.0 / 4.0, DIR_WEST); connpoint_update(&pgram->connections[10], top_left + width + 3.0 * offs, elem->corner.y + elem->height * 3.0 / 4.0, DIR_EAST); connpoint_update(&pgram->connections[11], top_left + 4.0 * offs, elem->corner.y + elem->height, DIR_SOUTHWEST); connpoint_update(&pgram->connections[12], top_left + 4.0 * offs + width / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[13], top_left + 4.0 * offs + width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[14], top_left + 4.0 * offs + 3.0 * width / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[15], top_left + 4.0 * offs + width, elem->corner.y + elem->height, DIR_SOUTHEAST); connpoint_update(&pgram->connections[16], top_left + 2.0 * offs + width / 2, elem->corner.y + elem->height / 2, DIR_ALL); extra->border_trans = pgram->border_width/2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void component_update_data(Component *cmp) { Element *elem = &cmp->element; DiaObject *obj = &elem->object; Point p; real cw2, ch; cmp->stereotype = remove_stereotype_from_string(cmp->stereotype); if (!cmp->st_stereotype) { cmp->st_stereotype = string_to_stereotype(cmp->stereotype); } text_calc_boundingbox(cmp->text, NULL); elem->width = cmp->text->max_width + 2*COMPONENT_MARGIN_X + COMPONENT_CWIDTH; elem->width = MAX(elem->width, 2*COMPONENT_CWIDTH); elem->height = cmp->text->height*cmp->text->numlines + cmp->text->descent + 0.1 + 2*COMPONENT_MARGIN_Y ; elem->height = MAX(elem->height, 5*COMPONENT_CHEIGHT); p = elem->corner; p.x += COMPONENT_CWIDTH + COMPONENT_MARGIN_X; p.y += COMPONENT_CHEIGHT; p.y += cmp->text->ascent; if (cmp->stereotype && cmp->stereotype[0] != '\0') { p.y += cmp->text->height; } text_set_position(cmp->text, &p); if (cmp->st_stereotype && cmp->st_stereotype[0] != '\0') { DiaFont *font; font = cmp->text->font; elem->height += cmp->text->height; elem->width = MAX(elem->width, dia_font_string_width(cmp->st_stereotype, font, cmp->text->height) + 2*COMPONENT_MARGIN_X + COMPONENT_CWIDTH); } cw2 = COMPONENT_CWIDTH/2; ch = COMPONENT_CHEIGHT; /* Update connections: */ connpoint_update(&cmp->connections[0], elem->corner.x + cw2, elem->corner.y, DIR_NORTH|DIR_WEST); connpoint_update(&cmp->connections[1], elem->corner.x + cw2 + (elem->width - cw2) / 2, elem->corner.y, DIR_NORTH); connpoint_update(&cmp->connections[2], elem->corner.x + elem->width, elem->corner.y, DIR_NORTH|DIR_EAST); connpoint_update(&cmp->connections[3], elem->corner.x + cw2, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&cmp->connections[4], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&cmp->connections[5], elem->corner.x + cw2, elem->corner.y + elem->height, DIR_SOUTH|DIR_WEST); connpoint_update(&cmp->connections[6], elem->corner.x + cw2 + (elem->width - cw2)/2, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&cmp->connections[7], elem->corner.x + elem->width, elem->corner.y + elem->height, DIR_SOUTH|DIR_EAST); connpoint_update(&cmp->connections[8], elem->corner.x, elem->corner.y + elem->height / 2.0 - ch, DIR_WEST); connpoint_update(&cmp->connections[9], elem->corner.x, elem->corner.y + elem->height / 2.0 + ch, DIR_WEST); connpoint_update(&cmp->connections[10], elem->corner.x + (elem->width-cw2)/2, elem->corner.y + elem->height / 2.0 + ch, DIR_ALL); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void actor_update_data(Actor *actor, AnchorShape horiz, AnchorShape vert) { Element *elem = &actor->element; DiaObject *obj = &elem->object; ElementBBExtras *extra = &elem->extra_spacing; Point center, bottom_right,p,c; real width, height, dw, dh; real radius, mradius; int i; center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(actor->text, NULL); width = actor->text->max_width+0.5; height = actor->text->height * (actor->text->numlines + 3); /* added 3 blank lines for top */ /* minimal radius */ mradius=width; if (mradius<height) mradius=height; if (mradius<ACTOR_RADIUS) mradius=ACTOR_RADIUS; /* radius */ radius=elem->width; if (radius<elem->height) radius=elem->height; /* enforce (minimal or resized) radius */ if (radius<mradius) radius=mradius; elem->width=elem->height=radius; /* move shape if necessary ... (untouched) */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - actor->text->height*actor->text->numlines/2 + actor->text->ascent; text_set_position(actor->text, &p); /* compute connection positions */ c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; dw = elem->width / 2.0; dh = elem->height / 2.0; for (i = 0; i < NUM_CONNECTIONS-1; i++) { real theta = M_PI / 8.0 * i; real costheta = cos(theta); real sintheta = sin(theta); connpoint_update(&actor->connections[i], c.x + dw * costheta, c.y - dh * sintheta, (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))| (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0))); } actor->connections[16].pos.x = c.x; actor->connections[16].pos.y = c.y; extra->border_trans = ACTOR_BORDER_WIDTH / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void objet_update_data(Objet *ob) { Element *elem = &ob->element; DiaObject *obj = &elem->object; DiaFont *font; Point p1, p2; real h, w = 0; text_calc_boundingbox(ob->text, NULL); ob->stereotype = remove_stereotype_from_string(ob->stereotype); if (!ob->st_stereotype) { ob->st_stereotype = string_to_stereotype(ob->stereotype); } font = ob->text->font; h = elem->corner.y + OBJET_MARGIN_Y(ob); if (ob->is_multiple) { h += OBJET_MARGIN_M(ob); } if ((ob->stereotype != NULL) && (ob->stereotype[0] != '\0')) { w = dia_font_string_width(ob->st_stereotype, font, OBJET_FONTHEIGHT(ob)); h += OBJET_FONTHEIGHT(ob); ob->st_pos.y = h; h += OBJET_MARGIN_Y(ob)/2.0; } w = MAX(w, ob->text->max_width); p1.y = h + ob->text->ascent; /* position of text */ h += ob->text->height*ob->text->numlines; if ((ob->exstate != NULL) && (ob->exstate[0] != '\0')) { w = MAX(w, dia_font_string_width(ob->exstate, font, OBJET_FONTHEIGHT(ob))); h += OBJET_FONTHEIGHT(ob); ob->ex_pos.y = h; } h += OBJET_MARGIN_Y(ob); if (ob->show_attributes) { h += OBJET_MARGIN_Y(ob) + ob->attributes->ascent; p2.x = elem->corner.x + OBJET_MARGIN_X(ob); p2.y = h; text_set_position(ob->attributes, &p2); h += ob->attributes->height*ob->attributes->numlines; text_calc_boundingbox(ob->attributes, NULL); w = MAX(w, ob->attributes->max_width); } w += 2*OBJET_MARGIN_X(ob); p1.x = elem->corner.x + w/2.0; text_set_position(ob->text, &p1); ob->ex_pos.x = ob->st_pos.x = p1.x; if (ob->is_multiple) { w += OBJET_MARGIN_M(ob); } elem->width = w; elem->height = h - elem->corner.y; /* Update connections: */ element_update_connections_rectangle(elem, ob->connections); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void other_update_data(Other *other, AnchorShape horiz, AnchorShape vert) { Element *elem = &other->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real width, height; Point nw,ne,se,sw; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(other->text, NULL); width = other->text->max_width + other->padding*2; height = other->text->height * other->text->numlines + other->padding*2; /* autoscale here */ if (width > elem->width) elem->width = width; if (height > elem->height) elem->height = height; if (elem->width<elem->height*1.5) elem->width=elem->height*1.5; /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - other->text->height * other->text->numlines / 2 + other->text->ascent; text_set_position(other->text, &p); extra->border_trans = OTHER_LINE_WIDTH / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ nw = elem->corner; se.x = nw.x + elem->width; se.y = nw.y + elem->height; ne.x = se.x; ne.y = nw.y; sw.y = se.y; sw.x = nw.x; connpointline_update(other->north); connpointline_putonaline(other->north,&ne,&nw,DIR_NORTH); connpointline_update(other->west); connpointline_putonaline(other->west,&nw,&sw,DIR_WEST); connpointline_update(other->south); connpointline_putonaline(other->south,&sw,&se,DIR_SOUTH); connpointline_update(other->east); connpointline_putonaline(other->east,&se,&ne,DIR_EAST); }
static void chronoref_select(Chronoref *chronoref, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&chronoref->element); }
static void grid_object_select(Grid_Object *grid_object, Point *clicked_point, DiaRenderer *interactive_renderer) { element_update_handles(&grid_object->element); }
static void chronoref_update_data(Chronoref *chronoref) { Element *elem = &chronoref->element; DiaObject *obj = &elem->object; real time_span,t; Point p1,p2; Point ur_corner; int shouldbe,i; real labelwidth; char biglabel[10]; ElementBBExtras *extra = &elem->extra_spacing; chronoref->majgrad_height = elem->height; chronoref->mingrad_height = elem->height / 3.0; /* build i = -log_{10}(time_step), then make a %.if format out of it. */ t = 1; i = 0; while (t > chronoref->time_step) { t /= 10; i++; } chronoref->spec = i; /* update precision */ g_snprintf(biglabel,sizeof(biglabel),"%.*f", chronoref->spec, MIN(-ABS(chronoref->start_time),-ABS(chronoref->end_time))); labelwidth = dia_font_string_width(biglabel,chronoref->font, chronoref->font_size); /* Now, update the drawing helper counters */ time_span = chronoref->end_time - chronoref->start_time; if (time_span == 0) { chronoref->end_time = chronoref->start_time + .1; time_span = .1; } else if (time_span < 0) { chronoref->start_time = chronoref->end_time; time_span = -time_span; chronoref->end_time = chronoref->start_time + time_span; } chronoref->firstmaj = chronoref->time_step * ceil(chronoref->start_time / chronoref->time_step); if (chronoref->firstmaj < chronoref->start_time) chronoref->firstmaj += chronoref->time_step; chronoref->firstmin = chronoref->time_lstep * ceil(chronoref->start_time / chronoref->time_lstep); if (chronoref->firstmin < chronoref->start_time) chronoref->firstmin += chronoref->time_lstep; chronoref->firstmaj_x = elem->corner.x + elem->width*((chronoref->firstmaj-chronoref->start_time)/time_span); chronoref->firstmin_x = elem->corner.x + elem->width*((chronoref->firstmin-chronoref->start_time)/time_span); chronoref->majgrad = (chronoref->time_step * elem->width) / time_span; chronoref->mingrad = (chronoref->time_lstep * elem->width) / time_span; extra->border_trans = chronoref->main_lwidth/2; element_update_boundingbox(elem); /* fix boundingbox for special extras: */ obj->bounding_box.left -= (chronoref->font_size + labelwidth)/2; obj->bounding_box.bottom += chronoref->font_size; obj->bounding_box.right += (chronoref->font_size + labelwidth)/2; obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ ur_corner.x = elem->corner.x + elem->width; ur_corner.y = elem->corner.y; shouldbe = (int)(ceil((chronoref->end_time-chronoref->firstmin)/ chronoref->time_lstep)); if (shouldbe == 0) shouldbe++; if (shouldbe < 0) shouldbe = 0; shouldbe++; /* off by one.. */ connpointline_adjust_count(chronoref->scale,shouldbe,&ur_corner); connpointline_update(chronoref->scale); point_copy(&p1,&elem->corner); point_copy(&p2,&ur_corner); p1.x -= chronoref->mingrad; p2.x += chronoref->mingrad; connpointline_putonaline(chronoref->scale,&p1,&p2, DIR_SOUTH); }
static void diamond_update_data(Diamond *diamond, AnchorShape horiz, AnchorShape vert) { Element *elem = &diamond->element; DiaObject *obj = &elem->object; ElementBBExtras *extra = &elem->extra_spacing; Point center, bottom_right; Point p; real dw, dh; real width, height; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(diamond->text, NULL); width = diamond->text->max_width + 2*diamond->padding+diamond->border_width; height = diamond->text->height * diamond->text->numlines + 2 * diamond->padding + diamond->border_width; if (diamond->text_fitting == TEXTFIT_ALWAYS || ( diamond->text_fitting == TEXTFIT_WHEN_NEEDED && height > (elem->width - width) * elem->height / elem->width)) { /* increase size of the diamond while keeping its aspect ratio */ real grad = elem->width/elem->height; if (grad < 1.0/4) grad = 1.0/4; if (grad > 4) grad = 4; elem->width = width + height * grad; elem->height = height + width / grad; } else { /* Need this for text alignment soon */ real grad = elem->width/elem->height; if (grad < 1.0/4) grad = 1.0/4; if (grad > 4) grad = 4; width = elem->width - height*grad; } /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - diamond->text->height*diamond->text->numlines/2 + diamond->text->ascent; switch (diamond->text->alignment) { case ALIGN_LEFT: p.x -= width/2; break; case ALIGN_RIGHT: p.x += width/2; break; case ALIGN_CENTER: break; } text_set_position(diamond->text, &p); dw = elem->width / 8.0; dh = elem->height / 8.0; /* Update connections: */ diamond->connections[0].pos.x = elem->corner.x + 4*dw; diamond->connections[0].pos.y = elem->corner.y; diamond->connections[1].pos.x = elem->corner.x + 5*dw; diamond->connections[1].pos.y = elem->corner.y + dh; diamond->connections[2].pos.x = elem->corner.x + 6*dw; diamond->connections[2].pos.y = elem->corner.y + 2*dh; diamond->connections[3].pos.x = elem->corner.x + 7*dw; diamond->connections[3].pos.y = elem->corner.y + 3*dh; diamond->connections[4].pos.x = elem->corner.x + elem->width; diamond->connections[4].pos.y = elem->corner.y + 4*dh; diamond->connections[5].pos.x = elem->corner.x + 7*dw; diamond->connections[5].pos.y = elem->corner.y + 5*dh; diamond->connections[6].pos.x = elem->corner.x + 6*dw; diamond->connections[6].pos.y = elem->corner.y + 6*dh; diamond->connections[7].pos.x = elem->corner.x + 5*dw; diamond->connections[7].pos.y = elem->corner.y + 7*dh; diamond->connections[8].pos.x = elem->corner.x + 4*dw; diamond->connections[8].pos.y = elem->corner.y + elem->height; diamond->connections[9].pos.x = elem->corner.x + 3*dw; diamond->connections[9].pos.y = elem->corner.y + 7*dh; diamond->connections[10].pos.x = elem->corner.x + 2*dw; diamond->connections[10].pos.y = elem->corner.y + 6*dh; diamond->connections[11].pos.x = elem->corner.x + dw; diamond->connections[11].pos.y = elem->corner.y + 5*dh; diamond->connections[12].pos.x = elem->corner.x; diamond->connections[12].pos.y = elem->corner.y + 4*dh; diamond->connections[13].pos.x = elem->corner.x + dw; diamond->connections[13].pos.y = elem->corner.y + 3*dh; diamond->connections[14].pos.x = elem->corner.x + 2*dw; diamond->connections[14].pos.y = elem->corner.y + 2*dh; diamond->connections[15].pos.x = elem->corner.x + 3*dw; diamond->connections[15].pos.y = elem->corner.y + dh; diamond->connections[16].pos.x = elem->corner.x + 4*dw; diamond->connections[16].pos.y = elem->corner.y + 4*dh; /* help autorouting */ element_update_connections_directions (elem, diamond->connections); extra->border_trans = diamond->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void other_update_data(Other *other, AnchorShape horiz, AnchorShape vert) { Element *elem = &other->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real width, height; Point nw,ne,se,sw; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(other->text, NULL); width = other->text->max_width + other->padding*2; /* reserve some place for agent icon */ if (other->type==AGENT) width+=AGENT_LEFT; height = other->text->height * other->text->numlines + other->padding*2; /* autoscale here */ if (width > elem->width) elem->width = width; if (height > elem->height) elem->height = height; /* some personal touch for agent */ if ((other->type==AGENT) && (elem->width<elem->height)) elem->width=elem->height; /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; if (other->type==AGENT) p.x += (AGENT_LEFT+elem->width) / 2.0; else p.x += elem->width / 2.0; p.y += elem->height / 2.0 - other->text->height * other->text->numlines / 2 + other->text->ascent; text_set_position(other->text, &p); extra->border_trans = OTHER_LINE_DOUBLE_WIDTH / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ nw = elem->corner; se = bottom_right; ne.x = se.x; ne.y = nw.y; sw.y = se.y; sw.x = nw.x; connpointline_update(other->north); connpointline_putonaline(other->north,&ne,&nw); connpointline_update(other->west); connpointline_putonaline(other->west,&nw,&sw); connpointline_update(other->south); connpointline_putonaline(other->south,&sw,&se); connpointline_update(other->east); connpointline_putonaline(other->east,&se,&ne); other->center_cp.pos.x = (nw.x + se.x) / 2; other->center_cp.pos.y = (nw.y + se.y) / 2; }