00001 #include "constants.h"
00002
00003 #include "transitionVArc.h"
00004 #include "state.h"
00005 #include "label.h"
00006 #include "transforms.h"
00007
00008 #include <math.h>
00009
00010 #include <QtDebug>
00011
00012 #ifdef PERFORMANCE_MEASUREMENT
00013 # include <QTime>
00014 #endif
00015
00016 TransitionVArc::TransitionVArc(Editor *parent, State *ss, State *es,
00017 const QString &labelText, bool leftO, bool dimmed)
00018 : TwoStatesTransition(parent, ss, es, leftO, dimmed),
00019 arcangle(DEF_ARC_ANGLE), ncurv(DEF_ARC_CURV)
00020 {
00021 setZValue(Z_TRANSITION);
00022 label = new LabelX(this, labelText, leftOriented, m_labelFontSize,
00023 dimmed ? QColor(dimEdgeLabelColor) : QColor(edgeLabelColor));
00024 label->setZValue(Z_TR_LABEL);
00025 label->setPosParam(DEF_ARC_LAB_POS);
00026 adjust();
00027 setLabelPosition();
00028 }
00029
00030 TransitionVArc::~TransitionVArc()
00031 {
00032 DBGLOG("called");
00033 }
00034
00035 void TransitionVArc::adjust()
00036 {
00037 #ifdef MEASURE_TR_ADJUST
00038 QTime timer;
00039 timer.start();
00040 #endif
00041 prepareGeometryChange();
00042 if (!startState || !endState) return;
00043
00044 startPoint = startState->pos();
00045 endPoint = endState->pos();
00046
00047 QLineF s_v(startPoint, endPoint);
00048 float angle = s_v.angle(QLineF(0,0,1,0));
00049 if (startPoint.y() < endPoint.y()){
00050 angle *= -1;
00051 }
00052
00053 QPolygonF anglePol, statePol, iPol;
00054 anglePol << startState->pos() << startState->pos() +
00055 QPointF(cos(M_PI/180*(arcangle+angle)), -sin(M_PI/180*(arcangle+angle)))*startState->getWidth();
00056 statePol << mapFromItem(startState, startState->getMyPolygon());
00057 iPol = (findIntersectedPoints(anglePol, statePol, eFIND_FIRST));
00058 if (iPol.empty())
00059 {
00060 qWarning("TransitionVArc::adjust -> startPoint is set to startState->pos()!");
00061 startPoint = startState->pos();
00062 }
00063 else
00064 {
00065 startPoint = iPol[0];
00066 }
00067
00068 anglePol.clear();
00069 statePol.clear();
00070 anglePol << endState->pos() << endState->pos() +
00071 QPointF(cos(M_PI/180*(180-arcangle+angle)), -sin(M_PI/180*(180-arcangle+angle)))*endState->getWidth();
00072 statePol << mapFromItem(endState, endState->getMyPolygon());
00073 iPol = (findIntersectedPoints(anglePol, statePol, eFIND_FIRST));
00074 if (iPol.empty())
00075 {
00076 qWarning("TransitionVArc::adjust -> endPoint is set to endState->pos()!");
00077 endPoint = endState->pos();
00078 }
00079 else
00080 {
00081 endPoint = iPol[0];
00082 }
00083
00084 if (startPoint == endPoint) {
00085 setLabelPosition();
00086 return;
00087 }
00088
00089 QPainterPath path;
00090
00091 s_v.setPoints(startPoint, endPoint);
00092 float len = s_v.length()/2;
00093
00094 angle = s_v.angle(QLineF(0,0,1,0));
00095 if (startPoint.y() < endPoint.y()){
00096 angle *= -1;
00097 }
00098
00099 float angleA, angleB;
00100 angleA = arcangle + angle;
00101 angleB = 180 - arcangle + angle;
00102
00103 float x,y;
00104 x = cos(M_PI/180*(angleA));
00105 y = sin(M_PI/180*(angleA));
00106 QPointF point = QPointF(x,-y);
00107 point += startPoint;
00108
00109 QLineF a_v(startPoint,point);
00110
00111
00112 x = cos(M_PI/180*(angleB));
00113 y = sin(M_PI/180*(angleB));
00114 point = QPointF(x,-y);
00115 point += endPoint;
00116
00117 QLineF b_v(s_v.p2(),point);
00118
00119
00120
00121 float current_ncurv = len * ncurv;
00122 a_v.setLength(current_ncurv);
00123 b_v.setLength(current_ncurv);
00124
00125 a_point = a_v.p2(); b_point = b_v.p2();
00126 path.moveTo(startPoint);
00127 path.cubicTo(a_point, b_point, endPoint);
00128
00129
00130 p = path;
00131
00132 QList<QPolygonF> pathList = p.toSubpathPolygons();
00133 if (pathList.size() > 1)
00134 RELLOG("not only one sub-path polygon!");
00135
00136 iPol = pathList[0];
00137 iPol << endState->pos();
00138 pa = getArrowPolygon(p);
00139
00140 setLabelPosition();
00141 createStrokes(p);
00142 #ifdef MEASURE_TR_ADJUST
00143 DBGLOG("PM:" << "takes" << timer.elapsed() << "ms");
00144 #endif
00145 }
00146
00147 void TransitionVArc::setLabelPosition()
00148 {
00149 if (label)
00150 {
00151 Transition::setLabelPosition(label, label->posParam(), leftOriented, label->getWidth(), label->getHeight());
00152 }
00153 Transition::setLabelPosition();
00154 }
00155
00156 QString TransitionVArc::getTypeName() const
00157 {
00158 return "VArc";
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
00204
00205
00206
00207
00208
00209
00210
00211
00212 QString TransitionVArc::getVCCommand() const
00213 {
00214 QString command = "\\";
00215
00216 command += getTypeName();
00217 command += getTypeNameSuffix();
00218
00219 const int def_arcangle = leftOriented ? DEF_ARC_ANGLE : -DEF_ARC_ANGLE;
00220
00221 Q_ASSERT(label != NULL);
00222 if (label->posParam() != DEF_ARC_LAB_POS)
00223 command += QString("[%1]").arg(label->posParam());
00224
00225 command += "{";
00226 if (getArcAngle() != def_arcangle)
00227 command += QString("arcangle=%1").arg(getArcAngle());
00228 if (getNCurv() != DEF_ARC_CURV)
00229 {
00230 if (getArcAngle() != DEF_ARC_ANGLE)
00231 command += ",";
00232 command += QString("ncurv=%1").arg(getNCurv());
00233 }
00234 command += "}";
00235
00236 command += "{" + startState->getName() + "}";
00237 command += "{" + endState->getName() + "}";
00238
00239 command += "{" + label->text() + "}";
00240
00241 command += getNextLabelsVCCommand();
00242
00243 return command;
00244 }
00245
00246 QString TransitionVArc::getGraphMLParams() const
00247 {
00248 QString params = "";
00249
00250 if (getArcAngle() != DEF_ARC_ANGLE)
00251 {
00252 params += QString(" <data key=\"d130\">%1</data>\n")
00253 .arg(getArcAngle());
00254 }
00255 if (getNCurv() != DEF_ARC_CURV)
00256 {
00257 params += QString(" <data key=\"d133\">%1</data>\n")
00258 .arg(getNCurv());
00259 }
00260
00261 return params;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302