1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2008 Torsten Rahn <tackat@kde.org>
4 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org>
5 //
6
7 #include "CompassFloatItem.h"
8 #include "ui_CompassConfigWidget.h"
9
10 #include "MarbleDebug.h"
11 #include "MarbleDirs.h"
12 #include "ViewportParams.h"
13
14 #include <QRect>
15 #include <QColor>
16 #include <QPainter>
17 #include <QPainterPath>
18 #include <QPushButton>
19 #include <QSvgRenderer>
20
21 namespace Marble
22 {
23
CompassFloatItem()24 CompassFloatItem::CompassFloatItem()
25 : AbstractFloatItem( nullptr ),
26 m_svgobj( nullptr ),
27 m_polarity( 0 ),
28 m_themeIndex( 0 ),
29 m_configDialog( nullptr ),
30 m_uiConfigWidget( nullptr )
31 {
32 }
33
CompassFloatItem(const MarbleModel * marbleModel)34 CompassFloatItem::CompassFloatItem( const MarbleModel *marbleModel )
35 : AbstractFloatItem( marbleModel, QPointF( -1.0, 10.0 ), QSizeF( 75.0, 75.0 ) ),
36 m_isInitialized( false ),
37 m_svgobj( nullptr ),
38 m_compass(),
39 m_polarity( 0 ),
40 m_themeIndex( 0 ),
41 m_configDialog( nullptr ),
42 m_uiConfigWidget( nullptr )
43 {
44 }
45
~CompassFloatItem()46 CompassFloatItem::~CompassFloatItem ()
47 {
48 delete m_svgobj;
49 }
50
backendTypes() const51 QStringList CompassFloatItem::backendTypes() const
52 {
53 return QStringList(QStringLiteral("compass"));
54 }
55
name() const56 QString CompassFloatItem::name() const
57 {
58 return tr( "Compass" );
59 }
60
guiString() const61 QString CompassFloatItem::guiString() const
62 {
63 return tr( "&Compass" );
64 }
65
nameId() const66 QString CompassFloatItem::nameId() const
67 {
68 return QStringLiteral("compass");
69 }
70
version() const71 QString CompassFloatItem::version() const
72 {
73 return QStringLiteral("1.0");
74 }
75
description() const76 QString CompassFloatItem::description() const
77 {
78 return tr( "This is a float item that provides a compass." );
79 }
80
copyrightYears() const81 QString CompassFloatItem::copyrightYears() const
82 {
83 return QStringLiteral("2009, 2010");
84 }
85
pluginAuthors() const86 QVector<PluginAuthor> CompassFloatItem::pluginAuthors() const
87 {
88 return QVector<PluginAuthor>()
89 << PluginAuthor(QStringLiteral("Dennis Nienhüser"), QStringLiteral("nienhueser@kde.org"))
90 << PluginAuthor(QStringLiteral("Torsten Rahn"), QStringLiteral("tackat@kde.org"));
91 }
92
icon() const93 QIcon CompassFloatItem::icon() const
94 {
95 return QIcon(QStringLiteral(":/icons/compass.png"));
96 }
97
initialize()98 void CompassFloatItem::initialize()
99 {
100 readSettings();
101 m_isInitialized = true;
102 }
103
isInitialized() const104 bool CompassFloatItem::isInitialized() const
105 {
106 return m_isInitialized;
107 }
108
backgroundShape() const109 QPainterPath CompassFloatItem::backgroundShape() const
110 {
111 QRectF contentRect = this->contentRect();
112 QPainterPath path;
113 int fontheight = QFontMetrics( font() ).ascent();
114 int compassLength = static_cast<int>( contentRect.height() ) - 5 - fontheight;
115
116 path.addEllipse( QRectF( QPointF( marginLeft() + padding() + ( contentRect.width() - compassLength ) / 2,
117 marginTop() + padding() + 5 + fontheight ),
118 QSize( compassLength, compassLength ) ).toRect() );
119 return path;
120 }
121
setProjection(const ViewportParams * viewport)122 void CompassFloatItem::setProjection( const ViewportParams *viewport )
123 {
124 // figure out the polarity ...
125 if ( m_polarity != viewport->polarity() ) {
126 m_polarity = viewport->polarity();
127 update();
128 }
129
130 AbstractFloatItem::setProjection( viewport );
131 }
132
paintContent(QPainter * painter)133 void CompassFloatItem::paintContent( QPainter *painter )
134 {
135 painter->save();
136
137 QRectF compassRect( contentRect() );
138
139 const QString dirstr =
140 (m_polarity == +1) ? tr("N") :
141 (m_polarity == -1) ? tr("S") :
142 /*else*/ QString();
143
144 int fontheight = QFontMetrics( font() ).ascent();
145 int fontwidth = QFontMetrics( font() ).boundingRect( dirstr ).width();
146
147 QPen outlinepen( background().color() );
148 outlinepen.setWidth( 2 );
149 QBrush outlinebrush( pen().color() );
150
151 QPainterPath outlinepath;
152 const QPointF baseline( 0.5 * (qreal)( compassRect.width() - fontwidth ),
153 (qreal)(fontheight) + 2.0 );
154
155 outlinepath.addText( baseline, font(), dirstr );
156
157 painter->setPen( outlinepen );
158 painter->setBrush( outlinebrush );
159 painter->drawPath( outlinepath );
160
161 painter->setPen( Qt::NoPen );
162 painter->drawPath( outlinepath );
163
164 int compassLength = static_cast<int>( compassRect.height() ) - 5 - fontheight;
165
166 QSize compassSize( compassLength, compassLength );
167
168 // Rerender compass pixmap if the size has changed
169 if ( m_compass.isNull() || m_compass.size() != compassSize ) {
170 m_compass = QPixmap( compassSize );
171 m_compass.fill( Qt::transparent );
172 QPainter mapPainter( &m_compass );
173 mapPainter.setViewport( m_compass.rect() );
174 m_svgobj->render( &mapPainter );
175 }
176 painter->drawPixmap( QPoint( static_cast<int>( compassRect.width() - compassLength ) / 2, fontheight + 5 ), m_compass );
177
178 painter->restore();
179 }
180
configDialog()181 QDialog *CompassFloatItem::configDialog()
182 {
183 if ( !m_configDialog ) {
184 m_configDialog = new QDialog();
185 m_uiConfigWidget = new Ui::CompassConfigWidget;
186 m_uiConfigWidget->setupUi( m_configDialog );
187 readSettings();
188 connect( m_uiConfigWidget->m_buttonBox, SIGNAL(accepted()),
189 SLOT(writeSettings()) );
190 connect( m_uiConfigWidget->m_buttonBox, SIGNAL(rejected()),
191 SLOT(readSettings()) );
192 QPushButton *applyButton = m_uiConfigWidget->m_buttonBox->button( QDialogButtonBox::Apply );
193 connect( applyButton, SIGNAL(clicked()),
194 this, SLOT(writeSettings()) );
195 }
196
197 return m_configDialog;
198 }
199
settings() const200 QHash<QString,QVariant> CompassFloatItem::settings() const
201 {
202 QHash<QString, QVariant> result = AbstractFloatItem::settings();
203
204 result.insert(QStringLiteral("theme"), m_themeIndex);
205
206 return result;
207 }
208
setSettings(const QHash<QString,QVariant> & settings)209 void CompassFloatItem::setSettings( const QHash<QString,QVariant> &settings )
210 {
211 AbstractFloatItem::setSettings( settings );
212
213 m_themeIndex = settings.value(QStringLiteral("theme"), 0).toInt();
214
215 readSettings();
216 }
217
readSettings()218 void CompassFloatItem::readSettings()
219 {
220 if ( m_uiConfigWidget && m_themeIndex >= 0 && m_themeIndex < m_uiConfigWidget->m_themeList->count() ) {
221 m_uiConfigWidget->m_themeList->setCurrentRow( m_themeIndex );
222 }
223
224 QString theme = QStringLiteral(":/compass.svg");
225 switch( m_themeIndex ) {
226 case 1:
227 theme = QStringLiteral(":/compass-arrows.svg");
228 break;
229 case 2:
230 theme = QStringLiteral(":/compass-atom.svg");
231 break;
232 case 3:
233 theme = QStringLiteral(":/compass-magnet.svg");
234 break;
235 }
236
237 delete m_svgobj;
238 m_svgobj = new QSvgRenderer( theme, this );
239 m_compass = QPixmap();
240 }
241
writeSettings()242 void CompassFloatItem::writeSettings()
243 {
244 if ( m_uiConfigWidget ) {
245 m_themeIndex = m_uiConfigWidget->m_themeList->currentRow();
246 }
247 readSettings();
248 update();
249 emit settingsChanged( nameId() );
250 }
251
252 }
253
254 #include "moc_CompassFloatItem.cpp"
255