File indexing completed on 2024-04-28 03:51:22

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 "worldgraphics.h"
0009 
0010 #include "settings.h"
0011 
0012 #include "worldmodel.h"
0013 #include "stepgraphicsitem.h"
0014 #include <stepcore/object.h>
0015 #include <stepcore/world.h>
0016 #include <stepcore/particle.h>
0017 
0018 #include <QGraphicsScene>
0019 #include <QGraphicsSceneMouseEvent>
0020 #include <QItemSelectionModel>
0021 #include <QMenu>
0022 
0023 #include <KActionCollection>
0024 #include <KLocalizedString>
0025 
0026 #include <cmath>
0027 
0028 // XXX
0029 #include "worldscene.h"
0030 
0031 void ItemCreator::showMessage(MessageFrame::Type type, const QString& text, MessageFrame::Flags flags)
0032 {
0033     if(Settings::showCreationTips()) {
0034         if(!(flags & MessageFrame::CloseButton) && !(flags & MessageFrame::CloseTimer)) {
0035             _messageId = _worldScene->changeMessage(_messageId, type, text, flags);
0036         } else {
0037             _worldScene->showMessage(type, text, flags);
0038         }
0039     }
0040 }
0041 
0042 void ItemCreator::closeMessage()
0043 {
0044     _worldScene->closeMessage(_messageId);
0045 }
0046 
0047 void ItemCreator::start()
0048 {
0049     showMessage(MessageFrame::Information,
0050             i18n("Click on the scene to create a %1", classNameTr()));
0051 }
0052 
0053 bool ItemCreator::sceneEvent(QEvent* event)
0054 {
0055     if(event->type() == QEvent::GraphicsSceneMousePress) {
0056         _worldModel->simulationPause();
0057 
0058         _worldModel->beginMacro(i18n("Create %1", _worldModel->newItemName(_className)));
0059         _item = _worldModel->createItem(_className); Q_ASSERT(_item != nullptr);
0060         const StepCore::MetaProperty* property = _item->metaObject()->property(QStringLiteral("position"));
0061         if(property != nullptr) {
0062             QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
0063             QPointF pos = mouseEvent->scenePos();
0064             QVariant vpos = QVariant::fromValue(StepGraphicsItem::pointToVector(pos));
0065             _worldModel->setProperty(_item, property, vpos);
0066         }
0067         _worldModel->addItem(_item);
0068 
0069         _worldModel->endMacro();
0070 
0071         _worldModel->selectionModel()->setCurrentIndex(_worldModel->objectIndex(_item),
0072                                                     QItemSelectionModel::ClearAndSelect);
0073 
0074         showMessage(MessageFrame::Information,
0075                 i18n("%1 named '%2' created", classNameTr(), _item->name()),
0076                 MessageFrame::CloseButton | MessageFrame::CloseTimer);
0077 
0078         setFinished();
0079         return true;
0080     }
0081     return false;
0082 }
0083 
0084 /////////////////////////////////////////////////////////////////////////////////////////
0085 
0086 void AttachableItemCreator::start()
0087 {
0088     if(_twoEnds)
0089         showMessage(MessageFrame::Information,
0090             i18n("Press left mouse button to position first end of a %1\n"
0091                  "then drag and release it to position the second end", classNameTr()));
0092     else
0093         showMessage(MessageFrame::Information,
0094             i18n("Click on the scene to create a %1", classNameTr()));
0095 }
0096 
0097 bool AttachableItemCreator::sceneEvent(QEvent* event)
0098 {
0099     QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
0100 
0101     if(event->type() == QEvent::GraphicsSceneMouseMove && _item == nullptr) {
0102         _worldScene->snapHighlight(mouseEvent->scenePos(), _snapFlags, _snapTypes);
0103         return false;
0104 
0105     } else if(event->type() == QEvent::GraphicsSceneMousePress && mouseEvent->button() == Qt::LeftButton) {
0106         QPointF pos = mouseEvent->scenePos();
0107         _worldModel->simulationPause();
0108         _worldModel->beginMacro(i18n("Create %1", _worldModel->newItemName(_className)));
0109         _item = _worldModel->createItem(className()); Q_ASSERT(_item != nullptr);
0110 
0111         if(_twoEnds) {
0112             _worldScene->snapItem(pos, _snapFlags, _snapTypes, StepGraphicsItem::Finished, _item, 1);
0113             _worldModel->setProperty(_item, QStringLiteral("localPosition2"),
0114                             QVariant::fromValue(StepGraphicsItem::pointToVector(pos)));
0115             _worldModel->setProperty(_item, QStringLiteral("restLength"), 0);
0116 
0117             showMessage(MessageFrame::Information,
0118                 i18n("Release left mouse button to position second end of the %1", classNameTr()));
0119         } else {
0120             _worldScene->snapItem(pos, _snapFlags, _snapTypes, StepGraphicsItem::Finished, _item);
0121             showMessage(MessageFrame::Information,
0122                 i18n("%1 named '%2' created", classNameTr(), _item->name()),
0123                 MessageFrame::CloseButton | MessageFrame::CloseTimer);
0124             _worldModel->endMacro();
0125             setFinished();
0126         }
0127         _worldModel->addItem(_item);
0128         _worldModel->selectionModel()->setCurrentIndex(_worldModel->objectIndex(_item),
0129                                                        QItemSelectionModel::ClearAndSelect);
0130         return true;
0131 
0132     } else if(event->type() == QEvent::GraphicsSceneMouseMove &&
0133                     (mouseEvent->buttons() & Qt::LeftButton) && _twoEnds) {
0134 
0135         QPointF pos = mouseEvent->scenePos();
0136         _worldScene->snapItem(pos, _snapFlags, _snapTypes, StepGraphicsItem::Moving, _item, 2);
0137 
0138         double length =
0139             (_item->metaObject()->property(QStringLiteral("position2"))->readVariant(_item).value<StepCore::Vector2d>() -
0140              _item->metaObject()->property(QStringLiteral("position1"))->readVariant(_item).value<StepCore::Vector2d>()).norm();
0141         _worldModel->setProperty(_item, QStringLiteral("restLength"), length);
0142         return true;
0143 
0144     } else if(event->type() == QEvent::GraphicsSceneMouseRelease &&
0145                     (mouseEvent->button() == Qt::LeftButton) && _twoEnds) {
0146 
0147         QPointF pos = mouseEvent->scenePos();
0148         _worldScene->snapItem(pos, _snapFlags, _snapTypes, StepGraphicsItem::Finished, _item, 2);
0149 
0150         double length =
0151             (_item->metaObject()->property(QStringLiteral("position2"))->readVariant(_item).value<StepCore::Vector2d>() -
0152              _item->metaObject()->property(QStringLiteral("position1"))->readVariant(_item).value<StepCore::Vector2d>()).norm();
0153         _worldModel->setProperty(_item, QStringLiteral("restLength"), length);
0154         _worldModel->endMacro();
0155 
0156         showMessage(MessageFrame::Information,
0157             i18n("%1 named '%2' created", classNameTr(), _item->name()),
0158             MessageFrame::CloseButton | MessageFrame::CloseTimer);
0159 
0160         setFinished();
0161         return true;
0162     }
0163 
0164     return false;
0165 }
0166 
0167 void AttachableItemCreator::abort()
0168 {
0169     _worldScene->snapClear();
0170 }
0171 
0172 /////////////////////////////////////////////////////////////////////////////////////////
0173 
0174 ItemMenuHandler::ItemMenuHandler(StepCore::Object* object, WorldModel* worldModel, QObject* parent)
0175     : QObject(parent)
0176     , _object(object)
0177     , _worldModel(worldModel)
0178 {
0179 }
0180 
0181 void ItemMenuHandler::populateMenu(QMenu* menu, KActionCollection* actions)
0182 {
0183     StepCore::Item* item = dynamic_cast<StepCore::Item*>(_object);
0184     
0185     if (item && item->world() != item) {
0186         menu->addAction(actions->action(QStringLiteral("edit_cut")));
0187         menu->addAction(actions->action(QStringLiteral("edit_copy")));
0188         menu->addAction(actions->action(QStringLiteral("edit_delete")));
0189     }
0190 }
0191 
0192 #include "moc_worldgraphics.cpp"