1 /* 2 SPDX-FileCopyrightText: 2011 Rafał Kułaga <rl.kulaga@gmail.com> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #pragma once 8 9 #include <QFont> 10 #include <QPoint> 11 #include <QColor> 12 13 class QPaintDevice; 14 class QPointF; 15 class QSize; 16 17 class ColorScheme; 18 class SkyMap; 19 class SkyQPainter; 20 21 /** 22 * \class Legend 23 * \brief Legend class is used for painting legends on class inheriting QPaintDevice. 24 * Its methods enable changing settings of legend such as legend type (scale only/full legend), 25 * symbol size, sizes for symbol description's bounding rectangles, symbol spacing etc. 26 * Typical use of this class would be to create instance of Legend class, set all properties 27 * using appropriate methods and paint it by calling paintLegend() method, passing QPaintDevice 28 * or QPainter subclass (useful eg. with QSvgGenerator class, which can't be painted by two QPainter 29 * classes). 30 * \author Rafał Kułaga 31 */ 32 class Legend 33 { 34 public: 35 /** 36 * \brief Legend type enumeration. 37 */ 38 enum LEGEND_TYPE 39 { 40 LT_FULL, 41 LT_SCALE_MAGNITUDES, 42 LT_SCALE_ONLY, 43 LT_MAGNITUDES_ONLY, 44 LT_SYMBOLS_ONLY, 45 }; 46 47 /** 48 * \brief Legend orientation enumeration. 49 */ 50 enum LEGEND_ORIENTATION 51 { 52 LO_HORIZONTAL, 53 LO_VERTICAL 54 }; 55 56 /** 57 * \brief Legend position enumeration. 58 */ 59 enum LEGEND_POSITION 60 { 61 LP_UPPER_LEFT, 62 LP_UPPER_RIGHT, 63 LP_LOWER_LEFT, 64 LP_LOWER_RIGHT, 65 LP_FLOATING 66 }; 67 68 /** 69 * \brief Constructor. 70 * \param orientation Legend orientation. 71 * \param pos Legend position. 72 */ 73 explicit Legend(LEGEND_ORIENTATION orientation = LO_HORIZONTAL, LEGEND_POSITION pos = LP_FLOATING); 74 75 /** 76 * \brief copy constructor 77 * \note This class needs to be explicitly copied because of the m_Painter pointer 78 */ 79 /** @{ */ 80 explicit Legend(const Legend &o); 81 Legend& operator=(const Legend &o) noexcept; 82 /** @} */ 83 84 85 /** 86 * \brief Destructor. 87 */ 88 ~Legend(); 89 90 /** 91 * \brief Get legend type. 92 * \return Current legend type value. 93 */ getType()94 inline LEGEND_TYPE getType() const { return m_Type; } 95 96 /** 97 * \brief Get legend orientation. 98 * \return Current legend orientation value. 99 */ getOrientation()100 inline LEGEND_ORIENTATION getOrientation() const { return m_Orientation; } 101 102 /** 103 * \brief Get legend position. 104 * \return Current legend position value. 105 */ getPosition()106 inline LEGEND_POSITION getPosition() const { return m_Position; } 107 108 /** 109 * \brief Get position of the floating legend. 110 * \return Current position of the floating legend. 111 */ getFloatingPosition()112 inline QPoint getFloatingPosition() const { return m_PositionFloating; } 113 114 /** 115 * \brief Get symbol size. 116 * \return Current symbol size value. 117 */ getSymbolSize()118 inline int getSymbolSize() const { return m_SymbolSize; } 119 120 /** 121 * \brief Get symbol description's bounding rectangle width. 122 * \return Current bounding rectangle width. 123 */ getBRectWidth()124 inline int getBRectWidth() const { return m_BRectWidth; } 125 126 /** 127 * \brief Get symbol description's bounding rectangle height. 128 * \return Current bounding rectangle height. 129 */ getBRectHeight()130 inline int getBRectHeight() const { return m_BRectHeight; } 131 132 /** 133 * \brief Get maximal horizontal scale size in pixels. 134 * \return Current maximal horizontal scale size in pixels. 135 */ getMaxHScalePixels()136 inline int getMaxHScalePixels() const { return m_MaxHScalePixels; } 137 138 /** 139 * \brief Get maximal vertical scale size in pixels. 140 * \brief Current maximal vertical scale size in pixels. 141 */ getMaxVScalePixels()142 inline int getMaxVScalePixels() const { return m_MaxVScalePixels; } 143 144 /** 145 * \brief Get symbol image X spacing. 146 * \return Current symbol image X spacing. 147 */ getXSymbolSpacing()148 inline int getXSymbolSpacing() const { return m_XSymbolSpacing; } 149 150 /** 151 * \brief Get symbol image Y spacing. 152 * \return Current symbol image Y spacing. 153 */ getYSymbolSpacing()154 inline int getYSymbolSpacing() const { return m_YSymbolSpacing; } 155 156 /** 157 * \brief Get font. 158 * \return Current font. 159 */ getFont()160 inline QFont getFont() const { return m_Font; } 161 162 /** 163 * \brief Get background color. 164 * \return Current background color. 165 */ getBgColor()166 inline QColor getBgColor() const { return m_BgColor; } 167 168 /** 169 * \brief Check if frame around legend is drawn. 170 * \return True if frame is drawn. 171 */ getDrawFrame()172 inline bool getDrawFrame() const { return m_DrawFrame; } 173 174 /** 175 * \brief Set legend type. 176 * \param type New legend type. 177 */ setType(LEGEND_TYPE type)178 inline void setType(LEGEND_TYPE type) { m_Type = type; } 179 180 /** 181 * \brief Set legend orientation. 182 * \param orientation New legend orientation. 183 */ setOrientation(LEGEND_ORIENTATION orientation)184 inline void setOrientation(LEGEND_ORIENTATION orientation) { m_Orientation = orientation; } 185 186 /** 187 * \brief Set legend position. 188 * \param pos New legend position enumeration value. 189 */ setPosition(LEGEND_POSITION pos)190 inline void setPosition(LEGEND_POSITION pos) { m_Position = pos; } 191 192 /** 193 * \brief Set floating legend position. 194 * \param pos New floating legend position. 195 */ setFloatingPosition(QPoint pos)196 inline void setFloatingPosition(QPoint pos) { m_PositionFloating = pos; } 197 198 /** 199 * \brief Set symbol size. 200 * \param size New symbol size. 201 */ setSymbolSize(int size)202 inline void setSymbolSize(int size) { m_SymbolSize = size; } 203 204 /** 205 * \brief Set symbol description's bounding rectangle width. 206 * \param width New bounding rectangle width. 207 */ setBRectWidth(int width)208 inline void setBRectWidth(int width) { m_BRectWidth = width; } 209 210 /** 211 * \brief Set symbol description's bounding rectangle height. 212 * \param height New bounding rectangle height. 213 */ setBRectHeight(int height)214 inline void setBRectHeight(int height) { m_BRectHeight = height; } 215 216 /** 217 * \brief Set maximal horizontal scale size in pixels. 218 * \param pixels New maximal horizontal scale size in pixels. 219 */ setMaxHScalePixels(int pixels)220 inline void setMaxHScalePixels(int pixels) { m_MaxHScalePixels = pixels; } 221 222 /** 223 * \brief Set maximal vertical scale size in pixels. 224 * \param pixels New maximal vertical scale size in pixels. 225 */ setMaxVScalePixels(int pixels)226 inline void setMaxVScalePixels(int pixels) { m_MaxVScalePixels = pixels; } 227 228 /** 229 * \brief Set symbol X spacing in pixels. 230 * \param spacing New symbol X spacing in pixels. 231 */ setXSymbolSpacing(int spacing)232 inline void setXSymbolSpacing(int spacing) { m_XSymbolSpacing = spacing; } 233 234 /** 235 * \brief Set symbol Y spacing in pixels. 236 * \param spacing New symbol Y spacing in pixels. 237 */ setYSymbolSpacing(int spacing)238 inline void setYSymbolSpacing(int spacing) { m_YSymbolSpacing = spacing; } 239 240 /** 241 * \brief Set font. 242 * \param font New font. 243 */ setFont(const QFont & font)244 inline void setFont(const QFont &font) { m_Font = font; } 245 246 /** 247 * \brief Set background color. 248 * \param color New background color. 249 */ setBgColor(const QColor & color)250 inline void setBgColor(const QColor &color) { m_BgColor = color; } 251 252 /** 253 * \brief Set if frame is drawn. 254 * \param draw True if frame should be drawn. 255 */ setDrawFrame(bool draw)256 inline void setDrawFrame(bool draw) { m_DrawFrame = draw; } 257 258 /** 259 * \brief Calculates size of legend that will be painted using current settings. 260 * \return Size of legend. 261 */ 262 QSize calculateSize(); 263 264 /** 265 * \brief Paint legend on passed QPaintDevice at selected position. 266 * \param pd QPaintDevice on which legend will be painted. 267 */ 268 void paintLegend(QPaintDevice *pd); 269 270 /** 271 * \brief Paint legend using passed SkyQPainter. 272 * This method is used to enable painting on QPaintDevice subclasses that can't be 273 * painted by multiple QPainter subclasses (e.g. QSvgGenerator). 274 * \param painter that will be used to paint legend. 275 * \note Passed SkyQPainter should be already set up to paint at specific QPaintDevice 276 * subclass and should be initialized by its begin() method. After legend is painted, SkyQPainter 277 * instance _will not_ be finished, so it's necessary to call end() method manually. 278 */ 279 void paintLegend(SkyQPainter *painter); 280 281 /** 282 * \brief Paint legend on passed QPaintDevice at selected position. 283 * \param pd QPaintDevice on which legend will be painted. 284 * \param type the legend type. 285 * \param pos LEGEND_POSITION enum value. 286 */ 287 void paintLegend(QPaintDevice *pd, LEGEND_TYPE type, LEGEND_POSITION pos); 288 289 /** 290 * \brief Paint legend using passed SkyQPainter. 291 * This method is used to enable painting on QPaintDevice subclasses that can't be painted 292 * by multiple QPainter subclasses (eg. QSvgGenerator). 293 * \param painter that will be used to paint legend. 294 * \param type the legend type. 295 * \param pos LEGEND_POSITION enum value. 296 * \note Passed SkyQPainter should be already set up to paint at specific QPaintDevice 297 * subclass and should be initialized by its begin() method. After legend is painted, SkyQPainter 298 * instance _will not_ be finished, so it's necessary to call end() method manually. 299 */ 300 void paintLegend(SkyQPainter *painter, LEGEND_TYPE type, LEGEND_POSITION pos); 301 302 private: 303 /** 304 * \brief Paint all symbols at passed position. 305 * \param pos position at which symbols will be painted (upper left corner). 306 * \note Orientation of the symbols group is determined by current legend orientation. 307 */ 308 void paintSymbols(QPointF pos); 309 310 /** 311 * \brief Paint single symbol with specified parameters. 312 * \param pos position at which symbol will be painted (center). 313 * \param type symbol type (see SkyQPainter class for symbol types list). 314 * \param e e parameter of symbol. 315 * \param angle angle of symbol (in degrees). 316 * \param label symbol label. 317 */ 318 void paintSymbol(QPointF pos, int type, float e, float angle, QString label); 319 320 /** 321 * \brief Paint 'Star Magnitudes' group at passed position. 322 * \param pos position at which 'Star Magnitudes' group will be painted (upper left corner). 323 */ 324 void paintMagnitudes(QPointF pos); 325 326 /** 327 * \brief Paint chart scale bar at passed position. 328 * \param pos position at which chart scale bar will be painted. 329 * \note Orientation of chart scale bar is determined by current legend orientation. Maximal 330 * bar size is determined by current values set by setMaxHScalePixels()/setMaxVScalePixels() method. 331 * Exact size is adjusted to full deg/min/sec. 332 */ 333 void paintScale(QPointF pos); 334 335 /** 336 * \brief Calculates legend position (upper left corner) based on LEGEND_POSITION enum value, paint device size and calculated legend size. 337 * \param pos LEGEND_POSITION enum value. 338 */ 339 QPoint positionToDeviceCoord(QPaintDevice *pd); 340 341 SkyQPainter *m_Painter { nullptr }; 342 SkyMap *m_SkyMap { nullptr }; 343 bool m_DeletePainter { false }; 344 345 LEGEND_TYPE m_Type { LT_FULL }; 346 LEGEND_ORIENTATION m_Orientation; 347 LEGEND_POSITION m_Position; 348 QPoint m_PositionFloating; 349 350 ColorScheme *m_cScheme { nullptr }; 351 QFont m_Font; 352 QColor m_BgColor; 353 bool m_DrawFrame { false }; 354 355 int m_SymbolSize { 0 }; 356 int m_BRectWidth { 0 }; 357 int m_BRectHeight { 0 }; 358 int m_MaxHScalePixels { 0 }; 359 int m_MaxVScalePixels { 0 }; 360 int m_XSymbolSpacing { 0 }; 361 int m_YSymbolSpacing { 0 }; 362 }; 363