1 /****************************************************************************
2 **
3 ** Copyright (C) 2018 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtLocation module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL3$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or later as published by the Free
28 ** Software Foundation and appearing in the file LICENSE.GPL included in
29 ** the packaging of this file. Please review the following information to
30 ** ensure the GNU General Public License version 2.0 requirements will be
31 ** met: http://www.gnu.org/licenses/gpl-2.0.html.
32 **
33 ** $QT_END_LICENSE$
34 **
35 ****************************************************************************/
36
37 #include "qmapcircleobject_p.h"
38 #include "qmapcircleobject_p_p.h"
39 #include <QExplicitlySharedDataPointer>
40 #include <QtPositioning/qgeocircle.h>
41
42 QT_BEGIN_NAMESPACE
43
44 /*!
45 \qmltype MapCircleObject
46 \instantiates QMapCircleObject
47 \inqmlmodule Qt.labs.location
48 \ingroup qml-QtLocation5-maps
49 \inherits QGeoMapObject
50
51 \brief The MapCircleObject displays a circle on a Map.
52
53 The MapCircleObject displays a circle on a Map.
54 The MapIconObject type only makes sense when contained in a Map or in a \l MapObjectView.
55 */
56
QMapCircleObjectPrivate(QGeoMapObject * q)57 QMapCircleObjectPrivate::QMapCircleObjectPrivate(QGeoMapObject *q) : QGeoMapObjectPrivate(q)
58 {
59
60 }
61
~QMapCircleObjectPrivate()62 QMapCircleObjectPrivate::~QMapCircleObjectPrivate()
63 {
64
65 }
66
type() const67 QGeoMapObject::Type QMapCircleObjectPrivate::type() const
68 {
69 return QGeoMapObject::CircleType;
70 }
71
geoShape() const72 QGeoShape QMapCircleObjectPrivate::geoShape() const
73 {
74 return QGeoCircle(center(), radius());
75 }
76
setGeoShape(const QGeoShape & shape)77 void QMapCircleObjectPrivate::setGeoShape(const QGeoShape &shape)
78 {
79 if (shape == geoShape())
80 return;
81
82 const QGeoCircle circle(shape); // if shape isn't a circle, circle will be created as a default-constructed circle
83 const bool centerHasChanged = circle.center() != center();
84 const bool radiusHasChanged = circle.radius() != radius();
85
86 if (centerHasChanged)
87 setCenter(circle.center()); // to handle overrides
88 if (radiusHasChanged)
89 setRadius(circle.radius()); // to handle overrides
90
91 if (centerHasChanged)
92 emit static_cast<QMapCircleObject *>(q)->centerChanged();
93 if (radiusHasChanged)
94 emit static_cast<QMapCircleObject *>(q)->radiusChanged();
95 }
96
97 //
98 // QMapCircleObjectPrivate default implementation
99 //
100
QMapCircleObjectPrivateDefault(QGeoMapObject * q)101 QMapCircleObjectPrivateDefault::QMapCircleObjectPrivateDefault(QGeoMapObject *q) : QMapCircleObjectPrivate(q)
102 {
103
104 }
105
QMapCircleObjectPrivateDefault(const QMapCircleObjectPrivate & other)106 QMapCircleObjectPrivateDefault::QMapCircleObjectPrivateDefault(const QMapCircleObjectPrivate &other) : QMapCircleObjectPrivate(other.q)
107 {
108 m_center = other.center();
109 m_radius = other.radius();
110 m_fillColor = other.color();
111 m_borderColor = other.borderColor();
112 m_borderWidth = other.borderWidth();
113 }
114
~QMapCircleObjectPrivateDefault()115 QMapCircleObjectPrivateDefault::~QMapCircleObjectPrivateDefault()
116 {
117
118 }
119
center() const120 QGeoCoordinate QMapCircleObjectPrivateDefault::center() const
121 {
122 return m_center;
123 }
124
setCenter(const QGeoCoordinate & center)125 void QMapCircleObjectPrivateDefault::setCenter(const QGeoCoordinate ¢er)
126 {
127 m_center = center;
128 }
129
radius() const130 qreal QMapCircleObjectPrivateDefault::radius() const
131 {
132 return m_radius;
133 }
134
setRadius(qreal radius)135 void QMapCircleObjectPrivateDefault::setRadius(qreal radius)
136 {
137 m_radius = radius;
138 }
139
color() const140 QColor QMapCircleObjectPrivateDefault::color() const
141 {
142 return m_fillColor;
143 }
144
setColor(const QColor & color)145 void QMapCircleObjectPrivateDefault::setColor(const QColor &color)
146 {
147 m_fillColor = color;
148 }
149
borderColor() const150 QColor QMapCircleObjectPrivateDefault::borderColor() const
151 {
152 return m_borderColor;
153 }
154
setBorderColor(const QColor & color)155 void QMapCircleObjectPrivateDefault::setBorderColor(const QColor &color)
156 {
157 m_borderColor = color;
158 }
159
borderWidth() const160 qreal QMapCircleObjectPrivateDefault::borderWidth() const
161 {
162 return m_borderWidth;
163 }
164
setBorderWidth(qreal width)165 void QMapCircleObjectPrivateDefault::setBorderWidth(qreal width)
166 {
167 m_borderWidth = width;
168 }
169
equals(const QGeoMapObjectPrivate & other) const170 bool QMapCircleObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
171 {
172 if (other.type() != type()) // This check might be unnecessary, depending on how equals gets used
173 return false;
174
175 const QMapCircleObjectPrivate &o = static_cast<const QMapCircleObjectPrivate &>(other);
176 return (QGeoMapObjectPrivate::equals(o)
177 && center() == o.center()
178 && radius() == o.radius()
179 && color() == o.color()
180 && borderColor() == o.borderColor()
181 && borderWidth() == o.borderWidth());
182 }
183
clone()184 QGeoMapObjectPrivate *QMapCircleObjectPrivateDefault::clone()
185 {
186 return new QMapCircleObjectPrivateDefault(static_cast<QMapCircleObjectPrivate &>(*this));
187 }
188
QMapCircleObject(QObject * parent)189 QMapCircleObject::QMapCircleObject(QObject *parent)
190 : QGeoMapObject(QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(new QMapCircleObjectPrivateDefault(this)), parent)
191
192 {
193 QMapCircleObjectPrivate *d = static_cast<QMapCircleObjectPrivate*>(d_ptr.data());
194 d->setBorderColor(QColor(Qt::black)); // These are QDeclarativeMapLineProperties defaults
195 d->setBorderWidth(1.0);
196 }
197
~QMapCircleObject()198 QMapCircleObject::~QMapCircleObject()
199 {
200
201 }
202
203 /*!
204 \qmlproperty coordinate Qt.labs.location::MapCircleObject::center
205
206 This property holds the central point about which the circle is defined.
207
208 \sa radius
209 */
center() const210 QGeoCoordinate QMapCircleObject::center() const
211 {
212 return static_cast<const QMapCircleObjectPrivate*>(d_ptr.data())->center();
213 }
214
215 /*!
216 \qmlproperty real Qt.labs.location::MapCircleObject::radius
217
218 This property holds the radius of the circle, in meters on the ground.
219
220 \sa center
221 */
radius() const222 qreal QMapCircleObject::radius() const
223 {
224 return static_cast<const QMapCircleObjectPrivate*>(d_ptr.data())->radius();
225 }
226
227 /*!
228 \qmlproperty color Qt.labs.location::MapCircleObject::color
229
230 This property holds the fill color of the circle when drawn. For no fill,
231 use a transparent color.
232 */
color() const233 QColor QMapCircleObject::color() const
234 {
235 return static_cast<const QMapCircleObjectPrivate*>(d_ptr.data())->color();
236 }
237
238 /*!
239 \qmlpropertygroup Qt.labs.location::MapCircleObject::border
240 \qmlproperty int MapCircleObject::border.width
241 \qmlproperty color MapCircleObject::border.color
242
243 This property is part of the border group property.
244 The border property holds the width and color used to draw the border of the circle.
245 The width is in pixels and is independent of the zoom level of the map.
246
247 The default values correspond to a black border with a width of 1 pixel.
248 For no line, use a width of 0 or a transparent color.
249 */
border()250 QDeclarativeMapLineProperties *QMapCircleObject::border()
251 {
252 if (!m_border) {
253 m_border = new QDeclarativeMapLineProperties(this);
254 connect(m_border, &QDeclarativeMapLineProperties::colorChanged, this, [this](const QColor &color){
255 static_cast<QMapCircleObjectPrivate*>(d_ptr.data())->setBorderColor(color);
256 });
257 connect(m_border, &QDeclarativeMapLineProperties::widthChanged, this, [this](qreal width){
258 static_cast<QMapCircleObjectPrivate*>(d_ptr.data())->setBorderWidth(width);
259 });
260 }
261 return m_border;
262 }
263
setCenter(const QGeoCoordinate & center)264 void QMapCircleObject::setCenter(const QGeoCoordinate ¢er)
265 {
266 auto ptr = static_cast<QMapCircleObjectPrivate*>(d_ptr.data());
267 if (ptr->center() == center)
268 return;
269
270 ptr->setCenter(center);
271 emit centerChanged();
272 }
273
setRadius(qreal radius)274 void QMapCircleObject::setRadius(qreal radius)
275 {
276 auto d = static_cast<QMapCircleObjectPrivate*>(d_ptr.data());
277 if (d->radius() == radius)
278 return;
279
280 d->setRadius(radius);
281 emit radiusChanged();
282 }
283
setColor(const QColor & color)284 void QMapCircleObject::setColor(const QColor &color)
285 {
286 auto d = static_cast<QMapCircleObjectPrivate*>(d_ptr.data());
287 if (d->color() == color)
288 return;
289
290 d->setColor(color);
291 emit colorChanged();
292 }
293
setMap(QGeoMap * map)294 void QMapCircleObject::setMap(QGeoMap *map)
295 {
296 QMapCircleObjectPrivate *d = static_cast<QMapCircleObjectPrivate *>(d_ptr.data());
297 if (d->m_map == map)
298 return;
299
300 QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
301
302 if (!map) {
303 // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
304 // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
305 d_ptr = new QMapCircleObjectPrivateDefault(*d);
306 // Old pimpl deleted implicitly by QExplicitlySharedDataPointer
307 }
308 }
309
310 QT_END_NAMESPACE
311