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 &center)
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