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

0001 /*.
0002     SPDX-FileCopyrightText: 2007 Vladimir Kuznetsov <ks.vladimir@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef STEP_WORLDGRAPHICS_H
0008 #define STEP_WORLDGRAPHICS_H
0009 
0010 #include "worldscene.h"
0011 
0012 #include <stepcore/vector.h>
0013 #include <QGraphicsItem>
0014 #include <QMenu>
0015 
0016 namespace StepCore {
0017     class Object;
0018     class Item;
0019     class Particle;
0020 }
0021 class WorldModel;
0022 class WorldScene;
0023 class QEvent;
0024 class KActionCollection;
0025 
0026 /** \brief Base class for item creators.
0027  *
0028  * Item creator handles the process of creating new item by the user. As long as it exists it
0029  * acts as a filer for all scene events. When creation is finished subclass should call
0030  * setFinished(true) to notify the scene. */
0031 class ItemCreator
0032 {
0033 public:
0034     ItemCreator(const QString& className, WorldModel* worldModel, WorldScene* worldScene)
0035            : _className(className), _worldModel(worldModel),
0036              _worldScene(worldScene), _item(nullptr), _finished(false), _messageId(-1) {}
0037     virtual ~ItemCreator() { closeMessage(); }
0038 
0039     /** Returns class name of the item which this creator creates */
0040     QString className() const { return _className; }
0041 
0042     /** Returns translated class name of the item which this creator creates */
0043     QString classNameTr() const { return QObject::tr(_className.toUtf8().constData(), "ObjectClass"); }
0044     
0045     /** Returns created item or NULL if item is not yet created */
0046     StepCore::Item* item() const { return _item; }
0047 
0048     /** Virtual function which is called on any scene event. Should return true if
0049      *  event is accepted or false to allow the scene to continue event processing. */
0050     virtual bool sceneEvent(QEvent* event);
0051 
0052     /** Virtual function which is called when
0053      *  creation process is started */
0054     virtual void start();
0055 
0056     /** Virtual function which is called when
0057      *  creation process is aborted by the user */
0058     virtual void abort() {}
0059 
0060     /** Return true if creation process is already
0061      *  finished and creator should be deleted */
0062     bool finished() { return _finished; }
0063 
0064 protected:
0065     /** Show creation status message. If flags do not contains CloseButton and CloseTimer than it is
0066      *  treated as persistent status message (and will replace previous status message, if any).
0067      *  In flags contains CloseButton or CloseTimer than it is treated as additional message */
0068     void showMessage(MessageFrame::Type type, const QString& text, MessageFrame::Flags flags = {});
0069     /** Close last persistent status message */
0070     void closeMessage();
0071 
0072     /** Set creation finished state */
0073     void setFinished(bool finished = true) { _finished = finished; }
0074 
0075     /** Set created item */
0076     void setItem(StepCore::Item* item) { _item = item; }
0077 
0078     /** Get associated WorldModel */
0079     WorldModel* worldModel() { return _worldModel; }
0080 
0081     /** Get associated WorldScene */
0082     WorldScene* worldScene() { return _worldScene; }
0083 
0084 protected:
0085     QString     _className;
0086     WorldModel* _worldModel;
0087     WorldScene* _worldScene;
0088     StepCore::Item* _item;
0089     bool _finished;
0090     int _messageId;
0091 };
0092 
0093 /////////////////////////////////////////////////////////////////////////////////////////
0094 
0095 /** \brief ItemCreator for items that can be attached to other items */
0096 class AttachableItemCreator: public ItemCreator
0097 {
0098 public:
0099     AttachableItemCreator(const QString& className, WorldModel* worldModel, WorldScene* worldScene)
0100                 : ItemCreator(className, worldModel, worldScene),
0101                     _snapFlags(WorldScene::SnapParticle | WorldScene::SnapRigidBody |
0102                     WorldScene::SnapSetPosition | WorldScene::SnapSetLocalPosition), _snapTypes(nullptr), _twoEnds(false) {}
0103 
0104     /** Constructs AttachableItemCreator
0105      *
0106      *  \param className class name
0107      *  \param worldModel WorldModel
0108      *  \param worldScene WorldScene
0109      *  \param snapFlags WorldScene::SnapFlags for attaching
0110      *  \param snapTypes Additional item types to attach
0111      *  \param twoEnds true if this item has two ends (like spring or stick)
0112      */
0113     AttachableItemCreator(const QString& className, WorldModel* worldModel, WorldScene* worldScene,
0114                             WorldScene::SnapFlags snapFlags, WorldScene::SnapList* snapTypes, bool twoEnds = false)
0115                         : ItemCreator(className, worldModel, worldScene),
0116                           _snapFlags(snapFlags), _snapTypes(snapTypes), _twoEnds(twoEnds) {}
0117 
0118     bool sceneEvent(QEvent* event) override;
0119     void start() override;
0120     void abort() override;
0121 
0122 protected:
0123     WorldScene::SnapFlags _snapFlags;
0124     WorldScene::SnapList* _snapTypes;
0125     bool                  _twoEnds;
0126 };
0127 
0128 
0129 /////////////////////////////////////////////////////////////////////////////////////////
0130 
0131 /** \brief Base class for item context menu handlers.
0132  * The menu handler is created before showing context menu
0133  * for the item and destroyed when menu is hidden.
0134  */
0135 class ItemMenuHandler : public QObject
0136 {
0137     Q_OBJECT
0138 
0139 public:
0140     ItemMenuHandler(StepCore::Object* object, WorldModel* worldModel, QObject* parent = nullptr);
0141 
0142     /** Populate context menu by item-specific entries.
0143      *  Default implementation adds delete action. */
0144     virtual void populateMenu(QMenu* menu, KActionCollection* actions);
0145 
0146 protected:
0147     StepCore::Object* _object;
0148     WorldModel* _worldModel;
0149 };
0150 
0151 #endif
0152