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