1 /* 2 * Copyright 2012, 2013 Thomas Schöps 3 * Copyright 2012-2019 Kai Pastor 4 * 5 * This file is part of OpenOrienteering. 6 * 7 * OpenOrienteering is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * OpenOrienteering is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 22 #ifndef OPENORIENTEERING_POINT_SYMBOL_H 23 #define OPENORIENTEERING_POINT_SYMBOL_H 24 25 #include <memory> 26 #include <vector> 27 28 #include <Qt> 29 #include <QtGlobal> 30 31 #include "symbol.h" 32 33 // IWYU pragma: no_include "core/objects/object.h" 34 35 class QPainterPath; 36 class QXmlStreamReader; 37 class QXmlStreamWriter; 38 39 namespace OpenOrienteering { 40 41 class Map; 42 class MapColor; 43 class MapColorMap; 44 class MapCoordF; 45 class ObjectRenderables; 46 class SymbolPropertiesWidget; 47 class SymbolSettingDialog; 48 class VirtualCoordVector; 49 50 51 /** 52 * Symbol for PointObjects. 53 * 54 * Apart from its own settings which are presented to the user as "[Midpoint 55 * symbol]" in the point symbol editor, this class can contain a list of 56 * elements together with a symbol for each element. All elements and the 57 * PointObject's own settings make up the appearance of the point symbol. 58 * The reason the own settings are left in is just efficiency, as for some 59 * symbols like crop land, a really huge number of point objects may be generated. 60 */ 61 class PointSymbol : public Symbol 62 { 63 friend class PointSymbolSettings; 64 friend class PointSymbolEditorWidget; 65 friend class OCAD8FileImport; 66 friend class XMLImportExport; 67 public: 68 /** Constructs an empty point symbol. */ 69 PointSymbol() noexcept; 70 ~PointSymbol() override; 71 72 protected: 73 explicit PointSymbol(const PointSymbol& proto); 74 PointSymbol* duplicate() const override; 75 76 public: 77 bool validate() const override; 78 79 void createRenderables( 80 const Object *object, 81 const VirtualCoordVector &coords, 82 ObjectRenderables &output, 83 RenderableOptions options ) const override; 84 85 void createRenderablesScaled(const MapCoordF& coord, qreal rotation, ObjectRenderables& output, qreal coord_scale = 1) const; 86 87 void createRenderablesIfCenterInside(const MapCoordF& point_coord, qreal rotation, const QPainterPath* outline, ObjectRenderables& output) const; 88 void createPrimitivesIfCompletelyInside(const MapCoordF& point_coord, const QPainterPath* outline, ObjectRenderables& output) const; 89 void createRenderablesIfCompletelyInside(const MapCoordF& point_coord, qreal rotation, const QPainterPath* outline, ObjectRenderables& output) const; 90 void createPrimitivesIfPartiallyInside(const MapCoordF& point_coord, const QPainterPath* outline, ObjectRenderables& output) const; 91 void createRenderablesIfPartiallyInside(const MapCoordF& point_coord, qreal rotation, const QPainterPath* outline, ObjectRenderables& output) const; 92 93 void colorDeletedEvent(const MapColor* color) override; 94 bool containsColor(const MapColor* color) const override; 95 const MapColor* guessDominantColor() const override; 96 void replaceColors(const MapColorMap& color_map) override; 97 void scale(double factor) override; 98 99 qreal dimensionForIcon() const override; 100 101 // Contained objects and symbols (elements) 102 103 /** Returns the number of contained elements. */ 104 int getNumElements() const; 105 /** Adds a new element consisting of object and symbol at the given index. */ 106 void addElement(int pos, Object* object, Symbol* symbol); 107 /** Returns the object of the i-th element. */ 108 Object* getElementObject(int pos); 109 /** Returns the object of the i-th element. */ 110 const Object* getElementObject(int pos) const; 111 /** Returns the symbol of the i-th element. */ 112 Symbol* getElementSymbol(int pos); 113 /** Returns the symbol of the i-th element. */ 114 const Symbol* getElementSymbol(int pos) const; 115 /** Deletes the i-th element. */ 116 void deleteElement(int pos); 117 118 /** 119 * Returns true if the point contains no elements and does not create 120 * renderables itself. Useful to check if it can be deleted. 121 */ 122 bool isEmpty() const; 123 124 /** 125 * Checks if the contained elements are rotationally symmetrical around 126 * the origin (this means, only point elements at (0,0) are allowed). 127 */ 128 bool isSymmetrical() const; 129 130 // Getters / Setters 131 using Symbol::setRotatable; /* public visibility */ getInnerRadius()132 inline int getInnerRadius() const {return inner_radius;} setInnerRadius(int value)133 inline void setInnerRadius(int value) {inner_radius = value;} getInnerColor()134 inline const MapColor* getInnerColor() const {return inner_color;} setInnerColor(const MapColor * color)135 inline void setInnerColor(const MapColor* color) {inner_color = color;} getOuterWidth()136 inline int getOuterWidth() const {return outer_width;} setOuterWidth(int value)137 inline void setOuterWidth(int value) {outer_width = value;} getOuterColor()138 inline const MapColor* getOuterColor() const {return outer_color;} setOuterColor(const MapColor * color)139 inline void setOuterColor(const MapColor* color) {outer_color = color;} 140 141 SymbolPropertiesWidget* createPropertiesWidget(SymbolSettingDialog* dialog) override; 142 143 144 protected: 145 void saveImpl(QXmlStreamWriter& xml, const Map& map) const override; 146 bool loadImpl(QXmlStreamReader& xml, const Map& map, SymbolDictionary& symbol_dict, int version) override; 147 bool equalsImpl(const Symbol* other, Qt::CaseSensitivity case_sensitivity) const override; 148 149 150 /// \todo Expose elements more directly in PointSymbol API. 151 struct Element 152 { 153 std::unique_ptr<Symbol> symbol; 154 std::unique_ptr<Object> object; 155 }; 156 std::vector<Element> elements; 157 158 const MapColor* inner_color; 159 const MapColor* outer_color; 160 int inner_radius; // in 1/1000 mm 161 int outer_width; // in 1/1000 mm 162 }; 163 164 165 } // namespace OpenOrienteering 166 167 #endif 168