File indexing completed on 2024-04-28 07:39:37

0001 /*.
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "particlegraphics.h"
0008 
0009 #include <stepcore/particle.h>
0010 
0011 #include "worldmodel.h"
0012 #include "worldfactory.h"
0013 #include <QGraphicsSceneMouseEvent>
0014 #include <QPainter>
0015 
0016 ParticleGraphicsItem::ParticleGraphicsItem(StepCore::Item* item, WorldModel* worldModel)
0017     : StepGraphicsItem(item, worldModel)
0018 {
0019     Q_ASSERT(dynamic_cast<StepCore::Particle*>(_item) != nullptr);
0020     setFlag(QGraphicsItem::ItemIsSelectable);
0021     setFlag(QGraphicsItem::ItemIsMovable);
0022     setAcceptHoverEvents(true);
0023     _lastArrowRadius = -1;
0024     _velocityHandler = new ArrowHandlerGraphicsItem(item, worldModel, this,
0025                    _item->metaObject()->property(QStringLiteral("velocity")));
0026     _velocityHandler->setVisible(false);
0027     //scene()->addItem(_velocityHandler);
0028 }
0029 
0030 QPainterPath ParticleGraphicsItem::shape() const
0031 {
0032     QPainterPath path;
0033     double radius = (RADIUS+1)/currentViewScale();
0034     path.addEllipse(QRectF(-radius,-radius,radius*2,radius*2));
0035     return path;
0036 }
0037 
0038 void ParticleGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
0039 {
0040     //painter->setPen(QPen(Qt::green, 0));
0041     //painter->drawRect(boundingRect());
0042 
0043     double s = currentViewScale();
0044     double radius = RADIUS/s;
0045 
0046     int renderHints = painter->renderHints();
0047     painter->setRenderHint(QPainter::Antialiasing, true);
0048     
0049     QColor color = QColor::fromRgba(particle()->color());
0050     if(isItemHighlighted()) color = highlightColor(color);
0051     painter->setPen(Qt::NoPen);
0052     painter->setBrush(QBrush(color));
0053 
0054     painter->drawEllipse(QRectF(-radius,-radius,radius*2,radius*2));
0055     //painter->setPen(QPen(QColor::fromRgba(particle()->color()), 2*radius, Qt::SolidLine, Qt::RoundCap));
0056     //painter->drawPoint(0,0);
0057 
0058     if(_isSelected) {
0059         painter->setPen(QPen(SELECTION_COLOR, 0, Qt::DashLine));
0060         painter->setBrush(Qt::NoBrush);
0061         //painter->setBrush(QBrush(QColor(0, 0x99, 0xff)));
0062         radius = (RADIUS+SELECTION_MARGIN)/s;
0063         painter->drawEllipse(QRectF(-radius, -radius, radius*2, radius*2));
0064     }
0065 
0066     if(_isMouseOverItem || _isSelected) {
0067         painter->setRenderHint(QPainter::Antialiasing, renderHints & QPainter::Antialiasing);
0068         painter->setPen(QPen(Qt::blue, 0));
0069         drawArrow(painter, particle()->velocity());
0070         painter->setPen(QPen(Qt::red, 0));
0071         drawArrow(painter, particle()->acceleration());
0072     }
0073 }
0074 
0075 void ParticleGraphicsItem::viewScaleChanged()
0076 {
0077     prepareGeometryChange();
0078 
0079     double s = currentViewScale();
0080     _boundingRect = QRectF((-RADIUS-SELECTION_MARGIN)/s,  (-RADIUS-SELECTION_MARGIN)/s,
0081                             (RADIUS+SELECTION_MARGIN)*2/s,(RADIUS+SELECTION_MARGIN)*2/s);
0082 
0083     if(_isMouseOverItem || _isSelected) {
0084         if(_lastArrowRadius < 0) {
0085             double vnorm = particle()->velocity().norm();
0086             double anorm = particle()->acceleration().norm();
0087             _lastArrowRadius = qMax(vnorm, anorm) + ARROW_STROKE/s;
0088         }
0089         _boundingRect |= QRectF(-_lastArrowRadius, -_lastArrowRadius,
0090                                     2*_lastArrowRadius, 2*_lastArrowRadius);
0091     }
0092 }
0093 
0094 void ParticleGraphicsItem::worldDataChanged(bool)
0095 {
0096     if(_isMouseOverItem || _isSelected) {
0097         double vnorm = particle()->velocity().norm();
0098         double anorm = particle()->acceleration().norm();
0099         double arrowRadius = qMax(vnorm, anorm) + ARROW_STROKE/currentViewScale();
0100         if(arrowRadius > _lastArrowRadius || arrowRadius < _lastArrowRadius/2) {
0101             _lastArrowRadius = arrowRadius;
0102             viewScaleChanged();
0103         }
0104         update();
0105     }
0106     setPos(vectorToPoint(particle()->position()));
0107 }
0108 
0109 void ParticleGraphicsItem::stateChanged()
0110 {
0111     if(_isSelected) _velocityHandler->setVisible(true);
0112     else _velocityHandler->setVisible(false);
0113     if(!_isMouseOverItem && !_isSelected) _lastArrowRadius = -1;
0114     viewScaleChanged();
0115     update();
0116 }
0117