void LineItem::updateChildGeometry(const QRectF &oldParentRect, const QRectF &newParentRect) { // parent has been resized: update the line's dimensions: // we would like to have lines in terms of relative endpoint locations, // but instead they are in terms of length (relative to parent width) // and angle, relative to the parent. qreal theta = rotationAngle()*M_PI/180.0; qreal oldL = relativeWidth()*oldParentRect.width(); // we want to keep the endpoints fixed relative to the parent, so // we need to calculate new lengths and angles. qreal newDx = cos(theta)*oldL*newParentRect.width()/oldParentRect.width(); qreal newDy = sin(theta)*oldL*newParentRect.height()/oldParentRect.height(); qreal newWidth = sqrt(newDx*newDx + newDy*newDy); QTransform transform; transform.rotate(atan2(newDy, newDx)*180.0/M_PI); // my brain hurts less for rotations when we center the object at 0,0 QRectF itemRect(-newWidth*0.5, -rect().height()*0.5, newWidth, rect().height()); // we don't now what the parents's origin is, so, add .x() and .y() setPos(relativeCenter().x() * newParentRect.width() + newParentRect.x(), relativeCenter().y() * newParentRect.height()+ newParentRect.y()); setViewRect(itemRect, true); setTransform(transform); setRelativeWidth(newWidth / newParentRect.width()); }
void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); if (d->points.size() < 2) return ; // draw the bounding rect if the arrow is selected if (isSelected() /* && !m_hoverBegin && !m_hoverEnd */) { painter->save(); painter->setPen(Qt::blue); painter->drawRect(boundingRect()); painter->restore(); } if (d->points.isEmpty()) return ; // prepare pen and brush painter->save(); QPen pen; pen.setWidthF(lineWidth()) ; pen.setCapStyle(Qt::RoundCap) ; pen.setJoinStyle(Qt::RoundJoin) ; pen.setColor(getColor()) ; painter->setPen(pen) ; QPainterPath path ; // draw the line path.moveTo(d->points.first()) ; if (d->spline && splinePossible(d->points.size())) { for (int i = 1 ; i+2 < d->points.size() ; i += 3) path.cubicTo(d->points[i], d->points[i+1], d->points[i+2]); if (isSelected()) // Draw help lines { painter->save(); painter->setPen(Qt::gray) ; QPointF previous(d->points.first()) ; for (int i = 1 ; i+2 < d->points.size() ; i += 3) { painter->drawLine(previous, d->points[i]) ; painter->drawLine(d->points[i+1], d->points[i+2]); previous = d->points[i+2] ; } painter->restore(); } } else foreach(const QPointF p, d->points.mid(1)) path.lineTo(p) ; path.translate(-pos()); painter->drawPath(path) ; // draw arrow tips painter->setBrush(pen.color()); qreal tipScaling = relativeWidth(); if (MolScene *sc = qobject_cast<MolScene*>(scene())) tipScaling *= sc->settings()->arrowTipWidth()->get(); if ((UpperBackward | LowerBackward) & d->arrowType) painter->drawPath(generateArrowTip(d->points.last(), d->points[d->points.size()-2], pos(), UpperBackward & d->arrowType, LowerBackward & d->arrowType, tipScaling )); if ((UpperForward | LowerForward) & d->arrowType) painter->drawPath(generateArrowTip(d->points.first(), d->points[1], pos(), LowerForward & d->arrowType, UpperForward & d->arrowType, tipScaling )) ; painter->restore(); graphicsItem::paint(painter, option, widget); }