/**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtLocation module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL3$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see http://www.qt.io/terms-conditions. For further ** information use the contact form at http://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPLv3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or later as published by the Free ** Software Foundation and appearing in the file LICENSE.GPL included in ** the packaging of this file. Please review the following information to ** ensure the GNU General Public License version 2.0 requirements will be ** met: http://www.gnu.org/licenses/gpl-2.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qdeclarativegeomapitembase_p.h" #include "qgeocameradata_p.h" #include #include #include #include #include QT_BEGIN_NAMESPACE QGeoMapViewportChangeEvent::QGeoMapViewportChangeEvent() : zoomLevelChanged(false), centerChanged(false), mapSizeChanged(false), tiltChanged(false), bearingChanged(false), rollChanged(false) { } QGeoMapViewportChangeEvent::QGeoMapViewportChangeEvent(const QGeoMapViewportChangeEvent &other) { this->operator=(other); } QGeoMapViewportChangeEvent &QGeoMapViewportChangeEvent::operator=(const QGeoMapViewportChangeEvent &other) { if (this == &other) return (*this); cameraData = other.cameraData; mapSize = other.mapSize; zoomLevelChanged = other.zoomLevelChanged; centerChanged = other.centerChanged; mapSizeChanged = other.mapSizeChanged; tiltChanged = other.tiltChanged; bearingChanged = other.bearingChanged; rollChanged = other.rollChanged; return (*this); } QDeclarativeGeoMapItemBase::QDeclarativeGeoMapItemBase(QQuickItem *parent) : QQuickItem(parent), map_(0), quickMap_(0), parentGroup_(0) { setFiltersChildMouseEvents(true); connect(this, SIGNAL(childrenChanged()), this, SLOT(afterChildrenChanged())); // Changing opacity on a mapItemGroup should affect also the opacity on the children. // This must be notified to plugins, if they are to render the item. connect(this, &QQuickItem::opacityChanged, this, &QDeclarativeGeoMapItemBase::mapItemOpacityChanged); parentGroup_ = qobject_cast(parent); if (parentGroup_) connect(qobject_cast(parent), &QQuickItem::opacityChanged, this, &QDeclarativeGeoMapItemBase::mapItemOpacityChanged); } QDeclarativeGeoMapItemBase::~QDeclarativeGeoMapItemBase() { disconnect(this, SLOT(afterChildrenChanged())); if (quickMap_) quickMap_->removeMapItem(this); } /*! \internal */ void QDeclarativeGeoMapItemBase::afterChildrenChanged() { QList kids = childItems(); if (kids.size() > 0) { bool printedWarning = false; foreach (QQuickItem *i, kids) { if (i->flags() & QQuickItem::ItemHasContents && !qobject_cast(i)) { if (!printedWarning) { qmlWarning(this) << "Geographic map items do not support child items"; printedWarning = true; } qmlWarning(i) << "deleting this child"; i->deleteLater(); } } } } /*! \internal */ void QDeclarativeGeoMapItemBase::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map) { if (quickMap == quickMap_) return; if (quickMap && quickMap_) return; // don't allow association to more than one map if (quickMap_) quickMap_->disconnect(this); if (map_) map_->disconnect(this); quickMap_ = quickMap; map_ = map; if (map_ && quickMap_) { connect(map_, SIGNAL(cameraDataChanged(QGeoCameraData)), this, SLOT(baseCameraDataChanged(QGeoCameraData))); connect(quickMap, SIGNAL(heightChanged()), this, SLOT(polishAndUpdate())); connect(quickMap, SIGNAL(widthChanged()), this, SLOT(polishAndUpdate())); lastSize_ = QSizeF(quickMap_->width(), quickMap_->height()); lastCameraData_ = map_->cameraData(); } } /*! \internal */ void QDeclarativeGeoMapItemBase::baseCameraDataChanged(const QGeoCameraData &cameraData) { QGeoMapViewportChangeEvent evt; evt.cameraData = cameraData; evt.mapSize = QSizeF(quickMap_->width(), quickMap_->height()); if (evt.mapSize != lastSize_) evt.mapSizeChanged = true; if (cameraData.bearing() != lastCameraData_.bearing()) evt.bearingChanged = true; if (cameraData.center() != lastCameraData_.center()) evt.centerChanged = true; if (cameraData.roll() != lastCameraData_.roll()) evt.rollChanged = true; if (cameraData.tilt() != lastCameraData_.tilt()) evt.tiltChanged = true; if (cameraData.zoomLevel() != lastCameraData_.zoomLevel()) evt.zoomLevelChanged = true; lastSize_ = evt.mapSize; lastCameraData_ = cameraData; afterViewportChanged(evt); } /*! \internal */ void QDeclarativeGeoMapItemBase::setPositionOnMap(const QGeoCoordinate &coordinate, const QPointF &offset) { if (!map_ || !quickMap_) return; QDoubleVector2D wrappedProjection = map_->geoProjection().geoToWrappedMapProjection(coordinate); if (!map_->geoProjection().isProjectable(wrappedProjection)) return; QDoubleVector2D pos = map_->geoProjection().wrappedMapProjectionToItemPosition(wrappedProjection); QPointF topLeft = pos.toPointF() - offset; setPosition(topLeft); } static const double opacityRampMin = 1.5; static const double opacityRampMax = 2.5; /*! \internal */ float QDeclarativeGeoMapItemBase::zoomLevelOpacity() const { if (quickMap_->zoomLevel() > opacityRampMax) return 1.0; else if (quickMap_->zoomLevel() > opacityRampMin) return quickMap_->zoomLevel() - opacityRampMin; else return 0.0; } bool QDeclarativeGeoMapItemBase::childMouseEventFilter(QQuickItem *item, QEvent *event) { Q_UNUSED(item) if (event->type() == QEvent::MouseButtonPress && !contains(static_cast(event)->pos())) { // In case of items that are not rectangles, this filter is used to test if the event has landed // inside the actual item shape. // If so, the method returns true, meaning that it prevents the event delivery to child "*item" (for example, // a mouse area that is on top of this map item). // However, this method sets "accepted" to false, so that the event can still be passed further up, // specifically to the parent Map, that is a sort of flickable. // Otherwise, if the event is not contained within the map item, the method returns false, meaning the event // is delivered to the child *item (like the mouse area associated). event->setAccepted(false); return true; } return false; } /*! \internal */ QSGNode *QDeclarativeGeoMapItemBase::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *pd) { if (!map_ || !quickMap_ || map_->supportedMapItemTypes() & itemType()) { if (oldNode) delete oldNode; oldNode = 0; return 0; } QSGOpacityNode *opn = static_cast(oldNode); if (!opn) opn = new QSGOpacityNode(); opn->setOpacity(zoomLevelOpacity()); QSGNode *oldN = opn->childCount() ? opn->firstChild() : 0; opn->removeAllChildNodes(); if (opn->opacity() > 0.0) { QSGNode *n = this->updateMapItemPaintNode(oldN, pd); if (n) opn->appendChildNode(n); } else { delete oldN; } return opn; } /*! \internal */ QSGNode *QDeclarativeGeoMapItemBase::updateMapItemPaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { delete oldNode; return 0; } qreal QDeclarativeGeoMapItemBase::mapItemOpacity() const { if (parentGroup_) return parentGroup_->opacity() * opacity(); return opacity(); } bool QDeclarativeGeoMapItemBase::isPolishScheduled() const { return QQuickItemPrivate::get(this)->polishScheduled; } void QDeclarativeGeoMapItemBase::polishAndUpdate() { polish(); update(); } QT_END_NAMESPACE