File indexing completed on 2024-04-28 07:39:40
0001 /*. 0002 SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com> 0003 SPDX-FileCopyrightText: 2014 Inge Wallin <inge@lysator.liu.se> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "stepgraphicsitem.h" 0009 0010 #include "settings.h" 0011 0012 #include "worldmodel.h" 0013 #include <stepcore/object.h> 0014 #include <stepcore/world.h> 0015 #include <stepcore/particle.h> 0016 0017 #include <QGraphicsScene> 0018 #include <QGraphicsSceneMouseEvent> 0019 #include <QItemSelectionModel> 0020 #include <QMenu> 0021 #include <QPainter> 0022 #include <QTimer> 0023 0024 #include <KLocalizedString> 0025 0026 #include <cmath> 0027 0028 // XXX 0029 #include "worldscene.h" 0030 0031 //XXX 0032 const QColor StepGraphicsItem::SELECTION_COLOR = QColor(0xff, 0x70, 0x70); 0033 0034 0035 ///////////////////////////////////////////////////////////////////////////////////////// 0036 0037 0038 StepGraphicsItem::StepGraphicsItem(StepCore::Item* item, WorldModel* worldModel, 0039 QGraphicsItem* parent) 0040 : QGraphicsItem(parent) 0041 , _item(item) 0042 , _worldModel(worldModel) 0043 , _exclusiveMoving(false) 0044 , _onHoverHandlerEnabled(false) 0045 , _isHighlighted(false) 0046 , _isMouseOverItem(false) 0047 , _isSelected(false) 0048 , _isMoving(false) 0049 , _onHoverHandler(nullptr) 0050 , _onHoverHandlerTimer(false) 0051 { 0052 // XXX: use persistent indexes here and in propertiesbrowser 0053 setZValue(BODY_ZVALUE); 0054 } 0055 0056 double StepGraphicsItem::currentViewScale() const 0057 { 0058 if(!scene()) return 1; 0059 return static_cast<WorldScene*>(scene())->currentViewScale(); 0060 } 0061 0062 QColor StepGraphicsItem::highlightColor(const QColor& color) 0063 { 0064 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) 0065 float h, s, v, a; 0066 #else 0067 qreal h, s, v, a; 0068 #endif 0069 QColor hsv = color.toHsv(); 0070 hsv.getHsvF(&h, &s, &v, &a); 0071 0072 v += float(COLOR_HIGHLIGHT_AMOUNT)/100; 0073 if (v > 1.0) { 0074 // overflow... adjust saturation 0075 s -= v - 1.0; 0076 if (s < 0) s = 0.0; 0077 v = 1.0; 0078 } 0079 0080 hsv.setHsvF(h, s, v, a); 0081 0082 // convert back to same color spec as original color 0083 return hsv.convertTo(color.spec()); 0084 } 0085 0086 void StepGraphicsItem::drawArrow(QPainter* painter, const StepCore::Vector2d& r, 0087 const StepCore::Vector2d& v) 0088 { 0089 double s = currentViewScale(); 0090 if(v.squaredNorm()*s*s > ARROW_STROKE*ARROW_STROKE) { // do not draw too small vectors 0091 StepCore::Vector2d vv = r+v; 0092 painter->drawLine(QLineF(r[0], r[1], vv[0], vv[1])); 0093 0094 const StepCore::Vector2d vn = v * (ARROW_STROKE / s / v.norm()); 0095 painter->drawLine(QLineF(vv[0], vv[1], vv[0] - 0.866*vn[0] - 0.5 *vn[1], 0096 vv[1] + 0.5 *vn[0] - 0.866*vn[1])); 0097 painter->drawLine(QLineF(vv[0], vv[1], vv[0] - 0.866*vn[0] + 0.5 *vn[1], 0098 vv[1] - 0.5 *vn[0] - 0.866*vn[1])); 0099 } 0100 } 0101 0102 void StepGraphicsItem::drawCircularArrow(QPainter* painter, const StepCore::Vector2d& r, 0103 double angle, double radius) 0104 { 0105 double s = currentViewScale(); 0106 double rs = radius/s; 0107 double x0 = rs*cos(angle)+r[0]/s; 0108 double y0 = rs*sin(angle)+r[1]/s; 0109 double xAr1 = CIRCULAR_ARROW_STROKE*cos(2*M_PI/3 + angle)/s; 0110 double yAr1 = CIRCULAR_ARROW_STROKE*sin(2*M_PI/3 + angle)/s; 0111 double xAr2 = CIRCULAR_ARROW_STROKE*cos(M_PI/3 + angle)/s; 0112 double yAr2 = CIRCULAR_ARROW_STROKE*sin(M_PI/3 + angle)/s; 0113 0114 QRectF rr(-rs, -rs, 2*rs, 2*rs); 0115 0116 if(angle > 2*M_PI || angle < -2*M_PI) { 0117 painter->drawArc(rr, int(-angle*180*16/M_PI-150*16), 300*16); 0118 for(int i=1; i<5; ++i) 0119 painter->drawArc(rr, int(-angle*180*16/M_PI-150*16-i*12*16), 1*16); 0120 } else if(angle > 0) { 0121 painter->drawArc(rr, -int(angle*180*16/M_PI), int(angle*180*16/M_PI)); 0122 } else { 0123 painter->drawArc(rr, 0, int(-angle*180*16/M_PI)); 0124 } 0125 0126 // do not draw too small vectors 0127 if(angle > 0 && angle*radius > CIRCULAR_ARROW_STROKE) { 0128 painter->drawLine(QLineF(x0, y0, x0-xAr1, y0-yAr1)); 0129 painter->drawLine(QLineF(x0, y0, x0-xAr2, y0-yAr2)); 0130 } if(angle < 0 && -angle*radius > CIRCULAR_ARROW_STROKE) { 0131 painter->drawLine(QLineF(x0, y0, x0+xAr1, y0+yAr1)); 0132 painter->drawLine(QLineF(x0, y0, x0+xAr2, y0+yAr2)); 0133 } 0134 } 0135 0136 void StepGraphicsItem::drawArrow(QPainter* painter, const StepCore::Vector2d& v) 0137 { 0138 drawArrow(painter, StepCore::Vector2d::Zero(), v); 0139 } 0140 0141 void StepGraphicsItem::drawCircularArrow(QPainter* painter, double angle, double radius) 0142 { 0143 drawCircularArrow(painter, StepCore::Vector2d::Zero(), angle, radius); 0144 } 0145 0146 void StepGraphicsItem::mouseSetPos(const QPointF& pos, const QPointF&, MovingState) 0147 { 0148 const StepCore::MetaProperty* property = _item->metaObject()->property(QStringLiteral("position")); 0149 if(property != nullptr) { 0150 _worldModel->simulationPause(); 0151 _worldModel->setProperty(_item, property, 0152 QVariant::fromValue( pointToVector(pos) )); 0153 } else { 0154 Q_ASSERT(false); 0155 } 0156 } 0157 0158 void StepGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 0159 { 0160 // Workaround for bug in Qt 0161 if (scene()->itemAt(event->scenePos(), QTransform()) != this) { 0162 event->ignore(); 0163 return; 0164 } 0165 0166 if(event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) { 0167 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0; 0168 if(!multiSelect && !isSelected()) { 0169 if(scene()) scene()->clearSelection(); 0170 _worldModel->selectionModel()->clearSelection(); 0171 setSelected(true); 0172 } 0173 } else if (!(flags() & ItemIsMovable)) { 0174 event->ignore(); 0175 } 0176 } 0177 0178 void StepGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 0179 { 0180 // Workaround for bug in Qt 0181 if (scene()->mouseGrabberItem() != this && 0182 scene()->itemAt(event->scenePos(), QTransform()) != this) { 0183 event->ignore(); 0184 return; 0185 } 0186 0187 if((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) { 0188 QPointF pdiff(mapToParent(event->pos()) - mapToParent(event->lastPos())); 0189 QPointF newPos(mapToParent(event->pos()) - transform().map(event->buttonDownPos(Qt::LeftButton))); 0190 0191 QPointF diff = newPos - pos(); 0192 if(diff == QPointF(0, 0)) return; 0193 0194 MovingState movingState = Moving; 0195 if(!_isMoving) { 0196 if(_exclusiveMoving) { 0197 if(!_exclusiveMovingMessage.isEmpty()) _worldModel->beginMacro(_exclusiveMovingMessage); 0198 else _worldModel->beginMacro(i18n("Move %1", _item->name())); 0199 0200 } else { 0201 int count = 0; 0202 foreach(QGraphicsItem *item, scene()->selectedItems()) 0203 if(item != this && (item->flags() & ItemIsMovable) && 0204 (!item->parentItem() || !item->parentItem()->isSelected()) && 0205 dynamic_cast<StepGraphicsItem*>(item)) { 0206 ++count; 0207 } 0208 if(!this->parentItem() || !this->parentItem()->isSelected()) ++count; 0209 0210 _worldModel->beginMacro(i18n("Move %1", count == 1 ? _item->name() : i18n("several objects"))); 0211 } 0212 0213 movingState = Started; 0214 _isMoving = true; 0215 } 0216 0217 if(_exclusiveMoving) { 0218 mouseSetPos(newPos, pdiff, movingState); 0219 } else { 0220 // Move all selected items 0221 foreach(QGraphicsItem *item, scene()->selectedItems()) { 0222 if(item != this && (item->flags() & ItemIsMovable) && 0223 (!item->parentItem() || !item->parentItem()->isSelected())) { 0224 StepGraphicsItem* worldItem = dynamic_cast<StepGraphicsItem*>(item); 0225 if(worldItem) worldItem->mouseSetPos(item->pos() + diff, pdiff, movingState); 0226 } 0227 } 0228 if(!this->parentItem() || !this->parentItem()->isSelected()) 0229 mouseSetPos(newPos, pdiff, movingState); 0230 } 0231 } else { 0232 event->ignore(); 0233 } 0234 } 0235 0236 void StepGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 0237 { 0238 // Workaround for bug in Qt 0239 if (scene()->itemAt(event->scenePos(), QTransform()) != this) { 0240 event->ignore(); 0241 return; 0242 } 0243 0244 if(_isMoving && event->button() == Qt::LeftButton) { 0245 QPointF pdiff(mapToParent(event->pos()) - mapToParent(event->lastPos())); 0246 QPointF newPos(mapToParent(event->pos()) - transform().map(event->buttonDownPos(Qt::LeftButton))); 0247 QPointF diff = newPos - pos(); 0248 0249 if(_exclusiveMoving) { 0250 mouseSetPos(newPos, pdiff, Finished); 0251 } else { 0252 foreach(QGraphicsItem *item, scene()->selectedItems()) { 0253 if(item != this && (item->flags() & ItemIsMovable) && 0254 (!item->parentItem() || !item->parentItem()->isSelected())) { 0255 StepGraphicsItem* worldItem = dynamic_cast<StepGraphicsItem*>(item); 0256 if(worldItem) worldItem->mouseSetPos(item->pos() + diff, pdiff, Finished); 0257 } 0258 } 0259 if(!this->parentItem() || !this->parentItem()->isSelected()) 0260 mouseSetPos(newPos, pdiff, Finished); 0261 } 0262 0263 _worldModel->endMacro(); 0264 _isMoving = false; 0265 } 0266 if(flags() & ItemIsSelectable) { 0267 bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0; 0268 if(event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) { 0269 // The item didn't move 0270 if (multiSelect) { 0271 setSelected(!isSelected()); 0272 } else { 0273 if(scene()) scene()->clearSelection(); 0274 _worldModel->selectionModel()->clearSelection(); 0275 setSelected(true); 0276 } 0277 } 0278 } 0279 } 0280 0281 void StepGraphicsItem::hoverMoveEvent(QGraphicsSceneHoverEvent* event) 0282 { 0283 if(_onHoverHandlerEnabled) { 0284 OnHoverHandlerGraphicsItem* newOnHoverHandler = createOnHoverHandler(event->scenePos()); 0285 if(_onHoverHandler && !newOnHoverHandler) { 0286 if(!_onHoverHandlerTimer) { 0287 _onHoverHandler->setDeleteTimerEnabled(true); 0288 _onHoverHandlerTimer = true; 0289 } 0290 } else if(_onHoverHandler == newOnHoverHandler) { 0291 if(_onHoverHandler && _onHoverHandlerTimer) { 0292 _onHoverHandler->setDeleteTimerEnabled(false); 0293 _onHoverHandlerTimer = false; 0294 } 0295 } else { 0296 delete _onHoverHandler; 0297 _onHoverHandler = newOnHoverHandler; 0298 _onHoverHandlerTimer = false; 0299 } 0300 } 0301 } 0302 0303 void StepGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* /*event*/) 0304 { 0305 if(_onHoverHandlerEnabled && _onHoverHandler && !_onHoverHandlerTimer) 0306 _onHoverHandler->setDeleteTimerEnabled(false); 0307 _isMouseOverItem = true; 0308 stateChanged(); 0309 //update(_boundingRect); 0310 } 0311 0312 void StepGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* /*event*/) 0313 { 0314 if(_onHoverHandlerEnabled && _onHoverHandler && !_onHoverHandlerTimer) 0315 _onHoverHandler->setDeleteTimerEnabled(true); 0316 _isMouseOverItem = false; 0317 stateChanged(); 0318 //update(_boundingRect); 0319 } 0320 0321 QVariant StepGraphicsItem::itemChange(GraphicsItemChange change, const QVariant& value) 0322 { 0323 if(change == ItemSelectedHasChanged && value.toBool() != _isSelected && scene()) { 0324 _isSelected = value.toBool(); 0325 if(_isSelected) setZValue(zValue() + 1); 0326 else setZValue(zValue() - 1); 0327 0328 QModelIndex index = _worldModel->objectIndex(_item); 0329 if(_isSelected && !_worldModel->selectionModel()->isSelected(index)) { 0330 _worldModel->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select); 0331 } else if(!_isSelected && _worldModel->selectionModel()->isSelected(index)) { 0332 _worldModel->selectionModel()->select(index, QItemSelectionModel::Deselect); 0333 } 0334 0335 stateChanged(); 0336 } 0337 return QGraphicsItem::itemChange(change, value); 0338 } 0339 0340 void StepGraphicsItem::setOnHoverHandlerEnabled(bool enabled) 0341 { 0342 _onHoverHandlerEnabled = enabled; 0343 if(!_onHoverHandlerEnabled) { 0344 _onHoverHandlerTimer = false; 0345 delete _onHoverHandler; 0346 } 0347 } 0348 0349 void StepGraphicsItem::viewScaleChanged() 0350 { 0351 } 0352 0353 void StepGraphicsItem::worldDataChanged(bool) 0354 { 0355 } 0356 0357 void StepGraphicsItem::stateChanged() 0358 { 0359 } 0360 0361 void StepGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem*, QWidget*) 0362 { 0363 painter->setPen(QPen(Qt::gray, 0)); 0364 painter->drawRect(_boundingRect); 0365 } 0366 0367 void StepGraphicsItem::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) 0368 { 0369 event->accept(); 0370 0371 QModelIndex index = _worldModel->objectIndex(_item); 0372 if(flags() & QGraphicsItem::ItemIsSelectable) 0373 _worldModel->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); 0374 0375 QMenu* menu = _worldModel->createContextMenu(index); 0376 menu->exec(event->screenPos()); 0377 delete menu; 0378 } 0379 0380 ///////////////////////////////////////////////////////////////////////////////////////// 0381 0382 ArrowHandlerGraphicsItem::ArrowHandlerGraphicsItem(StepCore::Item* item, WorldModel* worldModel, 0383 QGraphicsItem* parent, const StepCore::MetaProperty* property, 0384 const StepCore::MetaProperty* positionProperty) 0385 : StepGraphicsItem(item, worldModel, parent) 0386 , _property(property) 0387 , _positionProperty(positionProperty) 0388 { 0389 Q_ASSERT(!_property || _property->userTypeId() == qMetaTypeId<StepCore::Vector2d>()); 0390 setFlag(QGraphicsItem::ItemIsMovable); 0391 setZValue(HANDLER_ZVALUE); 0392 _exclusiveMoving = true; 0393 if(_property) _exclusiveMovingMessage = i18n("Change %1.%2", _item->name(), _property->nameTr()); 0394 else _exclusiveMovingMessage = i18n("Change %1", _item->name()); 0395 } 0396 0397 void ArrowHandlerGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, 0398 QWidget* /*widget*/) 0399 { 0400 painter->setPen(QPen(Qt::gray, 0)); 0401 painter->drawRect(_boundingRect); 0402 } 0403 0404 void ArrowHandlerGraphicsItem::viewScaleChanged() 0405 { 0406 if(isVisible()) { 0407 prepareGeometryChange(); 0408 double w = HANDLER_SIZE/currentViewScale()/2; 0409 _boundingRect = QRectF(-w, -w, w*2, w*2); 0410 } 0411 } 0412 0413 void ArrowHandlerGraphicsItem::worldDataChanged(bool) 0414 { 0415 if(isVisible()) { 0416 //qDebug() << "ArrowHandlerGraphicsItem::worldDataChanged()" << endl; 0417 setPos(vectorToPoint(value())); 0418 } 0419 } 0420 0421 QVariant ArrowHandlerGraphicsItem::itemChange(GraphicsItemChange change, const QVariant& value) 0422 { 0423 if(change == QGraphicsItem::ItemVisibleHasChanged) { 0424 if(isVisible()) { 0425 viewScaleChanged(); 0426 worldDataChanged(false); 0427 } 0428 } 0429 return StepGraphicsItem::itemChange(change, value); 0430 } 0431 0432 void ArrowHandlerGraphicsItem::mouseSetPos(const QPointF& pos, const QPointF&, MovingState) 0433 { 0434 setValue(pointToVector(pos)); 0435 } 0436 0437 /* 0438 void ArrowHandlerGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 0439 { 0440 if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) { 0441 if(!_isMoving) { 0442 if(_property) 0443 _worldModel->beginMacro(i18n("Change %1.%2", _item->name(), _property->nameTr())); 0444 else 0445 _worldModel->beginMacro(i18n("Change %1", _item->name())); 0446 _isMoving = true; 0447 } 0448 QPointF newPos(mapToParent(event->pos()) - matrix().map(event->buttonDownPos(Qt::LeftButton))); 0449 setValue(pointToVector(newPos)); 0450 //_worldModel->simulationPause(); 0451 //_worldModel->setProperty(_item, _property, QVariant::fromValue(pointToVector(newPos))); 0452 //Q_ASSERT(_property->writeVariant(_item, QVariant::fromValue(v))); 0453 //_worldModel->setData(_worldModel->objectIndex(_item), QVariant(), WorldModel::ObjectRole); 0454 } else event->ignore(); 0455 }*/ 0456 0457 StepCore::Vector2d ArrowHandlerGraphicsItem::value() 0458 { 0459 if(_property) { 0460 StepCore::Vector2d ret = _property->readVariant(_item).value<StepCore::Vector2d>(); 0461 if(_positionProperty) 0462 ret += _positionProperty->readVariant(_item).value<StepCore::Vector2d>(); 0463 return ret; 0464 } else { 0465 return StepCore::Vector2d::Zero(); 0466 } 0467 } 0468 0469 void ArrowHandlerGraphicsItem::setValue(const StepCore::Vector2d& value) 0470 { 0471 if(_property) { 0472 _worldModel->simulationPause(); 0473 StepCore::Vector2d v = value; 0474 if(_positionProperty) 0475 v -= _positionProperty->readVariant(_item).value<StepCore::Vector2d>(); 0476 _worldModel->setProperty(_item, _property, QVariant::fromValue(v)); 0477 } 0478 } 0479 0480 ///////////////////////////////////////////////////////////////////////////////////////// 0481 0482 CircularArrowHandlerGraphicsItem::CircularArrowHandlerGraphicsItem(StepCore::Item* item, 0483 WorldModel* worldModel, 0484 QGraphicsItem* parent, double radius, 0485 const StepCore::MetaProperty* property, 0486 const StepCore::MetaProperty* positionProperty) 0487 : StepGraphicsItem(item, worldModel, parent) 0488 , _property(property) 0489 , _positionProperty(positionProperty) 0490 , _radius(radius) 0491 { 0492 Q_ASSERT(!_property || _property->userTypeId() == qMetaTypeId<double>()); 0493 setFlag(QGraphicsItem::ItemIsMovable); 0494 setZValue(HANDLER_ZVALUE); 0495 } 0496 0497 void CircularArrowHandlerGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/) 0498 { 0499 painter->setPen(QPen(Qt::gray, 0)); 0500 painter->drawRect(_boundingRect); 0501 } 0502 0503 void CircularArrowHandlerGraphicsItem::viewScaleChanged() 0504 { 0505 if(isVisible()) { 0506 prepareGeometryChange(); 0507 double w = HANDLER_SIZE/currentViewScale()/2; 0508 _boundingRect = QRectF(-w, -w, w*2, w*2); 0509 worldDataChanged(true); 0510 } 0511 } 0512 0513 void CircularArrowHandlerGraphicsItem::worldDataChanged(bool) 0514 { 0515 if(isVisible()) { 0516 double s = currentViewScale(); 0517 double angle = value(); 0518 setPos(_radius*cos(angle)/s, _radius*sin(angle)/s); 0519 } 0520 } 0521 0522 QVariant CircularArrowHandlerGraphicsItem::itemChange(GraphicsItemChange change, const QVariant& value) 0523 { 0524 if(change == QGraphicsItem::ItemVisibleHasChanged) { 0525 if(isVisible()) { 0526 viewScaleChanged(); 0527 worldDataChanged(false); 0528 } 0529 } 0530 return StepGraphicsItem::itemChange(change, value); 0531 } 0532 0533 void CircularArrowHandlerGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) 0534 { 0535 if ((event->buttons() & Qt::LeftButton) && (flags() & ItemIsMovable)) { 0536 if(!_isMoving) { 0537 if(_property) 0538 _worldModel->beginMacro(i18n("Change %1.%2", _item->name(), _property->nameTr())); 0539 else 0540 _worldModel->beginMacro(i18n("Change %1", _item->name())); 0541 _isMoving = true; 0542 } 0543 0544 QPointF newPos(mapToParent(event->pos()) - transform().map(event->buttonDownPos(Qt::LeftButton))); 0545 double newValue = atan2(newPos.y(),newPos.x()); 0546 if(newValue < 0) newValue += 2*M_PI; 0547 0548 double v = value(); 0549 double b = 2*M_PI * int(v / (2*M_PI) - (v<0 ? 1 : 0)); 0550 double f = v - b; 0551 0552 if(f < M_PI_2 && newValue > 3*M_PI_2) newValue -= 2*M_PI; 0553 else if(f > 3*M_PI_2 && newValue < M_PI_2) newValue += 2*M_PI; 0554 0555 setValue(b + newValue); 0556 } else event->ignore(); 0557 } 0558 0559 void CircularArrowHandlerGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) 0560 { 0561 if(_isMoving && event->button() == Qt::LeftButton) { 0562 _worldModel->endMacro(); 0563 _isMoving = false; 0564 } 0565 } 0566 0567 double CircularArrowHandlerGraphicsItem::value() 0568 { 0569 if(_property) return _property->readVariant(_item).value<double>(); 0570 else return 0; 0571 } 0572 0573 void CircularArrowHandlerGraphicsItem::setValue(double value) 0574 { 0575 if(_property) { 0576 _worldModel->simulationPause(); 0577 _worldModel->setProperty(_item, _property, QVariant::fromValue(value)); 0578 } 0579 } 0580 0581 ///////////////////////////////////////////////////////////////////////////////////////// 0582 0583 const StepCore::Vector2d OnHoverHandlerGraphicsItem::corners[4] = { 0584 StepCore::Vector2d(-0.5,-0.5), StepCore::Vector2d( 0.5,-0.5), 0585 StepCore::Vector2d(-0.5, 0.5), StepCore::Vector2d( 0.5, 0.5) 0586 }; 0587 0588 const StepCore::Vector2d OnHoverHandlerGraphicsItem::scorners[4] = { 0589 StepCore::Vector2d(0,-1), StepCore::Vector2d( 1,0), 0590 StepCore::Vector2d(0, 1), StepCore::Vector2d(-1,0) 0591 }; 0592 0593 OnHoverHandlerGraphicsItem::OnHoverHandlerGraphicsItem(StepCore::Item* item, WorldModel* worldModel, 0594 QGraphicsItem* parent, const StepCore::MetaProperty* property, 0595 const StepCore::MetaProperty* positionProperty, int vertexNum) 0596 : ArrowHandlerGraphicsItem(item, worldModel, parent, property, positionProperty) 0597 , _vertexNum(vertexNum) 0598 { 0599 _deleteTimer = new QTimer(this); 0600 _deleteTimer->setInterval(500); 0601 _deleteTimer->setSingleShot(true); 0602 _deleteTimerEnabled = false; 0603 setAcceptHoverEvents(true); 0604 connect(_deleteTimer, &QTimer::timeout, this, &QObject::deleteLater); 0605 } 0606 0607 void OnHoverHandlerGraphicsItem::setDeleteTimerEnabled(bool enabled) 0608 { 0609 _deleteTimerEnabled = enabled; 0610 if(_deleteTimerEnabled && !isMouseOverItem()) _deleteTimer->start(); 0611 else _deleteTimer->stop(); 0612 } 0613 0614 void OnHoverHandlerGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) 0615 { 0616 if(_deleteTimerEnabled) _deleteTimer->stop(); 0617 ArrowHandlerGraphicsItem::hoverEnterEvent(event); 0618 } 0619 0620 void OnHoverHandlerGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) 0621 { 0622 if(_deleteTimerEnabled) _deleteTimer->start(); 0623 ArrowHandlerGraphicsItem::hoverLeaveEvent(event); 0624 } 0625 0626 #include "moc_stepgraphicsitem.cpp"