File indexing completed on 2024-12-08 08:10:46
0001 /*************************************************************************** 0002 * Copyright (C) 2005 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 RESIZEOVERLAY_H 0012 #define RESIZEOVERLAY_H 0013 0014 // This file contains class definitions for different types of resizing and rotating 0015 0016 //#include <canvas.h> // 2018.10.16 - not needed 0017 #include "canvasitems.h" 0018 #include "item.h" 0019 #include <QList> 0020 #include <QMap> 0021 #include <QObject> 0022 #include <QPointer> 0023 0024 class MechanicsItem; 0025 class ResizeHandle; 0026 class ResizeOverlay; 0027 class QEvent; 0028 0029 typedef QMap<int, QPointer<ResizeHandle>> ResizeHandleMap; 0030 0031 /** 0032 @author David Saxton 0033 */ 0034 class ResizeHandle : /* public QObject, */ public KtlQCanvasRectangle 0035 { 0036 Q_OBJECT 0037 public: 0038 /** 0039 * Convenience enumeration for resize handle positioning. Note: this class 0040 * does not make use of the values in this enumeration - it is just 0041 * provided here for use by other classes. 0042 */ 0043 enum ResizeHandlePosition { rhp_none, rhp_topLeft, rhp_topMiddle, rhp_topRight, rhp_middleRight, rhp_bottomRight, rhp_bottomMiddle, rhp_bottomLeft, rhp_middleLeft, rhp_center, rhp_start, rhp_end }; 0044 0045 enum DrawType { 0046 // Draws a simple rectangle 0047 dt_point_rect, 0048 0049 // Crosshair 0050 dt_point_crosshair, 0051 0052 // Straight arrows in various directions 0053 dt_resize_forwardsDiagonal, 0054 dt_resize_backwardsDiagonal, 0055 dt_resize_vertical, 0056 dt_resize_horizontal, 0057 0058 // Arrows as part of an arc 0059 dt_rotate_topLeft, 0060 dt_rotate_topRight, 0061 dt_rotate_bottomRight, 0062 dt_rotate_bottomLeft 0063 }; 0064 0065 ResizeHandle(ResizeOverlay *resizeOverlay, int id, DrawType drawType, int xsnap, int ysnap); 0066 ~ResizeHandle() override; 0067 0068 int id() const 0069 { 0070 return m_id; 0071 } 0072 0073 void setDrawType(DrawType drawType); 0074 void moveRH(double x, double y); 0075 void setHover(bool hover); 0076 0077 static const QPixmap &handlePixmap(DrawType drawType, bool hover); 0078 0079 QPolygon areaPoints() const override; 0080 0081 public slots: 0082 void slotMoveByX(double dx) 0083 { 0084 moveBy(dx, 0); 0085 } 0086 void slotMoveByY(double dy) 0087 { 0088 moveBy(0, dy); 0089 } 0090 0091 signals: 0092 void rhMovedBy(int id, double dx, double dy); 0093 void rhMovedByX(double dx); 0094 void rhMovedByY(double dy); 0095 0096 protected: 0097 void drawShape(QPainter &p) override; 0098 0099 DrawType m_drawType; 0100 bool b_hover; // If true, then paint resize handle for mouse hovering over 0101 int m_id; 0102 int m_xsnap; 0103 int m_ysnap; 0104 ResizeOverlay *p_resizeOverlay; 0105 }; 0106 typedef QList<ResizeHandle *> ResizeHandleList; 0107 0108 /** 0109 @author David Saxton 0110 */ 0111 class ResizeOverlay : public QObject 0112 { 0113 Q_OBJECT 0114 public: 0115 ResizeOverlay(Item *parent); 0116 ~ResizeOverlay() override; 0117 0118 Item *parentItem() const 0119 { 0120 return p_item; 0121 } 0122 0123 /** 0124 * Shows / hides the resize handles. They are hidden by default. 0125 */ 0126 void showResizeHandles(bool show); 0127 /** 0128 * Sets the visibility. Visibility is true by default. 0129 */ 0130 void setVisible(bool visible); 0131 /** 0132 * Reinherit this function to determine whether the X coordinate of the spot 0133 * that the resize handle has moved into is valid or not 0134 */ 0135 virtual bool isValidXPos(ResizeHandle *rh) 0136 { 0137 Q_UNUSED(rh); 0138 return true; 0139 } 0140 /** 0141 * Reinherit this function to determine whether the Y coordinate of the spot 0142 * that the resize handle has moved into is valid or not 0143 */ 0144 virtual bool isValidYPos(ResizeHandle *rh) 0145 { 0146 Q_UNUSED(rh); 0147 return true; 0148 } 0149 0150 public slots: 0151 void slotMoveAllResizeHandles(double dx, double dy); 0152 0153 protected slots: 0154 virtual void slotResizeHandleMoved(int id, double dx, double dy) = 0; 0155 0156 protected: 0157 /** 0158 * Connects up the given resize handles so that they are always kept at the 0159 * same horizontal coordinate 0160 */ 0161 void syncX(ResizeHandle *rh1, ResizeHandle *rh2); 0162 void syncX(ResizeHandle *rh1, ResizeHandle *rh2, ResizeHandle *rh3); 0163 /** 0164 * Connects up the given resize handles so that they are always kept at the 0165 * same vertical coordinate 0166 */ 0167 void syncY(ResizeHandle *rh1, ResizeHandle *rh2); 0168 void syncY(ResizeHandle *rh1, ResizeHandle *rh2, ResizeHandle *rh3); 0169 /** 0170 * Returns a pointer to the ResizeHandle with the given id, or 0 if no such 0171 * handle exists 0172 */ 0173 ResizeHandle *resizeHandle(int id); 0174 /** 0175 * Creates and attaches the resize handle with the given DrawType. If a 0176 * ResizeHandle with the given id exists, will return a pointer to that 0177 * instead 0178 */ 0179 ResizeHandle *createResizeHandle(int id, ResizeHandle::DrawType drawType, int xsnap = 1, int ysnap = 1); 0180 /** 0181 * Removes the resize handle with the given id 0182 */ 0183 void removeResizeHandle(int id); 0184 0185 Item *p_item; 0186 ResizeHandleMap m_resizeHandleMap; 0187 bool b_showResizeHandles; 0188 bool b_visible; 0189 }; 0190 0191 /** 0192 @author David Saxton 0193 */ 0194 class MechanicsItemOverlay : public ResizeOverlay 0195 { 0196 Q_OBJECT 0197 public: 0198 MechanicsItemOverlay(MechanicsItem *parent); 0199 ~MechanicsItemOverlay() override; 0200 0201 public slots: 0202 void slotUpdateResizeHandles(); 0203 0204 protected slots: 0205 void slotResizeHandleMoved(int id, double dx, double dy) override; 0206 0207 protected: 0208 ResizeHandle *m_tl; 0209 ResizeHandle *m_tm; 0210 ResizeHandle *m_tr; 0211 ResizeHandle *m_mr; 0212 ResizeHandle *m_br; 0213 ResizeHandle *m_bm; 0214 ResizeHandle *m_bl; 0215 ResizeHandle *m_ml; 0216 ResizeHandle *m_mm; 0217 MechanicsItem *p_mechanicsItem; 0218 }; 0219 0220 /** 0221 @author David Saxton 0222 */ 0223 class RectangularOverlay : public ResizeOverlay 0224 { 0225 Q_OBJECT 0226 public: 0227 RectangularOverlay(Item *item, int xsnap = 1, int ysnap = 1); 0228 void removeTopMiddle(); 0229 void removeBotMiddle(); 0230 /** 0231 * Get the size rectangle from the position of the handles. If the size 0232 * is invalid (e.g. the parent Item does not consider it a valid size, 0233 * then *ok is set to false; otherwise to true. 0234 * @returns the sizerect, regardless of whether or not it is valid 0235 */ 0236 QRect getSizeRect(bool *ok = nullptr, bool *widthOk = nullptr, bool *heightOk = nullptr) const; 0237 0238 bool isValidXPos(ResizeHandle *rh) override; 0239 bool isValidYPos(ResizeHandle *rh) override; 0240 0241 public slots: 0242 void slotUpdateResizeHandles(); 0243 0244 protected slots: 0245 void slotResizeHandleMoved(int id, double dx, double dy) override; 0246 0247 protected: 0248 ResizeHandle *m_tl; 0249 ResizeHandle *m_tm; 0250 ResizeHandle *m_tr; 0251 ResizeHandle *m_mr; 0252 ResizeHandle *m_br; 0253 ResizeHandle *m_bm; 0254 ResizeHandle *m_bl; 0255 ResizeHandle *m_ml; 0256 }; 0257 0258 /** 0259 @author David Saxton 0260 */ 0261 class LineOverlay : public ResizeOverlay 0262 { 0263 Q_OBJECT 0264 public: 0265 LineOverlay(Item *parent); 0266 QPoint startPoint() const; 0267 QPoint endPoint() const; 0268 0269 public slots: 0270 void slotUpdateResizeHandles(); 0271 0272 protected slots: 0273 void slotResizeHandleMoved(int id, double dx, double dy) override; 0274 0275 protected: 0276 ResizeHandle *m_pStart; 0277 ResizeHandle *m_pEnd; 0278 }; 0279 0280 #endif