00001 #include "constants.h"
00002
00003 #include "transitionArc.h"
00004 #include "state.h"
00005 #include "label.h"
00006 #include "transforms.h"
00007
00008 #include <math.h>
00009
00010 #include <QtDebug>
00011
00012 TransitionArc::TransitionArc(Editor *parent, State *ss, State *es,
00013 const QString &labelText, bool leftO,
00014 bool dimmed, bool radius)
00015 : TwoStatesTransition(parent, ss, es, leftO, dimmed), radius(radius)
00016 {
00017 setZValue(Z_TRANSITION);
00018 label = new LabelX(this, labelText, leftOriented, m_labelFontSize,
00019 dimmed ? QColor(dimEdgeLabelColor) : QColor(edgeLabelColor));
00020 label->setZValue(Z_TR_LABEL);
00021 label->setPosParam(DEF_ARC_LAB_POS);
00022 adjust();
00023 setLabelPosition();
00024 }
00025
00026 TransitionArc::~TransitionArc()
00027 {
00028 DBGLOG("called");
00029 }
00030
00031 void TransitionArc::adjust()
00032 {
00033 prepareGeometryChange();
00034 if (!startState || !endState) return;
00035
00036 startPoint = startState->pos();
00037 endPoint = endState->pos();
00038
00039 QLineF s_v(startPoint, endPoint);
00040 float angle = s_v.angle(QLineF(0,0,1,0));
00041 if (startPoint.y() < endPoint.y()){
00042 angle *= -1;
00043 }
00044
00045 QPolygonF anglePol, statePol, iPol;
00046 int arcangle = radius ? DEF_ARC_ANGLE : DEF_ARC_ANGLE/2;
00047
00048 if (!leftOriented) arcangle *= -1;
00049
00050 anglePol << startState->pos() << startState->pos() +
00051 QPointF(cos(M_PI/180*(arcangle+angle)), -sin(M_PI/180*(arcangle+angle)))*startState->getWidth();
00052 statePol << mapFromItem(startState, startState->getMyPolygon());
00053 iPol = (findIntersectedPoints(anglePol, statePol, eFIND_FIRST));
00054 if (iPol.empty())
00055 {
00056 qWarning("TransitionVArc::adjust -> startPoint is set to startState->pos()!");
00057 startPoint = startState->pos();
00058 }
00059 else
00060 {
00061 startPoint = iPol[0];
00062 }
00063
00064 anglePol.clear();
00065 statePol.clear();
00066 anglePol << endState->pos() << endState->pos() +
00067 QPointF(cos(M_PI/180*(180-arcangle+angle)), -sin(M_PI/180*(180-arcangle+angle)))*endState->getWidth();
00068 statePol << mapFromItem(endState, endState->getMyPolygon());
00069 iPol = (findIntersectedPoints(anglePol, statePol, eFIND_FIRST));
00070 if (iPol.empty())
00071 {
00072 qWarning("TransitionVArc::adjust -> endPoint is set to endState->pos()!");
00073 endPoint = endState->pos();
00074 }
00075 else
00076 {
00077 endPoint = iPol[0];
00078 }
00079
00080 if (startPoint == endPoint) {
00081 setLabelPosition();
00082 return;
00083 }
00084
00085 QPainterPath path;
00086
00087 s_v.setPoints(startPoint, endPoint);
00088 float len = s_v.length()/2;
00089
00090 angle = s_v.angle(QLineF(0,0,1,0));
00091 if (startPoint.y() < endPoint.y()){
00092 angle *= -1;
00093 }
00094
00095 float angleA, angleB;
00096 angleA = arcangle + angle;
00097 angleB = 180 - arcangle + angle;
00098
00099 float x,y;
00100 x = cos(M_PI/180*(angleA));
00101 y = sin(M_PI/180*(angleA));
00102 QPointF point = QPointF(x,-y);
00103 point += startPoint;
00104
00105 QLineF a_v(startPoint,point);
00106
00107
00108 x = cos(M_PI/180*(angleB));
00109 y = sin(M_PI/180*(angleB));
00110 point = QPointF(x,-y);
00111 point += endPoint;
00112
00113 QLineF b_v(s_v.p2(),point);
00114
00115
00116 float current_ncurv = len * DEF_ARC_CURV;
00117 a_v.setLength(current_ncurv);
00118 b_v.setLength(current_ncurv);
00119
00120 a_point = a_v.p2(); b_point = b_v.p2();
00121 path.moveTo(startPoint);
00122 path.cubicTo(a_point, b_point, endPoint);
00123
00124 p = path;
00125
00126 QList<QPolygonF> pathList = p.toSubpathPolygons();
00127 if (pathList.size() > 1)
00128 RELLOG("not only one subpath polygon!");
00129
00130 iPol = pathList[0];
00131 iPol << endState->pos();
00132 pa = getArrowPolygon(p);
00133
00134 setLabelPosition();
00135 createStrokes(p);
00136 }
00137
00138 void TransitionArc::setLabelPosition()
00139 {
00140 if (label)
00141 {
00142 Transition::setLabelPosition(label, label->posParam(), leftOriented, label->getWidth(), label->getHeight());
00143 }
00144 Transition::setLabelPosition();
00145 }
00146
00147 QString TransitionArc::getTypeName() const
00148 {
00149 return radius ? "LArc" : "Arc";
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 QString TransitionArc::getVCCommand() const
00204 {
00205 QString command = "\\";
00206
00207 command += getTypeName();
00208 command += getTypeNameSuffix();
00209
00210 Q_ASSERT(label != NULL);
00211 if (label->posParam() != DEF_ARC_LAB_POS)
00212 command += QString("[%1]").arg(label->posParam());
00213
00214 command += "{" + startState->getName() + "}";
00215 command += "{" + endState->getName() + "}";
00216
00217 command += "{" + label->text() + "}";
00218
00219 command += getNextLabelsVCCommand();
00220
00221 return command;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261