1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 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 "qmapiconobject_p.h"
38 #include "qmapiconobject_p_p.h"
39 #include <QExplicitlySharedDataPointer>
40 #include <QtPositioning/QGeoCircle>
41
42 QT_BEGIN_NAMESPACE
43
44 /*!
45 \qmltype MapIconObject
46 \instantiates QMapIconObject
47 \inqmlmodule Qt.labs.location
48 \ingroup qml-QtLocation5-maps
49 \inherits QGeoMapObject
50
51 \brief The MapIconObject displays an icon on a Map.
52
53 The MapIconObject displays an icon on a Map.
54 The MapIconObject type only makes sense when contained in a Map or in a \l MapObjectView.
55 */
56
~QMapIconObjectPrivate()57 QMapIconObjectPrivate::~QMapIconObjectPrivate()
58 {
59
60 }
61
QMapIconObjectPrivate(QGeoMapObject * q)62 QMapIconObjectPrivate::QMapIconObjectPrivate(QGeoMapObject *q) : QGeoMapObjectPrivate(q)
63 {
64
65 }
66
type() const67 QGeoMapObject::Type QMapIconObjectPrivate::type() const
68 {
69 return QGeoMapObject::IconType;
70 }
71
equals(const QGeoMapObjectPrivate & other) const72 bool QMapIconObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
73 {
74 if (other.type() != type()) // This check might be unnecessary, depending on how equals gets used
75 return false;
76
77 const QMapIconObjectPrivate &o = static_cast<const QMapIconObjectPrivate &>(other);
78 return (QGeoMapObjectPrivate::equals(o)
79 && content() == o.content()
80 && coordinate() == o.coordinate());
81 }
82
83 //
84 // QGeoMapIconPrivate default implementation
85 //
86
QMapIconObjectPrivateDefault(QGeoMapObject * q)87 QMapIconObjectPrivateDefault::QMapIconObjectPrivateDefault(QGeoMapObject *q) : QMapIconObjectPrivate(q)
88 {
89
90 }
QMapIconObjectPrivateDefault(const QMapIconObjectPrivate & other)91 QMapIconObjectPrivateDefault::QMapIconObjectPrivateDefault(const QMapIconObjectPrivate &other) : QMapIconObjectPrivate(other.q)
92 {
93 m_coordinate = other.coordinate();
94 m_content = other.content();
95 m_iconSize = other.iconSize();
96 qreal radius = QGeoCircle(other.geoShape()).radius();
97 m_radius = (qIsFinite(radius)) ? radius : 100.0;
98 }
99
~QMapIconObjectPrivateDefault()100 QMapIconObjectPrivateDefault::~QMapIconObjectPrivateDefault()
101 {
102
103 }
104
coordinate() const105 QGeoCoordinate QMapIconObjectPrivateDefault::coordinate() const
106 {
107 return m_coordinate;
108 }
109
setCoordinate(const QGeoCoordinate & coordinate)110 void QMapIconObjectPrivateDefault::setCoordinate(const QGeoCoordinate &coordinate)
111 {
112 m_coordinate = coordinate;
113 }
114
content() const115 QVariant QMapIconObjectPrivateDefault::content() const
116 {
117 return m_content;
118 }
119
setContent(const QVariant & content)120 void QMapIconObjectPrivateDefault::setContent(const QVariant &content)
121 {
122 m_content = content;
123 }
124
iconSize() const125 QSizeF QMapIconObjectPrivateDefault::iconSize() const
126 {
127 return m_iconSize;
128 }
129
setIconSize(const QSizeF & size)130 void QMapIconObjectPrivateDefault::setIconSize(const QSizeF &size)
131 {
132 m_iconSize = size;
133 }
134
clone()135 QGeoMapObjectPrivate *QMapIconObjectPrivateDefault::clone()
136 {
137 return new QMapIconObjectPrivateDefault(static_cast<QMapIconObjectPrivate &>(*this));
138 }
139
geoShape() const140 QGeoShape QMapIconObjectPrivateDefault::geoShape() const
141 {
142 return QGeoCircle(coordinate(), m_radius); // fixing the radius to 100 meters, as a meaningful size for
143 // fitting the viewport to this icon without losing context completely
144 }
145
setGeoShape(const QGeoShape & shape)146 void QMapIconObjectPrivateDefault::setGeoShape(const QGeoShape &shape)
147 {
148 QGeoCoordinate crd;
149 const QGeoCircle circle(shape); // if shape isn't a circle, circle will be created as a default-constructed circle
150 if (circle.isValid()) {
151 crd = circle.center();
152 m_radius = circle.radius();
153 } else {
154 crd = shape.boundingGeoRectangle().center();
155 }
156
157 if (crd == coordinate())
158 return;
159
160 setCoordinate(crd);
161 emit static_cast<QMapIconObject *>(q)->coordinateChanged(crd);
162 }
163
164
165 /*
166
167 QGeoMapIconPrivate default implementation
168
169 */
170
171
QMapIconObject(QObject * parent)172 QMapIconObject::QMapIconObject(QObject *parent)
173 : QGeoMapObject(QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(new QMapIconObjectPrivateDefault(this)), parent)
174 {}
175
~QMapIconObject()176 QMapIconObject::~QMapIconObject()
177 {
178
179 }
180
181 /*!
182 \qmlproperty Variant Qt.labs.location::MapIconObject::content
183
184 This property holds the content to be used for the icon. The actual content of this property is somehow
185 backend-dependent. The implementation for the raster engine accepts local urls or paths.
186 Other implementations may accept additional content types.
187 */
content() const188 QVariant QMapIconObject::content() const
189 {
190 const QMapIconObjectPrivate *d = static_cast<const QMapIconObjectPrivate *>(d_ptr.data());
191 return d->content();
192 }
193
194 /*!
195 \qmlproperty Variant Qt.labs.location::MapIconObject::coordinate
196
197 The coordinate where the icon is going to be shown.
198 What pixel of the icon matches the coordinate is somehow backend-dependent.
199 For example, due to limitations, some backends might associate the center of the icon with the
200 coordinate, others one of the corners.
201 If there is a choice, backend developers should use the center of the icon as the default anchor
202 point.
203
204 The behavior is also intended to be customizable with a \l DynamicParameter, when
205 using backends that support anchoring arbitrary points of the icon to the coordinate.
206 What kind of parameter to use and how to achieve this behavior is intended to be
207 documented per-backend.
208 */
coordinate() const209 QGeoCoordinate QMapIconObject::coordinate() const
210 {
211 const QMapIconObjectPrivate *d = static_cast<const QMapIconObjectPrivate *>(d_ptr.data());
212 return d->coordinate();
213 }
214
setContent(QVariant content)215 void QMapIconObject::setContent(QVariant content)
216 {
217 QMapIconObjectPrivate *d = static_cast<QMapIconObjectPrivate *>(d_ptr.data());
218 if (d->content() == content)
219 return;
220
221 d->setContent(content);
222 emit contentChanged(content);
223 }
224
setCoordinate(const QGeoCoordinate & center)225 void QMapIconObject::setCoordinate(const QGeoCoordinate ¢er)
226 {
227 QMapIconObjectPrivate *d = static_cast<QMapIconObjectPrivate*>(d_ptr.data());
228 if (d->coordinate() == center)
229 return;
230
231 d->setCoordinate(center);
232 emit coordinateChanged(center);
233 }
234
235 /*!
236 \qmlproperty Variant Qt.labs.location::MapIconObject::iconSize
237
238 The size of the icon as it will be shown on the map.
239 */
iconSize() const240 QSizeF QMapIconObject::iconSize() const
241 {
242 const QMapIconObjectPrivate *d = static_cast<const QMapIconObjectPrivate *>(d_ptr.data());
243 return d->iconSize();
244 }
245
246
setIconSize(const QSizeF & size)247 void QMapIconObject::setIconSize(const QSizeF &size)
248 {
249 QMapIconObjectPrivate *d = static_cast<QMapIconObjectPrivate*>(d_ptr.data());
250 if (d->iconSize() == size)
251 return;
252
253 d->setIconSize(size);
254 emit iconSizeChanged();
255 }
256
setMap(QGeoMap * map)257 void QMapIconObject::setMap(QGeoMap *map)
258 {
259 QMapIconObjectPrivate *d = static_cast<QMapIconObjectPrivate *>(d_ptr.data());
260 if (d->m_map == map)
261 return;
262
263 QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
264
265 if (!map) {
266 // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
267 // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
268 d_ptr = new QMapIconObjectPrivateDefault(*d);
269 // Old pimpl deleted implicitly by QExplicitlySharedDataPointer
270 }
271 }
272
273 QT_END_NAMESPACE
274