1 /*************************************************************************** 2 * Copyright (C) 2005 by David Saxton * 3 * david@bluehaze.org * 4 * * 5 * This program is free software; you can redistribute it and/or modify * 6 * it under the terms of the GNU General Public License as published by * 7 * the Free Software Foundation; either version 2 of the License, or * 8 * (at your option) any later version. * 9 ***************************************************************************/ 10 11 #ifndef RESIZEOVERLAY_H 12 #define RESIZEOVERLAY_H 13 14 // This file contains class definitions for different types of resizing and rotating 15 16 //#include <canvas.h> // 2018.10.16 - not needed 17 #include "canvasitems.h" 18 #include <QPointer> 19 #include <QMap> 20 #include <QObject> 21 #include <QList> 22 23 class MechanicsItem; 24 class ResizeHandle; 25 class ResizeOverlay; 26 class QEvent; 27 28 typedef QMap< int, QPointer<ResizeHandle> > ResizeHandleMap; 29 30 /** 31 @author David Saxton 32 */ 33 class ResizeHandle : /* public QObject, */ public KtlQCanvasRectangle 34 { 35 Q_OBJECT 36 public: 37 /** 38 * Convenience enumeration for resize handle positioning. Note: this class 39 * does not make use of the values in this enumeration - it is just 40 * provided here for use by other classes. 41 */ 42 enum ResizeHandlePosition 43 { 44 rhp_none, 45 rhp_topLeft, 46 rhp_topMiddle, 47 rhp_topRight, 48 rhp_middleRight, 49 rhp_bottomRight, 50 rhp_bottomMiddle, 51 rhp_bottomLeft, 52 rhp_middleLeft, 53 rhp_center, 54 rhp_start, 55 rhp_end 56 }; 57 58 enum DrawType 59 { 60 // Draws a simple rectangle 61 dt_point_rect, 62 63 // Crosshair 64 dt_point_crosshair, 65 66 // Straight arrows in various directions 67 dt_resize_forwardsDiagonal, 68 dt_resize_backwardsDiagonal, 69 dt_resize_vertical, 70 dt_resize_horizontal, 71 72 // Arrows as part of an arc 73 dt_rotate_topLeft, 74 dt_rotate_topRight, 75 dt_rotate_bottomRight, 76 dt_rotate_bottomLeft 77 }; 78 79 ResizeHandle( ResizeOverlay *resizeOverlay, int id, DrawType drawType, int xsnap, int ysnap ); 80 ~ResizeHandle() override; 81 id()82 int id() const { return m_id; } 83 84 void setDrawType( DrawType drawType ); 85 void moveRH( double x, double y ); 86 void setHover( bool hover ); 87 88 static const QPixmap& handlePixmap( DrawType drawType, bool hover ); 89 90 QPolygon areaPoints () const override; 91 92 public slots: slotMoveByX(double dx)93 void slotMoveByX( double dx ) { moveBy( dx, 0 ); } slotMoveByY(double dy)94 void slotMoveByY( double dy ) { moveBy( 0, dy ); } 95 96 signals: 97 void rhMovedBy( int id, double dx, double dy ); 98 void rhMovedByX( double dx ); 99 void rhMovedByY( double dy ); 100 101 protected: 102 void drawShape( QPainter &p ) override; 103 104 DrawType m_drawType; 105 bool b_hover; // If true, then paint resize handle for mouse hovering over 106 int m_id; 107 int m_xsnap; 108 int m_ysnap; 109 ResizeOverlay *p_resizeOverlay; 110 111 }; 112 typedef QList<ResizeHandle*> ResizeHandleList; 113 114 /** 115 @author David Saxton 116 */ 117 class ResizeOverlay : public QObject 118 { 119 Q_OBJECT 120 public: 121 ResizeOverlay( Item *parent ); 122 ~ResizeOverlay() override; 123 124 parentItem()125 Item *parentItem() const { return p_item; } 126 127 /** 128 * Shows / hides the resize handles. They are hidden by default. 129 */ 130 void showResizeHandles( bool show ); 131 /** 132 * Sets the visibility. Visibility is true by default. 133 */ 134 void setVisible( bool visible ); 135 /** 136 * Reinherit this function to determine whether the X coordinate of the spot 137 * that the resize handle has moved into is valid or not 138 */ isValidXPos(ResizeHandle * rh)139 virtual bool isValidXPos( ResizeHandle *rh ) { Q_UNUSED(rh); return true; } 140 /** 141 * Reinherit this function to determine whether the Y coordinate of the spot 142 * that the resize handle has moved into is valid or not 143 */ isValidYPos(ResizeHandle * rh)144 virtual bool isValidYPos( ResizeHandle *rh ) { Q_UNUSED(rh); return true; } 145 146 public slots: 147 void slotMoveAllResizeHandles( double dx, double dy ); 148 149 protected slots: 150 virtual void slotResizeHandleMoved( int id, double dx, double dy ) = 0; 151 152 protected: 153 /** 154 * Connects up the given resize handles so that they are always kept at the 155 * same horizontal coordinate 156 */ 157 void syncX( ResizeHandle *rh1, ResizeHandle *rh2 ); 158 void syncX( ResizeHandle *rh1, ResizeHandle *rh2, ResizeHandle *rh3 ); 159 /** 160 * Connects up the given resize handles so that they are always kept at the 161 * same vertical coordinate 162 */ 163 void syncY( ResizeHandle *rh1, ResizeHandle *rh2 ); 164 void syncY( ResizeHandle *rh1, ResizeHandle *rh2, ResizeHandle *rh3 ); 165 /** 166 * Returns a pointer to the ResizeHandle with the given id, or 0 if no such 167 * handle exists 168 */ 169 ResizeHandle *resizeHandle( int id ); 170 /** 171 * Creates and attaches the resize handle with the given DrawType. If a 172 * ResizeHandle with the given id exists, will return a pointer to that 173 * instead 174 */ 175 ResizeHandle *createResizeHandle( int id, ResizeHandle::DrawType drawType, int xsnap = 1, int ysnap = 1 ); 176 /** 177 * Removes the resize handle with the given id 178 */ 179 void removeResizeHandle( int id ); 180 181 Item *p_item; 182 ResizeHandleMap m_resizeHandleMap; 183 bool b_showResizeHandles; 184 bool b_visible; 185 }; 186 187 188 /** 189 @author David Saxton 190 */ 191 class MechanicsItemOverlay : public ResizeOverlay 192 { 193 Q_OBJECT 194 public: 195 MechanicsItemOverlay( MechanicsItem *parent ); 196 ~MechanicsItemOverlay() override; 197 198 199 public slots: 200 void slotUpdateResizeHandles(); 201 202 protected slots: 203 void slotResizeHandleMoved( int id, double dx, double dy ) override; 204 205 protected: 206 ResizeHandle *m_tl; 207 ResizeHandle *m_tm; 208 ResizeHandle *m_tr; 209 ResizeHandle *m_mr; 210 ResizeHandle *m_br; 211 ResizeHandle *m_bm; 212 ResizeHandle *m_bl; 213 ResizeHandle *m_ml; 214 ResizeHandle *m_mm; 215 MechanicsItem *p_mechanicsItem; 216 }; 217 218 219 /** 220 @author David Saxton 221 */ 222 class RectangularOverlay : public ResizeOverlay 223 { 224 Q_OBJECT 225 public: 226 RectangularOverlay( Item *item, int xsnap = 1, int ysnap = 1 ); 227 void removeTopMiddle(); 228 void removeBotMiddle(); 229 /** 230 * Get the size rectangle from the position of the handles. If the size 231 * is invalid (e.g. the parent Item does not consider it a valid size, 232 * then *ok is set to false; otherwise to true. 233 * @returns the sizerect, regardless of whether or not it is valid 234 */ 235 QRect getSizeRect( bool *ok = nullptr, bool *widthOk = nullptr, bool *heightOk = nullptr ) const; 236 237 bool isValidXPos( ResizeHandle *rh ) override; 238 bool isValidYPos( ResizeHandle *rh ) override; 239 240 public slots: 241 void slotUpdateResizeHandles(); 242 243 protected slots: 244 void slotResizeHandleMoved( int id, double dx, double dy ) override; 245 246 247 protected: 248 ResizeHandle *m_tl; 249 ResizeHandle *m_tm; 250 ResizeHandle *m_tr; 251 ResizeHandle *m_mr; 252 ResizeHandle *m_br; 253 ResizeHandle *m_bm; 254 ResizeHandle *m_bl; 255 ResizeHandle *m_ml; 256 }; 257 258 259 /** 260 @author David Saxton 261 */ 262 class LineOverlay : public ResizeOverlay 263 { 264 Q_OBJECT 265 public: 266 LineOverlay( Item * parent ); 267 QPoint startPoint() const; 268 QPoint endPoint() const; 269 270 public slots: 271 void slotUpdateResizeHandles(); 272 273 protected slots: 274 void slotResizeHandleMoved( int id, double dx, double dy ) override; 275 276 277 protected: 278 ResizeHandle * m_pStart; 279 ResizeHandle * m_pEnd; 280 }; 281 282 #endif 283