File indexing completed on 2025-01-05 03:59:14
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2012 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0004 // SPDX-FileCopyrightText: 2012 Mohammed Nafees <nafees.technocool@gmail.com> 0005 // 0006 0007 // self 0008 #include "BillboardGraphicsItem.h" 0009 #include "MarbleGraphicsItem_p.h" 0010 0011 // Marble 0012 #include "ViewportParams.h" 0013 0014 namespace Marble 0015 { 0016 0017 class BillboardGraphicsItemPrivate : public MarbleGraphicsItemPrivate 0018 { 0019 public: 0020 BillboardGraphicsItemPrivate(BillboardGraphicsItem *parent) 0021 : MarbleGraphicsItemPrivate(parent), 0022 m_alignment( Qt::AlignHCenter | Qt::AlignVCenter ) 0023 { 0024 } 0025 0026 QVector<QPointF> positions() const override 0027 { 0028 return m_positions; 0029 } 0030 0031 QVector<QPointF> absolutePositions() const override 0032 { 0033 return m_positions; 0034 } 0035 0036 Qt::Alignment m_alignment; 0037 0038 void setProjection(const ViewportParams *viewport) override 0039 { 0040 m_positions.clear(); 0041 0042 qreal x[100], y; 0043 int pointRepeatNumber = 0; 0044 bool globeHidesPoint; 0045 0046 viewport->screenCoordinates( m_coordinates, x, y, pointRepeatNumber, 0047 m_size, globeHidesPoint ); 0048 0049 // Don't display items if they are on the far side of the globe. 0050 if (globeHidesPoint) return; 0051 0052 m_positions.reserve(pointRepeatNumber); 0053 // handle vertical alignment 0054 qint32 topY = ( viewport->height() - m_size.height() ) / 2; 0055 if ( m_alignment & Qt::AlignTop ) { 0056 topY = y - m_size.height(); 0057 } 0058 else if ( m_alignment & Qt::AlignVCenter ) { 0059 topY = y - ( m_size.height() / 2 ); 0060 } 0061 else if ( m_alignment & Qt::AlignBottom ) { 0062 topY = y; 0063 } 0064 0065 for ( int i = 0; i < pointRepeatNumber; ++i ) { 0066 // handle horizontal alignment 0067 qint32 leftX = ( viewport->width() - m_size.width() ) / 2; 0068 if ( m_alignment & Qt::AlignLeft ) { 0069 leftX = x[i] - m_size.width(); 0070 } 0071 else if ( m_alignment & Qt::AlignHCenter ) { 0072 leftX = x[i] - ( m_size.width() / 2 ); 0073 } 0074 else if ( m_alignment & Qt::AlignRight ) { 0075 leftX = x[i]; 0076 } 0077 0078 m_positions.append( QPoint( leftX, topY ) ); 0079 } 0080 } 0081 0082 GeoDataCoordinates m_coordinates; 0083 QVector<QPointF> m_positions; 0084 }; 0085 0086 BillboardGraphicsItem::BillboardGraphicsItem() 0087 : MarbleGraphicsItem(new BillboardGraphicsItemPrivate(this)) 0088 { 0089 } 0090 0091 GeoDataCoordinates BillboardGraphicsItem::coordinate() const 0092 { 0093 Q_D(const BillboardGraphicsItem); 0094 return d->m_coordinates; 0095 } 0096 0097 void BillboardGraphicsItem::setCoordinate( const GeoDataCoordinates &coordinates ) 0098 { 0099 Q_D(BillboardGraphicsItem); 0100 d->m_coordinates = coordinates; 0101 } 0102 0103 QVector<QPointF> BillboardGraphicsItem::positions() const 0104 { 0105 Q_D(const BillboardGraphicsItem); 0106 return d->positions(); 0107 } 0108 0109 QVector<QRectF> BillboardGraphicsItem::boundingRects() const 0110 { 0111 Q_D(const BillboardGraphicsItem); 0112 0113 QVector<QRectF> rects; 0114 rects.reserve(d->m_positions.size()); 0115 0116 QSizeF const size = d->m_size; 0117 for (const QPointF &point: d->m_positions) { 0118 rects << QRectF(point, size); 0119 } 0120 return rects; 0121 } 0122 0123 QRectF BillboardGraphicsItem::containsRect( const QPointF &point ) const 0124 { 0125 for( const QRectF &rect: boundingRects() ) { 0126 if( rect.contains( point ) ) 0127 return rect; 0128 } 0129 0130 return QRectF(); 0131 } 0132 0133 Qt::Alignment BillboardGraphicsItem::alignment() const 0134 { 0135 Q_D(const BillboardGraphicsItem); 0136 return d->m_alignment; 0137 } 0138 0139 void BillboardGraphicsItem::setAlignment(Qt::Alignment alignment) 0140 { 0141 Q_D(BillboardGraphicsItem); 0142 d->m_alignment = alignment; 0143 } 0144 0145 } // Marble namespace