[Uml-devel] [Bug 110231] Association labels aren't moved correctly when moving the corresponding classes (class diagram)
Oliver Kellogg
okellogg at users.sourceforge.net
Sun Aug 7 06:04:20 UTC 2005
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.
http://bugs.kde.org/show_bug.cgi?id=110231
------- Additional Comments From okellogg users sourceforge net 2005-08-07 15:03 -------
SVN commit 443800 by okellogg:
CCBUG:110231 - First stab at constraining the text positions.
Only works for exactly vertical and horizontal association lines.
Only works when actively dragging around a FloatingText, i.e. does
not yet work as a side effect of moving one of the role objects.
In other words, all the hard stuff is still To Be Done :)
M +107 -0 associationwidget.cpp
M +13 -0 associationwidget.h
M +1 -4 floatingtext.cpp
M +0 -5 linkwidget.cpp
M +4 -3 linkwidget.h
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/associationwidget.cpp #443799:443800
@ -1870,6 +1870,113 @
return p;
}
+void AssociationWidget::constrainTextPos(int &textX, int &textY,
+ int textWidth, int textHeight,
+ Uml::Text_Role tr) {
+ const int CORRIDOR_HALFWIDTH = 30;
+ const int textHalfWidth = textWidth / 2;
+ const int textHalfHeight = textHeight / 2;
+ const int textCenterX = textX + textHalfWidth;
+ const int textCenterY = textY + textHalfHeight;
+ const uint lastSegment = m_LinePath.count() - 1;
+ QPoint p0, p1;
+ bool atBSide = false;
+ switch (tr) {
+ case tr_RoleAName:
+ case tr_MultiA:
+ case tr_ChangeA:
+ p0 = m_LinePath.getPoint(0);
+ p1 = m_LinePath.getPoint(1);
+ break;
+ case tr_RoleBName:
+ case tr_MultiB:
+ case tr_ChangeB:
+ p0 = m_LinePath.getPoint(lastSegment - 1);
+ p1 = m_LinePath.getPoint(lastSegment);
+ atBSide = true;
+ break;
+ case tr_Name:
+ // todo Find the linepath segment to which the (textX,textY) is closest
+ // and constrain to the corridor of that segment.
+ return;
+ break;
+ default:
+ kdError() << "AssociationWidget::constrainTextPos(): unexpected Text_Role "
+ << tr << endl;
+ return;
+ break;
+ }
+ if (p0.x() == p1.x()) {
+ // vertical line
+ // CAUTION: This is calculated in Qt coordinates!
+ ////////////////////////// constrain horizontally /////////////////////////
+ const int lineX = p0.x();
+ if (textX + textWidth < lineX - CORRIDOR_HALFWIDTH) // constrain at left
+ textX = lineX - CORRIDOR_HALFWIDTH - textWidth;
+ else if (textX > lineX + CORRIDOR_HALFWIDTH) // constrain at right
+ textX = lineX + CORRIDOR_HALFWIDTH;
+ ////////////////////////// constrain vertically ///////////////////////////
+ // pre-constrain the corridor to the appropriate half:
+ if (atBSide) {
+ if (p0.y() > p1.y())
+ p0.setY(p1.y() + (p0.y() - p1.y()) / 2);
+ else
+ p0.setY(p1.y() - (p1.y() - p0.y()) / 2);
+ } else {
+ if (p0.y() < p1.y())
+ p1.setY(p0.y() + (p1.y() - p0.y()) / 2);
+ else
+ p1.setY(p0.y() - (p0.y() - p1.y()) / 2);
+ }
+ // swap points so that p0 contains the one with the smaller Y
+ if (p0.y() > p1.y()) {
+ QPoint tmp = p0;
+ p0 = p1;
+ p1 = tmp;
+ }
+ if (textY + textHeight < p0.y()) // constrain at top
+ textY = p0.y() - textHeight;
+ else if (textY > p1.y()) // constrain at bottom
+ textY = p1.y();
+ return;
+ }
+ if (p0.y() == p1.y()) {
+ // horizontal line
+ // CAUTION: This is calculated in Qt coordinates!
+ ////////////////////////// constrain verticallly ///////////////////////////
+ const int lineY = p0.y();
+ if (textY + textHeight < lineY - CORRIDOR_HALFWIDTH) // constrain at top
+ textY = lineY - CORRIDOR_HALFWIDTH - textHeight;
+ else if (textY > lineY + CORRIDOR_HALFWIDTH) // constrain at bottom
+ textY = lineY + CORRIDOR_HALFWIDTH;
+ ////////////////////////// constrain horizontally //////////////////////////
+ // pre-constrain the corridor to the appropriate half:
+ if (atBSide) {
+ if (p0.x() < p1.x())
+ p0.setX(p1.x() - (p1.x() - p0.x()) / 2);
+ else
+ p0.setX(p1.x() + (p0.x() - p1.x()) / 2);
+ } else {
+ if (p0.x() < p1.x())
+ p1.setX(p0.x() + (p1.x() - p0.x()) / 2);
+ else
+ p1.setX(p0.x() - (p0.x() - p1.x()) / 2);
+ }
+ // swap points so that p0 contains the one with the smaller X
+ if (p0.x() > p1.x()) {
+ QPoint tmp = p0;
+ p0 = p1;
+ p1 = tmp;
+ }
+ if (textX + textWidth < p0.x()) // constrain at left
+ textX = p0.x() - textWidth;
+ else if (textX > p1.x()) // constrain at right
+ textX = p1.x();
+ return;
+ }
+ // todo: deal with slopes
+}
+
void AssociationWidget::calculateNameTextSegment() {
if(!m_pName) {
return;
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/associationwidget.h #443799:443800
@ -490,6 +490,19 @
void resetTextPositions();
/**
+ * Constrains the FloatingText X and Y values supplied.
+ * Implements the abstract 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::Text_Role of the text.
+ */
+ void constrainTextPos(int &textX, int &textY, int textWidth, int textHeight,
+ Uml::Text_Role tr);
+
+ /**
* Shows the association properties dialog and updates the
* corresponding texts if its execution is successful.
* Returns true for success.
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/floatingtext.cpp #443799:443800
@ -304,10 +304,7 @
int newX = newPosition.x();
int newY = newPosition.y();
- //implement specific rules for a sequence diagram
- if (m_Role == Uml::tr_Seq_Message || m_Role == Uml::tr_Seq_Message_Self) {
- m_pLink->constrainTextPos(newX, newY, width(), height(), m_Role);
- }
+ m_pLink->constrainTextPos(newX, newY, width(), height(), m_Role);
m_nOldX = newX;
m_nOldY = newY;
setX( newX );
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/linkwidget.cpp #443799:443800
@ -55,11 +55,6 @
return true;
}
-void LinkWidget::constrainTextPos(int & /*textX*/, int & /*textY*/,
- int /*textWidth*/, int /*textHeight*/,
- Uml::Text_Role /*tr*/) {
-}
-
void LinkWidget::calculateNameTextSegment() {
}
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/linkwidget.h #443799:443800
@ -113,11 +113,12 @
virtual void setSeqNumAndOp(const QString &seqNum, const QString &op) = 0;
/**
+ * Abstract operation implemented by inheriting classes.
* Motivated by FloatingText::mouseMoveEvent()
- * Only applies to MessageWidget.
*/
- virtual void constrainTextPos(int &textX, int &textY, int textWidth, int textHeight,
- Uml::Text_Role tr);
+ virtual void constrainTextPos(int &textX, int &textY,
+ int textWidth, int textHeight,
+ Uml::Text_Role tr) = 0;
/**
* Motivated by FloatingText::setLink().
More information about the umbrello-devel
mailing list