1 /*
2     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef KOSMINDOORMAP_SCENEGRAPHITEM_H
8 #define KOSMINDOORMAP_SCENEGRAPHITEM_H
9 
10 #include <KOSM/Element>
11 
12 #include <style/mapcsstypes.h>
13 
14 #include <QBrush>
15 #include <QColor>
16 #include <QFont>
17 #include <QIcon>
18 #include <QPainterPath>
19 #include <QPen>
20 #include <QPolygonF>
21 #include <QStaticText>
22 #include <QString>
23 
24 #include <memory>
25 
26 namespace KOSMIndoorMap {
27 
28 class SceneGraphItemPayload;
29 
30 /** Unit for geometry sizes. */
31 enum class Unit : uint8_t {
32     Pixel,
33     Meter,
34 };
35 
36 /** Scene graph item description and handle for its content.
37  *  This is a minimal and cheap part that can be used allocation-free,
38  *  and it holds the expensive polymorphic parts (geometry, materials) depending on the
39  *  type of this is item.
40  *  This split allows to use this part for searching/sorting/indexing.
41  */
42 class SceneGraphItem
43 {
44 public:
45     /** The OSM::Element this item refers to. */
46     OSM::Element element;
47 
48     int level = 0;
49     int layer = 0;
50 
51     LayerSelectorKey layerSelector;
52 
53     std::unique_ptr<SceneGraphItemPayload> payload;
54 };
55 
56 /** Payload base class for scene graph items. */
57 class SceneGraphItemPayload
58 {
59 public:
60     virtual ~SceneGraphItemPayload();
61 
62     /** See MapCSS spec: "Within a layer, first all fills are rendered, then all casings, then all strokes, then all icons and labels." .*/
63     enum RenderPhase : uint8_t {
64         NoPhase = 0,
65         FillPhase = 1,
66         CasingPhase = 2,
67         StrokePhase = 4,
68         LabelPhase = 8,
69     };
70     /** Returns in which phase this item needs to be rendered (can be multiple). */
71     virtual uint8_t renderPhases() const = 0;
72 
73     /** Bounding box of this item in scene coordinates.
74      *  Performance trumps precision here, so estimating this slightly larger rather than computing it expensively makes sense.
75      */
76     virtual QRectF boundingRect() const = 0;
77 
78     /** Is this item drawn in scene coordinates (as oposed to HUD coordinates)? */
79     bool inSceneSpace() const;
80     /** Is this item drawn in HUD coordinates (as oposed to scene coordinates)? */
81     bool inHUDSpace() const;
82 
83     int z = 0;
84 };
85 
86 
87 /** A path/way/line item in the scenegraph. */
88 class PolylineItem : public SceneGraphItemPayload
89 {
90 public:
91     uint8_t renderPhases() const override;
92     QRectF boundingRect() const override;
93 
94     QPolygonF path;
95     QPen pen;
96     QPen casingPen;
97     Unit penWidthUnit = Unit::Meter;
98     Unit casingPenWidthUnit = Unit::Pixel;
99 };
100 
101 
102 /** Base item for filled polygons. */
103 class PolygonBaseItem : public SceneGraphItemPayload
104 {
105 public:
106     uint8_t renderPhases() const override;
107 
108     QBrush brush = Qt::NoBrush;
109     QPen pen;
110     Unit penWidthUnit = Unit::Pixel;
111 };
112 
113 
114 /** A single filled polygon. */
115 class PolygonItem : public PolygonBaseItem
116 {
117 public:
118     QRectF boundingRect() const override;
119 
120     QPolygonF polygon;
121 };
122 
123 
124 /** Multi-polygon item, used for polygons with "holes" in them. */
125 class MultiPolygonItem : public PolygonBaseItem
126 {
127 public:
128     QRectF boundingRect() const override;
129 
130     QPainterPath path;
131 };
132 
133 /** A text or item label */
134 class LabelItem : public SceneGraphItemPayload
135 {
136 public:
137     uint8_t renderPhases() const override;
138     QRectF boundingRect() const override;
139 
140     QPointF pos;
141     QColor color;
142     QFont font;
143     QStaticText text;
144 
145     QIcon icon;
146     QSizeF iconSize;
147 
148     double casingWidth = 0.0;
149     QColor casingColor = Qt::transparent;
150     double frameWidth = 0.0;
151     QColor frameColor = Qt::transparent;
152     QColor shieldColor = Qt::transparent;
153 
154     double angle = 0.0;
155     double offset = 0.0;
156 
157     QColor haloColor = Qt::transparent;
158     double haloRadius = 0.0;
159 };
160 
161 
162 }
163 
164 #endif // KOSMINDOORMAP_SCENEGRAPHITEM_H
165