/** * Constrains the FloatingTextWidget X and Y values supplied. * Overrides operation from LinkWidget. * * @param textX candidate X value (may be modified by the constraint) * @param textY candidate Y value (may be modified by the constraint) * @param textWidth width of the text * @param textHeight height of the text * @param tr Uml::TextRole::Enum of the text */ void MessageWidget::constrainTextPos(qreal &textX, qreal &textY, qreal textWidth, qreal textHeight, Uml::TextRole::Enum tr) { textX = constrainX(textX, textWidth, tr); // Constrain Y. const qreal minTextY = getMinY(); const qreal maxTextY = getMaxY() - textHeight - 5; if (textY < minTextY) textY = minTextY; else if (textY > maxTextY) textY = maxTextY; // setY(textY + textHeight); // NB: side effect }
/** * Sets the text position relative to the sequence message. */ void MessageWidget::setTextPosition() { if (m_pFText == NULL) { DEBUG(DBG_SRC) << "m_pFText is NULL"; return; } if (m_pFText->displayText().isEmpty()) { return; } m_pFText->updateGeometry(); int ftX = constrainX(m_pFText->x(), m_pFText->width(), m_pFText->textRole()); int ftY = y() - m_pFText->height(); m_pFText->setX(ftX); m_pFText->setY(ftY); }
int cAdjust (graph_t * g, int mode) { int ret, i, nnodes = agnnodes (g); nitem *nlist = (nitem *) gmalloc ((nnodes) * sizeof (nitem)); node_t *n; for (n = agfstnode (g); n; n = agnxtnode (g, n)) { } if (overlaps (nlist, nnodes)) { switch ((adjust_mode) mode) { case AM_ORTHOXY: constrainX (g, nlist, nnodes, intersectY, 1); case AM_ORTHO: constrainX (g, nlist, nnodes, intersectY0, 1); constrainX (g, nlist, nnodes, intersectY, 1); case AM_PORTHO: default: constrainX (g, nlist, nnodes, intersectY0, 0); } } }
/* cAdjust: * Use optimization to remove overlaps. * Modifications; * - do y;x then x;y and use the better one * - for all overlaps (or if overlap with leftmost nodes), add a constraint; * constraint could move both x and y away, or the smallest, or some * mixture. * - follow by a scale down using actual shapes * We use an optimization based on Marriott, Stuckey, Tam and He, * "Removing Node Overlapping in Graph Layout Using Constrained Optimization", * Constraints,8(2):143--172, 2003. * We solve 2 constraint problem, one in X, one in Y. In each dimension, * we require relative positions to remain the same. That is, if two nodes * have the same x originally, they have the same x at the end, and if one * node is to the left of another, it remains to the left. In addition, if * two nodes could overlap by moving their X coordinates, we insert a constraint * to keep the two nodes sufficiently apart. Similarly, for Y. * * mode = AM_ORTHOXY => first X, then Y * mode = AM_ORTHOYX => first Y, then X * mode = AM_ORTHO => first X, then Y * mode = AM_ORTHO_YX => first Y, then X * In the last 2 cases, relax the constraints as follows: during the X pass, * if two nodes actually intersect and a smaller move in the Y direction * will remove the overlap, we don't force the nodes apart in the X direction, * but leave it for the Y pass to remove any remaining overlaps. Without this, * the X pass will remove all overlaps, and the Y pass only compresses in the * Y direction, causing a skewing of the aspect ratio. * * mode = AM_ORTHOXY => first X, then Y * mode = AM_ORTHOYX => first Y, then X * mode = AM_ORTHO => first X, then Y * mode = AM_ORTHO_YX => first Y, then X */ int cAdjust(graph_t * g, int mode) { expand_t margin; int ret, i, nnodes = agnnodes(g); nitem *nlist = N_GNEW(nnodes, nitem); nitem *p = nlist; node_t *n; margin = sepFactor (g); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { initItem(n, p, margin); p++; } if (overlaps(nlist, nnodes)) { point pt; switch ((adjust_mode)mode) { case AM_ORTHOXY: constrainX(g, nlist, nnodes, intersectY, 1); constrainY(g, nlist, nnodes, intersectX, 1); break; case AM_ORTHOYX: constrainY(g, nlist, nnodes, intersectX, 1); constrainX(g, nlist, nnodes, intersectY, 1); break; case AM_ORTHO : constrainX(g, nlist, nnodes, intersectY0, 1); constrainY(g, nlist, nnodes, intersectX, 1); case AM_ORTHO_YX : constrainY(g, nlist, nnodes, intersectX0, 1); constrainX(g, nlist, nnodes, intersectY, 1); case AM_PORTHOXY: constrainX(g, nlist, nnodes, intersectY, 0); constrainY(g, nlist, nnodes, intersectX, 0); break; case AM_PORTHOYX: constrainY(g, nlist, nnodes, intersectX, 0); constrainX(g, nlist, nnodes, intersectY, 0); break; case AM_PORTHO_YX : constrainY(g, nlist, nnodes, intersectX0, 0); constrainX(g, nlist, nnodes, intersectY, 0); break; case AM_PORTHO : default : constrainX(g, nlist, nnodes, intersectY0, 0); constrainY(g, nlist, nnodes, intersectX, 0); break; } p = nlist; for (i = 0; i < nnodes; i++) { n = p->np; pt = p->pos; ND_pos(n)[0] = PS2INCH(pt.x) / SCALE; ND_pos(n)[1] = PS2INCH(pt.y) / SCALE; p++; } ret = 1; } else ret = 0; free(nlist); return ret; }