Marble

PopupLayer.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2012 Mohammed Nafees <nafees.technocool@gmail.com>
4// SPDX-FileCopyrightText: 2012 Dennis Nienhüser <nienhueser@kde.org>
5// SPDX-FileCopyrightText: 2012 Illya Kovalevskyy <illya.kovalevskyy@gmail.com>
6// SPDX-FileCopyrightText: 2015 Imran Tatriev <itatriev@gmail.com>
7//
8
9#include "PopupLayer.h"
10
11#include "GeoDataCoordinates.h"
12#include "GeoPainter.h"
13#include "MarbleWidget.h"
14#include "PopupItem.h"
15#include "RenderPlugin.h"
16#include "RenderState.h"
17#include "ViewportParams.h"
18
19#include <QSizeF>
20
21namespace Marble
22{
23
24class Q_DECL_HIDDEN PopupLayer::Private
25{
26public:
27 Private(MarbleWidget *marbleWidget, PopupLayer *q);
28
29 /**
30 * @brief Sets size of the popup item, based on the requested size and viewport size
31 * @param viewport required to compute the maximum dimensions
32 */
33 void setAppropriateSize(const ViewportParams *viewport);
34
35 static QString filterEmptyShortDescription(const QString &description);
36 void setupDialogSatellite(const GeoDataPlacemark *index);
37 void setupDialogCity(const GeoDataPlacemark *index);
38 void setupDialogNation(const GeoDataPlacemark *index);
39 void setupDialogGeoPlaces(const GeoDataPlacemark *index);
40 void setupDialogSkyPlaces(const GeoDataPlacemark *index);
41
42 PopupItem *const m_popupItem;
43 MarbleWidget *const m_widget;
44 QSizeF m_requestedSize;
45 bool m_hasCrosshairsPlugin;
46 bool m_crosshairsVisible;
47};
48
49PopupLayer::Private::Private(MarbleWidget *marbleWidget, PopupLayer *q)
50 : m_popupItem(new PopupItem(q))
51 , m_widget(marbleWidget)
52 , m_hasCrosshairsPlugin(false)
53 , m_crosshairsVisible(true)
54{
55}
56
57PopupLayer::PopupLayer(MarbleWidget *marbleWidget, QObject *parent)
58 : QObject(parent)
59 , d(new Private(marbleWidget, this))
60{
61 for (const RenderPlugin *renderPlugin : d->m_widget->renderPlugins()) {
62 if (renderPlugin->nameId() == QLatin1StringView("crosshairs")) {
63 d->m_hasCrosshairsPlugin = true;
64 break;
65 }
66 }
67
68 connect(d->m_popupItem, &PopupItem::repaintNeeded, this, &PopupLayer::repaintNeeded);
69 connect(d->m_popupItem, &PopupItem::hide, this, &PopupLayer::hidePopupItem);
70}
71
72PopupLayer::~PopupLayer()
73{
74 delete d;
75}
76
77QStringList PopupLayer::renderPosition() const
78{
79 return QStringList(QStringLiteral("ALWAYS_ON_TOP"));
80}
81
82bool PopupLayer::render(GeoPainter *painter, ViewportParams *viewport, const QString &, GeoSceneLayer *)
83{
84 if (visible()) {
85 d->setAppropriateSize(viewport);
86 d->m_popupItem->paintEvent(painter, viewport);
87 }
88
89 return true;
90}
91
92bool PopupLayer::eventFilter(QObject *object, QEvent *e)
93{
94 return visible() && d->m_popupItem->eventFilter(object, e);
95}
96
97qreal PopupLayer::zValue() const
98{
99 return 4711.23;
100}
101
102RenderState PopupLayer::renderState() const
103{
104 return RenderState(QStringLiteral("Popup Window"));
105}
106
107bool PopupLayer::visible() const
108{
109 return d->m_popupItem->visible();
110}
111
112void PopupLayer::setVisible(bool visible)
113{
114 d->m_popupItem->setVisible(visible);
115 if (!visible) {
116 disconnect(d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()));
117 d->m_popupItem->clearHistory();
118 Q_EMIT repaintNeeded();
119 } else {
120 connect(d->m_popupItem, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded()));
121 }
122}
123
124void PopupLayer::popup()
125{
126 GeoDataCoordinates coords = d->m_popupItem->coordinate();
127 ViewportParams viewport(d->m_widget->viewport()->projection(),
128 coords.longitude(),
129 coords.latitude(),
130 d->m_widget->viewport()->radius(),
131 d->m_widget->viewport()->size());
132 qreal sx, sy, lon, lat;
133 viewport.screenCoordinates(coords, sx, sy);
134 sx = viewport.radius() < viewport.width() ? 0.5 * (viewport.width() + viewport.radius()) : 0.75 * viewport.width();
135 viewport.geoCoordinates(sx, sy, lon, lat, GeoDataCoordinates::Radian);
136 coords.setLatitude(lat);
137 coords.setLongitude(lon);
138 d->m_widget->centerOn(coords, true);
139
140 if (d->m_hasCrosshairsPlugin) {
141 d->m_crosshairsVisible = d->m_widget->showCrosshairs();
142
143 if (d->m_crosshairsVisible) {
144 d->m_widget->setShowCrosshairs(false);
145 }
146 }
147
148 setVisible(true);
149}
150
151void PopupLayer::setCoordinates(const GeoDataCoordinates &coordinates, Qt::Alignment alignment)
152{
153 d->m_popupItem->setCoordinate(coordinates);
154 d->m_popupItem->setAlignment(alignment);
155}
156
157void PopupLayer::setUrl(const QUrl &url)
158{
159 d->m_popupItem->setUrl(url);
160}
161
162void PopupLayer::setContent(const QString &html, const QUrl &baseUrl)
163{
164 d->m_popupItem->setContent(html, baseUrl);
165}
166
167void PopupLayer::setBackgroundColor(const QColor &color)
168{
169 if (color.isValid()) {
170 d->m_popupItem->setBackgroundColor(color);
171 }
172}
173
174void PopupLayer::setTextColor(const QColor &color)
175{
176 if (color.isValid()) {
177 d->m_popupItem->setTextColor(color);
178 }
179}
180
181void PopupLayer::setSize(const QSizeF &size)
182{
183 d->m_requestedSize = size;
184}
185
186void PopupLayer::Private::setAppropriateSize(const ViewportParams *viewport)
187{
188 qreal margin = 15.0;
189
190 QSizeF maximumSize;
191 maximumSize.setWidth(viewport->width() - margin);
192 maximumSize.setHeight(viewport->height() - margin);
193
194 QSizeF minimumSize(100.0, 100.0);
195
196 m_popupItem->setSize(m_requestedSize.boundedTo(maximumSize).expandedTo(minimumSize));
197}
198
199void PopupLayer::hidePopupItem()
200{
201 if (d->m_hasCrosshairsPlugin && d->m_crosshairsVisible) {
202 d->m_widget->setShowCrosshairs(d->m_crosshairsVisible);
203 }
204
205 setVisible(false);
206}
207
208}
209
210#include "moc_PopupLayer.cpp"
This file contains the headers for MarbleWidget.
This file contains the headers for ViewportParams.
A 3d point representation.
void setLatitude(qreal lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
set the longitude in a GeoDataCoordinates object
void setLongitude(qreal lon, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Radian)
set the longitude in a GeoDataCoordinates object
A public class that controls what is visible in the viewport of a Marble map.
bool screenCoordinates(const qreal lon, const qreal lat, qreal &x, qreal &y) const
Get the screen coordinates corresponding to geographical coordinates in the map.
bool geoCoordinates(const int x, const int y, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the map.
Binds a QML item to a specific geodetic location in screen coordinates.
bool isValid() const const
void setHeight(qreal height)
void setWidth(qreal width)
typedef Alignment
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.