summaryrefslogtreecommitdiffstats
path: root/src/mechanics/mechanicsitem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mechanics/mechanicsitem.h')
-rw-r--r--src/mechanics/mechanicsitem.h237
1 files changed, 237 insertions, 0 deletions
diff --git a/src/mechanics/mechanicsitem.h b/src/mechanics/mechanicsitem.h
new file mode 100644
index 0000000..db500fc
--- /dev/null
+++ b/src/mechanics/mechanicsitem.h
@@ -0,0 +1,237 @@
+/***************************************************************************
+ * Copyright (C) 2004-2005 by David Saxton *
+ * david@bluehaze.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#ifndef MECHANICSITEM_H
+#define MECHANICSITEM_H
+
+#include <item.h>
+#include <qvaluelist.h>
+
+class LibraryItem;
+class MechanicsItem;
+// class MechanicsItemOverlayItem;
+class MechanicsDocument;
+typedef QValueList<MechanicsItem*> MechanicsItemList;
+
+/**
+@short Stores mass, moment of inertia
+@author David Saxton
+*/
+class MechanicsInfo
+{
+public:
+ MechanicsInfo();
+
+ double mass; // Mass
+ double momentOfInertia; // Moment of inertia
+};
+
+class CombinedMechanicsInfo : public MechanicsInfo
+{
+public:
+ CombinedMechanicsInfo();
+ CombinedMechanicsInfo( const MechanicsInfo &info );
+
+ double x; // X coordinate of center of mass
+ double y; // Y coordinate of center of mass
+};
+
+/**
+@short Stores a position and orientation
+@author David Saxton
+*/
+class PositionInfo
+{
+public:
+ PositionInfo();
+ /**
+ * Adds together two positions: for this=PARENT +(CHILD), the new position
+ * is formed by translating this position by that of the CHILDs
+ * translation, and then rotating everything about the center of this item
+ */
+ const PositionInfo operator+( const PositionInfo &info );
+ /**
+ * Not quite the inverse of operator+. Subtracts the given position info
+ * as if it was applied before this current info.
+ */
+ const PositionInfo operator-( const PositionInfo &info );
+ /**
+ * x position (0 is left)
+ */
+ double x() const { return m_x; }
+ /**
+ * y position (0 is top)
+ */
+ double y() const { return m_y; }
+ /**
+ * Angle in radians, positive direction is anticlockwise
+ */
+ double angle() const { return m_angle; }
+ /**
+ * Sets the x-position
+ */
+ void setX( double x ) { m_x = x; }
+ /**
+ * Sets the y-position
+ */
+ void setY( double y ) { m_y = y; }
+ /**
+ * Sets the angle
+ */
+ void setAngle( double angle ) { m_angle = angle; }
+ /**
+ * Adds (x,y) to the current position
+ */
+ void translate( double dx, const double dy ) { m_x += dx; m_y += dy; }
+ /**
+ * Rotates anticlockwise by the given amount (in radians)
+ */
+ void rotate( double angle ) { m_angle += angle; }
+ /**
+ * Resets the position to (0,0), and the orientation to 0
+ */
+ void reset();
+ /**
+ * Rotates the current position about the given point through the given
+ * angle in radians anticlockwise. This will change the position and
+ * orientation.
+ */
+ void rotateAboutPoint( double x, double y, double angle );
+
+protected:
+ double m_x;
+ double m_y;
+ double m_angle;
+};
+
+
+/**
+@author David Saxton
+*/
+class MechanicsItem : public Item
+{
+Q_OBJECT
+public:
+ MechanicsItem( MechanicsDocument *mechanicsDocument, bool newItem, const QString &id );
+ virtual ~MechanicsItem();
+
+ enum SelectionMode
+ {
+ sm_move,
+ sm_resize,
+ sm_rotate
+ };
+ /**
+ * Returns the run-time identifier for the MechanicsItem
+ */
+ int rtti() const;
+ /**
+ * Sets the selection mode (sm_resize or sm_rotate). Note that setSelected
+ * also needs to be called to select the item.
+ */
+ void setSelectionMode( SelectionMode sm );
+ virtual void setSelected( bool yes );
+ /**
+ * @returns the selection mode
+ */
+ SelectionMode selectionMode() const { return m_selectionMode; }
+ /**
+ * Move the MechanicsItem by the given amount
+ */
+ virtual void moveBy( double dx, double dy );
+ /**
+ * Returns the absolute position on the canvas
+ */
+ PositionInfo absolutePosition() const;
+ /**
+ * Returns the position relative to the parent item (or the absolute
+ * position if there is no parent item)
+ */
+ PositionInfo relativePosition() const { return m_relativePosition; }
+ /**
+ * Returns the mechanics info for this item (so not taking into account that
+ * of attached children)
+ */
+ MechanicsInfo *mechanicsInfo() { return &m_mechanicsInfo; }
+ /**
+ * Returns the combined mechanics info for this item (which takes into
+ * account that of attached children).
+ */
+ CombinedMechanicsInfo *mechanicsInfoCombined() { return &m_mechanicsInfoCombined; }
+ /**
+ * Returns the rectangle that can legitimately fit inside the given bounding
+ * rectangle, given this items current rotation. Legitimately means that
+ * whether this item is allowed to be distorted, inverted, resized, etc.
+ */
+ QRect maxInnerRectangle( const QRect &outerRect ) const;
+
+ virtual ItemData itemData() const;
+
+ virtual bool mousePressEvent( const EventInfo &eventInfo );
+ virtual bool mouseReleaseEvent( const EventInfo &eventInfo );
+ virtual bool mouseDoubleClickEvent ( const EventInfo &eventInfo );
+ virtual bool mouseMoveEvent( const EventInfo &eventInfo );
+ virtual bool wheelEvent( const EventInfo &eventInfo );
+ virtual void enterEvent();
+ virtual void leaveEvent();
+
+public slots:
+ /**
+ * Rotate the item by the given amount (in radians)
+ */
+ void rotateBy( double dtheta );
+ void parentMoved();
+
+signals:
+ /**
+ * Emitted when this item moves (translates or rotates)
+ */
+ void moved();
+
+protected slots:
+ /**
+ * Recalculate the combined mechanics info (e.g. when mass is changed, or child added)
+ */
+ void updateMechanicsInfoCombined();
+
+protected:
+ virtual void reparented( Item *oldItem, Item *newItem );
+ virtual void childAdded( Item *child );
+ virtual void childRemoved( Item *child );
+ /**
+ * Called when this item is resized, so that sub classes can do whatever
+ */
+ virtual void itemResized() {};
+ /**
+ * Sets the correct orientation on the painter
+ */
+ void initPainter( QPainter &p );
+ /**
+ * *Must* be called after calling initPainter, if initPainter was called
+ */
+ void deinitPainter( QPainter &p );
+ virtual void dataChanged();
+ virtual void itemPointsChanged() { updateCanvasPoints(); }
+ /**
+ * Calculates the setPoints required from the current m_itemPoints and the
+ * current position / angle
+ */
+ void updateCanvasPoints();
+
+ MechanicsDocument *p_mechanicsDocument;
+ PositionInfo m_relativePosition; // Absolution position if not attached to a parent item, or otherwise relative to parent item
+ MechanicsInfo m_mechanicsInfo;
+ CombinedMechanicsInfo m_mechanicsInfoCombined;
+
+private:
+ SelectionMode m_selectionMode;
+};
+
+#endif