00001 #include "constants.h"
00002
00003 #include "transitionLoop.h"
00004 #include "state.h"
00005 #include "label.h"
00006 #include "transforms.h"
00007
00008 #include <math.h>
00009
00010 #include <QtDebug>
00011
00012 TransitionLoop::TransitionLoop(Editor *parent, State *state, const QString &labelText, int type,
00013 bool dimmed, int d)
00014 : OneStateTransition(parent,state,dimmed), loopType(type), direction(d)
00015 {
00016 setZValue(Z_TRANSITION);
00017 label = new LabelX(this, labelText, leftOriented, m_labelFontSize,
00018 dimmed ? QColor(dimEdgeLabelColor) : QColor(edgeLabelColor));
00019 label->setZValue(Z_TR_LABEL);
00020 label->setPosParam(DEF_LOOP_LAB_POS);
00021 adjust();
00022 }
00023
00024 TransitionLoop::~TransitionLoop()
00025 {
00026 DBGLOG("called");
00027 }
00028
00029 void TransitionLoop::adjust()
00030 {
00031 prepareGeometryChange();
00032 if (!startState) return;
00033 startPoint = startState->pos();
00034 setPos(startPoint.x(), startPoint.y());
00035
00036 int angle = (loopType == eLoop ? TR_LOOP_OPENING_ANGLE :
00037 (loopType == eCLoop ? TR_CLOOP_OPENING_ANGLE : TR_LOOPVAR_OPENING_ANGLE));
00038
00039 QLineF firstLine(0,0,startState->getWidth()+10,0);
00040 firstLine.setAngle(trAngleFromDirection(direction) + angle);
00041 QPolygonF anglePol;
00042 anglePol << firstLine.p1() << firstLine.p2();
00043 QPolygonF firstPol = findIntersectedPoints(anglePol, startState->getMyPolygon(), eFIND_FIRST);
00044 firstLine.translate(firstPol[0]);
00045
00046 QLineF secondLine(0,0,startState->getWidth()+10, 0);
00047 secondLine.setAngle(trAngleFromDirection(direction) - angle);
00048 anglePol.clear();
00049 anglePol << secondLine.p1() << secondLine.p2();
00050 QPolygonF secondPol = findIntersectedPoints(anglePol, startState->getMyPolygon(), eFIND_FIRST);
00051 secondLine.translate(secondPol[0]);
00052
00053 QLineF lenLine(firstPol[0], secondPol[0]);
00054 lenLine.setLength(lenLine.length() * TR_LOOP_MULTIPLICATOR);
00055
00056 firstLine.setLength(lenLine.length());
00057 secondLine.setLength(lenLine.length());
00058
00059 QPainterPath path;
00060 path.moveTo(firstPol[0]);
00061 path.cubicTo(firstLine.p2(),secondLine.p2(), secondPol[0]);
00062 p = path;
00063
00064 QList<QPolygonF> pathList;
00065
00066 QPolygonF loopPol;
00067 QLineF testLine;
00068 switch (direction)
00069 {
00070 case NORTH:
00071 case NORTH_EAST:
00072 case EAST:
00073 case SOUTH_WEST:
00074 pathList = p.toSubpathPolygons();
00075 loopPol << pathList[0] << QPointF(0,0);
00076 break;
00077 case NORTH_WEST:
00078 case WEST:
00079 case SOUTH:
00080 case SOUTH_EAST:
00081 p = p.toReversed();
00082 pathList = p.toSubpathPolygons();
00083 loopPol << pathList[0] << QPointF(0,0);
00084 break;
00085 default:
00086 RELLOG("unexpected state!!!");
00087 }
00088
00089 if (pathList.size() > 1)
00090 {
00091 RELLOG("not only one subpath polygon!");
00092 Q_ASSERT(!"not only one subpath polygon");
00093 }
00094
00095 pa = getArrowPolygon(p);
00096
00097 setLabelPosition();
00098 createStrokes(p);
00099 }
00100
00101 QString TransitionLoop::getTypeName() const
00102 {
00103 if (loopType == TransitionLoop::eCLoop)
00104 return "CLoop";
00105 else if (loopType == TransitionLoop::eLoopVar)
00106 return "LoopVar";
00107 else
00108 return "Loop";
00109 }
00110
00111 void TransitionLoop::setDirection(int d)
00112 {
00113 direction = d;
00114 adjust();
00115 setLabelPosition();
00116 }
00117
00118 int TransitionLoop::getDirection() const
00119 {
00120 return direction;
00121 }
00122
00123 void TransitionLoop::setLabelPosition()
00124 {
00125 bool isLeft = (direction == NORTH || direction == NORTH_EAST || direction == EAST || direction == SOUTH_WEST);
00126
00127 if (label)
00128 {
00129 Transition::setLabelPosition(label, label->posParam(), isLeft, label->getWidth(), label->getHeight());
00130 }
00131 Transition::setLabelPosition();
00132 }
00133
00134 void TransitionLoop::paint(QPainter * painter, const QStyleOptionGraphicsItem * , QWidget * )
00135 {
00136 QColor lineC;
00137 Qt::PenStyle lineS;
00138
00139 if (dimmed)
00140 {
00141 lineS = dimEdgeLineStyle;
00142 lineC = dimEdgeLineColor;
00143 }
00144 else
00145 {
00146 lineS = edgeLineStyle;
00147 lineC = edgeLineColor;
00148 }
00149
00150 if (checked)
00151 painter->setPen(QPen(checkedColor, m_lineWidth, lineS));
00152 else
00153 painter->setPen(QPen(lineC, m_lineWidth, lineS));
00154
00155 painter->setBrush(Qt::NoBrush);
00156 painter->drawPath(p);
00157
00158
00159 if (checked)
00160 painter->setBrush(checkedColor);
00161 else
00162 painter->setBrush(lineC);
00163
00164 painter->drawPolygon(pa);
00165
00166 paintSelectionDecoration(painter);
00167
00168 #ifdef TESTING_PAINTING
00169 # ifdef TESTING_BOUNDING_RECT_PAINTING
00170 painter->setBrush(QBrush(QColor(50,255,0,100)));
00171 painter->fillRect(boundingRect(), painter->brush());
00172 # endif
00173
00174 painter->setBrush(QBrush(QColor(0,0,255,150)));
00175 painter->fillPath(shape(), painter->brush());
00176 #endif
00177 }
00178
00179 QString TransitionLoop::getVCCommand() const
00180 {
00181 QString command = "\\";
00182
00183 bool isVarLoopNotNorthOrSouth = false;
00184
00185
00186
00187 if (loopType == eCLoop)
00188 {
00189 command += "CLoop";
00190 }
00191 else if (loopType == eLoop)
00192 {
00193 command += "Loop";
00194 }
00195 else
00196 {
00197 Q_ASSERT(loopType == eLoopVar);
00198 if (getDirection() != NORTH &&
00199 getDirection() != SOUTH)
00200 {
00201 isVarLoopNotNorthOrSouth = true;
00202 command += "VarLoopOn \\";
00203 command += "Loop";
00204 }
00205 else
00206 {
00207 command += "LoopVar";
00208 }
00209 }
00210
00211 command += getTypeNameSuffix().toUpper();
00212
00213 Q_ASSERT(label != NULL);
00214
00215 if (label->posParam() != DEF_LOOP_LAB_POS)
00216 command += QString("[%1]").arg(label->posParam());
00217
00218 command += "{" + startState->getName() + "}";
00219
00220 command += "{" + label->text() + "}";
00221
00222 if (isVarLoopNotNorthOrSouth)
00223 command += " \\VarLoopOff";
00224
00225 command += getNextLabelsVCCommand();
00226
00227 return command;
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
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271