File indexing completed on 2024-11-10 11:08:02
0001 /*************************************************************************** 0002 * Copyright (C) 2004-2006 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #ifndef ITEM_H 0012 #define ITEM_H 0013 0014 #include "itemdocument.h" 0015 #include "variant.h" 0016 0017 //#include <canvas.h> // 2018.10.16 - not needed 0018 #include "canvasitems.h" 0019 #include <QPointer> 0020 0021 class Document; 0022 class EventInfo; 0023 class Item; 0024 class ItemData; 0025 class ItemDocument; 0026 class ItemView; 0027 class DoubleSpinBox; 0028 class Document; 0029 class Variant; 0030 class QBitArray; 0031 class QTimer; 0032 0033 typedef Variant Property; 0034 0035 typedef Item *(*createItemPtr)(ItemDocument *itemDocument, bool newItem, const char *id); 0036 typedef QPointer<Item> GuardedItem; 0037 typedef QMap<QString, Variant *> VariantDataMap; 0038 typedef QList<GuardedItem> ItemList; 0039 0040 /** 0041 @author David Saxton 0042 @author Daniel Clarke 0043 */ 0044 class Item : /* public QObject, */ public KtlQCanvasPolygon 0045 { 0046 Q_OBJECT 0047 public: 0048 Item(ItemDocument *itemDocument, bool newItem, const QString &id); 0049 ~Item() override; 0050 0051 /** 0052 * @return Pointer to the VariantMap used for internal data storage 0053 */ 0054 VariantDataMap *variantMap() 0055 { 0056 return &m_variantData; 0057 } 0058 0059 double dataDouble(const QString &id) const; 0060 int dataInt(const QString &id) const; 0061 bool dataBool(const QString &id) const; 0062 QString dataString(const QString &id) const; 0063 QColor dataColor(const QString &id) const; 0064 0065 virtual Property *createProperty(const QString &id, Variant::Type::Value type); 0066 Property *property(const QString &id) const; 0067 bool hasProperty(const QString &id) const; 0068 0069 /** 0070 * Whether or not we can resize the item 0071 */ 0072 virtual bool canResize() const 0073 { 0074 return false; 0075 } 0076 /** 0077 * Returns whether the CNItem allows itself to be moved on the canvas. 0078 * Most do, but some (such as the PicItem) don't allow this 0079 */ 0080 virtual bool isMovable() const 0081 { 0082 return true; 0083 } 0084 /** 0085 * Returns whether or not what the item is displaying has (possibly) changed 0086 * since this function was last called. If your item doesn't move, yet still 0087 * continously changes what is being displayed (such as a seven segment 0088 * display or a lamp), then set m_bDynamicContent to be true in the 0089 * constructor or reinherit this to return true when the contents of the 0090 * item have changed since this function was last called. 0091 */ 0092 virtual bool contentChanged() const 0093 { 0094 return m_bDynamicContent; 0095 } 0096 /** 0097 * Returns a identifier for the CNItem, which is unique on the ICNDocument 0098 */ 0099 QString id() const 0100 { 0101 return m_id; 0102 } 0103 QString type() const 0104 { 0105 return m_type; 0106 } 0107 /** 0108 * @return the font used for drawing items. This is taken to be the 0109 * standard desktop font, limited to a size of 12 pixels. 0110 */ 0111 QFont font() const; 0112 /** 0113 * Called from ItemLibrary after this class and subclasses have finished 0114 * constructing themselves. 0115 */ 0116 virtual void finishedCreation(); 0117 /** 0118 * Sets the selected flag of the item to yes. selected or unselected will be 0119 * emitted as appropriate 0120 */ 0121 void setSelected(bool yes) override; 0122 /** 0123 * Convenience function for setting the item bounding area as changed on the 0124 * canvas 0125 */ 0126 void setChanged(); 0127 /** 0128 * Sets this item as a child of the given item. Calls reparented with the 0129 * old and the new parent. 0130 */ 0131 void setParentItem(Item *parentItem); 0132 /** 0133 * The parent item for this item, or nullptr if none 0134 */ 0135 Item *parentItem() const 0136 { 0137 return p_parentItem; 0138 } 0139 ItemDocument *itemDocument() const 0140 { 0141 return p_itemDocument; 0142 } 0143 /** 0144 * Returns the number of items away from the top item this is 0145 * (parent-wise). Returns 0 if has no parent. 0146 */ 0147 int level() const; 0148 /** 0149 * If true, then adds ItemDocument::Z::(RaisedItem-Item) to the z value of 0150 * the item. 0151 */ 0152 void setRaised(bool isRaised); 0153 /** 0154 * @Returns whether raised or not 0155 */ 0156 bool isRaised() const 0157 { 0158 return m_bIsRaised; 0159 } 0160 /** 0161 * Sets this item to the given baseZ level, and calls this function for the 0162 * children with baseZ incremented by one. Reinherit this function to set 0163 * the Z of attached stuff (such as nodes). 0164 */ 0165 virtual void updateZ(int baseZ); 0166 /** 0167 * Returns the item's position in the overall z-stack of items. 0168 */ 0169 int baseZ() const 0170 { 0171 return m_baseZ; 0172 } 0173 /** 0174 * Adds a child. Calls the virtual function childAdded. 0175 */ 0176 void addChild(Item *child); 0177 /** 0178 * Returns the list of children. 0179 * @param includeGrandChildren if includeGrandChildren is true then this list will also contain 0180 * the children's children, and so on recursively, instead of just the 0181 * immediate children. 0182 */ 0183 ItemList children(bool includeGrandChildren = false) const; 0184 /** 0185 * Returns whether we have the given child as either a direct child, or as 0186 * either a direct or indirect child 0187 */ 0188 bool contains(Item *item, bool direct = false) const; 0189 /** 0190 * Calls prePresize with the bounds, and if that returns true, sets 0191 * m_sizeRect to the given rect, and then calls postResize. The center of 0192 * \p sizeRect is taken as the point of rotation. 0193 * @param forceItemPoints if true, will set the item points to a rectangle 0194 * @of the given size. Pass true if you have already set the size, and want 0195 * to update the appearance and bounding of the item. 0196 */ 0197 void setSize(QRect sizeRect, bool forceItemPoints = false); 0198 /** 0199 * Convenience function. 0200 * @see setSize( QRect sizeRect, bool forceItemPoints ); 0201 */ 0202 void setSize(int x, int y, int w, int h, bool forceItemPoints = false) 0203 { 0204 setSize(QRect(x, y, w, h), forceItemPoints); 0205 } 0206 /** 0207 * @returns the m_sizeRect rectangble that contains the item points 0208 */ 0209 QRect sizeRect() const 0210 { 0211 return m_sizeRect; 0212 } 0213 /** 0214 * Reinherit this function if you want to determine what the minimum size is 0215 * that this item can be resized to. 0216 */ 0217 virtual QSize minimumSize() const 0218 { 0219 return QSize(0, 0); 0220 } 0221 int offsetX() const 0222 { 0223 return m_sizeRect.x(); 0224 } 0225 int offsetY() const 0226 { 0227 return m_sizeRect.y(); 0228 } 0229 int width() const 0230 { 0231 return m_sizeRect.width(); 0232 } 0233 int height() const 0234 { 0235 return m_sizeRect.height(); 0236 } 0237 virtual bool mousePressEvent(const EventInfo &eventInfo); 0238 virtual bool mouseReleaseEvent(const EventInfo &eventInfo); 0239 virtual bool mouseDoubleClickEvent(const EventInfo &eventInfo); 0240 virtual bool mouseMoveEvent(const EventInfo &eventInfo); 0241 virtual bool wheelEvent(const EventInfo &eventInfo); 0242 virtual void enterEvent(QEvent *); 0243 virtual void leaveEvent(QEvent *); 0244 /** 0245 * Returns the name of the CNItem, e.g. "Resistor" 0246 */ 0247 QString name() const 0248 { 0249 return m_name; 0250 } 0251 /** 0252 * Modifies the exponent of the number so that it appears readable: 0253 * eg 10000->10, 174822->175, 0.6->600, etc 0254 */ 0255 static int getNumberPre(double num); 0256 /** 0257 * Returns the SI exponent of the number as a letter: 0258 * eg 10000 returns 'k', 0.6 returns 'm', etc 0259 */ 0260 static QString getNumberMag(double num); 0261 /** 0262 * Returns the multiplier required to get the num up to human readable form: 0263 * eg 10000 returns 0.001, etc 0264 */ 0265 static double getMultiplier(double num); 0266 /** 0267 * Returns the multiplier required to get the num from human readable form 0268 * to its actual value based on the SI exponent: 0269 * eg 'm' returns 0.001, etc 0270 */ 0271 static double getMultiplier(const QString &mag); 0272 0273 virtual ItemData itemData() const; 0274 virtual void restoreFromItemData(const ItemData &itemData); 0275 0276 public slots: 0277 virtual void removeItem(); 0278 /** 0279 * Moves item - use this instead of moveBy() so that associated Nodes also get moved 0280 */ 0281 void moveBy(double dx, double dy) override; 0282 /** 0283 * Removes a child. Calls the virtual function childRemoved 0284 */ 0285 void removeChild(Item *child); 0286 0287 signals: 0288 /** 0289 * Emitted when the CNItem is removed. Normally, this signal is caught by associated 0290 * nodes, who will remove themselves as well. 0291 */ 0292 void removed(Item *item); 0293 /** 0294 * Emitted when the item is selected or unselected. 0295 */ 0296 void selectionChanged(); 0297 /** 0298 * Emitted when the item is resized (after calling postResize) 0299 */ 0300 void resized(); 0301 /** 0302 * Emitted when the item is moved (by dx, dy). 0303 */ 0304 void movedBy(double dx, double dy); 0305 0306 protected slots: 0307 virtual void propertyChangedInitial(); 0308 virtual void dataChanged() {}; 0309 0310 protected: 0311 /** 0312 * Reinherit this function if you want to do anything with children. Called 0313 * after the parent is changed, with the old parent and the new parent. 0314 */ 0315 virtual void reparented(Item * /*oldParent*/, Item * /*newParent*/) {}; 0316 /** 0317 * Reinherit this function if you want to do anything with children. Called 0318 * after a child has been added. 0319 */ 0320 virtual void childAdded(Item *) {}; 0321 /** 0322 * Reinherit this function if you want to do anything with children. Called 0323 * after a child has been removed. 0324 */ 0325 virtual void childRemoved(Item *) {}; 0326 /** 0327 * Set the rough bounding points for this item. Calls itemPointsChanged 0328 * after setting the points 0329 */ 0330 void setItemPoints(const QPolygon &pa, bool setSizeFromPoints = true); 0331 /** 0332 * Reinherit this function if you want to apply any sort of transformation 0333 * to the item points 0334 */ 0335 virtual void itemPointsChanged(); 0336 virtual bool preResize(QRect sizeRect) 0337 { 0338 Q_UNUSED(sizeRect); 0339 return true; 0340 } 0341 virtual void postResize() {}; 0342 0343 QString m_id; 0344 QString m_name; ///< Name (e.g. "Resistor") 0345 QString m_type; 0346 GuardedItem p_parentItem; // If attached to a parent item 0347 ItemList m_children; 0348 QPointer<ItemDocument> p_itemDocument; 0349 QPolygon m_itemPoints; // The unorientated and unsized item points 0350 QTimer *m_pPropertyChangedTimer; ///< Single show timer for one a property changes 0351 0352 friend class ItemLibrary; 0353 0354 int m_baseZ; 0355 bool m_bIsRaised; 0356 bool m_bDoneCreation; 0357 bool b_deleted; 0358 bool m_bDynamicContent; 0359 QRect m_sizeRect; 0360 VariantDataMap m_variantData; 0361 }; 0362 0363 #endif